UPSTREAM: usb: dwc3: Avoid unmapping USB requests if endxfer is not complete

If DWC3_EP_DELAYED_STOP is set during stop active transfers, then do not
continue attempting to unmap request buffers during dwc3_remove_requests().
This can lead to SMMU faults, as the controller has not stopped the
processing of the TRB.  Defer this sequence to the EP0 out start, which
ensures that there are no pending SETUP transactions before issuing the
endxfer.

Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
Link: https://lore.kernel.org/r/20220901193625.8727-2-quic_wcheng@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

(cherry picked from commit 2b2da6574e77ebf83c0df6d8b838bc37764c4bfa)

Bug: 263189538
Change-Id: I01ba6d79b56211316bfa492ae4d5d41680067c9e
Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
This commit is contained in:
Wesley Cheng
2022-09-01 12:36:21 -07:00
committed by Todd Kjos
parent 19803140c0
commit 4fc3932857
3 changed files with 10 additions and 2 deletions

View File

@@ -1564,6 +1564,7 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd,
u32 param);
void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt);
void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc);
void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status);
#else
static inline int dwc3_gadget_init(struct dwc3 *dwc)
{ return 0; }

View File

@@ -293,7 +293,10 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
continue;
dwc3_ep->flags &= ~DWC3_EP_DELAY_STOP;
dwc3_stop_active_transfer(dwc3_ep, true, true);
if (dwc->connected)
dwc3_stop_active_transfer(dwc3_ep, true, true);
else
dwc3_remove_requests(dwc, dwc3_ep, -ESHUTDOWN);
}
}

View File

@@ -967,12 +967,16 @@ out:
return 0;
}
static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status)
void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status)
{
struct dwc3_request *req;
dwc3_stop_active_transfer(dep, true, false);
/* If endxfer is delayed, avoid unmapping requests */
if (dep->flags & DWC3_EP_DELAY_STOP)
return;
/* - giveback all requests to gadget driver */
while (!list_empty(&dep->started_list)) {
req = next_request(&dep->started_list);