Skip to content

Commit 5bef4a9

Browse files
mathieuchopstmjfischer-no
authored andcommitted
drivers: usb: udc: skeleton: handle special case of set_halt() for EP0
The UDC stack assumes that 'halt' on control endpoints is automatically cleared by device drivers and never calls udc_ep_clear_halt() for such endpoints. In practice, most controllers do perform this automatic clear in hardware, but this requires special handling in udc_ep_set_halt() for control endpoints (EP0), as setting the 'halted' bit on such endpoints will lead to the software getting out-of-sync with the hardware. Update the UDC skeleton driver to handle this edge case and add a comment documenting the stack's behavior, along with the hardware behavior expected by the code added to the skeleton driver for it to be functional. Co-authored-by: Johann Fischer <[email protected]> Signed-off-by: Mathieu CHOPLAIN <[email protected]>
1 parent 32c6776 commit 5bef4a9

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

drivers/usb/udc/udc_skeleton.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,27 @@ static int udc_skeleton_ep_set_halt(const struct device *dev,
160160
{
161161
LOG_DBG("Set halt ep 0x%02x", cfg->addr);
162162

163-
cfg->stat.halted = true;
163+
/*
164+
* NOTE: udc_ep_clear_halt() is not called for control endpoints.
165+
*
166+
* When an endpoint is halted or a control pipe request is not
167+
* supported, endpoint responds with a STALL handshake packet. The
168+
* specification distinguishes between a functional stall and a
169+
* protocol stall. The stack calls udc_ep_set_halt() to set a
170+
* functional or protocol stall. A protocol stall is unique to control
171+
* pipes and terminates at the beginning of the next control transfer.
172+
* Although a control pipe may support functional stall, it is not
173+
* recommended by the specification. The stack does not call
174+
* udc_ep_clear_halt() for control endpoints.
175+
*
176+
* How a driver clears a protocol stall depends on the implementation.
177+
* Some controllers automatically clear the protocol stall condition
178+
* when the next setup packet arrives, while others require software
179+
* intervention.
180+
*/
181+
if (USB_EP_GET_IDX(cfg->addr) != 0U) {
182+
cfg->stat.halted = true;
183+
}
164184

165185
return 0;
166186
}

0 commit comments

Comments
 (0)