diff options
author | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-10-25 13:47:21 +0300 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-11-03 10:38:40 +0200 |
commit | e62c5bc57367ac277b932571943c9a09e737ad88 (patch) | |
tree | 0e0b3131783d3aef3f13a9d18acf7ef58a6b0489 /drivers/usb/dwc3 | |
parent | 6cb2e4e3de10893f38dbf3923a9cc50c76548a89 (diff) |
usb: dwc3: gadget: tracking per-TRB remaining bytes
This will give us a simpler way of figuring out how
many bytes were left in each TRB. It's useful for
cases where we queue only part of an SG-list due to
amount of available TRBs at the time of kicking the
transfer.
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r-- | drivers/usb/dwc3/core.h | 2 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 19 |
2 files changed, 8 insertions, 13 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index ebc8a542407f..2322863e3cf7 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -715,6 +715,7 @@ struct dwc3_hwparams { * @dep: struct dwc3_ep owning this request * @sg: pointer to first incomplete sg * @num_pending_sgs: counter to pending sgs + * @remaining: amount of data remaining * @epnum: endpoint number to which this request refers * @trb: pointer to struct dwc3_trb * @trb_dma: DMA address of @trb @@ -729,6 +730,7 @@ struct dwc3_request { struct scatterlist *sg; unsigned num_pending_sgs; + unsigned remaining; u8 epnum; struct dwc3_trb *trb; dma_addr_t trb_dma; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4191b00c0058..4e66e91fe883 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -178,6 +178,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, req->started = false; list_del(&req->list); req->trb = NULL; + req->remaining = 0; if (req->request.status == -EINPROGRESS) req->request.status = status; @@ -2014,7 +2015,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, return 1; count = trb->size & DWC3_TRB_SIZE_MASK; - req->request.actual += count; + req->remaining += count; if (dep->direction) { if (count) { @@ -2068,11 +2069,10 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, struct dwc3_request *req, *n; struct dwc3_trb *trb; bool ioc = false; - int ret; + int ret = 0; list_for_each_entry_safe(req, n, &dep->started_list, list) { unsigned length; - unsigned actual; int chain; length = req->request.length; @@ -2100,17 +2100,10 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, event, status, chain); } - /* - * We assume here we will always receive the entire data block - * which we should receive. Meaning, if we program RX to - * receive 4K but we receive only 2K, we assume that's all we - * should receive and we simply bounce the request back to the - * gadget driver for further processing. - */ - actual = length - req->request.actual; - req->request.actual = actual; + req->request.actual = length - req->remaining; - if (ret && chain && (actual < length) && req->num_pending_sgs) + if (ret && chain && (req->request.actual < length) + && req->num_pending_sgs) return __dwc3_gadget_kick_transfer(dep, 0); dwc3_gadget_giveback(dep, req, status); |