Windows and WDM expose a complicated model for Plug and Play and power management that depends on the driver to keep track of both the state of its device and the state of the system, thus in effect implementing its own informal state machine. WDM drivers must know which Plug and Play and power requests to handle in each state and which operations to perform in response to those requests. Some requests require the driver to perform one operation if the device is powered up and a different operation if it is not. Other requests require no driver action at all, but the driver must nevertheless include code that parses the request and checks the current device and system state to determine whether action is required.
In contrast, the WDF frameworks implement intelligent default behavior and expose a set of state-specific callbacks that drivers can implement to customize the Plug and Play and power behavior. WDF tracks the state of the device and the state of the system and maintains information about the Plug and Play and power capabilities of the driver and device hardware. The frameworks can also manage a driver's I/O queues with respect to the device's power state. Therefore, if an I/O request arrives while the device is not powered on, the framework can power up the device.
A WDF driver can "opt in" to device-specific handling for more complicated situations by implementing callbacks for such events as setup initialization, shutdown cleanup, power on, power off, and so forth. The WDF defaults apply to any event for which the driver does not implement a callback.
WDF provides a wide range of Plug and Play and power management options for drivers. For example:
By default, both KMDF and UMDF drivers support the fundamental Plug and Play and power management features, including fast resume and suspend.
A driver requires code only to save and restore device context and, in some KMDF drivers, to enable and disable device interrupts.
KMDF drivers can support automatically suspending an idle device on a running system.
During idle periods, the framework puts the device in a low-power state. For USB devices, the driver can use selective suspend. To support this extra functionality, most drivers require only one additional function call.
KMDF drivers can support a device wake signal that wakes the device or the system.
The driver identifies the power states at which the device can trigger a wake signal. A KMDF driver can support wake at any system power state other than the off state. Implementing wake typically requires adding just a few callback functions to a driver.
In each of these examples, a driver supplies only the code that is required to manipulate its device. The framework tracks device and system state and calls the driver at its registered callbacks to perform device-specific actions.
Plug and Play is a combination of system software, device hardware, and device driver support through which a computer system can recognize and adapt to hardware configuration changes with little or no intervention by an end user. An end user can add devices to and remove devices from the system without doing technical, hardware-level configuration. For example, a user can plug in a USB flash drive to transfer files or can dock a portable computer and use the docking station's keyboard, mouse, and monitor without making manual configuration changes.
If the device hardware and driver support Plug and Play, Windows recognizes the new devices, loads the proper drivers, and starts the devices to make them available for the user. The PnP manager is the kernel subsystem that recognizes hardware during initial system installation, recognizes hardware changes that occur between system boots, and responds to hardware events such as docking or undocking and device insertion or removal.
The bus driver detects and enumerates devices and requests resources for those devices. The PnP manager gathers resource requests from all of the bus drivers and assigns resources to the devices. Resources are not dynamically configurable for legacy devices, so the PnP manager assigns resources to legacy devices first. If the user adds a new device that requires resources that are already in use, the PnP manager reconfigures resource assignments.
At device object initialization, the bus driver indicates which of the following Plug and Play features its device supports:
The device can be ejected from its slot.
The device is a docking station.
The device can be removed while the system is running.
A user can remove the device without using the Unplug or Eject Hardware application.
The device can be locked in its slot to prevent ejection.
The device can be hidden in Device Manager.
A power state describes the level of power consumption for the system or for an individual device. System power states are named S0 for the working state and Sx, where x is a state number between 1 and 5, for the sleep states. Device power states are named D0 and Dx, where x is a state number between 1 and 3. The state number is inversely related to power consumption: higher numbered states use less power.
"Highest powered state" uses the most power In this book, the terms "highest-powered state" means the state that uses the most power, and conversely for "lowest-powered state." Therefore, D0 is a higher-powered state than D1, and D3 is a lower-powered state than D2.
For the system, state S0 is the highest powered, most functional, fully-on working state. State S4 is the hibernation state. State S5 is the off state. States S1, S2, and S3 are sleep states, with progressively lower levels of power consumption.
For a device, D0 is the fully-powered working state. D3 is the powered-down (off) state. All devices must support these two states. The exact definitions of the intermediate power states are bus and device specific, unlike the system states where S4 and S5 are universally defined. Not all devices support intermediate power states. Many devices support only the D0 and D3 states.
Note For PCI devices, the PCI specification defines the D3hot and D3cold states. In Windows, D3hot means that the device is in D3 and its parent bus is in D0. D3cold means that the device is in D3 and its parent bus is in Dx.
A device can transition from D0 to any lower-power state (Dx) and from any lower-power state to D0. However, a device cannot transition from one sleep state (Dx) to another; it must return to D0 before it can enter a different sleep state. In addition, the device must be in D0 when the driver arms or disarms the wake signal. The reason is that access to the device hardware is prohibited when the device is in a sleep state, so the driver must return the device to the working state before performing any hardware-related activity.
The power state of a device is related to the system state but is not required to match it. For example, many devices can be in the off state (D3) when the system is in the working state (S0). Usually, a device's power state is no higher than that of the system because many devices get their power from the system. Devices that are enabled to wake a suspended system are exceptions; such devices are typically in a sleep state (D1 or D2) when the system is in a sleep state.
UMDF For UMDF drivers, the underlying bus driver sets the power capabilities of the device and the UMDF driver cannot change them.
KMDF A KMDF driver can set power capabilities in the same way that it sets Plug and Play capabilities. Typically a bus driver sets the capabilities of the devices that are attached to the bus, but a function or filter driver can override the bus driver's settings. The settings include the following:
The power states that the device supports in addition to D0 and D3.
The power states from which the device can respond to a wake signal.
The highest-powered Dx state that the device supports for each system Sx state.
The highest-powered Dx state from which the device can trigger a wake signal to the system.
The lowest-powered Sx state at which the device can trigger a wake signal.
Approximate latency time for the device to return to D0 from each sleeping state.
The "ideal" Dx state that the device should enter when its wake signal is not enabled and the system is entering a sleep state.
When the system enters an Sx state, the framework transitions the device to either the ideal Dx state or the lowest-powered Dx state that the device can support at the given Sx state-whichever is higher powered.
The driver reports the power capabilities to the framework, and the framework, in turn, reports them to the system. The drivers in the device stack cooperatively set power capabilities, so it is possible for another driver higher in the stack to override the values that a KMDF driver sets.
The power policy for a device determines which power state the device should be in at any given time. One driver in each device stack is responsible for controlling the device's power policy, and that driver is called the power policy owner for the device stack:
A UMDF driver must explicitly indicate that it is the power policy manager.
KMDF assumes, by default, that the FDO is the power policy owner for the device. If the device is controlled by a raw PDO, KMDF assumes that the raw PDO is the power policy owner.
The function driver is responsible for the device's functional operation and is therefore most likely to have the necessary information about the best way to manage device power. A KMDF filter driver can indicate that it is the power policy owner for its device by notifying the framework during initialization.
The power policy owner is not necessarily the driver that manipulates the device hardware to change the power state. It is simply the driver that specifies when the device power state transitions should occur.
Drivers that claim power policy ownership must ensure, through some means outside standard operating system control, that they are indeed the only power policy owner in their stack. Usually, this mechanism is a documented policy that indicates which driver is the power policy manager.