Evaluating ACPI method

Hello,
I’ve searched this forum but didn’t find decision of my problem. I’m new to driver development. I develop driver for the custom SMBus device and I want to get access through ACPI methods. Just for training I try to evaluate any ACPI method of any device. For example, get temperature of the thermal zone. So, I have the following code in my DSDT table:

ThermalZone(DTSZ)
{
Method(_TMP, 0, Serialized)
{
If(LEqual(OSTH, 0x00))
{
_TZ.INTM(0x00)
Store(0x01, OSTH)
}
Return(GTTP(0x00))
}
}

I try to call this method from my driver. So, I wrote driver that creates device, accepts some ioctl from user mode and returns this temperature to user. I try to evaluate this ACPI method.
So, “DeviceTree” utility shows device with name “\Device\0000006c”, device ID “ACPI\ThermalZone” and instance ID “DTSZ”. I suppose that I should send IOCTL_ACPI_EVAL_METHOD request to this device for getting temperature.

I fill input buffer:

inputBuffer.MethodNameAsUlong = (ULONG)(‘PMT_’);
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;

Then I find device by name (it’s successful):

RtlInitUnicodeString(&TargetDeviceName, L"\Device\0000006c");
status = IoGetDeviceObjectPointer(&TargetDeviceName, FILE_READ_DATA, &pFileObject, &pTargetDevice);

And finally I build request (it’s successful too) and call IoCallDriver:

pIrp = IoBuildDeviceIoControlRequest(IOCTL_ACPI_EVAL_METHOD, pTargetDevice, &inputBuffer, sizeof(ACPI_EVAL_INPUT_BUFFER), &outputBuffer, sizeof(ACPI_EVAL_OUTPUT_BUFFER), FALSE, &Event, &IoStatus);
status = IoCallDriver(pTargetDevice, pIrp);

