summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2016-05-13 12:42:44 +0300
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-06-20 12:30:06 +0300
commit5ee85d890f8de5c6f1ab22ba13734a63fdf3ff2d (patch)
tree89e5edca8ce38ef5969515f6cf314f167e786643 /drivers
parent6b74289937f624439c87135cfabb3deb2955fb53 (diff)
usb: dwc3: gadget: split __dwc3_gadget_kick_transfer()
To aid code readability, we're gonna split __dwc3_gadget_kick_transfer() into its constituent parts: scatter gather and linear buffers. That way, it's easier to follow the code and focus debug effort when one or the other fails. Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/dwc3/gadget.c122
1 files changed, 65 insertions, 57 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 4c9fe7b55100..bff2c35f37a8 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -903,6 +903,65 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
return dep->trb_dequeue - dep->trb_enqueue;
}
+static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
+ struct dwc3_request *req, unsigned int trbs_left)
+{
+ struct usb_request *request = &req->request;
+ struct scatterlist *sg = request->sg;
+ struct scatterlist *s;
+ unsigned int last = false;
+ unsigned int length;
+ dma_addr_t dma;
+ int i;
+
+ for_each_sg(sg, s, request->num_mapped_sgs, i) {
+ unsigned chain = true;
+
+ length = sg_dma_len(s);
+ dma = sg_dma_address(s);
+
+ if (sg_is_last(s)) {
+ if (list_is_last(&req->list, &dep->pending_list))
+ last = true;
+
+ chain = false;
+ }
+
+ if (!trbs_left)
+ last = true;
+
+ if (last)
+ chain = false;
+
+ dwc3_prepare_one_trb(dep, req, dma, length,
+ last, chain, i);
+
+ if (last)
+ break;
+ }
+}
+
+static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
+ struct dwc3_request *req, unsigned int trbs_left)
+{
+ unsigned int last = false;
+ unsigned int length;
+ dma_addr_t dma;
+
+ dma = req->request.dma;
+ length = req->request.length;
+
+ if (!trbs_left)
+ last = true;
+
+ /* Is this the last request? */
+ if (list_is_last(&req->list, &dep->pending_list))
+ last = true;
+
+ dwc3_prepare_one_trb(dep, req, dma, length,
+ last, false, 0);
+}
+
/*
* dwc3_prepare_trbs - setup TRBs from requests
* @dep: endpoint for which requests are being prepared
@@ -915,70 +974,19 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
{
struct dwc3_request *req, *n;
u32 trbs_left;
- unsigned int last_one = 0;
BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
trbs_left = dwc3_calc_trbs_left(dep);
list_for_each_entry_safe(req, n, &dep->pending_list, list) {
- unsigned length;
- dma_addr_t dma;
- last_one = false;
-
- if (req->request.num_mapped_sgs > 0) {
- struct usb_request *request = &req->request;
- struct scatterlist *sg = request->sg;
- struct scatterlist *s;
- int i;
-
- for_each_sg(sg, s, request->num_mapped_sgs, i) {
- unsigned chain = true;
-
- length = sg_dma_len(s);
- dma = sg_dma_address(s);
-
- if (sg_is_last(s)) {
- if (list_is_last(&req->list, &dep->pending_list))
- last_one = true;
-
- chain = false;
- }
-
- trbs_left--;
- if (!trbs_left)
- last_one = true;
-
- if (last_one)
- chain = false;
-
- dwc3_prepare_one_trb(dep, req, dma, length,
- last_one, chain, i);
-
- if (last_one)
- break;
- }
-
- if (last_one)
- break;
- } else {
- dma = req->request.dma;
- length = req->request.length;
- trbs_left--;
-
- if (!trbs_left)
- last_one = true;
-
- /* Is this the last request? */
- if (list_is_last(&req->list, &dep->pending_list))
- last_one = true;
-
- dwc3_prepare_one_trb(dep, req, dma, length,
- last_one, false, 0);
+ if (req->request.num_mapped_sgs > 0)
+ dwc3_prepare_one_trb_sg(dep, req, trbs_left--);
+ else
+ dwc3_prepare_one_trb_linear(dep, req, trbs_left--);
- if (last_one)
- break;
- }
+ if (!trbs_left)
+ return;
}
}