mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
rp2040_update_buffer_control()/rp23xx_update_buffer_control() re-arm an endpoint buffer by setting the AVAILABLE bit in the buffer-control word, which lives in DPSRAM. When a buffer is re-armed from the completion path (rp2040_usbintr_buffstat/rp23xx_usbintr_buffstat), that runs after the handler has cleared the endpoint's bit in BUFF_STATUS, which lives in the USB controller register block -- a different peripheral region. The bus fabric may reorder those two stores. If the controller observes the AVAILABLE re-arm before the BUFF_STATUS clear lands, it can transmit the next IN packet and latch its completion in BUFF_STATUS before the clear arrives; the late clear then wipes that just-set completion bit. The lost completion edge stops all further buffer interrupts for the endpoint, so the class driver's write-complete callback never runs and TX wedges permanently. This is most visible on RP2350 (Cortex-M33) under dense/bursty IN traffic such as CDC-NCM with TCP write buffers. Add a UP_DMB() at the top of the AVAILABLE re-arm so the preceding BUFF_STATUS clear is ordered ahead of it. (Non-SMP builds reduce spin_lock_irqsave to a barrier-free up_irq_save, so nothing else orders these two stores.) Assisted-by: Claude (Anthropic Claude Code) Signed-off-by: Ricard Rosson <ricard@groundbits.com> |
||
|---|---|---|
| .. | ||
| arm | ||
| arm64 | ||
| avr | ||
| ceva | ||
| dummy | ||
| hc | ||
| mips | ||
| misoc | ||
| or1k | ||
| renesas | ||
| risc-v | ||
| sim | ||
| sparc | ||
| tricore | ||
| x86 | ||
| x86_64 | ||
| xtensa | ||
| z16 | ||
| z80 | ||
| CMakeLists.txt | ||
| Kconfig | ||