USB Hub enumeration fails with Colibri iMX7D

We have troubles getting the USB hub to run correctly: Initially, the hub is detected correctly, but when connecting certain types of devices (mainly a GSM module, but we saw this with a BLE stick as well), the hub fails to enumerate the devices and gets deleted:

[ 1294.870223] usb 1-1: USB disconnect, device number 2
[ 1294.877374] usb usb1-port1: cannot reset (err = -32)
[ 1294.884812] usb usb1-port1: cannot reset (err = -32)
[ 1294.891505] usb usb1-port1: cannot reset (err = -32)
[ 1294.897996] usb usb1-port1: cannot reset (err = -32)
[ 1294.904746] usb usb1-port1: cannot reset (err = -32)
[ 1294.911033] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 1294.918954] usb usb1-port1: cannot reset (err = -32)
[ 1294.925267] usb usb1-port1: cannot reset (err = -32)
[ 1294.931513] usb usb1-port1: cannot reset (err = -32)
[ 1294.937688] usb usb1-port1: cannot reset (err = -32)
[ 1294.943853] usb usb1-port1: cannot reset (err = -32)
[ 1294.949948] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 1294.957679] usb usb1-port1: attempt power cycle
[ 1295.300318] usb usb1-port1: cannot reset (err = -32)
[ 1295.306476] usb usb1-port1: cannot reset (err = -32)
[ 1295.313000] usb usb1-port1: cannot reset (err = -32)
[ 1295.318975] usb usb1-port1: cannot reset (err = -32)
[ 1295.325358] usb usb1-port1: cannot reset (err = -32)
[ 1295.331205] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 1295.338956] usb usb1-port1: cannot reset (err = -32)
[ 1295.345016] usb usb1-port1: cannot reset (err = -32)
[ 1295.350960] usb usb1-port1: cannot reset (err = -32)
[ 1295.356619] usb usb1-port1: cannot reset (err = -32)
[ 1295.362539] usb usb1-port1: cannot reset (err = -32)
[ 1295.368086] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 1295.375274] usb usb1-port1: unable to enumerate USB device

A hard reset of the hub chip restarts enumeration, and sometimes (>10 retries) it succeeds. Our suspicion is that this is related to power management: Using a Colibri VF61 board (different USB IP block I guess), everything works as expected.
Also, if we attach an additional USB hub that is self-powered and connect the module to this second hub, everything works.
If we connect another USB device (say, memory stick) to a port and then add the GSM module enumeration works as well.

The 5V supply is routed right nearby and can supply up to 10W, there are no noticable ripples on the Osci, increasing the 100u capacitors on the output ports has no effect as well.

We are using a custom board but have the same hub chip & configuration as on the Tordex eval board routed on it. We have replicated the behavior on the Toradex Eval board as well.

Did anyone see this as well? Any proposed workaround?

Simon

Some more information: This seems to be related to power management and timing: If we power down the ports via

echo 0 > /sys/devices/soc0/soc/30800000.aips-bus/30b20000.usb/ci_hdrc.0/usb1/1-1/1-1:1.0/1-1-port4/power/pm_qos_no_power_off

connect a device and re-enable the port with

echo 1 > /sys/devices/soc0/soc/30800000.aips-bus/30b20000.usb/ci_hdrc.0/usb1/1-1/1-1:1.0/1-1-port4/power/pm_qos_no_power_off

then device enumeration works as expected.

Simon

Another tidbit - we could work around the problem by adding an ugly long delay in git/drivers/usb/core/hub.c:

static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
{
   /// queries hub characteristics first

init2:               ///  line 1064 roughly
  msleep(900); //< insert long delay here

        /*                                                                                                                                                                                                           
         * Check each port and set hub->change_bits to let hub_wq know                                                                                                                                               
         * which ports need attention.                                                                                                                                                                               
         */
        for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
/// init individual ports
}
} 

This delays any device detection but works for us at the moment. Having a cleaner solution would be great…

Hi @svogl

We only have seen this error with some USB 3.0 devices as Harddisk as reported here and also reproduced this on our side. The issue seems related to the USB Power Management.

Best regards,
Jaski

Thanks for your Input. We will come back to you within this week.

it is definittely power/timing related as it seems; we see it very seldom with some BLE sticks, but consistently with a custom GSM module hosting a U-Blox Sara2 with fat capacitors at its internal power supply.
we have power indicator LEDs at the 5V output ports and we do see a considerable delay when bringing the hub chip out of reset. My guess: When releasing reset of the USB Hub (which is constantly powered), the hub enumerates instantly but the power rails of the 5V have not fully charged the downstream caps, resulting in this failure.

hi @svogl:
We still did not have time to work on this issue. We will come back soon to you.

Best regards,
Jaski

Hello,
did you find a solution or a workaround for this issue?
We have the same problem with different USB devices (storage key, badge and barcode reader), both on our proprietary board and on Toradex Evaluation Board using platform Colibri-iMX7-eMMC_LXDE-Image-Tezi_2.8b4.129.
Regards

gcrotti

Hi @gcrotti ,

Could you please state the HW version of the module and carrier you are using ?

Best Regards
Kevin

Hi @kevin.tx,
we are using module Colibri IMX7D 1GB v1.1A on Colibri Evaluation Board Rev. 3.2.
Same on our proprietary board, the ‘dmesg’ output is exactly the same reported by @svogl.
If you plugin the storage key or the badge/barcode reader after the boot it works correctly.
Regards

gcrotti

Hi @gcrotti,
did you try to introduce the delay in hub_activate() as suggested? That resolved the situation for us.
Simon

1 Like

Hello @svogl,
I recompiled the kernel and the delay resolved the problem.
Thanks

Giuliano

1 Like