This chapter has looked at the background to the Universal Serial Bus (USB). An understanding of the USB low-level frame structure helps when writing device drivers. The Windows USB system drivers read the standard descriptors in each USB device to determine which drivers to load.

The next chapter looks at how to write a device driver that can talk to USB devices through the Windows USB Device Interface (USBDI).

Chapter 21

USB Driver Interface

This chapter describes how to write a USB driver that uses the Windows USB Driver Interface (USBDI). The UsbKbd example driver talks to a USB keyboard and retrieves the raw keyboard input data. The corresponding Win32 test application displays this input data. In addition, you finally get the opportunity to flash some LEDs (the LEDs on keyboard).

A USB client is a device driver that uses the standard Windows system USB class drivers to talk to USB devices using USBDI. USBD.sys is the USB class driver. It uses either UHCD.sys to talk to Universal Host Controller Interface devices, or OpenHCI.sys for Open Host Controller Interface devices. USBHUB.sys is the USB driver for root hubs and external hubs. The relevant drivers are loaded when the PCI Enumerator finds each USB host controller.

Windows 2000 runs USBDI version 2.00, while Windows 98 uses version 1.01. There is no documentation on the differences. USBDI version 2.0 might return some Windows Management Instrumentation (WMI) data. Use the USBD_GetUSBDIVersion function to determine what version of the USB class drivers you are using. Only one very minor aspect of this chapter's driver is affected by the USBDI version.

As far as a USB client driver is concerned, the host computer (the Windows PC) talks directly to any function device that is plugged in. The details of bus enumeration and how information is transferred are not directly of concern to a USB client.

However, a client does need to be aware of the types of transfer, when they occur, and their timing, particularly in the case of isochronous transfers.

A client talks to a function device through one or more pipes. A pipe is a unidirectional or bidirectional channel for data transfer between the host and a device. A pipe may be one of four types. Control pipes transfer commands to the device (including USB set up and configuration information), with data transfer in either direction. Interrupt pipes transfer device-specific information to the host (e.g., when a keyboard key is pressed). Bulk pipes transfer larger amounts of data. Isochronous pipes carry time-sensitive data, such as voice.

Control endpoints are bidirectional. Interrupt endpoints are unidirectional into the host. Bulk and isochronous endpoints are unidirectional, in either direction.

The default pipe is used for control transfers. The USB specification defines several standard requests on the default pipe, such as 'get descriptor'. In addition, a device may respond to class-defined or vendor-defined requests on the default pipe.

Figure 21.1 shows the logical entities that a device and USBDI present to the client. A device exposes a series of connection points for pipes called endpoints. Endpoints may be grouped together to make an Interface. A configuration consists of one or more interfaces. A device usually contains just one configuration and one interface, but can contain more.

Figure 21.1 USB logical structure

Only one configuration is active at any one time, but all the interfaces and their endpoints within that configuration are active. Windows forces the selection of a configuration. As explained in the previous chapter, Windows forms a Hardware ID out of the USB Device descriptor, Vendor ID, and Product ID fields. This Hardware ID is used to try to find a matching device driver installation INF file. If there is no match, a Compatible ID is formed from the class fields in each interface descriptor in the selected configuration. These Compatible IDs are used to search for class-specific installation INF files; a device is created for each interface in the device.

USB Client Driver Design

A USB client driver is a standard WDM driver with Plug and Play support. As described in Chapters 11 and 20, the USB hub driver detects when a new USB device is inserted. The PnP Manager uses the vendor ID or device class information to select the driver to run. The driver's AddDevice routine is called and other PnP IRPs are issued as normal. Client USB drivers never receive any hardware resources, such ports or interrupts, as the USB class drivers handle all the low-level I/O.

USB devices are particularly prone to surprise removals, when the user accidentally (or deliberately) pulls out the USB plug. In Windows 2000, you will receive a Surprise Removal PnP IRP, while in Windows 98, only a Remove Device PnP IRP. These requests must succeed even if there are open handles to the device. Any transfers that are in progress must be aborted.

By definition, a USB client driver makes calls, at its lower edge, to the USB class drivers. However, it can implement whatever upper edge it deems necessary. The UsbKbd example driver in this chapter exposes a device interface that allows Win32 applications to read raw keyboard data and issue various IOCTLs. However, your driver could take a totally different approach, depending on what your USB device does.

The UsbKbd example driver is based on the Wdm2 driver, with Power Management support removed. The UsbKbd driver source code is in the book software UsbKbdSys directory. I suggest that you use UsbKbd as the basis for your USB client driver. Most of the USB handling routines are in the file Usb.cpp. You will need to alter the upper edge interface that is implemented in the dispatch routines in Dispatch.cpp.

A real USB client driver should support Power Management. An article on the Microsoft website at www.microsoft.com/hwdev entitled 'OnNow requirements in the USB Core Specification' discusses this issue.

Using UsbKbd

UsbKbd devices can be found by Win32 applications using the USBKBD_GUID device interface. When a handle to a UsbKbd device is opened, the UsbKbd driver starts talking to the USB peripheral. If the peripheral is a HID USB keyboard, its configuration is selected, thereby enabling the keyboard interrupt pipe. The UsbKbd Create IRP handler also obtains some more information from the device and the USB class drivers, displaying DebugPrint trace output in the checked build of the driver.

Closing the file handle deselects the keyboard's configuration.

The Win32 application can then use standard ReadFile calls to obtain raw keyboard data from UsbKbd. The raw data is in the form a HID keyboard input report, sent on a USB interrupt pipe. Chapter 22 details the format of this report precisely. All you need to know for now is that the first byte has all the modifier key bits (such as Shift, Control, etc.). The third and following bytes contain the HID keypress codes for all the keys that are currently pressed.

The time-out defaults to 10 seconds for ReadFile calls. One of the UsbKbd IOCTLs can be used to alter the time-out.

The UsbKbd driver also accepts WriteFile calls to change the state of the keyboard LEDs. The first byte of the WriteFile data is sent as a HID output report in a control transfer along the default pipe to Endpoint 0. The lower five bits of this byte are defined, though most keyboards just have three LEDs.

Table 21.1 shows the IOCTLs that UsbKbd supports. These functions are provided just to let you see how to exercise the USB interface. In most cases, you would not want to expose such IOCTLs for general use, although they might be useful for debugging purposes.

Table 21.1 UsbKbd IOCTLs

IOCTL_USBKBD_SET_READ_TIMEOUT Input ULONG Time-out in seconds Specifies the time-out for subsequent read requests
IOCTL_USBKBD_GET_DEVICE_DESCRIPTOR Output Received device descriptor Read the device descriptor.
IOCTL_USBKBD_GET_CONFIGURATION_DESCRIPTORS Output Received descriptors Read the first configuration descriptor, along with any associated, interface, endpoint, class and vendor descriptors.
IOCTL_USBKBD_GET_SPECIFIED_DESCRIPTOR Input
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×