Observing Device Power State Changes

The I/O Kit allows a driver to observe the power state of any device in the system and to receive notifications when the device's driver changes its power state. This can be used, for example, by a driver that is not part of the power plane but needs to interface with drivers that are power managed. Alternatively, these notifications allow a driver that initiates a change to its own power state through a method such as changePowerStateToPriv() or activityTickle() to determine when the power change has completed.

To receive notifications when another driver's power state changes, your driver must register for interest in that driver's power state. The IOService superclass provides two methods for doing this:

  • registerInterestedDriver(IOService* driver)
  • deRegisterInterestedDriver(IOService* driver)

Both of these methods are called on the driver object whose power state you are interested in observing. The parameter to the method is the driver that will receive the notifications, and so you will typically pass the “this” pointer. A driver can call either of these methods at any time to start and stop receiving notifications for changes to the power state of another driver. It is important that a driver deregister any notifications that are installed before it unloads; failure to do so could lead to a kernel panic.

When a driver has registered interest in another driver's power state changes, it will receive a notification before the device begins its transition to the new power state and another notification once the device has completed the transition to the new power state. These two notifications are delivered through the two methods described as follows:

  • IOReturn       powerStateWillChangeTo(IOPMPowerFlags capabilities,

                         unsigned long stateNumber, IOService* whatDevice)
  • IOReturn       powerStateDidChangeTo(IOPMPowerFlags capabilities,

                         unsigned long stateNumber, IOService* whatDevice)

These two notification methods are virtual methods that are implemented by the driver that wishes to receive the notifications. The notification powerStateWillChangeTo() is delivered before the observed driver's setPowerState() method is called. The notification powerStateDidChangeTo() is delivered after the observed driver's setPowerState() method is called. Both methods are passed an identical set of arguments. The capabilities argument is the value of the capabilityFlags bitmask from the IOPMPowerState that the observed driver is transitioning to. The stateNumber argument is the index of the power state that the observed driver is transitioning to. The whatDevice argument is the driver object whose power state is being changed.

After handling either notification, the driver should return a value of IOPMAckImplied. If your driver wishes to handle the notification asynchronously, it can return a non-zero value from the notification method that indicates the maximum amount of time (in microseconds) that the driver requires to complete the request. The driver can then continue processing the notification on a background thread; once the driver has completed the notification, it should call the method acknowledgePowerChange() to inform the I/O Kit that the notification has been handled. The method acknowledgePowerChange() can be called to acknowledge both the willChange and didChange notifications.

A driver that handles power management will automatically register for interest in itself, and so the two notification methods will be called for a driver that is responding to a change in its power state. Most drivers, however, will have no need to implement these two notification methods unless the driver is observing the state of another device, since a driver's own power changes should be handled within the setPowerState() method. Instead, for this purpose, the I/O Kit provides another notification method that is sent to a driver when its own power state has been changed and all of its children drivers have acknowledged the power change. To receive this notification method, a driver should implement the following virtual method:

void    powerChangeDone (unsigned long previousStateNumber);

The method is sent once the driver has handled the power state change (through the setPowerState() method) and all drivers that have registered an interest for the device's power state have been notified of the power change. The powerChangeDone() method provides a convenient way for a driver to determine when a power state change that it initiated has been completed and the device has become usable. It is important to note the parameter that is passed to the powerChangeDone() method is the power level that the device changed from and not the new power state of the device. To determine the power state that the device is currently in, the I/O Kit provides an accessor method named getPowerState(), as described as follows:

UInt32  getPowerState(void);
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.51.55