Chapter 8 216 more about how to implement low-level communications, one source of infor- mation is the source code and other documentation from the Linux USB Project. *QUV%QPVTQNNGT6[RGU To access low- and full-speed devices, a USB 1.x or USB 2.0 host can use a con- troller that conforms to the Open Host Controller Interface (OHCI) standard or the Universal Host Controller Interface (UHCI) standard. To access high-speed devices, a USB 2.0 host uses a host controller that conforms to the Enhanced Host Controller Interface (EHCI) standard. USB 3.0 hosts use a sin- gle Extensible Host Controller Interface (xHCI) controller for all speeds. The USB-IF’s website has links to the specifications. For information about which host-controller types are in a PC, in Windows Device Manager, look under Universal Serial Bus controllers. To view a driver’s name, right-click a host controller’s entry and select Properties > Driver > Driver Details. One of the drivers listed should have ohci, uhci, or ehci in the name. Chapter 9 has more about the Device Manager. 1*%+CPF7*%+&KHHGTGPEGU OHCI and UHCI controllers both provide a way for the low- and full-speed USB hardware to communicate with higher-level drivers, but each takes a dif- ferent approach. UHCI places more of the communications burden on software and thus can use simpler, cheaper hardware. OHCI places more of the burden on the hardware and allows simpler software control. UHCI was developed by Intel, and OHCI was developed by Compaq, Microsoft, and National Semi- conductor. Motherboards tend to have UHCI controllers, and expansion cards tend to have OHCI controllers. The differences between host controllers should be transparent to driver devel- opers and application programmers. Both controller types comply fully with the USB specification. Their performance can differ, however. Developers shouldn’t assume a device works fine based on tests with one host-controller type. An OHCI controller can schedule more than one stage of a control transfer in a single frame, while a UHCI controller always schedules each stage in a different frame. For bulk endpoints with a maximum packet size less than 64 bytes, a UHCI driver attempts no more than one transaction per frame, while an OHCI driver may schedule additional transactions in a frame. An OHCI con- How the Host Communicates 217 troller will poll an interrupt endpoint at least once every 32 ms even if the end- point descriptor requests a maximum latency of 255 ms, while UHCI controllers can, but don’t have to, support less-frequent polling. Developers who use UHCI hosts are sometimes surprised when their devices fail when connected to an OHCI host. The failure occurs because the device isn’t expecting to see multiple stages of a control transfer in a frame. Every device should work with both controller types. 5WRRQTVKPI/WNVKRNG5RGGFU An EHCI controller handles high-speed communications only. The EHCI specification says that a host that supports EHCI must also support low and full speeds except for the unusual situation where every port has a permanently attached high-speed device. To support low and full speeds, the host must have a companion OHCI or UHCI host controller or a USB 2.0-compliant hub, which performs the function of a host controller for low- and full-speed devices. Just about every PC with an EHCI controller has a companion OHCI or UHCI controller that shares the bus. In general, users and application programmers don’t have to know or care which host controller is communicating with a device. To ensure the best per- formance, Windows warns if the system has high-speed-capable ports and a user attaches a high-speed-capable device to a port that doesn’t support high speed. 9TKVKPI&TKXGTU To support vendor-specific functions, a device can use a vendor-specific ker- nel-mode driver or a vendor-specific user-mode driver that communicates with a kernel-mode driver provided by the operating system or a vendor. Writing drivers has long been an arcane and difficult art. To help ease the pro- cess, Microsoft provides the Windows Driver Foundation (WDF) framework for WDM drivers. When developing a WDF driver, you start with a function- ing driver that provides default processing for PnP, power-management, and device I/O events. To support device-specific behavior, you add code that over- rides the default processing. The framework hides much of the driver’s com- plexity and results in a more stable product. This section will help you decide whether you need a device-specific driver and if so, how to get started. For a detailed guide to driver writing, see the WDK Chapter 8 218 documentation and examples and the book Developing Drivers with the Win- dows Driver Foundation by Penny Orwick and Guy Smith (Microsoft Press). -GTPGNOQFG&TKXGTU Writing a kernel-mode client driver requires the WDK, which includes a C compiler, a linker, build utilities, and documentation including example source code. Kernel-mode drivers for Windows 2000 and later can use the Kernel-Mode Driver Framework (KMDF) library included in the WDK for Windows Vista and later. The KMDF isolates the driver code from the details of creating and passing IRPs and managing PnP and power functions. A KMDF driver creates a framework driver object to represent the driver and a framework device object for each device. Instead of creating and passing IRPs, KMDF drivers perform driver functions via properties, methods, and events of the framework device objects. Instead of handling PnP and power management directly, the framework manages these functions with callback functions pro- viding event notifications as needed. The framework defines additional object types to represent resources that driv- ers can use. USB communications use objects that represent USB devices, inter- faces, and pipes. Other framework objects can represent files, timers, strings, and other resources. 7UGTOQFG&TKXGTU User-mode drivers for Windows XP and Windows Vista can use the User-Mode Driver Framework (UMDF) library included in the WDK for Windows Vista and later. UMDF drivers communicate via the Windows API instead of kernel-mode functions. Developers of UMDF drivers can program in C++ and debug with user-mode debuggers. An example of an application that might use a UMDF driver is a device that uses the WinUSB kernel-mode driver but needs to support multiple open han- dles to a device interface. The user-mode WinUSB driver component limits interfaces to one open handle at a time, while a vendor-provided UMDF driver can allow multiple open handles. 6GUVKPI6QQNU The WDK’s Device Simulation Framework (DSF) can help with driver testing. The framework can simulate an EHCI host controller and devices in software. How the Host Communicates 219 Instead of having to attach a physical device to a physical bus for testing, you can use a simulated host controller and device. 7UKPI)7+&U A Globally Unique Identifier (GUID) is a 128-bit value that uniquely identifies a class or other entity. Windows uses GUIDs in identifying two types of device classes. A device setup GUID identifies a device setup class, which encompasses devices that Windows installs in the same way. A device interface GUID identi- fies a device interface class, which provides a mechanism for applications to communicate with a driver assigned to devices in the class. In many cases, devices that belong to a particular device setup class also belong to the same device interface class. Some SetupDi_ API functions accept either type of GUID. But each type of GUID provides access to different types of informa- tion used for different purposes. The conventional format divides the GUID into five sets of hex characters with the sets separated by hyphens. This is the GUID for the HIDCLASS device setup class: 745a17a0-74d3-11d0-b6fe-00a0c90f57da This is the GUID for the HID device interface class: 4d1e55b2-f16f-11cf-88cb-001111000030 Driver writers and others who need to provide a custom GUID can generate one using the guidgen utility provided with Visual Studio and also available as a free download from Microsoft. The utility uses an algorithm that makes it extremely unlikely that someone else will create an identical GUID. To create a GUID in Visual Studio Professional edition or better, select Tools > Create GUID. &GXKEG5GVWR)7+&U A device setup GUID identifies devices that Windows sets up and configures in the same way and using the same class installer and co-installers. The system file devguid.h defines device setup GUIDs for many classes. The WDK provides the file. Most devices should use a device setup class that corresponds to the device’s function, such as printer or disk drive. A single device can belong to multiple setup classes, such as HID and mouse. The USB class is appropriate for USB hosts and hubs and other devices whose installation and configuration require- Chapter 8 220 ments or capabilities don’t fit another class. A vendor-specific class is another option for such devices, but Microsoft discourages creating vendor-specific classes. Each device setup GUID corresponds to a Class key in the system registry. Each Class key has a subkey for each instance of a device in the class. Chapter 9 has more about Class keys. Applications can use device setup GUIDs to retrieve information and perform various installation functions on devices. The devcon example in the WDK shows how to use device setup GUIDs to detect and retrieve information about devices and perform functions such as enabling, disabling, restarting, updating drivers for, and removing devices. These functions are the same as those per- formed by the Device Manager. &GXKEG+PVGTHCEG)7+&U A class or device driver can register one or more device interface classes to enable applications to learn about and communicate with devices that use the driver. Each device interface class has a device interface GUID. Using a device interface GUID and SetupDi_ functions, an application can find all attached devices in a device interface class. On detecting a device, the application can obtain a device path name to pass to the CreateFile function. CreateFile returns a handle that the application can use to access the device. Applications can also use device interface GUIDs to request to be notified when a device is attached or removed. Chapter 10 has more about using GUIDs for this purpose. Unlike device setup GUIDs, device interface GUIDs aren’t stored in one file. A driver package may include a C header file or a Visual Basic or a Visual C# vari- able or constant that defines a device interface GUID. An application that uses the WinUSB driver can define a GUID for accessing a specific device. For the HID class, applications can retrieve the GUID with the function HidD_GetHidGuid. Device interface GUIDs are useful for finding devices that use the WinUSB driver, devices with vendor-specific drivers, and HID-class devices that perform vendor-specific functions. For many other devices that perform standard peripheral functions, applica- tions have other ways to find and gain access to devices. For example, to access a drive, the .NET Framework’s Directory class includes a GetLogicalDrives method that enables applications to find all of the logical drives on a system How the Host Communicates 221 (whether or not they use USB). A vendor-specific driver can also define an API to enable applications to access devices without having to provide a GUID. Some older drivers define a symbolic link for each device they control. For example, the first device attached might be \\.\mydevice0, followed by \\.\mydevice1, \\.\mydevice2, and so on up as needed. Applications access these devices using the symbolic links instead of device interface GUIDs. 223 /CVEJKPIC&TKXGTVQC &GXKEG On detecting a newly attached USB device, the operating system needs to decide what driver to assign to the device. This chapter shows how Windows uses INF files to select a driver and how the Device Manager and system regis- try store information about devices and their drivers. The information in this chapter applies to Windows XP through Windows Vista with some comments on earlier Windows editions. 7UKPIVJG&GXKEG/CPCIGT The Windows Device Manager displays information about all installed devices and presents a user interface for enabling, disabling, and uninstalling devices and updating or changing a device’s assigned driver. For developers, the Device Manager is useful for viewing the driver assigned to a device and for providing a user interface for making Window forget what it knows about a device and start fresh. Chapter 9 224 8KGYKPI&GXKEGU To view the Device Manager, right-click Computer, click Manage, and in the Computer Management pane, select Device Manager. Or from Start, select Set- tings > Control Panel > System > Hardware > Device Manager. Or save clicks by creating a shortcut to the file devmgmt.msc in Windows\System32. The Device Manager’s View menu offers options for viewing device informa- tion. Viewing devices by connection (Figure 9-1) shows the physical connec- tions from each host controller and root hub, through any additional hubs, to the attached devices. To view information about a device, including its driver(s) and any problem the operating system has detected with the device, right-click the device’s listing and select Properties (Figure 9-2). Viewing devices by type (Figure 9-3) groups devices according to their func- tions with little regard to hardware interface. The USB class lists host control- lers and hubs. A device with a vendor-specific driver can define its own class or use the USB class. Figure 9-1. Viewing devices by connection in the Device Manager shows which devices connect to which hubs and host controllers. Matching a Driver to a Device 225 By default, the Device Manager shows only attached USB devices. To view devices that have been removed but whose drivers are still installed, set the fol- lowing system environment variable: DEVMGR_SHOW_NONPRESENT_DEVICES=1 To set the variable, in the Windows Control Panel, select System > Advanced > Environment Variables, enter the variable’s name, and set its value. Then in Device Manager, click View and check the option to Show Hidden Devices. You may need to reboot after setting the environment variable. 2TQRGTV[2CIGU Each listing in the Device Manager has property pages that provide additional information about a device and an interface for configuring the device and its driver. To view the property pages, double-click the device’s entry. You can request to enable or disable the device or view, update, roll back, or uninstall the device’s driver. A Details page provides additional information, including Figure 9-2. Device Manager’s Properties screens provide more information about a device, including what driver the operating system has assigned to the device. . infor- mation is the source code and other documentation from the Linux USB Project. *QUV%QPVTQNNGT6[RGU To access low- and full-speed devices, a USB 1.x or USB 2.0 host can use a con- troller that. standard. To access high-speed devices, a USB 2.0 host uses a host controller that conforms to the Enhanced Host Controller Interface (EHCI) standard. USB 3.0 hosts use a sin- gle Extensible Host. defines additional object types to represent resources that driv- ers can use. USB communications use objects that represent USB devices, inter- faces, and pipes. Other framework objects can represent