drivers >> asynchronous usb driver

by Enzo » Fri, 11 Jun 2004 06:08:20 GMT

I'm not expert in drivers, so i'm trying to modify a general driver (from
Cypress), that performs every mode of transmition in synchronous mode, to
asynchronous ( I need only for bulk).
In synchronous mode it blocks the computer in case the device doesn't answer
and you have to do Ctrl Alt Del etc... To transform it in asynchronous I
tryed in changing the last parameter in: KeWaitForSingleObject() from NULL
to a timeout value, but the PC could still remain blocked as before.
The call sequence is: KeInitializeEvent - IoBuildDeviceIoControlRequest -
IoCallDriver - KeWaitForSingleObject
I have read that setting IoCompletionRoutine should work in changing the
behavior to asynchronous, but I do not know how to use it exactely.
Is there someone that can give me some advice ?

Thank, Enzo.

drivers >> asynchronous usb driver

by Peter Wieland [MSFT] » Fri, 11 Jun 2004 08:49:28 GMT

hen you set a completion routine on the IRP, the I/O manager will call it
when the IRP completes. It actually calls each stack location's completion
routine in reverse order, and each is given an chance to stop the completion
in case it needs to reuse the IRP for some purpose.

So rather than sending a request to the lower device and waiting for it to
complete, you send the request and then return control to the caller
(usually returning STATUS_PENDING as the status for the request). The
callers also have to be prepared for asynchronous completion of the request.
The thread continues on doing whatever it was doing and when the lower
driver completes the outstanding request your completion routine is invoked.
You can copy data back to the original IRP and complete it, transform the
data if you need to, start a new I/O request, queue a work item (the
completion routine may be at DPC level, so if you need to do stuff at
passive level you need to post to a worker thread), etc...

You could try reusing the IRP you were called with rather than allocating
your own (if you were called with one) - just setup the next irp stack
location for a device i/o control, set the completion routine and send the
IRP down. Personally i don't ever use IoBuildDeviceIoControlRequest any
more since it's pretty easy to build an IRP (synch or asynch) with
IoAllocateIrp once you've done it a few times (and the completion model it
uses doesn't work well in the storage stack), and i find it more work than i
need when i'm building asynch requests since the event and IO status block
aren't useful anymore.

however making a driver asynchronous can be quite a bit of work, and it may
not buy you what you're expecting. I'm surprised that the driver could
"block the computer in case the device doesn't answer" - it should only
block the process calling it unless it's waiting in some critical thread or
it's doing something silly like spinning until the device responds. Unless
the calling process uses overlapped I/O their calls to your driver will
still be blocking - you'll just move the wait from the driver into
NtReadFile. You may instead want to look into doing a UserMode wait so that
the waits abort when the calling thread is being terminated, or implmeenting
some cancel support that cancels the underlying I/O request to get the
client unblocked faster.

i hope this helps a little.


This posting is provided "AS IS" with no warranties, and confers no rights.
"Enzo" < XXXX@XXXXX.COM > wrote in message
news:oZ4yc.309560$ XXXX@XXXXX.COM ...

drivers >> asynchronous usb driver

by Enzo » Sat, 12 Jun 2004 00:04:37 GMT

Thank Peter, i will try to study better the problem following your info.
Managing Drivers " target="_top" rel="nofollow">[Driver Robot fixes your driver problems] is not an easy task.
About the "blocking of PC", i was running a VBasic application. Even with an
activex dll I have the same result, notwistanding the fatc that it sould be
apartment-model threading. May be I have done something wrong.

drivers >> asynchronous usb driver

by Michael Bahrs » Mon, 14 Jun 2004 15:55:02 GMT

Hi Enzo,

I had the same problem and found a solution here:

Similar Threads

1. problem with Asynchronous readfile (USB)


I have a problem with reading from the USB Device by Asynchronous Readfile. 

My App Send data to the device every 4 seconds, and 
Device respond to that request after about 1.2 sec. 

About 20 minutes, the program is working fine. 
The problem is that after about 20 minutes, I dont get the data any more 
from readfile in the following read thread. 

read Thread 
bRead = TRUE; 
if( bRead ) 
ReadFile( ,, Event) 

