ChangeSet 1.1455.1.19, 2003/07/15 14:32:34-07:00, [EMAIL PROTECTED]

[PATCH] USB: flush all in-flight urbs _before_ disconnect() is called.

This solves the module unload problem for some usb-serial drivers
(like visor.c and ftdi_sio.c), and makes usb drivers much simpler.


 drivers/usb/core/usb.c |   33 +++++++++++++++++++++++----------
 1 files changed, 23 insertions(+), 10 deletions(-)


diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c    Thu Jul 17 17:05:15 2003
+++ b/drivers/usb/core/usb.c    Thu Jul 17 17:05:15 2003
@@ -80,6 +80,23 @@
 
 static int usb_generic_driver_data;
 
+/* deallocate hcd/hardware state ... and nuke all pending urbs */
+static void nuke_urbs(struct usb_device *dev)
+{
+       void (*disable)(struct usb_device *, int);
+       int i;
+
+       if (!dev || !dev->bus || !dev->bus->op || !dev->bus->op->disable)
+               return;
+       dbg("nuking urbs assigned to %s", dev->dev.bus_id);
+
+       disable = dev->bus->op->disable;
+       for (i = 0; i < 15; i++) {
+               disable(dev, i);
+               disable(dev, USB_DIR_IN | i);
+       }
+}
+
 /* needs to be called with BKL held */
 int usb_device_probe(struct device *dev)
 {
@@ -116,6 +133,9 @@
 
        down(&driver->serialize);
 
+       /* release all urbs for this device */
+       nuke_urbs(interface_to_usbdev(intf));
+
        if (intf->driver && intf->driver->disconnect)
                intf->driver->disconnect(intf);
 
@@ -896,6 +916,9 @@
                        usb_disconnect(child);
        }
 
+       /* deallocate hcd/hardware state ... and nuke all pending urbs */
+       nuke_urbs(dev);
+
        /* disconnect() drivers from interfaces (a key side effect) */
        dev_dbg (&dev->dev, "unregistering interfaces\n");
        if (dev->actconfig) {
@@ -905,16 +928,6 @@
                        /* remove this interface */
                        interface = &dev->actconfig->interface[i];
                        device_unregister(&interface->dev);
-               }
-       }
-
-       /* deallocate hcd/hardware state */
-       if (ops->disable) {
-               void    (*disable)(struct usb_device *, int) = ops->disable;
-
-               for (i = 0; i < 15; i++) {
-                       disable (dev, i);
-                       disable (dev, USB_DIR_IN | i);
                }
        }
 



-------------------------------------------------------
This SF.net email is sponsored by: VM Ware
With VMware you can run multiple operating systems on a single machine.
WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines at the
same time. Free trial click here: http://www.vmware.com/wl/offer/345/0
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to