diff options
| author | hathach <[email protected]> | 2026-04-24 12:04:56 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2026-04-26 11:51:49 +0700 |
| commit | d3107be360b45c4b8dbc223dcc5e5f57b582c5ff (patch) | |
| tree | 5fe81a43ee805c78546a2d6c590a6edd42187365 /src | |
| parent | 8a63f9c57ee29bd34367c347663e86fe432a0a37 (diff) | |
usbd_control: consolidate status stage ep selection
Extract the "which endpoint is the Status stage on" rule into a single
TU_ATTR_ALWAYS_INLINE helper, and use it from both status_stage_xact()
and the completion callback. Replaces the two-operand wLength/direction
check with a direct endpoint-match comparison, matching the first
operand's pattern.
Per USB 2.0 §9.3.1, when wLength == 0 the bmRequestType Direction bit
is ignored and the Status stage is always IN; otherwise the Status
stage is opposite to the Data stage direction.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/device/usbd_control.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 1ec9b4649..b5dae7d59 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -71,15 +71,17 @@ uint8_t* usbd_get_ctrl_buf(void) { // Application API //--------------------------------------------------------------------+ +// Endpoint used for the Status stage of a control transfer. +// Per USB 2.0 §9.3.1, when wLength == 0 the Direction bit is ignored and the Status stage +// is always IN. Otherwise the Status stage is opposite to the Data stage direction. +TU_ATTR_ALWAYS_INLINE static inline uint8_t status_stage_ep(const tusb_control_request_t* request) { + if (request->wLength == 0) return EDPT_CTRL_IN; + return request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; +} + // Queue ZLP status transaction -static inline bool status_stage_xact(uint8_t rhport, const tusb_control_request_t* request) { - // Always use EDPT_CTRL_IN when control request wLength is zero - if (request->wLength==0) { - return usbd_edpt_xfer(rhport, EDPT_CTRL_IN, NULL, 0, false); - } - // Opposite to endpoint in Data Phase - const uint8_t ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; - return usbd_edpt_xfer(rhport, ep_addr, NULL, 0, false); +TU_ATTR_ALWAYS_INLINE static inline bool status_stage_xact(uint8_t rhport, const tusb_control_request_t* request) { + return usbd_edpt_xfer(rhport, status_stage_ep(request), NULL, 0, false); } // Status phase @@ -160,10 +162,8 @@ void usbd_control_set_request(const tusb_control_request_t* request) { bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; - // Endpoint Address is opposite to direction bit, this is Status Stage complete event - // Control request with zero wLength and IN direction also is Status Stage complete event - if ((tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction)|| - (_ctrl_xfer.request.wLength==0&&_ctrl_xfer.request.bmRequestType_bit.direction==TUSB_DIR_IN)) { + // Status Stage complete: callback endpoint matches the Status stage endpoint + if (ep_addr == status_stage_ep(&_ctrl_xfer.request)) { TU_ASSERT(0 == xferred_bytes); // invoke optional dcd hook if available |
