diff options
author | Thinh Nguyen <Thinh.Nguyen@synopsys.com> | 2019-12-18 18:14:50 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-02-11 04:35:09 -0800 |
commit | 91cfedb762bd967811d7453fb822907db4b58bb8 (patch) | |
tree | f6742b24ae79d20b3bababef695f21b3e0368819 /drivers/usb/dwc3/gadget.c | |
parent | 1dc0d21fc1e64b79a44b81ea7fcc87b173841cbe (diff) | |
download | linux-stable-91cfedb762bd967811d7453fb822907db4b58bb8.tar.gz linux-stable-91cfedb762bd967811d7453fb822907db4b58bb8.tar.bz2 linux-stable-91cfedb762bd967811d7453fb822907db4b58bb8.zip |
usb: dwc3: gadget: Delay starting transfer
commit da10bcdd6f70dc9977f2cf18f4783cf78520623a upstream.
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 76a638f8ac0d ("usb: dwc3: gadget: wait for End Transfer to
complete"). Let's only send START_TRANSFER command after the
END_TRANSFER command had completed.
Fixes: 3aec99154db3 ("usb: dwc3: gadget: remove DWC3_EP_END_TRANSFER_PENDING")
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 25d237d0f6a9..8b95be897078 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1447,6 +1447,12 @@ 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; + /* 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 * wait for a XferNotReady event so we will know what's the current @@ -2628,6 +2634,11 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; dep->flags &= ~DWC3_EP_TRANSFER_STARTED; 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; case DWC3_DEPEVT_STREAMEVT: |