]> git.hungrycats.org Git - linux/commitdiff
[PATCH] USB: fix usb-storage self-deadlock
authorDavid Brownell <david-b@pacbell.net>
Thu, 23 Oct 2003 10:28:44 +0000 (03:28 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Thu, 23 Oct 2003 10:28:44 +0000 (03:28 -0700)
This fixes a problem that showed in usb-storage (osdl bugme 1310)
and could have shown in other drivers that used usb_reset_device()
when they already held dev->serialize:  a self-deadlock with some
devices.

There are some drivers that should likely change so that they grab
this lock themselves, since they don't call this during probe()
when the lock is already held.  The lock protects against config
changes by other tasks, which is currently quite rate.

drivers/usb/core/message.c

index 374527d88b557bd4af6e3201b3e440b239dc8007..f97aa07084cde02b18b84da28d4cf820630d7559 100644 (file)
@@ -1001,8 +1001,10 @@ int usb_reset_configuration(struct usb_device *dev)
        int                     i, retval;
        struct usb_host_config  *config;
 
-       /* dev->serialize guards all config changes */
-       down(&dev->serialize);
+       /* caller must own dev->serialize (config won't change)
+        * and the usb bus readlock (so driver bindings are stable);
+        * so calls during probe() are fine
+        */
 
        for (i = 1; i < 16; ++i) {
                usb_disable_endpoint(dev, i);
@@ -1016,7 +1018,7 @@ int usb_reset_configuration(struct usb_device *dev)
                        NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
        if (retval < 0) {
                dev->state = USB_STATE_ADDRESS;
-               goto done;
+               return retval;
        }
 
        dev->toggle[0] = dev->toggle[1] = 0;
@@ -1029,9 +1031,7 @@ int usb_reset_configuration(struct usb_device *dev)
                intf->act_altsetting = 0;
                usb_enable_interface(dev, intf);
        }
-done:
-       up(&dev->serialize);
-       return (retval < 0) ? retval : 0;
+       return 0;
 }
 
 /**