summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2014-04-24 17:52:37 -0600
committerMarek Vasut <marex@denx.de>2014-04-30 10:30:57 +0200
commit8aac6e9c537a2dd0c76acc3a0768ae7af5e166ab (patch)
treeb79b50c76f6b05ac0621782677f0bbf65146fb93 /drivers/usb
parentf5c03006dd1794362a2be7136fed9e664bc1775b (diff)
downloadu-boot-imx-8aac6e9c537a2dd0c76acc3a0768ae7af5e166ab.zip
u-boot-imx-8aac6e9c537a2dd0c76acc3a0768ae7af5e166ab.tar.gz
u-boot-imx-8aac6e9c537a2dd0c76acc3a0768ae7af5e166ab.tar.bz2
usb: ci_udc: set ep->req.actual after transfer
At least drivers/usb/gadget/storage_common.c expects that ep->req.actual contain the number of bytes actually transferred. (At least in practice, I observed it failing to work correctly unless this was the case). However, ci_udc.c modifies ep->req.length instead. I assume that .length is supposed to represent the allocated buffer size, whereas .actual is supposed to represent the actual number of bytes transferred. In the OUT transaction case, this may happen simply because the host sends a smaller packet than the max possible size, which is quite legal. In the IN case, transferring fewer bytes than requested could presumably happen as an error. Modify handle_ep_complete() to write to .actual rather than modifying .length. Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/ci_udc.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 815ce7b..832606f 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -321,7 +321,7 @@ static void ci_debounce(struct ci_ep *ep, int in)
if (addr == ba)
return; /* not a bounce */
- memcpy(ep->req.buf, ep->b_buf, ep->req.length);
+ memcpy(ep->req.buf, ep->b_buf, ep->req.actual);
free:
/* Large payloads use allocated buffer, free it. */
if (ep->b_buf != ep->b_fast)
@@ -388,7 +388,7 @@ static void handle_ep_complete(struct ci_ep *ep)
num, in ? "in" : "out", item->info, item->page0);
len = (item->info >> 16) & 0x7fff;
- ep->req.length -= len;
+ ep->req.actual = ep->req.length - len;
ci_debounce(ep, in);
DBG("ept%d %s complete %x\n",