From: Thinh Nguyen Date: Wed, 6 May 2020 02:46:57 +0000 (-0700) Subject: usb: dwc3: gadget: Wait for transfer completion X-Git-Tag: v5.10.7~2412^2~16^2~24 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e0d19563eb6c191ca5539789173fb0e8fc5e69ed;p=platform%2Fkernel%2Flinux-rpi.git usb: dwc3: gadget: Wait for transfer completion 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 Signed-off-by: Felipe Balbi --- diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 7204a83..b11183a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -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) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 052f6dc..97c6a57 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -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,