From f09424e39f22ba2f245d0db93c2daa540bc1d04d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 23 Jun 2011 12:41:56 -0300 Subject: [RHEL6 qemu-kvm PATCH 081/115] usb-linux: walk async urb list in cancel RH-Author: Gerd Hoffmann Message-id: <1308832951-8995-81-git-send-email-kraxel@redhat.com> Patchwork-id: 28407 O-Subject: [RHEL-6.2 kvm PATCH 080/115] usb-linux: walk async urb list in cancel Bugzilla: 561414 632299 645351 711354 RH-Acked-by: Hans de Goede RH-Acked-by: Jes Sorensen 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 (cherry picked from commit 227ebeb5353681b206a74db44530e60a46c24275) --- usb-linux.c | 28 +++++++++++++++++----------- 1 files changed, 17 insertions(+), 11 deletions(-) Signed-off-by: Eduardo Habkost --- usb-linux.c | 28 +++++++++++++++++----------- 1 files changed, 17 insertions(+), 11 deletions(-) diff --git a/usb-linux.c b/usb-linux.c index f3a0344..5ea0b79 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -314,19 +314,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); + } } } @@ -692,7 +698,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; } @@ -823,7 +829,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; } -- 1.7.3.2