USB client driver & IoCompletion

Hi All,

I am writing a USB Client driver for a USB device.

I want to know whether “submitting” URB request again in IoCompletion routine of IRP/URB request to USBD is OK?

Thanks in advance.

Anand


Speed up your surfing with Juno SpeedBand.
Now includes pop-up blocker!
Only $14.95/month -visit http://www.juno.com/surf to sign up today!

Yes.
Look into isochronous ddk sample.
There is one exception: A RESET_PIPE will only work at passive level.
So you should try to send it from completion routine.
Norbert.

“A friend is someone who knows all about you, but likes you anyway.”
---- snip ----

I want to know whether “submitting” URB request again in
IoCompletion routine of IRP/URB request to USBD is OK?
---- snip ----

Sorry, I meant:
So you should NOT try to send it from completion routine.
Norbert.

Warning:
As with all IoCallDriver calls done from a completion routine you should
carefully check against the stack limits. You may be called recursively
in your completion routine ( escpecially when URBs fail ).
Norbert.

“All generalizations are false.”
---- snip ----

Yes, it is OK.

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

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Tuesday, May 10, 2005 10:12 AM
Subject: [ntdev] USB client driver & IoCompletion

>
> Hi All,
>
> I am writing a USB Client driver for a USB device.
>
> I want to know whether “submitting” URB request again in IoCompletion routine
of IRP/URB request to USBD is OK?
>
> Thanks in advance.
>
> Anand
>
> ___________________________________________________________________
> Speed up your surfing with Juno SpeedBand.
> Now includes pop-up blocker!
> Only $14.95/month -visit http://www.juno.com/surf to sign up today!
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

>>
>>I want to know whether “submitting” URB request again in IoCompletion
>> routine of IRP/URB request to USBD is OK?
>>

No, it is NOT “OK”. Resubmitting an IRP from a completion routine is
almost NEVER OK, except in very rare and special circumstances.

Consider that your completion routine is called from IoCompleteRequest,
and that IoCompleteRequest could be called synchronously on the same
stack as your original call to IoCallDriver. Result? Very little stack
space.

Further, consider that your completion routine could be called from the
DCP of the device driver. Result? Your completion routine runs at IRQL
DISPATCH_LEVEL. It’s not polite, to say the very least, to call other’s
dispatch entry points at IRQL DISPATCH_LEVEL>

You probably want to read this month’s article on this topic in The NT
Insider: http://www.osronline.com/article.cfm?id=391

Peter
OSR

Send/receive URBs can be sent to USB stack on DISPATCH_LEVEL.

So are the serial read/write, and the disk stack read/write. So is
TDI_SEND.

Yes, stack size is an issue. Call IoGetRemainingStackSize, and if the size
is too small - queue the operation by using KeInsertQueueDpc.

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

----- Original Message -----
From: “PeterGV (OSR)”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Tuesday, May 10, 2005 5:07 PM
Subject: Re:[ntdev] USB client driver & IoCompletion

> >>
> >>I want to know whether “submitting” URB request again in IoCompletion
> >> routine of IRP/URB request to USBD is OK?
> >>
>
> No, it is NOT “OK”. Resubmitting an IRP from a completion routine is
> almost NEVER OK, except in very rare and special circumstances.
>
> Consider that your completion routine is called from IoCompleteRequest,
> and that IoCompleteRequest could be called synchronously on the same
> stack as your original call to IoCallDriver. Result? Very little stack
> space.
>
> Further, consider that your completion routine could be called from the
> DCP of the device driver. Result? Your completion routine runs at IRQL
> DISPATCH_LEVEL. It’s not polite, to say the very least, to call other’s
> dispatch entry points at IRQL DISPATCH_LEVEL>
>
> You probably want to read this month’s article on this topic in The NT
> Insider: http://www.osronline.com/article.cfm?id=391
>
> Peter
> OSR
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

As a general rule, I agree with you. The USB core has been specifically
engineered to allow irp resends from a completion routine. IRPs are
usually completed from the DPC routine, so even if it is resent from
w/in the completion routine, the stack will unwind a bit before
recalling your CR.

Another thing to consider is total DPC time. If you are resending your
IRP in the CR and your device is constantly streaming data, you could
trigger the DPC is running for more then one second ASSERT b/c you are
not allowing the USB core’s DPC to return. In WDF, I always requeue to
my own DPC before resending, I figured it was middle ground between a
pure resend and queueing a work item.

In terms of stack space, you can figure out if your completion routine
has completed synchronously on you (ie consumed a bunch of stack space
and possibly more if it continues) or if it completed asynchronously
rather easily. Look at the sermouse example in the ddk, in particular,
1 the ReadInterlock field of the DeviceExtension
2 the values SERIAL_MOUSE_START_READ, SERIAL_MOUSE_END_READ,
SERIAL_MOUSE_IMMEDIATE_READ
3 the use of InterlockedXxx operations using the field and the values

