----- Original Message -----
> From: [email protected]
> To: [email protected], [email protected], [email protected],
> "sarah a sharp"
> <[email protected]>, [email protected]
> Cc: [email protected]
> Sent: Wednesday, January 9, 2013 4:48:48 AM
> Subject: FAILED: patch "[PATCH] USB: fix endpoint-disabling for failed config
> changes" failed to apply to 3.0-stable
> tree
>
>
> The patch below does not apply to the 3.0-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git
> commit
> id to <[email protected]>.
I'll working on this too.
>
> thanks,
>
> greg k-h
>
> ------------------ original commit in Linus's tree ------------------
>
> From 36caff5d795429c572443894e8789c2150dd796b Mon Sep 17 00:00:00
> 2001
> From: Alan Stern <[email protected]>
> Date: Wed, 7 Nov 2012 10:31:30 -0500
> Subject: [PATCH] USB: fix endpoint-disabling for failed config
> changes
>
> This patch (as1631) fixes a bug that shows up when a config change
> fails for a device under an xHCI controller. The controller needs to
> be told to disable the endpoints that have been enabled for the new
> config. The existing code does this, but before storing the
> information about which endpoints were enabled! As a result, any
> second attempt to install the new config is doomed to fail because
> xhci-hcd will refuse to enable an endpoint that is already enabled.
>
> The patch optimistically initializes the new endpoints' device
> structures before asking the device to switch to the new config. If
> the request fails then the endpoint information is already stored, so
> we can use usb_hcd_alloc_bandwidth() to disable the endpoints with no
> trouble. The rest of the error path is slightly more complex now; we
> have to disable the new interfaces and call put_device() rather than
> simply deallocating them.
>
> Signed-off-by: Alan Stern <[email protected]>
> Reported-and-tested-by: Matthias Schniedermeyer <[email protected]>
> CC: Sarah Sharp <[email protected]>
> CC: <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
> index 1ed5afd..a557658 100644
> --- a/drivers/usb/core/message.c
> +++ b/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 stable" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html