WdfUsbTargetPipeReadSynchronously

Hello,

does anyone know what causes WdfUsbTargetPipeReadSynchronously to return
0xC0000001 (STATUS_UNSUCCESSFUL)?

I’m trying to read from a interrupt pipe, but it always returns that
error. Here is the code I’m using (error handling omitted):

PUCHAR outBufferC = NULL;

WdfRequestRetrieveOutputBuffer(Request, 15, &outBufferC, NULL);

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, outBufferC, 15);

status = WdfUsbTargetPipeReadSynchronously(pDevContext->InterruptPipe,
NULL,
NULL,
&memDesc,
(PULONG)&bytesReturned);

//-------------------------------------------------------

The pipe was configured like this:

UsbInterface=WdfUsbTargetDeviceGetInterface(pDeviceContext->UsbDevice,0);
pipe = WdfUsbInterfaceGetConfiguredPipe(UsbInterface, 0, NULL);

WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

pDeviceContext->UsbInterface = UsbInterface;
pDeviceContext->InterruptPipe = pipe;

//-------------------------------------------------------

One final note: the device is low-speed, so MaximumPacketSize was forced
to 8 (because endpoint descriptor was wrongly configured with 15, and I
have no access to the firmware).

Thanks for your help,

  • AS

Is the URB completion status USBD_STATUS_BUFFER_OVERRUN or USBD_STATUS_DATA_OVERRUN? (I don’t know how you access the URB status using the WdfUsb interface.)

Do you have access to a bus analyzer? Is the device returning a 15-byte packet across the bus?

If the low-speed device is returning a 15-byte packet across the bus and you do not have access to the device firmware to modify that behavior you will not be able to get that device to work on Windows Vista.

One final note: the device is low-speed, so MaximumPacketSize was forced
to 8 (because endpoint descriptor was wrongly configured with 15, and I
have no access to the firmware).

xxxxx@microsoft.com ha scritto:

Is the URB completion status USBD_STATUS_BUFFER_OVERRUN or USBD_STATUS_DATA_OVERRUN? (I don’t know how you access the URB status using the WdfUsb interface.)

Do you have access to a bus analyzer? Is the device returning a 15-byte packet across the bus?

If the low-speed device is returning a 15-byte packet across the bus and you do not have access to the device firmware to modify that behavior you will not be able to get that device to work on Windows Vista.

Hello,

I tried using a bus analyzer and this was the result:

http://www.labinf.polito.it/~s111729/trace.html

I don’t understand much of what is going on, but it’s clear that the URB
completion status was USBD_STATUS_BUFFER_OVERRUN.

Would anyone be so kind to explain why that happens?

Thank you very much in advance,

  • AS

Alessandro Sardo wrote:

I tried using a bus analyzer and this was the result:

You are using a software bus analyzer, which isn’t the same thing, but
even this shows the issue.

http://www.labinf.polito.it/~s111729/trace.html
I don’t understand much of what is going on, but it’s clear that the
URB completion status was USBD_STATUS_BUFFER_OVERRUN.

Would anyone be so kind to explain why that happens?

Yes, and I’m not sure why this isn’t clear to you already. Your device
violates the USB specification, by saying that it supports 15 byte
packets in an interrupt pipe for a low-speed device. The host
controller driver still has the raw descriptor, so it still thinks your
device has 15 byte packets. You set the “ignore the max packet size”
bit, so your request (which was for 15 bytes) gets sent down the stack
as-is. In response to the read request, your device then tries to
return 15 bytes. That is an invalid bus transaction for a low-speed device.

You must change the firmware either to deal in packets of 8 bytes, or to
make it a full-speed device, where 15-byte interrupt packets are legal.

What device is this?


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

Did you really know that off the top of your head?

Heck, *I* didn’t know until Vista was about to RTM that Full Speed interrupt packets weren’t allowed to be 512 bytes long :wink:

Peter
OSR

> You must change the firmware either to deal in packets of 8 bytes, or to

make it a full-speed device, where 15-byte interrupt packets are legal.

What device is this?

Hello,

thanks very much for your explanation. The device is an eletro-medical
vertical controller.

