On 29.12.2021 15:07, Mathias Nyman wrote:
On 23.12.2021 15.26, Wohl, Tobias wrote:
Hi all,
Hi
I noticed a strange beavior when unplugging USB3 sticks. I'm using a zynq ultrascale + platform and the problem
still occured when testing with 5.16-rc6 kernel.
Does older kernels have the same issue?
Yes. I have also checked with 5.4 and 5.10 kernel. Both showed the issue.
In some cases when unplugging the USB3 stick it takes aroung 10s until the disconnect is detected.
Moreover after unplugging the usb driver ends up in a endless loop of trying to perform "warm resets".
After replugging the USB stick, the loop stops and everything seems to be fine again. This only happens
with USB3 sticks.
There's been a couple reports like this.
I saw you noticed the patch in usb-next that solves this by giving the link some time to
notice the disconnect, and automatically go to RxDetect from inactive state, thus avoiding
unnecessary warm reset of disconnected devices.
Seems it works for some cases, but not all.
The kernel log looks as follows:
[ 1831.312566] handle_port_status: xhci-hcd xhci-hcd.0.auto: Port change event, 2-1, id 2, portsc: 0x4012c1
[ 1831.312583] handle_port_status: xhci-hcd xhci-hcd.0.auto: handle_port_status: starting port polling.
[ 1831.312853] hub_event: hub 2-0:1.0: state 7 ports 1 chg 0000 evt 0002
[ 1831.312874] xhci_hub_control: xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read: 0x4012c1, return 0x4002c1
[ 1831.312899] port_event: usb usb2-port1: link state change
[ 1831.312912] xhci_clear_port_change_bit: xhci-hcd xhci-hcd.0.auto: clear port1 link state change, portsc: 0x12c1
12c1 = Connected, Disabled, Link:Inactive
[ 1831.312929] port_event: usb usb2-port1: do warm reset
...
[ 1831.379730] xhci_hub_control: xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read: 0x12b1, return 0x2b1
12b1 = Connected, Disabled, reset asserted, Link: Rx Detect. (Link value is unreliable while reset is asserted)
...
[ 1831.447759] hub_port_wait_reset: usb usb2-port1: not warm reset yet, waiting 200ms
[ 1831.655731] xhci_hub_control: xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read: 0x12f1, return 0x2f1
12f1 = Connected, Disabled, reset asserted, Link: Polling. (Link value is unreliable while reset is asserted)
[ 1831.863726] xhci_hub_control: xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read: 0x2812e1, return 0x3002e1
Connected, Disabled, Link: Polling, Warm reset change, reset changed
The odd thing here is that the "connected" bit remains set the whole time.
Other reports had a bit different symptoms after not detecting disconnect, such as reset asserted
bit being stuck forever.
In xhci specs 4.19.1.2 "USB3 root hub port" Figure 4-27 it shows that when link goes to
the Error "link:inactive" state it should drop the connected bit as well.
http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf
(four bits in the figure are Port Power(PP), Current Connect status (CCS), Port Enabled/Disabled (PED), and
Port Reset (PR). Those should be set to (1,0,0,0) once entering the Error "inactive" state.
No idea why CCS bit is still set for you?
Is the device connected to a USB-C port or a "A" port?
It is connected to a USB-C port.
Can there be some retimer/redriver mux or something else between port and xHCI that messes up disconnect
detection?
The only thing in between is a 2:1 mux and redriver IC
(https://www.ti.com/product/TUSB542) for signal conditioning and
flippable connector support.
I also found that when I boot the device with USB3 stick already
connected that the stick is not recognized properly and warm resets are
performed:
[ 1.804909] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[ 1.804920] xhci-hcd xhci-hcd.0.auto: new USB bus registered,
assigned bus number 2
[ 1.804933] xhci-hcd xhci-hcd.0.auto: Host supports USB 3.0 SuperSpeed
[ 1.804939] xhci-hcd xhci-hcd.0.auto: supports USB remote wakeup
[ 1.804945] xhci-hcd xhci-hcd.0.auto: // Turn on HC, cmd = 0x5.
[ 1.804951] xhci-hcd xhci-hcd.0.auto: Finished xhci_run for USB3 roothub
[ 1.805054] usb usb2: skipped 1 descriptor after endpoint
[ 1.805073] usb usb2: default language 0x0409
[ 1.805117] usb usb2: udev 1, busnum 2, minor = 128
[ 1.805125] usb usb2: New USB device found, idVendor=1d6b,
idProduct=0003, bcdDevice= 5.10
[ 1.805131] usb usb2: New USB device strings: Mfr=3, Product=2,
SerialNumber=1
[ 1.805136] usb usb2: Product: xHCI Host Controller
[ 1.805141] usb usb2: Manufacturer: Linux 5.10.81-arri-standard xhci-hcd
[ 1.805147] usb usb2: SerialNumber: xhci-hcd.0.auto
[ 1.805359] usb usb2: usb_probe_device
[ 1.805367] usb usb2: configuration #1 chosen from 1 choice
[ 1.805374] xHCI xhci_add_endpoint called for root hub
[ 1.805378] xHCI xhci_check_bandwidth called for root hub
[ 1.805406] usb usb2: adding 2-0:1.0 (config #1, interface 0)
[ 1.805478] hub 2-0:1.0: usb_probe_interface
[ 1.805485] hub 2-0:1.0: usb_probe_interface - got id
[ 1.805493] hub 2-0:1.0: USB hub found
[ 1.805517] hub 2-0:1.0: 1 port detected
[ 1.805523] hub 2-0:1.0: standalone hub
[ 1.805528] hub 2-0:1.0: no power switching (usb 1.0)
[ 1.805533] hub 2-0:1.0: individual port over-current protection
[ 1.805539] hub 2-0:1.0: TT requires at most 8 FS bit times (666 ns)
[ 1.805544] hub 2-0:1.0: power on to power good time: 100ms
[ 1.805574] hub 2-0:1.0: local power source is good
[ 1.805617] usb usb2-port1: peered to usb1-port1
[ 1.805626] hub 2-0:1.0: trying to enable port power on
non-switchable hub
[ 1.805638] xhci-hcd xhci-hcd.0.auto: set port power 2-1 ON, portsc:
0x2a0
[ 1.906768] xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read:
0x2a0, return 0x2a0
[ 1.906800] hub 2-0:1.0: state 7 ports 1 chg 0000 evt 0000
[ 1.906822] xhci-hcd xhci-hcd.0.auto: set port remote wake mask,
actual port 2-1 status = 0xe0002a0
[ 1.906848] hub 2-0:1.0: hub_suspend
[ 1.906873] usb usb2: bus auto-suspend, wakeup 1
[ 3.640888] xhci-hcd xhci-hcd.0.auto: Port change event, 2-1, id 2,
portsc: 0xa4002c0
[ 3.640895] xhci-hcd xhci-hcd.0.auto: resume root hub
[ 3.640910] xhci-hcd xhci-hcd.0.auto: handle_port_status: starting
port polling.
[ 3.640930] usb usb2: usb wakeup-resume
[ 3.640941] usb usb2: usb auto-resume
[ 3.641954] hub 2-0:1.0: hub_resume
[ 3.641967] xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read:
0x4002c0, return 0x4002c0
[ 3.642012] hub 2-0:1.0: state 7 ports 1 chg 0000 evt 0002
[ 3.642025] xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read:
0x4002c0, return 0x4002c0
[ 3.642046] usb usb2-port1: link state change
[ 3.642057] xhci-hcd xhci-hcd.0.auto: clear port1 link state change,
portsc: 0x2c0
[ 3.642076] usb usb2-port1: do warm reset, port only
[ 3.698663] xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read:
0x2b0, return 0x2b0
[ 3.698695] usb usb2-port1: not warm reset yet, waiting 50ms
[ 3.758716] xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read:
0x2f0, return 0x2f0
[ 3.758787] usb usb2-port1: not warm reset yet, waiting 200ms
[ 3.966668] xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read:
0x2f0, return 0x2f0
[ 3.966705] usb usb2-port1: not warm reset yet, waiting 200ms
[ 4.382712] usb usb2-port1: not warm reset yet, waiting 200ms
[ 4.382723] xhci-hcd xhci-hcd.0.auto: clear port1 reset change,
portsc: 0x802e0
[ 4.382747] xhci-hcd xhci-hcd.0.auto: clear port1 warm(BH) reset
change, portsc: 0x2e0
[ 4.382770] xhci-hcd xhci-hcd.0.auto: clear port1 link state change,
portsc: 0x2e0
[ 4.382794] xhci-hcd xhci-hcd.0.auto: Get port status 2-1 read:
0x2e0, return 0x2e0
...
Here it seems to be the other way around. The CCS bit remains 0.
Thanks
Tobias