Commit da10bcdd authored by Thinh Nguyen's avatar Thinh Nguyen Committed by Greg Kroah-Hartman

usb: dwc3: gadget: Delay starting transfer

If the END_TRANSFER command hasn't completed yet, then don't send the
START_TRANSFER command. The controller may not be able to start if
that's the case. Some controller revisions depend on this. See
commit 76a638f8 ("usb: dwc3: gadget: wait for End Transfer to
complete"). Let's only send START_TRANSFER command after the
END_TRANSFER command had completed.

Fixes: 3aec9915 ("usb: dwc3: gadget: remove DWC3_EP_END_TRANSFER_PENDING")
Signed-off-by: default avatarThinh Nguyen <thinhn@synopsys.com>
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c58d8bfc
...@@ -690,6 +690,7 @@ struct dwc3_ep { ...@@ -690,6 +690,7 @@ struct dwc3_ep {
#define DWC3_EP_TRANSFER_STARTED BIT(3) #define DWC3_EP_TRANSFER_STARTED BIT(3)
#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)
/* 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)
......
...@@ -1450,6 +1450,12 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) ...@@ -1450,6 +1450,12 @@ 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;
/* Start the transfer only after the END_TRANSFER is completed */
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
dep->flags |= DWC3_EP_DELAY_START;
return 0;
}
/* /*
* NOTICE: Isochronous endpoints should NEVER be prestarted. We must * NOTICE: Isochronous endpoints should NEVER be prestarted. We must
* wait for a XferNotReady event so we will know what's the current * wait for a XferNotReady event so we will know what's the current
...@@ -2631,6 +2637,11 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, ...@@ -2631,6 +2637,11 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
dep->flags &= ~DWC3_EP_TRANSFER_STARTED; dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
dwc3_gadget_ep_cleanup_cancelled_requests(dep); dwc3_gadget_ep_cleanup_cancelled_requests(dep);
if ((dep->flags & DWC3_EP_DELAY_START) &&
!usb_endpoint_xfer_isoc(dep->endpoint.desc))
__dwc3_gadget_kick_transfer(dep);
dep->flags &= ~DWC3_EP_DELAY_START;
} }
break; break;
case DWC3_DEPEVT_STREAMEVT: case DWC3_DEPEVT_STREAMEVT:
......
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