summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2018-03-29 13:32:10 +0300
committerFelipe Balbi <felipe.balbi@linux.intel.com>2018-05-21 10:00:54 +0300
commitd36929538f8b02615260075a9c512bddd75fea4e (patch)
tree1d2c6713b7471e2490917be2ef8cd2345d95c398 /drivers/usb/dwc3
parentd5044a04b5292d3ac6c837af70d632a7d593f6db (diff)
downloadlinux-d36929538f8b02615260075a9c512bddd75fea4e.tar.xz
usb: dwc3: gadget: split scatterlist and linear handlers
instead of having one big loop, let's split it down into two smaller handlers: one for linear buffers and one for scatterlist. Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/gadget.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2c79563caa33..b0b72e72bbac 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2271,6 +2271,45 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
return 0;
}
+static int dwc3_gadget_ep_reclaim_trb_sg(struct dwc3_ep *dep,
+ struct dwc3_request *req, const struct dwc3_event_depevt *event,
+ int status)
+{
+ struct dwc3_trb *trb = &dep->trb_pool[dep->trb_dequeue];
+ struct scatterlist *sg = req->sg;
+ struct scatterlist *s;
+ unsigned int pending = req->num_pending_sgs;
+ unsigned int i;
+ int ret = 0;
+
+ for_each_sg(sg, s, pending, i) {
+ trb = &dep->trb_pool[dep->trb_dequeue];
+
+ if (trb->ctrl & DWC3_TRB_CTRL_HWO)
+ break;
+
+ req->sg = sg_next(s);
+ req->num_pending_sgs--;
+
+ ret = dwc3_gadget_ep_reclaim_completed_trb(dep, req,
+ trb, event, status, true);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep,
+ struct dwc3_request *req, const struct dwc3_event_depevt *event,
+ int status)
+{
+ struct dwc3_trb *trb = &dep->trb_pool[dep->trb_dequeue];
+
+ return dwc3_gadget_ep_reclaim_completed_trb(dep, req, trb,
+ event, status, false);
+}
+
static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
const struct dwc3_event_depevt *event, int status)
{
@@ -2284,32 +2323,12 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
length = req->request.length;
chain = req->num_pending_sgs > 0;
- if (chain) {
- struct scatterlist *sg = req->sg;
- struct scatterlist *s;
- unsigned int pending = req->num_pending_sgs;
- unsigned int i;
-
- for_each_sg(sg, s, pending, i) {
- trb = &dep->trb_pool[dep->trb_dequeue];
-
- if (trb->ctrl & DWC3_TRB_CTRL_HWO)
- break;
-
- req->sg = sg_next(s);
- req->num_pending_sgs--;
-
- ret = dwc3_gadget_ep_reclaim_completed_trb(dep,
- req, trb, event, status,
- chain);
- if (ret)
- break;
- }
- } else {
- trb = &dep->trb_pool[dep->trb_dequeue];
- ret = dwc3_gadget_ep_reclaim_completed_trb(dep, req,
- trb, event, status, chain);
- }
+ if (chain)
+ ret = dwc3_gadget_ep_reclaim_trb_sg(dep, req, event,
+ status);
+ else
+ ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event,
+ status);
if (req->unaligned || req->zero) {
trb = &dep->trb_pool[dep->trb_dequeue];