8 Bus_PDO_EvalMethod(PPDO_DEVICE_DATA DeviceData
,
13 ACPI_OBJECT_LIST ParamList
;
14 PACPI_EVAL_INPUT_BUFFER EvalInputBuff
= Irp
->AssociatedIrp
.SystemBuffer
;
15 ACPI_BUFFER RetBuff
= {ACPI_ALLOCATE_BUFFER
, NULL
};
16 PACPI_EVAL_OUTPUT_BUFFER OutputBuf
;
17 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
18 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER
*SimpleInt
;
19 ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING
*SimpleStr
;
21 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ULONG
))
22 return STATUS_INVALID_PARAMETER
;
24 Signature
= *((PULONG
)Irp
->AssociatedIrp
.SystemBuffer
);
28 case ACPI_EVAL_INPUT_BUFFER_SIGNATURE
:
29 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER
))
30 return STATUS_INVALID_PARAMETER
;
35 case ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE
:
36 SimpleInt
= Irp
->AssociatedIrp
.SystemBuffer
;
38 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER
))
39 return STATUS_INVALID_PARAMETER
;
43 ParamList
.Pointer
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ACPI_OBJECT
), 'IPCA');
44 if (!ParamList
.Pointer
) return STATUS_INSUFFICIENT_RESOURCES
;
46 ParamList
.Pointer
[0].Type
= ACPI_TYPE_INTEGER
;
47 ParamList
.Pointer
[0].Integer
.Value
= SimpleInt
->IntegerArgument
;
50 case ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_SIGNATURE
:
51 SimpleStr
= Irp
->AssociatedIrp
.SystemBuffer
;
53 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING
))
54 return STATUS_INVALID_PARAMETER
;
58 ParamList
.Pointer
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ACPI_OBJECT
), 'IPCA');
59 if (!ParamList
.Pointer
) return STATUS_INSUFFICIENT_RESOURCES
;
61 ParamList
.Pointer
[0].String
.Pointer
= (CHAR
*)SimpleStr
->String
;
62 ParamList
.Pointer
[0].String
.Length
= SimpleStr
->StringLength
;
66 DPRINT1("Unsupported input buffer signature: %d\n", Signature
);
67 return STATUS_NOT_IMPLEMENTED
;
70 Status
= AcpiEvaluateObject(DeviceData
->AcpiHandle
,
71 (CHAR
*)EvalInputBuff
->MethodName
,
75 if (ParamList
.Count
!= 0)
76 ExFreePoolWithTag(ParamList
.Pointer
, 'IPCA');
78 if (ACPI_SUCCESS(Status
))
80 ACPI_OBJECT
*Obj
= RetBuff
.Pointer
;
81 ULONG ExtraParamLength
;
83 /* If we didn't get anything back then we're done */
84 if (!RetBuff
.Pointer
|| RetBuff
.Length
== 0)
85 return STATUS_SUCCESS
;
89 case ACPI_TYPE_INTEGER
:
90 ExtraParamLength
= sizeof(ULONG
);
93 case ACPI_TYPE_STRING
:
94 ExtraParamLength
= Obj
->String
.Length
;
97 case ACPI_TYPE_BUFFER
:
98 ExtraParamLength
= Obj
->Buffer
.Length
;
101 case ACPI_TYPE_PACKAGE
:
102 DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
103 return STATUS_UNSUCCESSFUL
;
107 return STATUS_UNSUCCESSFUL
;
110 /* Enough space for a ULONG is always included */
111 if (ExtraParamLength
>= sizeof(ULONG
))
112 ExtraParamLength
-= sizeof(ULONG
);
114 ExtraParamLength
= 0;
116 OutputBuf
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
117 ExtraParamLength
, 'IPCA');
118 if (!OutputBuf
) return STATUS_INSUFFICIENT_RESOURCES
;
120 OutputBuf
->Signature
= ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
;
121 OutputBuf
->Length
= ExtraParamLength
+ sizeof(ACPI_METHOD_ARGUMENT
);
122 OutputBuf
->Count
= 1;
126 case ACPI_TYPE_INTEGER
:
127 ACPI_METHOD_SET_ARGUMENT_INTEGER(OutputBuf
->Argument
, Obj
->Integer
.Value
);
130 case ACPI_TYPE_STRING
:
131 ACPI_METHOD_SET_ARGUMENT_STRING(OutputBuf
->Argument
, Obj
->String
.Pointer
);
134 case ACPI_TYPE_BUFFER
:
135 ACPI_METHOD_SET_ARGUMENT_BUFFER(OutputBuf
->Argument
, Obj
->Buffer
.Pointer
, Obj
->Buffer
.Length
);
138 case ACPI_TYPE_PACKAGE
:
139 DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
140 return STATUS_UNSUCCESSFUL
;
144 return STATUS_UNSUCCESSFUL
;
147 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
150 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
, OutputBuf
, sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
152 Irp
->IoStatus
.Information
= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) + ExtraParamLength
;
153 ExFreePoolWithTag(OutputBuf
, 'IPCA');
154 return STATUS_SUCCESS
;
158 ExFreePoolWithTag(OutputBuf
, 'IPCA');
159 return STATUS_BUFFER_TOO_SMALL
;
164 DPRINT1("Query method %s failed on %p\n", EvalInputBuff
->MethodName
, DeviceData
->AcpiHandle
);
165 return STATUS_UNSUCCESSFUL
;