mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
341 lines
10 KiB
C
341 lines
10 KiB
C
/*
|
|
* PROJECT: ReactOS ACPI-Compliant Control Method Battery
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
* FILE: boot/drivers/bus/acpi/cmbatt/cmexec.c
|
|
* PURPOSE: ACPI Method Execution/Evaluation Glue
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include "cmbatt.h"
|
|
|
|
#include <acpiioct.h>
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument,
|
|
OUT PULONG Value)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
/* Must have an integer */
|
|
if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER)
|
|
{
|
|
/* Not an integer, fail */
|
|
Status = STATUS_ACPI_INVALID_DATA;
|
|
if (CmBattDebug & 0x4C)
|
|
DbgPrint("GetDwordElement: Object contained wrong data type - %d\n",
|
|
Argument->Type);
|
|
}
|
|
else
|
|
{
|
|
/* Read the integer value */
|
|
*Value = Argument->Argument;
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
GetStringElement(IN PACPI_METHOD_ARGUMENT Argument,
|
|
OUT PCHAR Value)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
/* Must have a string of buffer */
|
|
if ((Argument->Type == ACPI_METHOD_ARGUMENT_STRING) ||
|
|
(Argument->Type == ACPI_METHOD_ARGUMENT_BUFFER))
|
|
{
|
|
/* String must be less than 256 characters */
|
|
if (Argument->DataLength < 256)
|
|
{
|
|
/* Copy the buffer */
|
|
RtlCopyMemory(Value, Argument->Data, Argument->DataLength);
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
/* The buffer is too small (the string is too large) */
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
if (CmBattDebug & 0x4C)
|
|
DbgPrint("GetStringElement: return buffer not big enough - %d\n", Argument->DataLength);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Not valid string data */
|
|
Status = STATUS_ACPI_INVALID_DATA;
|
|
if (CmBattDebug & 0x4C)
|
|
DbgPrint("GetStringElement: Object contained wrong data type - %d\n", Argument->Type);
|
|
}
|
|
|
|
/* Return the status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject,
|
|
IN ULONG IoControlCode,
|
|
IN PVOID InputBuffer,
|
|
IN ULONG InputBufferLength,
|
|
IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,
|
|
IN ULONG OutputBufferLength)
|
|
{
|
|
PIRP Irp;
|
|
NTSTATUS Status;
|
|
KEVENT Event;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
PAGED_CODE();
|
|
|
|
/* Initialize our wait event */
|
|
KeInitializeEvent(&Event, SynchronizationEvent, 0);
|
|
|
|
/* Allocate the IRP */
|
|
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
|
|
DeviceObject,
|
|
InputBuffer,
|
|
InputBufferLength,
|
|
OutputBuffer,
|
|
OutputBufferLength,
|
|
0,
|
|
&Event,
|
|
&IoStatusBlock);
|
|
if (!Irp)
|
|
{
|
|
/* No IRP, fail */
|
|
if (CmBattDebug & 0x4C)
|
|
DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n");
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
/* Call ACPI */
|
|
if (CmBattDebug & 0x40)
|
|
DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n",
|
|
Irp, KeGetCurrentThread());
|
|
Status = IoCallDriver(DeviceObject, Irp);
|
|
if (Status == STATUS_PENDING)
|
|
{
|
|
/* Wait for completion */
|
|
KeWaitForSingleObject(&Event,
|
|
Executive,
|
|
KernelMode,
|
|
FALSE,
|
|
NULL);
|
|
Status = Irp->IoStatus.Status;
|
|
}
|
|
|
|
/* Check if caller wanted output */
|
|
if (OutputBuffer)
|
|
{
|
|
/* Make sure it's valid ACPI output buffer */
|
|
if ((OutputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) ||
|
|
!(OutputBuffer->Count))
|
|
{
|
|
/* It isn't, so set failure code */
|
|
Status = STATUS_ACPI_INVALID_DATA;
|
|
}
|
|
}
|
|
|
|
/* Return status */
|
|
if (CmBattDebug & 0x40)
|
|
DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n",
|
|
Irp, Status, KeGetCurrentThread());
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmBattGetPsrData(IN PDEVICE_OBJECT DeviceObject,
|
|
OUT PULONG PsrData)
|
|
{
|
|
NTSTATUS Status;
|
|
ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
PAGED_CODE();
|
|
if (CmBattDebug & 0x40)
|
|
DbgPrint("CmBattGetPsrData: Entered with Pdo %x Tid %x\n",
|
|
DeviceObject, KeGetCurrentThread());
|
|
|
|
/* Initialize to zero */
|
|
ASSERT(PsrData != NULL);
|
|
*PsrData = 0;
|
|
|
|
/* Request the _PSR method */
|
|
*(PULONG)InputBuffer.MethodName = 'RSP_';
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
/* Send it to ACPI */
|
|
Status = CmBattSendDownStreamIrp(DeviceObject,
|
|
IOCTL_ACPI_EVAL_METHOD,
|
|
&InputBuffer,
|
|
sizeof(InputBuffer),
|
|
&OutputBuffer,
|
|
sizeof(OutputBuffer));
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
/* Read the result */
|
|
Status = GetDwordElement(OutputBuffer.Argument, PsrData);
|
|
if (CmBattDebug & 0x440)
|
|
DbgPrint("CmBattGetPsrData: _PSR method returned %x \n", *PsrData);
|
|
}
|
|
else if (CmBattDebug & 0x44C)
|
|
{
|
|
/* Failure */
|
|
DbgPrint("CmBattGetPsrData: Failed _PSR method - Status (0x%x)\n", Status);
|
|
}
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject,
|
|
OUT PULONG StaData)
|
|
{
|
|
NTSTATUS Status;
|
|
ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
PAGED_CODE();
|
|
if (CmBattDebug & 0x40)
|
|
DbgPrint("CmBattGetStaData: Entered with Pdo %x Tid %x\n",
|
|
DeviceObject, KeGetCurrentThread());
|
|
|
|
/* Initialize to zero */
|
|
ASSERT(StaData != NULL);
|
|
*StaData = 0;
|
|
|
|
/* Request the _PSR method */
|
|
*(PULONG)InputBuffer.MethodName = 'ATS_';
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
/* Send it to ACPI */
|
|
Status = CmBattSendDownStreamIrp(DeviceObject,
|
|
IOCTL_ACPI_EVAL_METHOD,
|
|
&InputBuffer,
|
|
sizeof(InputBuffer),
|
|
&OutputBuffer,
|
|
sizeof(OutputBuffer));
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
/* Read the result */
|
|
Status = GetDwordElement(OutputBuffer.Argument, StaData);
|
|
if (CmBattDebug & 0x440)
|
|
DbgPrint("CmBattGetStaData: _STA method returned %x \n", *StaData);
|
|
}
|
|
else if (CmBattDebug & 0x44C)
|
|
{
|
|
/* Failure */
|
|
DbgPrint("CmBattGetStaData: Failed _STA method - Status (0x%x)\n", Status);
|
|
Status = STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject,
|
|
OUT PULONG UniqueId)
|
|
{
|
|
NTSTATUS Status;
|
|
ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
PAGED_CODE();
|
|
if (CmBattDebug & 0x40)
|
|
DbgPrint("CmBattGetUniqueId: Entered with Pdo %x Tid %x\n",
|
|
DeviceObject, KeGetCurrentThread());
|
|
|
|
/* Initialize to zero */
|
|
ASSERT(UniqueId != NULL);
|
|
*UniqueId = 0;
|
|
|
|
/* Request the _PSR method */
|
|
*(PULONG)InputBuffer.MethodName = 'DIU_';
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
/* Send it to ACPI */
|
|
Status = CmBattSendDownStreamIrp(DeviceObject,
|
|
IOCTL_ACPI_EVAL_METHOD,
|
|
&InputBuffer,
|
|
sizeof(InputBuffer),
|
|
&OutputBuffer,
|
|
sizeof(OutputBuffer));
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
/* Read the result */
|
|
Status = GetDwordElement(OutputBuffer.Argument, UniqueId);
|
|
if (CmBattDebug & 0x440)
|
|
DbgPrint("CmBattGetUniqueId: _UID method returned %x \n", *UniqueId);
|
|
}
|
|
else if (CmBattDebug & 0x44C)
|
|
{
|
|
/* Failure */
|
|
DbgPrint("CmBattGetUniqueId: Failed _UID method - Status (0x%x)\n", Status);
|
|
Status = STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmBattSetTripPpoint(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
|
IN ULONG AlarmValue)
|
|
{
|
|
NTSTATUS Status;
|
|
ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER InputBuffer;
|
|
PAGED_CODE();
|
|
if (CmBattDebug & 0x440)
|
|
DbgPrint("CmBattSetTripPpoint: _BTP Alarm Value %x Device %x Tid %x\n",
|
|
AlarmValue, DeviceExtension->DeviceId, KeGetCurrentThread);
|
|
|
|
/* Request the _BTP method */
|
|
*(PULONG)InputBuffer.MethodName = 'PTB_';
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE;
|
|
InputBuffer.IntegerArgument = AlarmValue;
|
|
|
|
/* Send it to ACPI */
|
|
Status = CmBattSendDownStreamIrp(DeviceExtension->AttachedDevice,
|
|
IOCTL_ACPI_EVAL_METHOD,
|
|
&InputBuffer,
|
|
sizeof(InputBuffer),
|
|
NULL,
|
|
0);
|
|
if (!(NT_SUCCESS(Status)) && (CmBattDebug & 0x440))
|
|
DbgPrint("CmBattSetTripPpoint: Failed _BTP method on device %x - Status (0x%x)\n",
|
|
DeviceExtension->DeviceId, Status);
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
|
PACPI_BIF_DATA BifData)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
|
PACPI_BST_DATA BstData)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/* EOF */
|