Commit e0d19563 authored by Thinh Nguyen's avatar Thinh Nguyen Committed by Felipe Balbi

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: default avatarThinh Nguyen <thinhn@synopsys.com>
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
parent 3eaecd0c
...@@ -701,6 +701,7 @@ struct dwc3_ep { ...@@ -701,6 +701,7 @@ struct dwc3_ep {
#define DWC3_EP_END_TRANSFER_PENDING BIT(4) #define DWC3_EP_END_TRANSFER_PENDING BIT(4)
#define DWC3_EP_PENDING_REQUEST BIT(5) #define DWC3_EP_PENDING_REQUEST BIT(5)
#define DWC3_EP_DELAY_START BIT(6) #define DWC3_EP_DELAY_START BIT(6)
#define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7)
/* This last one is specific to EP0 */ /* This last one is specific to EP0 */
#define DWC3_EP0_DIR_IN BIT(31) #define DWC3_EP0_DIR_IN BIT(31)
......
...@@ -1292,6 +1292,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) ...@@ -1292,6 +1292,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
return ret; return ret;
} }
if (dep->stream_capable && req->request.is_last)
dep->flags |= DWC3_EP_WAIT_TRANSFER_COMPLETE;
return 0; return 0;
} }
...@@ -1498,6 +1501,9 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) ...@@ -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); list_add_tail(&req->list, &dep->pending_list);
req->status = DWC3_REQUEST_STATUS_QUEUED; 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 */ /* Start the transfer only after the END_TRANSFER is completed */
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) { if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
dep->flags |= DWC3_EP_DELAY_START; dep->flags |= DWC3_EP_DELAY_START;
...@@ -2735,7 +2741,8 @@ static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep, ...@@ -2735,7 +2741,8 @@ static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep,
if (event->status & DEPEVT_STATUS_BUSERR) if (event->status & DEPEVT_STATUS_BUSERR)
status = -ECONNRESET; 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, static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment