19 USB Driver Design Guidelines

There are several categories of USB drivers that cooperate to provide the USB driver stack in a platform. The table below lists these USB drivers.

Table 30-Classes of USB drivers
Class of driver Description
USB host controller driver Consumes PCI I/O Protocol on the USB host controller handle and produces the USB2 Host Controller Protocol.
USB bus driver Consumes the USB2 Host Controller Protocol and produces a child handle for each USB controller on the USB bus. Installs the Device Path Protocol and USB I/O Protocol onto each child handle.
USB device driver Consumes the USB I/O Protocol and produces an I/O abstraction that provides services for the console devices and boot devices required to boot an EFI-conformant operating system.

This chapter shows how to write host controller drivers and USB device drivers. USB drivers must follow all of the general design guidelines described in Chapter 4 of this guide. In addition, any USB host controllers that are PCI controllers must also follow the PCI-specific design guidelines (see Chapter 18).


Note: USB device drivers do not typically include HII functionality because they do not have configurable information. For example, USB device drivers are typically for hot-plug devices.


The figure below shows an example of a USB driver stack and the protocols the USB drivers consume and produce. Because the USB hub is a special kind of device that simply acts as a signal repeater, it is not included in Figure 21.

Figure 21-USB driver stack

In this example, the platform hardware provides a single USB host controller on the PCI bus. The PCI bus driver produces a handle with EFI_DEVICE_PATH_PROTOCOL and EFI_PCI_IO_PROTOCOL installed for this USB host controller. The USB host controller driver then consumes EFI_PCI_IO_PROTOCOL on that USB host controller device handle and installs the EFI_USB2_HC_PROTOCOL onto the same handle.

The USB bus driver consumes the services of EFI_USB2_HC_PROTOCOL. It uses these services to enumerate the USB bus. In this example, the USB bus driver detects a USB keyboard, a USB mouse, and a USB mass storage device. As a result, the USB bus driver creates three child handles and installs the EFI_DEVICE_PATH_PROTOCOL and EFI_USB_IO_PROTOCOL onto each of those handles.

The USB mouse driver consumes the EFI_USB_IO_PROTOCOL and produces the EFI_SIMPLE_POINTER_PROTOCOL. The USB keyboard driver consumes the EFI_USB_IO_PROTOCOL to produce the EFI_SIMPLE_TEXT_INPUT_PROTOCOL. The USB mass storage driver consumes the EFI_USB_IO_PROTOCOL to produce the EFI_USB_IO_PROTOCOL.

The protocol interfaces for the USB2 Host Controller Protocol and the USB I/O Protocol are shown below in the following two examples.

Example 202-USB 2 Host Controller Protocol
typedef struct _EFI_USB2_HC_PROTOCOL EFI_USB2_HC_PROTOCOL;
///
/// The EFI_USB2_HC_PROTOCOL provides USB host controller management, basic
/// data transactions over a USB bus, and USB root hub access. A device driver
/// that wishes to manage a USB bus in a system retrieves the EFI_USB2_HC_PROTOCOL
/// instance that is associated with the USB bus to be managed. A device handle
/// for a USB host controller minimally contains an EFI_DEVICE_PATH_PROTOCOL
/// instance, and an EFI_USB2_HC_PROTOCOL instance.
///
struct _EFI_USB2_HC_PROTOCOL {
  EFI_USB2_HC_PROTOCOL_GET_CAPABILITY             GetCapability;
  EFI_USB2_HC_PROTOCOL_RESET                      Reset;
  EFI_USB2_HC_PROTOCOL_GET_STATE                  GetState;
  EFI_USB2_HC_PROTOCOL_SET_STATE                  SetState;
  EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER           ControlTransfer;
  EFI_USB2_HC_PROTOCOL_BULK_TRANSFER              BulkTransfer;
  EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER   AsyncInterruptTransfer;
  EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER    SyncInterruptTransfer;
  EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER       IsochronousTransfer;
  EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER AsyncIsochronousTransfer;
  EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS    GetRootHubPortStatus;
  EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE   SetRootHubPortFeature;
  EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE ClearRootHubPortFeature;

  ///
  /// The major revision number of the USB host controller. The revision
  /// information indicates the release of the Universal Serial Bus Specification
  /// with which the host controller is compliant.
  ///
  UINT16                                          MajorRevision;

  ///
  /// The minor revision number of the USB host controller. The revision
  /// information indicates the release of the Universal Serial Bus Specification
  /// with which the host controller is compliant.
  ///
  UINT16                                          MinorRevision;
};
Example 203-USB I/O Protocol
typedef struct _EFI_USB_IO_PROTOCOL EFI_USB_IO_PROTOCOL;

///
/// The EFI_USB_IO_PROTOCOL provides four basic transfers types described
/// in the USB 1.1 Specification. These include control transfer, interrupt
/// transfer, bulk transfer and isochronous transfer. The EFI_USB_IO_PROTOCOL
/// also provides some basic USB device/controller management and configuration
/// interfaces. A USB device driver uses the services of this protocol to manage
/// USB devices.
///
struct _EFI_USB_IO_PROTOCOL {
  //
  // IO transfer
  //
  EFI_USB_IO_CONTROL_TRANSFER              UsbControlTransfer;
  EFI_USB_IO_BULK_TRANSFER                 UsbBulkTransfer;
  EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER      UsbAsyncInterruptTransfer;
  EFI_USB_IO_SYNC_INTERRUPT_TRANSFER       UsbSyncInterruptTransfer;
  EFI_USB_IO_ISOCHRONOUS_TRANSFER          UsbIsochronousTransfer;
  EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER    UsbAsyncIsochronousTransfer;

  //
  // Common device request
  //
  EFI_USB_IO_GET_DEVICE_DESCRIPTOR         UsbGetDeviceDescriptor;
  EFI_USB_IO_GET_CONFIG_DESCRIPTOR         UsbGetConfigDescriptor;
  EFI_USB_IO_GET_INTERFACE_DESCRIPTOR      UsbGetInterfaceDescriptor;
  EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR       UsbGetEndpointDescriptor;
  EFI_USB_IO_GET_STRING_DESCRIPTOR         UsbGetStringDescriptor;
  EFI_USB_IO_GET_SUPPORTED_LANGUAGE        UsbGetSupportedLanguages;

  //
  // Reset controller's parent port
  //
  EFI_USB_IO_PORT_RESET UsbPortReset;
};