On Thu, 1 Nov 2012, Sarah Sharp wrote:

> On Wed, Oct 31, 2012 at 03:54:49PM -0400, Alan Stern wrote:
> > +   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);
> 
> usb_disable_interface() will set the udev->ep_out and udev->ep_in array
> entries to NULL.  The bandwidth functions need those arrays to figure
> out which entries to disable.

You're right.  I should have realized that.  :-(

> Is there a particular reason why you wanted to call
> usb_disable_interface() before calling usb_hcd_alloc_bandwidth()?

Sheer oversight.  Some days I am dumber than others...

> And I do agree that this patch is much cleaner than my patch.

Okay, Matthias, here's an updated version of that patch.  The only 
difference is that it puts the usb_hcd_alloc_bandwidth() call _before_ 
the usb_disable_interface() calls.

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.
+                */
+               usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+               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;
+       }
+
+       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