summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2014-09-04 10:28:10 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-10-05 13:41:06 -0700
commit2b3a58058b0f7523f0907cfd8f22bbd315335964 (patch)
tree9599ad794d216470dd2d7f7ab20cbcbf67277904 /drivers/usb
parente8b1e9604f97d8c74c84b3754e8ca9ad7e41b38a (diff)
usb: dwc3: fix TRB completion when multiple TRBs are started
commit 0b93a4c838fa10370d72f86fe712426ac63804de upstream. After commit 2ec2a8be (usb: dwc3: gadget: always enable IOC on bulk/interrupt transfers) we created a situation where it was possible to hang a bulk/interrupt endpoint if we had more than one pending request in our queue and they were both started with a single Start Transfer command. The problems triggers because we had not enabled Transfer In Progress event for those endpoints and we were not able to process early giveback of requests completed without LST bit set. Fix the problem by finally enabling Xfer In Progress event for all endpoint types, except control. Fixes: 2ec2a8be (usb: dwc3: gadget: always enable IOC on bulk/interrupt transfers) Reported-by: Pratyush Anand <pratyush.anand@st.com> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/gadget.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index dab7927d1009..f5b352a19eb0 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -527,7 +527,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
dep->stream_capable = true;
}
- if (usb_endpoint_xfer_isoc(desc))
+ if (!usb_endpoint_xfer_control(desc))
params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN;
/*
@@ -2042,12 +2042,6 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
dwc3_endpoint_transfer_complete(dwc, dep, event, 1);
break;
case DWC3_DEPEVT_XFERINPROGRESS:
- if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
- dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n",
- dep->name);
- return;
- }
-
dwc3_endpoint_transfer_complete(dwc, dep, event, 0);
break;
case DWC3_DEPEVT_XFERNOTREADY: