From 28ebe0143087b53db8fa760034003c9ae80e5157 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Jan 2019 13:01:16 +0200 Subject: [PATCH] UPSTREAM: usb: dwc3: gadget: early giveback if End Transfer already completed 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. Change-Id: I98d4f8a42459d752be969cf3aabc9b01d5bcd212 Tested-by: Thinh Nguyen Signed-off-by: Felipe Balbi Signed-off-by: William Wu (cherry picked from commit 9f45581f5eec6786c6eded2b3c85345d82a910c9) --- drivers/usb/dwc3/gadget.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 300793792ff1..a36187808d36 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1541,7 +1541,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); @@ -1549,6 +1552,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, goto out0; } +out1: dwc3_gadget_giveback(dep, req, -ECONNRESET); out0: