Hi, this is Qiang Qiu again from USB core test team. Last week, I wrote about how to get started with USB driver development and gave an overview of highly used samples in the WDK. In this article, I'm going to list out the features side-by-side of two most important KMDF based USB samples, namely USBSAMP and OSRUSBFX2. My hope is that this will enable you to decide which sample to follow as a reference for your driver development.  I have listed couple of frequently asked questions about these samples at the end of this article.

Features

USBSAMP Sample

OSRUSBFX2 Sample

Test Board Hardware

Intel 82930 USB Test Board

Vendor ID: 0x045E

Product ID: 0x930A


(Note: OSR USB-Fx2 Learning Kit can also be used for USBSAMP driver just to do the loop read and write operations )

OSR USB-FX2 Learning Kit

Vendor ID: 0x0547

Product ID: 0x1002

Test Board Configuration

The board supports a single configuration and can operate at high-speed and full-speed mode. It implements one interface.  Two endpoints can be configured as internal loopback function for bulk transfer. Two endpoints can be configured as an internal loopback function to perform isochronous transfer.

The board supports a single configuration and can operate at high-speed and full-speed mode. It implements Interface 0 with three endpoints (Interrupt IN - Endpoint 1, Bulk Out - Endpoint 6, Bulk IN - Endpoint 8).

Endpoint 1 is used to indicate the state of the 8-switch pack on the OSR USB-FX2 board. Endpoints 6 and 8 perform an internal loop-back function. Data which is sent to EP6 and returned to EP8.

(Note: The bulk endpoints are DOUBLE buffered. Read data will not complete if the buffers are empty. If buffers are full, write data will not complete until the buffers are emptied.)

Support Control Transfer

Yes

Yes

Support Bulk Transfer

Yes

Yes

Support Interrupt Transfer

No

Yes

Support Isochronous Transfer

Yes

No

Support for wait-wake and Selective Suspend

Yes, Test Board will enter suspend after 10 seconds idle.

Yes, Test Board will enter suspend after 10 seconds idle.

Support additional IOCTL

IOCTL_USBSAMP_RESET_PIPE
IOCTL_USBSAMP_GET_CONFIG_DESCRIPTOR
IOCTL_USBSAMP_RESET_DEVICE

IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR
IOCTL_OSRUSBFX2_RESET_DEVICE IOCTL_OSRUSBFX2_REENUMERATE_DEVICE
IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY
IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY
IOCTL_OSRUSBFX2_READ_SWITCHES
IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY
IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY
IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE

Support ETW Events

No

Yes, the sample driver package includes an osrusbfx2.man file which describes events that added: Failure during the add device routine; Failure to start the OSF device on a USB 1.1 controller; Invocation of the "re-enumerate device" IOCTL. There are also read/write start/stop events that can be used to measure the time taken.

Support vendor command

No

The firmware on the test board supports vendor commands to query or set LED Bar graph display, 7-segment LED display, and query toggle switch states.

Console Application

The Usbsamp.exe console application is used to initiate read and write bulk/isoch transfers, send ioctl requests, and obtain a dump of information on the device's endpoints.

The Osrusbfx2.exe console application is used to initiate read and write to bulk endpoints, play with 7 segment display, toggle switches and bar graph display, reset and re-enumerate the device and dump descriptors.

Testing with console application

Usage for usbsamp.exe:

-r [n] where n is number of bytes to read
-w [n] where n is number of bytes to write
-c [n] where n is number of iterations (default = 1)
-i [s] where s is the input pipe
-o [s] where s is the output pipe
-v verbose -- dumps read data
-u to dump USB configuration and pipe info

One interesting feature of this sample is that it enables the application to pick the pipes it wants to use for I/O operations.  For example,

Usbsamp.exe -w 1024 -o pipe03 -r 1024 -i pipe02 <- This command first writes 1024 bytes of data to pipe3 and  reads 1024 bytes of data from pipe02.

If you don't specify the pipe name, the application uses default input pipe name as "PIPE00" and out pipe name as "PIPE01". Pipe name is appended to the device-path when the application opens a handle to the device. The driver receives this string as fileobject name in the create callback. It then parses out the pipe number, finds the corresponding pipe-handle and saves it in the fileobject context to be used during I/O.

Usage for osrusbfx2.exe:

-r [n] where n is number of bytes to read
-w [n] where n is number of bytes to write
-c [n] where n is number of iterations (default = 1)
-v verbose -- dumps read data
-p to control bar LEDs, seven segment, and dip switch
-a to perform asynchronous I/O
-u to dump USB configuration and pipe info

-Osrusbfx2.exe -p option 1-11 allows to set and clear bar graph display, set and get seven segment state, read the toggle switch states, reset and reenumerate the device:

 1- Light Bar
2- Clear Bar
3- Light entire Bar graph
4- Clear entire Bar graph
5- Get bar graph state
6- Get Switch state
7- Get Switch Interrupt Message
8- Get 7 segment state
9- Set 7 segment state
10- Reset the device
11- Reenumerate the device

Windows Support

Windows 2000 and later

Windows 2000 and later

 

FAQ: 

Question: What is Maximum Transfer Size of USBSAMP and OSRUSBFX2 sample driver? Is it possible to change their sizes?

Answer: Technically, from the device point of view, you could submit reads of any size. For writes, you can also submit larger as long as the reads are submitted before the writes complete, otherwise the writes will block as device NAKs when its buffer is full.

The maximum transfer size of USBSAMP is set by 65536 because it was originally designed with the i82930 test board's which is limited by a 64KB circular buffer. You can change the size of "MaximumTransferSize" for your device in usbsamp.inf as below and rebuild your driver package.

[usbsamp.AddReg]

HKR,"Parameters","MaximumTransferSize",0x10001,65536

The maximum transfer size of OSRUSBFX2 is also 65536 (64*1024). It is set in the file orusbfx2.h:

#define TEST_BOARD_TRANSFER_BUFFER_SIZE (64*1024)

You can change this value as you expected.

Question: What I/O types are supported in USBSAMP? How do I change the I/O types? Is bulk and isochronous transfer supported in both direct and buffered I/O types in this sample?

Answer: There is a compile switch "-DBUFFERED_READ_WRITE = 1" for buffered I/O in USBSAMP's build source file as below:

C_DEFINES= $(C_DEFINES)

#-DBUFFERED_READ_WRITE=1

It is commented out so that USBSAMP is doing direct I/O for Reads and Writes by default. Developer can uncomment this switch to do buffered I/O for Reads and Writes.

Please NOTE that USBSAMP can do isochronous transfer only if the I/O type is set as direct I/O in this sample.