Commit Graph
2 Commits
Author SHA1 Message Date
NoahandClaude Opus 5 4a5481b6a5 Instrument the dwc3 OTG path to test the guard
The guard alone did not fix flare-edge#160: with dr_mode="otg" and the live
re-init skipped, the controller still died 14s after carrier-on under load
(carrier 54.1s, first Tx timeout 63.4s, HC died 68.4s).

That means either the OTG event path is not the trigger, or the harm comes from
somewhere else in it. dr_mode="host" removes far more than this one call: it
also skips dwc3_otgregs_init() and hands port-power control to xHCI instead of
the OTG block.

IRQ 47 is shared between dwc3-otg and xhci-hcd, so /proc/interrupts cannot say
whether OTG events fire at all. CONFIG_DYNAMIC_DEBUG is off, so dev_dbg is
compiled out and invisible.

So this build logs, ratelimited and always compiled:
  - every OTG hardware event with its OEVT value, role and restart flag
  - each time the guard skips a re-init on a live host

Run under load, that answers whether the OTG path is even active during the
failure window, instead of guessing a third patch.

Also worth measuring: load accelerates this dramatically -- 452-587s idle
versus 9-14s under line-rate traffic -- so idle soaks are not comparable to
load tests and earlier comparisons need re-reading with that in mind.

Refs flare-edge#160

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MVGTC78dgCGfRANNKjoPea
2026-09-22 17:34:51 -06:00
NoahandClaude Opus 5 9ff60d60db Do not re-init OTG host registers on a live controller
dwc3_otg_host_init() carries the comment "should be called before Host
controller driver is started". It rewrites OCTL/OCFG, touches GUSB2PHYCFG and
re-asserts port power (OCTL.PrtPwrCtl).

dwc3_otg_irq() sets otg_restart_host ONLY when current_otg_role is already
DWC3_OTG_ROLE_HOST. The threaded handler then calls dwc3_otg_host_init()
unconditionally, so that path always ran against a live, running host -- the
exact condition the comment forbids. Re-asserting port power under a running
xHCI corrupts an in-flight command.

Observed on the RV1106 86-panel as the controller failing to answer a Stop
Endpoint command, after which xhci-hcd declares it dead and tears the bus down.
An r8152 USB NIC stalls a transfer and the controller died 8 times out of 8
between 452s and 587s. Compiling the OTG path out entirely (dr_mode=host)
survived 1810s with zero deaths, which localised it here.

On this board the event is always spurious: the dwc3 node deliberately carries
no extcon, because wiring it pins the role to peripheral on D1-modded panels,
and CONIDSTS reads 0 -- so the role cannot legitimately change while host is
current. Skip the re-init in that case and log it at debug level.

This does not remove the restart capability. dwc3_set_mode() still runs
immediately below, and if the role has genuinely changed dwc3_otg_update()
performs a proper dwc3_host_exit() before re-initialising. The only behaviour
removed is poking a running controller, which was never legitimate.

Refs flare-edge#160

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MVGTC78dgCGfRANNKjoPea
2026-09-22 16:54:54 -06:00