Greg KH wrote:

IMO this change would be worth considering for 2.5 even at this
late date, even though it'd break some TBD number of drivers.


What would break?  At the worse, drivers would just spit back a bunch of
"warnings" about urbs that were not in flight attempting to be
disconnected, right?

What would break is TBD, as is how it'd break. I've seen oopses come from changes that are more innocuous.


Because the upside of that change would be that on 2.5, USB
device driver disconnect() bugs would be less _able_ to break
things in usbcore or elsewhere in the system.  And there are
a lot of driver disconnect() bugs that likely won't get fixed
without some fundamental change like that.


I agree, I'd like to at least test this kind of change out, and
hopefully add it.  It is the "right" thing to do :)

OK, then for anyone who wants to test out such a change, try this (untested) patch to see what breaks. It doesn't update the API docs, or the other cases where driver disconnect() methods are called, or any of the disconnect() methods, but it should be a start.

- Dave

--- 1.126/drivers/usb/core/usb.c        Thu Jun 12 07:28:01 2003
+++ edited/drivers/usb/core/usb.c       Fri Jun 27 16:57:30 2003
@@ -890,6 +890,16 @@
                        usb_disconnect(child);
        }
 
+       /* deallocate hcd/hardware state ... and nuke all pending urbs */
+       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);
+               }
+       }
+
        /* disconnect() drivers from interfaces (a key side effect) */
        dev_dbg (&dev->dev, "unregistering interfaces\n");
        if (dev->actconfig) {
@@ -899,16 +909,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);
                }
        }
 

Reply via email to