summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2011-05-16 09:20:06 +0200
committerGerd Hoffmann <kraxel@redhat.com>2011-05-26 11:55:02 +0200
commit7e94052c9109c7cdc471ce9f7ba07d3b5adf7a7a (patch)
treec925cca7c80d852d1b728affd65c485b0021ee47
parentc77c9941c1a18b43599a47e4b94ba57562be268f (diff)
downloadqemu-7e94052c9109c7cdc471ce9f7ba07d3b5adf7a7a.tar.gz
qemu-7e94052c9109c7cdc471ce9f7ba07d3b5adf7a7a.tar.bz2
qemu-7e94052c9109c7cdc471ce9f7ba07d3b5adf7a7a.zip
usb-linux: walk async urb list in cancel
Lookup async urbs which are to be canceled using the linked list instead of the direct opaque pointer. There are two reasons we are doing that: First, to avoid the opaque poiner to the callback, which is needed for upcoming cleanups. Second, because we might need multiple urbs per request for highspeed support, so a single opaque pointer doesn't cut it any more anyway. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--usb-linux.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/usb-linux.c b/usb-linux.c
index 3213215eec..5e9c5e4135 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -315,19 +315,25 @@ static void async_complete(void *opaque)
}
}
-static void async_cancel(USBPacket *unused, void *opaque)
+static void async_cancel(USBPacket *p, void *opaque)
{
- AsyncURB *aurb = opaque;
- USBHostDevice *s = aurb->hdev;
+ USBHostDevice *s = opaque;
+ AsyncURB *aurb;
- DPRINTF("husb: async cancel. aurb %p\n", aurb);
+ QLIST_FOREACH(aurb, &s->aurbs, next) {
+ if (p != aurb->packet) {
+ continue;
+ }
- /* Mark it as dead (see async_complete above) */
- aurb->packet = NULL;
+ DPRINTF("husb: async cancel: packet %p, aurb %p\n", p, aurb);
- int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
- if (r < 0) {
- DPRINTF("husb: async. discard urb failed errno %d\n", errno);
+ /* Mark it as dead (see async_complete above) */
+ aurb->packet = NULL;
+
+ int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
+ if (r < 0) {
+ DPRINTF("husb: async. discard urb failed errno %d\n", errno);
+ }
}
}
@@ -696,7 +702,7 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
}
}
- usb_defer_packet(p, async_cancel, aurb);
+ usb_defer_packet(p, async_cancel, s);
return USB_RET_ASYNC;
}
@@ -828,7 +834,7 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
}
}
- usb_defer_packet(p, async_cancel, aurb);
+ usb_defer_packet(p, async_cancel, s);
return USB_RET_ASYNC;
}