Bug 213839 - XHCI 7 port usb hub does not work correctly
Summary: XHCI 7 port usb hub does not work correctly
Status: NEW
Alias: None
Product: Drivers
Classification: Unclassified
Component: USB (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Default virtual assignee for Drivers/USB
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-07-24 13:41 UTC by tomas m
Modified: 2022-01-01 19:53 UTC (History)
2 users (show)

See Also:
Kernel Version: 5.13.4
Subsystem:
Regression: No
Bisected commit-id:


Attachments
Plugged in under Windows, USB flash drive inserted into port on second hub (276.82 KB, application/vnd.tcpdump.pcap)
2021-12-31 16:32 UTC, Jonathan McDowell
Details
Plugged in under Linux, USB flash drive inserted into port on second hub (28.52 KB, application/x-pcapng)
2021-12-31 16:32 UTC, Jonathan McDowell
Details
dmesg, no usb autosuspend, hub working (4.96 KB, text/plain)
2022-01-01 10:37 UTC, Jonathan McDowell
Details
dmesg, usb autosuspend, usb_snoop, hub not working (6.74 KB, text/plain)
2022-01-01 10:38 UTC, Jonathan McDowell
Details
dmesg, usb autosuspend, 2 drives, working (8.31 KB, text/plain)
2022-01-01 10:39 UTC, Jonathan McDowell
Details
Mark child resume requests in hub->event_bits, not hub->change_bits (470 bytes, patch)
2022-01-01 16:26 UTC, Alan Stern
Details | Diff

Description tomas m 2021-07-24 13:41:17 UTC
I got an off brand 7-port usb 2.0 which internally has two ICs.

first IC connected to the host's usb port exposes 3 USB ports. its 4th usb port has a second identical IC connected which exposes 4 USB ports making it a total of 7 USB 2.0 ports available.

Bus 002 Device 065: ID 0a05:7211 Unknown Manufacturer hub
Bus 002 Device 064: ID 0a05:7211 Unknown Manufacturer hub

As they appear from lsusb

the problem is that the first chip works correctly (first 3 USB ports connected to it work). But as soon as I connect a usb device on any of the ports from the second chip. i get the following problems in dmesg:

[ 2215.717828] usb 2-1.1: new full-speed USB device number 29 using xhci_hcd
[ 2215.808680] usb 2-1.1: New USB device found, idVendor=0a05, idProduct=7211, bcdDevice= 1.00
[ 2215.808685] usb 2-1.1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 2215.808688] usb 2-1.1: Product: USB2.0 HUB
[ 2215.809333] hub 2-1.1:1.0: USB hub found
[ 2215.809426] hub 2-1.1:1.0: 4 ports detected
[ 2216.158062] usb 2-1.1: USB disconnect, device number 29
[ 2216.174608] usb 2-1.1-port3: attempt power cycle
[ 2216.561173] usb 2-1.1: new full-speed USB device number 34 using xhci_hcd
[ 2216.652346] usb 2-1.1: New USB device found, idVendor=0a05, idProduct=7211, bcdDevice= 1.00
[ 2216.652359] usb 2-1.1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 2216.652365] usb 2-1.1: Product: USB2.0 HUB
[ 2216.654327] hub 2-1.1:1.0: USB hub found
[ 2216.654480] hub 2-1.1:1.0: 4 ports detected
[ 2217.001529] usb 2-1.1: USB disconnect, device number 34
[ 2217.017975] usb 2-1.1-port3: attempt power cycle
[ 2217.404536] usb 2-1.1: new full-speed USB device number 39 using xhci_hcd
[ 2217.495411] usb 2-1.1: New USB device found, idVendor=0a05, idProduct=7211, bcdDevice= 1.00
[ 2217.495417] usb 2-1.1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 2217.495419] usb 2-1.1: Product: USB2.0 HUB
[ 2217.496120] hub 2-1.1:1.0: USB hub found
[ 2217.496221] hub 2-1.1:1.0: 4 ports detected
[ 2217.844888] usb 2-1.1: USB disconnect, device number 39
[ 2217.861345] usb 2-1.1-port3: attempt power cycle



and so on....


This same device at a Windows computer works correctly.

