On Mon, 14 Sep 2015, Igor Kotrasinski wrote: > 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@xxxxxxxxxxx> > --- > drivers/usb/gadget/udc/dummy_hcd.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c > index 0ba0ab3..38f51ff 100644 > --- a/drivers/usb/gadget/udc/dummy_hcd.c > +++ b/drivers/usb/gadget/udc/dummy_hcd.c > @@ -1283,6 +1283,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 */ > @@ -1345,6 +1346,7 @@ top: > req->req.status = len; > } else { > limit -= len; > + sent += len; > urb->actual_length += len; > req->req.actual += len; > } > @@ -1414,7 +1416,7 @@ top: > if (rescan) > goto top; > } > - return limit; > + return sent; > } > > static int periodic_bytes(struct dummy *dum, struct dummy_ep *ep) > @@ -1844,7 +1846,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; > } Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html