Power IRPs for the System
A system power IRP specifies major IRP code IRP_MJ_POWER, one of the minor power IRP codes listed below, and the value SystemPowerState in the Power.Type member of the IRP stack. Only the power manager can send such an IRP; a driver cannot send a system power IRP.
The power manager sends a system power IRP for one of the following reasons:
To change the system power state in response to an idle time-out, a change in system activity, a user request, or an expiring battery (IRP_MN_SET_POWER)
To query devices to determine whether the system can go to sleep (IRP_MN_QUERY_POWER)
To reaffirm the current system power state after a query (IRP_MN_SET_POWER)
The power manager sends IRP_MN_QUERY_POWER and IRP_MN_SET_POWER requests on behalf of the system. A driver can fail an IRP_MN_QUERY_POWER request but cannot fail IRP_MN_SET_POWER.
For example, to change the system power state, the power manager sends a system power IRP to the top driver in the stack at each device node of the device tree. The following figure shows how drivers within a single device stack handle a system power IRP.
As the previous figure shows:
The power manager calls the I/O manager to send a system power IRP to each leaf node in the device tree.
Drivers handle the IRP if possible, set IoCompletion routines if necessary, and call IoCallDriver (Windows 7 and Windows Vista) or PoCallDriver (Windows Server 2003, Windows XP, and Windows 2000) to forward the IRP down the stack. If a driver must fail the IRP, the driver does so immediately and completes the IRP. Drivers can fail IRP_MN_QUERY_POWER IRPs, but must not fail IRP_MN_SET_POWER IRPs that set the system power state.
When the driver that owns power policy for the device receives the IRP, that driver sets an IoCompletion routine for the system IRP and then forwards the IRP.
Any other drivers in the stack handle the IRP if possible, set IoCompletion routines if necessary, and forward the IRP to the next-lower driver, as in step 2.
Eventually, the bus driver receives and completes the system IRP.
The I/O manager calls any IoCompletion routines that were set as drivers passed the system IRP down the device stack.
In its IoCompletion routine, the device power policy owner calls PoRequestPowerIrp to send a device power IRP, specifying a device power state that is valid for the system power state in the system IRP. The driver sets a callback routine to be invoked when the device power IRP completes.
If necessary, the driver consults the DeviceState member in its cached copy of the DEVICE_CAPABILITIES structure (see Reporting Device Power Capabilities) to determine which device power states correspond to the system power state in the IRP.
After the device IRP is complete and any device IRP completion routines have run, the power policy owner's callback routine is invoked. In the callback routine, the driver copies its returned status into the system IRP. In Windows Server 2003, Windows XP, and Windows 2000, the callback calls PoStartNextPowerIrp to start the next power IRP. However, in Windows 7 and Windows Vista, calling PoStartNextPowerIrp is not required and such a call performs no power management operation. Finally, the callback calls IoCompleteRequest to complete the system IRP.
For further information, see Handling System Power State Requests.
Because some devices require an inrush of current when they power on, system inrush power IRPs are handled synchronously and serially throughout the system. Only one such IRP can be active at a time. For further information, see Calling IoCallDriver vs. Calling PoCallDriver.