Hi
I have below Get() func. to execute an ACPI _DSM method (@ bottom) in my device ACPI namespace().
It fails when I do WdfIoTargetSendIoctlSynchronously(IOCTL_ACPI_EVAL_METHOD) with STATUS_BUFFER_TOO_SMALL.
I am invoking it as
DEFINE_GUID(GUID_M,…)
ULONG ValueLength = sizeof(ULONG);
LONG Value = -1;
GetAcpiDsm_L3Data(WdfDevice, ‘abcd’,
(PUCHAR)(&GUID_M), 0, 1,0, ValueLength, (PVOID)&Value);
If I change the IOCTL to IOCTL_ACPI_EVAL_METHOD_EX I get STATUS_INFO_LENGTH_MISMATCH.
I seem to be messing the args, but unable to find where.
Also what do I call on my memory desc/handle/buffers
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER()
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE()
When I change the i/p buff to use WDF_MEMORY_DESCRIPTOR_INIT_HANDLE() and o/p buff to WDF_MEMORY_DESCRIPTOR_INIT_BUFFER() I get the error code STATUS_OBJECT_NAME_NOT_FOUND instead.
I just want to know what the problem at high level is
- my arguments passing or
- driver inferred semantics of the _DSM method vs. actual _DSM method (below)
- Use the other IOCTL_ACPI_EVAL_METHOD / Ex
- Else use GUID_ACPI_* (<wdmguid.h>) interfaces (probably not)
NTSTATUS
Get(
IN WDFDEVICE Device,
IN ULONG PoolTag,
IN PUCHAR Arg0,
IN ULONG Arg1,
IN ULONG Arg2,
IN ULONG Arg3,
IN ULONG ValueLength,
OUT PVOID Value
)
/
Arg0: GUID
Arg1: don?t care
Arg2: Required Op Index
Arg3: Don’t care
IN ULONG ValueLength : Expected output value length 4
/
{
WDFIOTARGET ioTarget = WdfDeviceGetIoTarget(Device);
NTSTATUS status = STATUS_SUCCESS;
WDF_MEMORY_DESCRIPTOR inputDescriptor;
WDF_MEMORY_DESCRIPTOR outputDescriptor;
ULONG_PTR bytesReturned = 0;
ULONG outputSize;
ULONG inputSize;
ULONG inputArgSize;
ACPI_EVAL_INPUT_BUFFER_COMPLEX input;
ACPI_EVAL_OUTPUT_BUFFER output;
PACPI_METHOD_ARGUMENT arg;
WDFMEMORY inputMemoryHandle = NULL;
WDFMEMORY outputMemoryHandle = NULL;
//
// Iutput
//
inputArgSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(GUID));
inputArgSize += 3 * ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG));
inputSize = sizeof(ACPI_EVAL_INPUT_BUFFER_COMPLEX) + inputArgSize - sizeof(ACPI_METHOD_ARGUMENT);
status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES,
PagedPool, PoolTag,
inputSize, &inputMemoryHandle, NULL);
if (!(NT_SUCCESS(status)))
{
goto done;
}
input = (ACPI_EVAL_INPUT_BUFFER_COMPLEX)WdfMemoryGetBuffer(inputMemoryHandle, NULL);
input->Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
input->MethodNameAsUlong = (ULONG)‘MSD_’;
input->Size = inputArgSize;
input->ArgumentCount = 4;
arg = input->Argument;
ACPI_METHOD_SET_ARGUMENT_BUFFER(arg, Arg0, sizeof(GUID)); // Arg0
arg = ACPI_METHOD_NEXT_ARGUMENT(arg);
ACPI_METHOD_SET_ARGUMENT_INTEGER(arg, Arg1); // Arg1
arg = ACPI_METHOD_NEXT_ARGUMENT(arg);
ACPI_METHOD_SET_ARGUMENT_INTEGER(arg, Arg2); // Arg2
arg = ACPI_METHOD_NEXT_ARGUMENT(arg);
ACPI_METHOD_SET_ARGUMENT_INTEGER(arg, Arg3); // Arg3
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDescriptor, input, inputSize);
//
// Output
//
outputSize = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + ValueLength - sizeof(ACPI_METHOD_ARGUMENT);
if (outputSize)
status = WdfMemoryCreate(NULL,
PagedPool, PoolTag,
outputSize, &outputMemoryHandle, NULL);
else
status = STATUS_INVALID_PARAMETER;
if (!(NT_SUCCESS(status)))
{
goto done;
}
output = (ACPI_EVAL_OUTPUT_BUFFER)WdfMemoryGetBuffer(outputMemoryHandle, NULL);
//WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDescriptor, output, outputSize);
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputDescriptor, outputMemoryHandle, NULL);
//
// Send IOCTL
//
status = WdfIoTargetSendIoctlSynchronously(
ioTarget,
NULL,
IOCTL_ACPI_EVAL_METHOD,
&inputDescriptor,
&outputDescriptor,
NULL,
&bytesReturned);
if (!(NT_SUCCESS(status)))
{
/////FAILL!!!
goto done;
}
–
Method(_DSM, 4, Serialized)
{
If(LEqual(Arg0, ToUUID(“…”)}))
{
If(LEqual(Arg2, Zero))
{
Return(Buffer(One)
{
0x08
})
}
If(LEqual(Arg2, One))
{
Return(XYZ)
}
If(LEqual(Arg2, 0x02))
{
Store(abc, XYZ)
Return(Zero)
}
}
Return(Buffer(One)
{
0x00
})</wdmguid.h>