Num Bytes transferred over USB Interrupt Pipe

> Interrupt and bulk read requests complete when (A) the whole transfer buffer is filled, or (B) the device sends back a packet shorter than the endpoint maximum.

To be pedantic, if your last packet size is endpoint max packet size and the transfer is finished, you need to send a subsequent zero length packet (ZLP) to satisfy the requirement that you send a packet shorter than the EP max.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, December 5, 2016 10:33 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Num Bytes transferred over USB Interrupt Pipe

xxxxx@gmail.com wrote:
> The issue that I am facing is that, NumBytesTransferred is always set to max TransferLength configured, i.e 2048. , even though the pipe is transferring only few bytes of data.
> I was expecting this value to be actual Number of Bytes transferred on the Pipe.

What is the endpoint’s max packet size? If, for example, your endpoint’s max packet size is 8 (which is not uncommon for an interrupt pipe), then as long as your device keeps sending packets of 8 bytes, your read request will not complete until all 2048 bytes have been read. Interrupt and bulk read requests complete when (A) the whole transfer buffer is filled, or (B) the device sends back a packet shorter than the endpoint maximum.

> Similar is the case when a control setup packet is transferred from
> Device to Host, using below APi?s {
> WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
> (PVOID)msg,//(PVOID)test,
>
> msg_size);
>
> status = WdfUsbTargetDeviceSendControlTransferSynchronously(
> DevContext->UsbDevice,
> WDF_NO_HANDLE, // Optional WDFREQUEST
> &sendOptions,
> &controlSetupPacket,
> &memDesc,
> &bytesTransferred);
>
> }
> bytesTransferred is always reported as the TransferLength configured on this pipe.

It is somewhat unusual to have a control transfer return a short packet, although it is allowed. I’m not sure what you mean by “TransferLength configured on this pipe”. The kernel will set the wLength field equal to the size of your memory descriptor, and that’s what you should get back. The bytesTransferred value is copied straight from the TransferBufferLength field of the URB, and that gets updated with the actual data length as read.


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


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Doron Holan wrote:

> Interrupt and bulk read requests complete when (A) the whole transfer buffer is filled, or (B) the device sends back a packet shorter than the endpoint maximum.
To be pedantic, if your last packet size is endpoint max packet size and the transfer is finished, you need to send a subsequent zero length packet (ZLP) to satisfy the requirement that you send a packet shorter than the EP max.

Well, the read request will still complete as soon as the buffer fills,
even without a ZLP. The ZLP is only necessary if the actual transfer is
smaller than the buffer AND happens to be an even multiple of the
endpoint size.


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

I havent configured explictly max packet size for endpoints. So the default value should be good.
The data returned in Continuous reader is 12 bytes, but the NumBytesTransferred is always set to 2048.

Since my interrupt pipe can read variable length data, how do i make sure, how much data to read from the buffer ?

Regards
Mukesh

ZLP should be sent from the device side, and i guess its sending it properly, as the same device is returning proper number of bytes in Completion parameter, when used with WinUSB API.

Issue is when i use UMDF 2.0 Native USB api’s continuous reader.

continuous readers are just a reader configured for Interrupt pipe, and should return the actual no of bytes available in Buffer, not the complete buffer length. Is my thinking correct ?

Thank you for being more specifically pedantic :slight_smile:

Get Outlook for Android


From: xxxxx@lists.osr.com on behalf of Tim Roberts
Sent: Monday, December 5, 2016 10:47:06 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Num Bytes transferred over USB Interrupt Pipe

Doron Holan wrote:
>> Interrupt and bulk read requests complete when (A) the whole transfer buffer is filled, or (B) the device sends back a packet shorter than the endpoint maximum.
> To be pedantic, if your last packet size is endpoint max packet size and the transfer is finished, you need to send a subsequent zero length packet (ZLP) to satisfy the requirement that you send a packet shorter than the EP max.

Well, the read request will still complete as soon as the buffer fills,
even without a ZLP. The ZLP is only necessary if the actual transfer is
smaller than the buffer AND happens to be an even multiple of the
endpoint size.


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


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

For an interrupt pipe, you should not be using WdfUsbTargetDeviceSendControlTransferSynchronously.

Use WdfUsbTargetDeviceSendUrbSynchronously.

xxxxx@gmail.com wrote:

I havent configured explictly max packet size for endpoints. So the default value should be good.