Ideas?
Comment 1 Alan Stern 2021-07-24 14:30:56 UTC
This could easily be a power issue.  Does either the 7-port hub or the device you plug into it have its own power source?
Comment 2 tomas m 2021-07-24 14:45:09 UTC
(In reply to Alan Stern from comment #1)
> This could easily be a power issue.  Does either the 7-port hub or the
> device you plug into it have its own power source?

I measured the 5v on both chips and its 5v sharp.

Soldered an additional cap to its vcc too.

Its the same vcc source.

Like i said. Under windows it works

It is being powered by the usb port.

I will test an external suppy just to be safe and report
Comment 3 Alan Stern 2021-07-24 15:45:10 UTC
Have you tried using Wireshark to capture the USB communications to/from the hub under both Windows and Linux for comparison?  If there's a difference, it should show up.
Comment 4 ST 2021-09-15 22:46:43 UTC
I have exactly the same device, it is sold as USB3.0, but I observe same behaviour ( detected as USB2.0) on all my computers. Tomorrow I will find a chance to try it on a Windows machine, and report back.
Comment 5 Jonathan McDowell 2021-12-30 14:30:30 UTC
I've just ended up with one of these devices and see the same behaviour; on Linux (5.10.70 from Debian) only 3 ports are operational, whereas when plugged into a Windows laptop all 7 ports work. It seems this is a knock-off hub - it was sold as 480Mb/s capable, but is only reporting itself as full-speed (12Mb/s).

As Tomas reports it shows up as 2 USB hubs - lsusb -vv output as follows:

Bus 003 Device 080: ID 0a05:7211 Unknown Manufacturer hub
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0         8
  idVendor           0x0a05 Unknown Manufacturer
  idProduct          0x7211 hub
  bcdDevice            1.00
  iManufacturer           0 
  iProduct                1 USB2.0 HUB
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0019
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0001  1x 1 bytes
        bInterval             255

Apparently the chip involved is a Micov MW7211 which is a single chip full-speed hub solution. I've no particular interest in seeing this work, given that it's not high-speed capable, but figured the additional information might be helpful as there's obviously some difference in the way Windows is driving the hub compared to Linux.
Comment 6 Alan Stern 2021-12-30 20:22:57 UTC
What would actually be useful would be USB packet traces for the hub recorded under both Linux and Windows, showing what happens when the hub is first plugged in and and then when another device is plugged into one of the non-working ports.  This would allow us to compare the behavior of the two operating systems and look for differences.
Comment 7 Jonathan McDowell 2021-12-31 16:32:13 UTC
Created attachment 300189 [details]
Plugged in under Windows, USB flash drive inserted into port on second hub
Comment 8 Jonathan McDowell 2021-12-31 16:32:34 UTC
Created attachment 300190 [details]
Plugged in under Linux, USB flash drive inserted into port on second hub
Comment 9 Jonathan McDowell 2021-12-31 16:35:41 UTC
Attached files are hopefully helpful. Capture is started, hub is plugged in, USB3 flash drive is then plugged into a port off the second hub chip. In the Windows case it's detected fine (you can see the flurry of USB Mass Storage requests), in the Linux case there's some sort of disconnect/reconnect event but the flash drive never appears.
Comment 10 Alan Stern 2022-01-01 01:49:42 UTC
So far I have only looked at the Linux trace.  It shows two unusual things I don't understand.

One is that some process (I don't know which) re-reads the hub's device and configuration descriptors while the second device is being initialized, and apparently as a result of this the process decides to reset the hub.  Why does this happen?

The second is that when the descriptors are re-read, the hub's config descriptor has changed!  The original bmAttributes value is 0xe0, as shown in the lsusb output above.  But the bmAttributes value in the trace is 0xc0; the changed bit is the flag for Wakeup support.  Most likely this is a bug in the hub's firmware.

Perhaps additional debugging information will help.  You can enable dynamic debugging and snooping for USB by doing:

  echo 'module usbcore =p' >/sys/kernel/debug/dynamic_debug/control
  echo 1 >/sys/module/usbcore/parameters/usbfs_snoop

Clear the kernel log buffer by doing:

  dmesg -C

Then plug in the hub and and plug in a device to one of the non-working ports.  Let's see what the dmesg log shows after that.

Another unusual thing shows up clearly in the trace: The autosuspend_delay_ms time is set to a very low value; it looks like 20 ms.  You might get better results leaving the delay set to its default value of 2 seconds.  Or turn USB autosuspend off entirely by doing:

  echo -1 >/sys/module/usbcore/parameters/autosuspend

before plugging in the hub.
Comment 11 Jonathan McDowell 2022-01-01 10:36:40 UTC
Autosuspend appears to be the issue; if I disable it using the echo command provided then the additional ports on the hub work ok and the flash drive is detected.

Looking at my kernel config (this is Debian 11/bullseye, their stock 5.10.70-1 kernel) I see:

CONFIG_USB_AUTOSUSPEND_DELAY=2

Which according to drivers/usb/core/Kconfig is the default.

However hub_probe in drivers/usb/core/hub.c forces the suspend delay for a hub to 0ms as long as autosuspend is enabled.

As an experiment, theorising if the first hub chip didn't get put immediately to sleep devices off the 2nd hub chip would be seen, I tried plugging in the hub, plugging a flash drive into a port on the first chip (which is seen, as expected) and then plugging a flash drive into a port on the second chip (which would normally not be seen). Both drives are correctly detected.

I'll attach all 3 dmesgs now but it seems like the 0 delay in hub.c is what's causing the problem.
Comment 12 Jonathan McDowell 2022-01-01 10:37:44 UTC
Created attachment 300193 [details]
dmesg, no usb autosuspend, hub working
Comment 13 Jonathan McDowell 2022-01-01 10:38:18 UTC
Created attachment 300194 [details]
dmesg, usb autosuspend, usb_snoop, hub not working
Comment 14 Jonathan McDowell 2022-01-01 10:39:26 UTC
Created attachment 300195 [details]
dmesg, usb autosuspend, 2 drives, working
Comment 15 Alan Stern 2022-01-01 16:26:22 UTC
Created attachment 300199 [details]
Mark child resume requests in hub->event_bits, not hub->change_bits

Congratulations on tracking this down.  Later on I will send you a patch to disable autosuspend for these hubs, if it turns out to be needed.  But for now, I'd like to track down the exact pathway for the problem, if you don't mind.

Can you test the attached patch?  It looks like there is a bug in the hub driver's resume handler.  When a resuming hub sees that one of its downstream ports got a resume request from a child device, it sets a corresponding bit in the hub->change_bits variable.  But this variable is meant for connection changes, not suspend/resume status changes; which explains why the child hub ends up getting reset.  The bit should be set in the hub->event_bits variable instead.  (If you read through port_event() and hub_event(), you'll see how the two variables are handled similarly but not exactly the same.)

This bug wasn't noticed before because non-buggy devices don't change their descriptors, and hub_port_connect_change() is careful to check for cases where there wasn't a real connection change (i.e., device is still connected, port is still enabled, and device descriptors haven't changed).  But your buggy hub does change its config descriptor and so it gets reset.
Comment 16 Jonathan McDowell 2022-01-01 18:46:44 UTC
Excellent. Your fix appears to make things work fine. Built it on top of 5.12.12, plugged in the hub, plugged flash drive into a port off the second hub chip and it gets detected fine:

