summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-06-13 00:17:07 +0700
committerhathach <[email protected]>2026-06-13 23:34:57 +0700
commit06b8f4f013a6ce0d91d2f713c88313569d8a722c (patch)
treefd1f88f490eedecc99edcc10b79b31099c5a32e5 /src
parent3d745ee9d62414e7bd0c255b833715c5261edeee (diff)
dcd/musb: extract pipe0_read_setup() helper
The 8-byte EP0 SETUP drain (count0 assert + two FIFO word reads via a union) was duplicated verbatim between the IDLE case and the deferral case; a future fix applied to one copy but not the other would only show up on the rare deferred-race path. Share one helper. count0 is now read inside the only remaining user (DATA OUT drain). Review follow-up for #3643 (dcd_musb.c l.507 finding). Co-Authored-By: Claude Fable 5 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/portable/mentor/musb/dcd_musb.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index e00585068..08d7dd700 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -104,6 +104,19 @@ typedef struct {
static dcd_data_t _dcd;
+// Drain a SETUP packet (8 bytes) from the EP0 FIFO. Does not ack RxPktRdy.
+static bool pipe0_read_setup(musb_regs_t* musb_regs, musb_ep_csr_t* ep_csr, tusb_control_request_t* req) {
+ TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->count0);
+ union {
+ tusb_control_request_t req;
+ uint32_t u32[2];
+ } setup_packet;
+ setup_packet.u32[0] = musb_regs->fifo[0];
+ setup_packet.u32[1] = musb_regs->fifo[0];
+ *req = setup_packet.req;
+ return true;
+}
+
static void pipe0_start_setup(uint8_t rhport, musb_ep_csr_t* ep_csr,
tusb_control_request_t const* req, bool is_isr) {
_dcd.pipe0.remain_wlength = req->wLength;
@@ -466,23 +479,18 @@ static void process_ep0(uint8_t rhport) {
// Receive Data (Setup or OUT)
if (csrl & MUSB_CSRL0_RXRDY) {
- const uint16_t count0 = ep_csr->count0;
switch (_dcd.pipe0.state) {
case PIPE0_STATE_IDLE: {
- TU_ASSERT(sizeof(tusb_control_request_t) == count0, );
- union {
- tusb_control_request_t req;
- uint32_t u32[2];
- } setup_packet;
- setup_packet.u32[0] = musb_regs->fifo[0];
- setup_packet.u32[1] = musb_regs->fifo[0];
- pipe0_start_setup(rhport, ep_csr, &setup_packet.req, true);
+ tusb_control_request_t req;
+ TU_VERIFY(pipe0_read_setup(musb_regs, ep_csr, &req), );
+ pipe0_start_setup(rhport, ep_csr, &req, true);
break;
}
case PIPE0_STATE_DATA_OUT: {
// EP0 OUT is single-packet (TU_ASSERT total_bytes <= EP0_SIZE in edpt0_xfer)
// so the whole packet drains in one shot.
+ const uint16_t count0 = ep_csr->count0;
if (count0) {
tu_hwfifo_read(&musb_regs->fifo[0], _dcd.pipe0.buf, count0, NULL);
_dcd.pipe0.remain_wlength -= count0;
@@ -503,15 +511,7 @@ static void process_ep0(uint8_t rhport) {
case PIPE0_STATE_STATUS_OUT_PENDING:
case PIPE0_STATE_STATUS_IN:
case PIPE0_STATE_DATA_IN: {
- TU_ASSERT(sizeof(tusb_control_request_t) == count0, );
- union {
- tusb_control_request_t req;
- uint32_t u32[2];
- } setup_packet;
- setup_packet.u32[0] = musb_regs->fifo[0];
- setup_packet.u32[1] = musb_regs->fifo[0];
-
- _dcd.pipe0.deferred_setup = setup_packet.req;
+ TU_VERIFY(pipe0_read_setup(musb_regs, ep_csr, &_dcd.pipe0.deferred_setup), );
_dcd.pipe0.deferred_setup_valid = true;
goto process_status;
}