Skip to content

Commit 4db0fbb

Browse files
Thinh Nguyengregkh
authored andcommitted
usb: dwc3: gadget: Don't delay End Transfer on delayed_status
The gadget driver may wait on the request completion when it sets the USB_GADGET_DELAYED_STATUS. Make sure that the End Transfer command can go through if the dwc->delayed_status is set so that the request can complete. When the delayed_status is set, the Setup packet is already processed, and the next phase should be either Data or Status. It's unlikely that the host would cancel the control transfer and send a new Setup packet during End Transfer command. But if that's the case, we can try again when ep0state returns to EP0_SETUP_PHASE. Fixes: e1ee843 ("usb: dwc3: gadget: Force sending delayed status during soft disconnect") Cc: [email protected] Signed-off-by: Thinh Nguyen <[email protected]> Link: https://lore.kernel.org/r/3f9f59e5d74efcbaee444cf4b30ef639cc7b124e.1666146954.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d182c2e commit 4db0fbb

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

drivers/usb/dwc3/gadget.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1698,6 +1698,16 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
16981698
cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
16991699
memset(&params, 0, sizeof(params));
17001700
ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
1701+
/*
1702+
* If the End Transfer command was timed out while the device is
1703+
* not in SETUP phase, it's possible that an incoming Setup packet
1704+
* may prevent the command's completion. Let's retry when the
1705+
* ep0state returns to EP0_SETUP_PHASE.
1706+
*/
1707+
if (ret == -ETIMEDOUT && dep->dwc->ep0state != EP0_SETUP_PHASE) {
1708+
dep->flags |= DWC3_EP_DELAY_STOP;
1709+
return 0;
1710+
}
17011711
WARN_ON_ONCE(ret);
17021712
dep->resource_index = 0;
17031713

@@ -3719,7 +3729,7 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
37193729
* timeout. Delay issuing the End Transfer command until the Setup TRB is
37203730
* prepared.
37213731
*/
3722-
if (dwc->ep0state != EP0_SETUP_PHASE) {
3732+
if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status) {
37233733
dep->flags |= DWC3_EP_DELAY_STOP;
37243734
return;
37253735
}

0 commit comments

Comments
 (0)