Wait/Wake Callback Routines
When a driver requests a wait/wake IRP, it must specify a callback routine so that it can return the device to the working state (D0) when the wake-up event occurs. After the wake-up event occurs and all drivers have completed the IRP, the system calls the callback routine passed to PoRequestPowerIrp.
Because this callback routine is set on behalf of the driver that originated the IRP—and not for a driver that is handling the IRP—it must not call PoStartNextPowerIrp; only the IoCompletion routines set as drivers pass the IRP down the stack should start the next power IRP. Keep in mind that the policy owner not only sends the IRP but handles it, and it therefore might set an IoCompletion routine as it passes the IRP down the stack in addition to setting a callback routine when it requests the wait/wake IRP.
The callback routine has the following responsibilities:
If the driver controls more than one device, determine which of its devices signaled the wake-up.
Service the event that caused the wake-up signal.
Set the device that signaled the wake-up in the D0 state by calling PoRequestPowerIrp to send a PowerDeviceD0 request. The driver must also call PoSetPowerState to inform the power manager of the new device power state. For more information, see Sending IRP_MN_QUERY_POWER or IRP_MN_SET_POWER for Device Power States.
If the driver set a Cancel routine for the IRP, call IoSetCancelRoutine to reset the Cancel routine to NULL.
If the driver owns power policy for more than one device, decrement its wait/wake reference count. If the count is nonzero, indicating that another device had previously sent a wait/wake IRP, request another wait/wake IRP (PoRequestPowerIrp) for its PDO.
For example, a PCI device might have wait/wake enabled for both a modem and a Network Interface Card (NIC). If the NIC wakes the system (thus completing the IRP), the PCI FDO must send another wait/wake IRP to itself so that the modem will still be able to wake up.
Because the driver that requested the wait/wake IRP controls power policy for its device stack, it is responsible for returning its device to the working state when the IRP completes. Although lower drivers might already have physically applied power to the device, the policy owner must call PoRequestPowerIrp to send an IRP_MN_SET_POWER request for device power state D0. Only after all drivers in the device stack have handled this power-up IRP will the device be returned to the working state.