IoCallDriver returns STATUS_NOT_SUPPORTED ("The request is not supported.
").
Please tell me, what I’m doing wrong and what I should do to evaluate this ACPI method. Thanks in advance.

Like it says in the documentation, you can’t evaluate arbitrary ACPI methods in other branch of the device tree. You have to be instantiated *directly in* the branch of the device tree that contains the namespace for the method that you’re evaluating.

In other words, you can’t send evaluate _TMP unless you’re the driver for ACPI\ThermalZone.

Peter
OSR

So I should attach my device to device stack above “ACPI/ThermalZone”, right? Or it would be better to act in some another way?

Well, yes, but…

There must be a driver there already, right? I don’t recommend you take its place.

If you attach ABOVE that driver, there’s no reason to believe the underlying driver would pass through the IOCTL_ACPI_EVAL_METHOD calls you send.

Perhaps you could try attaching as a LOWER filter, below the current driver. Don’t forget to pass through EVERYTHING you receive. And now you’re a filter… did you want to get that data back to user mode somehow? If so, you’ll need to create a control device object.

As I often ask in these threads: What are you trying to ultimately accomplish? There’s probably a MUCH easier way to do what you want… Perhaps you can briefly describe your ultimate goal?

Peter
OSR

My goal is to get data from SMBus device. As I’ve understood, the right way is evaluating ACPI methods.

Assuming you understand the methods the BIOS exports, that’ll work, yes. Or that you can alter the BIOS to fit your needs.

Another possibility would be to do this from user mode, if your BIOS exposes a WMI mapper interface.

Peter
OSR

Thank you for advice.
It looks like I’m able to modify BIOS (at least, DSDT). Not personally I, but there is such ability. But first I want to call methods, that work with SMBus and are declared in existing DSDT to determine what I need to modify and make sure that I’m able to do anything.
Now I try to get SMBus device. Of course, there is “Device(SBUS)” in DSDT, it’s situated in “_SB\PCI0” section and it contains all necessary methods for reading/writing SMBus device, but I can’t find this device in DeviceTree, I even don’t know how to find it. Only “Name(_ADR, 0x001F003)” is set for this device in DSDT and there are about 25 nearly nameless devices attached to PCI in DeviceTree.
There is target embedded system, SMBus must work only on it, it soon will be available for me. I took ACPI dump from it and there methods for working with SMBus are allocated in DSDT root, even aren’t included in any device. I don’t imagine, what device I should send ioctl to (maybe “Root\ACPI_HAL”?).
So, of course, there are difficulties on the way of finding suitable ACPI device, attaching my device to it and sending IOCTL_ACPI_EVAL_METHOD to it. By the way, as you recommended, I tried to attach my device to device stack under thermal zone, it was successful, but finally I got the same “The request is not supported” status in IoCallDriver.
Maybe WMI would be better, but there’s no “PNP0C14” device in DSDT on target system (and I don’t know and for a while can’t check if there will be such device in DeviceTree). Is it necessary to have this device for mapping ACPI to WMI?
Thanks for help once again, many things become a bit more clear for me.

Will this SMbus device always sit on the BIOS-owned SMBus controller?
If not - you don’t have to jump over all these humps.
Get another 3rd party I2C controller (a PCI card for example)
and play with your device as you wish.
– pa

Pavel, thanks for advice.
I can’t modify hardware configuration

Let’s review for a minute. I want to be sure I completely understand where you are.

  1. You want to evaluate an ACPI method named _TMP, which takes no arguments and returns one ACPI integer value.

  2. ACPI exports a device, and the _TMP method that you want to evaluate is within that device

  3. There’s currently a driver and a device instantiated on this device

  4. You don’t want to replace the existing driver, but you still want to evaluate the method.

  5. You wrote lower filter driver, VERIFIED THAT IT WAS INSTALLED DIRECTLY BELOW THE DRIVER for the device that exports the _TMP method, and that there are no other filters/drivers/devices between your driver’s device object and the ACPI PDO.

  6. You try to evaluate the _TMP method and it fails with “The request is not
    supported” status (can you please provide the specific error code).

Is that all correct??

Did you single-step through the IoCallDriver path where you sent the request? Who’s failing it??

Would you post the code that builds the ACPI request?

There’s no reason this shouldn’t work…

Peter
OSR

On 11-Sep-2012 08:45, xxxxx@gmail.com wrote:

Pavel, thanks for advice.
I can’t modify hardware configuration

This means, you don’t know how to do this, or you must use the built-in
(chipset) smbus?

Remember that you can buy a cheap I2C adapter or eval. kit like this
http://www.i2cchip.com/shop.html#I2CKIT1

and be focused on your project, rather than suffering over the esoteric
ACPI stuff.

–pa

Peter, thermal zones are implemented as raw PDOs in the ACPI driver. There
is no FDO.

Jake Oshins
Windows Kernel Team

The message offers no warranties and confers no rights.

wrote in message news:xxxxx@ntdev…

Let’s review for a minute. I want to be sure I completely understand where
you are.

  1. You want to evaluate an ACPI method named _TMP, which takes no arguments
    and returns one ACPI integer value.

  2. ACPI exports a device, and the _TMP method that you want to evaluate is
    within that device

  3. There’s currently a driver and a device instantiated on this device

  4. You don’t want to replace the existing driver, but you still want to
    evaluate the method.

  5. You wrote lower filter driver, VERIFIED THAT IT WAS INSTALLED DIRECTLY
    BELOW THE DRIVER for the device that exports the _TMP method, and that there
    are no other filters/drivers/devices between your driver’s device object and
    the ACPI PDO.

  6. You try to evaluate the _TMP method and it fails with “The request is not
    supported” status (can you please provide the specific error code).

Is that all correct??

Did you single-step through the IoCallDriver path where you sent the
request? Who’s failing it??

Would you post the code that builds the ACPI request?

There’s no reason this shouldn’t work…

Peter
OSR

Hmmm… Thanks. I wasn’t sure and didn’t bother to look it up.

So now I’m even MORE confused, because the OP seemed to indicate that there IS an FDO and that he installed a Lower Filter on it.

Peter
OSR

I must use built-in chipset, I can’t insert any other adapters.

I installed IrpTracker and saw that there are IRPs with IOCTL_ACPI_EVAL_METHOD, that are sent to the battery and AC adapter devices. I tried to attach my driver to these devices and evaluating ACPI methods was successful.
So, my final goal is to read data from custom SMBus device on another computer. There are such methods in DSDT (they don’t belong to any device). So I’ve created custom device in DSDT with methods that call these methods of reading SMBus data. Firstly I try to read data from existing thermal sensor with slave address (already shifted left) 0x98. As I understand, _HID is necessary for finding device and then to attach to it. I’m not sure that I assigned allowable _HID.
That’s my device in DSDT:
Device(SMK1)
{
Name(_HID, “ACPI2401”)
Method(GTB0, 0, NotSerialized)
{
Return(RBYT(0x98, 0x00))
}
}
I’ve inserted this device in the “PCI0” branch of DSDT (not sure that it’s correct).
Then, after modifying BIOS, this device appeared. In the “DeviceTree” device ACPI\ACPI2401 appeared in the same branch where other ACPI devices (like thermal zones) were. Then I started my WDM driver and then (in DriverEntry function) tried to find this SMK1 device by IoGetDeviceObjectPointer. It failed with code 0xC000000E (STATUS_NO_SUCH_DEVICE, “The request is not supported”).
Here are my most essential pieces of code (I don’t include here checks, setting major functions and so on):
#define ACPI_METHOD_GTB0 (ULONG)(‘0BTG’)
typedef struct _EXAMPLE_FILTER_EXTENSION
{
PDEVICE_OBJECT pNextDeviceInChain;
} EXAMPLE_FILTER_EXTENSION, *PEXAMPLE_FILTER_EXTENSION;

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
PEXAMPLE_FILTER_EXTENSION pExampleFilterDeviceContext;
NtStatus = IoCreateDevice(pDriverObject, sizeof(EXAMPLE_FILTER_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
RtlInitUnicodeString(&targetDeviceName, L"\Device\0000003c");
NtStatus = IoGetDeviceObjectPointer(&targetDeviceName, FILE_ALL_ACCESS, &pFileObject, &pTargetDevice);
}

So, maybe I should declare device in DSDT in some another way or update some windows configuration files? Or maybe I do something incorrect in my WDM driver ?

And the device shows up in Device Manager with no driver?

BTW, I don’t think you want to use “ACPIxxxx” as your ID. Why not just do “SMKDEV” or something?

Assuming this shows up in Device Manager, just have your device instantiate on that PDO… in other words, write a proper PnP driver.

Peter
OSR

Peter is right. Strings of the form “ACPIxxxx” are reserved for use by the
ACPI specification itself. You’re potentially colliding with something
defined in a future version of the spec. You need to pick a string unique
to you. I can be anything.

As for the rest of your confusion, I think that you’re conflating the BIOS
namespace with the OS namespace. Having a device with a specific name in
the DSDT says nothing about how you open that device from another driver.
You need to supply a driver for that device. That driver needs to create a
symbolic link for itself, either statically or through a PnP device
interface. Then user-mode code or other kernel-mode components and use that
symbolic link to open a handle to it and send it requests. This driver
should be the one which submits the IOCTLs to evaluate methods.

It’s also worth noting here that you’ve been experimenting by evaluating
methods which are owned by other drivers. This is mostly harmless until you
pick a method which has stateful side effects. _TMP doesn’t tend to have
any. Other thermal zone objects and some of the battery objects do. And
when you do things with side effects to stuff that’s owned by another
driver, you introduce instability into the system. Don’t do that. Evaluate
only the methods your driver owns.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

wrote in message news:xxxxx@ntdev…

And the device shows up in Device Manager with no driver?

BTW, I don’t think you want to use “ACPIxxxx” as your ID. Why not just do
“SMKDEV” or something?

Assuming this shows up in Device Manager, just have your device instantiate
on that PDO… in other words, write a proper PnP driver.

Peter
OSR

I guess he should ask for ACPI Vendor ID: http://msdn.microsoft.com/en-us/library/windows/hardware/gg463195.aspx

Michal

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-513535-
xxxxx@lists.osr.com] On Behalf Of Jake Oshins
Sent: Thursday, September 13, 2012 7:08 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Evaluating ACPI method

Peter is right. Strings of the form “ACPIxxxx” are reserved for use by the
ACPI specification itself. You’re potentially colliding with something
defined in a future version of the spec. You need to pick a string unique
to you. I can be anything.

As for the rest of your confusion, I think that you’re conflating the BIOS
namespace with the OS namespace. Having a device with a specific name in
the DSDT says nothing about how you open that device from another driver.
You need to supply a driver for that device. That driver needs to create a
symbolic link for itself, either statically or through a PnP device
interface. Then user-mode code or other kernel-mode components and use
that
symbolic link to open a handle to it and send it requests. This driver
should be the one which submits the IOCTLs to evaluate methods.

It’s also worth noting here that you’ve been experimenting by evaluating
methods which are owned by other drivers. This is mostly harmless until you
pick a method which has stateful side effects. _TMP doesn’t tend to have
any. Other thermal zone objects and some of the battery objects do. And
when you do things with side effects to stuff that’s owned by another
driver, you introduce instability into the system. Don’t do that. Evaluate
only the methods your driver owns.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

wrote in message news:xxxxx@ntdev…

And the device shows up in Device Manager with no driver?

BTW, I don’t think you want to use “ACPIxxxx” as your ID. Why not just do
“SMKDEV” or something?

Assuming this shows up in Device Manager, just have your device instantiate
on that PDO… in other words, write a proper PnP driver.

Peter
OSR


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

NOTE: The information in this message is intended for the personal and confidential use of the designated recipient(s) named above. To the extent the recipient(s) is/are bound by a non-disclosure agreement, or other agreement that contains an obligation of confidentiality, with AuthenTec, then this message and/or any attachments shall be considered confidential information and subject to the confidentiality terms of that agreement. If the reader of this message is not the intended recipient named above, you are notified that you have received this document in error, and any review, dissemination, distribution or copying of this message is strictly prohibited. If you have received this document in error, please delete the original message and notify the sender immediately.
Thank You!
AuthenTec, Inc. http://www.authentec.com/

That would be ideal, though it’s not really necessary for his closed world
machine. The real need for asking for those vendor IDs came from the ISA
PnP requirement (long predating ACPI) that those vendor IDs be representable
in 15 bits.

It will be sufficient for him to pick a string long enough that it’s unique,
probably including the company that he works for.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

“Vodicka, Michal” wrote in message news:xxxxx@ntdev…

I guess he should ask for ACPI Vendor ID:
http://msdn.microsoft.com/en-us/library/windows/hardware/gg463195.aspx

Michal

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-513535-
xxxxx@lists.osr.com] On Behalf Of Jake Oshins
Sent: Thursday, September 13, 2012 7:08 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Evaluating ACPI method