This pattern can be applied to any stack where you are resending i/o
from the CR.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of PeterGV (OSR)
Sent: Tuesday, May 10, 2005 6:08 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] USB client driver & IoCompletion

>
>>I want to know whether “submitting” URB request again in IoCompletion
>> routine of IRP/URB request to USBD is OK?
>>

No, it is NOT “OK”. Resubmitting an IRP from a completion routine is
almost NEVER OK, except in very rare and special circumstances.

Consider that your completion routine is called from IoCompleteRequest,
and that IoCompleteRequest could be called synchronously on the same
stack as your original call to IoCallDriver. Result? Very little stack

space.

Further, consider that your completion routine could be called from the
DCP of the device driver. Result? Your completion routine runs at IRQL

DISPATCH_LEVEL. It’s not polite, to say the very least, to call other’s

dispatch entry points at IRQL DISPATCH_LEVEL>

You probably want to read this month’s article on this topic in The NT
Insider: http://www.osronline.com/article.cfm?id=391

Peter
OSR


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The OP asked for URBs. Even the isousb ddk sample uses this technique.
So I assume it is OK in this case. I think it is also a good idea to do
so for devices that have a ‘streaming’ architecture (performance,
lesser context switches).

I remember a discussion in this list about 3 years back. The consensus
then was, that it is the responsibility of a dispatch routine to
handle unexpected IRQL.

Hmm, 4th posting to same thread on one day( that is my all-time
record).

excerpt of isousb sample (3790 DDK):
At the end of completion routine:

//
// otherwise circulate the irps.
//

IsoUsb_InitializeStreamUrb(deviceObject, transferObject);

nextStack = IoGetNextIrpStackLocation(Irp);
nextStack->Parameters.Others.Argument1 = transferObject->Urb;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;

IoSetCompletionRoutine(Irp,
IsoUsb_IsoIrp_Complete,
transferObject,
TRUE,
TRUE,
TRUE);

transferObject->TimesRecycled++;

ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);

IsoUsb_DbgPrint(3, (“IsoUsb_IsoIrp_Complete - ends\n”));
IsoUsb_DbgPrint(3, (“-----------------------------\n”));

return STATUS_MORE_PROCESSING_REQUIRED;
}

Norbert.

“Quarrel with a friend and you are both wrong. - Lao Tzu”
---- snip ----

No, it is NOT “OK”. Resubmitting an IRP from a completion routine is
almost NEVER OK, except in very rare and special circumstances.
---- snip ----

Norbert Kawulski wrote:

The OP asked for URBs. Even the isousb ddk sample uses this technique.
So I assume it is OK in this case.
>

And, like, there haven’t been any mistakes in the DDK USB driver samples?

In the USB case, Doron has assured us that the USB stack has been
engineered specifically to allow URBs to be resubmitted from the I/O
completion routine callback. I have the utmost respect for Doron, and
believe what he says about USB implicitly (well, except when he’s
wrong!). But you have to read ALL of Doron’s post. It’s not a wholesale
invitation to IoCallDriver from your completion routine.

I’ll file a bug to get Doron’s wisdom etched into the tablets that are
the DDK documentation. That’ll make it harder for the next group of MS
USB devs to change this design.

I think it is also a good idea to do
so for devices that have a ‘streaming’ architecture (performance,
lesser context switches).

There are always exceptions to the rule. Like almost anything, if done
correctly, it’s fine. If done incorrectly, it’s not OK. Another
example of where you see this done is video capture.

Remember, the question wasn’t “to which drivers can I submit an IRP at
IRQL DISPATCH_LEVEL and not have the driver blue screen, as of today.”
The question was “is this OK?” Doron has given us the architectural
answer that in the USB stack, it IS OK.

However, that doesn’t detract from the fact that IN GENERAL calling
IoCallDriver from within an I/O completion callback is NOT OK for all
the reasons previously mentioned.

I remember a discussion in this list about 3 years back. The consensus
then was, that it is the responsibility of a dispatch routine to
handle unexpected IRQL.

If that was the consensus, it’s wrong.

Good engineering demands that one is strict in what one does, and
tolerant in what one accepts. Thus, it’s good engineering practice to
write one’s dispatch routine such that it can be called at IRQL
DISPATCH_LEVEL. It is also good engineering practice to limit one’s
calls to OTHERs dispatch routines to IRQL PASSIVE_LEVEL unless the
driver you’re calling specifically notes and allows calls at IRQL
DISPATCH_LEVEL.

Peter
OSR

> ----------

From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of PeterGV (OSR)[SMTP:xxxxx@osr.com]
Reply To: Windows System Software Devs Interest List
Sent: Wednesday, May 11, 2005 12:08 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] USB client driver & IoCompletion

