----- 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

Reply via email to