usb: dwc3: gadget: fix trb ring full bug
authorWu Liang feng <wulf@rock-chips.com>
Fri, 30 Sep 2016 11:19:40 +0000 (19:19 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 7 Oct 2016 08:40:12 +0000 (16:40 +0800)
The upstream commit 5e8ec28765 (usb: dwc3: gadget: Handle TRB
index 0 when full or empty) only use the HWO = 1 to check if
the TRB ring is full. But refer to DWC3 databook Version 3.00a,
8.2.3.2 TRB Control Bit Rules: When an OUT endpoint receives a
short packet, some TRBs in a chain may still have their HWO bit
set to 1 while belonging to software.

So if HWO=1 and CSP=1 on OUT endpoint, it also means that TRB
ring is empty, software may reclaim those TRBs even though HWO=1.

TEST=use MTP to transfer big data, and then cancel the transition,
check if it can transfer again.

Change-Id: I45cc683dc733ff7a642cfcd3ebc20455ef677753
Signed-off-by: Wu Liang feng <wulf@rock-chips.com>
drivers/usb/dwc3/gadget.c

index 776de55028f6d3efa442943a8169ff3ee0768ab8..ca4229f3a1cc84848c5b3227acf29d5a97293635 100644 (file)
@@ -876,10 +876,14 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
         */
        if (dep->trb_enqueue == dep->trb_dequeue) {
                tmp = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
-               if (tmp->ctrl & DWC3_TRB_CTRL_HWO)
-                       return 0;
 
-               return DWC3_TRB_NUM - 1;
+               if (!(tmp->ctrl & DWC3_TRB_CTRL_HWO) ||
+                   ((tmp->ctrl & DWC3_TRB_CTRL_HWO) &&
+                    (tmp->ctrl & DWC3_TRB_CTRL_CSP) &&
+                    !dep->direction))
+                       return DWC3_TRB_NUM - 1;
+
+               return 0;
        }
 
        trbs_left = dep->trb_dequeue - dep->trb_enqueue;