USB on KMDF

I’ve tested speed of KMDF driver working with USB 2.0 device (Cypress). I’ve got maximum 8 MB/s.

Here’s testing code. It is modified osrusbfx2 sample. Am I missing something in the code? Or is wdf slower than WDM?

NTSTATUS
ConfigContReaderForInterruptEndPoint(PDEVICE_CONTEXT DeviceContext)
{
WDF_USB_CONTINUOUS_READER_CONFIG contReaderConfig;
NTSTATUS status;

WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&contReaderConfig,
EvtUsbInterruptPipeReadComplete,
DeviceContext, // Context
1024); // TransferLength

contReaderConfig.NumPendingReads = 255;

status = WdfUsbTargetPipeConfigContinuousReader(DeviceContext->InterruptPipe,
&contReaderConfig);

KdPrint((“Interrupt pipe has been configured\n”));
if (!NT_SUCCESS(status))
{
KdPrint((“OsrFxConfigContReaderForInterruptEndPoint failed %x\n”, status));
return status;
}
return status;
}

VOID
EvtUsbInterruptPipeReadComplete(WDFUSBPIPE Pipe,
WDFMEMORY Buffer,
size_t NumBytesTransferred,
WDFCONTEXT Context)
{
PUCHAR switchState = NULL;
WDFDEVICE device;
PDEVICE_CONTEXT pDeviceContext = (PDEVICE_CONTEXT)Context;
pDeviceContext->Count++;
if(pDeviceContext->Count == 10000)
{
KdPrint(("10 MB have beeen catched!));
pDeviceContext->Count = 0;
}

}

xxxxx@gmail.com wrote:

I’ve tested speed of KMDF driver working with USB 2.0 device (Cypress). I’ve got maximum 8 MB/s.

How is the endpoint configured? Unless you configured this as a
“high-bandwidth” device with multiple transactions per microframe, 8
MB/s is the maximum possible bandwidth on an interrupt pipe (1024 bytes
per microframe x 8 microframes per frame x 1000 frames per second).

You should try this with a bulk pipe. I’ll bet you max out closer to 30
MB/s.


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

You are only allowed 10 max readers, not 255 (and you don’t have to ask simultaneously on my blog and NTDEV). Have you tried a WDM driver? Perhaps 1024 bytes/transfer is not enough to saturate the bus. It also depends on if there are other devices on the bus as well consuming bandwidth.

In short, WDF can easily reach the max throughput on a usb device, we can even do it via winusb in a UM application, but you have to design how your read and the length of your i/o buffers properly

d

I would try all of these things:

  1. Use a bulk endpoint.

  2. Make sure the bulk endpoint’s maximum packet size is set to 512.

  3. Bump your read size to 4096 (or higher if you don’t need to support Win2k).

  4. For good measure, make sure your usermode app is submitting several reads at a time as well (unless this is a driver-only test).

OK. I’ve used bulk pipe and i’ve used big buffers in functions like WDF_USB_CONTINUOUS_READER_CONFIG_INIT and WdfUsbTargetPipeFormatRequestForRead. So i’ve got more than 30 Mb/s.
But what i need is to control size of packets(transfers) sent from device. I use the size to synchonize the stream. So if i use buffers, which consists of many packets, i don’t know which packet has needed size.

In WDM driver i can take control of each transfer and i have speed up to 10 MB/s with the same device. In WDF driver i can do this only at max speed of 4 MB/s.

By size of packet, I assume you mean the size of each transfer to/from the device and not the MaxPacketSize specified during select config/interface setting. If you want a variably sized buffer on each transfer, the continuous reader is not for you. The continuous reader design is that it always sends the same sized buffer on each transfer. You can easily implement your WDM behavior by manually formatting the request for the correct buffer size in your pipe read completion routine.

d