Files
bfe-core1106-sdk/patches/28-dwc3-otg-no-live-reinit.patch
T
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

34 lines
1.1 KiB
Diff

diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -55,7 +55,17 @@
spin_lock(&dwc->lock);
if (dwc->otg_restart_host) {
- dwc3_otg_host_init(dwc);
+ /*
+ * flare-edge#160: dwc3_otg_host_init() is documented as "should be
+ * called before Host controller driver is started" but this path
+ * only ever runs while current_otg_role is already HOST. Skip it
+ * on a live host and record that we did.
+ */
+ if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST)
+ dev_warn_ratelimited(dwc->dev,
+ "OTGDIAG skipped host re-init on live host\n");
+ else
+ dwc3_otg_host_init(dwc);
dwc->otg_restart_host = false;
}
@@ -83,6 +93,10 @@
if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST &&
!(reg & DWC3_OEVT_DEVICEMODE))
dwc->otg_restart_host = true;
+ /* flare-edge#160 diagnostic: is the OTG event path active at all? */
+ dev_warn_ratelimited(dwc->dev,
+ "OTGDIAG irq OEVT=0x%08x role=%u restart=%d\n",
+ reg, dwc->current_otg_role, dwc->otg_restart_host);
dwc3_writel(dwc, DWC3_OEVT, reg);
ret = IRQ_WAKE_THREAD;
}