]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/usb/core/message.c
usb: allow drivers to use allocated bandwidth until unbound
[linux-imx.git] / drivers / usb / core / message.c
index fd4c36ea5e4688971afc9c2f32e3668429d0ae63..844683e503830485147910ff16ca035a90194d27 100644 (file)
@@ -1724,6 +1724,15 @@ free_interfaces:
        if (ret)
                goto free_interfaces;
 
+       /* if it's already configured, clear out old state first.
+        * getting rid of old interfaces means unbinding their drivers.
+        */
+       if (dev->state != USB_STATE_ADDRESS)
+               usb_disable_device(dev, 1);     /* Skip ep0 */
+
+       /* Get rid of pending async Set-Config requests for this device */
+       cancel_async_set_config(dev);
+
        /* Make sure we have bandwidth (and available HCD resources) for this
         * configuration.  Remove endpoints from the schedule if we're dropping
         * this configuration to set configuration 0.  After this point, the
@@ -1733,20 +1742,11 @@ free_interfaces:
        mutex_lock(&hcd->bandwidth_mutex);
        ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
        if (ret < 0) {
-               usb_autosuspend_device(dev);
                mutex_unlock(&hcd->bandwidth_mutex);
+               usb_autosuspend_device(dev);
                goto free_interfaces;
        }
 
-       /* if it's already configured, clear out old state first.
-        * getting rid of old interfaces means unbinding their drivers.
-        */
-       if (dev->state != USB_STATE_ADDRESS)
-               usb_disable_device(dev, 1);     /* Skip ep0 */
-
-       /* Get rid of pending async Set-Config requests for this device */
-       cancel_async_set_config(dev);
-
        ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                              USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
                              NULL, 0, USB_CTRL_SET_TIMEOUT);
@@ -1761,8 +1761,8 @@ free_interfaces:
        if (!cp) {
                usb_set_device_state(dev, USB_STATE_ADDRESS);
                usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
-               usb_autosuspend_device(dev);
                mutex_unlock(&hcd->bandwidth_mutex);
+               usb_autosuspend_device(dev);
                goto free_interfaces;
        }
        mutex_unlock(&hcd->bandwidth_mutex);