usb: dwc3: gadget: don't wrap around the TRB poll on non-ISOC
authorPaul Zimmerman <paulz@synopsys.com>
Wed, 15 Feb 2012 11:35:06 +0000 (13:35 +0200)
committerFelipe Balbi <balbi@ti.com>
Fri, 2 Mar 2012 10:12:03 +0000 (12:12 +0200)
If we have a non-ISOC endpoint, we will not have a Link TRB
pointing to the beginning of the TRB pool. On such endpoints,
we don't want to let the driver wrap around the TRB pool
otherwise controller will hang waiting for a valid TRB.

Cc: stable@vger.kernel.org
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc3/gadget.c

index d121e73d89ae4a495a929467aca0b3d1a6993c56..48b2d0d14481a4173efaa6e3371faf516222a87b 100644 (file)
@@ -826,6 +826,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 {
        struct dwc3_request     *req, *n;
        u32                     trbs_left;
+       u32                     max;
        unsigned int            last_one = 0;
 
        BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
@@ -833,6 +834,13 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
        /* the first request must not be queued */
        trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
 
+       /* Can't wrap around on a non-isoc EP since there's no link TRB */
+       if (!usb_endpoint_xfer_isoc(dep->desc)) {
+               max = DWC3_TRB_NUM - (dep->free_slot & DWC3_TRB_MASK);
+               if (trbs_left > max)
+                       trbs_left = max;
+       }
+
        /*
         * If busy & slot are equal than it is either full or empty. If we are
         * starting to process requests then we are empty. Otherwise we are