From 5a97f312484fa3a20a819e71bd699e5d4075e44d Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Fri, 30 Apr 2021 14:10:43 +0530 Subject: [PATCH] usb: dwc3: gadget: handle ep_dequeue in LPM properly Currently, the driver is relying on remove_requests or ep_dequeue to giveback the requests to function driver, but when the stop active transfer is called it will return with error status and will bail out from remove request without clearing the requests. At this point we rely on ep_dequeue to clear those requests, but since usb is disconnected, it will be in LPM which would drive dequeue to bailout without clearing the requests. Fix this by removing the LPM check from dequeue to stop_active_transfer. Now if dequeue process proceeds will check in stop_active_transfer, if dwc3 is in lpm bail out from the process. Dequeue will further proceed & clean up the request from cancelled list. Change-Id: I13628ab96059fbae14bed64056ff8d7561cd240f Signed-off-by: Udipto Goswami --- drivers/usb/dwc3/gadget.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a77855d8e7cd..a102a35b9f23 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1805,11 +1805,6 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, unsigned long flags; int ret = 0; - if (atomic_read(&dwc->in_lpm)) { - dev_err(dwc->dev, "Unable to dequeue while in LPM\n"); - return -EAGAIN; - } - trace_dwc3_ep_dequeue(req); dbg_ep_dequeue(dep->number, req); @@ -3533,6 +3528,11 @@ int dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) u32 cmd; int ret; + if (atomic_read(&dwc->in_lpm)) { + dev_err(dwc->dev, "cannot stop transfers while in LPM\n"); + return -EINVAL; + } + if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) || (dep->flags & DWC3_EP_END_TRANSFER_PENDING)) return 0;