summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorIgor Kotrasinski <i.kotrasinsk@samsung.com>2015-09-15 16:55:32 +0200
committerFelipe Balbi <balbi@ti.com>2015-09-21 14:42:36 -0500
commit9a9ce1dfaef9aa15980cec22b806b39a65a9467e (patch)
treef5bafcb806b1fed4199e07c69612c37f62342684 /drivers/usb
parente42bd6a54b97e2a39b5004deac66a0fcd6ebbe75 (diff)
usb: gadget: dummy_hcd: in transfer(), return data sent, not limit
dummy_timer uses transfer() to update transfer limit. However, limit passed to dummy_timer changes depending on transfer type, so the actual limit is overwritten. This can cause unpredictably slow / fast bulk transfers when coupled with control / interrupt transfers. Fix by returning actual amount of data sent in transfer() and substracting from total. Signed-off-by: Igor Kotrasinski <i.kotrasinsk@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index ab7e015e2f55..27af0f008b57 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -1348,6 +1348,7 @@ static int transfer(struct dummy_hcd *dum_hcd, struct urb *urb,
{
struct dummy *dum = dum_hcd->dum;
struct dummy_request *req;
+ int sent = 0;
top:
/* if there's no request queued, the device is NAKing; return */
@@ -1402,6 +1403,7 @@ top:
req->req.status = len;
} else {
limit -= len;
+ sent += len;
urb->actual_length += len;
req->req.actual += len;
}
@@ -1472,7 +1474,7 @@ top:
if (rescan)
goto top;
}
- return limit;
+ return sent;
}
static int periodic_bytes(struct dummy *dum, struct dummy_ep *ep)
@@ -1902,7 +1904,7 @@ restart:
default:
treat_control_like_bulk:
ep->last_io = jiffies;
- total = transfer(dum_hcd, urb, ep, limit, &status);
+ total -= transfer(dum_hcd, urb, ep, limit, &status);
break;
}