Any updates on this subject? I was investigating it myself with Stereolabs ZED 2i and ZED Mini cameras.
DGX Spark “HC died” with UVC cameras: ep0 control transfers AFTER stream-start wedge the MT8901
We root-caused the HC died crash (same signature as this thread). The trigger is an ep0 control transfer issued after the video stream has started. A capture pipeline that issues no ep0 traffic once streaming runs indeterminately (tested ~30min stream from the DGX Spark to my Host PC); an application that sends a UVC control (e.g. an extension-unit / ISP control: exposure, gain, register access) on ep0 after STREAMON wedges the controller. Confirmed with in-flight usbmon + xhci-hcd tracepoints, camera-agnostic.
Environment:
DGX Spark, DGX OS 7.5 / Ubuntu 24.04.4 (aarch64),
kernel 6.17.0-1021-nvidia.
Host = NVIDIA/MediaTek MT8901 (NVDA8000/PNP0D15, xhci-plat-hcd,
quirks 0x0008000000000010 = XHCI_NVIDIA_MT8901_HOST|SPURIOUS_SUCCESS).
Case A — works: gstreamer, NO ep0 after stream-start (ran 37 min clean)
gst-launch-1.0 v4l2src ! video/x-raw,YUY2,2560x720,30/1 ! jpegenc ! ... — pure UVC capture, no controls.
usbmon ep0 timeline (bus 4): UVC PROBE/COMMIT, then zero ep0 transfers until teardown:
21 01 0100 0001 SET_CUR PROBE ⇄ a1 81/82/83 GET_CUR/MIN/MAX (probe handshake)
21 01 0200 0001 SET_CUR COMMIT
── 25 s of PURE bulk-IN, ZERO ep0 control transfers ──
Recorded result (25 s window):
usbmon bulk-IN: 83327 × "C Bi:4:002:1 0 32768" (status 0, full payload)
0 × ESHUTDOWN(-108), 0 × stall(-32), 0 × proto(-71)
xhci tracepoints: ring_ep_doorbell 84122 ≈ handle_transfer 84103 (events posted 1:1)
HC died: 0
Case B — wedges: one ep0 control AFTER the stream commit
The identical ep0 control completes fine before the commit, then gets no completion event after it:
# BEFORE commit — completes in ~130 us:
S Ci:4:002:0 s a1 85 0200 0400 0002 2 <
C Ci:4:002:0 0 2 = 8001 # status 0, 2 bytes returned
# AFTER commit (stream running) — same request, NO completion event:
xhci_urb_enqueue ep0 length 0/2
xhci_queue_trb Setup / Data / Status
xhci_ring_ep_doorbell ep0in
── 5.117 s: NO xhci_handle_transfer, NO xhci_handle_event for this TD ──
xhci_urb_dequeue (5 s kernel timeout, -110)
xhci_queue_trb Stop Ring Command ── also gets NO completion ──
Host halt failed, -110
HC died; cleaning up ── takes down every device on the controller
The interrupt line is healthy throughout (hundreds of xhci_handle_transfer delivered for other traffic, no LOST EVENTS) — this is not a lost IRQ. After a stream-state transition the MT8901 simply stops posting completion events for the endpoint. (Same defect also seen as bulk-IN going silent on a 2nd stream of the same boot.)
Notes
- Not bandwidth/power: every mode works as the first stream incl. the highest-bandwidth ones; even 640×480 over USB3 crashes for others here; a powered/PD hub does not fix it (this thread + our bench).
- Can’t be recovered once wedged: a Stop-EP timeout falling through to a command-ring abort also times out
-110 — the controller is hung below the command-ring level. Only an electrical port reset (USBDEVFS_RESET/libusb_reset_device) re-inits the device. Host-side can prevent (reset before each stream, or force USB2, whose ep0 path does not wedge) but not repair.
- There is a second way to trigger the problem, open the stream twice in a row (open>close>open but a libusb_reset_device() (open>close>reset>open) made it so that i can restart the streaming without EP0 after closing the first stream.
Ask
Is there a controller/firmware fix in progress for the MT8901 completion engine going silent across a stream-state transition (the “ep0 after STREAMON” case is the easiest repro)? And once wedged below the command-ring level, is there any command-ring-free recovery the driver could do short of a reboot? Full captures available on request.