usb: dwc3: gadget: tracking per-TRB remaining bytes
authorFelipe Balbi <felipe.balbi@linux.intel.com>
Tue, 25 Oct 2016 10:47:21 +0000 (13:47 +0300)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Thu, 3 Nov 2016 08:38:40 +0000 (10:38 +0200)
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>
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c

index ebc8a542407f12d451d2c474887957b9df6dcbf8..2322863e3cf78da7ab5e26436854009c3595f9ff 100644 (file)
@@ -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;
index 4191b00c0058bd53686715a24083a0096250c96c..4e66e91fe88369238d806f54f8f6872caed85b64 100644 (file)
@@ -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);