[PATCH AUTOSEL 4.19 032/100] usb: dwc3: gadget: clear DWC3_EP_TRANSFER_STARTED on cmd complete

From: Sasha Levin
Date: Fri Oct 18 2019 - 18:06:32 EST


From: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>

[ Upstream commit acbfa6c26f21a18830ee064b588c92334305b6af ]

We must wait until End Transfer completes in order to clear
DWC3_EP_TRANSFER_STARTED, otherwise we may confuse the driver.

This patch is in preparation to fix a rare race condition that happens
upon Disconnect Interrupt.

Tested-by: Thinh Nguyen <thinhn@xxxxxxxxxxxx>
Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
drivers/usb/dwc3/gadget.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 7b0957c530485..54de732550648 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -375,19 +375,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,

trace_dwc3_gadget_ep_cmd(dep, cmd, params, cmd_status);

- if (ret == 0) {
- switch (DWC3_DEPCMD_CMD(cmd)) {
- case DWC3_DEPCMD_STARTTRANSFER:
- dep->flags |= DWC3_EP_TRANSFER_STARTED;
- dwc3_gadget_ep_get_transfer_index(dep);
- break;
- case DWC3_DEPCMD_ENDTRANSFER:
- dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
- break;
- default:
- /* nothing */
- break;
- }
+ if (ret == 0 && DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
+ dep->flags |= DWC3_EP_TRANSFER_STARTED;
+ dwc3_gadget_ep_get_transfer_index(dep);
}

if (unlikely(susphy)) {
@@ -2417,7 +2407,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
cmd = DEPEVT_PARAMETER_CMD(event->parameters);

if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
- dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
+ dep->flags &= ~(DWC3_EP_END_TRANSFER_PENDING |
+ DWC3_EP_TRANSFER_STARTED);
dwc3_gadget_ep_cleanup_cancelled_requests(dep);
}
break;
--
2.20.1