I’m not sure you get how this works. This is specified by the device.
The configuration descriptor from the device gives the max packet size
for every endpoint, in the same descriptor where it identifies bulk vs
interrupt vs isochronous. That’s also where the repeat rate for
interrupt pipes is specified. There is no “default”, and it’s not a
choice you make in the driver.

You can dump the configuration descriptor in your driver to find this,
or you can use usbview.

The data returned in Continuous reader is 12 bytes, but the NumBytesTransferred is always set to 2048.

Again, if the endpoint descriptor specifies the max packet size at 12
bytes, this is all as expected.

Since my interrupt pipe can read variable length data, how do i make sure, how much data to read from the buffer ?

This is all part of the USB convention. When the device sends a full
packet (that is, the endpoint’s maximum packet size), that is considered
to be one part of a larger “transfer”. The transfer is not completed
until the buffer fills, or a packet shorter than the maximum gets sent.

If you need to send responses of various sizes, then the max packet size
in the descriptor should be set to a large number. If the max packet
size is 512, for example, and the device sends a packet of 12 bytes,
that will end the current transfer. Your 2048-byte buffer will contain
12 bytes, and then you’ll have to submit another.


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

@Tim, Doron ,
Could you please help me or give any pointers to check the actual data length (and not the buffer length) in continuous reader ?

WdfUsbTargetDeviceSendUrbSynchronously is available only for KMDF driver.
I am following the windows sample driver umdf2_fx2, so believe we can use the WdfUsbTargetDeviceSendControlTransferSynchronously.

“If you need to send responses of various sizes, then the max packet size
in the descriptor should be set to a large number. If the max packet
size is 512, for example, and the device sends a packet of 12 bytes,
that will end the current transfer. Your 2048-byte buffer will contain
12 bytes, and then you’ll have to submit another.”

The buffer is having 12bytes data only, but the numofBytesreturned is set to 512, as per above example. How do i know in the continuous reader if the actual data is only 12 bytes or more or complete 512bytes is the actual data ? Buffer is all zeroed out, which can be a valid data. So how much buffer length i should access to read the actual data ? This is the reason i need actual NumBytesTransferred, to restrict my read to only those many bytes in buffer.

if you look to the osrusbfx2 interrupt code you will see this:

In the continuous reader configuration:

WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&contReaderConfig,
OsrFxEvtUsbInterruptPipeReadComplete,
DeviceContext, // Context
sizeof(UCHAR)); // TransferLength

And then in the OsrFxEvtUsbInterruptPipeReadComplete callback, you have:

assert(NumBytesTransferred == sizeof(UCHAR));

For you, the assertion would be:

assert(NumBytesTransferred == 2048);

https://github.com/Microsoft/Windows-driver-samples/blob/master/usb/umdf2_fx2/driver/interrupt.c

You want to call WdfUsbTargetPipeWriteSynchronously for sending a transfer on the interrupt pipe. The third parameter, NumBytesTransferred, indicates how many bytes were transferred (not the max buffer size)

Get Outlook for Android


From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Monday, December 5, 2016 11:46:25 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Num Bytes transferred over USB Interrupt Pipe

@Tim, Doron ,
Could you please help me or give any pointers to check the actual data length (and not the buffer length) in continuous reader ?

WdfUsbTargetDeviceSendUrbSynchronously is available only for KMDF driver.
I am following the windows sample driver umdf2_fx2, so believe we can use the WdfUsbTargetDeviceSendControlTransferSynchronously.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Sorry if i am not able to convey the message properly.

I cant use “assert(NumBytesTransferred == 2048);”, as this will always check for the NumBytesTransferred = 2048. My interrupt pipe can receive less value like 8 bytes, 12 bytes.
And thats perfectly ok for the driver. However i want that number of bytes to be reflected properly in NumBytesTransferred.

In WDF_USB_CONTINUOUS_READER_CONFIG_INIT, i configure the transferLength to be the Max data that i can receive on this Pipe, but need not always get the Max. If i receive a shorter packet, the actual size should be reflected in the NumBytesTransferred.

That is how the cont reader works. If it isn’t working this way your device isn’t doing the right thing on the USB wire

Get Outlook for Android


From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Monday, December 5, 2016 8:18:52 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Num Bytes transferred over USB Interrupt Pipe

Sorry if i am not able to convey the message properly.

I cant use “assert(NumBytesTransferred == 2048);”, as this will always check for the NumBytesTransferred = 2048. My interrupt pipe can receive less value like 8 bytes, 12 bytes.
And thats perfectly ok for the driver. However i want that number of bytes to be reflected properly in NumBytesTransferred.

