Possible USB peripheral issue on Rock 5B+ (missing DISCONNECT event)?

On the Rock 5B+ (and possibly other Radxa SBCs as well), when using the appropriate USB port in peripheral mode with the Mass Storage Gadget function, the dwc3_gadget_interrupt function in the kernel’s DWC3 gadget driver does not receive a DWC3_DEVICE_EVENT_DISCONNECT event when the USB cable is unplugged or the host disconnects.

Driver source:

This leads to incorrect gadget behavior, where the USB controller does not return to a default or idle state — the current_speed field does not become UNKNOWN , but instead remains stuck in super-speed , high-speed , or even full-speed speed. As a result, on the next USB connection attempt, the gadget may not re-enumerate properly or not show up at all on the host.

Can someone with hardware or kernel knowledge confirm whether this issue is caused by a hardware limitation or bug, or perhaps something else? On other vendor SBCs using similar SoCs and USB configurations, the DWC3_DEVICE_EVENT_DISCONNECT is correctly generated when unplugging the USB cable.

I recorded a dwc3_event trace log on both the Orange Pi 5 Ultra and the Rock 5B+ while unplugging the USB cable and then reconnecting it after a few seconds.

As you can see, on the Orange Pi, after the cable is unplugged, the Suspend event is followed by a proper Disconnect event. Then, after a short wait, reconnecting the cable triggers the expected Reset and Connection Done events.

However, on the Rock 5B+, the same sequence only produces the Suspend event — the Disconnect event is missing. After a short pause, I see a duplicated pair of Reset and Connection Done events, which could be a result of the missing disconnect. Then I tried to repeat the procedure again, but this time the Mass Storage Gadget did not reappear, and the trace log remained empty — so it seems something may have locked up outside the gadget driver.

Orange Pi 5 Ultra trace log:

root@orangepi-5-ultra:/home/orangepi# cat /sys/kernel/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 942/942   #P:8
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
     irq/77-dwc3-2541    [000] D....  1421.469777: dwc3_event: event (00006084): ep1out: Transfer In Progress [00000000] (SIm)
     irq/77-dwc3-2541    [000] D....  1421.470542: dwc3_event: event (00004086): ep1in: Transfer In Progress [00000000] (sIm)
     irq/77-dwc3-2541    [000] D....  1421.470570: dwc3_event: event (00006084): ep1out: Transfer In Progress [00000000] (SIm)
     irq/77-dwc3-2541    [000] D....  1421.470879: dwc3_event: event (00004086): ep1in: Transfer In Progress [00000000] (sIm)
     irq/77-dwc3-2541    [000] D....  1421.470912: dwc3_event: event (00130601): Suspend [U3]
     irq/77-dwc3-2541    [000] D....  1424.184725: dwc3_event: event (00000001): Disconnect: [U0]
     irq/77-dwc3-2541    [000] D....  1431.312894: dwc3_event: event (00000101): Reset [U0]
     irq/77-dwc3-2541    [000] D....  1431.317971: dwc3_event: event (00000201): Connection Done [U0]
     irq/77-dwc3-2541    [000] D....  1431.318477: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/77-dwc3-2541    [000] D....  1431.318503: dwc3_event: event (000020c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.318523: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.318668: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/77-dwc3-2541    [000] D....  1431.318712: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.318749: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.318763: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.318799: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.320915: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/77-dwc3-2541    [000] D....  1431.320947: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.321006: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.321014: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.321060: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.321159: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/77-dwc3-2541    [000] D....  1431.321180: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.321227: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.321234: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.321278: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Status Phase]
     irq/77-dwc3-2541    [000] D....  1431.321510: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/77-dwc3-2541    [000] D....  1431.321539: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.321600: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/77-dwc3-2541    [000] D....  1431.321608: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     ...

Rock 5B+ trace log:

root@rock-5b-plus:~# cat /sys/kernel/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1163/1163   #P:8
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
     irq/81-dwc3-1715    [000] D....  1121.272296: dwc3_event: event (00030601): Suspend [U3]
     irq/81-dwc3-1715    [000] D....  1131.913846: dwc3_event: event (00000101): Reset [U0]
     irq/81-dwc3-1715    [000] D....  1131.916039: dwc3_event: event (00000201): Connection Done [U0]
     irq/81-dwc3-1715    [000] D....  1131.916208: dwc3_event: event (00000101): Reset [U0]
     irq/81-dwc3-1715    [000] D....  1131.919440: dwc3_event: event (00000201): Connection Done [U0]
     irq/81-dwc3-1715    [000] D....  1131.969191: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/81-dwc3-1715    [000] D....  1131.969230: dwc3_event: event (000020c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.969263: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.969287: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/81-dwc3-1715    [000] D....  1131.969327: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.969342: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.969354: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.969373: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.971607: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/81-dwc3-1715    [000] D....  1131.971650: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.971665: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.971676: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.971695: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.971762: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/81-dwc3-1715    [000] D....  1131.971786: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.971801: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.971813: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.971839: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.971960: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/81-dwc3-1715    [000] D....  1131.971990: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.972006: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.972014: dwc3_event: event (000020c0): ep0out: Transfer Not Ready [00000000] (Not Active) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.972034: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Status Phase]
     irq/81-dwc3-1715    [000] D....  1131.972167: dwc3_event: event (0000c040): ep0out: Transfer Complete (sIL) [Setup Phase]
     irq/81-dwc3-1715    [000] D....  1131.972191: dwc3_event: event (000010c2): ep0in: Transfer Not Ready [00000000] (Not Active) [Data Phase]
     irq/81-dwc3-1715    [000] D....  1131.972207: dwc3_event: event (0000c042): ep0in: Transfer Complete (sIL) [Data Phase]
     ...
2 Likes

@RadxaYuntian, @Jack, @Nasca could you please look into this issue?
In peripheral mode, USB is unusable in this state, which makes the project I’m working on unfeasible.
The most important question is whether the hardware generates an interrupt after the USB cable is disconnected.

There are 2 OTG ports. Are both behaving like this?
CC @ken

@RadxaYuntian Yes, both USB ports show the same behavior. I also tested it under Armbian, and the issue is exactly the same there as well.