summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>2020-09-24 01:22:01 -0700
committerFelipe Balbi <balbi@kernel.org>2020-10-02 09:57:44 +0300
commit30892cba55968fe244feac811cd00cc12b1a574b (patch)
tree8fa66191a32c26de998ec1b536d3a211b93f24b4 /drivers/usb
parent490410b2e73cd350ba91946913b017c8f6e1b612 (diff)
usb: dwc3: gadget: Set IOC if not enough for extra TRBs
If we run out of TRBs because we need extra TRBs, make sure to set the IOC bit for the previously prepared TRB to get completion notification to free up TRBs to resume later. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/gadget.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index ec142724e85c..f091e107d9cb 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1197,7 +1197,27 @@ static int dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
break;
}
+ return req->num_trbs - num_trbs;
+
out:
+ /*
+ * If we run out of TRBs for MPS alignment setup, then set IOC on the
+ * previous TRB to get notified for TRB completion to resume when more
+ * TRBs are available.
+ *
+ * Note: normally we shouldn't update the TRB after the HWO bit is set.
+ * However, the controller doesn't update its internal cache to handle
+ * the newly prepared TRBs until UPDATE_TRANSFER or START_TRANSFER
+ * command is executed. At this point, it doesn't happen yet, so we
+ * should be fine modifying it here.
+ */
+ if (i) {
+ struct dwc3_trb *trb;
+
+ trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
+ trb->ctrl |= DWC3_TRB_CTRL_IOC;
+ }
+
return req->num_trbs - num_trbs;
}