Windows USB Device Communication: The Driver Stack and I/O Path

Driver Stack Initialization

The Windows USB subsystem is a layered architecture involving the Plug and Play (PnP) manager, bus drivers, function drivers, hub drivers, and host controller drivers. The initialization proceeds bottom-up.

Host Controller Discovery

During system boot, the PnP manager coordinates bus enumeration. The PCI bus driver identifies USB host controller hardware, such as an xHCI controller. A Physical Device Object (PDO) is created for this hardware, representing its identity in the system and containing device identification and resource requirements.

Host Controller Function Driver Loading

The PnP manager uses the PDO's hardware ID to locate and load the appropriate driver. For a USB 3.x controller, this is typically the xHCI host controller driver. This driver attaches to the PDO and creates a Functional Device Object (FDO), which implements the logic to operate the device.

The initial driver stack forms as follows:

[FDO: xHCI Host Controller Driver]
    |
[PDO: Host Controller Hardware Representation]
    |
[Physical USB Controller]

Root Hub Enumeration

After initializing the host controller, the system enumerates the integrated Root Hub. The host controller driver creates a new PDO for the Root Hub and reports it to the PnP manager. The generic USB Hub driver is then loaded, forming the Root Hub's stack.

Stack representation:

[FDO: USB Hub Driver]
    |
[PDO: Root Hub]
    |
[FDO: Host Controller Driver]
    |
[PDO: Host Controller Hardware]
    |
[Physical USB Controller]

External Device Connection

When a device is connected, the hub driver detects the port status change and initiates a similar stack-building process:

  1. Hub driver detects port activity.
  2. Creates a PDO for the new device.
  3. PnP manager queries device identifiers.
  4. Matches and loads the appropriate function driver.
  5. Function driver creates an FDO.
  6. Device becomes operational.

Core System Components

Plug and Play Manager

Manages the device lifecycle, encluding discovery, identification, driver matching, resource allocation, and handling of plug-and-play events. Correct driver matching depends on the PnP manager's ability to find a driver for the device's descriptors.

Physical Device Object (PDO)

Created by a bus driver to represent a physical device found on the bus. For USB, the hub driver creates a PDO upon device detection. It provides device identity information like device ID, hardware IDs, and compatible IDs.

Functional Device Object (FDO)

Created by a function driver to implement device functionality. Examples include storage class drivers for mass storage, HID class drivers for input devices, and video class drivers for cameras. The FDO processes I/O requests from higher layers and translates them into low-level operations.

Device Descriptors

Provide fundamental identification data for a USB device. Key fields include:

  • idVendor: Manufacturer identifier.
  • idProduct: Product identifier.
  • bcdDevice: Device version.
  • bDeviceClass: Device class code.
  • bDeviceSubClass: Device subclass code.
  • bDeviceProtocol: Protocol code.

These values are used by Windows for driver matching.

Configuration, Interface, and Endpoint Descriptors

Provide detailed device capabilities beyond the basic device descriptor.

  • Configuration Descriptor: Defines power requirements and the number of interfaces.
  • Interface Descriptor: Describes a specific function provided by the device. Composite devices may have multiple interfaces.
  • Endpoint Descriptor: Defines a data channel, including address, direction, transfer type, and maximum packet size. Function drivers often bind to an interface rather than the entire device.

Device Enumeration Sequence

Enumeration is the process by which the system identifies a device and loads its driver.

  1. Physical Connection: A hub detects an electrical change on a port and notifies the host controller and hub drivers.
  2. Port Reset: The host controller issues a reset command to the port, placing the device in a default state.
  3. Retrieve Device Descriptor: The host reads the device descriptor from the default address to obtain basic information like VID and PID.
  4. Assign Address: The host assigns a unique USB address to the device for subsequent communication.
  5. Retrieve Full Configuration: The host reads configuration, interface, endpoint, and string descriptors to understand the device's functions and data channels.
  6. Construct Device Identifiers: The hub driver provides identifiers to the PnP manager, including a specific Device ID, a list of Hardware IDs, and Compatible IDs (often based on class/subclass/protocol).
  7. Load Function Driver: The PnP manager searches for a matching driver, prioritizing specific Device IDs over general Hardware IDs and Compatible IDs. Standard class-compliant devices often use built-in Windows drivers (e.g., USB Mass Storage driver, HID driver).

I/O Request Pathway

Once enumerated, applications access the device via system APIs, which are translated into kernel-level requests.

  1. Application to IRP: User-mode calls like ReadFile or WriteFile are converted by the I/O manager into an I/O Request Packet (IRP), a kernel structure describing the operation.
  2. Function Driver Processing: The IRP is sent to the function driver's FDO. The driver interprets the high-level request (e.g., reading a file sector) and translates it into a USB-specific operation.
  3. IRP to URB: The function driver constructs a USB Request Block (URB) to describe the low-level USB transaction. A URB specifies the transfer type, target endpoint, data buffer, and length.
    • IRP: High-level I/O request.
    • URB: Low-level USB protocol request.
  4. URB Dispatch: The URB is passed down the driver stack to the hub and host controller drivers.
  5. Host Controller Execution: The host controller driver translates the URB into hardware-specific commands (e.g., transfer descriptors for xHCI) and initiates the transfer via DMA. The USB transaction involves token, data, and handshake packets.
  6. Completion Notification: Upon completion, an interrupt signals the host controller driver, which updates the URB status. The result propagates back up the stack, culminating in the application receiving the data.

The complete path is: Application -> System API -> I/O Manager -> IRP -> Function Driver -> URB -> Hub/Bus Driver -> Host Controller Driver -> USB Controller Hardware

USB Transfer Types

  1. Control Transfers: Used for device configuration and command/control. Essential for enumeration and vendor-specific commands.
  2. Interrupt Transfers: For small, time-sensitive data (e.g., keyboard, mouse). The host polls the endpoint at regular intervals.
  3. Bulk Transfers: For reliable, non-time-critical large data transfers (e.g., storage devices, printers). Optimized for throughput.
  4. Isochronous Transfers: For real-time streaming data (e.g., audio, video). Prioritizes consistent bandwidth over perfect reliability, allowing for potential data loss.

Relevance to USB Redirection

Effective USB redirection requires understanding the local device access pathway to replicate it remotely. Key aspects include:

  • How descriptors identify the device.
  • PnP driver matching.
  • Translation of application I/O into IRPs and then URBs.
  • Performance and reliability characteristics of different transfer types.

Redirection challenges often stem from mismatches in timing, bandwidth, or protocol behavior between the local and remote environments, rather than network issues alone. For instance, isochronous streams are more complex to redirect than bulk transfers.

Tags: Windows USB Driver Stack Device Communication IRP

Posted on Mon, 08 Jun 2026 18:46:56 +0000 by dmb