This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM4378: Linux USB2.0 driver?

Part Number: AM4378

In order to address the USB controller pf AM437x I am using the dwc3 driver. That driver will only work with xhci-hcd. Both, dwc3 and xhci are normally meant to address USB 3.0 controllers, not USB 2.0.

The combination of the above drivers usually works very well except when large amounts of data are being read and written from and to a USB 3.0 memory stick at the same time (such as unzipping a file on that memory). Then I will get "reset high-speed USB device number 2 using xhci-hcd" errors and the disk needs to be mounted again.

Excluding a hardware issue - behavior is the same for our board as the TI EVM board - some articles which can be found on the Internet like https://access.redhat.com/solutions/194273 suggest using the USB 2.0 driver ehci-hcd. I have tried that but I did not find any way to either get dwc3 work with ehci-hcd or by using an alternative driver to dwc3.

Is there a way to address AM4378's USB controller in USB 2.0 mode in Linux or is there a fix to the reset high-speed error? Or shall I revert to 4.19.59 which appears not have that problems (we did not do extensive testing though).

Thank you and regards

Peter

  • Hi Peter,

    Do you use TI Processor SDK Linux for AM437x? Which version?

    That driver will only work with xhci-hcd. Both, dwc3 and xhci are normally meant to address USB 3.0 controllers, not USB 2.0.

    Not true. xhci doesn't mean USB3.0 controllers.

    some articles which can be found on the Internet like https://access.redhat.com/solutions/194273 suggest using the USB 2.0 driver ehci-hcd.

    Not correct either. The USB controller used on AM437x is not EHCI compliant, rather xHCI compliant.

  • Ok, so if all that is not true, someone may need to change rhe driver names and kernel status messages stating USB 3.0...

    Anyway, which solution do you suggest? 

  • Peter,

    someone may need to change rhe driver names and kernel status messages stating USB 3.0...

    I am not sure I understand your comment. Could you please elaborate?

    Anyway, which solution do you suggest? 

    Please answer my first question about what Linux you run on AM437x? I need to understand the problem first.

  • Dear Bin Liu,

    I am working with SDK 08.02.00.24 which corresponds to kernel version 5.10.100.

    Linux kernel detects:

    [ 4.118806] hub 1-0:1.0: USB hub found
    [ 4.122749] hub 1-0:1.0: 1 port detected
    [ 4.127297] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
    [ 4.132932] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
    [ 4.140683] xhci-hcd xhci-hcd.0.auto: Host supports USB 3.0 SuperSpeed
    [ 4.147340] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
    [ 4.155832] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 5.10
    [ 4.164168] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1

    Linux kernel documentation titles:

    xHCI HCD (USB 3.0) support
    EHCI HCD (USB 2.0) support

    Without any devices connected, lsusb reports:

    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 002: ID 24a9:205a
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

    modinfo dwc3 states:

    filename: /lib/modules/5.1.110/kernel/drivers/usb/dwc3/dwc3.ko
    description: DesignWare USB3 DRD Controller Driver
    license: GPL v2
    author: Felipe Balbi <balbi@ti.com>
    alias: platform:dwc3
    srcversion: E6EE8F401C1A63BEF771D3B
    alias: of:N*T*Csynopsys,dwc3C*
    alias: of:N*T*Csynopsys,dwc3
    alias: of:N*T*Csnps,dwc3C*
    alias: of:N*T*Csnps,dwc3
    depends: udc-core,usb-common
    intree: Y
    name: dwc3
    vermagic: 5.1.110 SMP preempt mod_unload modversions ARMv7 p2v8
    In any case, my problem is that that the driver shows USB 3.0, the problem is that in case of heavy read/write operations on a USB 3.0 memory stick connected, I get "reset high-speed USB device number 2 using xhci-hcd" error. If I use a USB 2.0 memory instead, no problems.
    My idea was to force USB 2.0 mode for the controller but if there is another way from preventing Linux from restarting the USB driver with the above error message, I will be more than happy.
    Regards
    Peter

  • Peter,

    I know all these kernel messages are confusing, that is mostly because how the xHCI Spec is defined and how USB3.x Specs and USB2.0 Specs co-exist. I don't want to explain the details here (I don't even know where to start, all the relevant xHCI, USB 3.x and USB2.0 Specs are tens of thousand pages...), because I am afraid it might create more confusion to you, if I am not able to summarize the relevant USB Specs in a few paragraphs here.

    Rather I think we need to focus on the problem and to see if it can be solved. I probably need to replicate the issue on my AM437x EVM and debug it. Could you please describe the steps to trigger the error? I understand it only happens with USB2.0 memory sticks, but how to use it to trigger the error?

    By the way, do you have the links to the documents you mentioned?

    Linux kernel documentation titles:

    xHCI HCD (USB 3.0) support
    EHCI HCD (USB 2.0) support

  • Hi Bin Liu,

    Sorry for letting you wait; in the meantime, we have done some more testing.

    First you are right: while a USB 3.0 bus is shown when using xHCI driver on AM437x, devices are connected to the bus with the 2.0 controller. So that is fine and the USB 3.0 hub appears to be only virtual.

    However, on our boards as well as on your EVM board, we are always and reproducibly facing the same issue when you stress the system with parallel read and write operations.

    Scenario:
    1. Create a zip archive with of 500 MB size. In our case uncompressed size is 2GB.
    2. Unzip the file within the same folder so that there is continuous R/W activity.

    Outcome:
    At some point you will receive one or more "reset high-speed USB device number 2 using xhci-hcd" messages. Randomly the reset will happen fast enough so that the file operation just continues (and in some cases even concludes correctly) or it will take too long to have Linux lose the mount point.

    In all our tests, this has happened only with recent USB 3.0 memories, and we were unable to reproduce the issue with USB 2.0 memories. I cannot tell you if the USB version is the reason is the speed of the devices. Probably it is a speed issue as we were unable to reproduce the error using a USB 3.0 hard drive. The file system has no influence on the error itself, just on the likelihood of a recovery after the error (never recovers with FAT32, sometimes recovers with exFAT and ext4).

    No difference by kernel or SDK version (using SDKs 06.01.00.08, 06.03.00.106, 08.02.00.24). Due to driver support, we have done the tests with exFAT on 08.02.00.24 (kernel 5.10.100) only.

    No chance to reproduce the same behavior on a PC with the same kernel version and using a USB 2.0-only port.

    Regards
    Peter

  • Hi Peter,

    Thanks for the details. I will try to reproduce it and take a look.

  • Hi Bin Lui, do you have any update on this case?

  • Hi Peter,

    Sorry for the late response. I tried a couple USB super-speed thumb drives uncompressing a 800+MB files on AM437x GP EVM, but the usb bus reset issue didn't happen in my test.

    But can you please try the following kernel patch to see if it solves the issue on your setup? This patch helped some customers in the past in using USB3.0 thumb drives on USB2.0 ports.

    diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
    index 2a58030d26bb..141f9c23867a 100644
    --- a/drivers/usb/core/hub.c
    +++ b/drivers/usb/core/hub.c
    @@ -4569,7 +4569,6 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
            struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
            int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
    
    -       if (!udev->usb2_hw_lpm_capable || !udev->bos)
                    return;
    
            if (hub)