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>
This commit is contained in:
parent
6cb2e4e3de
commit
e62c5bc573
|
@ -715,6 +715,7 @@ struct dwc3_hwparams {
|
||||||
* @dep: struct dwc3_ep owning this request
|
* @dep: struct dwc3_ep owning this request
|
||||||
* @sg: pointer to first incomplete sg
|
* @sg: pointer to first incomplete sg
|
||||||
* @num_pending_sgs: counter to pending sgs
|
* @num_pending_sgs: counter to pending sgs
|
||||||
|
* @remaining: amount of data remaining
|
||||||
* @epnum: endpoint number to which this request refers
|
* @epnum: endpoint number to which this request refers
|
||||||
* @trb: pointer to struct dwc3_trb
|
* @trb: pointer to struct dwc3_trb
|
||||||
* @trb_dma: DMA address of @trb
|
* @trb_dma: DMA address of @trb
|
||||||
|
@ -729,6 +730,7 @@ struct dwc3_request {
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
|
|
||||||
unsigned num_pending_sgs;
|
unsigned num_pending_sgs;
|
||||||
|
unsigned remaining;
|
||||||
u8 epnum;
|
u8 epnum;
|
||||||
struct dwc3_trb *trb;
|
struct dwc3_trb *trb;
|
||||||
dma_addr_t trb_dma;
|
dma_addr_t trb_dma;
|
||||||
|
|
|
@ -178,6 +178,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||||
req->started = false;
|
req->started = false;
|
||||||
list_del(&req->list);
|
list_del(&req->list);
|
||||||
req->trb = NULL;
|
req->trb = NULL;
|
||||||
|
req->remaining = 0;
|
||||||
|
|
||||||
if (req->request.status == -EINPROGRESS)
|
if (req->request.status == -EINPROGRESS)
|
||||||
req->request.status = status;
|
req->request.status = status;
|
||||||
|
@ -2014,7 +2015,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
count = trb->size & DWC3_TRB_SIZE_MASK;
|
count = trb->size & DWC3_TRB_SIZE_MASK;
|
||||||
req->request.actual += count;
|
req->remaining += count;
|
||||||
|
|
||||||
if (dep->direction) {
|
if (dep->direction) {
|
||||||
if (count) {
|
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_request *req, *n;
|
||||||
struct dwc3_trb *trb;
|
struct dwc3_trb *trb;
|
||||||
bool ioc = false;
|
bool ioc = false;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
list_for_each_entry_safe(req, n, &dep->started_list, list) {
|
list_for_each_entry_safe(req, n, &dep->started_list, list) {
|
||||||
unsigned length;
|
unsigned length;
|
||||||
unsigned actual;
|
|
||||||
int chain;
|
int chain;
|
||||||
|
|
||||||
length = req->request.length;
|
length = req->request.length;
|
||||||
|
@ -2100,17 +2100,10 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
|
||||||
event, status, chain);
|
event, status, chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
req->request.actual = length - req->remaining;
|
||||||
* 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;
|
|
||||||
|
|
||||||
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);
|
return __dwc3_gadget_kick_transfer(dep, 0);
|
||||||
|
|
||||||
dwc3_gadget_giveback(dep, req, status);
|
dwc3_gadget_giveback(dep, req, status);
|
||||||
|
|
Loading…
Reference in New Issue