e4b3297a9beb2d26b79d974904d958163d152e3d
[reactos.git] / reactos / drivers / bus / acpi / cmbatt / cmexec.c
1 /*
2 * PROJECT: ReactOS ACPI-Compliant Control Method Battery
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/drivers/bus/acpi/cmbatt/cmexec.c
5 * PURPOSE: ACPI Method Execution/Evaluation Glue
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "cmbatt.h"
12
13 /* FUNCTIONS ******************************************************************/
14
15 NTSTATUS
16 NTAPI
17 GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument,
18 OUT PULONG Value)
19 {
20 NTSTATUS Status;
21
22 /* Must have an integer */
23 if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER)
24 {
25 /* Not an integer, fail */
26 Status = STATUS_ACPI_INVALID_DATA;
27 if (CmBattDebug & 0x4C)
28 DbgPrint("GetDwordElement: Object contained wrong data type - %d\n",
29 Argument->Type);
30 }
31 else
32 {
33 /* Read the integer value */
34 *Value = Argument->Argument;
35 Status = STATUS_SUCCESS;
36 }
37
38 /* Return status */
39 return Status;
40 }
41
42 NTSTATUS
43 NTAPI
44 GetStringElement(IN PACPI_METHOD_ARGUMENT Argument,
45 OUT PCHAR Value)
46 {
47 NTSTATUS Status;
48
49 /* Must have a string of buffer */
50 if ((Argument->Type == ACPI_METHOD_ARGUMENT_STRING) ||
51 (Argument->Type == ACPI_METHOD_ARGUMENT_BUFFER))
52 {
53 /* String must be less than 256 characters */
54 if (Argument->DataLength < 256)
55 {
56 /* Copy the buffer */
57 RtlCopyMemory(Value, Argument->Data, Argument->DataLength);
58 Status = STATUS_SUCCESS;
59 }
60 else
61 {
62 /* The buffer is too small (the string is too large) */
63 Status = STATUS_BUFFER_TOO_SMALL;
64 if (CmBattDebug & 0x4C)
65 DbgPrint("GetStringElement: return buffer not big enough - %d\n", Argument->DataLength);
66 }
67 }
68 else
69 {
70 /* Not valid string data */
71 Status = STATUS_ACPI_INVALID_DATA;
72 if (CmBattDebug & 0x4C)
73 DbgPrint("GetStringElement: Object contained wrong data type - %d\n", Argument->Type);
74 }
75
76 /* Return the status */
77 return Status;
78 }
79
80 NTSTATUS
81 NTAPI
82 CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject,
83 IN ULONG IoControlCode,
84 IN PVOID InputBuffer,
85 IN ULONG InputBufferLength,
86 IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,
87 IN ULONG OutputBufferLength)
88 {
89 PIRP Irp;
90 NTSTATUS Status;
91 KEVENT Event;
92 IO_STATUS_BLOCK IoStatusBlock;
93 PAGED_CODE();
94
95 /* Initialize our wait event */
96 KeInitializeEvent(&Event, SynchronizationEvent, 0);
97
98 /* Allocate the IRP */
99 Irp = IoBuildDeviceIoControlRequest(IoControlCode,
100 DeviceObject,
101 InputBuffer,
102 InputBufferLength,
103 OutputBuffer,
104 OutputBufferLength,
105 0,
106 &Event,
107 &IoStatusBlock);
108 if (!Irp)
109 {
110 /* No IRP, fail */
111 if (CmBattDebug & 0x4C)
112 DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n");
113 return STATUS_INSUFFICIENT_RESOURCES;
114 }
115
116 /* Call ACPI */
117 if (CmBattDebug & 0x40)
118 DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n",
119 Irp, KeGetCurrentThread());
120 Status = IoCallDriver(DeviceObject, Irp);
121 if (Status == STATUS_PENDING)
122 {
123 /* Wait for completion */
124 KeWaitForSingleObject(&Event,
125 Executive,
126 KernelMode,
127 FALSE,
128 NULL);
129 Status = Irp->IoStatus.Status;
130 }
131
132 /* Check if caller wanted output */
133 if (OutputBuffer)
134 {
135 /* Make sure it's valid ACPI output buffer */
136 if ((OutputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) ||
137 !(OutputBuffer->Count))
138 {
139 /* It isn't, so set failure code */
140 Status = STATUS_ACPI_INVALID_DATA;
141 }
142 }
143
144 /* Return status */
145 if (CmBattDebug & 0x40)
146 DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n",
147 Irp, Status, KeGetCurrentThread());
148 return Status;
149 }
150
151 NTSTATUS
152 NTAPI
153 CmBattGetPsrData(INP DEVICE_OBJECT DeviceObject,
154 OUT PULONG PsrData)
155 {
156 NTSTATUS Status;
157 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
158 ACPI_EVAL_INPUT_BUFFER InputBuffer;
159 PAGED_CODE();
160 if (CmBattDebug & 0x40)
161 DbgPrint("CmBattGetPsrData: Entered with Pdo %x Tid %x\n",
162 DeviceObject, KeGetCurrentThread());
163
164 /* Initialize to zero */
165 ASSERT(PsrData != NULL);
166 *PsrData = 0;
167
168 /* Request the _PSR method */
169 *(PULONG)InputBuffer.MethodName = 'RSP_';
170 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
171
172 /* Send it to ACPI */
173 Status = CmBattSendDownStreamIrp(DeviceObject,
174 IOCTL_ACPI_EVAL_METHOD,
175 &InputBuffer,
176 sizeof(InputBuffer),
177 &OutputBuffer,
178 sizeof(OutputBuffer));
179 if (NT_SUCCESS(Status))
180 {
181 /* Read the result */
182 Status = GetDwordElement(OutputBuffer.Argument, PsrData);
183 if (CmBattDebug & 0x440)
184 DbgPrint("CmBattGetPsrData: _PSR method returned %x \n", *PsrData);
185 }
186 else if (CmBattDebug & 0x44C)
187 {
188 /* Failure */
189 DbgPrint("CmBattGetPsrData: Failed _PSR method - Status (0x%x)\n", Status);
190 }
191
192 /* Return status */
193 return Status;
194 }
195
196 NTSTATUS
197 NTAPI
198 CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject,
199 OUT PULONG StaData)
200 {
201 NTSTATUS Status;
202 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
203 ACPI_EVAL_INPUT_BUFFER InputBuffer;
204 PAGED_CODE();
205 if (CmBattDebug & 0x40)
206 DbgPrint("CmBattGetStaData: Entered with Pdo %x Tid %x\n",
207 DeviceObject, KeGetCurrentThread());
208
209 /* Initialize to zero */
210 ASSERT(StaData != NULL);
211 *StaData = 0;
212
213 /* Request the _PSR method */
214 *(PULONG)InputBuffer.MethodName = 'ATS_';
215 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
216
217 /* Send it to ACPI */
218 Status = CmBattSendDownStreamIrp(DeviceObject,
219 IOCTL_ACPI_EVAL_METHOD,
220 &InputBuffer,
221 sizeof(InputBuffer),
222 &OutputBuffer,
223 sizeof(OutputBuffer));
224 if (NT_SUCCESS(Status))
225 {
226 /* Read the result */
227 Status = GetDwordElement(OutputBuffer.Argument, StaData);
228 if (CmBattDebug & 0x440)
229 DbgPrint("CmBattGetStaData: _STA method returned %x \n", *StaData);
230 }
231 else if (CmBattDebug & 0x44C)
232 {
233 /* Failure */
234 DbgPrint("CmBattGetStaData: Failed _STA method - Status (0x%x)\n", Status);
235 Status = STATUS_NO_SUCH_DEVICE;
236 }
237
238 /* Return status */
239 return Status;
240 }
241
242 NTSTATUS
243 NTAPI
244 CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject,
245 OUT PULONG UniqueId)
246 {
247 NTSTATUS Status;
248 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
249 ACPI_EVAL_INPUT_BUFFER InputBuffer;
250 PAGED_CODE();
251 if (CmBattDebug & 0x40)
252 DbgPrint("CmBattGetUniqueId: Entered with Pdo %x Tid %x\n",
253 DeviceObject, KeGetCurrentThread());
254
255 /* Initialize to zero */
256 ASSERT(UniqueId != NULL);
257 *UniqueId = 0;
258
259 /* Request the _PSR method */
260 *(PULONG)InputBuffer.MethodName = 'DIU_';
261 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
262
263 /* Send it to ACPI */
264 Status = CmBattSendDownStreamIrp(DeviceObject,
265 IOCTL_ACPI_EVAL_METHOD,
266 &InputBuffer,
267 sizeof(InputBuffer),
268 &OutputBuffer,
269 sizeof(OutputBuffer));
270 if (NT_SUCCESS(Status))
271 {
272 /* Read the result */
273 Status = GetDwordElement(OutputBuffer.Argument, UniqueId);
274 if (CmBattDebug & 0x440)
275 DbgPrint("CmBattGetUniqueId: _UID method returned %x \n", *UniqueId);
276 }
277 else if (CmBattDebug & 0x44C)
278 {
279 /* Failure */
280 DbgPrint("CmBattGetUniqueId: Failed _UID method - Status (0x%x)\n", Status);
281 Status = STATUS_NO_SUCH_DEVICE;
282 }
283
284 /* Return status */
285 return Status;
286 }
287
288 NTSTATUS
289 NTAPI
290 CmBattSetTripPpoint(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
291 IN ULONG AlarmValue)
292 {
293 NTSTATUS Status;
294 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER InputBuffer;
295 PAGED_CODE();
296 if (CmBattDebug & 0x440)
297 DbgPrint("CmBattSetTripPpoint: _BTP Alarm Value %x Device %x Tid %x\n",
298 AlarmValue, DeviceExtension->DeviceId, KeGetCurrentThread);
299
300 /* Request the _BTP method */
301 *(PULONG)InputBuffer.MethodName = 'PTB_';
302 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE;
303 InputBuffer.IntegerArgument = AlarmValue;
304
305 /* Send it to ACPI */
306 Status = CmBattSendDownStreamIrp(DeviceExtension->AttachedDevice,
307 IOCTL_ACPI_EVAL_METHOD,
308 &InputBuffer,
309 sizeof(InputBuffer),
310 NULL,
311 0);
312 if (!(NT_SUCCESS(Status)) && (CmBattDebug & 0x440))
313 DbgPrint("CmBattSetTripPpoint: Failed _BTP method on device %x - Status (0x%x)\n",
314 DeviceExtension->DeviceId, Status);
315
316 /* Return status */
317 return Status;
318 }
319
320 NTSTATUS
321 NTAPI
322 CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
323 PACPI_BIF_DATA BifData)
324 {
325 UNIMPLEMENTED;
326 return STATUS_NOT_IMPLEMENTED;
327 }
328
329 NTSTATUS
330 NTAPI
331 CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
332 PACPI_BST_DATA BstData)
333 {
334 UNIMPLEMENTED;
335 return STATUS_NOT_IMPLEMENTED;
336 }
337
338 /* EOF */