From e9cfaddeec509e93d2100fce0d182f995fc159e6 Mon Sep 17 00:00:00 2001 From: Wu Liang feng Date: Fri, 30 Sep 2016 19:19:40 +0800 Subject: [PATCH] usb: dwc3: gadget: fix trb ring full bug MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- drivers/usb/dwc3/gadget.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 776de55028f6..ca4229f3a1cc 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -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; -- 2.34.1