USB Bus Driver calling Completion Routine

Scenario: My USB driver has allocated multiple IRPS/URBS(7 for example) with a completion routine and sent these to the USBD using IoCallDriver, and then the device is removed while 3 of the Irps are still in the USBD queue.

Question: Is it required that my surprise removal handler call IoCancelIrp() to cause the USBD to call the completion routine 3 times before the driver unloads? The docs say that if I set the InvokeOnCancel flag to true in IoSetCompletionRoutine() that the completion routine will be called if the driver or kernel has called IoCancelIrp().

If I don’t set InvokeOnCancel to true and do not call IoCancelIrp() will the USBD unload all the Irps and call the completion routine multiple times before the driver is unloaded on surprise removal?

Thanks
-decoder

Short answer: you get nothing for free.

No USBD will not complete these for you on surprise removal. You need to cancel them. If you do not set InvokeOnCancel when setting the cancel routine, the irp (which I assume you allocated) will complete back to the io manager where it will try to queue an APC to the owning thread (which is not set) which will bluescreen. You need to have the c.r. be invoked in all cases and then return STATUS_MORE_PROCESSING_REQUIRED so that it does not complete back to the io manager and you must free it on your own. You need to synchronize the io you have sent to the lower stack with the pnp state of the stack. If you use KMDF, you get all of the building blocks for this for free and the KMDF solution is a one line function call

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@maxlinear.com
Sent: Wednesday, June 25, 2008 6:58 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] USB Bus Driver calling Completion Routine

Scenario: My USB driver has allocated multiple IRPS/URBS(7 for example) with a completion routine and sent these to the USBD using IoCallDriver, and then the device is removed while 3 of the Irps are still in the USBD queue.

Question: Is it required that my surprise removal handler call IoCancelIrp() to cause the USBD to call the completion routine 3 times before the driver unloads? The docs say that if I set the InvokeOnCancel flag to true in IoSetCompletionRoutine() that the completion routine will be called if the driver or kernel has called IoCancelIrp().

If I don’t set InvokeOnCancel to true and do not call IoCancelIrp() will the USBD unload all the Irps and call the completion routine multiple times before the driver is unloaded on surprise removal?

Thanks
-decoder


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Doran,

Thanks for the clear explanation!

-decoder

Hello Doron,

What if i dont have cancel routine and just completion routine? Will the completion routine will still get a call back from USBD when IoCancelIrp is called?

xxxxx@gmail.com wrote:

What if i dont have cancel routine and just completion routine? Will the completion routine will still get a call back from USBD when IoCancelIrp is called?

If you set InvokeOnCancel, certainly. Most people pass “TRUE, TRUE,
TRUE” to IoSetCompletionRoutine just for this reason.

Also note that it isn’t IoCancelIrp that causes the callback. That just
sets a bit in the IRP. As many have said, it is a “suggestion”. At
some point, USBD (because it is a well-behaved driver) will notice that
the cancel bit has been set, and will complete the IRP with
STATUS_CANCELED. That’s what triggers the completion routine.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

That answers my question.

Thanks Tim.

You are confusing 2 different routines. The driver which pends the irp and holds onto it (and will complete it later) has a cancel routine. This is what it means to mark an irp as cancelable. Your driver, the one who is sending the irp, has a completion routine which is invoked when the irp is completed by the driver you sent the irp to. There can be many completion routines, as many as there are stack locations in the PIRP, but there can only be one cancel routine for an IRP

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, June 26, 2008 10:30 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] USB Bus Driver calling Completion Routine

Hello Doron,

What if i dont have cancel routine and just completion routine? Will the completion routine will still get a call back from USBD when IoCancelIrp is called?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> What if i dont have cancel routine and just completion routine? Will the

completion routine will still get a call back from USBD when IoCancelIrp is
called?

Cancel routines should be implemented by the driver which processes the IRP,
not the one which creates the IRP and sends it down.

Completion routines, unlike cancel ones, should be implemented in the driver
which creates the IRP and sends it down.

If the IRP-processing driver has no cancel routine - then most usually
IoCancelIrp is a no-op, and the upper driver will need to wait for the IRP’s
normal completion, which can take forever.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com