--> When Error State is IO_PENDING ,,or Previous is WAIT_TIMEOUT, process 
the following ! 
dwRet = WaitForSingleObject(,,, timeout = 2000 ) 
if( dwRet == WAIT_OBJECT_0 ) 
bRet = GetOverLappedResult( ,, lpbytes,,) 
if( bRet = TRUE && lpBytes > 0 ) 
{ success !! fine about 20 - 30 minutes 
bRead = TRUE; 
else if( bRet == FALSE ) return; //error 
else { 
bRead = TRUE; } 
;; In this part, even usb monitoring tool shows, 
there is data, 
But I get lpbytes = 0 
else if( dwRet == WAIT_TIMEOUT) 
{ bRead = FALSE; // dont want to call readfile again !! 

else {} // dont happen.. 
} // endwhile 

Any Help will be Appreciated . Thanks in Advance. 

2. Asynchronous command buffer processing

3. USBAudio.sys bug for Asynchronous OUT enpoint with rate feedba

4. Asynchronous io monitor

5. Asynchronous IRP remove lock race?

In the WDM book, I see the way to send an asynchronous IRP to a lower
driver is to do an IoAcquireRemoveLock(), install a completion
routine, do the IoCallDriver(), and do an IoReleaseRemoveLock() in the
completion routine.  The remove lock is meant to prevent a PNP remove
from being forwarded to the lower driver while it's processing the
IRP, but won't the lower driver still be blocked in its call to
IoCompleteRequest() when the completion routine releases the remove
lock?  That is, couldn't the other driver then be removed before its
completely done with the IRP?

I can think of two cases:

    If the lower driver is calling IoCompleteRequest() from a worker
thread or a DPC, then it should be expected that thread or DPC will be
allowed to finish before the driver is removed.  This case should be

    If the lower driver is calling IoCompleteRequest() from its
dispatch routine, won't the completion routine remove the lock before
the dispatch routine returns so the lower driver could be removed
before the next few instructions that return from its dispatch
routine?  This case seems to require the same extra reference solution
the WDM book mentions that initially confused me for a few days.  I
think the remove lock needs to be acquired twice and released in both
the completion routine and after the call to IoCallDriver(), to make
sure the lower driver can't be removed until they're both finished
(whichever finishes first).  As an alternative, I guess an extra
reference would work too.

(Of course, this alternative makes me wonder what are the advantages
of using a remove lock vs. taking extra references.  They can both be
used to keep a device object in memory, but I guess the remove lock
can be used to start failing new IRPs at a certain point in the
removal process, so the removal goes faster.  It doesn't actually
prevent new IRPs from being received by a dispatch routine.  It just
allows them to be quickly completed with error status.)

6. Driver's Role in an Asynchronous Call to DeviceIOControl

7. Difference between synchronous and asynchronous operation/calls (NDISPROT)


I think I understand a little bit the differences between these two modes of 
operation and I would like to learn/know some more about possible problems 
or solutions.

The main problem with synchronous operation/calls seems to be the lack of 
buffers for the driver to store data into. (So far I have only 
examined/thought about how receiving would work in both modes)

In synchronous mode it seems the driver uses it's own buffers and it only 
has a few of those. If the application does not call ReadFile fast enough 
the driver has no choice but to through away some buffers to recycle them to 
catch new frames/data on the wire. So the application starts losing this 

In asynchronous mode it seems the application supplies the driver some 
buffers up front... for example the application tells the driver to perform 
multiple read operations. Each "read call" supplies the driver with a buffer 
and optionally a completion routine so that the driver can inform the 
application when the requested operation (the read/receive/send whatever) 
is/was done.

However there seems to be more to it than that. Since somebody else posted a 
message about decreased performance and somebody else recommend issueing 
multiple read request... for example 32 "outstanding" read requests... to 
keep the driver busy etc. Why is this exactly ?

Why would the following two simple designs give slower performance ?

1. First slow design:

Driver uses it's own single buffer and receives data into the buffer. Then 
informs the user/application about this via a callback and requests a buffer 
from the user. Then the driver copies the received data into the user's 

This would almost be the same as an i/o completion routine. Maybe it's 
almost exactly the same. The only difference is the user only supplies the 
buffer when the driver requests it and not vica versa.

The copy is ofcourse bad because copieing costs cpu time. However it seems 
the current windows/driver design does some copies as well ? I am not to 
sure about that.

2. Second slow design:

User supplies the buffer up front and the driver receives the data into the 
buffer and informs the user when it received the data via the callback. The 
user should supply a new buffer immediatly and then the user can process the 
older buffer. But ofcourse this would be a little bad... because the 
processing could take to long. Anyway This would prevent a copy whatever. I 
think this was the second design I my mind maybe I forgot what the second 
design was lol. This was probably it though.

Anyway the main difference between synchronous and asynchronous operation 
seems to be in the buffer handlig. With asynchronous operation the user is 
in control of the buffers mostly. The driver still has some internal buffers 
but if everything goes well the driver should only need one or two internal 
buffers and immediatly issue i/o completion callbacks etc. However NDISPROT 
seems limited to only 4 internal buffers ? That seems a little bit low and 

Anyway in reality there seems to be more to it than that.

I for example do not understand what I takes to transfer a buffer from 
"kernel mode" to "user mode". Maybe this is simply done with a special 
function. But "user mode" could also have it's own thread/process and the 
driver could also have it's own thread/process.

So how does the driver transfer the buffer between threads/processes ?

Which takes me to my next question:

What could prevent a driver from completing a request.... so what could 
prevent a driver from calling the i/o completion routine ?

Which could explain why the driver needs more buffers because for some 
reason it can't complete it. So it has to wait and meanwhile needs more 
buffers to keep receiving new data ?!?

Also doesn't this mean the driver needs a while loop... to quickly perform 
multiple completion callbacks because it couldn't do it previously... to 
keep up. This while loop would cause the driver to take a little sprint and 
catch up if you know what I mean.

Any answers could help me make understand a little bit better how many 
buffers a driver needs...


8. Asynchronous IRP and ISR