Книга: Writing Windows WDM Device Drivers

Advanced Power Management

Advanced Power Management

Wake

The basic idea of IRP_MN_WAIT_WAKE Power IRP is quite simple. It lets devices wake the system up from a sleeping state. A classic example is letting an incoming call from a modem wake up the system. Alternatively, a soft power on/off switch could power the system up when it is pressed.

Send an IRP_MN_WAIT_WAKE IRP to yourself using PoRequestPowerIrp before you power down. The bus driver marks the IRP as pending. When the wake event occurs, the bus driver completes the IRP and wakes the system up or powers the device up.

The situation becomes complicated when your bus driver cannot wake up the system. The bus driver FDO must generate another IRP_MN_WAIT_WAKE IRP and send it to its PDO. This continues until the root ACPI driver is reached, which can wake the system up. Each IRP_MN_ WAIT_WAKE IRP is completed in turn by the bus drivers when a wake event is detected.

You must be prepared to cancel an IRP_MN_WAIT_WAKE IRP when a device is removed.

When a device is stopped, the IRP_MN_WAIT_WAKE IRP must be cancelled and sent again when the resources have been reassigned.

Power Sequence

A driver can send an IRP_MN_POWER_SEQUENCE IRP to its bus driver (device power policy manager) to see how many times the device has entered the device states D1, D2, and D3. This information is used to see if a device did power down and so needs to be powered up.

A bus driver zeroes these counts when the device is created. It then increments the relevant count every time it moves into that device state. It never zeroes the counts again.

Stopping System Power Down Events

The PoRegisterSystemState kernel call provides a function similar to the SetThreadExecutionState Win32 call. It lets a driver tell the Power Manager that the system is busy, that the display is required, or that a user is present. If successful, PoRegisterSystemState returns a non-NULL pointer. When you are finished, call PoUnregisterSystemState to cancel your busy notification.

The similar function, PoSetSystemState just resets the Power Manager idle counters for these same attributes. Calling PoSetSystemState does not make the settings persist.

These functions are only available in W2000.

Power Notification

A driver can register to receive power notification events on a device tree using the PoRegisterDeviceNotify function. A notification handle is returned that must be passed to PoCancelDeviceNotify to stop receiving power notification events. These functions are only available in W2000.

Detecting System Power State Changes

In Windows 2000, a driver can use a kernel callback object to detect when the system power policy changes or when a sleep or shutdown is imminent. Register a callback routine to receive notification of CallbackPowerState events.

First, initialise an attribute block using InitializeObjectAttributes. Then obtain a callback object pointer using ExCreateCallback. Finally, register your callback routine using ExRegisterCallback. The arguments passed to your callback routine indicate what power event has happened — see the DDK for details. Call ExUnregisterCallback when you do not wish to receive any more notifications.

You can also register to receive CallbackSetSystemTime notifications when the system time is changed. Finally, you can create your own callback object; calling ExNotifyCallback runs the callback routines in all the other drivers that have registered for your callback.

WMI Support

Chapter 12 shows that Windows Management Instrumentation (WMI) is a facility that lets users interact with drivers. In fact, it will be just system operators, developers, or network professionals who wish to use WMI to see what is happening in a system, possibly to diagnose a fault condition.

A driver supports WMI by handling the IRP_MJ_SYSTEM_CONTROL IRP. WMI lets drivers make information available to users or receive data from them. The data objects are in structures identified by GUIDs. There are various standard WMI data blocks, but drivers can define their own data blocks, if need be.

The Power Management portion of a driver can use two standard WMI data blocks to let a user enable or disable two features. The MSPower_DeviceEnable data block, identified by GUID_POWER_DEVICE_ENABLE, has an Enable Boolean that a driver should use to determine if it should dynamically power itself down when it is idle. The MSPower_DeviceWakeEnable data block, identified by GUID_POWER_DEVICE_WAKE_ENABLE, has a similar Enable Boolean whose value should be used to enable its Wake feature.

A driver that supports these WMI features may also let their settings be changed using IOCTLs.

GUID_POWER_DEVICE_TIMEOUT is also defined to let the user change the idle timeouts. This feature is not working in W2000 Beta 3.

If you implement WMI for the MSPower_DeviceEnable or MSPower_DeviceWakeEnable data blocks, the driver properties box gains an extra Power Management tab. Figure 10.4 shows how this looks for a Wdm3 device. The Wdm3 driver supports the MSPower_DeviceEnable data block, but not MSPower_DeviceWakeEnable, so only the power down option is available in the Power Management tab.

Figure 10.4 Wdm3 Power Management device properties


Оглавление книги


Генерация: 0.702. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз