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
9 /* INCLUDES *******************************************************************/
14 /* FUNCTIONS ******************************************************************/
18 GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument
,
23 /* Must have an integer */
24 if (Argument
->Type
!= ACPI_METHOD_ARGUMENT_INTEGER
)
26 /* Not an integer, fail */
27 Status
= STATUS_ACPI_INVALID_DATA
;
28 if (CmBattDebug
& 0x4C)
29 DbgPrint("GetDwordElement: Object contained wrong data type - %d\n",
34 /* Read the integer value */
35 *Value
= Argument
->Argument
;
36 Status
= STATUS_SUCCESS
;
45 GetStringElement(IN PACPI_METHOD_ARGUMENT Argument
,
50 /* Must have a string of buffer */
51 if ((Argument
->Type
== ACPI_METHOD_ARGUMENT_STRING
) ||
52 (Argument
->Type
== ACPI_METHOD_ARGUMENT_BUFFER
))
54 /* String must be less than 256 characters */
55 if (Argument
->DataLength
< 256)
58 RtlCopyMemory(Value
, Argument
->Data
, Argument
->DataLength
);
59 Status
= STATUS_SUCCESS
;
63 /* The buffer is too small (the string is too large) */
64 Status
= STATUS_BUFFER_TOO_SMALL
;
65 if (CmBattDebug
& 0x4C)
66 DbgPrint("GetStringElement: return buffer not big enough - %d\n", Argument
->DataLength
);
71 /* Not valid string data */
72 Status
= STATUS_ACPI_INVALID_DATA
;
73 if (CmBattDebug
& 0x4C)
74 DbgPrint("GetStringElement: Object contained wrong data type - %d\n", Argument
->Type
);
77 /* Return the status */
83 CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject
,
84 IN ULONG IoControlCode
,
86 IN ULONG InputBufferLength
,
87 IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer
,
88 IN ULONG OutputBufferLength
)
93 IO_STATUS_BLOCK IoStatusBlock
;
96 /* Initialize our wait event */
97 KeInitializeEvent(&Event
, SynchronizationEvent
, 0);
99 /* Allocate the IRP */
100 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
112 if (CmBattDebug
& 0x4C)
113 DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n");
114 return STATUS_INSUFFICIENT_RESOURCES
;
118 if (CmBattDebug
& 0x40)
119 DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n",
120 Irp
, KeGetCurrentThread());
121 Status
= IoCallDriver(DeviceObject
, Irp
);
122 if (Status
== STATUS_PENDING
)
124 /* Wait for completion */
125 KeWaitForSingleObject(&Event
,
130 Status
= Irp
->IoStatus
.Status
;
133 /* Check if caller wanted output */
136 /* Make sure it's valid ACPI output buffer */
137 if ((OutputBuffer
->Signature
!= ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
) ||
138 !(OutputBuffer
->Count
))
140 /* It isn't, so set failure code */
141 Status
= STATUS_ACPI_INVALID_DATA
;
146 if (CmBattDebug
& 0x40)
147 DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n",
148 Irp
, Status
, KeGetCurrentThread());
154 CmBattGetPsrData(IN PDEVICE_OBJECT DeviceObject
,
158 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer
;
159 ACPI_EVAL_INPUT_BUFFER InputBuffer
;
161 if (CmBattDebug
& 0x40)
162 DbgPrint("CmBattGetPsrData: Entered with Pdo %x Tid %x\n",
163 DeviceObject
, KeGetCurrentThread());
165 /* Initialize to zero */
166 ASSERT(PsrData
!= NULL
);
169 /* Request the _PSR method */
170 *(PULONG
)InputBuffer
.MethodName
= 'RSP_';
171 InputBuffer
.Signature
= ACPI_EVAL_INPUT_BUFFER_SIGNATURE
;
173 /* Send it to ACPI */
174 Status
= CmBattSendDownStreamIrp(DeviceObject
,
175 IOCTL_ACPI_EVAL_METHOD
,
179 sizeof(OutputBuffer
));
180 if (NT_SUCCESS(Status
))
182 /* Read the result */
183 Status
= GetDwordElement(OutputBuffer
.Argument
, PsrData
);
184 if (CmBattDebug
& 0x440)
185 DbgPrint("CmBattGetPsrData: _PSR method returned %x \n", *PsrData
);
187 else if (CmBattDebug
& 0x44C)
190 DbgPrint("CmBattGetPsrData: Failed _PSR method - Status (0x%x)\n", Status
);
199 CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject
,
203 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer
;
204 ACPI_EVAL_INPUT_BUFFER InputBuffer
;
206 if (CmBattDebug
& 0x40)
207 DbgPrint("CmBattGetStaData: Entered with Pdo %x Tid %x\n",
208 DeviceObject
, KeGetCurrentThread());
210 /* Initialize to zero */
211 ASSERT(StaData
!= NULL
);
214 /* Request the _PSR method */
215 *(PULONG
)InputBuffer
.MethodName
= 'ATS_';
216 InputBuffer
.Signature
= ACPI_EVAL_INPUT_BUFFER_SIGNATURE
;
218 /* Send it to ACPI */
219 Status
= CmBattSendDownStreamIrp(DeviceObject
,
220 IOCTL_ACPI_EVAL_METHOD
,
224 sizeof(OutputBuffer
));
225 if (NT_SUCCESS(Status
))
227 /* Read the result */
228 Status
= GetDwordElement(OutputBuffer
.Argument
, StaData
);
229 if (CmBattDebug
& 0x440)
230 DbgPrint("CmBattGetStaData: _STA method returned %x \n", *StaData
);
232 else if (CmBattDebug
& 0x44C)
235 DbgPrint("CmBattGetStaData: Failed _STA method - Status (0x%x)\n", Status
);
236 Status
= STATUS_NO_SUCH_DEVICE
;
245 CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject
,
249 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer
;
250 ACPI_EVAL_INPUT_BUFFER InputBuffer
;
252 if (CmBattDebug
& 0x40)
253 DbgPrint("CmBattGetUniqueId: Entered with Pdo %x Tid %x\n",
254 DeviceObject
, KeGetCurrentThread());
256 /* Initialize to zero */
257 ASSERT(UniqueId
!= NULL
);
260 /* Request the _PSR method */
261 *(PULONG
)InputBuffer
.MethodName
= 'DIU_';
262 InputBuffer
.Signature
= ACPI_EVAL_INPUT_BUFFER_SIGNATURE
;
264 /* Send it to ACPI */
265 Status
= CmBattSendDownStreamIrp(DeviceObject
,
266 IOCTL_ACPI_EVAL_METHOD
,
270 sizeof(OutputBuffer
));
271 if (NT_SUCCESS(Status
))
273 /* Read the result */
274 Status
= GetDwordElement(OutputBuffer
.Argument
, UniqueId
);
275 if (CmBattDebug
& 0x440)
276 DbgPrint("CmBattGetUniqueId: _UID method returned %x \n", *UniqueId
);
278 else if (CmBattDebug
& 0x44C)
281 DbgPrint("CmBattGetUniqueId: Failed _UID method - Status (0x%x)\n", Status
);
282 Status
= STATUS_NO_SUCH_DEVICE
;
291 CmBattSetTripPpoint(IN PCMBATT_DEVICE_EXTENSION DeviceExtension
,
295 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER InputBuffer
;
297 if (CmBattDebug
& 0x440)
298 DbgPrint("CmBattSetTripPpoint: _BTP Alarm Value %x Device %x Tid %x\n",
299 AlarmValue
, DeviceExtension
->DeviceId
, KeGetCurrentThread
);
301 /* Request the _BTP method */
302 *(PULONG
)InputBuffer
.MethodName
= 'PTB_';
303 InputBuffer
.Signature
= ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE
;
304 InputBuffer
.IntegerArgument
= AlarmValue
;
306 /* Send it to ACPI */
307 Status
= CmBattSendDownStreamIrp(DeviceExtension
->AttachedDevice
,
308 IOCTL_ACPI_EVAL_METHOD
,
313 if (!(NT_SUCCESS(Status
)) && (CmBattDebug
& 0x440))
314 DbgPrint("CmBattSetTripPpoint: Failed _BTP method on device %x - Status (0x%x)\n",
315 DeviceExtension
->DeviceId
, Status
);
323 CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
324 PACPI_BIF_DATA BifData
)
327 return STATUS_NOT_IMPLEMENTED
;
332 CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
333 PACPI_BST_DATA BstData
)
338 IO_STATUS_BLOCK IoStatusBlock
;
341 /* Initialize our wait event */
342 KeInitializeEvent(&Event
, SynchronizationEvent
, 0);
344 /* Allocate the IRP */
345 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
357 if (CmBattDebug
& 0x4C)
358 DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n");
359 return STATUS_INSUFFICIENT_RESOURCES
;
363 if (CmBattDebug
& 0x40)
364 DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n", Irp
, KeGetCurrentThread());
365 Status
= IoCallDriver(DeviceObject
, Irp
);
366 if (Status
== STATUS_PENDING
)
368 /* Wait for completion */
369 KeWaitForSingleObject(&Event
,
374 Status
= Irp
->IoStatus
.Status
;
377 /* Check if caller wanted output */
380 /* Make sure it's valid ACPI output buffer */
381 if ((OutputBuffer
->Signature
!= ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
) ||
382 !(OutputBuffer
->Count
))
384 /* It isn't, so set failure code */
385 Status
= STATUS_ACPI_INVALID_DATA
;
390 if (CmBattDebug
& 0x40)
391 DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n",
392 Irp
, Status
, KeGetCurrentThread());