On Fri, 26 Oct 2012, Sarah Sharp wrote:

> On Fri, Oct 26, 2012 at 03:01:32PM -0700, Sarah Sharp wrote:
> > The USB core isn't dropping the endpoints before it calls
> > xhci_check_bandwidth.  I remember running into this bug a while back,
> > and I even started on a fix, but then couldn't reproduce the problem.
> > I found the branch with the old fix on it, but it still needs a bit of
> > work.  I'll send you a patch on Monday.
> 
> Matthias, can you try the attached patch?  You should be able to echo 1
> to the configuration file after this is applied.

Matthias, here's a different patch to fix the same bug.  Can you try it
out in place of Sarah's patch?

Alan Stern



Index: usb-3.7/drivers/usb/core/message.c
===================================================================
--- usb-3.7.orig/drivers/usb/core/message.c
+++ usb-3.7/drivers/usb/core/message.c
@@ -1806,29 +1806,8 @@ free_interfaces:
                goto free_interfaces;
        }
 
-       ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                             USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
-                             NULL, 0, USB_CTRL_SET_TIMEOUT);
-       if (ret < 0) {
-               /* All the old state is gone, so what else can we do?
-                * The device is probably useless now anyway.
-                */
-               cp = NULL;
-       }
-
-       dev->actconfig = cp;
-       if (!cp) {
-               usb_set_device_state(dev, USB_STATE_ADDRESS);
-               usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
-               /* Leave LPM disabled while the device is unconfigured. */
-               mutex_unlock(hcd->bandwidth_mutex);
-               usb_autosuspend_device(dev);
-               goto free_interfaces;
-       }
-       mutex_unlock(hcd->bandwidth_mutex);
-       usb_set_device_state(dev, USB_STATE_CONFIGURED);
-
-       /* Initialize the new interface structures and the
+       /*
+        * Initialize the new interface structures and the
         * hc/hcd/usbcore interface/endpoint state.
         */
        for (i = 0; i < nintf; ++i) {
@@ -1872,6 +1851,35 @@ free_interfaces:
        }
        kfree(new_interfaces);
 
+       ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+                             USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
+                             NULL, 0, USB_CTRL_SET_TIMEOUT);
+       if (ret < 0 && cp) {
+               /*
+                * All the old state is gone, so what else can we do?
+                * The device is probably useless now anyway.
+                */
+               for (i = 0; i < nintf; ++i) {
+                       usb_disable_interface(dev, cp->interface[i], true);
+                       put_device(&cp->interface[i]->dev);
+                       cp->interface[i] = NULL;
+               }
+               cp = NULL;
+               usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+       }
+
+       dev->actconfig = cp;
+       mutex_unlock(hcd->bandwidth_mutex);
+
+       if (!cp) {
+               usb_set_device_state(dev, USB_STATE_ADDRESS);
+
+               /* Leave LPM disabled while the device is unconfigured. */
+               usb_autosuspend_device(dev);
+               return ret;
+       }
+       usb_set_device_state(dev, USB_STATE_CONFIGURED);
+
        if (cp->string == NULL &&
                        !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
                cp->string = usb_cache_string(dev, cp->desc.iConfiguration);

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to