I’m new to ACPI device driver. I need to implement a driver to evaluate the ASL method call. To confirm the communication between my driver and the ASL, I set a ASL method ‘RTN0’ which does nothing but return ‘0’. If I can successfully called ‘RTN0’ and get the ‘0’, then I can go ahead for next steps. However…
The problem I met is
outputBuffer.Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
And the data I get is of course useless. I guess the reason is the fdo in MyRead passed from I/O manager is not the one I thought. And a related finding is using WinDbg to check the device object, I can see the device object is “AttachedTo” “Device\ACPI” object, but from the dump of my driver, the “AttachedDevice” is null…
Any advise from anyone is high appreciated, my code is also attached in below.
-tftu
My current approach is quite simple, based on the normal WDM structure and the instruction of “ACPI Driver Interface in Windows Vista”, below are the codes(list the important piece only):
// Send the request along
status = SendDownStreamIrp(
Pdo,
IOCTL_ACPI_EVAL_METHOD_EX,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
&outputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER)
);
for (i = 0; i <= 50; i++) {
KdPrintEx((DPFLTR_IHVDRIVER_ID, 0, “(outputBuffer.Argument->Data)[%d] = (x=%x), (c=%c)\n”,i, (outputBuffer.Argument->Data)[i], (outputBuffer.Argument->Data)[i]));
}
if (!NT_SUCCESS(status)) {
return status;
}
// Sanity check the data
if ((outputBuffer.Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) ||
(outputBuffer.Count == 0)) {
return STATUS_ACPI_INVALID_DATA;
}
// Grab the argument
argument = outputBuffer.Argument;
return status;
}
NTSTATUS
SendDownStreamIrp(
IN PDEVICE_OBJECT Pdo,
IN ULONG Ioctl,
IN PVOID InputBuffer,
IN ULONG InputSize,
IN PVOID OutputBuffer,
IN ULONG OutputSize
)
{
IO_STATUS_BLOCK ioBlock;
KEVENT myIoctlEvent;
NTSTATUS status;
PIRP irp;
KSPIN_LOCK SpinLock;
KIRQL OldIrql;
// Initialize an event to wait on
KeInitializeEvent(&myIoctlEvent, SynchronizationEvent, FALSE);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
// Pass request to Pdo, always wait for completion routine
status = IoCallDriver(Pdo, irp);
KdPrintEx((DPFLTR_IHVDRIVER_ID, 0, “IoCallDriver status = (%d)\n”, status));
if (status == STATUS_PENDING) {
// Wait for the IRP to be completed, and then return the status code
KeWaitForSingleObject(
&myIoctlEvent,
Executive,
KernelMode,
FALSE,
NULL);
What is the status that’s being returned from your call to IOCTL_ACPI_EVAL_METHOD_EX?
Why are you using IOCTL_ACPI_EVAL_METHOD_EX, and not IOCTL_ACPI_EVAL_METHOD? You only use the EX variant if your driver is not directly instantiated on the device that represents the namespace that implements the method you’re calling.
What are you specifying as the path for the method to evaluate?
FIRST of all, it’s a serious mistake to be doing this driver in WDM. You REALLY want to write it using KMDF. You’ll avoid all SORTS of problems.
So, THAT’s the problem, right? NOT the fact that you get back something other than ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE. You’re sending a method invocation and that’s failing.
It’s only SUPPORTED on Vista and later. Unless you need to specify the path to a child device, don’t use the EX function.
Now, back to your original post:
Huh?? YOU create your FDO via IoCreateDevice (let me repeat again that you SHOULD be using KMDF for this).
What’s the name of the PDO in the devnode on which your driver is instantiated?
I use INF to load driver, AKDV is the device name in ASL and it’s a sensor,
How is it connected?
Have no idea about the slot number of the device, could you please clarify it in detail?
The ACPI DSDT says there is an AKDV device, and describes exactly where
it is located (such PCI slot 6, USB root hub port 3 in host controller #1, I/O port number, etc). In order for your driver to use the ACPI
information, the PDO you are driving must exactly match the location in
the ACPI description. Otherwise, ACPI won’t be able to match up your
device to the DSDT information.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Thanks for your explain, but how do I specify the location? I thought the PDO is representing the AKDV and then I can just pass the method call… Could I have a sample code for my reference?
Based on the instruction from the reply of this thread, I implement two KMDF versions of my driver, both are modified from the WDK samples and both no success
1st is from \general\toaster\kmdf\func\simple, the return NTSTATUS is 0xC0000010, STATUS_INVALID_DEVICE_REQUEST
2nd is from \general\portio\sys, return NTSTATUS is 0x00000103, STATUS_PENDING
Have also compared the Pdo by WinDbg, it’s exactly the same one, howcome it cannot return me the value I expected? Below is the data from WinDbg:
0: kd> !devobj 86927C10
Device object (86927c10) is for:
AKDV \Driver\ADRV99 DriverObject 867e0b10
Current Irp 00000000 RefCount 0 Type 00000032 Flags 00002044
Dacl 8acec138 DevExt 868d84c0 DevObjExt 86927ce0
ExtensionFlags (0000000000)
AttachedTo (Lower) 8608acb8 \Driver\ACPI
Device queue is not busy.
86927c10 \Driver\ADRV99 868d84c0 AKDV
8608acb8 \Driver\ACPI 8605e270 00000058
!DevNode 86d506a8 :
DeviceInst is “ACPI\ADV0001\2&daba3ff&2”
ServiceName is “AK8975”
Can anyone advise me how to correctly accessed the device object? For this ACPI device, should I process any initialization or registration in my driver? And, now I’m confused by the instruction in MSDN, is the ACPI driver means ACPI.sys or the driver I’m developing? I have been stuck here for a month, any advise or hint is highly appreciated!
Many thanks for your advise since the beginning of this thread. I do modify my driver based on your instruction:
use IOCTL_ACPI_EVAL_METHOD
use KMDF to implement my driver
But regarding your below question:
[quote]
What’s the name of the PDO in the devnode on which your driver is instantiated?
<\quote>
I understand you want me to figure out the bug by tracing the Pdo, but since the Device Object “86927C10” in both WinDbg and KdPrint dump is exactly the same, I really need a further advise to refresh my thinking…
And the driver is installed by a INF file, I also need to learn how does the INF affect the Pdo, your kind advise is more than welcome…
Anyhow, I appreciate your support which has help me to think more and go further!
; ================= Class section =====================
[ClassInstall32]
Addreg=ADRV99ClassReg
[ADRV99ClassReg]
HKR,0,%ClassName%
HKR,Icon,-5
HKR,DeviceCharacteristics,0x10001,0x100 ;Use same security checks on relative opens
HKR,Security,“D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;LS)” ;Allow generic all access to system, built-in Admin, and Local System.
;This one overrides the security set by the driver
Well, Mr. Tu, I’m glad you decided that my questions were finally worthy of a reply. You know, when you ask for help, and somebody asks a clarifying question in order to be better able to provide that help, it’s rather rude to ignore their question.
We can see YOUR driver is named ADRV99 and your device object (which is your FDO) is named \Device\AKDV… can you please confirm – if it’s not too much trouble Mr. Tu – that what I just said is correct.
… and the device instance is ACPI\ADV0001.… which is the hardware ID for which you’re installing your driver, given your INF.
So… tell me more about what you’re doing in your driver, and how the driver acts. What callbacks are you getting? From what routine are you attempting to send the IOCT_ACPI_EVAL_METHOD call? Is this in response to an IOCTL you send from user mode?
In your EvtDriverDeviceAdd event processing callback you’re creating your FDO, right? And you’re getting the underlying (local, i.e. In-Stack) target from the returned WDFDEVICE handle by calling WdfDeviceGetIoTarget, right? And you’re sending the IOCTL_ACPI_EVAL_METHOD to that In-Stack target?
Sorry, I don’t understand the question.
“ACPI driver” means the ACPI driver. There’s only one of them. It’s ACPI.SYS – You’re driver is a driver for an APCI device.
Well, I’m glad we got you moved from WDM to KMDF, for one thing. That’ll make your life easier.
I suspect there’s a simple bug either in your driver or in your ASL. It could be either place, right? How confident are you about your ASL code? Do you have more experience with ASL than you have with Windows drivers?
status = WdfDeviceInitAssignName(DeviceInit,&ntDeviceName);
if (!NT_SUCCESS(status)) {
return status;
}
WdfDeviceInitSetDeviceType(DeviceInit, GPD_TYPE);
status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &hDevice);
if (!NT_SUCCESS(status)) {
KdPrint( (“WdfDeviceCreate failed with status code 0x%x\n”, status));
return status;
}
VOID
ADRV99EvtIoDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
NTSTATUS status= STATUS_SUCCESS;
//For testing only
NTSTATUS AccessADRV99_ASL_RTNO_Method(IN PDEVICE_OBJECT Pdo)
{
ACPI_EVAL_INPUT_BUFFER inputBuffer;
ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
NTSTATUS status;
PACPI_METHOD_ARGUMENT argument;
int i;
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) (‘0NTR’);
KdPrintEx((DPFLTR_IHVDRIVER_ID, 0, “inputBuffer.MethodNameAsUlong = %s\n”, inputBuffer.MethodNameAsUlong));
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
// Pass request to Pdo, always wait for completion routine
status = IoCallDriver(Pdo, irp);
KdPrintEx((DPFLTR_IHVDRIVER_ID, 0, “IoCallDriver status = (%d)\n”, status));
if (status == STATUS_PENDING) {
// Wait for the IRP to be completed, and then return the status code
KeWaitForSingleObject(
&myIoctlEvent,
Executive,
KernelMode,
FALSE,
NULL);
status = ioBlock.Status;
KdPrintEx((DPFLTR_IHVDRIVER_ID, 0, “ioBlock.Status = (%d)\n”, status));
}
And below is the highlight of my user mode testing code:
CreateFile(
“\\.\AKDV99”, // Open the Device "file
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
The NTSTATUS I get is 0xC0000010, STATUS_INVALID_DEVICE_REQUEST…
Please ignore, this is just from my imagination…
As my colleague Vincent mentioned in his email, the ASL is maintained by different
team, we should confirm no bug in our driver before questioning their ASL…
Now is mid night here and I will leave office during Wed. ~ Sun. I’ll try my
best to check email and this thread in hotel, but please let me officially reply
on next Mon. And I hope you have read and accept the explain in my previous email.
Yes, it’s correct too, and you can see it in [ADV.NTx86] section of my INF
OK, but just naming your device object “AKDV” is not enough to connect
to the ACPI DSDT. The information you want is in a section called AKDV
in the APCI DSDT, right? Are you 100% absolutely convinced that the
AKDV section is exposing the name ADV0001? Remember, this all gets
launched from the bottom up. The ACPI driver parses the DSDT. It looks
for names that need to be exposed as PDOs (such as your ADV0001). That
PDO will have access to the DSDT section that created it, and ONLY that
section. If the ADV0001 name comes from the AKDV section, the you
should be able to access the data. Otherwise, there is no access.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Mr. Tu… you’re still writing what’s probably the most important part of the code in WDM. But, in a QUICK read-through (and I *do* mean quick, I make it a policy not to carefully plow-through code that people post here on NTDEV), it LOOKS like you’re sending the request to the PDO.
This driver loads? It gets and processes requests that you send?
So, what are the symptoms you’re getting now? You said in your post that you’re getting STATUS_INVALID_DEVICE_REQUEST from your application… WHERE are you getting this… on CreateFile? THAT’s not a good sign, because KMDF will typically handle that request for you.
Which he APPEARS to be saying it is… is that not a priori proof that he’s exposing the right device name and loading on the right PDO? Or are you concerned that he’s loading on a name “ADV0001” that’s defined in a DIFFERENT place in the DSDT?
>> Mr. Tu… Perhaps you should give us the complete ASL definition of your device, not one with the “…skip…” stuff left out. That would probably help us out here.
For the legal concern, please forgive me I can’t post the complete ASL, but below are the key piese for my questions (I think, pls correct me if you need more details…):
Yes, the driver successfully loaded w/o complaint. And yes, it process request and trigger the ADRV99EvtIoRead method of my driver.
My current expectation for my driver is I can get NTSTATUS = 0 (SUCCESS) and a return value ‘0’ (ASL RTN0 return value)from the ACPI_EVAL_OUTPUT_BUFFER in method AccessADRV99_ASL_RTNO_Method of my driver, however, I get 0xC0000010, STATUS_INVALID_DEVICE_REQUEST from this driver which is based on KMDF and copy from WDK \general\toaster\kmdf\func\simple sample, but add AccessADRV99_ASL_RTNO_Method and SendDownStreamIrp. AccessADRV99_ASL_RTNO_Method is invoked by ADRV99EvtIoRead method which is the callback of EVT_WDF_IO_QUEUE_IO_READ.