You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
511 lines
15 KiB
511 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ospower.h
|
|
|
|
Abstract:
|
|
|
|
This contains the OS-shared power structures. These varify depending
|
|
on the OS that is being used
|
|
|
|
Author:
|
|
|
|
Stephane Plante (splante)
|
|
|
|
Environment:
|
|
|
|
NT Kernel Model Driver only
|
|
|
|
--*/
|
|
|
|
#ifndef _OSPOWER_H_
|
|
#define _OSPOWER_H_
|
|
|
|
//
|
|
// Makesure that the _DEVICE_EXTENSION structure is defined
|
|
//
|
|
struct _DEVICE_EXTENSION;
|
|
|
|
//
|
|
// These are the flags that can used with the Power Device Node
|
|
//
|
|
#define DEVICE_NODE_PRESENT 0x0001
|
|
#define DEVICE_NODE_INITIALIZED 0x0002
|
|
#define DEVICE_NODE_STA_UNKNOWN 0x0004
|
|
#define DEVICE_NODE_ON 0x0010
|
|
#define DEVICE_NODE_OVERRIDE_ON 0x0020
|
|
#define DEVICE_NODE_OVERRIDE_OFF 0x0040
|
|
#define DEVICE_NODE_ALWAYS_ON 0x0200
|
|
#define DEVICE_NODE_ALWAYS_OFF 0x0400
|
|
|
|
//
|
|
// These are fast macros
|
|
//
|
|
#define DEVICE_NODE_TURN_ON (DEVICE_NODE_OVERRIDE_ON | DEVICE_NODE_ALWAYS_ON)
|
|
#define DEVICE_NODE_TURN_OFF (DEVICE_NODE_OVERRIDE_OFF | DEVICE_NODE_ALWAYS_OFF)
|
|
|
|
//
|
|
// These flags are more for status of the device node. Note that the
|
|
// Hibernate Path flags requires special handling
|
|
//
|
|
#define DEVICE_NODE_FAIL 0x10000
|
|
#define DEVICE_NODE_HIBERNATE_PATH 0x20000
|
|
|
|
//
|
|
// These are the various request flags for device requests
|
|
//
|
|
#define DEVICE_REQUEST_DELAYED 0x00000001
|
|
#define DEVICE_REQUEST_NO_QUEUE 0x00000002
|
|
#define DEVICE_REQUEST_LOCK_DEVICE 0x00000004
|
|
#define DEVICE_REQUEST_UNLOCK_DEVICE 0x00000008
|
|
#define DEVICE_REQUEST_LOCK_HIBER 0x00000010
|
|
#define DEVICE_REQUEST_UNLOCK_HIBER 0x00000020
|
|
#define DEVICE_REQUEST_HAS_CANCEL 0x00000040
|
|
#define DEVICE_REQUEST_UPDATE_HW_PROFILE 0x00000080
|
|
#define DEVICE_REQUEST_TO_SYNC_QUEUE 0x00000100
|
|
|
|
//
|
|
// These values are used with WorkDone variables and InterlockedXXX
|
|
// functions to synchronize the various phases of DevicePowerManagement
|
|
//
|
|
typedef enum _WORK_DONE {
|
|
WORK_DONE_COMPLETE = 0,
|
|
WORK_DONE_PENDING,
|
|
WORK_DONE_FAILURE,
|
|
WORK_DONE_STEP_0,
|
|
WORK_DONE_STEP_1,
|
|
WORK_DONE_STEP_2,
|
|
WORK_DONE_STEP_3,
|
|
WORK_DONE_STEP_4,
|
|
WORK_DONE_STEP_5,
|
|
WORK_DONE_STEP_6,
|
|
WORK_DONE_STEP_7,
|
|
WORK_DONE_STEP_8,
|
|
WORK_DONE_STEP_9,
|
|
WORK_DONE_STEP_10,
|
|
WORK_DONE_STEP_11,
|
|
WORK_DONE_STEP_12,
|
|
WORK_DONE_STEP_13,
|
|
WORK_DONE_STEP_14,
|
|
WORK_DONE_STEP_15,
|
|
WORK_DONE_STEP_16,
|
|
WORK_DONE_STEP_17,
|
|
WORK_DONE_STEP_18,
|
|
WORK_DONE_STEP_19,
|
|
WORK_DONE_STEP_20,
|
|
WORK_DONE_STEP_21,
|
|
WORK_DONE_STEP_22,
|
|
WORK_DONE_STEP_23,
|
|
WORK_DONE_STEP_24,
|
|
WORK_DONE_STEP_25,
|
|
WORK_DONE_STEP_26,
|
|
} WORK_DONE;
|
|
|
|
//
|
|
// This describes a single power device node
|
|
//
|
|
// This used to be called a POWERDEVICEDEPENCIES
|
|
// but that was to hard to type out
|
|
//
|
|
typedef struct _ACPI_POWER_DEVICE_NODE {
|
|
|
|
//
|
|
// Keeps the things in order
|
|
//
|
|
LIST_ENTRY ListEntry;
|
|
|
|
//
|
|
// This define the current device state and flags
|
|
//
|
|
union{
|
|
ULONGLONG Flags;
|
|
struct {
|
|
ULONGLONG Present:1;
|
|
ULONGLONG Initialized:1;
|
|
ULONGLONG StatusUnknown:1;
|
|
ULONGLONG On:1;
|
|
ULONGLONG OverrideOn:1;
|
|
ULONGLONG OverrideOff:1;
|
|
ULONGLONG AlwaysOn:1;
|
|
ULONGLONG AlwaysOff:1;
|
|
ULONGLONG Reserved1:5;
|
|
ULONGLONG Failed:1;
|
|
ULONGLONG HibernatePath:1;
|
|
ULONGLONG Reserved2:49;
|
|
} UFlags;
|
|
};
|
|
|
|
//
|
|
// How many references there are to the node
|
|
//
|
|
ULONG UseCounts;
|
|
|
|
//
|
|
// The name space object associated with the power node
|
|
//
|
|
PNSOBJ PowerObject;
|
|
|
|
//
|
|
// The resource order
|
|
//
|
|
UCHAR ResourceOrder;
|
|
|
|
//
|
|
// The supported system level
|
|
//
|
|
SYSTEM_POWER_STATE SystemLevel;
|
|
|
|
//
|
|
// This is the head of a list of DPNs that are associated with this
|
|
// PDN
|
|
//
|
|
LIST_ENTRY DevicePowerListHead;
|
|
|
|
//
|
|
// This reflects the amount of work that has been done on the
|
|
// DeviceNode
|
|
//
|
|
ULONG WorkDone;
|
|
|
|
//
|
|
// This is a pointer to the on function
|
|
//
|
|
PNSOBJ PowerOnObject;
|
|
|
|
//
|
|
// This is a pointer to the off function
|
|
//
|
|
PNSOBJ PowerOffObject;
|
|
|
|
//
|
|
// This is a pointer to the sta function
|
|
//
|
|
PNSOBJ PowerStaObject;
|
|
|
|
} ACPI_POWER_DEVICE_NODE, *PACPI_POWER_DEVICE_NODE;
|
|
|
|
//
|
|
// This describes a single power node for a devices list of power reqs
|
|
//
|
|
// This was known as a POWER_RES_LIST_NODE. Again that was a pain
|
|
// to type and it didn't quite do what I need it to do
|
|
//
|
|
typedef struct _ACPI_DEVICE_POWER_NODE {
|
|
|
|
//
|
|
// Contains pointer to next element
|
|
//
|
|
struct _ACPI_DEVICE_POWER_NODE *Next;
|
|
|
|
//
|
|
// Pointer to actual power resource
|
|
//
|
|
PACPI_POWER_DEVICE_NODE PowerNode;
|
|
|
|
//
|
|
// This is the system level that is supported for this node
|
|
//
|
|
SYSTEM_POWER_STATE SystemState;
|
|
|
|
//
|
|
// This is the device power level of the device that this node
|
|
// is associated with
|
|
//
|
|
DEVICE_POWER_STATE AssociatedDeviceState;
|
|
|
|
//
|
|
// This determines if the Device Power Node is on the wake path
|
|
// or not
|
|
//
|
|
BOOLEAN WakePowerResource;
|
|
|
|
//
|
|
// This is a pointer back to the DeviceExtension
|
|
//
|
|
struct _DEVICE_EXTENSION *DeviceExtension;
|
|
|
|
//
|
|
// This is the list that is used to link all of the DPN attached
|
|
// to a single PDN.
|
|
//
|
|
LIST_ENTRY DevicePowerListEntry;
|
|
|
|
} ACPI_DEVICE_POWER_NODE, *PACPI_DEVICE_POWER_NODE;
|
|
|
|
//
|
|
// This callback is used for handling power requests which must be
|
|
// processed through the main power DPC. Win9x does not use this
|
|
// approach to power managament
|
|
//
|
|
typedef VOID ( *PACPI_POWER_CALLBACK )(PDEVICE_EXTENSION, PVOID, NTSTATUS);
|
|
|
|
typedef enum {
|
|
AcpiPowerRequestDevice = 0,
|
|
AcpiPowerRequestSystem,
|
|
AcpiPowerRequestWaitWake,
|
|
AcpiPowerRequestWarmEject,
|
|
AcpiPowerRequestSynchronize,
|
|
AcpiPowerRequestMaximum
|
|
} ACPI_POWER_REQUEST_TYPE;
|
|
|
|
//
|
|
// This is how we describe the power requests that we have outstanding
|
|
// on a single device extension
|
|
//
|
|
typedef struct _ACPI_POWER_REQUEST {
|
|
|
|
//
|
|
// This is the ListEntry used to chain all the PowerRequests on
|
|
// the same queue
|
|
//
|
|
LIST_ENTRY ListEntry;
|
|
|
|
//
|
|
// This is the ListEntry used to chain all the PowerRequests on the
|
|
// same device/irp. These requests are processed in serial
|
|
//
|
|
LIST_ENTRY SerialListEntry;
|
|
|
|
//
|
|
// This is the signature block --- if this is not the value we expect,
|
|
// then we assume the request is garbage
|
|
//
|
|
ULONG Signature;
|
|
|
|
//
|
|
// This is a pointer to the associated DeviceExtension
|
|
//
|
|
struct _DEVICE_EXTENSION *DeviceExtension;
|
|
|
|
//
|
|
// This is the type of request
|
|
//
|
|
ACPI_POWER_REQUEST_TYPE RequestType;
|
|
|
|
//
|
|
// Has this request failed already?
|
|
//
|
|
BOOLEAN FailedOnce;
|
|
|
|
//
|
|
// Holds information about what we need to do for the various
|
|
// requests
|
|
//
|
|
union {
|
|
|
|
//
|
|
// This is the Information required by a DevicePower request
|
|
//
|
|
struct {
|
|
ULONG Flags;
|
|
DEVICE_POWER_STATE DevicePowerState;
|
|
} DevicePowerRequest;
|
|
|
|
//
|
|
// This is the Information required by a SystemPower request
|
|
//
|
|
struct {
|
|
SYSTEM_POWER_STATE SystemPowerState;
|
|
POWER_ACTION SystemPowerAction;
|
|
} SystemPowerRequest;
|
|
|
|
//
|
|
// This is the Information required by a WaitWake request
|
|
//
|
|
struct {
|
|
ULONG Flags;
|
|
SYSTEM_POWER_STATE SystemPowerState;
|
|
} WaitWakeRequest;
|
|
|
|
//
|
|
// This is the information required by the WarmEject request
|
|
//
|
|
struct {
|
|
ULONG Flags;
|
|
SYSTEM_POWER_STATE EjectPowerState;
|
|
} EjectPowerRequest;
|
|
|
|
//
|
|
// This is the information required by the Synchronize request
|
|
//
|
|
struct {
|
|
ULONG Flags;
|
|
} SynchronizePowerRequest;
|
|
|
|
//
|
|
// Make the flags easy to access...
|
|
//
|
|
struct {
|
|
ULONG Delayed:1;
|
|
ULONG NoQueue:1;
|
|
ULONG LockDevice:1;
|
|
ULONG UnlockDevice:1;
|
|
ULONG LockHiber:1;
|
|
ULONG UnlockHiber:1;
|
|
ULONG HasCancel:1;
|
|
ULONG UpdateProfile:1;
|
|
ULONG SyncQueue:1;
|
|
ULONG Reserved:23;
|
|
} UFlags;
|
|
|
|
} u;
|
|
|
|
//
|
|
// This is the routine that will get called when the request is
|
|
// done
|
|
//
|
|
PACPI_POWER_CALLBACK CallBack;
|
|
|
|
//
|
|
// This is the context that will be passed to the completion routine
|
|
//
|
|
PVOID Context;
|
|
|
|
//
|
|
// This defines the amount of work that has been done on the
|
|
// request. This can only be touched with an InterlockedXXX call
|
|
//
|
|
ULONG WorkDone;
|
|
|
|
//
|
|
// This is the next value for WorkDone, if we have been successfull
|
|
//
|
|
ULONG NextWorkDone;
|
|
|
|
//
|
|
// Since we sometimes need to get data back from the interpreter,
|
|
// we need some place to store that data
|
|
//
|
|
OBJDATA ResultData;
|
|
|
|
//
|
|
// This is the result of the request
|
|
//
|
|
NTSTATUS Status;
|
|
|
|
} ACPI_POWER_REQUEST, *PACPI_POWER_REQUEST;
|
|
|
|
//
|
|
// Define the power information
|
|
//
|
|
// This was known as a DEVICEPOWERDEPENDENCIES. But that
|
|
// was incredibly confusing and not quite suited to my needs
|
|
//
|
|
typedef struct _ACPI_POWER_INFO {
|
|
|
|
//
|
|
// Context is the OS object we are associated with, either a
|
|
// device node or a device extension
|
|
//
|
|
PVOID Context;
|
|
|
|
//
|
|
// Current State of the device
|
|
//
|
|
DEVICE_POWER_STATE PowerState;
|
|
|
|
//
|
|
// This is the notify callback (and context) for the current device
|
|
//
|
|
PDEVICE_NOTIFY_CALLBACK DeviceNotifyHandler;
|
|
PVOID HandlerContext;
|
|
|
|
//
|
|
// This is an array of powerNodes, which point to Wake, D0, D1, and D2,
|
|
// respectively
|
|
//
|
|
PACPI_DEVICE_POWER_NODE PowerNode[PowerDeviceD2+1];
|
|
|
|
//
|
|
// This is an array of PowerObjects, which represent _PS0 to _PS3
|
|
// and _PRW
|
|
//
|
|
PNSOBJ PowerObject[PowerDeviceD3+1];
|
|
|
|
//
|
|
// This is the Enable bit for the GPE mask for Wake support
|
|
//
|
|
ULONG WakeBit;
|
|
|
|
//
|
|
// We want to remember the devices capabilities so that we can dump
|
|
// it out at some later point in time.
|
|
//
|
|
DEVICE_POWER_STATE DevicePowerMatrix[PowerSystemMaximum];
|
|
|
|
//
|
|
// This is the deepest sleep level that can used and at the same
|
|
// time, have the device wake the system
|
|
//
|
|
SYSTEM_POWER_STATE SystemWakeLevel;
|
|
|
|
//
|
|
// This is the deepest power level that the device can be in and
|
|
// still wake up the system
|
|
//
|
|
DEVICE_POWER_STATE DeviceWakeLevel;
|
|
|
|
//
|
|
// This is the current desired state of the device
|
|
//
|
|
DEVICE_POWER_STATE DesiredPowerState;
|
|
|
|
//
|
|
// This keeps track of the number of times the device has
|
|
// been enabled for Wake Support. On a 0-1 transition, we
|
|
// must run _PSW(1). On a 1-0 transition, we must run _PSW(0).
|
|
//
|
|
ULONG WakeSupportCount;
|
|
|
|
//
|
|
// This is the list of pending _PSW calls
|
|
//
|
|
LIST_ENTRY WakeSupportList;
|
|
|
|
//
|
|
// This is a pointer associated with the current PowerRequest
|
|
//
|
|
PACPI_POWER_REQUEST CurrentPowerRequest;
|
|
|
|
//
|
|
// This is the queue that is used to link the PowerRequests associated
|
|
// with this device. Note: that this list is *only* for DevicePower
|
|
// requests with no associated Irps
|
|
//
|
|
LIST_ENTRY PowerRequestListEntry;
|
|
|
|
//
|
|
// Remember what we support so that we can answer the QueryCapibilities
|
|
//
|
|
ULONG SupportDeviceD1 : 1;
|
|
ULONG SupportDeviceD2 : 1;
|
|
ULONG SupportWakeFromD0 : 1;
|
|
ULONG SupportWakeFromD1 : 1;
|
|
ULONG SupportWakeFromD2 : 1;
|
|
ULONG SupportWakeFromD3 : 1;
|
|
ULONG Reserved :26;
|
|
|
|
} ACPI_POWER_INFO, *PACPI_POWER_INFO;
|
|
|
|
//
|
|
// Find the power information for the given node
|
|
//
|
|
PACPI_POWER_INFO
|
|
OSPowerFindPowerInfo(
|
|
PNSOBJ AcpiObject
|
|
);
|
|
|
|
PACPI_POWER_INFO
|
|
OSPowerFindPowerInfoByContext(
|
|
PVOID Context
|
|
);
|
|
|
|
PACPI_POWER_DEVICE_NODE
|
|
OSPowerFindPowerNode(
|
|
PNSOBJ PowerObject
|
|
);
|
|
|
|
#endif
|