Hi,
I’ve recently started testing a driver under Windows Vista. The driver was originally written a while back with Windows 2000 and XP in mind, and has been used on extensively without any problems. Initially my testing suggested that it would also work under Vista. However, after closer examination I discovered a problem…
The driver reads from a USB device by submitting 8 URBs. These URBs are in the form of IRPs created using IoAllocateIrp. Normally when a URB completes, the data it contains is passed to the user, the IRP is reused using IoReuseIrp, and it is resubmitted. However, I also pass a structure to the completion routine which contains the index of the URB. The URB is only processed if it is the next one to complete. If not, it is added to a list and processed when all previous URBs have been received and processed.
This all works well under XP and 2000, and deals with any out of order completion which may occur on multi-processor/core machines. However, under Vista things don’t quite go to plan. Occasionally a URB will complete out of order and the driver will re-order it. The problem is that the data contained within the out of order URB is actually in order.
I’ll try and show this with an example. This is how things should work, and how it works under XP/2000:
URB 0 submitted
URB 1 submitted
URB 2 submitted
URB 3 submitted
URB 4 submitted
URB 5 submitted
URB 6 submitted
URB 7 submitted
URB 0 completes - data 0 passed to user
URB 0 re-submitted
URB 1 completes - data 1 passed to user
URB 1 re-submitted
URB 2 completes - data 2 passed to user
URB 2 re-submitted
URB 3 completes - data 3 passed to user
URB 3 re-submitted
URB 4 completes - data 4 passed to user
URB 4 re-submitted
URB 5 completes - data 5 passed to user
URB 5 re-submitted
URB 6 completes - data 6 passed to user
URB 6 re-submitted
URB 7 completes - data 7 passed to user
URB 7 re-submitted
URB 0 completes - data 8 passed to user
URB 0 re-submitted
URB 4 completes - data 12 not passed to user
URB 1 completes - data 9 passed to user
URB 1 re-submitted
URB 2 completes - data 10 passed to user
URB 2 re-submitted
URB 3 completes - data 11 passed to user
URB 3 re-submitted
Data 12 passed to user
URB 4 re-submitted
URB 5 completes - data 13 passed to user
URB 5 re-submitted
URB 6 completes - data 14 passed to user
URB 6 re-submitted
URB 7 completes - data 15 passed to user
URB 7 re-submitted
And this is what occasionally happens under Vista:
URB 0 submitted
URB 1 submitted
URB 2 submitted
URB 3 submitted
URB 4 submitted
URB 5 submitted
URB 6 submitted
URB 7 submitted
URB 0 completes - data 0 passed to user
URB 0 re-submitted
URB 1 completes - data 1 passed to user
URB 1 re-submitted
URB 2 completes - data 2 passed to user
URB 2 re-submitted
URB 3 completes - data 3 passed to user
URB 3 re-submitted
URB 4 completes - data 4 passed to user
URB 4 re-submitted
URB 5 completes - data 5 passed to user
URB 5 re-submitted
URB 6 completes - data 6 passed to user
URB 6 re-submitted
URB 7 completes - data 7 passed to user
URB 7 re-submitted
URB 0 completes - data 8 passed to user
URB 0 re-submitted
URB 4 completes - data 9 not passed to user
URB 1 completes - data 10 passed to user
URB 1 re-submitted
URB 2 completes - data 11 passed to user
URB 2 re-submitted
URB 3 completes - data 12 passed to user
URB 3 re-submitted
Data 9 passed to user
URB 4 re-submitted
URB 5 completes - data 13 passed to user
URB 5 re-submitted
URB 6 completes - data 14 passed to user
URB 6 re-submitted
URB 7 completes - data 15 passed to user
URB 7 re-submitted
So what’s happening is the data past to the user is out of sequence. Hope that all makes sense (and there’s no limit to the maximum post size)! I’ve checked with a CATC USB Analyser, and the USB traffic is definitely in the correct order. Running Verifier reports no bad things happening, and I’ve gone over my code without finding any problems.
So, to my questions. Is there some change in Vista that I don’t know about that’s causing this out of order completion? Or can anyone suggest something else that might be wrong to cause this? I’ve spent a great deal of time looking into this and have ran out of ideas.
Thanks in advance, and sorry for the long post.