Merge remote-tracking branch 'kraxel/usb.59' into staging

* kraxel/usb.59:
  ehci: Fix setting of halt bit from usbcmd register updates
  ehci: fix Interrupt Threshold Control implementation
  usb: update uas product id
  usb: async control xfer fixup
This commit is contained in:
Anthony Liguori 2012-08-22 12:53:18 -05:00
commit b6825cd79c
4 changed files with 24 additions and 13 deletions

View File

@ -107,6 +107,7 @@ static int do_token_setup(USBDevice *s, USBPacket *p)
} }
usb_packet_copy(p, s->setup_buf, p->iov.size); usb_packet_copy(p, s->setup_buf, p->iov.size);
p->result = 0;
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6]; s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
s->setup_index = 0; s->setup_index = 0;

View File

@ -223,7 +223,7 @@ static const USBDescDevice desc_device_high = {
static const USBDesc desc = { static const USBDesc desc = {
.id = { .id = {
.idVendor = 0x46f4, /* CRC16() of "QEMU" */ .idVendor = 0x46f4, /* CRC16() of "QEMU" */
.idProduct = 0x0002, .idProduct = 0x0003,
.bcdDevice = 0, .bcdDevice = 0,
.iManufacturer = STR_MANUFACTURER, .iManufacturer = STR_MANUFACTURER,
.iProduct = STR_PRODUCT, .iProduct = STR_PRODUCT,

View File

@ -575,7 +575,12 @@ static inline void ehci_update_irq(EHCIState *s)
/* flag interrupt condition */ /* flag interrupt condition */
static inline void ehci_raise_irq(EHCIState *s, int intr) static inline void ehci_raise_irq(EHCIState *s, int intr)
{ {
s->usbsts_pending |= intr; if (intr & (USBSTS_PCD | USBSTS_FLR | USBSTS_HSE)) {
s->usbsts |= intr;
ehci_update_irq(s);
} else {
s->usbsts_pending |= intr;
}
} }
/* /*
@ -1182,22 +1187,23 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
break; break;
} }
if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) !=
((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & s->usbcmd)) {
if (s->pstate == EST_INACTIVE) {
SET_LAST_RUN_CLOCK(s);
}
ehci_update_halt(s);
s->async_stepdown = 0;
qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock));
}
/* not supporting dynamic frame list size at the moment */ /* not supporting dynamic frame list size at the moment */
if ((val & USBCMD_FLS) && !(s->usbcmd & USBCMD_FLS)) { if ((val & USBCMD_FLS) && !(s->usbcmd & USBCMD_FLS)) {
fprintf(stderr, "attempt to set frame list size -- value %d\n", fprintf(stderr, "attempt to set frame list size -- value %d\n",
val & USBCMD_FLS); val & USBCMD_FLS);
val &= ~USBCMD_FLS; val &= ~USBCMD_FLS;
} }
if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) !=
((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & s->usbcmd)) {
if (s->pstate == EST_INACTIVE) {
SET_LAST_RUN_CLOCK(s);
}
s->usbcmd = val; /* Set usbcmd for ehci_update_halt() */
ehci_update_halt(s);
s->async_stepdown = 0;
qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock));
}
break; break;
case USBSTS: case USBSTS:
@ -2466,13 +2472,16 @@ static int usb_ehci_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_ehci = { static const VMStateDescription vmstate_ehci = {
.name = "ehci", .name = "ehci",
.version_id = 1, .version_id = 2,
.minimum_version_id = 1,
.post_load = usb_ehci_post_load, .post_load = usb_ehci_post_load,
.fields = (VMStateField[]) { .fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, EHCIState), VMSTATE_PCI_DEVICE(dev, EHCIState),
/* mmio registers */ /* mmio registers */
VMSTATE_UINT32(usbcmd, EHCIState), VMSTATE_UINT32(usbcmd, EHCIState),
VMSTATE_UINT32(usbsts, EHCIState), VMSTATE_UINT32(usbsts, EHCIState),
VMSTATE_UINT32_V(usbsts_pending, EHCIState, 2),
VMSTATE_UINT32_V(usbsts_frindex, EHCIState, 2),
VMSTATE_UINT32(usbintr, EHCIState), VMSTATE_UINT32(usbintr, EHCIState),
VMSTATE_UINT32(frindex, EHCIState), VMSTATE_UINT32(frindex, EHCIState),
VMSTATE_UINT32(ctrldssegment, EHCIState), VMSTATE_UINT32(ctrldssegment, EHCIState),

View File

@ -1045,6 +1045,7 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
/* Note request is (bRequestType << 8) | bRequest */ /* Note request is (bRequestType << 8) | bRequest */
trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index); trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index);
assert(p->result == 0);
switch (request) { switch (request) {
case DeviceOutRequest | USB_REQ_SET_ADDRESS: case DeviceOutRequest | USB_REQ_SET_ADDRESS: