7 #include <acpi_drivers.h>
21 Bus_PDO_EvalMethod(PPDO_DEVICE_DATA DeviceData
,
26 ACPI_OBJECT_LIST ParamList
;
27 PACPI_EVAL_INPUT_BUFFER EvalInputBuff
= Irp
->AssociatedIrp
.SystemBuffer
;
28 ACPI_BUFFER RetBuff
= {ACPI_ALLOCATE_BUFFER
, NULL
};
29 PACPI_EVAL_OUTPUT_BUFFER OutputBuf
;
30 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
31 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER
*SimpleInt
;
32 ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING
*SimpleStr
;
34 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ULONG
))
35 return STATUS_INVALID_PARAMETER
;
37 Signature
= *((PULONG
)Irp
->AssociatedIrp
.SystemBuffer
);
41 case ACPI_EVAL_INPUT_BUFFER_SIGNATURE
:
42 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER
))
43 return STATUS_INVALID_PARAMETER
;
48 case ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE
:
49 SimpleInt
= Irp
->AssociatedIrp
.SystemBuffer
;
51 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER
))
52 return STATUS_INVALID_PARAMETER
;
56 ParamList
.Pointer
= ExAllocatePool(NonPagedPool
, sizeof(ACPI_OBJECT
));
57 if (!ParamList
.Pointer
) return STATUS_INSUFFICIENT_RESOURCES
;
59 ParamList
.Pointer
[0].Type
= ACPI_TYPE_INTEGER
;
60 ParamList
.Pointer
[0].Integer
.Value
= SimpleInt
->IntegerArgument
;
63 case ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_SIGNATURE
:
64 SimpleStr
= Irp
->AssociatedIrp
.SystemBuffer
;
66 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING
))
67 return STATUS_INVALID_PARAMETER
;
71 ParamList
.Pointer
= ExAllocatePool(NonPagedPool
, sizeof(ACPI_OBJECT
));
72 if (!ParamList
.Pointer
) return STATUS_INSUFFICIENT_RESOURCES
;
74 ParamList
.Pointer
[0].String
.Pointer
= (CHAR
*)SimpleStr
->String
;
75 ParamList
.Pointer
[0].String
.Length
= SimpleStr
->StringLength
;
79 DPRINT1("Unsupported input buffer signature: %d\n", Signature
);
80 return STATUS_NOT_IMPLEMENTED
;
83 Status
= AcpiEvaluateObject(DeviceData
->AcpiHandle
,
84 (CHAR
*)EvalInputBuff
->MethodName
,
88 if (ParamList
.Count
!= 0)
89 ExFreePool(ParamList
.Pointer
);
91 if (ACPI_SUCCESS(Status
))
93 ACPI_OBJECT
*Obj
= RetBuff
.Pointer
;
94 ULONG ExtraParamLength
;
96 /* If we didn't get anything back then we're done */
97 if (!RetBuff
.Pointer
|| RetBuff
.Length
== 0)
98 return STATUS_SUCCESS
;
102 case ACPI_TYPE_INTEGER
:
103 ExtraParamLength
= sizeof(ULONG
);
106 case ACPI_TYPE_STRING
:
107 ExtraParamLength
= Obj
->String
.Length
;
110 case ACPI_TYPE_BUFFER
:
111 ExtraParamLength
= Obj
->Buffer
.Length
;
114 case ACPI_TYPE_PACKAGE
:
115 DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
116 return STATUS_UNSUCCESSFUL
;
120 return STATUS_UNSUCCESSFUL
;
123 /* Enough space for a ULONG is always included */
124 if (ExtraParamLength
>= sizeof(ULONG
))
125 ExtraParamLength
-= sizeof(ULONG
);
127 ExtraParamLength
= 0;
129 OutputBuf
= ExAllocatePool(NonPagedPool
, sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
131 if (!OutputBuf
) return STATUS_INSUFFICIENT_RESOURCES
;
133 OutputBuf
->Signature
= ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
;
134 OutputBuf
->Length
= ExtraParamLength
+ sizeof(ACPI_METHOD_ARGUMENT
);
135 OutputBuf
->Count
= 1;
139 case ACPI_TYPE_INTEGER
:
140 ACPI_METHOD_SET_ARGUMENT_INTEGER(OutputBuf
->Argument
, Obj
->Integer
.Value
);
143 case ACPI_TYPE_STRING
:
144 ACPI_METHOD_SET_ARGUMENT_STRING(OutputBuf
->Argument
, Obj
->String
.Pointer
);
147 case ACPI_TYPE_BUFFER
:
148 ACPI_METHOD_SET_ARGUMENT_BUFFER(OutputBuf
->Argument
, Obj
->Buffer
.Pointer
, Obj
->Buffer
.Length
);
151 case ACPI_TYPE_PACKAGE
:
152 DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
153 return STATUS_UNSUCCESSFUL
;
157 return STATUS_UNSUCCESSFUL
;
160 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
163 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
, OutputBuf
, sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
165 Irp
->IoStatus
.Information
= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) + ExtraParamLength
;
166 ExFreePool(OutputBuf
);
167 return STATUS_SUCCESS
;
171 ExFreePool(OutputBuf
);
172 return STATUS_BUFFER_TOO_SMALL
;
177 DPRINT1("Query method %s failed on %p\n", EvalInputBuff
->MethodName
, DeviceData
->AcpiHandle
);
178 return STATUS_UNSUCCESSFUL
;