From 313d6a04df22fa267897dee03988f65bcf80123b Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Mon, 19 Sep 2022 16:12:13 -0700 Subject: [PATCH] UPSTREAM: usb: dwc3: gadget: Do not clear ep delayed stop flag during ep disable DWC3_EP_DELAYED_STOP is utilized to defer issuing the end transfer command until the subsequent SETUP stage, in order to avoid end transfer timeouts. During cable disconnect scenarios, __dwc3_gadget_ep_disable() is responsible for ensuring endpoints have no active transfers pending. Since dwc3_remove_request() can now exit early if the EP delayed stop is set, avoid clearing all DEP flags, otherwise the transition back into the SETUP stage won't issue an endxfer command. Change-Id: Ifaaf6405e24868b1b52f23aa492ed8ed783d1e14 Fixes: 2b2da6574e77 ("usb: dwc3: Avoid unmapping USB requests if endxfer is not complete") Reviewed-by: Thinh Nguyen Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/r/20220919231213.21364-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Frank Wang (cherry picked from commit 76bff31c7fba6cc21bf8f9785572484d54d31878) --- drivers/usb/dwc3/gadget.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8a3248c6d063..087a5927f887 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1145,6 +1145,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) { struct dwc3 *dwc = dep->dwc; u32 reg; + u32 mask; trace_dwc3_gadget_ep_disable(dep); @@ -1166,7 +1167,15 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) dep->stream_capable = false; dep->type = 0; - dep->flags &= DWC3_EP_TXFIFO_RESIZED; + mask = DWC3_EP_TXFIFO_RESIZED; + /* + * dwc3_remove_requests() can exit early if DWC3 EP delayed stop is + * set. Do not clear DEP flags, so that the end transfer command will + * be reattempted during the next SETUP stage. + */ + if (dep->flags & DWC3_EP_DELAY_STOP) + mask |= (DWC3_EP_DELAY_STOP | DWC3_EP_TRANSFER_STARTED); + dep->flags &= mask; return 0; }