diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2012-07-03 10:11:21 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2012-07-09 11:59:54 +0200 |
commit | 19deaa089cb874912767bc6071f3b7372d3ff961 (patch) | |
tree | 7620b7aa28c64623ced9885826353f858725eb29 /hw | |
parent | adae502c0ae4572ef08f71cb5b5ed5a8e90299fe (diff) |
usb: split endpoint init and reset
Create a new usb_ep_reset() function to reset endpoint state, without
re-initialiting the queues, so we don't unlink in-flight packets just
because usb-host has to re-parse the descriptor tables.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/usb.h | 1 | ||||
-rw-r--r-- | hw/usb/core.c | 13 | ||||
-rw-r--r-- | hw/usb/host-linux.c | 5 |
3 files changed, 15 insertions, 4 deletions
@@ -363,6 +363,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p); void usb_cancel_packet(USBPacket * p); void usb_ep_init(USBDevice *dev); +void usb_ep_reset(USBDevice *dev); void usb_ep_dump(USBDevice *dev); struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep); uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep); diff --git a/hw/usb/core.c b/hw/usb/core.c index 0e02da7601..fe15be064f 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -550,7 +550,7 @@ void usb_packet_cleanup(USBPacket *p) qemu_iovec_destroy(&p->iov); } -void usb_ep_init(USBDevice *dev) +void usb_ep_reset(USBDevice *dev) { int ep; @@ -559,7 +559,6 @@ void usb_ep_init(USBDevice *dev) dev->ep_ctl.ifnum = 0; dev->ep_ctl.dev = dev; dev->ep_ctl.pipeline = false; - QTAILQ_INIT(&dev->ep_ctl.queue); for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { dev->ep_in[ep].nr = ep + 1; dev->ep_out[ep].nr = ep + 1; @@ -573,6 +572,16 @@ void usb_ep_init(USBDevice *dev) dev->ep_out[ep].dev = dev; dev->ep_in[ep].pipeline = false; dev->ep_out[ep].pipeline = false; + } +} + +void usb_ep_init(USBDevice *dev) +{ + int ep; + + usb_ep_reset(dev); + QTAILQ_INIT(&dev->ep_ctl.queue); + for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { QTAILQ_INIT(&dev->ep_in[ep].queue); QTAILQ_INIT(&dev->ep_out[ep].queue); } diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c index 5479fb5987..9ba892505a 100644 --- a/hw/usb/host-linux.c +++ b/hw/usb/host-linux.c @@ -1136,7 +1136,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) USBDescriptor *d; bool active = false; - usb_ep_init(&s->dev); + usb_ep_reset(&s->dev); for (i = 0;; i += d->bLength) { if (i+2 >= s->descr_len) { @@ -1239,7 +1239,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) return 0; error: - usb_ep_init(&s->dev); + usb_ep_reset(&s->dev); return 1; } @@ -1326,6 +1326,7 @@ static int usb_host_open(USBHostDevice *dev, int bus_num, goto fail; } + usb_ep_init(&dev->dev); ret = usb_linux_update_endp_table(dev); if (ret) { goto fail; |