USB: Cancelling a request on a control endpoint

Guys,

I have a device that does not support string descriptors. When I issue a
USB_STRING_DESCRIPTOR_TYPE the device usually responds with a STALL PID –
which I believe is the correct behavior. However, occationally it will fail
to return the stall pid. If I issue the IRP synchronously, IoCallDriver
never returns. I would like to make the call asynchronously and then cancel
the IRP if it times out. But if I call IoCancelIrp() I almost always get a
BSOD in USBPORT.

Question: Is there a way to cancel a request on a control endpoint?

Thanks,
J.

Isn’t it better to fix the device? It isn’t USB compliant if behaves
like this.

I’m not sure if you can use URB_FUNCTION_ABORT_PIPE for control pipe. If
so, it cancels all outstanding requests. If it can’t be used, you can
try to reset parent port: IOCTL_INTERNAL_USB_RESET_PORT. Maybe you’ll
need to do it anyway to restore from this state.

Best regards,

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of jjjames1
Sent: Tuesday, February 19, 2008 12:25 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] USB: Cancelling a request on a control endpoint

Guys,

I have a device that does not support string descriptors.
When I issue a
USB_STRING_DESCRIPTOR_TYPE the device usually responds with a
STALL PID –
which I believe is the correct behavior. However,
occationally it will fail
to return the stall pid. If I issue the IRP synchronously,
IoCallDriver
never returns. I would like to make the call asynchronously
and then cancel
the IRP if it times out. But if I call IoCancelIrp() I almost
always get a
BSOD in USBPORT.

Question: Is there a way to cancel a request on a control endpoint?

Thanks,
J.


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

Fix the device! Ya well that’s not going to happen. That would make it a
problem for the hardware guys. Driver guys are the ones to fix problems.

At any rate:

Thanks for your reply. URB_FUNCTION_ABORT_PIPE requires a handle to a
pipe – which we don’t have for a control endpoint. However
IOCTL_INTERNAL_USB_RESET_PORT does seem to be working.

Regards,
J

“Michal Vodicka” wrote in message
news:xxxxx@ntdev…
Isn’t it better to fix the device? It isn’t USB compliant if behaves
like this.

I’m not sure if you can use URB_FUNCTION_ABORT_PIPE for control pipe. If
so, it cancels all outstanding requests. If it can’t be used, you can
try to reset parent port: IOCTL_INTERNAL_USB_RESET_PORT. Maybe you’ll
need to do it anyway to restore from this state.

Best regards,

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

> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of jjjames1
> Sent: Tuesday, February 19, 2008 12:25 AM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] USB: Cancelling a request on a control endpoint
>
> Guys,
>
> I have a device that does not support string descriptors.
> When I issue a
> USB_STRING_DESCRIPTOR_TYPE the device usually responds with a
> STALL PID –
> which I believe is the correct behavior. However,
> occationally it will fail
> to return the stall pid. If I issue the IRP synchronously,
> IoCallDriver
> never returns. I would like to make the call asynchronously
> and then cancel
> the IRP if it times out. But if I call IoCancelIrp() I almost
> always get a
> BSOD in USBPORT.
>
> Question: Is there a way to cancel a request on a control endpoint?
>
> Thanks,
> J.
>
>
>
> —
> 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
>

Jimmy James wrote:

However, occationally it will fail to return the stall pid. If I issue the
IRP synchronously, IoCallDriver never returns. I would like to make
the call asynchronously and then cancel the IRP if it times out. But
if I call IoCancelIrp() I almost always get a BSOD in USBPORT.

I believe I’ve hit this issue as well, looking back in my files this is all I have written down:

DRIVER_IRQL_NOT_LESS_OR_EQUAL
*** STOP: 0x000000D1 (0x00000003 0x00000002 0x00000000 0xF807BE84)
*** USBPORT.SYS - Address F807BE84 base at F8074000, DateStamp 41107d62

You may not be able to cancel the IRP successfully once the system gets into this state. I think your device is misbehaving, you’re not supposed to NAK a control request for more than some amount of time, I believe.

jjjames1 wrote:

I have a device that does not support string descriptors. When I issue a
USB_STRING_DESCRIPTOR_TYPE the device usually responds with a STALL PID –
which I believe is the correct behavior. However, occationally it will fail
to return the stall pid. If I issue the IRP synchronously, IoCallDriver
never returns. I would like to make the call asynchronously and then cancel
the IRP if it times out. But if I call IoCancelIrp() I almost always get a
BSOD in USBPORT.

Question: Is there a way to cancel a request on a control endpoint?

Why are you trying to read a string descriptor from a device that
doesn’t have one? Devices are NOT, in fact, required to support string
descriptors. But in that case, the string descriptor ID numbers in the
device descriptor must all be 0. In that case, your driver should never
try to read the strings.