[   64.055322] usb 1-1: new full-speed USB device number 2 using xhci_hcd
[   64.223348] usb 1-1: New USB device found, idVendor=0a05, idProduct=7211, bcdDevice= 1.00
[   64.223357] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[   64.223360] usb 1-1: Product: USB2.0 HUB
[   64.272644] hub 1-1:1.0: USB hub found
[   64.275305] hub 1-1:1.0: 4 ports detected
[   64.715299] usb 1-1.4: new full-speed USB device number 3 using xhci_hcd
[   64.843578] usb 1-1.4: New USB device found, idVendor=0a05, idProduct=7211, bcdDevice= 1.00
[   64.843584] usb 1-1.4: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[   64.843586] usb 1-1.4: Product: USB2.0 HUB
[   64.880662] hub 1-1.4:1.0: USB hub found
[   64.883305] hub 1-1.4:1.0: 4 ports detected
[   78.843353] usb 1-1.4.2: new full-speed USB device number 4 using xhci_hcd
[   78.982539] usb 1-1.4.2: not running at top speed; connect to a high speed hub
[   79.000617] usb 1-1.4.2: New USB device found, idVendor=0951, idProduct=1697, bcdDevice= 1.00
[   79.000626] usb 1-1.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[   79.000629] usb 1-1.4.2: Product: DT Ultimate G3
[   79.000631] usb 1-1.4.2: Manufacturer: Kingston
[   79.000633] usb 1-1.4.2: SerialNumber: 0018F30C9F50BE5181712973
[   79.013499] SCSI subsystem initialized
[   79.015328] usb-storage 1-1.4.2:1.0: USB Mass Storage device detected
[   79.015438] scsi host0: usb-storage 1-1.4.2:1.0
[   79.015492] usbcore: registered new interface driver usb-storage
[   79.016658] usbcore: registered new interface driver uas
[   80.026221] scsi 0:0:0:0: Direct-Access     Kingston DT Ultimate G3   PMAP PQ: 0 ANSI: 6
[   80.029716] scsi 0:0:0:0: Attached scsi generic sg0 type 0
[   80.032151] sd 0:0:0:0: [sda] 61407232 512-byte logical blocks: (31.4 GB/29.3 GiB)
[   80.033068] sd 0:0:0:0: [sda] Write Protect is off
[   80.033070] sd 0:0:0:0: [sda] Mode Sense: 2b 80 00 08
[   80.033986] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[   80.271640]  sda: sda1
[   80.275055] sd 0:0:0:0: [sda] Attached SCSI removable disk
[   82.061123] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: errors=remount-ro. Quota mode: none.
Comment 17 Jonathan McDowell 2022-01-01 18:51:43 UTC
(In reply to Jonathan McDowell from comment #16)
> Excellent. Your fix appears to make things work fine. Built it on top of
> 5.12.12, plugged in the hub, plugged flash drive into a port off the second
> hub chip and it gets detected fine:

Er, 5.15.12, i.e. latest stable, I didn't just pick a random kernel version to test!
Comment 18 Alan Stern 2022-01-01 19:53:42 UTC
Good news!  I have posted the patch on the linux-usb mailing list; it should get merged sometime in the next few weeks.

Note You need to log in before you can comment on or make changes to this bug.