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.

AM3358: Multiple USB devices with more than 32 endpoints

Part Number: AM3358

In customer system, connect a USB HUB(USB2517i) on USB1 which has 7 ports. connected 5 modules, one module is USB to 3*UART converter, each UART need 3 endpoint(interrupt, RX, TX), so each module need 9 endpoint. 

When connect 4 module need 36 endpoint, will it result in out of resource? 

Below  is USB module initialization message: 

[  453.113981] usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  453.127726] usb 2-1.3: Product: GD32 Trible CDC
[  453.132304] usb 2-1.3: Manufacturer: GigaDevice
[  453.137652] usb 2-1.3: SerialNumber: GD32E10X-V2.0.0-4b5c6de
[  453.150852] cdc_acm 2-1.3:1.0: ttyACM7: USB ACM device
[  453.179116] cdc_acm 2-1.3:1.2: ttyACM8: USB ACM device
[  453.251910] cdc_acm 2-1.3:1.4: ttyACM9: USB ACM device

It is OK to install and uninstall 4 modules, can observe all detected UART devices under /dev, and can communicate with 3 modules normally.  but when communicate with the 4th module, reports below errors:

[  103.483217] cdc_acm 2-1.5:1.4: acm_port_activate - usb_submit_urb(ctrl irq) failed
[  104.741250] musb-hdrc musb-hdrc.1: int hwep alloc failed for 1x8
[  104.741295] cdc_acm 2-1.5:1.4: acm_port_activate - usb_submit_urb(ctrl irq) failed
[  105.325624] musb-hdrc musb-hdrc.1: int hwep alloc failed for 1x8
[  105.325670] cdc_acm 2-1.5:1.4: acm_port_activate - usb_submit_urb(ctrl irq) failed
[  112.055419] musb-hdrc musb-hdrc.1: int hwep alloc failed for 1x8
[  112.055467] cdc_acm 2-1.5:1.4: acm_port_activate - usb_submit_urb(ctrl irq) failed
[  112.921202] musb-hdrc musb-hdrc.1: int hwep alloc failed for 1x8
[  112.921245] cdc_acm 2-1.5:1.4: acm_port_activate - usb_submit_urb(ctrl irq) failed
[  113.689117] musb-hdrc musb-hdrc.1: int hwep alloc failed for 1x8
[  113.689164] cdc_acm 2-1.5:1.4: acm_port_activate - usb_submit_urb(ctrl irq) failed

The message: musb-hdrc musb-hdrc.1: int hwep alloc failed for 1x8 locates in line 2152 of musb_host.c

