Skip to content

Commit

Permalink
usb: gadget: mv_udc: optimize bounce
Browse files Browse the repository at this point in the history
Only perform one copy, either in the bounce
routine for IN transfers, or the debounce
rtn for OUT transfer.

On out transfers, only copy the number
of bytes received from the bounce buffer

Signed-off-by: Troy Kisky <[email protected]>
  • Loading branch information
tkisky authored and Marek Vasut committed Oct 20, 2013
1 parent 3b59abf commit 1ebf027
Showing 1 changed file with 16 additions and 21 deletions.
37 changes: 16 additions & 21 deletions drivers/usb/gadget/mv_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ static int mv_ep_disable(struct usb_ep *ep)
return 0;
}

static int mv_bounce(struct mv_ep *ep)
static int mv_bounce(struct mv_ep *ep, int in)
{
uint32_t addr = (uint32_t)ep->req.buf;
uint32_t ba;
Expand Down Expand Up @@ -290,8 +290,8 @@ static int mv_bounce(struct mv_ep *ep)
if (!ep->b_buf)
return -ENOMEM;
}

memcpy(ep->b_buf, ep->req.buf, ep->req.length);
if (in)
memcpy(ep->b_buf, ep->req.buf, ep->req.length);

flush:
ba = (uint32_t)ep->b_buf;
Expand All @@ -300,29 +300,25 @@ static int mv_bounce(struct mv_ep *ep)
return 0;
}

static void mv_debounce(struct mv_ep *ep)
static void mv_debounce(struct mv_ep *ep, int in)
{
uint32_t addr = (uint32_t)ep->req.buf;
uint32_t ba = (uint32_t)ep->b_buf;

if (in) {
if (addr == ba)
return; /* not a bounce */
goto free;
}
invalidate_dcache_range(ba, ba + ep->b_len);

/* Input buffer address is not aligned. */
if (addr & (ARCH_DMA_MINALIGN - 1))
goto copy;

/* Input buffer length is not aligned. */
if (ep->req.length & (ARCH_DMA_MINALIGN - 1))
goto copy;

/* The buffer is well aligned, only invalidate cache. */
return;
if (addr == ba)
return; /* not a bounce */

copy:
memcpy(ep->req.buf, ep->b_buf, ep->req.length);

free:
/* Large payloads use allocated buffer, free it. */
if (ep->req.length > 64)
if (ep->b_buf != ep->b_fast)
free(ep->b_buf);
}

Expand All @@ -340,7 +336,7 @@ static int mv_ep_queue(struct usb_ep *ep,
head = mv_get_qh(num, in);
len = req->length;

ret = mv_bounce(mv_ep);
ret = mv_bounce(mv_ep, in);
if (ret)
return ret;

Expand Down Expand Up @@ -383,10 +379,9 @@ static void handle_ep_complete(struct mv_ep *ep)
num, in ? "in" : "out", item->info, item->page0);

len = (item->info >> 16) & 0x7fff;

mv_debounce(ep);

ep->req.length -= len;
mv_debounce(ep, in);

DBG("ept%d %s complete %x\n",
num, in ? "in" : "out", len);
ep->req.complete(&ep->ep, &ep->req);
Expand Down

0 comments on commit 1ebf027

Please sign in to comment.