Commit fa04f891 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: fix usb-storage self-deadlock

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.
parent e4a93f13
...@@ -1001,8 +1001,10 @@ int usb_reset_configuration(struct usb_device *dev) ...@@ -1001,8 +1001,10 @@ int usb_reset_configuration(struct usb_device *dev)
int i, retval; int i, retval;
struct usb_host_config *config; struct usb_host_config *config;
/* dev->serialize guards all config changes */ /* caller must own dev->serialize (config won't change)
down(&dev->serialize); * and the usb bus readlock (so driver bindings are stable);
* so calls during probe() are fine
*/
for (i = 1; i < 16; ++i) { for (i = 1; i < 16; ++i) {
usb_disable_endpoint(dev, i); usb_disable_endpoint(dev, i);
...@@ -1016,7 +1018,7 @@ int usb_reset_configuration(struct usb_device *dev) ...@@ -1016,7 +1018,7 @@ int usb_reset_configuration(struct usb_device *dev)
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
if (retval < 0) { if (retval < 0) {
dev->state = USB_STATE_ADDRESS; dev->state = USB_STATE_ADDRESS;
goto done; return retval;
} }
dev->toggle[0] = dev->toggle[1] = 0; dev->toggle[0] = dev->toggle[1] = 0;
...@@ -1029,9 +1031,7 @@ int usb_reset_configuration(struct usb_device *dev) ...@@ -1029,9 +1031,7 @@ int usb_reset_configuration(struct usb_device *dev)
intf->act_altsetting = 0; intf->act_altsetting = 0;
usb_enable_interface(dev, intf); usb_enable_interface(dev, intf);
} }
done: return 0;
up(&dev->serialize);
return (retval < 0) ? retval : 0;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment