Developing Drivers with the Windows Driver Foundation (Pro Developer)

WDF implements Plug and Play and power management with several internal state machines. Both KMDF and UMDF use the same state machines. An event is associated with the specific actions that a driver might be required to perform at a particular time, and the driver implements the event callbacks to perform the actions that its device requires. The callbacks are called in a defined order and each conforms to a "contract," so that both the device and the system are guaranteed to be in a particular state when the driver is called to perform an action.

Plug and Play and Power Management Defaults

Although WDF provides great flexibility so that a driver can control detailed aspects of its device's Plug and Play capabilities, WDF also implements defaults that enable many filter drives and software-only drivers to omit any Plug and Play code whatsoever. By default, WDF supports all Plug and Play features that such drivers need.

By default, WDF assumes the following:

State Machines and the Clear Contract

The history of the state machines in the framework provides an interesting view into how much we underestimated the complexity involved in implementing them. When Jake Oshins first introduced his idea of using formalized state machines with a Unified Modeling Language (UML) diagram as a visual aid, there were two state machines (PnP and Power) with fewer than ten states between them. In fact, power just had two states, on and off!

Needless to say, the number of states grew dramatically to nearly 300 states among all of the state machines. Not only did the number of states grow, but so did the number of state machines. In addition to the PnP, power, and power policy machines, the framework also uses state machines to manage the idle logic and self-managed I/O callbacks.

Taking a step back and looking at the final implementation, we had no idea what we were in for when we started, and we could never have predicted the final results. The biggest satisfaction that I derived from working on the state machines was that all of the complexity remained internal to the framework. What the driver writer sees is a very clear contract with very clear guidelines, never having to worry about this set of problems again.-Doron Holan, Windows Driver Foundation Team, Microsoft

I/O Queues and Power Management

The frameworks implement power management for I/O queues, so that the queue automatically starts and stops when the device enters and leaves the working state. Such a queue is "power managed." The framework dispatches I/O requests from a power-managed queue to the driver only when the device hardware is accessible and in the working power state. The driver is not required to maintain device state or to check device state each time it receives an I/O request from a power-managed queue.

By default, the I/O queues of FDOs and PDOs are power managed. A driver can easily change this default to create a non-power-managed queue or to configure power-managed queues for a filter DO. If an I/O request arrives while the device is in a low-power idle state, the framework can restore device power before it delivers the request to the driver.

Plug and Play and Power Event Callbacks

Most of the Plug and Play and power callbacks are defined in pairs: one event occurs upon entry to a state and the other occurs upon exit from the state. Generally, one member of the pair performs a task that the other reverses. A driver can implement one, both, or neither of a pair. In a UMDF driver where both methods are defined on a single interface, the driver must implement the entire interface on the device callback object but can supply minimal implementations of the methods that it does not require.

The frameworks are designed to work with drivers on an opt-in basis. A driver implements callbacks for only the events that affect its device. For example, some drivers must save device state immediately before the device leaves the D0 power state and restore device state immediately after the device reenters the D0 power state. As another example, a device might have a motor or fan that the driver must start when the device enters D0 and stop before the device leaves D0. A driver can implement callback functions that are invoked at those times. If the device does not require service at those particular times, its driver does not implement the callbacks.

Table 7-1 summarizes the types of Plug and Play and power features that a driver might require and the UMDF interfaces and KMDF event callbacks that the driver implements to support those features.

Table 7-1: Plug and Play and Power Callbacks for WDF Drivers

Open table as spreadsheet

If your driver…

Implement this UMDF interface and its methods on the device callback object…

Implement this KMDF event callback…

Uses self-managed I/O

IPnpCallbackSelfManagedIo::Xxx

EvtDeviceSelfManagedIoXxx

Requires service immediately before the device is initially powered up and after it powers down during resource rebalancing or device removal

IPnpCallbackHardware::OnPrepareHardware OnReleaseHardware

EvtDevicePrepareHardware and EvtDeviceReleaseHardware

Requires service immediately after the device enters D0 and before it leaves D0

IPnpCallback::OnD0Entry OnD0Exit

EvtDeviceD0Entry and EvtDeviceD0Exit

Requires the opportunity to evaluate and veto each attempt to stop or remove the device

IPnpCallback::OnQueryStop OnQueryRemove

EvtDeviceQueryStop and EvtDeviceQueryRemove

Requires additional service at surprise-removal beyond the normal device removal processing

