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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html