diff options
| author | hathach <[email protected]> | 2026-06-13 00:20:37 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2026-06-13 23:34:57 +0700 |
| commit | 91608e3c4f8c944674547e5c254759c1dda08379 (patch) | |
| tree | afdb77febbdf7d062bd41cc8bb0747a3057972a9 /lib/rt-thread/SConscript | |
| parent | 1ea385a6c431cee759695515a4bed94c6dff65c6 (diff) | |
dcd/musb: fix deferred-SETUP replay racing usbd's status call
STATUS_OUT_PENDING conflated "edpt0_xfer(STATUS OUT) called, awaiting
confirm IRQ" with "confirm IRQ seen, awaiting edpt0_xfer". The
deferral path completed the status and replayed the saved SETUP from
the ISR in both flavors; in the IRQ-first one, usbd's still-
outstanding edpt0_xfer(STATUS OUT) for the old transfer (queued via
status_stage_xact) then landed in the replayed transfer's state and
corrupted it: NULL pipe0.buf armed plus RXRDYC, so the host's next
DATA OUT drained through a NULL pointer. usbd processes EP0
XFER_COMPLETE events unconditionally, so nothing downstream defuses
it.
Split the state into STATUS_OUT_PENDING_XFER / _IRQ. The deferral
completes and replays only in PENDING_XFER (old transfer already
retired); in PENDING_IRQ it only holds the SETUP and the usbd-driven
edpt0_xfer fires the completion and replays. The DATA_IN deferral now
synthesizes PENDING_IRQ (its remain==0 invariant asserted: a SETUP
before DataEnd raises SetupEnd instead), which also makes the old
deferred-promotion in the csrl==0 DATA_IN case unreachable - dropped.
Assert the drain buffer before the DATA OUT FIFO read as a cheap
backstop for this corruption class.
Review follow-up for #3643 (dcd_musb.c l.503 finding).
Co-Authored-By: Claude Fable 5 <[email protected]>
Diffstat (limited to 'lib/rt-thread/SConscript')
0 files changed, 0 insertions, 0 deletions
