summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2016-10-25 13:47:21 +0300
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-11-03 10:38:40 +0200
commite62c5bc57367ac277b932571943c9a09e737ad88 (patch)
tree0e0b3131783d3aef3f13a9d18acf7ef58a6b0489 /drivers/usb/dwc3
parent6cb2e4e3de10893f38dbf3923a9cc50c76548a89 (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.h2
-rw-r--r--drivers/usb/dwc3/gadget.c19
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);