So, the CORRECT solution is to fix your driver: if the string ID numbers
in the device descriptors are 0, don’t try to read them.


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

Well, that’s time to paraphrase Don. Could you tell us name of your
device/company so we can avoid it?

There are standard compliance tests for USB devices. Your device should
pass them and it should be your hw developers’ job to ensure it. I don’t
have a personal experience with it; it is our hw developers’ job and
they do it. What’d you do when your device needs to be used on some
different OS? Write a driver for every OS to fix the device bug?

Reset port IOCTL is rather “heavy”. It should be used to solve real and
rare hw errors as ESD. If you’re using it routinely, be prepared for
occasional BSOD at Vista. There is a bug even in SP1 when port reset IRP
is blocked forever and Vista BSODs when timeout expires.

BTW, take a look at _URB_CONTROL_TRANSFER_EX. I’ve never used it but it
could help, too.

Best regards,

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of jjjames1
Sent: Tuesday, February 19, 2008 1:08 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] USB: Cancelling a request on a control endpoint

Fix the device! Ya well that’s not going to happen. That
would make it a
problem for the hardware guys. Driver guys are the ones to
fix problems.

At any rate:

Thanks for your reply. URB_FUNCTION_ABORT_PIPE requires a handle to a
pipe – which we don’t have for a control endpoint. However
IOCTL_INTERNAL_USB_RESET_PORT does seem to be working.

Regards,
J

“Michal Vodicka” wrote in message
> news:xxxxx@ntdev…
> Isn’t it better to fix the device? It isn’t USB compliant if behaves
> like this.
>
> I’m not sure if you can use URB_FUNCTION_ABORT_PIPE for
> control pipe. If
> so, it cancels all outstanding requests. If it can’t be used, you can
> try to reset parent port: IOCTL_INTERNAL_USB_RESET_PORT. Maybe you’ll
> need to do it anyway to restore from this state.
>
> Best regards,
>
> Michal Vodicka
> UPEK, Inc.
> [xxxxx@upek.com, http://www.upek.com]
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com] On Behalf Of jjjames1
> > Sent: Tuesday, February 19, 2008 12:25 AM
> > To: Windows System Software Devs Interest List
> > Subject: [ntdev] USB: Cancelling a request on a control endpoint
> >
> > Guys,
> >
> > I have a device that does not support string descriptors.
> > When I issue a
> > USB_STRING_DESCRIPTOR_TYPE the device usually responds with a
> > STALL PID –
> > which I believe is the correct behavior. However,
> > occationally it will fail
> > to return the stall pid. If I issue the IRP synchronously,
> > IoCallDriver
> > never returns. I would like to make the call asynchronously
> > and then cancel
> > the IRP if it times out. But if I call IoCancelIrp() I almost
> > always get a
> > BSOD in USBPORT.
> >
> > Question: Is there a way to cancel a request on a control endpoint?
> >
> > Thanks,
> > J.
> >
> >
> >
> > —
> > 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
> >
>
>
>
> —
> 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
>

No the device is suppose to reply with a stall condition. The point of the
test is to verify that the device is behaving properly.

“Tim Roberts” wrote in message news:xxxxx@ntdev…
> jjjames1 wrote:
>> I have a device that does not support string descriptors. When I issue a
>> USB_STRING_DESCRIPTOR_TYPE the device usually responds with a STALL
>> PID – which I believe is the correct behavior. However, occationally it
>> will fail to return the stall pid. If I issue the IRP synchronously,
>> IoCallDriver never returns. I would like to make the call asynchronously
>> and then cancel the IRP if it times out. But if I call IoCancelIrp() I
>> almost always get a BSOD in USBPORT.
>>
>> Question: Is there a way to cancel a request on a control endpoint?
>>
>
> Why are you trying to read a string descriptor from a device that doesn’t
> have one? Devices are NOT, in fact, required to support string
> descriptors. But in that case, the string descriptor ID numbers in the
> device descriptor must all be 0. In that case, your driver should never
> try to read the strings.
>
> So, the CORRECT solution is to fix your driver: if the string ID numbers
> in the device descriptors are 0, don’t try to read them.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>

Michal Vodicka wrote:

There are standard compliance tests for USB devices. Your device
should pass them and it should be your hw developers’ job to
ensure it. I don’t have a personal experience with it; it is our hw
developers’ job and they do it. What’d you do when your device
needs to be used on some different OS? Write a driver for every
OS to fix the device bug?

While I don’t disagree with you, I sympathize with Jimmy James’ plight. In my last job (at a “well known” consumer electronics company), the PC tools team existed largely to work around device bugs, both at the user/application level and driver level.

The device could never be touched, either because millions of defective units were already shipped to the field, or because the device’s vice presidents had more sway than ours.

