summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/dwc3/gadget.c93
1 files changed, 25 insertions, 68 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 173421508635..e74d97aa8b53 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1060,10 +1060,11 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
* @trb_length: buffer size of the TRB
* @chain: should this TRB be chained to the next?
* @node: only for isochronous endpoints. First TRB needs different type.
+ * @use_bounce_buffer: set to use bounce buffer
*/
static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
struct dwc3_request *req, unsigned int trb_length,
- unsigned int chain, unsigned int node)
+ unsigned int chain, unsigned int node, bool use_bounce_buffer)
{
struct dwc3_trb *trb;
dma_addr_t dma;
@@ -1072,7 +1073,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
unsigned int no_interrupt = req->request.no_interrupt;
unsigned int is_last = req->request.is_last;
- if (req->request.num_sgs > 0)
+ if (use_bounce_buffer)
+ dma = dep->dwc->bounce_addr;
+ else if (req->request.num_sgs > 0)
dma = sg_dma_address(req->start_sg);
else
dma = req->request.dma;
@@ -1129,56 +1132,35 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
chain = false;
if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) {
- struct dwc3 *dwc = dep->dwc;
- struct dwc3_trb *trb;
-
req->needs_extra_trb = true;
/* prepare normal TRB */
- dwc3_prepare_one_trb(dep, req, trb_length, true, i);
+ dwc3_prepare_one_trb(dep, req, trb_length,
+ true, i, false);
/* Now prepare one extra TRB to align transfer size */
- trb = &dep->trb_pool[dep->trb_enqueue];
- req->num_trbs++;
- __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr,
- maxp - rem, false, 1,
- req->request.stream_id,
- req->request.short_not_ok,
- req->request.no_interrupt,
- req->request.is_last);
+ dwc3_prepare_one_trb(dep, req, maxp - rem,
+ false, 1, true);
} else if (req->request.zero && req->request.length &&
!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
!rem && !chain) {
- struct dwc3 *dwc = dep->dwc;
- struct dwc3_trb *trb;
-
req->needs_extra_trb = true;
/* Prepare normal TRB */
- dwc3_prepare_one_trb(dep, req, trb_length, true, i);
+ dwc3_prepare_one_trb(dep, req, trb_length,
+ true, i, false);
/* Prepare one extra TRB to handle ZLP */
- trb = &dep->trb_pool[dep->trb_enqueue];
- req->num_trbs++;
- __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0,
- !req->direction, 1,
- req->request.stream_id,
- req->request.short_not_ok,
- req->request.no_interrupt,
- req->request.is_last);
+ dwc3_prepare_one_trb(dep, req, 0,
+ !req->direction, 1, true);
/* Prepare one more TRB to handle MPS alignment */
- if (!req->direction) {
- trb = &dep->trb_pool[dep->trb_enqueue];
- req->num_trbs++;
- __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp,
- false, 1, req->request.stream_id,
- req->request.short_not_ok,
- req->request.no_interrupt,
- req->request.is_last);
- }
+ if (!req->direction)
+ dwc3_prepare_one_trb(dep, req, maxp,
+ false, 1, true);
} else {
- dwc3_prepare_one_trb(dep, req, trb_length, chain, i);
+ dwc3_prepare_one_trb(dep, req, trb_length,
+ chain, i, false);
}
/*
@@ -1216,54 +1198,29 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
unsigned int rem = length % maxp;
if ((!length || rem) && usb_endpoint_dir_out(dep->endpoint.desc)) {
- struct dwc3 *dwc = dep->dwc;
- struct dwc3_trb *trb;
-
req->needs_extra_trb = true;
/* prepare normal TRB */
- dwc3_prepare_one_trb(dep, req, length, true, 0);
+ dwc3_prepare_one_trb(dep, req, length, true, 0, false);
/* Now prepare one extra TRB to align transfer size */
- trb = &dep->trb_pool[dep->trb_enqueue];
- req->num_trbs++;
- __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp - rem,
- false, 1, req->request.stream_id,
- req->request.short_not_ok,
- req->request.no_interrupt,
- req->request.is_last);
+ dwc3_prepare_one_trb(dep, req, maxp - rem, false, 1, true);
} else if (req->request.zero && req->request.length &&
!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
(IS_ALIGNED(req->request.length, maxp))) {
- struct dwc3 *dwc = dep->dwc;
- struct dwc3_trb *trb;
-
req->needs_extra_trb = true;
/* prepare normal TRB */
- dwc3_prepare_one_trb(dep, req, length, true, 0);
+ dwc3_prepare_one_trb(dep, req, length, true, 0, false);
/* Prepare one extra TRB to handle ZLP */
- trb = &dep->trb_pool[dep->trb_enqueue];
- req->num_trbs++;
- __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0,
- !req->direction, 1, req->request.stream_id,
- req->request.short_not_ok,
- req->request.no_interrupt,
- req->request.is_last);
+ dwc3_prepare_one_trb(dep, req, 0, !req->direction, 1, true);
/* Prepare one more TRB to handle MPS alignment for OUT */
- if (!req->direction) {
- trb = &dep->trb_pool[dep->trb_enqueue];
- req->num_trbs++;
- __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp,
- false, 1, req->request.stream_id,
- req->request.short_not_ok,
- req->request.no_interrupt,
- req->request.is_last);
- }
+ if (!req->direction)
+ dwc3_prepare_one_trb(dep, req, maxp, false, 1, true);
} else {
- dwc3_prepare_one_trb(dep, req, length, false, 0);
+ dwc3_prepare_one_trb(dep, req, length, false, 0, false);
}
}