diff mbox series

[3/4] usb: dwc3: gadget: early giveback if End Transfer already completed

Message ID 20190124072501.15100-3-felipe.balbi@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series [1/4] usb: dwc3: gadget: clear DWC3_EP_TRANSFER_STARTED on cmd complete | expand

Commit Message

Felipe Balbi Jan. 24, 2019, 7:25 a.m. UTC
There is a rare race condition that may happen during a Disconnect
Interrupt if we have a started request that happens to be
dequeued *after* completion of End Transfer command. If that happens,
that request will be left waiting for completion of an End Transfer
command that will never happen.

If End Transfer command has already completed before, we are safe to
giveback the request straight away.

Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
 drivers/usb/dwc3/gadget.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f0320fcfdaf4..e81c973bb69d 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1543,7 +1543,10 @@  static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 				goto out0;
 
 			dwc3_gadget_move_cancelled_request(req);
-			goto out0;
+			if (dep->flags & DWC3_EP_TRANSFER_STARTED)
+				goto out0;
+			else
+				goto out1;
 		}
 		dev_err(dwc->dev, "request %pK was not queued to %s\n",
 				request, ep->name);
@@ -1551,6 +1554,7 @@  static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 		goto out0;
 	}
 
+out1:
 	dwc3_gadget_giveback(dep, req, -ECONNRESET);
 
 out0: