Plug and Play and power events are defined for the device object, so the driver must register them in its EvtDriverDeviceAdd
callback when it creates the device object. Most of the Plug and Play
and power callbacks are defined in pairs: One event occurs when the
device is added or powered up, and the other occurs when the device is removed or powered down. The following are the two most commonly used pairs:
EvtDeviceDOEntry and EvtDeviceDOExit, which are called immediately after the device enters the working state and before it exits the working state.
EvtDevicePrepareHardware and EvtDeviceReleaseHardware,
which are called before the device enters the working state and after
it exits the working state. Typically, drivers map and unmap hardware
resources in these callbacks.
KMDF defines the WDF_PNPPOWER_EVENT_CALLBACKS
structure to hold the Plug and Play and power settings and provides a
function to record the information from that structure into the WDFDEVICE_INIT
structure. It also includes a method to set the Plug and Play and power
management callbacks. Thus, to register its Plug and Play and power
management callbacks, a driver
Calls WDF_PNPPOWER_EVENT_CALLBACKS_INIT to initialize a WDF_PNPPOWER_EVENT_CALLBACKS structure.
Sets entry points in the WDF_PNPPOWER_EVENT_CALLBACKS structure for its Plug and Play and power management event callbacks.
Calls WdfDeviceInitSetPnpPowerEventCallbacks, passing pointers to the WDFDEVICE_INIT structure and the completed WDF_PNPPOWER_EVENT_CALLBACKS structure.
A driver that manages power policy for its devices
also must provide callback functions for power policy events, such as
arming and disarming wake signals. The following are the power policy
event callbacks:
EvtDeviceArmWakeFromSO, which is called to arm the device to wake the system from SO, the system working state.
EvtDeviceDisarmWakeFromSO, which is called to disarm wake signals from SO.
EvtDeviceWakeFromSOTriggered, which is called when the system is in SO and the wake signal is triggered.
EvtDeviceArmWakeFromSx, which is called to arm the device to wake the system from one of the lower-powered system sleep states.
EvtDeviceDisarmWakeFromSx, which is called to disarm the wake signal, set by the EvtDeviceArmWakeFromSx callback.
EvtDeviceWakeFromSxTriggered, which is called when the wake signal is triggered and the system is not in the working state.
Like the power management callbacks, the power
policy event callbacks are required to initialize the device object.
KMDF defines a structure and function that the driver can use to record
this information in the DEVICE_INIT structure. The driver proceeds as follows:
Calls WDF_POWER_POLICY_EVENT_CALLBACKS_INIT to initialize a WDF_POWER_POLICY_EVENT_CALLBACKS structure.
Sets entry points for the power policy event callbacks that are supported by the driver.
Calls WdfDeviceInitSetPowerPolicyEventCallbacks with pointers to the WDFDEVICE_INIT structure and the completed WDF_POWER_POLICY_EVENT_CALLBACKS structure.
After creating the device object, the driver sets addition power policy options.
1. Sample Code to Register Plug and Play and Power Callbacks
The following code is excerpted from the Featured Toaster’s EvtDriverDeviceAdd callback (ToasterEvtDeviceAdd). It shows how to register the Plug and Play, power management, and power policy callbacks.
//
// Initialize the pnpPowerCallbacks structure. Callback events
// for PNP and Power are specified here. If you don't supply any
// callbacks, KMDF will take appropriate default actions based on
// whether DeviceInit is initialized as an FDO, a PDO, or a
// filter device object.
//
WDF_PNPPOWER_EVENT_CALLBACKS_INIT (&pnpPowerCallbacks);
//
// Register PNP callbacks.
//
pnpPowerCallbacks.EvtDevicePrepareHardware =
ToasterEvtDevicePrepareHardware;
pnpPowerCallbacks.EvtDeviceReleaseHardware =
ToasterEvtDeviceReleaseHardware;
//
// Register Power callbacks.
//
pnpPowerCallbacks.EvtDeviceDOEntry = ToasterEvtDeviceDOEntry;
pnpPowerCallbacks.EvtDeviceDOExit = ToasterEvtDeviceDOExit;
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit,
&pnpPowerCallbacks);
//
// Register power policy event callbacks so that driver is called
// to arm/disarm the hardware to handle wait wake and
// when the wake event is triggered by the hardware.
//
WDF_POWER_POLICY_EVENT_CALLBACKS_INIT(
&powerPolicyCallbacks);
//
// This group of three callbacks allows this sample driver to
// arm the device for wake from the SO or Sx state. We don't
// differentiate between SO and Sx state.
//
powerPolicyCallbacks.EvtDeviceArmWakeFromSO =
ToasterEvtDeviceWakeArm;
powerPolicyCallbacks.EvtDeviceDisarmWakeFromSO =
ToasterEvtDeviceWakeDisarm;
powerPolicyCallBack.EvtDeviceWakeFromSOTriggered =
ToasterEvtDeviceWakeTriggered;
powerPolicyCallbacks.EvtDeviceArmWakeFromSx =
ToasterEvtDeviceWakeArm;
powerPolicyCallbacks.EvtDeviceDisarmWakeFromSx =
ToasterEvtDeviceWakeDisarm;
powerPolicyCallbacks.EvtDeviceWakeFromSxTriggered =
ToasterEvtDeviceWakeTriggered;
//
// Register the power policy callbacks.
//
WdfDeviceInitSetPowerPolicyEventCallbacks(DeviceInit,
&powerPolicyCallbacks);
//
// Additional code to initialize other features such as
// device file callbacks, the device context area, and
// other device object attributes is shown in the
// previous discussions
//
//
// Call the framework to create the
// device and attach it to the lower stack.
//
status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);
if (!NT_SUCCESS(status)) {
KdPrint(("WdfDeviceCreate failed with Status Code 0x%x\n",
status));
return status;
}
The Featured Toaster driver sets callbacks for the EvtDevicePrepareHardware, EvtDeviceReleaseHardware, EvtDeviceDOEntry, and EvtDeviceDOExit events in pnpPowerCallbacks, which is a WDF_PNPPOWER_EVENT_CALLBACKS structure. It then calls WdfDeviceInitSetPnpPowerEventCallbacks to record this information in DeviceInit, which is a WDFDEVICE_INIT structure.
The Featured Toaster driver also sets callbacks for EvtDevicePrepareHardware and EvtDeviceReleaseHardware,
in which a driver can map and unmap resources. However, because this
driver does not operate physical hardware, these functions are
essentially stubs.
The driver sets callbacks for power policy in powerPolicyCallbacks, which is a WDF_POWER_POLICY_EVENT_CALLBACKS structure. The Featured Toaster
device requires the same driver actions regardless of the system state
in which wake-up is armed, disarmed, or triggered. Therefore, the Featured Toaster sample provides only three callbacks for the six possible power policy events:
ToasterEvtDeviceWakeArm arms the device for wake-up.
ToasterEvtDeviceWakeDisarm disarms the device for wake-up.
ToasterEvtDeviceWakeTrigger handles the wake-up signal.
The driver calls WdfDeviceInitSetPowerPolicyEventCallbacks to record these callbacks in the DeviceInit structure. Finally, it passes the DeviceInit structure in its call to WdfDeviceCreate to create the WDFDEVICE
object. (The excerpt shown here omits the code that registers file
object events and sets additional device object attributes; this code
was shown previously.)