Patchwork [3.5.y.z,extended,stable] Patch "USB: Handle warm reset failure on empty port." has been added to staging queue

login
register
mail settings
Submitter Herton Ronaldo Krzesinski
Date Jan. 23, 2013, 4:41 a.m.
Message ID <1358916086-21830-1-git-send-email-herton.krzesinski@canonical.com>
Download mbox | patch
Permalink /patch/214736/
State New
Headers show

Comments

Herton Ronaldo Krzesinski - Jan. 23, 2013, 4:41 a.m.
This is a note to let you know that I have just added a patch titled

    USB: Handle warm reset failure on empty port.

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Herton

------

From 148e42f3b68f8b704d8d57306c2f0a6b0c0f1067 Mon Sep 17 00:00:00 2001
From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Date: Wed, 14 Nov 2012 17:58:04 -0800
Subject: [PATCH] USB: Handle warm reset failure on empty port.

commit 65bdac5effd15d6af619b3b7218627ef4d84ed6a upstream.

An empty port can transition to either Inactive or Compliance Mode if a
newly connected USB 3.0 device fails to link train.  In that case, we
issue a warm reset.  Some devices, such as John's Roseweil eusb3
enclosure, slip back into Compliance Mode after the warm reset.

The current warm reset code does not check for device connect status on
warm reset completion, and it incorrectly reports the warm reset
succeeded.  This causes the USB core to attempt to send a Set Address
control transfer to a port in Compliance Mode, which will always fail.

Make hub_port_wait_reset check the current connect status and link state
after the warm reset completes.  Return a failure status if the device
is disconnected or the link state is Compliance Mode or SS.Inactive.

Make hub_events disable the port if warm reset fails.  This will disable
the port, and then bring it back into the RxDetect state.  Make the USB
core ignore the connect change until the device reconnects.

Note that this patch does NOT handle connected devices slipping into the
Inactive state very well.  This is a concern, because devices can go
into the Inactive state on U1/U2 exit failure.  However, the fix for
that case is too large for stable, so it will be submitted in a separate
patch.

This patch should be backported to kernels as old as 3.2, contain the
commit ID 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>
Reported-by: John Covici <covici@ccs.covici.com>
Signed-off-by: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
---
 drivers/usb/core/hub.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--
1.7.9.5

Patch

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 89fc61b..2532bdc 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2488,6 +2488,11 @@  static int hub_port_wait_reset(struct usb_hub *hub, int port1,
 				return 0;
 			}
 		} else {
+			if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+					hub_port_warm_reset_required(hub,
+						portstatus))
+				return -ENOTCONN;
+
 			return 0;
 		}

@@ -4492,9 +4497,14 @@  static void hub_events(void)
 			 * SS.Inactive state.
 			 */
 			if (hub_port_warm_reset_required(hub, portstatus)) {
+				int status;
+
 				dev_dbg(hub_dev, "warm reset port %d\n", i);
-				hub_port_reset(hub, i, NULL,
+				status = hub_port_reset(hub, i, NULL,
 						HUB_BH_RESET_TIME, true);
+				if (status < 0)
+					hub_port_disable(hub, i, 1);
+				connect_change = 0;
 			}

 			if (connect_change)