@@ -701,6 +701,7 @@ struct dwc3_ep {
#define DWC3_EP_END_TRANSFER_PENDING BIT(4)
#define DWC3_EP_PENDING_REQUEST BIT(5)
#define DWC3_EP_DELAY_START BIT(6)
+#define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7)
/* This last one is specific to EP0 */
#define DWC3_EP0_DIR_IN BIT(31)
@@ -1292,6 +1292,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
return ret;
}
+ if (dep->stream_capable && req->request.is_last)
+ dep->flags |= DWC3_EP_WAIT_TRANSFER_COMPLETE;
+
return 0;
}
@@ -1498,6 +1501,9 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
list_add_tail(&req->list, &dep->pending_list);
req->status = DWC3_REQUEST_STATUS_QUEUED;
+ if (dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)
+ return 0;
+
/* Start the transfer only after the END_TRANSFER is completed */
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
dep->flags |= DWC3_EP_DELAY_START;
@@ -2735,7 +2741,8 @@ static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep,
if (event->status & DEPEVT_STATUS_BUSERR)
status = -ECONNRESET;
- dwc3_gadget_endpoint_trbs_complete(dep, event, status);
+ if (dwc3_gadget_endpoint_trbs_complete(dep, event, status))
+ dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;
}
static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
If a transfer is in-progress, any new request should not kick off another transfer. The driver needs to wait for the current transfer to complete before starting off the next transfer. Introduce a new flag DWC3_EP_WAIT_TRANSFER_COMPLETE for this. Signed-off-by: Thinh Nguyen <thinhn@synopsys.com> --- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-)