Unfortunately, the firmware is closed and I have no way to change it (I
don’t produce this thing, I was just asked to write a driver for Vista).

So, I assume there is no way to get a >8 byte interrupt transfer without
changing the firmware, right?

Thanks,

  • AS

Tim said:

Yes, and I’m not sure why this isn’t clear to you already. Your
device violates the USB specification, by saying that it supports 15
byte packets in an interrupt pipe for a low-speed device. The host
controller driver still has the raw descriptor, so it still thinks
your device has 15 byte packets. You set the “ignore the max packet
size” bit, so your request (which was for 15 bytes) gets sent down the
stack as-is. In response to the read request, your device then tries
to return 15 bytes. That is an invalid bus transaction for a
low-speed device.

Minor correction: I’m fairly ignorant of USB support in KMDF and I don’t know what the “ignore the max packet size” bit (WdfUsbTargetPipeSetNoMaximumPacketSizeCheck?) does, but I do know that the USB stack in Vista would not be using the original Endpoint Descriptor in this case.

It would have to be using the modified Endpoint Descriptor with the modified wMaxPacketSize value of 8. Otherwise the URB_FUNCTION_SELECT_CONFIGURATION request would fail with USBD_STATUS_INVALID_PARAMETER.

So then the UHCI Transfer Descriptor Maximum Length field or the OHCI Endpoint Descriptor Maximum Packet Size field would be programmed with the value 8, and then the host controller would report a Babble Detected or Data Overrun error when the larger than expected packet is received from the device.

This happens to work on XP as the low-speed device wMaxPacketSize is not validated and the host controller gets programmed expecting a 15-byte Max Packet Size, which the host controller happily receives, even though it is a violation of the USB specification. There were some potential issues in allowing this behavior to continue in Vista so it is no longer allowed.

Alessandro Sardo wrote:

thanks very much for your explanation. The device is an eletro-medical
vertical controller.

Unfortunately, the firmware is closed and I have no way to change it
(I don’t produce this thing, I was just asked to write a driver for
Vista).

So, I assume there is no way to get a >8 byte interrupt transfer
without changing the firmware, right?

Right. The device has a design flaw. It is broken, and always has
been. It happens to work in XP, because XP was somewhat lax about
enforcing the standard. Vista is a lot more particular.


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

if you want to see the URB status, you need to a little more work. The SendSynchronously DDI does not expose it, but the async verison does. Here is what you do in very rough code

// create a WDFREQUEST or use a WDFQUEUE presented request
// if necessary, create a WDFMEMORY for the transfer buffer or use the WDFMEMORY from
// the WDFQUEUE presented request

