diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2011-12-13 15:58:19 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2012-01-17 09:44:50 +0100 |
commit | 25d5de7d81a5b1a5c625775648d3d92e8398741c (patch) | |
tree | d27fdeb3d10f8fb510722ff093b814764d726cbb | |
parent | f003397ce95441cd8de01a728affb3de7accd1dd (diff) | |
download | qemu-25d5de7d81a5b1a5c625775648d3d92e8398741c.zip qemu-25d5de7d81a5b1a5c625775648d3d92e8398741c.tar.gz qemu-25d5de7d81a5b1a5c625775648d3d92e8398741c.tar.bz2 |
usb: link packets to endpoints not devices
Add USBEndpoint for the control endpoint to USBDevices. Link async
packets to the USBEndpoint instead of the USBDevice.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r-- | hw/usb-ehci.c | 3 | ||||
-rw-r--r-- | hw/usb-musb.c | 3 | ||||
-rw-r--r-- | hw/usb-ohci.c | 4 | ||||
-rw-r--r-- | hw/usb-uhci.c | 3 | ||||
-rw-r--r-- | hw/usb.c | 12 | ||||
-rw-r--r-- | hw/usb.h | 4 |
6 files changed, 22 insertions, 7 deletions
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index 7c926c0..a305661 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -715,7 +715,8 @@ static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev) EHCIQueue *q, *tmp; QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) { - if (q->packet.owner != dev) { + if (q->packet.owner == NULL || + q->packet.owner->dev != dev) { continue; } ehci_free_queue(q); diff --git a/hw/usb-musb.c b/hw/usb-musb.c index 01e2e7c..4f528d2 100644 --- a/hw/usb-musb.c +++ b/hw/usb-musb.c @@ -812,7 +812,8 @@ static void musb_async_cancel_device(MUSBState *s, USBDevice *dev) for (ep = 0; ep < 16; ep++) { for (dir = 0; dir < 2; dir++) { - if (s->ep[ep].packey[dir].p.owner != dev) { + if (s->ep[ep].packey[dir].p.owner == NULL || + s->ep[ep].packey[dir].p.owner->dev != dev) { continue; } usb_cancel_packet(&s->ep[ep].packey[dir].p); diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 81488c4..69463d2 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -1707,7 +1707,9 @@ static void ohci_mem_write(void *opaque, static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev) { - if (ohci->async_td && ohci->usb_packet.owner == dev) { + if (ohci->async_td && + ohci->usb_packet.owner != NULL && + ohci->usb_packet.owner->dev == dev) { usb_cancel_packet(&ohci->usb_packet); ohci->async_td = 0; } diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index f8912e2..25d4e8c 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -245,7 +245,8 @@ static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev) UHCIAsync *curr, *n; QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) { - if (curr->packet.owner != dev) { + if (curr->packet.owner == NULL || + curr->packet.owner->dev != dev) { continue; } uhci_async_unlink(s, curr); @@ -329,7 +329,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p) ret = dev->info->handle_packet(dev, p); if (ret == USB_RET_ASYNC) { if (p->owner == NULL) { - p->owner = dev; + p->owner = usb_ep_get(dev, p->pid, p->devep); } else { /* We'll end up here when usb_handle_packet is called * recursively due to a hub being in the chain. Nothing @@ -357,7 +357,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p) void usb_cancel_packet(USBPacket * p) { assert(p->owner != NULL); - p->owner->info->cancel_packet(p->owner, p); + p->owner->dev->info->cancel_packet(p->owner->dev, p); p->owner = NULL; } @@ -419,11 +419,16 @@ void usb_ep_init(USBDevice *dev) { int ep; + dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL; + dev->ep_ctl.ifnum = 0; + dev->ep_ctl.dev = dev; for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID; dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID; dev->ep_in[ep].ifnum = 0; dev->ep_out[ep].ifnum = 0; + dev->ep_in[ep].dev = dev; + dev->ep_out[ep].dev = dev; } } @@ -472,6 +477,9 @@ void usb_ep_dump(USBDevice *dev) struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep) { struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev->ep_in : dev->ep_out; + if (ep == 0) { + return &dev->ep_ctl; + } assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT); assert(ep > 0 && ep <= USB_MAX_ENDPOINTS); return eps + ep - 1; @@ -177,6 +177,7 @@ struct USBEndpoint { uint8_t type; uint8_t ifnum; int max_packet_size; + USBDevice *dev; }; /* definition of a USB device */ @@ -204,6 +205,7 @@ struct USBDevice { int32_t setup_len; int32_t setup_index; + USBEndpoint ep_ctl; USBEndpoint ep_in[USB_MAX_ENDPOINTS]; USBEndpoint ep_out[USB_MAX_ENDPOINTS]; @@ -317,7 +319,7 @@ struct USBPacket { QEMUIOVector iov; int result; /* transfer length or USB_RET_* status code */ /* Internal use by the USB layer. */ - USBDevice *owner; + USBEndpoint *owner; }; void usb_packet_init(USBPacket *p); |