Escalate USB recovery when keyboard HID writes time out - #1516
Escalate USB recovery when keyboard HID writes time out#1516adamshiervani wants to merge 1 commit into
Conversation
After a UDC rebind, the RV1106 DWC3 race can leave /dev/hidg0 openable but non-functional: every write times out while the UDC still reports "configured". The rebind recovery path verified health by reopening the chardev — which succeeds in this state — and writeWithTimeout swallows the deadline errors (host-suspend tolerance), so nothing ever escalated to the full gadget reconfigure that actually fixes it. Keyboard input was silently dropped until the user manually cycled identifier profiles (#1512). Two complementary mechanisms: 1. Write-probe verification in the recovery ladder: after reopening the keyboard HID file, re-send the current keys-down state (a no-op for the host) and, unlike the regular report path, surface a timeout. While the UDC reports "configured", a reopen that probes broken is not success — the ladder escalates to the full reconfigure instead of declaring victory, fixing the gadget before the user ever types. 2. Runtime write-timeout streak: consecutive keyboard write timeouts are counted (reset on success, on recovery, and while the state is not "configured", where timeouts are expected — e.g. host suspend). When the streak reaches 3 while "configured", recovery runs the full reconfigure directly, rate-limited to one attempt per 30s. This catches breakage that occurs without a preceding detach event. Fixes #1512
|
Exact stacked candidate is now available in #1554 at It keeps the recovery ladder here, but makes acknowledgement synchronous: non- Deterministic pipe-stall tests cover first-failure and successful exact-byte delivery for every report path. Upstream Build and test, Go, UI, and CLA checks all pass at the exact head. No firmware was installed or flashed. |
|
Post-review candidate supersedes the earlier |
Fixes #1512
After a UDC rebind, the DWC3 race can leave
/dev/hidg0openable but dead: every write times out while the UDC still reportsconfigured. Recovery verifies health by reopening the chardev — which succeeds in that state — andwriteWithTimeoutswallows deadline errors (host-suspend tolerance), so the existing escalation to a full gadget reconfigure never fires. Keyboard input is silently dropped (mouse fine, stateconfigured) until identifier profiles are cycled by hand.Changes
configured→ escalate to the full reconfigure, so recovery completes before the user types.configured(where timeouts are expected, e.g. host suspend). 3 in a row whileconfigured→ full reconfigure, rate-limited to 30s. Covers breakage with no preceding detach.Testing
ra-hid-write-recoverye2e reproduces the bug deterministically: unbindusbhidfrom the gadget keyboard interface on the host → gadget writes time out whileconfigured. Fails ondev(keyboard dead for the full 120s window), passes here (recovery ~2s after the first timeout, confirmed by re-enumeration in host dmesg).hidg0unusable converges via ladder → reconfigure in one extra re-enumeration — no input needed, no reconfigure loop after.