I/O Kit Power Controller

This technical note provides a terse description of an I/O Kit KEXT which supports power management.

If you haven't the time to learn about power management, this technote will quickly guide you through the steps needed to add power management to your KEXT.

If you're in a hurry download the Project Builder KEXT below, open the system log, and build the kernel extension. You can observe your KEXT being loaded, registering for power events, and responding to sleep events. You can then copy and paste the code (not a large amount) into your driver.

Finally there is a section that points to additional power management documentation, samples, DDK, etc. so that you can learn everything concerning power management on Mac OS X given you have more time.





An I/O Kit power controller: A quick look

An I/O Kit power controller is an entity that controls the voltage (Vcc ) and current (i) to an I/O device usually via a driver (KEXT).

To make your KEXT a power controller, you must:.

Create a power-state array. This array defines your power parameters or needs such as current rise and settle times, steady state current, etc.

Register your KEXT with I/O Kit. This step places your device into the IOPower plane of the I/O Registry.

Override your provider's setPowerState method. Your setPowerState method will receive power on and off messages. Your KEXT must do what is needed to remove and restore power to your device, including any stes information that may be needed by your KEXT.

These three steps are described in more detail below.

Back to Top

The power-state array

The power state array, contained in the Developer SDK, is located at this path.

/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/IOKit/pwr_mgt/IOPMpowerState.h

The example shown in Listing 1 has a two state power-state array, whose states are "on" and "off". Two-state arrays (on/off) are common and provide a simple way to add power-management code to your KEXT. See Chapter 10 of I/O Kit Fundamentals and the header file in the HelloIOKitWithPowerManagement project Downloads for more details.

Look at the header file in the enclosed project and Chapter 10 of I/O Kit Fundamentals for details.

This completes the first step. Now you will need to register your power-state array.

Listing 1: power-state enum & array

enum {
    kDTSOffState = 0,
    kDTSOnState = 1,
    kNumDTSStates = 2
    };
static const IOPMPowerState ourPowerStates[kNumDTSStates] = {
    {kIOPMPowerStateVersion1,0,0,0,0,0,0,0,0,0,0,0},
    {kIOPMPowerStateVersion1,kIOPMDeviceUsable,
    IOPMPowerOn,IOPMPowerOn,0,0,0,0,0,0,0,0}
    };

Back to Top

The registration process

There are three functions you must call to complete the power management registration process, as shown in Listing 2 .

First, call PMinit to allocate and initialize the power management instance variables. Be sure to call PMinit before you attempt to access those variables or the power management methods.

Second, call your parent class method registerPowerDriver to volunteer to control your device and don't forget to check for a success.

Finally you must call your parent class method to join the IOPower plane of the I/O Registry.

WARNING: joinPMtree is a virtual method. Do not override this method. Do not call joinPMtree or super::joinPMtree as they will compile, but not place your object into the right part of the I/O Registry IOPower plane.

Listing 2: Registering as a power controller

IOLog("PowerManagement is Starting\n");
// initialize superclass variables from IOService.h
        PMinit();
// register as controlling driver from IOService.h
        myValue = registerPowerDriver( this,
 (IOPMPowerState *) ourPowerStates, kNumDTSStates );
        if (myValue != kIOReturnSuccess) {
        IOLog("%s: Failed to registerPowerDriver.\n", getName());
        }
        // join the tree from IOService.h
        provider->joinPMtree( this);

Back to Top

Responding to power events

The final step is to implement (override) your IOService parent's setPowerState method. Your driver is the only entity that understands how to power up and power down your device. Place the declaration shown in Listing 4 into your header file:

Listing 3: setPowerState Declaration

virtual IOReturn setPowerState(unsigned long, IOService *);

This trivial implementation will suffice for this technical note. You can learn the details of this implementation in Chapter 10 of I/O Kit Fundamentals.

However, if you put your computer to sleep, via the Apple Menu, this implementation will log its entry in the IOLog.

Listing 4: setPowerState Implementation

IOReturn com_DTS_iokit_HelloIOKit::setPowerState(
unsigned long whatState, IOService* dontCare){
    IOLog("Setting power state:%lu\n", whatState);
    // turn your device on/off here
    return IOPMAckImplied;
}

That's all you need to do to have a simple on/off power-aware driver. Now let's look at these three steps as they appear in a complete I/O Kit KEXT.

Back to Top

The project

The enclosed Project Builder project is derived from the Hello I/O Kit tutorial .

If you are new to Apple development you might want to run this tutorial first. If not, just download the project. This project includes the three power management steps described above and is ready to run. You'll need to know how to load a KEXT into the Extensions folder. If you don't know how to do this, see the "Test the Device Driver" section of the tutorial.

Back to Top

Other sources

Finally, if you have the time, you can get more information about power management from the following sources:

The Power Manager DDK contains samples, tools, etc.

The document called I/O Kit Fundamentals Chapter 10, "Managing Power and Device Removal" also has current information.

A companion technical note to this one, TN 2075 PowerManagement for Macintosh;getting started, describes all links to various power management data.

Good luck with your development effort. DTS Engineering

Back to Top

Downloads

Document Revision History

Date Notes
2003-06-20 Describes code to include in a KEXT in order to register for power management events.

Posted: 2003-06-20


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.