On Thu, Jun 25, 2009 at 1:56 PM, Daniel Drake<dsd@xxxxxxxxxx> wrote: > Alan Stern wrote: >> >> Daniel: >> >> I've got an idea for improving the way libusb handles short bulk-IN >> transfers (under Linux, anyway -- I don't know about Windows or Mac >> OS). It would require some changes to usbfs and corresponding changes >> to libusb. >> >> usbfs would be changed so that whenever a bulk URB with the >> URB_SHORT_NOT_OK flag set ended with a short packet, all the >> outstanding URBs queued to the same endpoint would be unlinked >> immediately. In addition, an "endpoint blocked" flag would prevent >> further URBs from being submitted to that endpoint until it was cleared >> by a new USBDEVFS_UNBLOCKEP ioctl. > Hi Alan, I think having a stop on short mechanism is a very good idea. If the devio would just abort all pending transfers on the endpoint, on this and all other urbs, we don't need a USBDEVFS_UNBLOCKEP call. The user app knows the transfer is done, the next submission should start another (possibly short transfer cancelled) IN urb. > I like the idea but I think there is a flaw, or maybe I'm not understanding > it right. > > Let's say I use libusb to create 2 64kb transfers to the same endpoint. I > submit both. libusb translates that to 8x16kb URBs, however libusb still > maintains a clear distinction of 2 separate transfers. > > The device sends 20kb of data. > The first URB completes all 16kb. The second URB completes 4kb. At this > point, your proposal would cancel all the remaining URBs, even those from > the queued 2nd transfer which we would desire to have left in place for > immediately picking up the next batch of incoming data. > > I like your other idea on the thread with David, basically that instead of > rejecting >16kb URBs from userspace, you just split them up into several > 16kb kmalloc()ed "kernel URBs" and maintain the grouping of several > kernel-URBs with the single "userspace URB" within usbfs. Basically moving > that type of logic from libusb to the kernel. > Lets be very clear about what a short transfer is. It is when a device sends a less than maxpacket sized transfer. This is only meaningful for int and bulk transfers (control too, but not relevant here). The idea is, if your protocol is to just have a device send data until it is "done", there needs to be a way to tell the receiver end the transfer is done. So if your maxpacket size is 512, sending a packet length 0 to 511 will say it is done. I don't think there is a current standard class that uses a short packet transfer termination, but it is useful in many custom applications. For lower overhead and higher transfer rates, userspace often asks for multiple packets. There is the current arbitrary maximum xfer size of 16*1024 bytes per urb. However, nothing stops an app from asking for 4 urbs of 16K and then waiting. It think that now the short packet will end the urb, but what of the other pending urbs? Alan's suggestion will fix that. I don't really think it is necessary to have bulk transfers of more than 16K, because multiple urbs can be queued up. However, it would be really nice to have devio accept iso transfers greater than the current 32K - which actually is limited by spec to 3*1024*8=24576. For high speed, high bandwidth iso, you need to schedule LOTS of urbs to keep the iso channel busy. Bulk, by definition, is not an inherent race like iso - more urbs is faster, but only xfer speed is lost if the app cannot keep up. Regards, Steve -- 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