Patchwork [11/18] usb-linux: walk async urb list in cancel

login
register
mail settings
Submitter Gerd Hoffmann
Date May 16, 2011, 7:56 p.m.
Message ID <1305575782-31766-12-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/95814/
State New
Headers show

Comments

Gerd Hoffmann - May 16, 2011, 7:56 p.m.
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>
---
 usb-linux.c |   28 +++++++++++++++++-----------
 1 files changed, 17 insertions(+), 11 deletions(-)

Patch

diff --git a/usb-linux.c b/usb-linux.c
index 3c5a248..b8f7705 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;
 }