From c2897307004827f126dfd305f3cce7395084a0a2 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 24 Mar 2010 23:13:51 +0000 Subject: [PATCH] [ACPI] - Fix a warning - Implement some IOCTL_ACPI_EVAL_METHOD handling (no input parameters are supported yet but it should be enough for what cmbatt needs it to do) svn path=/trunk/; revision=46413 --- reactos/drivers/bus/acpi/acpi.rbuild | 1 + reactos/drivers/bus/acpi/eval.c | 142 +++++++++++++++++++++ reactos/drivers/bus/acpi/include/acpisys.h | 5 + reactos/drivers/bus/acpi/main.c | 55 +++++--- 4 files changed, 184 insertions(+), 19 deletions(-) create mode 100644 reactos/drivers/bus/acpi/eval.c diff --git a/reactos/drivers/bus/acpi/acpi.rbuild b/reactos/drivers/bus/acpi/acpi.rbuild index 4b9ec8674a5..d8594d1c957 100644 --- a/reactos/drivers/bus/acpi/acpi.rbuild +++ b/reactos/drivers/bus/acpi/acpi.rbuild @@ -26,6 +26,7 @@ osl.c acpienum.c + eval.c interface.c pnp.c power.c diff --git a/reactos/drivers/bus/acpi/eval.c b/reactos/drivers/bus/acpi/eval.c new file mode 100644 index 00000000000..a912e03372d --- /dev/null +++ b/reactos/drivers/bus/acpi/eval.c @@ -0,0 +1,142 @@ +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#define NDEBUG +#include + +NTSTATUS +NTAPI +Bus_PDO_EvalMethod(PPDO_DEVICE_DATA DeviceData, + PIRP Irp) +{ + ULONG Signature; + NTSTATUS Status; + ACPI_OBJECT_LIST *ParamList; + PACPI_EVAL_INPUT_BUFFER EvalInputBuff = Irp->AssociatedIrp.SystemBuffer; + ACPI_BUFFER RetBuff = {ACPI_ALLOCATE_BUFFER, NULL}; + PACPI_EVAL_OUTPUT_BUFFER OutputBuf; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + + if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) + return STATUS_INVALID_PARAMETER; + + Signature = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + + switch (Signature) + { + case ACPI_EVAL_INPUT_BUFFER_SIGNATURE: + if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ACPI_EVAL_INPUT_BUFFER)) + return STATUS_INVALID_PARAMETER; + + ParamList = NULL; + break; + + /* FIXME: Support input parameters */ + + default: + DPRINT1("Unsupported input buffer signature: %d\n", Signature); + return STATUS_NOT_IMPLEMENTED; + } + + Status = AcpiEvaluateObject(DeviceData->AcpiHandle, + (CHAR*)EvalInputBuff->MethodName, + ParamList, + &RetBuff); + if (ACPI_SUCCESS(Status)) + { + ACPI_OBJECT *Obj = RetBuff.Pointer; + ULONG ExtraParamLength; + + switch (Obj->Type) + { + case ACPI_TYPE_INTEGER: + ExtraParamLength = sizeof(ULONG); + break; + + case ACPI_TYPE_STRING: + ExtraParamLength = Obj->String.Length; + break; + + case ACPI_TYPE_BUFFER: + ExtraParamLength = Obj->Buffer.Length; + break; + + case ACPI_TYPE_PACKAGE: + DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n"); + return STATUS_UNSUCCESSFUL; + + default: + ASSERT(FALSE); + return STATUS_UNSUCCESSFUL; + } + + /* Enough space for a ULONG is always included */ + if (ExtraParamLength >= sizeof(ULONG)) + ExtraParamLength -= sizeof(ULONG); + else + ExtraParamLength = 0; + + OutputBuf = ExAllocatePool(NonPagedPool, sizeof(ACPI_EVAL_OUTPUT_BUFFER) + + ExtraParamLength); + if (!OutputBuf) return STATUS_INSUFFICIENT_RESOURCES; + + OutputBuf->Signature = ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE; + OutputBuf->Length = ExtraParamLength + sizeof(ACPI_METHOD_ARGUMENT); + OutputBuf->Count = 1; + + switch (Obj->Type) + { + case ACPI_TYPE_INTEGER: + ACPI_METHOD_SET_ARGUMENT_INTEGER(OutputBuf->Argument, Obj->Integer.Value); + break; + + case ACPI_TYPE_STRING: + ACPI_METHOD_SET_ARGUMENT_STRING(OutputBuf->Argument, Obj->String.Pointer); + break; + + case ACPI_TYPE_BUFFER: + ACPI_METHOD_SET_ARGUMENT_BUFFER(OutputBuf->Argument, Obj->Buffer.Pointer, Obj->Buffer.Length); + break; + + case ACPI_TYPE_PACKAGE: + DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n"); + return STATUS_UNSUCCESSFUL; + + default: + ASSERT(FALSE); + return STATUS_UNSUCCESSFUL; + } + + if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ACPI_EVAL_OUTPUT_BUFFER) + + ExtraParamLength) + { + RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, OutputBuf, sizeof(ACPI_EVAL_OUTPUT_BUFFER) + + ExtraParamLength); + Irp->IoStatus.Information = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + ExtraParamLength; + ExFreePool(OutputBuf); + return STATUS_SUCCESS; + } + else + { + ExFreePool(OutputBuf); + return STATUS_BUFFER_TOO_SMALL; + } + } + else + { + DPRINT1("Query method %s failed on %p\n", EvalInputBuff->MethodName, DeviceData->AcpiHandle); + return STATUS_UNSUCCESSFUL; + } +} diff --git a/reactos/drivers/bus/acpi/include/acpisys.h b/reactos/drivers/bus/acpi/include/acpisys.h index 368ac97c83f..bf3c65ee0f8 100644 --- a/reactos/drivers/bus/acpi/include/acpisys.h +++ b/reactos/drivers/bus/acpi/include/acpisys.h @@ -90,6 +90,11 @@ NTSTATUS ACPIEnumerateDevices( PFDO_DEVICE_DATA DeviceExtension); +NTSTATUS +NTAPI +Bus_PDO_EvalMethod(PPDO_DEVICE_DATA DeviceData, + PIRP Irp); + NTSTATUS NTAPI Bus_CreateClose ( diff --git a/reactos/drivers/bus/acpi/main.c b/reactos/drivers/bus/acpi/main.c index 3d1170eefd6..c4f2c221e83 100644 --- a/reactos/drivers/bus/acpi/main.c +++ b/reactos/drivers/bus/acpi/main.c @@ -6,6 +6,8 @@ #include #include +#include + #define NDEBUG #include @@ -29,7 +31,9 @@ Bus_AddDevice( PDEVICE_OBJECT deviceObject = NULL; PFDO_DEVICE_DATA deviceData = NULL; PWCHAR deviceName = NULL; +#ifndef NDEBUG ULONG nameLength; +#endif PAGED_CODE (); @@ -168,32 +172,45 @@ ACPIDispatchDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; + PIO_STACK_LOCATION irpStack; + NTSTATUS status = STATUS_NOT_SUPPORTED; + PCOMMON_DEVICE_DATA commonData; - DPRINT("Called. IRP is at (0x%X)\n", Irp); - - Irp->IoStatus.Information = 0; + PAGED_CODE (); - IrpSp = IoGetCurrentIrpStackLocation(Irp); - switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { - default: - DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); - Status = STATUS_NOT_IMPLEMENTED; - break; - } + irpStack = IoGetCurrentIrpStackLocation (Irp); + ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction); - if (Status != STATUS_PENDING) { - Irp->IoStatus.Status = Status; + commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; - DPRINT("Completing IRP at 0x%X\n", Irp); + Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } + if (!commonData->IsFDO) + { + switch (irpStack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_ACPI_EVAL_METHOD: + status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData, + Irp); + break; + + /* TODO: Implement other IOCTLs */ + + default: + DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode); + break; + } + } + else + DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n"); - DPRINT("Leaving. Status 0x%X\n", Status); + if (status != STATUS_PENDING) + { + Irp->IoStatus.Status = status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } - return Status; + return status; } NTSTATUS -- 2.17.1