[RFC 2/8] USB: Ignore xHCI Reset Device status.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A device may need to be reset several times during enumeration, and this
causes a disconnect between the USB core's device state and the xHC's
device state.

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.

The problem is that the xHC was sent a Reset Device command after the
first port reset.  At that point, it thinks the device is in the Default
state.  The failed Set Address commands do not move the device from the
Default state.  On the second port reset, the Reset Device command is
issued again.  Since the xHC thinks device is already in the Default
state, it will reject the second Reset Device command.  This will cause
the port reset to fail until the device is logically disconnected.

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@xxxxxxxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
 drivers/usb/core/hub.c |   13 +++++--------
 1 files 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:
-- 
1.7.9

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux