lkml.org 
[lkml]   [2013]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 007/128] USB: Ignore xHCI Reset Device status.
    3.2-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Sarah Sharp <sarah.a.sharp@linux.intel.com>

    commit 8b8132bc3d1cc3d4c0687e4d638a482fa920d98a upstream.

    When the USB core finishes reseting a USB device, the xHCI driver sends
    a Reset Device command to the host. The xHC then updates its internal
    representation of the USB device to the 'Default' device state. If the
    device was already in the Default state, the xHC will complete the
    command with an error status.

    If a device needs to be reset several times during enumeration, the
    second reset will always fail because of the xHCI Reset Device command.
    This can cause issues during enumeration.

    For example, usb_reset_and_verify_device calls into hub_port_init in a
    loop. Say that on the first call into hub_port_init, the device is
    successfully reset, but doesn't respond to several set address control
    transfers. Then the port will be disabled, but the udev will remain in
    tact. usb_reset_and_verify_device will call into hub_port_init again.

    On the second call into hub_port_init, the device will be reset, and the
    xHCI driver will issue a Reset Device command. This command will fail
    (because the device is already in the Default state), and
    usb_reset_and_verify_device will fail. The port will be disabled, and
    the device won't be able to enumerate.

    Fix this by ignoring the return value of the HCD reset_device callback.

    This commit should be backported to kernels as old as 3.2, that contain
    the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
    warm reset logic".

    Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
    Acked-by: Alan Stern <stern@rowland.harvard.edu>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/usb/core/hub.c | 13 +++++--------
    1 file changed, 5 insertions(+), 8 deletions(-)

    diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
    index 7f8f10e..3bc50fc 100644
    --- a/drivers/usb/core/hub.c
    +++ b/drivers/usb/core/hub.c
    @@ -2565,14 +2565,11 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1,
    msleep(10 + 40);
    update_devnum(udev, 0);
    hcd = bus_to_hcd(udev->bus);
    - if (hcd->driver->reset_device) {
    - *status = hcd->driver->reset_device(hcd, udev);
    - if (*status < 0) {
    - dev_err(&udev->dev, "Cannot reset "
    - "HCD device state\n");
    - break;
    - }
    - }
    + /* The xHC may think the device is already reset,
    + * so ignore the status.
    + */
    + if (hcd->driver->reset_device)
    + hcd->driver->reset_device(hcd, udev);
    }
    /* FALL THROUGH */
    case -ENOTCONN:



    \
     
     \ /
      Last update: 2013-02-03 17:21    [W:4.248 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site