[v3.16-stable] usb: dwc3: fix TRB completion when multiple TRBs are started

Message ID 1412352595-398-1-git-send-email-balbi@ti.com
State New
Headers show

Commit Message

Felipe Balbi Oct. 3, 2014, 4:09 p.m.
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)
Cc: <stable@vger.kernel.org> # v3.14+
Reported-by: Pratyush Anand <pratyush.anand@st.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/gadget.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

Comments

Greg Kroah-Hartman Oct. 3, 2014, 7:03 p.m. | #1
On Fri, Oct 03, 2014 at 11:09:55AM -0500, Felipe Balbi wrote:
> 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)
> Cc: <stable@vger.kernel.org> # v3.14+

That commit isn't in Linus's tree, it should be
f3af36511e60669a2b5644d17378c7ea4e42d8b1, right?  And that showed up in
3.15-rc1, so why is this needed in 3.14?

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Felipe Balbi Oct. 3, 2014, 7:19 p.m. | #2
On Fri, Oct 03, 2014 at 12:03:16PM -0700, Greg KH wrote:
> On Fri, Oct 03, 2014 at 11:09:55AM -0500, Felipe Balbi wrote:
> > 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)
> > Cc: <stable@vger.kernel.org> # v3.14+
> 
> That commit isn't in Linus's tree, it should be
> f3af36511e60669a2b5644d17378c7ea4e42d8b1, right?  And that showed up in
> 3.15-rc1, so why is this needed in 3.14?

that's right. I pointed to a commit on TI's tree, sorry about that. We
can certainly skip this one from v3.14.

Patch

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index dab7927..f5b352a 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: