Making Your OS/2 Device Driver APM-Aware

by Frank J. Schroeder

A recent trend in the computer industry is to encourage computer hardware manufacturers to design battery conservation into both battery (mobile) and non-battery (desktop) powered personal computers. In fact, the U.S. government has created the Energy St★r program to encourage just this.

Designing and implementing power-conservation capability into the hardware is just the first step. Software must be written to set the hardware into a low-energy usage mode when the device is not needed and to return the hardware to normal energy usage mode when the device is required. OS/2 has implemented this type of power management. To achieve the highest rate of power conservation, OS/2 device drivers must receive power management notification events and to manage the power of their devices accordingly.

The Advanced Power Management (APM) specification is an industry specification that defines a software interface to a set of BIOS routines that manage the power consumption of the factory installed devices within your computer.

Version 1.0 of the APM specification supports a subset of all devices (display, DASD, serial, parallel, and so forth). Requests made to the APM BIOS can apply to one of these devices or apply to all BIOS-managed devices. In contrast, Version 1.1 of the APM specification adds support for network adapters and PCMCIA sockets. The 1.1 specification adds additional interfaces to enable/disable power management on a per-device basis with either the BIOS performing the management or a cooperative effort between the operating system and the BIOS.

OS/2 Version 2.1 exploits Version 1.0 of the APM specification. And, because Version 1.1 of the APM specification is a superset of the 1.0 specification, OS/2 2.1 can execute on a system implemented to the 1.1 specification, although it will not take advantage of the 1.1 functions. An APM BIOS implemented to the 1.1 specification must emulate and default to the 1.0 specification.

The two primary components of OS/2 APM support are the power icon and the APM device driver (See Figure 1). The power icon displays the power source (AC/DC), the remaining battery life, and the battery state (high, low, critical, charging, unknown). You also can use the power icon to set the system into a suspend state. By managing the power consumption of your hardware, you can extend the length of time your system is usable. This becomes critical when AC power is unavailable.



The OS/2 APM device driver exports IOCtl and IDC interfaces to applications and device drivers to set and query the power state, notifies applications and device drivers to changes in power state, and notifies the APM BIOS when the operating system becomes idle or busy so that appropriate power state changes can occur. The APM device driver also queries the APM BIOS once per second for BIOS-initiated power events.

Users can install power manageable hardware into the expansion bus of their system. Unfortunately, APM BIOS is aware only of the factory installed equipment and cannot manage the power of installed hardware. This is the responsibility of the associated OS/2 device driver.

The OS/2 2.1 APM device driver lets you notify a device driver of changes in power state, which lets the device driver manage the power consumption of its device. The APM device driver exports an IDC interface, so a device driver can register a notification routine with the APM device driver. After it establishes the client/server relationship, the APM device driver communicates pending changes in power, which allows the client device driver to properly manage the power consumption of the installed hardware relative to the input and output occurring on the device.

The rest of this article describes the steps necessary to make your device driver APM-aware. These steps involve establishing a method of communication with the OS/2 APM device driver.

Obtain the APM Device Driver IDC Entry Point
A client device driver obtains the APM device driver IDC entry point by calling the AttachDD device helper service. You can issue AttachDD either in the initializiation routine or in the initialization complete routine. An advantage of issuing the AttachDD call in the initialization complete routine is that the initialization complete command removes device driver ordering dependencies in the CONFIG.SYS file. In addition, when a device driver is called with an initialization complete command, all device drivers are resident in memory and have been initialized.

When a client device driver chooses to process the AttachDD call in its initialization routine, the APM device driver's DEVICE= statement must appear in the CONFIG.SYS file before that of the client's device driver. If the client device driver appears be fore the APM device driver, the client device driver is initialized first. It then attempts to obtain an IDC entry point to a non-resident/non-initialized APM device driver. In this case, the client device driver cannot obtain the IDC entry point to the APM device driver or register its power management notification routine.

The client device driver passes a pointer in the ds and bx registers to an ASCIIZ string containing the name of the device driver (APM$) whose IDC entry point is to be returned (See Sample Code 1). The client device driver passes a pointer in the ds and di registers to a structure that contains the 16-bit protect mode IDC entry point and data segment selector to the APM device driver on return from the AttachDD call. If the carry flag is set on return from the AttachDD call, the call failed and an error code is returned in the ax register. The client device driver must verify the APM IDC entry point address returned is not zero before using the address to call the APM device driver. ''Sample Code 1. Initialization Complete routine''

Register a Power Management Notification Routine
After the client device driver obtains a valid IDC entry point to the APM device driver, it must register its power management notification routine. The client device driver cannot call the APM device driver to register a power management notification routine at initialization time. The address to the APM device driver IDC entry point returned on the AttachDD</tt> call is a ring 0 code selector. Loadable device drivers (DEVICE=</tt> statement in CONFIG.SYS) are initialized at ring 3; therefore, they cannot use ring 0 selectors during their initialization routine. Using a ring 0 selector while the processor is at ring 3 causes a general protection violation and halt the system.

The client device driver should register its power management notification routine in its initialization complete routine. In the registration structure, the client device driver passes to the APM device driver the function code (RegisterDDRtn</tt>), the 16:16</tt> address to its power management notification routine, a mask containing the power management notification events in which the device driver requests notification, its data segment selector, and the device ID of the device that the client device driver manages. The client device driver passes the registration structure in the es and bx registers to the APM device driver. Unlike typical IDC entry points, the client device driver does not need to set the ds register to the APM device driver before calling the APM IDC entry point. The APM device driver handles setting up its data segment selector. The APM device driver updates its internal data structures with the information passed in the registration structure. After the APM device driver registration is complete, the client device driver power management notification routine is active. The APM device driver calls the client device driver's power management notification routine to notify the client device driver of power management event messages for which it has registered. When the client device driver returns from the registration call, it must save the registration handle returned in the registration structure so that it can be passed on a subsequent deregistration call.

The client device driver can be notified when power management is enabled or disabled, when the APM BIOS power management default settings are restored, when a power management state change occurs, when the battery charge is low, and when power resumes after a suspend. The critical resume event notification occurs when power is removed without first notifying the operating system. The device ID field identifies the device being power managed. It is a word-length field where the first byte represents the type of device and the second byte represents which device of that type.

Implement a Power Management Notification Routine
The power management notification routine is the routine called by the APM device driver to notify the client device driver of power management events. The APM device driver calls the client device driver's power management notification routine with the es and bx registers containing the APM event message. The power management notification routine saves and restores any registers used with the exception of the ax register and the flags. The power management notification routine processes the power management event message, sets the return value in the ax register, and adjusts the carry flag accordingly.

For all APM event messages. except for the set power state</tt> message, the power management notification routine clears the carry flag and sets the AX register to zero indicating successful completion of the request. For the set power state</tt> message, the power management notification routine may return non-zero in the ax register and the carry flag set to indicate that the client device driver rejects the power state change. In this case, the APM device driver sends a normal resume event message to all other client device drivers whose notification routine had previously been called.

The APM event message consists of five words. The first word contains the power event type. A power event type of zero indicates that this packet is a power event notification. The second word contains the event message identifier. The event message identifier corresponds to a notification mask that was passed to the APM device driver on the power management notification routine registration call. The third word is a reserved field and contains zero. The fourth and fifth words contain zero unless the event message identifier contains the set power state event identifier. When the set power state event message identifier is set, then the fourth word contains the device identifier and the fifth word contains the power state.

Deregister a Power Management Notification Routine
If a client device driver chooses not to continue receiving power management events, it must deregister its power management notification routine with the APM device driver. The client device driver must call the APM device driver with the deregistration structure. In the deregistration structure, the client device driver passes to the APM device driver the function code (DeregisterDDRtn</tt>) and the registration handle. The registration handle is returned to the client device driver in the registration structure. The client device driver passes the registration structure in the es and bx registers to the APM device driver. When the APM device driver completes deregistration, the client device driver power management notification routine is no longer active. The APM device driver will no longer call the client device driver's power management notification routine to notify the client device driver of power management event messages for which it had previously registered.

Conclusion
For an OS/2 device driver to integrate the power management capabilities of its hardware into the operating system, the OS/2 device driver must register and handle power management notifications from the OS/2 APM device driver. This article provided an example of how to establish the communication between a client device driver and the APM device driver for the purpose of power management event notification.