Self-Management Example

A device that implements all five power states manages its power dynamically by stepping down from D0 to D1, or D1 to D2, if it has been inactive for some period of time. The device does this in stages because D2's power consumption is lower but it is much less responsive also. If the device detects activity, and it is not in D0, it will attempt to go to D0.

Such a device's interrupt service thread might look like the following code example.

while(!fDone) {
    dwStatus = WaitForSingleObject(hInterruptEvent, dwTimeout);
    switch(dwStatus) {
    case WAIT_OBJECT_0: // device activity
        // service device
        ...
        if(deviceDx != D0 && !fBoostRequested) {
            fBoostRequested = TRUE;
            DevicePowerNotify(pszDeviceName, D0, POWER_DRIVER | POWER_NAME);

        }
        dwTimeout = INACTIVITY_TIMEOUT;
        break;
    case WAIT_TIMEOUT:  // device inactive
        if(deviceDx < D2 && !fReductionRequested) {
            fReductionRequested = TRUE;
            DevicePowerNotify(pszDeviceName, deviceDx + 1, POWER_DRIVER | POWER_NAME);

        }
        if(deviceDx >= D2) {
            dwTimeout = INFINITE;
        }
    default:            // error handling
        break;
    }
}

The device's DeviceIoControl routine might include the following code example.

case IOCTL_POWER_SET:
    // update device registers
    ...
    deviceDx = *(PCEDEVICE_POWER_STATE) pOutBuf;
    fBoostRequested = FALSE;
    fReductionRequested = FALSE;
    break;

The driver code only keeps track of whether or not it has requested a state transition, not whether the transition has occurred. This is important, because the device might request D0 while at D2, but the Power Manager might only set it to D1 because of the current power state. On the next device activity the device would request D0 again and the Power Manager might simply leave it at D1. Keeping track of the fact that it requested a state transition would prevent further unnecessary Power Manager API calls while the device is active. The same logic applies to power state reductions due to inactivity time-outs.

The device's IST sets the fBoostRequested and fReductionRequested flags before calling DevicePowerNotify. This is because the DevicePowerNotify invocation may result in an IOCTL_POWER_SET call into the driver on the same thread. The DeviceIoControl call clears the flags, which enables the driver to make further adjustments to the device power state in the future.

See Also

Device Power Self-Management

 Last updated on Tuesday, May 18, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.