Hi list! I'm running into a USB3.0 regression on ipq806x hardware.
Consider one physical USB port as one linux-4.9 xHCI HC. It comes with
two USB busses with one logical USB port each. One high-speed port and
one superspeed port port.
] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
] ehci-platform: EHCI generic platform driver
] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
] ohci-platform: OHCI generic platform driver
] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1
] xhci-hcd xhci-hcd.0.auto: hcc params 0x0228f065 hci version 0x100
quirks 0x00010010
] xhci-hcd xhci-hcd.0.auto: irq 168, io mem 0x11000000
] hub 1-0:1.0: USB hub found
] hub 1-0:1.0: 1 port detected
] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
] usb usb2: We don't know the algorithms for LPM for this host,
disabling LPM.
] hub 2-0:1.0: USB hub found
] hub 2-0:1.0: 1 port detected
] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 3
] xhci-hcd xhci-hcd.1.auto: hcc params 0x0228f065 hci version 0x100
quirks 0x00010010
] xhci-hcd xhci-hcd.1.auto: irq 169, io mem 0x10000000
] hub 3-0:1.0: USB hub found
] hub 3-0:1.0: 1 port detected
] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 4
] usb usb4: We don't know the algorithms for LPM for this host,
disabling LPM.
] hub 4-0:1.0: USB hub found
] hub 4-0:1.0: 1 port detected
Everything is working just fine when I'm waiting for the host to have
finished starting up and then go on with inserting USB2.0 or USB3.0 devices.
] usb 4-1: new SuperSpeed USB device number 2 using xhci-hcd
The bug however:
Inserting a pendrive/thumbdrive first and next power on the host Linux
3.4.103, 4.4.49, 4.9.10 all would be detecting a high-speed and a
superspeed device at the same time (one for each logical USB port) and
would make the xHCI HC getting halted just 10 seconds later.
] usb 3-1: new high-speed USB device number 2 using xhci-hcd
] usb 4-1: new SuperSpeed USB device number 2 using xhci-hcd
+10s:
] xhci-hcd xhci-hcd.1.auto: xHCI host not responding to stop endpoint
command.
] xhci-hcd xhci-hcd.1.auto: Assuming host is dying, halting host.
] xhci-hcd xhci-hcd.1.auto: Host not halted after 16000 microseconds.
] xhci-hcd xhci-hcd.1.auto: Non-responsive xHCI host is not halting.
] xhci-hcd xhci-hcd.1.auto: Completing active URBs anyway.
] xhci-hcd xhci-hcd.1.auto: HC died; cleaning up
] usb usb3-port1: couldn't allocate usb_device
] usb 4-1: USB disconnect, device number 2
Having enabled USB_DEBUG and xhci_dbg() from the drivers/usb/Kconfig and
drivers/usb/Makefile files I was able to find three working "WORKAROUNDS".
1. Increase HUB_ROOT_RESET_TIME from 50 to "more than 130" in core/hub.c
--- drivers/usb/core/hub.c.orig 2017-03-05 14:26:42.248122743 +0100
+++ drivers/usb/core/hub.c 2017-03-05 14:26:50.072122785 +0100
@@ -2544,7 +2544,7 @@
#define SET_CONFIG_TRIES (2 * (use_both_schemes + 1))
#define USE_NEW_SCHEME(i) ((i) / 2 == (int)old_scheme_first)
-#define HUB_ROOT_RESET_TIME 50 /* times are in msec */
+#define HUB_ROOT_RESET_TIME 150 /* times are in msec */
#define HUB_SHORT_RESET_TIME 10
#define HUB_BH_RESET_TIME 50
#define HUB_LONG_RESET_TIME 200
2. In core/hub.c static int hub_port_wait_reset()
--- drivers/usb/core/hub.c.orig 2017-03-05 14:26:42.248122743 +0100
+++ drivers/usb/core/hub.c 2017-03-05 14:28:29.912123314 +0100
@@ -2603,7 +2603,7 @@
return ret;
/* The port state is unknown until the reset completes. */
- if (!(portstatus & USB_PORT_STAT_RESET))
+ if (!(portstatus & USB_PORT_STAT_RESET) && !(portstatus
& USB_PORT_STAT_HIGH_SPEED))
break;
/* switch to the long delay after two short delay
failures */
3. Follow the Netgear approach in their GPL'ed 3.4.103 kernel and send
the root_hub in another reset() during init() which would come back with
-ENOTCONN.
--- drivers/usb/core/hub.c.orig 2017-03-05 14:26:42.248122743 +0100
+++ drivers/usb/core/hub.c 2017-03-05 14:35:16.896125472 +0100
@@ -4269,6 +4269,13 @@
retval = hub_port_reset(hub, port1, udev, delay, false);
if (retval < 0) /* error or disconnect */
goto fail;
+
+ if (udev->speed != USB_SPEED_SUPER) {
+ retval = hub_port_reset(hub, port1, udev, delay, false);
+ if (retval < 0)
+ goto fail;
+ }
+
/* success, speed is known */
retval = -ENODEV;
All these 3 above fixes are fixing the observed behavior, that is the
thumbdrive/pendrive no longer gets recognized as high-speed device and
superspeed device but as a superspeed device only. As a result the HC is
not halted and it just works.
Plans are to get a working fix into Linux-next however I'd need someone
to let me know how bad my approaches are and someone to guide me to a
better fix/workaround.
Is one of the above three fixes considered "ok"?
Am I looking at the right places?
How to proceed?
Please find all the available debug including xhci_dbg() here:
withbug-inserting-after-booting.txt : http://cxg.de/_bfd3bb.htm
withbug-inserting-prior-to-host-poweron.txt : http://cxg.de/_41ae6d.htm
fix1-inserting-after-booting.txt : http://cxg.de/_d5d5b8.htm
fix1-inserting-prior-to-host-poweron.txt : http://cxg.de/_10b096.htm
fix2-inserting-after-booting.txt : http://cxg.de/_7da6e0.htm
fix2-inserting-prior-to-host-poweron.txt http://cxg.de/_b6cfbd.htm
fix3-inserting-after-booting.txt : http://cxg.de/_209271.htm
fix3-inserting-prior-to-host-poweron.txt : http://cxg.de/_1092b8.htm
Thank you
Thomas
--
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