diff options
author | Dima Zavin <dima@android.com> | 2011-07-07 17:55:44 -0700 |
---|---|---|
committer | Dima Zavin <dima@android.com> | 2011-07-07 17:55:44 -0700 |
commit | 814cdea670616252e4cdf297a07b02ce59698bf1 (patch) | |
tree | c4a5665995e813c252b07f1e863166059bfb5bcb /drivers/usb/core/message.c | |
parent | 487ffb052891a552fecf865ad4b24bbe7945a413 (diff) | |
parent | fe0d42203cb5616eeff68b14576a0f7e2dd56625 (diff) | |
download | kernel_samsung_espresso10-814cdea670616252e4cdf297a07b02ce59698bf1.zip kernel_samsung_espresso10-814cdea670616252e4cdf297a07b02ce59698bf1.tar.gz kernel_samsung_espresso10-814cdea670616252e4cdf297a07b02ce59698bf1.tar.bz2 |
Merge commit 'v3.0-rc6' into android-3.0
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r-- | drivers/usb/core/message.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5701e85..64c7ab4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1135,10 +1135,13 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. + * + * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; + struct usb_hcd *hcd = bus_to_hcd(dev->bus); /* getting rid of interfaces will disconnect * any drivers bound to them (a key side effect) @@ -1172,6 +1175,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, skip_ep0 ? "non-ep0" : "all"); + if (hcd->driver->check_bandwidth) { + /* First pass: Cancel URBs, leave endpoint pointers intact. */ + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, false); + usb_disable_endpoint(dev, i + USB_DIR_IN, false); + } + /* Remove endpoints from the host controller internal state */ + usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + /* Second pass: remove endpoint pointers */ + } for (i = skip_ep0; i < 16; ++i) { usb_disable_endpoint(dev, i, true); usb_disable_endpoint(dev, i + USB_DIR_IN, true); @@ -1727,6 +1740,7 @@ free_interfaces: /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ + mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1739,7 +1753,6 @@ free_interfaces: * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ - mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); |