The power handler functions, XXX_PowerUp (Device Manager) and XXX_PowerDown (Device Manager), execute in kernel mode, and they cannot be pre-empted.
Most function calls are not allowed in this mode. In general, the power handler functions are not allowed to make system calls. The following list shows how the operating system (OS) handles a system call from the XXX_PowerUp function or the XXX_PowerDown function:
- The OS outputs the following to the kernel debug port.
- The OS calls the lpNKHaltSystem function.
By default, lpNKHaltSystem halts the system. You can override this default behavior by initializing lpNKHaltSystem to point to your own function.
You can optionally use DEBUGMSG, RETAILMSG, CeSetPowerOnEvent, and SetInterruptEvent from the power handler functions. For more information about the DEBUGMSG and RETAILMSG macros, see Debugging Macros.
Use the LockPages function to lock in memory all code and data pages accessed by a power handler function. For example, if your device driver executes from RAM that has been paged from NAND flash or decompressed from storage, do not use the DEVFLAGS_LOADLIBRARY flag. This flag allows the code pages of your device driver to be discarded from RAM and paged in as needed. If you are accessing a memory-mapped file, make sure that those data pages have been locked into RAM with the LockPages function.
The power handler functions should never generate an exception. The following list shows some ways that exceptions can be generated:
- Dereferencing a null pointer.
- Dividing by zero. This generates an exception on most microprocessors.
- Explicitly raising an SEH or C++ exception.
- A page-fault.
The following list shows how the OS handles an exception generated from a power handler function.
- The OS outputs the following string to the kernel debug port.
- The OS calls the lpNKHaltSystem function.
By default, lpNKHaltSystem halts the system. You can override this default behavior by initializing lpNKHaltSystem to point to your own function.
The OS invokes this function to restore power to a device. The OS might call this function when it is about to leave a power-save mode. The driver might also receive a separate power-up request from the Power Manager before the XXX_PowerUp function executes. For example, IOCTL_POWER_SET might request a D3 or D4 power state.
Microsoft recommends using Power Manager and the power management IOCTLs to manage power to your device. For more information, see Power Management IOCTLs.
If you do not use Power Manager, this function should only perform the required hardware-level recovery. XXX_PowerUp should not call any functions that might cause it to block, and it should return as quickly as possible. One strategy for returning quickly is to have XXX_PowerUp set a global variable to indicate that a power loss occurred. If full recovery is time consuming or requires OS services that are not available in power callbacks, this function should signal a driver thread to complete the process. XXX_PowerUp and XXX_PowerDown callbacks can use CeSetPowerOnEvent to signal to arbitrary driver threads that a suspend or resume cycle has occurred. To signal the driver's interrupt service thread, use SetInterruptEvent instead.
Device Manager uses the XXX prefix as a placeholder. When implementing the stream interface, replace XXX with a prefix appropriate for your implementation or use undecorated entry point names in conjunction with DEVFLAGS_NAKEDENTRIES. For more information about other valid Flags values, see ActivateDeviceEx.
By default, interrupts are on during stream interface driver entry points.