IPnpCallback::OnSurpriseRemoval

EvtDeviceSurpriseRemoval

 KMDF  Because KMDF drivers have greater access to device hardware than UMDF drivers do, KMDF supports additional features, such as system wake. Table 7-2 lists additional callbacks that apply only to KMDF drivers.

Table 7-2: Additional KMDF Plug and Play Callbacks

Open table as spreadsheet

If your driver…

Implement this KMDF event callback…

Manages device resource requirements

EvtDeviceResourceRequirementsQuery

EvtDeviceResourcesQuery

EvtDeviceRemoveAddedResources

EvtDeviceFilterAddResourceRequirements

EvtDeviceFilterRemoveResourceRequirements

Manages the device's wake signal

EvtDeviceArmWakeFromSx and EvtDeviceDisarmWakeFromSx

EvtDeviceArmWakeFromS0 and EvtDeviceDisarmWakeFromS0

EvtDeviceEnableWakeAtBus and EvtDeviceDisableWakeAtBus

EvtDeviceWakeFromSxTriggered and EvtDeviceWakeFromS0Triggered

Performs hardware-related tasks around interrupts

EvtInterruptEnable and EvtInterruptDisable

EvtDeviceD0EntryPostInterruptsEnabled and EvtDeviceD0ExitPreInterruptsDisabled

 WDF automatically translates system power events to device power events  If you're familiar with WDM drivers, you probably remember that any time the system power state changes, the WDM power policy owner must determine the correct power state for its device and then send power management requests to put the device in that state at the appropriate time. The WDF state machine automatically translates system power events to device power events and notifies the driver to do the following:

 KMDF  KMDF automatically provides for the correct behavior in device parent/child relationships for bus drivers. If both a parent and a child device are powered down, KMDF ensures that the parent is powered up before it transitions the child to the D0 state.

Idle and Wake Support (KMDF Only)

To manage idle devices, the framework notifies the driver to transition the device from the working state to the designated low-power state when the device is idle and to return the device to the working state when requests need to be processed. The driver supplies callbacks that initialize and deinitialize the device, save and restore device state, and enable and disable the device wake signal.

By default, a user who has the appropriate privileges can control both the behavior of the device while it is idle and the ability of the device to wake the system. KMDF implements the required WMI provider, and Device Manager displays a property page through which the user can configure the settings. The power policy owner for the device can disable this feature by specifying the appropriate enumeration value when it initializes certain power policy settings.

Power-Pageable and Non-Power-Pageable Drivers

Most devices can be powered down without affecting the system's ability to access the paging file or to write a hibernation file. The drivers for such devices are considered "power pageable":

 KMDF  A device that is in the hibernation path, however, must remain in D0 during some power transitions so that the system can write the hibernation file. A device that is in the paging path remains in D0 until the system has written the hibernation file, at which point the entire machine shuts off. The device stacks for the hibernation and paging devices are considered non-power pageable. A KMDF driver indicates that it can support the paging, hibernation file, or system dump file by calling WdfDeviceSetSpecialFileSupport and providing a callback for notification if the device is actually used for such a file.

For example, drivers in the video and storage stacks are non-power pageable because the system uses these devices during power-down. The monitor must remain on so that Windows can display information to the user. During transitions to S4, the target disk for the hibernation file and the disk that contains the paging file must remain in D0 so that the system can write the hibernation file. For the disks to retain power, every device that they depend on must also retain power-such as the disk controller, the PCI bus, the interrupt controller, and so on. All of the drivers in all of these device stacks must thus be non-power pageable.

Most drivers should use the framework's defaults, which are as follows:

If the default is inappropriate, a function or bus driver can explicitly call the WdfDeviceInitSetPowerPageable or WdfDeviceInitSetPowerNotPageable method during device object initialization to change the default. These methods set and clear the DO_POWER_PAGABLE value in the Flags field of the underlying WDM device object for an FDO or PDO, but have no effect for filter DOs.

The framework can change the value of the DO_POWER_PAGABLE flag for any device object if the system notifies the driver that the device is used for a hibernation, paging, or dump file.

If you are certain that none of the drivers in the device stack must be non-power pageable, your driver can call WdfDeviceInitSetPowerPageable. This might be the case if you wrote all of the drivers in the stack or if the requirements for the device stack are clearly documented. A PDO must not be power pageable unless the device stacks of all of the child devices are also power pageable.

KMDF provides the following special handling for drivers that are non-power pageable:

Категории