3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/po/power.c
6 * PURPOSE: Power Manager
8 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * Hervé Poussineau (hpoussin@reactos.com)
14 #include <internal/debug.h>
16 typedef struct _REQUEST_POWER_ITEM
18 PREQUEST_POWER_COMPLETE CompletionRoutine
;
19 POWER_STATE PowerState
;
21 } REQUEST_POWER_ITEM
, *PREQUEST_POWER_ITEM
;
23 PDEVICE_NODE PopSystemPowerDeviceNode
= NULL
;
24 BOOLEAN PopAcpiPresent
= FALSE
;
32 IN PDEVICE_OBJECT DeviceObject
,
37 Status
= IoCallDriver(DeviceObject
, Irp
);
47 PoRegisterDeviceForIdleDetection(
48 IN PDEVICE_OBJECT DeviceObject
,
49 IN ULONG ConservationIdleTime
,
50 IN ULONG PerformanceIdleTime
,
51 IN DEVICE_POWER_STATE State
)
61 PoRegisterSystemState(
63 IN EXECUTION_STATE Flags
)
70 PopRequestPowerIrpCompletion(
71 IN PDEVICE_OBJECT DeviceObject
,
75 PIO_STACK_LOCATION Stack
;
76 PREQUEST_POWER_ITEM RequestPowerItem
;
78 Stack
= IoGetNextIrpStackLocation(Irp
);
79 RequestPowerItem
= (PREQUEST_POWER_ITEM
)Context
;
81 RequestPowerItem
->CompletionRoutine(
84 RequestPowerItem
->PowerState
,
85 RequestPowerItem
->Context
,
88 ExFreePool(&Irp
->IoStatus
);
90 return STATUS_SUCCESS
;
99 IN PDEVICE_OBJECT DeviceObject
,
100 IN UCHAR MinorFunction
,
101 IN POWER_STATE PowerState
,
102 IN PREQUEST_POWER_COMPLETE CompletionFunction
,
104 OUT PIRP
*pIrp OPTIONAL
)
106 PDEVICE_OBJECT TopDeviceObject
;
107 PIO_STACK_LOCATION Stack
;
109 PIO_STATUS_BLOCK IoStatusBlock
;
110 PREQUEST_POWER_ITEM RequestPowerItem
;
113 if (MinorFunction
!= IRP_MN_QUERY_POWER
114 && MinorFunction
!= IRP_MN_SET_POWER
115 && MinorFunction
!= IRP_MN_WAIT_WAKE
)
116 return STATUS_INVALID_PARAMETER_2
;
118 RequestPowerItem
= ExAllocatePool(NonPagedPool
, sizeof(REQUEST_POWER_ITEM
));
119 if (!RequestPowerItem
)
120 return STATUS_INSUFFICIENT_RESOURCES
;
121 IoStatusBlock
= ExAllocatePool(NonPagedPool
, sizeof(IO_STATUS_BLOCK
));
124 ExFreePool(RequestPowerItem
);
125 return STATUS_INSUFFICIENT_RESOURCES
;
128 /* Always call the top of the device stack */
129 TopDeviceObject
= IoGetAttachedDeviceReference(DeviceObject
);
131 Irp
= IoBuildSynchronousFsdRequest(
141 ExFreePool(RequestPowerItem
);
142 ExFreePool(IoStatusBlock
);
143 return STATUS_INSUFFICIENT_RESOURCES
;
146 /* POWER IRPs are always initialized with a status code of
147 STATUS_NOT_IMPLEMENTED */
148 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
149 Irp
->IoStatus
.Information
= 0;
151 Stack
= IoGetNextIrpStackLocation(Irp
);
152 Stack
->MinorFunction
= MinorFunction
;
153 if (MinorFunction
== IRP_MN_WAIT_WAKE
)
154 Stack
->Parameters
.WaitWake
.PowerState
= PowerState
.SystemState
;
156 Stack
->Parameters
.WaitWake
.PowerState
= PowerState
.DeviceState
;
158 RequestPowerItem
->CompletionRoutine
= CompletionFunction
;
159 RequestPowerItem
->PowerState
= PowerState
;
160 RequestPowerItem
->Context
= Context
;
165 IoSetCompletionRoutine(Irp
, PopRequestPowerIrpCompletion
, RequestPowerItem
, TRUE
, TRUE
, TRUE
);
166 Status
= IoCallDriver(TopDeviceObject
, Irp
);
168 /* Always return STATUS_PENDING. The completion routine
169 * will call CompletionFunction and complete the Irp.
171 return STATUS_PENDING
;
187 IN PDEVICE_OBJECT DeviceObject
,
188 IN POWER_STATE_TYPE Type
,
189 IN POWER_STATE State
)
193 ASSERT_IRQL(DISPATCH_LEVEL
);
195 ps
.SystemState
= PowerSystemWorking
; // Fully on
196 ps
.DeviceState
= PowerDeviceD0
; // Fully on
207 IN EXECUTION_STATE Flags
)
226 PoUnregisterSystemState(
227 IN PVOID StateHandle
)
233 PopSetSystemPowerState(
234 SYSTEM_POWER_STATE PowerState
)
236 IO_STATUS_BLOCK IoStatusBlock
;
237 PDEVICE_OBJECT DeviceObject
;
238 PIO_STACK_LOCATION IrpSp
;
244 if (!PopAcpiPresent
) return STATUS_NOT_IMPLEMENTED
;
246 Status
= IopGetSystemPowerDeviceObject(&DeviceObject
);
247 if (!NT_SUCCESS(Status
)) {
248 CPRINT("No system power driver available\n");
249 return STATUS_UNSUCCESSFUL
;
252 Fdo
= IoGetAttachedDeviceReference(DeviceObject
);
254 if (Fdo
== DeviceObject
)
256 DPRINT("An FDO was not attached\n");
257 return STATUS_UNSUCCESSFUL
;
260 KeInitializeEvent(&Event
,
264 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_POWER
,
272 IrpSp
= IoGetNextIrpStackLocation(Irp
);
273 IrpSp
->MinorFunction
= IRP_MN_SET_POWER
;
274 IrpSp
->Parameters
.Power
.Type
= SystemPowerState
;
275 IrpSp
->Parameters
.Power
.State
.SystemState
= PowerState
;
277 Status
= PoCallDriver(Fdo
, Irp
);
278 if (Status
== STATUS_PENDING
)
280 KeWaitForSingleObject(&Event
,
285 Status
= IoStatusBlock
.Status
;
288 ObDereferenceObject(Fdo
);
296 PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock
,
297 BOOLEAN ForceAcpiDisable
)
299 if (ForceAcpiDisable
)
301 /* Set the ACPI State to False if it's been forced that way */
302 PopAcpiPresent
= FALSE
;
306 /* Otherwise check the LoaderBlock's Flag */
307 PopAcpiPresent
= (LoaderBlock
->Flags
& MB_FLAGS_ACPI_TABLE
) ? TRUE
: FALSE
;
316 NtInitiatePowerAction (
317 IN POWER_ACTION SystemAction
,
318 IN SYSTEM_POWER_STATE MinSystemState
,
320 IN BOOLEAN Asynchronous
)
323 return STATUS_NOT_IMPLEMENTED
;
332 IN POWER_INFORMATION_LEVEL PowerInformationLevel
,
333 IN PVOID InputBuffer OPTIONAL
,
334 IN ULONG InputBufferLength
,
335 OUT PVOID OutputBuffer OPTIONAL
,
336 IN ULONG OutputBufferLength
343 DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
344 "InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
345 PowerInformationLevel
,
346 InputBuffer
, InputBufferLength
,
347 OutputBuffer
, OutputBufferLength
);
348 switch (PowerInformationLevel
)
350 case SystemBatteryState
:
352 PSYSTEM_BATTERY_STATE BatteryState
= (PSYSTEM_BATTERY_STATE
)OutputBuffer
;
354 if (InputBuffer
!= NULL
)
355 return STATUS_INVALID_PARAMETER
;
356 if (OutputBufferLength
< sizeof(SYSTEM_BATTERY_STATE
))
357 return STATUS_BUFFER_TOO_SMALL
;
359 /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */
360 RtlZeroMemory(BatteryState
, sizeof(SYSTEM_BATTERY_STATE
));
361 BatteryState
->EstimatedTime
= (ULONG
)-1;
363 Status
= STATUS_SUCCESS
;
368 Status
= STATUS_NOT_IMPLEMENTED
;
369 DPRINT1("PowerInformationLevel 0x%x is UNIMPLEMENTED! Have a nice day.\n",
370 PowerInformationLevel
);
381 PoQueueShutdownWorkItem(
382 IN PWORK_QUEUE_ITEM WorkItem
387 DPRINT1("PoQueueShutdownWorkItem(%p)\n", WorkItem
);
389 return STATUS_NOT_IMPLEMENTED
;