Skip to content

Commit

Permalink
usb: dwc3: ep0: handle non maxpacket aligned transfers > 512
Browse files Browse the repository at this point in the history
Use chained TRB mechanism to handle non maxpacket aligned transfers
greater than bounce buffer size. With this the first TRB will be programmed
to receive 'ALIGN(ur->length - maxp, maxp)' data and the second TRB
will be programmed to receive the remaining data using bounce buffer.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Kishon Vijay Abraham I authored and Felipe Balbi committed Jul 30, 2015
1 parent 2abd9d5 commit c0bd545
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions drivers/usb/dwc3/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,13 +834,26 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
maxp = ep0->endpoint.maxpacket;

if (dwc->ep0_bounced) {
/*
* Handle the first TRB before handling the bounce buffer if
* the request length is greater than the bounce buffer size
*/
if (ur->length > DWC3_EP0_BOUNCE_SIZE) {
transfer_size = ALIGN(ur->length - maxp, maxp);
transferred = transfer_size - length;
buf = (u8 *)buf + transferred;
ur->actual += transferred;
remaining_ur_length -= transferred;

trb++;
length = trb->size & DWC3_TRB_SIZE_MASK;

ep0->free_slot = 0;
}

transfer_size = roundup((ur->length - transfer_size),
maxp);

/* Maximum of DWC3_EP0_BOUNCE_SIZE can only be received */
if (transfer_size > DWC3_EP0_BOUNCE_SIZE)
transfer_size = DWC3_EP0_BOUNCE_SIZE;

transferred = min_t(u32, remaining_ur_length,
transfer_size - length);
memcpy(buf, dwc->ep0_bounce, transferred);
Expand Down Expand Up @@ -963,21 +976,22 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
}

maxpacket = dep->endpoint.maxpacket;
transfer_size = roundup((req->request.length - transfer_size),
maxpacket);

if (transfer_size > DWC3_EP0_BOUNCE_SIZE) {
dev_WARN(dwc->dev, "bounce buf can't handle req len\n");
transfer_size = DWC3_EP0_BOUNCE_SIZE;
if (req->request.length > DWC3_EP0_BOUNCE_SIZE) {
transfer_size = ALIGN(req->request.length - maxpacket,
maxpacket);
ret = dwc3_ep0_start_trans(dwc, dep->number,
req->request.dma,
transfer_size,
DWC3_TRBCTL_CONTROL_DATA,
true);
}

transfer_size = roundup((req->request.length - transfer_size),
maxpacket);

dwc->ep0_bounced = true;

/*
* REVISIT in case request length is bigger than
* DWC3_EP0_BOUNCE_SIZE we will need two chained
* TRBs to handle the transfer.
*/
ret = dwc3_ep0_start_trans(dwc, dep->number,
dwc->ep0_bounce_addr, transfer_size,
DWC3_TRBCTL_CONTROL_DATA, false);
Expand Down

0 comments on commit c0bd545

Please sign in to comment.