The pinnacle of achievement here was when I discovered that in one case, despite a device actually running Linux itself, it would not enumerate in mass storage mode while connected to a Linux host PC. I immediately reported my findings, but apparently, judging by a quick Google search (I’ve since left), management chose to ship the device anyway.

So, that’s what Jimmy and I are up against…

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Tuesday, February 19, 2008 1:57 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] USB: Cancelling a request on a control endpoint

So, that’s what Jimmy and I are up against…

I understand you both. My point is one should at least try. If not for
anything (as or the sake of correctness and similar nonsense) one should
fight with hw department to save himself. Because once broken hw is
manufactured, who will have to make all the workarounds at all possible
platforms?

Best regards,

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

Michal Vodicka wrote:

Well, that’s time to paraphrase Don. Could you tell us name of your
device/company so we can avoid it?

There are standard compliance tests for USB devices. Your device should
pass them and it should be your hw developers’ job to ensure it.

Are you clear that his device IS compliant? USB devices are NOT
required to support string descriptors.

From section 9.5 of the USB 2.0 specification:

Where appropriate, descriptors contain references to string
descriptors that provide displayable information describing a
descriptor in human-readable form. The inclusion of string
descriptors is optional. However, the reference fields within
descriptors are mandatory. If a device does not support string
descriptors, string reference fields must be reset to zero to
indicate no string descriptor is available


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

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, February 19, 2008 2:21 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] USB: Cancelling a request on a control endpoint

Michal Vodicka wrote:
> Well, that’s time to paraphrase Don. Could you tell us name of your
> device/company so we can avoid it?
>
> There are standard compliance tests for USB devices. Your
device should
> pass them and it should be your hw developers’ job to ensure it.

Are you clear that his device IS compliant? USB devices are NOT
required to support string descriptors.

From section 9.5 of the USB 2.0 specification:

Where appropriate, descriptors contain references to string
descriptors that provide displayable information describing a
descriptor in human-readable form. The inclusion of string
descriptors is optional. However, the reference fields within
descriptors are mandatory. If a device does not support string
descriptors, string reference fields must be reset to zero to
indicate no string descriptor is available

We haven’t seen his device descriptors so we can only guess. I vote for
NON compliant device as I believe it should at least behave consistently
and it doesn’t. How exactly it should react to unsupported string
descriptor request (STALL seems correctly) I haven’t verified. Don’t
know about you but I don’t remember whole USB specification :wink:

Best regards,

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

> Are you clear that his device IS compliant? USB devices are NOT

required to support string descriptors.

From section 9.5 of the USB 2.0 specification:

Where appropriate, descriptors contain references to string
descriptors that provide displayable information describing a
descriptor in human-readable form. The inclusion of string
descriptors is optional. However, the reference fields within
descriptors are mandatory. If a device does not support string
descriptors, string reference fields must be reset to zero to
indicate no string descriptor is available

I’m not sure if I understand your point accurately. It your point is that it a USB device is not required to implement string descriptors, that is correct.

If you point was trying to suggest that the specified device behavior is undefined if a device does not implement string descriptors and the device receives a Get String Descriptor request, or if the device does implement string descriptors and receives a Get String Descriptor request with a string index that it does not implement, that is not correct. That would fall into the category of a Request Error. A device that gets hopelessly lost in space in either of these cases instead of cleanly returning a STALL PID is a broken non-compliant device.

Universal Serial Bus Specification Revision 2.0
9.2.7 Request Error

“When a request is received by a device that is not defined for the
device, is inappropriate for the current setting of the device, or has
values that are not compatible with the request, then a Request Error
exists. The device deals with the Request Error by returning a STALL
PID in response to the next Data stage transaction or in the Status
stage of the message. It is preferred that the STALL PID be returned
at the next Data stage transaction, as this avoids unnecessary bus
activity.”

jjjames1 wrote:

I have a device that does not support string descriptors. When I issue a
USB_STRING_DESCRIPTOR_TYPE the device usually responds with a STALL PID –
which I believe is the correct behavior.

If your device descriptors are set up correctly, there are no strings
advertised (string index != 0x00), and then at most two string
descriptors should be queried by any OS:

(a) String descriptor 0x00 (gets the supported language IDs).

(b) On Windows, the Microsoft-defined USB string descriptor 0xEE - see
http://msdn2.microsoft.com/en-us/library/ms790473.aspx -, which is
queried only on the very first connect of the device to a Windows (XP
and later) box. The descriptor content itself is AFAIK not documented.

So, for Windows, for these two string descriptors 0x00 and 0xEE, the
device absolutely must support stall if they are not defined.

If your device doesnt’t, you must have the device firmware fixed.
Don’t mess with the OS.

HTH -H

jjjames1 wrote:

No the device is suppose to reply with a stall condition. The point of the
test is to verify that the device is behaving properly.

Well, it does not always when it should. So you have successfully
verified that the device is broken. Good, now it can be fixed!
Or am I missing something here? :slight_smile: