diff options
author | Wesley Cheng <quic_wcheng@quicinc.com> | 2022-04-14 00:39:02 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-04-23 10:33:52 +0200 |
commit | 2840d6dfcf4306878f7d17ac16d4a0a6422728cc (patch) | |
tree | 1b5d43e3817702576e1af787ae99c7c3aac2dfeb /drivers/usb/dwc3/core.h | |
parent | 0f01017191384e3962fa31520a9fd9846c3d352f (diff) |
usb: dwc3: EP clear halt leading to clearing of delayed_status
The usb_ep_clear_halt() API can be called from the function driver, and
translates to dwc3_gadget_ep_set_halt(). This routine is shared with when
the host issues a clear feature ENDPOINT_HALT, and is differentiated by the
protocol argument. If the following sequence occurs, there can be a
situation where the delayed_status flag is improperly cleared for the wrong
SETUP transaction:
1. Vendor specific control transfer returns USB_GADGET_DELAYED_STATUS.
2. DWC3 gadget sets dwc->delayed_status to '1'.
3. Another function driver issues a usb_ep_clear_halt() call.
4. DWC3 gadget issues dwc3_stop_active_transfer() and sets
DWC3_EP_PENDING_CLEAR_STALL.
5. EP command complete interrupt triggers for the end transfer, and
dwc3_ep0_send_delayed_status() is allowed to run, as delayed_status
is '1' due to step#1.
6. STATUS phase is sent, and delayed_status is cleared.
7. Vendor specific control transfer is finished being handled, and issues
usb_composite_setup_continue(). This results in queuing of a data
phase.
Cache the protocol flag so that DWC3 gadget is aware of when the clear halt
is due to a SETUP request from the host versus when it is sourced from a
function driver. This allows for the EP command complete interrupt to know
if it needs to issue a delayed status phase.
Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
Link: https://lore.kernel.org/r/20220414073902.21960-1-quic_wcheng@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/dwc3/core.h')
-rw-r--r-- | drivers/usb/dwc3/core.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5c9d467195a6..81c486b3941c 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1046,6 +1046,7 @@ struct dwc3_scratchpad_array { * @tx_thr_num_pkt_prd: periodic ESS transmit packet count * @tx_max_burst_prd: max periodic ESS transmit burst size * @tx_fifo_resize_max_num: max number of fifos allocated during txfifo resize + * @clear_stall_protocol: endpoint number that requires a delayed status phase * @hsphy_interface: "utmi" or "ulpi" * @connected: true when we're connected to a host, false otherwise * @softconnect: true when gadget connect is called, false when disconnect runs @@ -1266,6 +1267,7 @@ struct dwc3 { u8 tx_thr_num_pkt_prd; u8 tx_max_burst_prd; u8 tx_fifo_resize_max_num; + u8 clear_stall_protocol; const char *hsphy_interface; |