On Mon, 14 Sep 2015, Igor Kotrasinski wrote: > transfer() schedules a rescan for transfers larger than > maxpacket, which is wrong for transfers that are multiples > of maxpacket. > > Rewrite to fix and clarify packet multiple / remainder > transfer logic. > > Signed-off-by: Igor Kotrasinski <i.kotrasinsk@xxxxxxxxxxx> > --- > drivers/usb/gadget/udc/dummy_hcd.c | 17 ++++++++++++----- > 1 file changed, 12 insertions(+), 5 deletions(-) > > diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c > index 552c533..0ba0ab3 100644 > --- a/drivers/usb/gadget/udc/dummy_hcd.c > +++ b/drivers/usb/gadget/udc/dummy_hcd.c > @@ -1288,6 +1288,7 @@ top: > /* if there's no request queued, the device is NAKing; return */ > list_for_each_entry(req, &ep->queue, queue) { > unsigned host_len, dev_len, len; > + unsigned quot, rem; > int is_short, to_host; > int rescan = 0; > > @@ -1324,12 +1325,18 @@ top: > if (len == 0) > break; > > - /* use an extra pass for the final short packet */ > - if (len > ep->ep.maxpacket) { > - rescan = 1; > - len -= (len % ep->ep.maxpacket); > + /* send multiple of maxpacket first, then remainder */ > + rem = (len % ep->ep.maxpacket); > + quot = len - rem; You shouldn't call this "quot" because it isn't a quotient. In fact, you don't really need quot at all; you could just write "len -= rem;". > + if (quot > 0) { > + is_short = 0; > + len = quot; > + if (rem > 0) > + rescan = 1; > + } else { /* rem > 0 */ > + is_short = 1; > + len = rem; > } > - is_short = (len % ep->ep.maxpacket) != 0; > > len = dummy_perform_transfer(urb, req, len); Alan Stern -- 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