summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorJohn Youn <johnyoun@synopsys.com>2016-05-19 17:26:17 -0700
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-06-20 12:32:45 +0300
commit361572b5f7a95b341a92d34b9bf41f71bbdae34d (patch)
tree9acd370326e26392f1bd933e5927923268f89546 /drivers/usb/dwc3
parent7d0a038b130cde7265d6bbc5e148734cb127f341 (diff)
downloadtalos-obmc-linux-361572b5f7a95b341a92d34b9bf41f71bbdae34d.tar.gz
talos-obmc-linux-361572b5f7a95b341a92d34b9bf41f71bbdae34d.zip
usb: dwc3: gadget: Handle TRB index 0 when full or empty
If the trb->enqueue == trb->dequeue, then it could be full or empty. This could also happen at TRB index 0, so modify the check to handle that condition. At index 0, the previous TRB is the one just before the link TRB. Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/gadget.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 3c4fd4854317..fbc796892f6b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -842,6 +842,25 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
trace_dwc3_prepare_trb(dep, trb);
}
+/**
+ * dwc3_ep_prev_trb() - Returns the previous TRB in the ring
+ * @dep: The endpoint with the TRB ring
+ * @index: The index of the current TRB in the ring
+ *
+ * Returns the TRB prior to the one pointed to by the index. If the
+ * index is 0, we will wrap backwards, skip the link TRB, and return
+ * the one just before that.
+ */
+static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index)
+{
+ if (!index)
+ index = DWC3_TRB_NUM - 2;
+ else
+ index = dep->trb_enqueue - 1;
+
+ return &dep->trb_pool[index];
+}
+
static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
{
struct dwc3_trb *tmp;
@@ -855,12 +874,9 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
* more transfers in our ring.
*/
if (dep->trb_enqueue == dep->trb_dequeue) {
- /* If we're full, enqueue/dequeue are > 0 */
- if (dep->trb_enqueue) {
- tmp = &dep->trb_pool[dep->trb_enqueue - 1];
- if (tmp->ctrl & DWC3_TRB_CTRL_HWO)
- return 0;
- }
+ tmp = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
+ if (tmp->ctrl & DWC3_TRB_CTRL_HWO)
+ return 0;
return DWC3_TRB_NUM - 1;
}
OpenPOWER on IntegriCloud