1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS ACPI-Compliant Control Method Battery
3c2c66affSColin Finck * LICENSE: BSD - See COPYING.ARM in the top level directory
4c2c66affSColin Finck * FILE: boot/drivers/bus/acpi/cmbatt/cmexec.c
5c2c66affSColin Finck * PURPOSE: ACPI Method Execution/Evaluation Glue
6c2c66affSColin Finck * PROGRAMMERS: ReactOS Portable Systems Group
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck /* INCLUDES *******************************************************************/
10c2c66affSColin Finck
11c2c66affSColin Finck #include "cmbatt.h"
12c2c66affSColin Finck
13c2c66affSColin Finck #include <acpiioct.h>
14c2c66affSColin Finck #include <debug.h>
15c2c66affSColin Finck
16359e73d0SHervé Poussineau typedef struct
17359e73d0SHervé Poussineau {
18359e73d0SHervé Poussineau LPSTR Name;
19359e73d0SHervé Poussineau BOOLEAN IsString;
20359e73d0SHervé Poussineau PVOID Data;
21359e73d0SHervé Poussineau } ACPI_PACKAGE_FIELD, *PACPI_PACKAGE_FIELD;
22359e73d0SHervé Poussineau
23c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
24c2c66affSColin Finck
25c2c66affSColin Finck NTSTATUS
26c2c66affSColin Finck NTAPI
GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument,OUT PULONG Value)27c2c66affSColin Finck GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument,
28c2c66affSColin Finck OUT PULONG Value)
29c2c66affSColin Finck {
30c2c66affSColin Finck NTSTATUS Status;
31c2c66affSColin Finck
32c2c66affSColin Finck /* Must have an integer */
33c2c66affSColin Finck if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER)
34c2c66affSColin Finck {
35c2c66affSColin Finck /* Not an integer, fail */
36c2c66affSColin Finck Status = STATUS_ACPI_INVALID_DATA;
37c2c66affSColin Finck if (CmBattDebug & 0x4C)
38c2c66affSColin Finck DbgPrint("GetDwordElement: Object contained wrong data type - %d\n",
39c2c66affSColin Finck Argument->Type);
40c2c66affSColin Finck }
41c2c66affSColin Finck else
42c2c66affSColin Finck {
43c2c66affSColin Finck /* Read the integer value */
44c2c66affSColin Finck *Value = Argument->Argument;
45c2c66affSColin Finck Status = STATUS_SUCCESS;
46c2c66affSColin Finck }
47c2c66affSColin Finck
48c2c66affSColin Finck /* Return status */
49c2c66affSColin Finck return Status;
50c2c66affSColin Finck }
51c2c66affSColin Finck
52c2c66affSColin Finck NTSTATUS
53c2c66affSColin Finck NTAPI
GetStringElement(IN PACPI_METHOD_ARGUMENT Argument,OUT PCHAR Value)54c2c66affSColin Finck GetStringElement(IN PACPI_METHOD_ARGUMENT Argument,
55c2c66affSColin Finck OUT PCHAR Value)
56c2c66affSColin Finck {
57c2c66affSColin Finck NTSTATUS Status;
58c2c66affSColin Finck
59c2c66affSColin Finck /* Must have a string of buffer */
60c2c66affSColin Finck if ((Argument->Type == ACPI_METHOD_ARGUMENT_STRING) ||
61c2c66affSColin Finck (Argument->Type == ACPI_METHOD_ARGUMENT_BUFFER))
62c2c66affSColin Finck {
63c2c66affSColin Finck /* String must be less than 256 characters */
64c2c66affSColin Finck if (Argument->DataLength < 256)
65c2c66affSColin Finck {
66c2c66affSColin Finck /* Copy the buffer */
67c2c66affSColin Finck RtlCopyMemory(Value, Argument->Data, Argument->DataLength);
68c2c66affSColin Finck Status = STATUS_SUCCESS;
69c2c66affSColin Finck }
70c2c66affSColin Finck else
71c2c66affSColin Finck {
72c2c66affSColin Finck /* The buffer is too small (the string is too large) */
73c2c66affSColin Finck Status = STATUS_BUFFER_TOO_SMALL;
74c2c66affSColin Finck if (CmBattDebug & 0x4C)
75c2c66affSColin Finck DbgPrint("GetStringElement: return buffer not big enough - %d\n", Argument->DataLength);
76c2c66affSColin Finck }
77c2c66affSColin Finck }
78c2c66affSColin Finck else
79c2c66affSColin Finck {
80c2c66affSColin Finck /* Not valid string data */
81c2c66affSColin Finck Status = STATUS_ACPI_INVALID_DATA;
82c2c66affSColin Finck if (CmBattDebug & 0x4C)
83c2c66affSColin Finck DbgPrint("GetStringElement: Object contained wrong data type - %d\n", Argument->Type);
84c2c66affSColin Finck }
85c2c66affSColin Finck
86c2c66affSColin Finck /* Return the status */
87c2c66affSColin Finck return Status;
88c2c66affSColin Finck }
89c2c66affSColin Finck
90c2c66affSColin Finck NTSTATUS
91c2c66affSColin Finck NTAPI
CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject,IN ULONG IoControlCode,IN PVOID InputBuffer,IN ULONG InputBufferLength,IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,IN ULONG OutputBufferLength)92c2c66affSColin Finck CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject,
93c2c66affSColin Finck IN ULONG IoControlCode,
94c2c66affSColin Finck IN PVOID InputBuffer,
95c2c66affSColin Finck IN ULONG InputBufferLength,
96c2c66affSColin Finck IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,
97c2c66affSColin Finck IN ULONG OutputBufferLength)
98c2c66affSColin Finck {
99c2c66affSColin Finck PIRP Irp;
100c2c66affSColin Finck NTSTATUS Status;
101c2c66affSColin Finck KEVENT Event;
102c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
103c2c66affSColin Finck PAGED_CODE();
104c2c66affSColin Finck
105c2c66affSColin Finck /* Initialize our wait event */
106c2c66affSColin Finck KeInitializeEvent(&Event, SynchronizationEvent, 0);
107c2c66affSColin Finck
108c2c66affSColin Finck /* Allocate the IRP */
109c2c66affSColin Finck Irp = IoBuildDeviceIoControlRequest(IoControlCode,
110c2c66affSColin Finck DeviceObject,
111c2c66affSColin Finck InputBuffer,
112c2c66affSColin Finck InputBufferLength,
113c2c66affSColin Finck OutputBuffer,
114c2c66affSColin Finck OutputBufferLength,
115c2c66affSColin Finck 0,
116c2c66affSColin Finck &Event,
117c2c66affSColin Finck &IoStatusBlock);
118c2c66affSColin Finck if (!Irp)
119c2c66affSColin Finck {
120c2c66affSColin Finck /* No IRP, fail */
121c2c66affSColin Finck if (CmBattDebug & 0x4C)
122c2c66affSColin Finck DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n");
123c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
124c2c66affSColin Finck }
125c2c66affSColin Finck
126c2c66affSColin Finck /* Call ACPI */
127c2c66affSColin Finck if (CmBattDebug & 0x40)
128c2c66affSColin Finck DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n",
129c2c66affSColin Finck Irp, KeGetCurrentThread());
130c2c66affSColin Finck Status = IoCallDriver(DeviceObject, Irp);
131c2c66affSColin Finck if (Status == STATUS_PENDING)
132c2c66affSColin Finck {
133c2c66affSColin Finck /* Wait for completion */
134c2c66affSColin Finck KeWaitForSingleObject(&Event,
135c2c66affSColin Finck Executive,
136c2c66affSColin Finck KernelMode,
137c2c66affSColin Finck FALSE,
138c2c66affSColin Finck NULL);
139c2c66affSColin Finck Status = Irp->IoStatus.Status;
140c2c66affSColin Finck }
141c2c66affSColin Finck
142c2c66affSColin Finck /* Check if caller wanted output */
143c2c66affSColin Finck if (OutputBuffer)
144c2c66affSColin Finck {
145c2c66affSColin Finck /* Make sure it's valid ACPI output buffer */
146c2c66affSColin Finck if ((OutputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) ||
147c2c66affSColin Finck !(OutputBuffer->Count))
148c2c66affSColin Finck {
149c2c66affSColin Finck /* It isn't, so set failure code */
150c2c66affSColin Finck Status = STATUS_ACPI_INVALID_DATA;
151c2c66affSColin Finck }
152c2c66affSColin Finck }
153c2c66affSColin Finck
154c2c66affSColin Finck /* Return status */
155c2c66affSColin Finck if (CmBattDebug & 0x40)
156c2c66affSColin Finck DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n",
157c2c66affSColin Finck Irp, Status, KeGetCurrentThread());
158c2c66affSColin Finck return Status;
159c2c66affSColin Finck }
160c2c66affSColin Finck
161359e73d0SHervé Poussineau static
162359e73d0SHervé Poussineau NTSTATUS
CmBattCallAcpiPackage(_In_ LPCSTR FunctionName,_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,_In_ ULONG PackageName,_In_ ULONG OutputBufferSize,_In_ PACPI_PACKAGE_FIELD PackageFields,_In_ ULONG PackageFieldCount)163359e73d0SHervé Poussineau CmBattCallAcpiPackage(
164359e73d0SHervé Poussineau _In_ LPCSTR FunctionName,
165359e73d0SHervé Poussineau _In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
166359e73d0SHervé Poussineau _In_ ULONG PackageName,
167359e73d0SHervé Poussineau _In_ ULONG OutputBufferSize,
168359e73d0SHervé Poussineau _In_ PACPI_PACKAGE_FIELD PackageFields,
169359e73d0SHervé Poussineau _In_ ULONG PackageFieldCount)
170359e73d0SHervé Poussineau {
171359e73d0SHervé Poussineau NTSTATUS Status;
172359e73d0SHervé Poussineau PACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
173359e73d0SHervé Poussineau ACPI_EVAL_INPUT_BUFFER InputBuffer;
174359e73d0SHervé Poussineau PACPI_METHOD_ARGUMENT Argument;
175359e73d0SHervé Poussineau ULONG i;
176359e73d0SHervé Poussineau PAGED_CODE();
177359e73d0SHervé Poussineau
178359e73d0SHervé Poussineau OutputBuffer = ExAllocatePoolWithTag(PagedPool,
179359e73d0SHervé Poussineau OutputBufferSize,
180359e73d0SHervé Poussineau 'MtaB');
181359e73d0SHervé Poussineau if (!OutputBuffer)
182359e73d0SHervé Poussineau {
183359e73d0SHervé Poussineau if (CmBattDebug & (CMBATT_ACPI_ENTRY_EXIT | CMBATT_ACPI_WARNING | CMBATT_GENERIC_WARNING))
184359e73d0SHervé Poussineau DbgPrint("%s: Failed to allocate Buffer\n", FunctionName);
185359e73d0SHervé Poussineau return STATUS_INSUFFICIENT_RESOURCES;
186359e73d0SHervé Poussineau }
187359e73d0SHervé Poussineau
188359e73d0SHervé Poussineau /* Initialize to zero */
189359e73d0SHervé Poussineau RtlZeroMemory(OutputBuffer, OutputBufferSize);
190359e73d0SHervé Poussineau
191359e73d0SHervé Poussineau /* Request the ACPI method */
192359e73d0SHervé Poussineau *(PULONG)InputBuffer.MethodName = PackageName;
193359e73d0SHervé Poussineau InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
194359e73d0SHervé Poussineau
195359e73d0SHervé Poussineau /* Send it to ACPI */
196359e73d0SHervé Poussineau Status = CmBattSendDownStreamIrp(DeviceExtension->AttachedDevice,
197359e73d0SHervé Poussineau IOCTL_ACPI_EVAL_METHOD,
198359e73d0SHervé Poussineau &InputBuffer,
199359e73d0SHervé Poussineau sizeof(InputBuffer),
200359e73d0SHervé Poussineau OutputBuffer,
201359e73d0SHervé Poussineau OutputBufferSize);
202359e73d0SHervé Poussineau if (!NT_SUCCESS(Status))
203359e73d0SHervé Poussineau {
204359e73d0SHervé Poussineau if (CmBattDebug & (CMBATT_ACPI_ASSERT | CMBATT_ACPI_ENTRY_EXIT | CMBATT_ACPI_WARNING | CMBATT_GENERIC_WARNING))
205359e73d0SHervé Poussineau DbgPrint("%s: Failed 0x%08x method on device %x - Status (0x%x)\n",
206359e73d0SHervé Poussineau FunctionName, PackageName, DeviceExtension->DeviceId, Status);
207359e73d0SHervé Poussineau ExFreePoolWithTag(OutputBuffer, 'MtaB');
208359e73d0SHervé Poussineau return Status;
209359e73d0SHervé Poussineau }
210359e73d0SHervé Poussineau
211359e73d0SHervé Poussineau /* Check if we got the right number of elements */
212359e73d0SHervé Poussineau if (OutputBuffer->Count != PackageFieldCount)
213359e73d0SHervé Poussineau {
214359e73d0SHervé Poussineau if (CmBattDebug & (CMBATT_ACPI_ASSERT | CMBATT_ACPI_ENTRY_EXIT | CMBATT_ACPI_WARNING | CMBATT_GENERIC_WARNING))
215359e73d0SHervé Poussineau DbgPrint("%s: 0x%08x method returned %d elements (requires %d)\n",
216359e73d0SHervé Poussineau FunctionName, PackageName, OutputBuffer->Count, PackageFieldCount);
217359e73d0SHervé Poussineau ExFreePoolWithTag(OutputBuffer, 'MtaB');
218359e73d0SHervé Poussineau return STATUS_ACPI_INVALID_DATA;
219359e73d0SHervé Poussineau }
220359e73d0SHervé Poussineau
221359e73d0SHervé Poussineau Argument = OutputBuffer->Argument;
222359e73d0SHervé Poussineau for (i = 0; i < PackageFieldCount && NT_SUCCESS(Status); i++)
223359e73d0SHervé Poussineau {
224359e73d0SHervé Poussineau if (PackageFields[i].IsString)
225359e73d0SHervé Poussineau Status = GetStringElement(Argument, PackageFields[i].Data);
226359e73d0SHervé Poussineau else
227359e73d0SHervé Poussineau Status = GetDwordElement(Argument, PackageFields[i].Data);
228359e73d0SHervé Poussineau if (!NT_SUCCESS(Status))
229359e73d0SHervé Poussineau {
230359e73d0SHervé Poussineau if (CmBattDebug & (CMBATT_ACPI_ASSERT | CMBATT_ACPI_ENTRY_EXIT | CMBATT_ACPI_WARNING | CMBATT_GENERIC_WARNING))
231359e73d0SHervé Poussineau DbgPrint("%s: Failed to get %s\n", FunctionName, PackageFields[i].Name);
232359e73d0SHervé Poussineau break;
233359e73d0SHervé Poussineau }
234359e73d0SHervé Poussineau Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
235359e73d0SHervé Poussineau }
236359e73d0SHervé Poussineau
237359e73d0SHervé Poussineau ExFreePoolWithTag(OutputBuffer, 'MtaB');
238359e73d0SHervé Poussineau return Status;
239359e73d0SHervé Poussineau }
240359e73d0SHervé Poussineau
241c2c66affSColin Finck NTSTATUS
242c2c66affSColin Finck NTAPI
CmBattGetPsrData(IN PDEVICE_OBJECT DeviceObject,OUT PULONG PsrData)243c2c66affSColin Finck CmBattGetPsrData(IN PDEVICE_OBJECT DeviceObject,
244c2c66affSColin Finck OUT PULONG PsrData)
245c2c66affSColin Finck {
246c2c66affSColin Finck NTSTATUS Status;
247c2c66affSColin Finck ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
248c2c66affSColin Finck ACPI_EVAL_INPUT_BUFFER InputBuffer;
249c2c66affSColin Finck PAGED_CODE();
250c2c66affSColin Finck if (CmBattDebug & 0x40)
251c2c66affSColin Finck DbgPrint("CmBattGetPsrData: Entered with Pdo %x Tid %x\n",
252c2c66affSColin Finck DeviceObject, KeGetCurrentThread());
253c2c66affSColin Finck
254c2c66affSColin Finck /* Initialize to zero */
255c2c66affSColin Finck ASSERT(PsrData != NULL);
256c2c66affSColin Finck *PsrData = 0;
257c2c66affSColin Finck
258c2c66affSColin Finck /* Request the _PSR method */
259c2c66affSColin Finck *(PULONG)InputBuffer.MethodName = 'RSP_';
260c2c66affSColin Finck InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
261c2c66affSColin Finck
262c2c66affSColin Finck /* Send it to ACPI */
263c2c66affSColin Finck Status = CmBattSendDownStreamIrp(DeviceObject,
264c2c66affSColin Finck IOCTL_ACPI_EVAL_METHOD,
265c2c66affSColin Finck &InputBuffer,
266c2c66affSColin Finck sizeof(InputBuffer),
267c2c66affSColin Finck &OutputBuffer,
268c2c66affSColin Finck sizeof(OutputBuffer));
269c2c66affSColin Finck if (NT_SUCCESS(Status))
270c2c66affSColin Finck {
271c2c66affSColin Finck /* Read the result */
272c2c66affSColin Finck Status = GetDwordElement(OutputBuffer.Argument, PsrData);
273c2c66affSColin Finck if (CmBattDebug & 0x440)
274c2c66affSColin Finck DbgPrint("CmBattGetPsrData: _PSR method returned %x \n", *PsrData);
275c2c66affSColin Finck }
276c2c66affSColin Finck else if (CmBattDebug & 0x44C)
277c2c66affSColin Finck {
278c2c66affSColin Finck /* Failure */
279c2c66affSColin Finck DbgPrint("CmBattGetPsrData: Failed _PSR method - Status (0x%x)\n", Status);
280c2c66affSColin Finck }
281c2c66affSColin Finck
282c2c66affSColin Finck /* Return status */
283c2c66affSColin Finck return Status;
284c2c66affSColin Finck }
285c2c66affSColin Finck
286c2c66affSColin Finck NTSTATUS
287c2c66affSColin Finck NTAPI
CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject,OUT PULONG StaData)288c2c66affSColin Finck CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject,
289c2c66affSColin Finck OUT PULONG StaData)
290c2c66affSColin Finck {
291c2c66affSColin Finck NTSTATUS Status;
292c2c66affSColin Finck ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
293c2c66affSColin Finck ACPI_EVAL_INPUT_BUFFER InputBuffer;
294c2c66affSColin Finck PAGED_CODE();
295c2c66affSColin Finck if (CmBattDebug & 0x40)
296c2c66affSColin Finck DbgPrint("CmBattGetStaData: Entered with Pdo %x Tid %x\n",
297c2c66affSColin Finck DeviceObject, KeGetCurrentThread());
298c2c66affSColin Finck
299c2c66affSColin Finck /* Initialize to zero */
300c2c66affSColin Finck ASSERT(StaData != NULL);
301c2c66affSColin Finck *StaData = 0;
302c2c66affSColin Finck
303*5c4fcd99SEric Kohl /* Request the _STA method */
304c2c66affSColin Finck *(PULONG)InputBuffer.MethodName = 'ATS_';
305c2c66affSColin Finck InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
306c2c66affSColin Finck
307c2c66affSColin Finck /* Send it to ACPI */
308c2c66affSColin Finck Status = CmBattSendDownStreamIrp(DeviceObject,
309c2c66affSColin Finck IOCTL_ACPI_EVAL_METHOD,
310c2c66affSColin Finck &InputBuffer,
311c2c66affSColin Finck sizeof(InputBuffer),
312c2c66affSColin Finck &OutputBuffer,
313c2c66affSColin Finck sizeof(OutputBuffer));
314c2c66affSColin Finck if (NT_SUCCESS(Status))
315c2c66affSColin Finck {
316c2c66affSColin Finck /* Read the result */
317c2c66affSColin Finck Status = GetDwordElement(OutputBuffer.Argument, StaData);
318c2c66affSColin Finck if (CmBattDebug & 0x440)
319c2c66affSColin Finck DbgPrint("CmBattGetStaData: _STA method returned %x \n", *StaData);
320c2c66affSColin Finck }
321c2c66affSColin Finck else if (CmBattDebug & 0x44C)
322c2c66affSColin Finck {
323c2c66affSColin Finck /* Failure */
324c2c66affSColin Finck DbgPrint("CmBattGetStaData: Failed _STA method - Status (0x%x)\n", Status);
325c2c66affSColin Finck Status = STATUS_NO_SUCH_DEVICE;
326c2c66affSColin Finck }
327c2c66affSColin Finck
328c2c66affSColin Finck /* Return status */
329c2c66affSColin Finck return Status;
330c2c66affSColin Finck }
331c2c66affSColin Finck
332c2c66affSColin Finck NTSTATUS
333c2c66affSColin Finck NTAPI
CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject,OUT PULONG UniqueId)334c2c66affSColin Finck CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject,
335c2c66affSColin Finck OUT PULONG UniqueId)
336c2c66affSColin Finck {
337c2c66affSColin Finck NTSTATUS Status;
338c2c66affSColin Finck ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
339c2c66affSColin Finck ACPI_EVAL_INPUT_BUFFER InputBuffer;
340c2c66affSColin Finck PAGED_CODE();
341c2c66affSColin Finck if (CmBattDebug & 0x40)
342c2c66affSColin Finck DbgPrint("CmBattGetUniqueId: Entered with Pdo %x Tid %x\n",
343c2c66affSColin Finck DeviceObject, KeGetCurrentThread());
344c2c66affSColin Finck
345c2c66affSColin Finck /* Initialize to zero */
346c2c66affSColin Finck ASSERT(UniqueId != NULL);
347c2c66affSColin Finck *UniqueId = 0;
348c2c66affSColin Finck
349*5c4fcd99SEric Kohl /* Request the _UID method */
350c2c66affSColin Finck *(PULONG)InputBuffer.MethodName = 'DIU_';
351c2c66affSColin Finck InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
352c2c66affSColin Finck
353c2c66affSColin Finck /* Send it to ACPI */
354c2c66affSColin Finck Status = CmBattSendDownStreamIrp(DeviceObject,
355c2c66affSColin Finck IOCTL_ACPI_EVAL_METHOD,
356c2c66affSColin Finck &InputBuffer,
357c2c66affSColin Finck sizeof(InputBuffer),
358c2c66affSColin Finck &OutputBuffer,
359c2c66affSColin Finck sizeof(OutputBuffer));
360c2c66affSColin Finck if (NT_SUCCESS(Status))
361c2c66affSColin Finck {
362c2c66affSColin Finck /* Read the result */
363c2c66affSColin Finck Status = GetDwordElement(OutputBuffer.Argument, UniqueId);
364c2c66affSColin Finck if (CmBattDebug & 0x440)
365c2c66affSColin Finck DbgPrint("CmBattGetUniqueId: _UID method returned %x \n", *UniqueId);
366c2c66affSColin Finck }
367c2c66affSColin Finck else if (CmBattDebug & 0x44C)
368c2c66affSColin Finck {
369c2c66affSColin Finck /* Failure */
370c2c66affSColin Finck DbgPrint("CmBattGetUniqueId: Failed _UID method - Status (0x%x)\n", Status);
371c2c66affSColin Finck Status = STATUS_NO_SUCH_DEVICE;
372c2c66affSColin Finck }
373c2c66affSColin Finck
374c2c66affSColin Finck /* Return status */
375c2c66affSColin Finck return Status;
376c2c66affSColin Finck }
377c2c66affSColin Finck
378c2c66affSColin Finck NTSTATUS
379c2c66affSColin Finck NTAPI
CmBattSetTripPpoint(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,IN ULONG AlarmValue)380c2c66affSColin Finck CmBattSetTripPpoint(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
381c2c66affSColin Finck IN ULONG AlarmValue)
382c2c66affSColin Finck {
383c2c66affSColin Finck NTSTATUS Status;
384c2c66affSColin Finck ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER InputBuffer;
385c2c66affSColin Finck PAGED_CODE();
386c2c66affSColin Finck if (CmBattDebug & 0x440)
387c2c66affSColin Finck DbgPrint("CmBattSetTripPpoint: _BTP Alarm Value %x Device %x Tid %x\n",
388c2c66affSColin Finck AlarmValue, DeviceExtension->DeviceId, KeGetCurrentThread);
389c2c66affSColin Finck
390c2c66affSColin Finck /* Request the _BTP method */
391c2c66affSColin Finck *(PULONG)InputBuffer.MethodName = 'PTB_';
392c2c66affSColin Finck InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE;
393c2c66affSColin Finck InputBuffer.IntegerArgument = AlarmValue;
394c2c66affSColin Finck
395c2c66affSColin Finck /* Send it to ACPI */
396c2c66affSColin Finck Status = CmBattSendDownStreamIrp(DeviceExtension->AttachedDevice,
397c2c66affSColin Finck IOCTL_ACPI_EVAL_METHOD,
398c2c66affSColin Finck &InputBuffer,
399c2c66affSColin Finck sizeof(InputBuffer),
400c2c66affSColin Finck NULL,
401c2c66affSColin Finck 0);
402c2c66affSColin Finck if (!(NT_SUCCESS(Status)) && (CmBattDebug & 0x440))
403c2c66affSColin Finck DbgPrint("CmBattSetTripPpoint: Failed _BTP method on device %x - Status (0x%x)\n",
404c2c66affSColin Finck DeviceExtension->DeviceId, Status);
405c2c66affSColin Finck
406c2c66affSColin Finck /* Return status */
407c2c66affSColin Finck return Status;
408c2c66affSColin Finck }
409c2c66affSColin Finck
410c2c66affSColin Finck NTSTATUS
411c2c66affSColin Finck NTAPI
CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension,PACPI_BIF_DATA BifData)412c2c66affSColin Finck CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
413c2c66affSColin Finck PACPI_BIF_DATA BifData)
414c2c66affSColin Finck {
415359e73d0SHervé Poussineau ACPI_PACKAGE_FIELD BifFields[] = {
416359e73d0SHervé Poussineau { "PowerUnit", FALSE, &BifData->PowerUnit },
417359e73d0SHervé Poussineau { "DesignCapacity", FALSE, &BifData->DesignCapacity },
418359e73d0SHervé Poussineau { "LastFullCapacity", FALSE, &BifData->LastFullCapacity },
419359e73d0SHervé Poussineau { "BatteryTechnology", FALSE, &BifData->BatteryTechnology },
420359e73d0SHervé Poussineau { "DesignVoltage", FALSE, &BifData->DesignVoltage },
421359e73d0SHervé Poussineau { "DesignCapacityWarning", FALSE, &BifData->DesignCapacityWarning },
422359e73d0SHervé Poussineau { "DesignCapacityLow", FALSE, &BifData->DesignCapacityLow },
423359e73d0SHervé Poussineau { "BatteryCapacityGranularity1", FALSE, &BifData->BatteryCapacityGranularity1 },
424359e73d0SHervé Poussineau { "BatteryCapacityGranularity2", FALSE, &BifData->BatteryCapacityGranularity2 },
425359e73d0SHervé Poussineau { "ModelNumber", TRUE, &BifData->ModelNumber },
426359e73d0SHervé Poussineau { "SerialNumber", TRUE, &BifData->SerialNumber },
427359e73d0SHervé Poussineau { "BatteryType", TRUE, &BifData->BatteryType },
428359e73d0SHervé Poussineau { "OemInfo", TRUE, &BifData->OemInfo },
429359e73d0SHervé Poussineau };
430359e73d0SHervé Poussineau PAGED_CODE();
431359e73d0SHervé Poussineau
432359e73d0SHervé Poussineau if (CmBattDebug & CMBATT_ACPI_ENTRY_EXIT)
433359e73d0SHervé Poussineau DbgPrint("CmBattGetBifData: Buffer (0x%x) Device %x Tid %x\n",
434359e73d0SHervé Poussineau BifData, DeviceExtension->DeviceId, KeGetCurrentThread());
435359e73d0SHervé Poussineau
436359e73d0SHervé Poussineau /* Request the _BIF method */
437359e73d0SHervé Poussineau /* Note that _BIF method is deprecated since ACPI 4.0, and replaced by _BIX method.
438359e73d0SHervé Poussineau * However, VirtualBox 7.0 only support _BIF method.
439359e73d0SHervé Poussineau */
440359e73d0SHervé Poussineau return CmBattCallAcpiPackage("CmBattGetBifData",
441359e73d0SHervé Poussineau DeviceExtension,
442359e73d0SHervé Poussineau 'FIB_',
443359e73d0SHervé Poussineau 512,
444359e73d0SHervé Poussineau BifFields,
445359e73d0SHervé Poussineau RTL_NUMBER_OF(BifFields));
446c2c66affSColin Finck }
447c2c66affSColin Finck
448faf61231SGeorge Bișoc /**
449faf61231SGeorge Bișoc * @brief
450faf61231SGeorge Bișoc * Retrieves the eXtended static battery information from the
451faf61231SGeorge Bișoc * ACPI _BIX method.
452faf61231SGeorge Bișoc *
453faf61231SGeorge Bișoc * @param[in] DeviceExtension
454faf61231SGeorge Bișoc * A pointer to a Control Method (CM) battery device extension.
455faf61231SGeorge Bișoc * It is used to send the ACPI method evaluation operation
456faf61231SGeorge Bișoc * to the ACPI driver of which it is attached to this CM battery.
457faf61231SGeorge Bișoc *
458faf61231SGeorge Bișoc * @param[out] BixData
459faf61231SGeorge Bișoc * A pointer to a structure that contains the _BIX data fields,
460faf61231SGeorge Bișoc * returned to caller.
461faf61231SGeorge Bișoc *
462faf61231SGeorge Bișoc * @return
463faf61231SGeorge Bișoc * Returns STATUS_SUCCESS if the operation has succeeded successfully,
464faf61231SGeorge Bișoc * otherwise a failure NTSTATUS code is returned.
465faf61231SGeorge Bișoc */
466faf61231SGeorge Bișoc NTSTATUS
467faf61231SGeorge Bișoc NTAPI
CmBattGetBixData(_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,_Out_ PACPI_BIX_DATA BixData)468faf61231SGeorge Bișoc CmBattGetBixData(
469faf61231SGeorge Bișoc _In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
470faf61231SGeorge Bișoc _Out_ PACPI_BIX_DATA BixData)
471faf61231SGeorge Bișoc {
472faf61231SGeorge Bișoc ACPI_PACKAGE_FIELD BixFields[] = {
473faf61231SGeorge Bișoc { "Revision", FALSE, &BixData->Revision },
474faf61231SGeorge Bișoc { "PowerUnit", FALSE, &BixData->PowerUnit },
475faf61231SGeorge Bișoc { "DesignCapacity", FALSE, &BixData->DesignCapacity },
476faf61231SGeorge Bișoc { "LastFullCapacity", FALSE, &BixData->LastFullCapacity },
477faf61231SGeorge Bișoc { "BatteryTechnology", FALSE, &BixData->BatteryTechnology },
478faf61231SGeorge Bișoc { "DesignVoltage", FALSE, &BixData->DesignVoltage },
479faf61231SGeorge Bișoc { "DesignCapacityWarning", FALSE, &BixData->DesignCapacityWarning },
480faf61231SGeorge Bișoc { "DesignCapacityLow", FALSE, &BixData->DesignCapacityLow },
481faf61231SGeorge Bișoc { "CycleCount", FALSE, &BixData->CycleCount },
482faf61231SGeorge Bișoc { "Accuracy", FALSE, &BixData->Accuracy },
483faf61231SGeorge Bișoc { "MaxSampleTime", FALSE, &BixData->MaxSampleTime },
484faf61231SGeorge Bișoc { "MinSampleTime", FALSE, &BixData->MinSampleTime },
485faf61231SGeorge Bișoc { "MaxAverageInterval", FALSE, &BixData->MaxAverageInterval },
486faf61231SGeorge Bișoc { "MinAverageInterval", FALSE, &BixData->MinAverageInterval },
487faf61231SGeorge Bișoc { "BatteryCapacityGranularity1", FALSE, &BixData->BatteryCapacityGranularity1 },
488faf61231SGeorge Bișoc { "BatteryCapacityGranularity2", FALSE, &BixData->BatteryCapacityGranularity2 },
489faf61231SGeorge Bișoc { "ModelNumber", TRUE, &BixData->ModelNumber },
490faf61231SGeorge Bișoc { "SerialNumber", TRUE, &BixData->SerialNumber },
491faf61231SGeorge Bișoc { "BatteryType", TRUE, &BixData->BatteryType },
492faf61231SGeorge Bișoc { "OemInfo", TRUE, &BixData->OemInfo },
493faf61231SGeorge Bișoc { "SwapCapability", FALSE, &BixData->SwapCapability },
494faf61231SGeorge Bișoc };
495faf61231SGeorge Bișoc PAGED_CODE();
496faf61231SGeorge Bișoc
497faf61231SGeorge Bișoc if (CmBattDebug & CMBATT_ACPI_ENTRY_EXIT)
498faf61231SGeorge Bișoc {
499faf61231SGeorge Bișoc DbgPrint("CmBattGetBixData: Buffer (0x%x) Device %x Tid %x\n",
500faf61231SGeorge Bișoc BixData, DeviceExtension->DeviceId, KeGetCurrentThread());
501faf61231SGeorge Bișoc }
502faf61231SGeorge Bișoc
503faf61231SGeorge Bișoc /* Request the ACPI driver to get the _BIX data for us */
504faf61231SGeorge Bișoc return CmBattCallAcpiPackage("CmBattGetBifData",
505faf61231SGeorge Bișoc DeviceExtension,
506faf61231SGeorge Bișoc 'XIB_',
507faf61231SGeorge Bișoc 512,
508faf61231SGeorge Bișoc BixFields,
509faf61231SGeorge Bișoc RTL_NUMBER_OF(BixFields));
510faf61231SGeorge Bișoc }
511faf61231SGeorge Bișoc
512c2c66affSColin Finck NTSTATUS
513c2c66affSColin Finck NTAPI
CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension,PACPI_BST_DATA BstData)514c2c66affSColin Finck CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
515c2c66affSColin Finck PACPI_BST_DATA BstData)
516c2c66affSColin Finck {
517359e73d0SHervé Poussineau ACPI_PACKAGE_FIELD BstFields[] = {
518359e73d0SHervé Poussineau { "State", FALSE, &BstData->State },
519359e73d0SHervé Poussineau { "PresentRate", FALSE, &BstData->PresentRate },
520359e73d0SHervé Poussineau { "RemainingCapacity", FALSE, &BstData->RemainingCapacity },
521359e73d0SHervé Poussineau { "PresentVoltage", FALSE, &BstData->PresentVoltage },
522359e73d0SHervé Poussineau };
523359e73d0SHervé Poussineau PAGED_CODE();
524359e73d0SHervé Poussineau
525359e73d0SHervé Poussineau if (CmBattDebug & CMBATT_ACPI_ENTRY_EXIT)
526359e73d0SHervé Poussineau DbgPrint("CmBattGetBstData: Buffer (0x%x) Device %x Tid %x\n",
527359e73d0SHervé Poussineau BstData, DeviceExtension->DeviceId, KeGetCurrentThread());
528359e73d0SHervé Poussineau
529359e73d0SHervé Poussineau
530359e73d0SHervé Poussineau return CmBattCallAcpiPackage("CmBattGetBstData",
531359e73d0SHervé Poussineau DeviceExtension,
532359e73d0SHervé Poussineau 'TSB_',
533359e73d0SHervé Poussineau 512,
534359e73d0SHervé Poussineau BstFields,
535359e73d0SHervé Poussineau RTL_NUMBER_OF(BstFields));
536c2c66affSColin Finck }
537c2c66affSColin Finck
538c2c66affSColin Finck /* EOF */
539