I’ll file a bug to get Doron’s wisdom etched into the tablets that are
the DDK documentation. That’ll make it harder for the next group of MS
USB devs to change this design.

Great, such things should be documented. However, not only IsoUsb sample uses this technique, also BulkUsb. There is a lot of drivers in the wild based on this sample and I believe (or hope :slight_smile: even MS can’t afford to change design the way which’d break significant number of USB drivers and affect their users.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

A ton of internal MSFT in box drivers have a variation on this theme as
well, so it will show up as broken very quickly if they ever decided to
break this type of I/O model.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Michal Vodicka
Sent: Tuesday, May 10, 2005 4:57 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] USB client driver & IoCompletion


From:
xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com
] on behalf of PeterGV (OSR)[SMTP:xxxxx@osr.com]
Reply To: Windows System Software Devs Interest List
Sent: Wednesday, May 11, 2005 12:08 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] USB client driver & IoCompletion

I’ll file a bug to get Doron’s wisdom etched into the tablets that are

the DDK documentation. That’ll make it harder for the next group of
MS
USB devs to change this design.

Great, such things should be documented. However, not only IsoUsb sample
uses this technique, also BulkUsb. There is a lot of drivers in the wild
based on this sample and I believe (or hope :slight_smile: even MS can’t afford to
change design the way which’d break significant number of USB drivers
and affect their users.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

see below
Norbert.

“Consciousness: that annoying time between naps.”
---- snip ----

I’ll file a bug to get Doron’s wisdom etched into the tablets that are
the DDK documentation. That’ll make it harder for the next group of MS
USB devs to change this design.
Good.
However, that doesn’t detract from the fact that IN GENERAL calling
IoCallDriver from within an I/O completion callback is NOT OK for all
the reasons previously mentioned.

Sure.

> I remember a discussion in this list about 3 years back. The consensus
> then was, that it is the responsibility of a dispatch routine to
> handle unexpected IRQL.
>

If that was the consensus, it’s wrong.

It must be my wording or lack of understanding. What is wrong having
the dispatch routine being responsible for handling IRQLs that are not
PASSIVE_LEVEL (instead of just give BSOD). I think below you just gave
the same advice as being ‘good engineering practice’. So, yes I agree
:slight_smile:

Good engineering demands that one is strict in what one does, and
tolerant in what one accepts. Thus, it’s good engineering practice to
write one’s dispatch routine such that it can be called at IRQL
DISPATCH_LEVEL.
---- snip ----

b/c if this were the design, you would never be able to mark any
dispatch routine as PAGEable. As the provider of a service / interface,
you get to define the rules for that interface. As a client of that
interface, you must follow the rules. Allowing the client to define the
rules is a bit chaotic and leads to some very nasty, entangled, and
unmanagable code very quickly b/c you then don’t know what is going to
happen and when.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Norbert Kawulski
Sent: Wednesday, May 11, 2005 10:07 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] USB client driver & IoCompletion

see below
Norbert.

“Consciousness: that annoying time between naps.”
---- snip ----

I’ll file a bug to get Doron’s wisdom etched into the tablets that are

the DDK documentation. That’ll make it harder for the next group of
MS USB devs to change this design.
Good.
However, that doesn’t detract from the fact that IN GENERAL calling
IoCallDriver from within an I/O completion callback is NOT OK for all
the reasons previously mentioned.

Sure.

> I remember a discussion in this list about 3 years back. The
> consensus then was, that it is the responsibility of a dispatch
> routine to handle unexpected IRQL.
>

If that was the consensus, it’s wrong.

It must be my wording or lack of understanding. What is wrong having
the dispatch routine being responsible for handling IRQLs that are not
PASSIVE_LEVEL (instead of just give BSOD). I think below you just gave
the same advice as being ‘good engineering practice’. So, yes I agree
:slight_smile:

Good engineering demands that one is strict in what one does, and
tolerant in what one accepts. Thus, it’s good engineering practice to

write one’s dispatch routine such that it can be called at IRQL
DISPATCH_LEVEL.
---- snip ----


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Doron, thanks for this clarification. As many drivers do not
explicitly define their rules, Peter’s advice makes the most sense.
Now I understand where I was wrong.(These days the dark side of the
force is strong :slight_smile:
Norbert.

“Wise men learn more from fools than fools from wise men. - Marcus
Pocius Cato”
---- snip ----

b/c if this were the design, you would never be able to mark any
dispatch routine as PAGEable. As the provider of a service / interface,
you get to define the rules for that interface. As a client of that
interface, you must follow the rules. Allowing the client to define the
rules is a bit chaotic and leads to some very nasty, entangled, and
unmanagable code very quickly b/c you then don’t know what is going to
happen and when.

d

---- snip ----