If out of limited endpoint, can driver support dynamically endpoint assignment?

  • Hi,
    You query has been assigned to a TI engineer. Please note that response may be delayed due to Christmas and New Year holidays.
  • Hi Tony,

    Tony Tang said:
    [  113.689117] musb-hdrc musb-hdrc.1: int hwep alloc failed for 1x8

    Yes, this message indicates it runs out of endpoints.

    Tony Tang said:
    If out of limited endpoint, can driver support dynamically endpoint assignment?

    No. the driver doesn't limit on bulk endpoints, but due to the nature of interrupt endpoints defined in the USB Spec, an allocated interrupt endpoint will only be freed until the USB device is detached, dynamic allocation on interrupt (and isoch) endpoints is not supported in the driver.

  • Hi,

        It is said  that interrupt endpoints defined in the USB Spec.as we all know,am335x souports 16 Transmit (TX) and 16 Receive (RX) endpoints including endpoint 0.  Is  the Maximum interrupt endpoints 15 (tx)? and USB HUB(USB2517i)  will occupy interrupt endpoints or not ?

    Regards. Qiang Luo

  • Hi

    it is said that interrupt endpoints defined in the USB Spec. As we all know ,am335x supports 16 Transmit (TX) and 16 Receive (RX) endpoints including endpoint 0. is it that the Maximum of interrupt endpoints are 15(tx)? and whether USB HUB(USB2517i) will occupy some interrupt endpoints or not? so, we want to confirm the number of modules according to  the nature of interrupt endpoints

    Best Regards
    Qiang Luo
  • Hi Qiang,

    Yes, the MUSB controller hardware can support up to 15 TX interrupt endpoints, but to cover most of USB use cases, the MUSB driver configures some endpoint FIFO in shared FIFO mode, which might affect the up limit of the interrupt use cases. The endpoint FIFO configuration is in struct mode_4_cfg[] in musb_core.c. You can try to modify hw_ep_num 13, 14, 15 to have the same .style as hw_ep_num 1, and modify .maxpacket to 512 for ALL endpoints, to see if you can get the 4th module enumerated.

    Yes, a USB hub will occupy one interrupt endpoint.

    To check the endpoint numbers and types needed for a USB device, you can read the output of command 'lsusb -v -d <vid:pid>

  • Hi Bin:

    mode_4 in musb_core.c means that  the MUSB controller has 16K fifo. Do two MUSB controllers share 32K fifo?As shown below,it is the output of conmmand ' cat /sys/kernel/debug/usb/devices '. We usbed bus01 to connect usb2517 hub,and usb2517 hub connect some usb devices. I think that the root hub occupys one tx as intterupt endpoint, usb2517 hub occupys two tx as intterupt endpoint and GD32 Trible CDC occupys four tx as intterupt endpoint or input endpoint.So,The Total of occupyed tx is seven.  I don't know I calculated it correctly ?

  • Hi Qiang,

    Each MUSB controller has its own 16KB fifo, both don't share with each other.

    In the case you show which has one hub and one CDC device connected, I think total 5 tx endpoints are allocated from the MUSB controller.

    - The root hub (1d6b:0002) has a logical endpoint, but it don't require a hw endpoint, so this one doesn't count;

    - The #2 and #3 you highlighted are on two different Alt, only one is used, so only count for 1 endpoint.

    - The 4 tx endpoints you highlighted for the CDC device are correct.

    You can also verify the endpoint allocation by add some debug message in musb_schedule() in musb_host.c.

  • Hi Bin

    Thank you very much. it really help to answer my question about the endpoint allocation.  However,I have a problem need your help. The topology of connection is the same.while CDC device  is transfering data, we power off the CDC device. And, we power on the CDC device after 20 seconds.  Repeat  it about 10 times.the port of usb2517 connectting with CDC device can't enumerate USB device .   it  occur some errors as below.  

    [ 1185.326659] usb 1-1.4: config 1 has 2 interfaces, different from the descriptor's value: 4
    [ 1185.335558] usb 1-1.4: New USB device found, idVendor=05f9, idProduct=f485
    [ 1185.343118] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    [ 1185.350813] usb 1-1.4: Product: GD32 Trible CDC
    [ 1185.355373] usb 1-1.4: Manufacturer: GigaDevice
    [ 1185.360313] usb 1-1.4: SerialNumber: GD32E10X-V2.0.0-4b5c6de
    [ 1185.367901] cdc_acm 1-1.4:1.0: ttyACM1: USB ACM device
    [ 1187.215360] ####musb_schedule:qh db10c400 periodic slot 11
    [ 1187.215406] ####musb_schedule:qh db10c480 periodic slot 12
    [ 1187.221577] ####musb_schedule:qh db10c500 periodic slot 10
    [ 1197.506123] usb 1-1.4: USB disconnect, device number 24
    [ 1197.518327] cdc_acm 1-1.4:1.0: failed to set dtr/rts
    [ 1202.075777] usb 1-1.4: new full-speed USB device number 25 using musb-hdrc
    [ 1207.205599] usb 1-1.4: device descriptor read/64, error -110
    [ 1222.785075] usb 1-1.4: device descriptor read/64, error -110
    [ 1223.005043] usb 1-1.4: new full-speed USB device number 26 using musb-hdrc
    [ 1228.164910] usb 1-1.4: device descriptor read/64, error -110
    [ 1243.524393] usb 1-1.4: device descriptor read/64, error -110
    [ 1243.644478] usb 1-1-port4: attempt power cycle
    [ 1244.304361] usb 1-1.4: new full-speed USB device number 27 using musb-hdrc
    [ 1254.844018] usb 1-1.4: device not accepting address 27, error -110
    [ 1254.944014] usb 1-1.4: new full-speed USB device number 28 using musb-hdrc
    [ 1265.483659] usb 1-1.4: device not accepting address 28, error -110
    [ 1265.490005] usb 1-1-port4: unable to enumerate USB device

    Best Regards

    Qiang Luo

  • Qiang,

    Technically powering off the USB device without detaching it is not a normal operation, so we need some debug to understand why the issue happens.

    What is the dr_mode setting in device tree setting for this MUSB host port?

    What kernel version do you use?

  • Hi Bin

    the dr_mode setting in dts is "host" as below. The version of SDK used is ti-processor-sdk-linux-am335x-evm-05.00.00.15. The kernel version is linux4.14.40. I don't know how to detaching usb device with safe way in Embedded Linux. Can you teach me ? thank you.

    &usb1 {
    status = "okay";
    dr_mode = "host";
    };

    Best Regards,

    Qiang Luo

  • Hi Qiang,

    Does the USB device have a dedicated power supply and you just turned it off, and the USB device is till plugged in the USB hub?

    What if you don't touch its power supply but remove the USB device from the hub then wait a bit and plug it back to the hub, does the enumeration issue still happen?

  • Hi Bin

    The enumeration issue still happen. the port of usbhub can't enumerat and connect USB device any more. Unless it reset USB hub or reboot linux .The USB device  was self powered. it's easy to happen while the host is transferring data  with usb device. it seems there are not transmission, the usb device detach and attach normally

  • Qiang,

    Please let me know if the following kernel patch solves the issue. If not, we would have to debug the kernel to understand the issue.

    diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
    index b59ce9ad14ce..7cb56c1f150b 100644
    --- a/drivers/usb/musb/musb_host.c
    +++ b/drivers/usb/musb/musb_host.c
    @@ -1811,7 +1811,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
            } else if (rx_csr & MUSB_RXCSR_H_ERROR) {
                    musb_dbg(musb, "end %d RX proto error", epnum);
    
    -               status = -EPROTO;
    +               status = -ESHUTDOWN;
                    musb_writeb(epio, MUSB_RXINTERVAL, 0);
    
                    rx_csr &= ~MUSB_RXCSR_H_ERROR;
    
    
  • Hi Bin

    The patch doesn't  work. But, there are some changes. Before , if the port is died, it doesn't connect and enumerate usb device any more,and no output of kernel log. After making the patch, it try to enumerate the USB device three times while powered on three times . The kernel log as below .I want to know how to open musb_dbg function? Thanks.

  • Hi Qiang,

    To turn on musb_dbg(), please enable FTRACE in kernel menuconfig, then rebuild the kernel and modules.

    To capture musb_dbg() logs, run the following commands on the linux console. I recommend to run them on a telnet session instead of the uart console, because it is much faster. There will be a lot of messages when usb is transferring data.

    root@am335x-evm:~# echo 1 > /sys/kernel/debug/tracing/events/musb/musb_log/enable
    root@am335x-evm:~# cat /sys/kernel/debug/tracing/trace_pipe

  • Hi Bin

    if the data is tranferring between usb host and usb device, the power of usb device cut off several times. it will read device descriptor, set address and  enumerate device failed. Do you have any advice to me? Look forward to your reply,thanks

    [root@~]#[ 264.245951] usb 2-1.4: USB disconnect, device number 22
    [ 268.565946] usb 2-1.4: new full-speed USB device number 23 using musb-hdrc
    [ 273.705902] usb 2-1.4: device descriptor read/64, error -110
    [ 289.065899] usb 2-1.4: device descriptor read/64, error -110
    [ 289.285976] usb 2-1.4: new full-speed USB device number 24 using musb-hdrc
    [ 294.425903] usb 2-1.4: device descriptor read/64, error -110
    [ 309.785963] usb 2-1.4: device descriptor read/64, error -110
    [ 309.906067] usb 2-1-port4: attempt power cycle
    [ 310.565925] usb 2-1.4: new full-speed USB device number 25 using musb-hdrc
    [ 321.105944] usb 2-1.4: device not accepting address 25, error -110
    [ 321.205886] usb 2-1.4: new full-speed USB device number 26 using musb-hdrc
    [ 331.745893] usb 2-1.4: device not accepting address 26, error -110
    [ 331.752411] usb 2-1-port4: unable to enumerate USB device

    best regards

    Qiang Luo

  • Hi Qiang,

    user1794335 said:
    the power of usb device cut off several times.

    Do you mean the USB VBUS voltage disappears? What leads you to this conclusion? Please provide more details.

  • Hi Bin

    No,USB VBUS connect +5V. The usb CDC device is self powered  and it is controlled by  gpio pin . So we can control the power of usb CDC device. It simulate that when the usb CDC device is transferring data ,it  disconnect suddenly.  

  • Hi Qiang,

    Okay, I understand the scenario now.

    There are multiple things we need to check to understand why the enumeration failed. First please connect a USB protocol analyzer between the MUSB host port and the USB CDC device to capture the USB bus transactions. I'd like to check the bus activity first.

  • Or you can first test the USB CDC device with a Linux PC to see if the PC can enumerate the device properly after the device power lost.

  • Hi Bin

    OK,how to send your data collected by USB protocol analyzer?email ?

  • You can compress the file and attach it to this e2e thread:

  • usb_device_data.rar

    Hi Bin

    this is our data collected by USB protocol analyzer .it includes upstream and downstream.can you help to analyse it. thanks

  • Hi,

    Thanks for the trace. I spent some time on it but haven't observed anything obviously wrong, other than the USB bus between AM335x and the hub becomes full-speed at some point of the time, but I am not sure how much I can trust the analyzer's interpretation of the bus signals.

    Anyway, can you please do a few more tests?

    If you don't use the hub and only connect one CDC device directly to the AM335x USB port and run the test, do you still see the enumeration failure?

    Can you please add the following parameter to the U-Boot bootargs env and run the test with the hub, does the enumeration error still happen?

    usbcore.autosuspend=-1

  • Hi Bin

            The AM335x USB port connected one CDC device directly , it works normal. I tested  more than 50 times. if the CDC device connectted by hub,it is easy to happen.The data collected by usb  analyzer may not collect enumeration error.

    And then, I set "usbcore.autosuspend=-1" in bootargs and run the test in kernel,

    the result is below: [root@~]#cat /sys/module/usbcore/parameters/autosuspend  -1. I think the setting is correct. But The enumeration error still happened. 

  • Hi,

    Thanks for the testing. The information is useful.

    Once more test - you mentioned before that you power on/off the CDC device to simulate connect/disconnect, what if you test with plugging/unplugging the CDC device to/from the hub instead of powering it on/off, does the enumeration issue also happen?

  •  Hi

    Plugging/unplugging the CDC device ,the enumeration failed still happen.it is very strange。

  • Hi Bin

    There is another problem. This is power on/off modules several times. while the module disconnect kernel,it seems that fifo scrubbed falied. Do you  resolve the similar situation? thanks

    [ 455.680616] usb 1-1.1: USB disconnect, device number 20
    [ 456.682886] ------------[ cut here ]------------
    [ 456.687580] WARNING: CPU: 0 PID: 2544 at drivers/usb/musb/musb_host.c:140 musb_h_tx_flush_fifo+0x144/0x148
    [ 456.697282] musb-hdrc musb-hdrc.0: Could not flush host TX10 fifo: csr: 2003
    [ 456.704362] Modules linked in: wfos_state_detect wfos_irda wfos_pwm pwm_omap_dmtimer wfos_temperature wfos_pm wfos_adc wfos_version wfos_esam wfos_led wfos_kbd wfos_lcd wfos_product_info wfos_watchdog wfos_devices
    [ 456.723472] CPU: 0 PID: 2544 Comm: kworker/0:0 Not tainted 4.14.40 #200
    [ 456.730115] Hardware name: Generic AM33XX (Flattened Device Tree)
    [ 456.736262] Workqueue: usb_hub_wq hub_event
    [ 456.740465] Backtrace:
    [ 456.742941] [<c010c8e0>] (dump_backtrace) from [<c010cbf4>] (show_stack+0x20/0x24)
    [ 456.750551] r7:00000009 r6:00000000 r5:c0b26ba0 r4:db1efa80
    [ 456.756251] [<c010cbd4>] (show_stack) from [<c08d7028>] (dump_stack+0x24/0x28)
    [ 456.763528] [<c08d7004>] (dump_stack) from [<c012ce40>] (__warn+0xf4/0x10c)
    [ 456.770530] [<c012cd4c>] (__warn) from [<c012cea0>] (warn_slowpath_fmt+0x48/0x50)
    [ 456.778054] r9:0ccccb60 r8:c0b4edd0 r7:c0deb334 r6:c0deb33c r5:e08ef410 r4:c0b26bf8
    [ 456.785843] [<c012ce5c>] (warn_slowpath_fmt) from [<c069d020>] (musb_h_tx_flush_fifo+0x144/0x148)
    [ 456.794756] r3:c09687ec r2:c0b26bf8
    [ 456.798347] r4:dc0e6010
    [ 456.800902] [<c069cedc>] (musb_h_tx_flush_fifo) from [<c069e024>] (musb_cleanup_urb+0x64/0xf0)
    [ 456.809558] r10:00000001 r9:0000b334 r8:c0deb33c r7:e08ef410 r6:db1d2e00 r5:00000000
    [ 456.817423] r4:dc0e6bc8
    [ 456.819977] [<c069dfc0>] (musb_cleanup_urb) from [<c069e250>] (musb_urb_dequeue+0x1a0/0x1f0)
    [ 456.828460] r10:00000001 r9:c0009400 r8:db1a8900 r7:00000000 r6:dc0e6010 r5:db1d2e00
    [ 456.836327] r4:a0070013 r3:db1a8900
    [ 456.839931] [<c069e0b0>] (musb_urb_dequeue) from [<c063f22c>] (unlink1+0x3c/0x150)
    [ 456.847541] r10:00000000 r9:db140f68 r8:60070013 r7:fffffffe r6:dc66a200 r5:db0ec800
    [ 456.855407] r4:db1d2e00 r3:c069e0b0
    [ 456.859007] [<c063f1f0>] (unlink1) from [<c064178c>] (usb_hcd_unlink_urb+0xa8/0xc8)
    [ 456.866705] r9:db140f68 r8:60070013 r7:fffffffe r6:db1d2e00 r5:db0ec800 r4:00000000
    [ 456.874492] [<c06416e4>] (usb_hcd_unlink_urb) from [<c0642b88>] (usb_kill_urb.part.4+0x40/0xb8)
    [ 456.883237] r9:db140f68 r8:00000001 r7:db130800 r6:db130800 r5:db1d2e0c r4:db1d2e00
    [ 456.891020] [<c0642b48>] (usb_kill_urb.part.4) from [<c0642c38>] (usb_kill_urb+0x38/0x3c)
    [ 456.899238] r6:db130800 r5:db130980 r4:db130818
    [ 456.903887] [<c0642c00>] (usb_kill_urb) from [<c0685f1c>] (acm_kill_urbs+0x34/0x6c)
    [ 456.911587] [<c0685ee8>] (acm_kill_urbs) from [<c06865f0>] (acm_port_shutdown+0xb4/0xc0)
    [ 456.919717] r7:db130800 r6:00000000 r5:db130cac r4:db130814
    [ 456.925415] [<c068653c>] (acm_port_shutdown) from [<c0512fc8>] (tty_port_shutdown+0x9c/0xa8)
    [ 456.933895] r7:00000000 r6:db140e00 r5:db130894 r4:db130814
    [ 456.939586] [<c0512f2c>] (tty_port_shutdown) from [<c0513324>] (tty_port_hangup+0xc4/0xf8)
    [ 456.947892] r7:00000000 r6:00000000 r5:db140e00 r4:db130814
    [ 456.953584] [<c0513260>] (tty_port_hangup) from [<c0686960>] (acm_tty_hangup+0x20/0x24)
    [ 456.961625] r5:db1ee000 r4:db140e00
    [ 456.965235] [<c0686940>] (acm_tty_hangup) from [<c0509390>] (__tty_hangup+0x360/0x374)
    [ 456.973195] [<c0509030>] (__tty_hangup) from [<c05093c0>] (tty_vhangup+0x1c/0x20)
    [ 456.980718] r10:dc7bdc00 r9:dc7bdc74 r8:dc7bdc20 r7:db140e00 r6:db130814 r5:dc7bdc00
    [ 456.988582] r4:db130800
    [ 456.991135] [<c05093a4>] (tty_vhangup) from [<c068619c>] (acm_disconnect+0xc0/0x154)
    [ 456.998924] [<c06860dc>] (acm_disconnect) from [<c06475a8>] (usb_unbind_interface+0x88/0x2b8)
    [ 457.007492] r7:00000000 r6:c0d83bf0 r5:dc7bdc54 r4:c0d83bf0
    [ 457.013189] [<c0647520>] (usb_unbind_interface) from [<c0554c2c>] (device_release_driver_internal+0x168/0x208)
    [ 457.023242] r10:00000001 r9:dc7bdc74 r8:00000034 r7:00000000 r6:c0d83bf0 r5:dc7bdc54
    [ 457.031107] r4:dc7bdc20
    [ 457.033659] [<c0554ac4>] (device_release_driver_internal) from [<c0554cec>] (device_release_driver+0x20/0x24)
    [ 457.043624] r9:dc7bdc74 r8:dc7bdc28 r7:c0de928c r6:c0d81cc0 r5:dc7bdc20 r4:dc2433ec
    [ 457.051409] [<c0554ccc>] (device_release_driver) from [<c0553a40>] (bus_remove_device+0xdc/0x108)
    [ 457.060337] [<c0553964>] (bus_remove_device) from [<c0550638>] (device_del+0x1d0/0x338)
    [ 457.068381] r7:c0de928c r6:db0ec870 r5:dc7bdc20 r4:dc7bdc74
    [ 457.074073] [<c0550468>] (device_del) from [<c0644cf0>] (usb_disable_device+0x9c/0x1e0)
    [ 457.082121] r9:dc7bd400 r8:dc7bdc00 r7:dc66a200 r6:00000001 r5:00000000 r4:db0ec800
    [ 457.089909] [<c0644c54>] (usb_disable_device) from [<c063afe0>] (usb_disconnect+0xc0/0x240)
    [ 457.098306] r9:dc7bd400 r8:dc792000 r7:db0ec8a4 r6:db0ec870 r5:db0ec800 r4:00000100
    [ 457.106092] [<c063af20>] (usb_disconnect) from [<c063c674>] (hub_port_connect+0x70/0xa34)
    [ 457.114314] r10:00000001 r9:dc7578fc r8:00000001 r7:dc6d4000 r6:00000001 r5:dc757800
    [ 457.122177] r4:00000100
    [ 457.124732] [<c063c604>] (hub_port_connect) from [<c063d664>] (hub_event+0x62c/0x7a8)
    [ 457.132604] r10:00000001 r9:dc7578fc r8:00000001 r7:00000100 r6:00000001 r5:db0ec800
    [ 457.140468] r4:dc79219c
    [ 457.143031] [<c063d038>] (hub_event) from [<c0146d64>] (process_one_work+0x214/0x554)
    [ 457.150904] r10:c0d1c5c0 r9:00000000 r8:c0d139b8 r7:00000000 r6:dcb3aa00 r5:db246480
    [ 457.158769] r4:dc7578fc
    [ 457.161323] [<c0146b50>] (process_one_work) from [<c0147130>] (worker_thread+0x8c/0x688)
    [ 457.169456] r10:c0d1c5c0 r9:00000008 r8:c0d139cc r7:ffffe000 r6:db246498 r5:c0d139b8
    [ 457.177321] r4:db246480
    [ 457.179877] [<c01470a4>] (worker_thread) from [<c014d2f4>] (kthread+0x168/0x170)
    [ 457.187313] r10:dc6d7e9c r9:c01470a4 r8:db246480 r7:db1ee000 r6:00000000 r5:dc7cef00
    [ 457.195178] r4:dc7ce0c0
    [ 457.197738] [<c014d18c>] (kthread) from [<c0108268>] (ret_from_fork+0x14/0x2c)
    [ 457.205000] r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c014d18c
    [ 457.212865] r4:dc7cef00
    [ 457.215410] ---[ end trace c856859729c36937 ]---
    Down !
    [ 459.048835] usb 1-1.1: new full-speed USB device number 21 using musb-hdrc
    [ 464.178354] usb 1-1.1: device descriptor read/64, error -110
    Down !
    Down !
    [ 479.756930] usb 1-1.1: device descriptor read/64, error -110
    [ 479.976907] usb 1-1.1: new full-speed USB device number 22 using musb-hdrc
    Down !
    Down !
    [ 485.356597] usb 1-1.1: device descriptor read/64, error -110
    Down !
    Down !
    [ 500.954689] usb 1-1.1: device descriptor read/64, error -110
    [ 501.074772] usb 1-1-port1: attempt power cycle
    [ 501.734591] usb 1-1.1: new full-speed USB device number 23 using musb-hdrc
    Down !
    Down !
    [ 512.293691] usb 1-1.1: device not accepting address 23, error -110
    [ 512.613654] usb 1-1.1: new full-speed USB device number 24 using musb-hdrc
    Down !
    [ 523.172941] usb 1-1.1: device not accepting address 24, error -110
    [ 523.179292] usb 1-1-port1: unable to enumerate USB device
    Down !
    [ 524.322862] usb 1-1.1: new full-speed USB device number 25 using musb-hdrc
    [ 529.452558] usb 1-1.1: device descriptor read/64, error -110
    Down !
    Down !
    [ 545.031824] usb 1-1.1: device descriptor read/64, error -110
    [ 545.251761] usb 1-1.1: new full-speed USB device number 26 using musb-hdrc
    Down !
    Down !
    [ 550.631564] usb 1-1.1: device descriptor read/64, error -110
    Down !
    Down !
    [ 566.231523] usb 1-1.1: device descriptor read/64, error -110
    [ 566.351443] usb 1-1-port1: attempt power cycle
    [ 567.011298] usb 1-1.1: new full-speed USB device number 27 using musb-hdrc
    Down !
    Down !
    [ 577.571151] usb 1-1.1: device not accepting address 27, error -110
    [ 577.891143] usb 1-1.1: new full-speed USB device number 28 using musb-hdrc
    Down !
    [ 588.450967] usb 1-1.1: device not accepting address 28, error -110
    [ 588.457315] usb 1-1-port1: unable to enumerate USB device

  • Hi Bin

    it is said that the situation happened sometimes. but it doesn't mention how to solve this problem.

  • user1794335 said:
    [ 456.682886] ------------[ cut here ]------------
    [ 456.687580] WARNING: CPU: 0 PID: 2544 at drivers/usb/musb/musb_host.c:140 musb_h_tx_flush_fifo+0x144/0x148
    [ 456.697282] musb-hdrc musb-hdrc.0: Could not flush host TX10 fifo: csr: 2003

    This TX fifo flushing issue should be harmless, we haven't seen it cause any USB functional problem.

    Anyway, please apply the kernel patch attached below to see if it solves the enumeration issue.

    From 465160e6c2c37d4f102b5955596b9e376d7f599f Mon Sep 17 00:00:00 2001
    From: Bin Liu <b-liu@ti.com>
    Date: Thu, 18 Apr 2019 10:06:09 -0500
    Subject: [PATCH] usb: musb: host: handle clear TT buffer
    
    ---
     drivers/usb/musb/musb_host.c | 24 ++++++++++++++++++++++++
     drivers/usb/musb/musb_host.h |  1 +
     2 files changed, 25 insertions(+)
     mode change 100644 => 100755 drivers/usb/musb/musb_host.c
    
    diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
    old mode 100644
    new mode 100755
    index 8617a18b4c50..85a0a310e80e
    --- a/drivers/usb/musb/musb_host.c
    +++ b/drivers/usb/musb/musb_host.c
    @@ -300,6 +300,21 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
     	}
     }
     
    +static void musb_clear_tt_buffer_complete(struct usb_hcd *hcd,
    +               struct usb_host_endpoint *ep)
    +{
    +       struct musb             *musb = hcd_to_musb(hcd);
    +       struct musb_qh          *qh = ep->hcpriv;
    +       unsigned long           flags;
    +
    +       if (!qh)
    +               return;
    +
    +       spin_lock_irqsave(&musb->lock, flags);
    +       qh->clearing_tt = 0;
    +       spin_unlock_irqrestore(&musb->lock, flags);
    +}
    +
     /* Context: caller owns controller lock, IRQs are blocked */
     static void musb_giveback(struct musb *musb, struct urb *urb, int status)
     __releases(musb->lock)
    @@ -362,6 +377,14 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
     		break;
     	}
     
    +	if (urb->dev->tt &&
    +		(urb->dev->tt->hub != musb->hcd->self.root_hub) &&
    +		(usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) &&
    +		(status || urb->unlinked)
    +		&& !qh->clearing_tt)
    +			if (usb_hub_clear_tt_buffer(urb) == 0)
    +				qh->clearing_tt = 1;
    +
     	qh->is_ready = 0;
     	musb_giveback(musb, urb, status);
     	qh->is_ready = ready;
    @@ -2750,6 +2773,7 @@ static const struct hc_driver musb_hc_driver = {
     	.bus_resume		= musb_bus_resume,
     	/* .start_port_reset	= NULL, */
     	/* .hub_irq_enable	= NULL, */
    +	.clear_tt_buffer_complete = musb_clear_tt_buffer_complete,
     };
     
     int musb_host_alloc(struct musb *musb)
    diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h
    index 54d02ed032df..1dad7513059b 100644
    --- a/drivers/usb/musb/musb_host.h
    +++ b/drivers/usb/musb/musb_host.h
    @@ -65,6 +65,7 @@ struct musb_qh {
     	unsigned		iso_idx;	/* in urb->iso_frame_desc[] */
     	struct sg_mapping_iter sg_miter;	/* for highmem in PIO mode */
     	bool			use_sg;		/* to track urb using sglist */
    +	unsigned                clearing_tt:1;  /* Clear-TT-Buf in progress */
     };
     
     /* map from control or bulk queue head to the first qh on that ring */
    -- 
    2.17.1
    
    

  • Hi Bin

    It seems work fine. I tested it more than 2 hours. I will test  more time. Can you explain how it works? Another question,what's the difference between DMA and PIO,the kernel menuconfig is #CONFIG_MUSB_PIO_ONLY=y. thanks

    Best regards

    Qiang Luo

  • Hi Qiang,

    The MUSB driver doesn't handle clearing USB hub TT buffer to recover hub TT failures. The patch I provided was submitted to the Linux kernel community by somebody else some time ago, but got community feedback that the patch is not complete and misses some corner case handlings. But the patch author didn't update the patch so it never got merged into the kernel.

    PIO mode is the non-DMA mode.

  • Hi Bin

    So,we should do more test. I'm interested in how the community judge that the patch is incomplete. 

  • Here is the beginning of the conversation of this patch on linux-usb mailing list.

    https://marc.info/?l=linux-usb&m=150956108100645&w=2

  • Hi Bin

    There is bad news. I power on/off the module while it is transferring datas.I test it more than 2000 times in last night. But it still happened. the port can't enumerate any more. The last log  as below. 

    So, what can I do next step. Can you improve the patch?look forward to your reply. Thank you.

    [40638.291607] usb 2-1.3: new full-speed USB device number 72 using musb-hdrc
    [40638.447848] usb 2-1.3: New USB device found, idVendor=05f9, idProduct=ffff
    [40638.470839] usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    [40638.499722] usb 2-1.3: Product: GD32 Trible CDC
    [40638.507366] usb 2-1.3: Manufacturer: GigaDevice
    [40638.521625] usb 2-1.3: SerialNumber: GD32E10X-V2.0.0-4b5c6de
    [40638.533533] cdc_acm 2-1.3:1.0: ttyACM0: USB ACM device
    [40638.573457] cdc_acm 2-1.3:1.2: ttyACM1: USB ACM device
    Down !

    [40649.944852] cdc_acm 2-1.3:1.0: failed to set dtr/rts
    [40649.971345] cdc_acm 2-1.3:1.2: failed to set dtr/rts
    [40650.056430] usb 2-1.3: USB disconnect, device number 72
    Power ON/OFF count=2656

  • Can you please describe the detail of your test setup? You use a GPIO on AM3358 to control on/off of the GD32 USB device power supply, right? How do you perform the data transfer? Please share the script or program. I want to see if I can reproduce the issue.

  • Hi Bin

            Yes, The GD32 USB device is USB-UART module  for two RS485.  We connetion two RS485 echo other and transfer data with loopback . While the transmission is going,power on/off the module by GPIO. We test it automatically through shell. One process transfer data Continuous,one process power on/off the module. Meanwhile,it record the count of power on/off.  After 2000 times ,it can't enumerate the device any more. the port of hub is abnormal. But the patch can improve the issue apparently. Look forward to you.thansks

    best regards

    Qiang Luo

  • Hi Qiang,

    Thanks for the details. After the enumeration failed at the end, if you unplug the hub and plug it back, does the GD32 device get enumerated again?

    I will try to create the same test case, but it would take some time. I will keep you posted.

  • Hi Bin

               Yes,if reset the hub,the GD32 device will work again. We can reset the hub by GPIO.

  • Great, it does sound like the issue is till on the hub handling. I will look into it.

  • Hi Bin

    Do you have some progress? Look forward to you. Thank you 

  • Hi Qiang,

    Sorry for my late response. I have spent last week on this issue, but I am unable to find the root cause of the enumeration failure. I captured multiple USB bus traces when the failure happened, but none of them showed any SPLIT transaction error.

    One way I can workaround the issue is to reset the USB hub when the driver detects full-speed device enumeration failure, the problem with this workaround is that if you have other USB devices connected to the hub, they would be reset too. Please let me know if this workaround works for your use case, I will implement it in the kernel driver.

  • Hi Qiang,

    I haven't heard your confirmation if the workaround mentioned in my previous post is acceptable or not, but I am posting the workaround patches below. Please test them along with the clear_tt_buffer patch you got from the Linux community and let me know if you have any questions.

    From cd0160602233bb9d305d2e81c834410976c54b02 Mon Sep 17 00:00:00 2001
    From: Bin Liu <b-liu@ti.com>
    Date: Mon, 3 Feb 2020 14:43:19 -0600
    Subject: [PATCH 1/3] [hack] usb: musb: power cycle the hub if downstream
     device enum failed
    
    Signed-off-by: Bin Liu <b-liu@ti.com>
    ---
     drivers/usb/core/hub.c       |  2 ++
     drivers/usb/musb/musb_host.c | 19 +++++++++++++++++++
     2 files changed, 21 insertions(+)
    
    diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
    index b33ec768404b..8df0ca5854c2 100644
    --- a/drivers/usb/core/hub.c
    +++ b/drivers/usb/core/hub.c
    @@ -4814,6 +4814,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
     	if (retval) {
     		hub_port_disable(hub, port1, 0);
     		update_devnum(udev, devnum);	/* for disconnect processing */
    +		if (hdev != hcd->self.root_hub)
    +			hcd->driver->relinquish_port(hcd, port1);
     	}
     	mutex_unlock(hcd->address0_mutex);
     	return retval;
    diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
    index 2e3ff723f576..e039db38e858 100755
    --- a/drivers/usb/musb/musb_host.c
    +++ b/drivers/usb/musb/musb_host.c
    @@ -2708,6 +2708,24 @@ static void musb_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
     }
     #endif /* !CONFIG_MUSB_PIO_ONLY */
     
    +static void musb_relinquish_port(struct usb_hcd *hcd, int port1)
    +{
    +	struct musb	*musb = hcd_to_musb(hcd);
    +	void __iomem *mbase = musb->mregs;
    +	u8 devctl;
    +
    +	devctl = musb_readb(mbase, MUSB_DEVCTL);
    +	if (!devctl & MUSB_DEVCTL_SESSION)
    +		return;
    +
    +	dev_info(musb->controller, "toggle VBUS to power cycle hub\n");
    +	devctl &= ~MUSB_DEVCTL_SESSION;
    +	musb_writeb(mbase, MUSB_DEVCTL, devctl);
    +	msleep(1000);
    +	devctl |= MUSB_DEVCTL_SESSION;
    +	musb_writeb(mbase, MUSB_DEVCTL, devctl);
    +}
    +
     static const struct hc_driver musb_hc_driver = {
     	.description		= "musb-hcd",
     	.product_desc		= "MUSB HDRC host driver",
    @@ -2736,6 +2754,7 @@ static const struct hc_driver musb_hc_driver = {
     	.hub_control		= musb_hub_control,
     	.bus_suspend		= musb_bus_suspend,
     	.bus_resume		= musb_bus_resume,
    +	.relinquish_port	= musb_relinquish_port,
     	/* .start_port_reset	= NULL, */
     	/* .hub_irq_enable	= NULL, */
     	.clear_tt_buffer_complete = musb_clear_tt_buffer_complete,
    -- 
    2.17.1
    
    

    From ae6168eb77233ceb45bfc4b5ec783b67dd32cfe7 Mon Sep 17 00:00:00 2001
    From: Bin Liu <b-liu@ti.com>
    Date: Mon, 3 Feb 2020 14:44:31 -0600
    Subject: [PATCH 2/3] [hack] usb: hub: reset TT when full-speed device detached
     from hub
    
    Signed-off-by: Bin Liu <b-liu@ti.com>
    ---
     drivers/usb/core/hub.c | 9 +++++++++
     1 file changed, 9 insertions(+)
    
    diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
    index 8df0ca5854c2..dbaf9e7c225a 100644
    --- a/drivers/usb/core/hub.c
    +++ b/drivers/usb/core/hub.c
    @@ -5188,6 +5188,7 @@ static void port_event(struct usb_hub *hub, int port1)
     	struct usb_device *udev = port_dev->child;
     	struct usb_device *hdev = hub->hdev;
     	u16 portstatus, portchange;
    +	struct usb_hcd *hcd;
     
     	connect_change = test_bit(port1, hub->change_bits);
     	clear_bit(port1, hub->event_bits);
    @@ -5199,6 +5200,14 @@ static void port_event(struct usb_hub *hub, int port1)
     	if (portchange & USB_PORT_STAT_C_CONNECTION) {
     		usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
     		connect_change = 1;
    +		hcd = bus_to_hcd(hdev->bus);
    +		if (!(portstatus & USB_PORT_STAT_CONNECTION) &&
    +		    hdev != hcd->self.root_hub) {
    +			dev_info(&port_dev->dev, "RESET_TT\n");
    +			usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
    +					HUB_RESET_TT, USB_RT_PORT,
    +					0, port1, NULL, 0, 1000);
    +		}
     	}
     
     	if (portchange & USB_PORT_STAT_C_ENABLE) {
    -- 
    2.17.1
    
    

    From 82a7867f8dee3fcfbe8980585a1dc38bc43cd5af Mon Sep 17 00:00:00 2001
    From: Bin Liu <b-liu@ti.com>
    Date: Wed, 5 Feb 2020 10:12:50 -0600
    Subject: [PATCH 3/3] [hack] usb: hub: reset TT when clear TT buffer failed
    
    Signed-off-by: Bin Liu <b-liu@ti.com>
    ---
     drivers/usb/core/hub.c | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
    index dbaf9e7c225a..6ff19c4a8117 100644
    --- a/drivers/usb/core/hub.c
    +++ b/drivers/usb/core/hub.c
    @@ -763,10 +763,15 @@ static void hub_tt_work(struct work_struct *work)
     		/* drop lock so HCD can concurrently report other TT errors */
     		spin_unlock_irqrestore(&hub->tt.lock, flags);
     		status = hub_clear_tt_buffer(hdev, clear->devinfo, clear->tt);
    -		if (status && status != -ENODEV)
    +		if (status && status != -ENODEV) {
     			dev_err(&hdev->dev,
     				"clear tt %d (%04x) error %d\n",
     				clear->tt, clear->devinfo, status);
    +			dev_info(&hdev->dev, "RESET_TT on clearing tt error\n");
    +			usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
    +					HUB_RESET_TT, USB_RT_PORT,
    +					0, clear->tt, NULL, 0, 1000);
    +		}
     
     		/* Tell the HCD, even if the operation failed */
     		drv = clear->hcd->driver;
    -- 
    2.17.1