Re: Handling short transfers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux