Alex Ionescu <ionucu@videotron.ca>
[reactos.git] / reactos / ntoskrnl / po / power.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/po/power.c
6 * PURPOSE: Power Manager
7 *
8 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 */
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <internal/debug.h>
14
15 PDEVICE_NODE PopSystemPowerDeviceNode = NULL;
16 BOOLEAN PopAcpiPresent = FALSE;
17
18 /*
19 * @implemented
20 */
21 NTSTATUS
22 STDCALL
23 PoCallDriver(
24 IN PDEVICE_OBJECT DeviceObject,
25 IN OUT PIRP Irp)
26 {
27 NTSTATUS Status;
28
29 Status = IoCallDriver(DeviceObject, Irp);
30
31 return Status;
32 }
33
34 /*
35 * @unimplemented
36 */
37 PULONG
38 STDCALL
39 PoRegisterDeviceForIdleDetection(
40 IN PDEVICE_OBJECT DeviceObject,
41 IN ULONG ConservationIdleTime,
42 IN ULONG PerformanceIdleTime,
43 IN DEVICE_POWER_STATE State)
44 {
45 return NULL;
46 }
47
48 /*
49 * @unimplemented
50 */
51 PVOID
52 STDCALL
53 PoRegisterSystemState(
54 IN PVOID StateHandle,
55 IN EXECUTION_STATE Flags)
56 {
57 return NULL;
58 }
59
60 /*
61 * @unimplemented
62 */
63 NTSTATUS
64 STDCALL
65 PoRequestPowerIrp(
66 IN PDEVICE_OBJECT DeviceObject,
67 IN UCHAR MinorFunction,
68 IN POWER_STATE PowerState,
69 IN PREQUEST_POWER_COMPLETE CompletionFunction,
70 IN PVOID Context,
71 OUT PIRP *Irp OPTIONAL)
72 {
73 return STATUS_NOT_IMPLEMENTED;
74 }
75
76 VOID
77 STDCALL
78 PoSetDeviceBusy(
79 PULONG IdlePointer)
80 {
81 }
82
83 /*
84 * @unimplemented
85 */
86 POWER_STATE
87 STDCALL
88 PoSetPowerState(
89 IN PDEVICE_OBJECT DeviceObject,
90 IN POWER_STATE_TYPE Type,
91 IN POWER_STATE State)
92 {
93 POWER_STATE ps;
94
95 ASSERT_IRQL(DISPATCH_LEVEL);
96
97 ps.SystemState = PowerSystemWorking; // Fully on
98 ps.DeviceState = PowerDeviceD0; // Fully on
99
100 return ps;
101 }
102
103 /*
104 * @unimplemented
105 */
106 VOID
107 STDCALL
108 PoSetSystemState(
109 IN EXECUTION_STATE Flags)
110 {
111 }
112
113 /*
114 * @unimplemented
115 */
116 VOID
117 STDCALL
118 PoStartNextPowerIrp(
119 IN PIRP Irp)
120 {
121 }
122
123 /*
124 * @unimplemented
125 */
126 VOID
127 STDCALL
128 PoUnregisterSystemState(
129 IN PVOID StateHandle)
130 {
131 }
132
133 NTSTATUS
134 PopSetSystemPowerState(
135 SYSTEM_POWER_STATE PowerState)
136 {
137 IO_STATUS_BLOCK IoStatusBlock;
138 PDEVICE_OBJECT DeviceObject;
139 PIO_STACK_LOCATION IrpSp;
140 PDEVICE_OBJECT Fdo;
141 NTSTATUS Status;
142 KEVENT Event;
143 PIRP Irp;
144
145 if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
146
147 Status = IopGetSystemPowerDeviceObject(&DeviceObject);
148 if (!NT_SUCCESS(Status)) {
149 CPRINT("No system power driver available\n");
150 return STATUS_UNSUCCESSFUL;
151 }
152
153 Fdo = IoGetAttachedDeviceReference(DeviceObject);
154
155 if (Fdo == DeviceObject)
156 {
157 DPRINT("An FDO was not attached\n");
158 return STATUS_UNSUCCESSFUL;
159 }
160
161 KeInitializeEvent(&Event,
162 NotificationEvent,
163 FALSE);
164
165 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_POWER,
166 Fdo,
167 NULL,
168 0,
169 NULL,
170 &Event,
171 &IoStatusBlock);
172
173 IrpSp = IoGetNextIrpStackLocation(Irp);
174 IrpSp->MinorFunction = IRP_MN_SET_POWER;
175 IrpSp->Parameters.Power.Type = SystemPowerState;
176 IrpSp->Parameters.Power.State.SystemState = PowerState;
177
178 Status = PoCallDriver(Fdo, Irp);
179 if (Status == STATUS_PENDING)
180 {
181 KeWaitForSingleObject(&Event,
182 Executive,
183 KernelMode,
184 FALSE,
185 NULL);
186 Status = IoStatusBlock.Status;
187 }
188
189 ObDereferenceObject(Fdo);
190
191 return Status;
192 }
193
194 VOID
195 INIT_FUNCTION
196 PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock,
197 BOOLEAN ForceAcpiDisable)
198 {
199 /* Set the ACPI State to False if it's been forced that way */
200 if (ForceAcpiDisable) PopAcpiPresent = FALSE;
201
202 /* Otherwise check the LoaderBlock's Flag */
203 PopAcpiPresent = LoaderBlock->Flags & MB_FLAGS_ACPI_TABLE;
204 }
205
206 /*
207 * @unimplemented
208 */
209 NTSTATUS
210 STDCALL
211 NtInitiatePowerAction (
212 IN POWER_ACTION SystemAction,
213 IN SYSTEM_POWER_STATE MinSystemState,
214 IN ULONG Flags,
215 IN BOOLEAN Asynchronous)
216 {
217 UNIMPLEMENTED;
218 return STATUS_NOT_IMPLEMENTED;
219 }
220
221 /*
222 * @unimplemented
223 */
224 NTSTATUS
225 STDCALL
226 NtPowerInformation(
227 IN POWER_INFORMATION_LEVEL PowerInformationLevel,
228 IN PVOID InputBuffer OPTIONAL,
229 IN ULONG InputBufferLength,
230 OUT PVOID OutputBuffer OPTIONAL,
231 IN ULONG OutputBufferLength
232 )
233 {
234 NTSTATUS Status;
235
236 PAGED_CODE();
237
238 DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
239 "InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
240 PowerInformationLevel,
241 InputBuffer, InputBufferLength,
242 OutputBuffer, OutputBufferLength);
243 switch (PowerInformationLevel)
244 {
245 case SystemBatteryState:
246 {
247 PSYSTEM_BATTERY_STATE BatteryState = (PSYSTEM_BATTERY_STATE)OutputBuffer;
248
249 if (InputBuffer != NULL)
250 return STATUS_INVALID_PARAMETER;
251 if (OutputBufferLength < sizeof(SYSTEM_BATTERY_STATE))
252 return STATUS_BUFFER_TOO_SMALL;
253
254 /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */
255 RtlZeroMemory(BatteryState, sizeof(SYSTEM_BATTERY_STATE));
256 BatteryState->EstimatedTime = (ULONG)-1;
257
258 Status = STATUS_SUCCESS;
259 break;
260 }
261
262 default:
263 Status = STATUS_NOT_IMPLEMENTED;
264 DPRINT1("PowerInformationLevel 0x%x is UNIMPLEMENTED! Have a nice day.\n",
265 PowerInformationLevel);
266 for (;;);
267 break;
268 }
269
270 return Status;
271 }
272
273 /* EOF */