In WDF_USB_CONTINUOUS_READER_CONFIG_INIT, i configure the transferLength to be the Max data that i can receive on this Pipe, but need not always get the Max. If i receive a shorter packet, the actual size should be reflected in the NumBytesTransferred.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

xxxxx@gmail.com wrote:

I cant use “assert(NumBytesTransferred == 2048);”, as this will always check for the NumBytesTransferred = 2048. My interrupt pipe can receive less value like 8 bytes, 12 bytes.
And thats perfectly ok for the driver. However i want that number of bytes to be reflected properly in NumBytesTransferred.

In WDF_USB_CONTINUOUS_READER_CONFIG_INIT, i configure the transferLength to be the Max data that i can receive on this Pipe, but need not always get the Max. If i receive a shorter packet, the actual size should be reflected in the NumBytesTransferred.

You still seem to be missing the point. You (the driver) do not get to
decide “the max data that I can receive on this pipe”. That piece of
information is specified by the device, in its descriptors. The fact
that you have STILL not showed us your descriptors leads me to suspect
that you don’t know what the endpoint’s maximum packet size is, and
without that piece of information, it is absolutely impossible to debug
your problem. The behavior will depend on the endpoint descriptor.


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

Hi Tim,
Please find the descriptor detail as follows :

Device Descriptor:
Length 18
DescriptorType 1 (DEVICE)
bcdUSB 0x200 (512)
DeviceClass 239
DeviceSubClass 2
DeviceProtocol 1
MaxPacketSize0 64
VendorId 0x5C6 (1478)
ProductId 0x9085 (36997)
bcdDevice 0x318 (792)
Manufacturer 1
Product 2
SerialNumber 3
NumConfigurations 1

Does it help ? let me know if you need any more info.

xxxxx@gmail.com wrote:

Hi Tim,
Please find the descriptor detail as follows :

Device Descriptor:
Length 18

Does it help ?

No. That’s the device descriptor. We need the configuration descriptor.

It seems to be a Qualcomm modem.


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

sorry… As i mentioned i am new to USb, so mixed it.
used WdfUsbTargetDeviceRetrieveConfigDescriptor to get configuration descriptor details :

bLength - 9
bDescriptorType - 2
wTotalLength - 25
bNumInterfaces - 1
bConfigurationValue - 1
iConfiguration - 0
bmAttributes - 160
MaxPower - 250

Regards
Mukesh

xxxxx@gmail.com wrote:

sorry… As i mentioned i am new to USb, so mixed it.
used WdfUsbTargetDeviceRetrieveConfigDescriptor to get configuration descriptor details :

bLength - 9
bDescriptorType - 2
wTotalLength - 25
bNumInterfaces - 1
bConfigurationValue - 1
iConfiguration - 0
bmAttributes - 160
MaxPower - 250

The configuration descriptor is variable length. After this header, it
contains the interface and endpoint descriptors. For this device, the
total descriptor is 25 bytes, which means you have this 9-byte header,
plus a 9-byte interface descriptor, plus a 7-byte endpoint descriptor.
We need all of that.


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

Hi Tim,

Please find the complete Detail.

Device Descriptor:
Length 18
DescriptorType 1 (DEVICE)
bcdUSB 0x200 (512)
DeviceClass 239
DeviceSubClass 2
DeviceProtocol 1
MaxPacketSize0 64
VendorId 0x5C6 (1478)
ProductId 0x9085 (36997)
bcdDevice 0x318 (792)
Manufacturer 1
Product 2
SerialNumber 3
NumConfigurations 1

Configuration Descriptor:

bLength - 9
bDescriptorType - 2
wTotalLength - 25
bNumInterfaces - 1
bConfigurationValue - 1
iConfiguration - 0
bmAttributes - 160
MaxPower - 250

Interface Descriptor:

bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 255
bInterfaceSubClass 255
bInterfaceProtocol 255
iInterface 0

Endpoint Descriptor :
Size 20
MaximumPacketSize 64
EndpointAddress 133
Interval 9
SettingIndex 0
PipeType WdfUsbPipeTypeInterrupt (4) _WDF_USB_PIPE_TYPE
MaximumTransferSize 2097152

Regards
Mukesh

Hi Tim,

Please find the USB trace log shared @https://drive.google.com/open?id=0B4kmJvERgfWZdUwwaldZTzFyV0U

Appreciate your kind help.

Thanks