Handling a Wait/Wake IRP in a Bus Driver (PDO)

Like other power IRPs, each wait/wake IRP must be passed all the way down the device stack to the bus driver (PDO), which is ultimately responsible for completing the IRP. Upon receiving the IRP, the bus driver can either fail it immediately or hold it pending for later completion. The following are the steps the bus driver must take:

  1. Inspect the value at Irp->Parameters.WaitWake.PowerState. If the device supports wake-up, but not from the specified SystemWake state or not from the current device power state, the driver should fail the IRP as follows:

    • Set STATUS_INVALID_DEVICE_STATE in Irp->IoStatus.Status.

    • Complete the IRP (IoCompleteRequest), specifying a priority boost of IO_NO_INCREMENT.

    • Return the status set in Irp->IoStatus.Status from the DispatchPower routine.

  2. Check whether a wait/wake IRP is already pending for the PDO. If so, set Irp->IoStatus.Status to STATUS_DEVICE_BUSY, increment the driver's internal count of wait/wake IRPs, and complete the IRP as described in the previous step.

    Only one wait/wake IRP can be pending for a PDO.

  3. If the device supports wake-up from the specified system power state and no wait/wake IRP is already pending, call IoMarkIrpPending to indicate to the I/O manager that the IRP will be completed or canceled later. Do not set an IoCompletion routine.

  4. Set the device hardware to enable wake-up.

    The specific mechanism by which a bus driver enables its hardware for wake-up is device-dependent. For a PCI device, Pci.sys is responsible for setting the PME-enable bit because this driver owns the PME register. For other devices, refer to the device-class-specific documentation.

  5. If the PDO is the child of an FDO, request a wait/wake IRP for the FDO, making sure to set a Cancel routine for the current IRP (the IRP that it holds pending). Do not attempt to pass on or reuse the current IRP.

  6. Return STATUS_PENDING from the DispatchPower routine.

  7. When a wake-up signal arrives, call IoCompleteRequest to complete the pending wait/wake IRP, setting Irp-IoStatus.Status to STATUS_SUCCESS, and specifying a priority boost of IO_NO_INCREMENT.

Note

During device removal, normally the power policy owner (PPO) should have cancelled the wait-wake IRP. But in case the PPO does not do so, as a resiliency mechanism we recommend that the bus PDO complete the IRP with a failure status. The bus PDO should do this when handling both IRP_MN_SURPRISE_REMOVE and IRP_MN_REMOVE_DEVICE.

For Devices That Do Not Support Wake-Up

If the device does not support wake-up, the bus driver (PDO) should proceed as follows:

  1. Complete the wait/wake IRP by calling IoCompleteRequest, specifying IO_NO_INCREMENT.

  2. Return from the DispatchPower routine, passing the value at Irp->IoStatus.Status as its return value.