usb: dwc3: gadget: Fix calculation of request.actual for SG
When a request completes, cleanup_done_trbs() tries to calculate request.actual by subtracting the TRB remainder from the original request.length, but does not account for scatter-gather requests that queued multiple TRBs. In this case, the request.length field may be used by the function to keep track of the aggregate length of all the provided SG entries, and thus will produce an incorrect request.actual. Instead, for scatter-gather, to find the pre-transfer buffer length of each TRB, get the length field of each SG entry. Then the number of bytes transfered can be correctly determined as the difference between that and the bytes remaining in the TRB. Change-Id: I4c197462ce5b804c9d684240e95c35b532976220 Signed-off-by: Jack Pham <jackp@codeaurora.org>
This commit is contained in:
parent
4e32ea8f3b
commit
0071b357da
1 changed files with 9 additions and 3 deletions
|
@ -2044,7 +2044,7 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
|
|||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
|
||||
struct dwc3_request *req, struct dwc3_trb *trb,
|
||||
struct dwc3_request *req, struct dwc3_trb *trb, unsigned length,
|
||||
const struct dwc3_event_depevt *event, int status)
|
||||
{
|
||||
unsigned int count;
|
||||
|
@ -2109,7 +2109,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
|
|||
* should receive and we simply bounce the request back to the
|
||||
* gadget driver for further processing.
|
||||
*/
|
||||
req->request.actual += req->request.length - count;
|
||||
req->request.actual += length - count;
|
||||
if (s_pkt)
|
||||
return 1;
|
||||
if ((event->status & DEPEVT_STATUS_LST) &&
|
||||
|
@ -2129,6 +2129,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
|
|||
struct dwc3_trb *trb;
|
||||
unsigned int slot;
|
||||
unsigned int i;
|
||||
unsigned int trb_len;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
|
@ -2147,8 +2148,13 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
|
|||
slot %= DWC3_TRB_NUM;
|
||||
trb = &dep->trb_pool[slot];
|
||||
|
||||
if (req->request.num_mapped_sgs)
|
||||
trb_len = sg_dma_len(&req->request.sg[i]);
|
||||
else
|
||||
trb_len = req->request.length;
|
||||
|
||||
ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
|
||||
event, status);
|
||||
trb_len, event, status);
|
||||
if (ret)
|
||||
break;
|
||||
} while (++i < req->request.num_mapped_sgs);
|
||||
|
|
Loading…
Add table
Reference in a new issue