ODROID-C1/-C2 USB Detection only triggered by some devices dwc2
Alan Stern
stern at rowland.harvard.edu
Wed Jul 21 08:58:17 PDT 2021
Minas, some of the things noted below may require your attention. In
particular, the usbmon traces don't show the root hub doing what it should,
which leads me to wonder whether the Genesys Logic hub attached to port 1
really is getting suspended and resumed properly.
On Tue, Jul 20, 2021 at 11:55:05PM +0200, Martin Blumenstingl wrote:
> > That's what it looks like to me too. This means that the hub on the
> > Odroid doesn't support remote wakeup properly. Or else the root hub
> > gets the remote-wakeup message and doesn't handle it properly. Either
> > way it's a pretty nasty bug for a significant piece of hardware.
> as a wild idea: I do have a 24MHz logic analyzer. If there was a way
> for me to force the communication between the hub and dwc2 to use
> "full speed" or or slower I might be able to look at the signals on
> the bus.
> in case you're aware of any possibility to force the communication to
> use a slower speed then please let me know.
In theory you don't need to worry about this. When a high-speed device such
as the Genesys Logic hub goes into suspend, it reverts to full-speed
signalling (see section 7.1.7.6 of the USB-2 specification).
As such, you can easily measure the change from a suspend signal to a wakeup
or resume signal, although you can't easily tell which device (the computer
or the hub) caused the change. A suspend signal has the D+ line steady at
high voltage (> 3 V) and the D- line at low voltage (close to 0 V). A
resume signal is the opposite, typically lasting only a few (or a few tens)
of microseconds.
> I misread your comment at first and used slightly different steps:
> - boot without usbcore.autosuspend=-1
> - plug in my Corsair Voyager USB 3.0 flash drive
> - start the usbmon dump
> - echo -1 >/sys/bus/usb/devices/1-1/power/autosuspend
> - (the flash drive is detected automatically)
> - stop the usbmon dump
>
> The result of this test can be found in:
> 0u.mon-odroidc1-plugged-after-boot-disable-autosuspend.out
This was the second attachment to your email.
> After that I did the test as I believe you're expecting it to be done:
> - plug in my Corsair Voyager USB 3.0 flash drive
> - boot without usbcore.autosuspend=-1
> - start the usbmon dump
> - echo -1 >/sys/bus/usb/devices/1-1/power/autosuspend
> - (the flash drive is detected automatically)
This is weird. Didn't you say earlier that doing the same thing, except for
using "lsusb -vvv" to wake up the GL hub rather than this sysfs write, would
not lead to the Corsair drive being detected?
> - stop the usbmon dump
>
> The result of this test can be found in:
> 0u.mon-odroidc1-plugged-during-boot-disable-autosuspend.out
That was the first attachment.
> In both tests I observe the following in the kernel log:
> usb 1-1: reset high-speed USB device number 2 using dwc2
> I assume that this brings the hub into a well-defined state where
> remote wakeup may not be relevant
I saw such a reset only in the first usbmon trace, not the second. It looks
like the reset was performed because of a communication error (the -71
status code near the beginning of the trace), but it's not at all clear why
the error occurred.
In fact, there were a few strange things in the traces. Let's look at the
start of the first one. The trace starts by showing the root hub
being resumed, which involves asking for the port status:
c57f1680 41352445 S Ci:1:001:0 s a3 00 0000 0001 0004 4 <
c57f1680 41352762 C Ci:1:001:0 0 4 = 03050000
The status for port 1 shows that the port isn't suspended and hasn't
undergone a wakeup transition. It's simply active, as though it had never
been suspended in the first place.
(For those unaccustomed to reading these traces, the 03050000 status value
above means the following: The two bits in the "3" are "Port connected" and
"Port enabled", and the two bits in the "5" are "Port power on" and "Port is
high-speed". If the port were still suspended, the 04000000 bit would be
set. Notably missing is the bit which would indicate "Port suspend status
change", which is in the 00000400 position and is supposed to be set
whenever the port is resumed because of a wakeup request from the attached
device.)
c5753280 41352977 S Ii:1:001:1 -115:2048 4 <
The shows the root hub's interrupt URB starting up, the last part of a
normal resume.
So was the GL hub actually suspended? It's hard to tell exactly what the
hardware's doing, but you can get a trace that will help. Do the following:
Boot with no device plugged in and with "usbcore.autosuspend=-1" on the
command line. Then start a usbmon trace.
Next, do
echo 2 >/sys/bus/usb/devices/1-1/power/autosuspend
and wait a few seconds for the GL hub to be suspended. To make sure it has,
do "grep . /sys/bus/usb/devices/1-1/power/*" and include the output in your
reply.
Then do
echo 2 >/sys/bus/usb/devices/usb1/power/autosuspend
and wait a few seconds for the root hub to be suspended. Again, to make
sure it has, do "grep . /sys/bus/usb/devices/usb1/power/*".
Once that has settled down, wake up the root hub by doing
echo -1 >/sys/bus/usb/devices/usb1/power/autosuspend
and a few seconds later, wake up the GL hub by doing
echo -1 >/sys/bus/usb/devices/1-1/power/autosuspend
All these suspends and resumes should show up in the usbmon trace. I'd like
to see what it really says; my guess is that it won't show quite what it
should.
> > It's possible to create a udev script that will perform this action
> > automatically at startup (does your OS use udev?). Again, the only way
> > to see if the Corsair drive will then work is to try it.
> I am an Arch Linux ARM user so udev scripts are possible.
>
> > If this doesn't work, I think the only solution will be a kernel patch.
> Personally I'd prefer a kernel patch (maybe with some flag in
> device-tree like broken-remote-wakeup) as from my understanding all
> Odroid-C1 and Odroid-C2 (both using Amlogic SoCs) boards are affected.
> As a reviewer of the Amlogic platform patches I'd rather avoid
> recommending some udev rules for every user.
I want to nail down the actual reason for the problem before recommending
any changes.
> > One other thought: It may be that the reason the Corsair drive and
> > others don't work when they are plugged in before boot-up is because
> > they are too slow to connect to the USB bus. That would cause the
> > Genesys Logic hub to go into runtime suspend before the drive is
> > detected, and then the hub never resumes because its remote wakeup
> > support is faulty.
> >
> > You can test this guess by plugging the Corsair drive into the Odroid
> > before booting, and adding "usbcore.autosuspend=10" to the boot command
> > line. This will cause the hub to delay for ten seconds before going
> > into runtime suspend, and that might be enough time for the drive to
> > connect to the bus and be detected.
> usbcore.autosuspend=10 doesn't make any difference for me, the device
> is still not detected.
> With autosuspend disabled it's quick to detect the device (I haven't
> timed it but it's below 2 seconds).
In the second usbmon trace, the detection required 2.05 seconds from the
time when the GL hub was resumed. This may explain why waking up the hub
with "lsusb -vvv" doesn't cause the drive to be detected; the hub may be
suspended again before the drive shows up.
But it doesn't tell us what happens during boot-up, and unfortunately
there's no way to start a usbmon trace at that time.
Alan Stern
More information about the linux-amlogic
mailing list