WinUSB packet ordering

Hi!

Let’s say I have a USB 2.0 function which transfers data at several Mbytes/sec, providing data packets in order A, B, C.
Do I have any guarantee that the packets arrive at the user-mode application in the same order, when using WinUSB?

NB I have complete control over the firmware as well as the device driver to be used. I would really like to use WinUSB so there is no
driver work to be done.

Thank you!
Chris

Just to make it more clear: the data rate isn’t my concern - we are talking well below 30 MB/sec on a 2.0 host controller. I am worried that Windows’ asnyc kernel/completion may re-order the packets when read from the HC, so the UM app sees them for example as C, A, B.

I’d appreciate any help or comments on this!

c_bauer wrote:

Let’s say I have a USB 2.0 function which transfers data at several Mbytes/sec, providing data packets in order A, B, C.

Do I have any guarantee that the packets arrive at the user-mode application in the same order, when using WinUSB?

NB I have complete control over the firmware as well as the device driver to be used. I would really like to use WinUSB so there is no driver work to be done.

In practical terms, yes.  To answer your overall question, there is
nothing you can do in a custom driver that will improve what WinUSB does
in this regard.

Technically speaking, you’re at the mercy of the scheduler.  The driver
will certainly complete the requests in order.  If you are using
overlapped I/O, that means you’ll have two overlapped events signalled. 
If the two events happen very close to each other, and you happen to be
using WaitForMultipleObjects, the operating system doesn’t guarantee
that the WFMO return value points to the earliest object.

There are ways to handle that.  If you are using synchronous I/O, so
that you wait for the packet, then it all works fine, because you won’t
submit the second request until the first completes.  If you are using
asynchronous I/O, then with the data rates you’re talking about, it
shouldn’t be a problem.

c_bauer wrote:

Just to make it more clear: the data rate isn’t my concern - we are talking well below 30 MB/sec on a 2.0 host controller. I am worried that Windows’ asnyc kernel/completion may re-order the packets when read from the HC, so the UM app sees them for example as C, A, B.

That can’t happen.  USB is all scheduled in advance, and it’s all done
by hardware DMA.  Let’s you submit a request for 10,240 bytes, which is
20 packets.  The host controller driver chops that into 200 packet
requests and lays them out in its schedule in order.  The first packet
will have a DMA descriptor pointing to the first 512 bytes of your
buffer.  The next packet has a DMA descriptor pointing to the next 512
bytes.  That will continue across into the next frame, at which point
the transfer should be satisfied.

The hardware then “executes” this schedule by sending out IN tokens to
the device.  Whatever the device sends will get DMAed directly into your
buffer before the hardware advances to the next packet in its schedule.

When the frame completes, the host controller driver will complete any
requests that have been fully satisfied, in the order they appear.  So,
the client driver’s completion routine will be called in order.  The
host controller can’t move on to the next completed request until your
completion routine returns.

> Technically speaking, you’re at the mercy of the scheduler. The driver

will certainly complete the requests in order. If you are using
overlapped I/O, that means you’ll have two overlapped events signalled.
If the two events happen very close to each other, and you happen to be
using WaitForMultipleObjects, the operating system doesn’t guarantee
that the WFMO return value points to the earliest object.

The trick is to wait for the correct event. Single one, not all. In the past I used a queue of overlapped requests passed to the driver and waited always just for the first/front one. Once signaled, removed it from queue and continued the same way. Worked well with WinUsb.

Michal