Peter is right. Strings of the form “ACPIxxxx” are reserved for use by
the
ACPI specification itself. You’re potentially colliding with something
defined in a future version of the spec. You need to pick a string unique
to you. I can be anything.

As for the rest of your confusion, I think that you’re conflating the BIOS
namespace with the OS namespace. Having a device with a specific name in
the DSDT says nothing about how you open that device from another driver.
You need to supply a driver for that device. That driver needs to create
a
symbolic link for itself, either statically or through a PnP device
interface. Then user-mode code or other kernel-mode components and use
that
symbolic link to open a handle to it and send it requests. This driver
should be the one which submits the IOCTLs to evaluate methods.

It’s also worth noting here that you’ve been experimenting by evaluating
methods which are owned by other drivers. This is mostly harmless until
you
pick a method which has stateful side effects. _TMP doesn’t tend to have
any. Other thermal zone objects and some of the battery objects do. And
when you do things with side effects to stuff that’s owned by another
driver, you introduce instability into the system. Don’t do that.
Evaluate
only the methods your driver owns.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

wrote in message news:xxxxx@ntdev…

And the device shows up in Device Manager with no driver?

BTW, I don’t think you want to use “ACPIxxxx” as your ID. Why not just do
“SMKDEV” or something?

Assuming this shows up in Device Manager, just have your device
instantiate
on that PDO… in other words, write a proper PnP driver.

Peter
OSR


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

NOTE: The information in this message is intended for the personal and
confidential use of the designated recipient(s) named above. To the extent
the recipient(s) is/are bound by a non-disclosure agreement, or other
agreement that contains an obligation of confidentiality, with AuthenTec,
then this message and/or any attachments shall be considered confidential
information and subject to the confidentiality terms of that agreement. If
the reader of this message is not the intended recipient named above, you
are notified that you have received this document in error, and any review,
dissemination, distribution or copying of this message is strictly
prohibited. If you have received this document in error, please delete the
original message and notify the sender immediately.
Thank You!
AuthenTec, Inc. http://www.authentec.com/

Thanks to all.
I’ll rename HID.
As I’ve understood, I should write PnP driver for this new DSDT device. This driver will own this device, not create new. Symbolic link will allow accessing this driver from userspace. OK.
Little question. To what device should I send request IOCTL_ACPI_EVAL_METHOD from my driver?

P.S. I had mistake in my previous post. Of course, error message was “A device which does not exist was specified”.

To your own PDO.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

wrote in message news:xxxxx@ntdev…

Thanks to all.
I’ll rename HID.
As I’ve understood, I should write PnP driver for this new DSDT device. This
driver will own this device, not create new. Symbolic link will allow
accessing this driver from userspace. OK.
Little question. To what device should I send request
IOCTL_ACPI_EVAL_METHOD from my driver?

P.S. I had mistake in my previous post. Of course, error message was “A
device which does not exist was specified”.