WDF_REQUEST_SEND_OPTION options;
WDF_REQUEST_SEND_OPTION_INIT(&options, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
WDF_REQUEST_COMPLETION_PARAMS params;
WDF_REQUEST_COMPLETION_PARAMS_INIT(&params);

WdfUsbTargetPipeFormatRequestForRead(Pipe, request, memory, NULL)
WdfRequestSend(Pipe, request, &options);

// params are valid until the request is deleted/reformatted/completed
WdfRequestGetCompletionParams(request, &params);

params.Parameters.Usb.Completion->UsbdStatus <= the USBD status from the URB

// delete the request if you created it
// delete the memory if you created it

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Alessandro Sardo
Sent: Monday, January 28, 2008 2:08 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WdfUsbTargetPipeReadSynchronously

You must change the firmware either to deal in packets of 8 bytes, or to
make it a full-speed device, where 15-byte interrupt packets are legal.

What device is this?

Hello,

thanks very much for your explanation. The device is an eletro-medical
vertical controller.

Unfortunately, the firmware is closed and I have no way to change it (I
don’t produce this thing, I was just asked to write a driver for Vista).

So, I assume there is no way to get a >8 byte interrupt transfer without
changing the firmware, right?

Thanks,

  • AS

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

xxxxx@microsoft.com ha scritto:

It would have to be using the modified Endpoint Descriptor with the modified wMaxPacketSize value of 8. Otherwise the URB_FUNCTION_SELECT_CONFIGURATION request would fail with USBD_STATUS_INVALID_PARAMETER.

So then the UHCI Transfer Descriptor Maximum Length field or the OHCI Endpoint Descriptor Maximum Packet Size field would be programmed with the value 8, and then the host controller would report a Babble Detected or Data Overrun error when the larger than expected packet is received from the device.

Hello,

that’s exactly what I did. I forced both the endpoint descriptor’s
wMaxPacketSize and the pipe’s MaximumPacketSize to 8. Without that, the
URB_FUNCTION_SELECT_CONFIGURATION request failed.

Now any call to WdfUsbTargetPipeReadSynchronously returns
STATUS_UNSUCCESSFUL with USBD_STATUS_BUFFER_OVERRUN, even if I set a
buffer equal to 8.

Thanks,

  • AS

Alessandro Sardo wrote:

xxxxx@microsoft.com ha scritto:
> It would have to be using the modified Endpoint Descriptor with the
> modified wMaxPacketSize value of 8. Otherwise the
> URB_FUNCTION_SELECT_CONFIGURATION request would fail with
> USBD_STATUS_INVALID_PARAMETER.
>
> So then the UHCI Transfer Descriptor Maximum Length field or the OHCI
> Endpoint Descriptor Maximum Packet Size field would be programmed
> with the value 8, and then the host controller would report a Babble
> Detected or Data Overrun error when the larger than expected packet
> is received from the device.

Hello,

that’s exactly what I did. I forced both the endpoint descriptor’s
wMaxPacketSize and the pipe’s MaximumPacketSize to 8. Without that,
the URB_FUNCTION_SELECT_CONFIGURATION request failed.

Now any call to WdfUsbTargetPipeReadSynchronously returns
STATUS_UNSUCCESSFUL with USBD_STATUS_BUFFER_OVERRUN, even if I set a
buffer equal to 8.

Everything you are doing here is only affecting data structures on the
host. The device is never told about these changes. It won’t know that
you tweaked wMaxPacketSize. Indeed, in USB the device is *never* told
how many bytes are being requested. All it knows is that there was a
read request. If the device is programmed to send 15 bytes for each
interrupt request, but the host controller is expecting 8, that will be
diagnosed as babble.

If that’s the case here, you *cannot* fix that from host software. You
have to fix the device.


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

Tim Roberts ha scritto:

Everything you are doing here is only affecting data structures on the
host. The device is never told about these changes. It won’t know that
you tweaked wMaxPacketSize. Indeed, in USB the device is *never* told
how many bytes are being requested. All it knows is that there was a
read request. If the device is programmed to send 15 bytes for each
interrupt request, but the host controller is expecting 8, that will be
diagnosed as babble.

If that’s the case here, you *cannot* fix that from host software. You
have to fix the device.

Hello,

I finally got it. Thank you again for your explanation, and pardon me
for my newbie questions (I started working on USB drivers only few days
ago) :slight_smile:

  • AS

Alessandro Sardo wrote:

Tim Roberts ha scritto:
> Everything you are doing here is only affecting data structures on
> the host. The device is never told about these changes. It won’t
> know that you tweaked wMaxPacketSize. Indeed, in USB the device is
> *never* told how many bytes are being requested. All it knows is
> that there was a read request. If the device is programmed to send
> 15 bytes for each interrupt request, but the host controller is
> expecting 8, that will be diagnosed as babble.
>
> If that’s the case here, you *cannot* fix that from host software.
> You have to fix the device.
>

Hello,

I finally got it. Thank you again for your explanation, and pardon me
for my newbie questions (I started working on USB drivers only few
days ago) :slight_smile:

Don’t feel too bad. This is a somewhat obscure condition that wouldn’t
be obvious unless you had been told about it.

When you start asking stupid questions, you’ll know it, because there
are many of us on this list who will be happy to tell you about it…


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

[USB device bug, works with XP, not with Vista]

Tim Roberts wrote:

If that’s the case here, you *cannot* fix that from host software. You
have to fix the device.

…hopefully no-one will say “But with Windows XP everything worked!”
and demand a working solution for Vista… :slight_smile: