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
;
22 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ULONG
))
23 return STATUS_INVALID_PARAMETER
;
25 Signature
= *((PULONG
)Irp
->AssociatedIrp
.SystemBuffer
);
29 case ACPI_EVAL_INPUT_BUFFER_SIGNATURE
:
30 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER
))
31 return STATUS_INVALID_PARAMETER
;
36 case ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE
:
37 SimpleInt
= Irp
->AssociatedIrp
.SystemBuffer
;
39 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER
))
40 return STATUS_INVALID_PARAMETER
;
44 ParamList
.Pointer
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ACPI_OBJECT
), 'OpcA');
45 if (!ParamList
.Pointer
) return STATUS_INSUFFICIENT_RESOURCES
;
47 ParamList
.Pointer
[0].Type
= ACPI_TYPE_INTEGER
;
48 ParamList
.Pointer
[0].Integer
.Value
= SimpleInt
->IntegerArgument
;
51 case ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_SIGNATURE
:
52 SimpleStr
= Irp
->AssociatedIrp
.SystemBuffer
;
54 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING
))
55 return STATUS_INVALID_PARAMETER
;
59 ParamList
.Pointer
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ACPI_OBJECT
), 'OpcA');
60 if (!ParamList
.Pointer
) return STATUS_INSUFFICIENT_RESOURCES
;
62 ParamList
.Pointer
[0].String
.Pointer
= (CHAR
*)SimpleStr
->String
;
63 ParamList
.Pointer
[0].String
.Length
= SimpleStr
->StringLength
;
67 DPRINT1("Unsupported input buffer signature: %d\n", Signature
);
68 return STATUS_NOT_IMPLEMENTED
;
71 RtlCopyMemory(MethodName
,
72 EvalInputBuff
->MethodName
,
73 sizeof(EvalInputBuff
->MethodName
));
74 MethodName
[4] = ANSI_NULL
;
75 Status
= AcpiEvaluateObject(DeviceData
->AcpiHandle
,
80 if (ParamList
.Count
!= 0)
81 ExFreePoolWithTag(ParamList
.Pointer
, 'OpcA');
83 if (ACPI_SUCCESS(Status
))
85 ACPI_OBJECT
*Obj
= RetBuff
.Pointer
;
86 ULONG ExtraParamLength
;
88 /* If we didn't get anything back then we're done */
89 if (!RetBuff
.Pointer
|| RetBuff
.Length
== 0)
90 return STATUS_SUCCESS
;
94 case ACPI_TYPE_INTEGER
:
95 ExtraParamLength
= sizeof(ULONG
);
98 case ACPI_TYPE_STRING
:
99 ExtraParamLength
= Obj
->String
.Length
;
102 case ACPI_TYPE_BUFFER
:
103 ExtraParamLength
= Obj
->Buffer
.Length
;
106 case ACPI_TYPE_PACKAGE
:
107 DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
108 return STATUS_UNSUCCESSFUL
;
112 return STATUS_UNSUCCESSFUL
;
115 /* Enough space for a ULONG is always included */
116 if (ExtraParamLength
>= sizeof(ULONG
))
117 ExtraParamLength
-= sizeof(ULONG
);
119 ExtraParamLength
= 0;
121 OutputBuf
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
122 ExtraParamLength
, 'BpcA');
123 if (!OutputBuf
) return STATUS_INSUFFICIENT_RESOURCES
;
125 OutputBuf
->Signature
= ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
;
126 OutputBuf
->Length
= ExtraParamLength
+ sizeof(ACPI_METHOD_ARGUMENT
);
127 OutputBuf
->Count
= 1;
131 case ACPI_TYPE_INTEGER
:
132 ACPI_METHOD_SET_ARGUMENT_INTEGER(OutputBuf
->Argument
, Obj
->Integer
.Value
);
135 case ACPI_TYPE_STRING
:
136 ACPI_METHOD_SET_ARGUMENT_STRING(OutputBuf
->Argument
, Obj
->String
.Pointer
);
139 case ACPI_TYPE_BUFFER
:
140 ACPI_METHOD_SET_ARGUMENT_BUFFER(OutputBuf
->Argument
, Obj
->Buffer
.Pointer
, Obj
->Buffer
.Length
);
143 case ACPI_TYPE_PACKAGE
:
144 DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
145 return STATUS_UNSUCCESSFUL
;
149 return STATUS_UNSUCCESSFUL
;
152 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
155 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
, OutputBuf
, sizeof(ACPI_EVAL_OUTPUT_BUFFER
) +
157 Irp
->IoStatus
.Information
= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) + ExtraParamLength
;
158 ExFreePoolWithTag(OutputBuf
, 'BpcA');
159 return STATUS_SUCCESS
;
163 ExFreePoolWithTag(OutputBuf
, 'BpcA');
164 return STATUS_BUFFER_TOO_SMALL
;
169 DPRINT1("Query method %s failed on %p\n", EvalInputBuff
->MethodName
, DeviceData
->AcpiHandle
);
170 return STATUS_UNSUCCESSFUL
;