mirror of
https://github.com/torvalds/linux.git
synced 2026-03-13 22:36:17 +01:00
New WMI drivers should use the new buffer-based WMI API instead of the deprecated ACPI-based API. Update the driver development guide to recommend the buffer-based API to driver developers and explain the purpose of struct wmi_buffer. Also update the ACPI interface documentation to describe the conversion rules for converting ACPI objects into WMI buffers. Reviewed-by: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://patch.msgid.link/20260116204116.4030-10-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
174 lines
8.8 KiB
ReStructuredText
174 lines
8.8 KiB
ReStructuredText
.. SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
==================
|
|
ACPI WMI interface
|
|
==================
|
|
|
|
The ACPI WMI interface is a proprietary extension of the ACPI specification made
|
|
by Microsoft to allow hardware vendors to embed WMI (Windows Management Instrumentation)
|
|
objects inside their ACPI firmware. Typical functions implemented over ACPI WMI
|
|
are hotkey events on modern notebooks and configuration of BIOS options.
|
|
|
|
PNP0C14 ACPI device
|
|
-------------------
|
|
|
|
Discovery of WMI objects is handled by defining ACPI devices with a PNP ID
|
|
of ``PNP0C14``. These devices will contain a set of ACPI buffers and methods
|
|
used for mapping and execution of WMI methods and/or queries. If there exist
|
|
multiple of such devices, then each device is required to have a
|
|
unique ACPI UID.
|
|
|
|
_WDG buffer
|
|
-----------
|
|
|
|
The ``_WDG`` buffer is used to discover WMI objects and is required to be
|
|
static. Its internal structure consists of data blocks with a size of 20 bytes,
|
|
containing the following data:
|
|
|
|
======= =============== =====================================================
|
|
Offset Size (in bytes) Content
|
|
======= =============== =====================================================
|
|
0x00 16 128 bit Variant 2 object GUID.
|
|
0x10 2 2 character method ID or single byte notification ID.
|
|
0x12 1 Object instance count.
|
|
0x13 1 Object flags.
|
|
======= =============== =====================================================
|
|
|
|
The WMI object flags control whether the method or notification ID is used:
|
|
|
|
- 0x1: Data block is expensive to collect.
|
|
- 0x2: Data block contains WMI methods.
|
|
- 0x4: Data block contains ASCIZ string.
|
|
- 0x8: Data block describes a WMI event, use notification ID instead
|
|
of method ID.
|
|
|
|
Each WMI object GUID can appear multiple times inside a system.
|
|
The method/notification ID is used to construct the ACPI method names used for
|
|
interacting with the WMI object.
|
|
|
|
WQxx ACPI methods
|
|
-----------------
|
|
|
|
If a data block does not contain WMI methods, then its content can be retrieved
|
|
by this required ACPI method. The last two characters of the ACPI method name
|
|
are the method ID of the data block to query. Their single parameter is an
|
|
integer describing the instance which should be queried. This parameter can be
|
|
omitted if the data block contains only a single instance.
|
|
|
|
WSxx ACPI methods
|
|
-----------------
|
|
|
|
Similar to the ``WQxx`` ACPI methods, except that it is optional and takes an
|
|
additional buffer as its second argument. The instance argument also cannot
|
|
be omitted.
|
|
|
|
WMxx ACPI methods
|
|
-----------------
|
|
|
|
Used for executing WMI methods associated with a data block. The last two
|
|
characters of the ACPI method name are the method ID of the data block
|
|
containing the WMI methods. Their first parameter is a integer describing the
|
|
instance which methods should be executed. The second parameter is an integer
|
|
describing the WMI method ID to execute, and the third parameter is a buffer
|
|
containing the WMI method parameters. If the data block is marked as containing
|
|
an ASCIZ string, then this buffer should contain an ASCIZ string. The ACPI
|
|
method will return the result of the executed WMI method.
|
|
|
|
WExx ACPI methods
|
|
-----------------
|
|
|
|
Used for optionally enabling/disabling WMI events, the last two characters of
|
|
the ACPI method are the notification ID of the data block describing the WMI
|
|
event as hexadecimal value. Their first parameter is an integer with a value
|
|
of 0 if the WMI event should be disabled, other values will enable
|
|
the WMI event.
|
|
|
|
Those ACPI methods are always called even for WMI events not registered as
|
|
being expensive to collect to match the behavior of the Windows driver.
|
|
|
|
WCxx ACPI methods
|
|
-----------------
|
|
Similar to the ``WExx`` ACPI methods, except that instead of WMI events it controls
|
|
data collection of data blocks registered as being expensive to collect. Thus the
|
|
last two characters of the ACPI method name are the method ID of the data block
|
|
to enable/disable.
|
|
|
|
Those ACPI methods are also called before setting data blocks to match the
|
|
behavior of the Windows driver.
|
|
|
|
_WED ACPI method
|
|
----------------
|
|
|
|
Used to retrieve additional WMI event data, its single parameter is a integer
|
|
holding the notification ID of the event. This method should be evaluated every
|
|
time an ACPI notification is received, since some ACPI implementations use a
|
|
queue to store WMI event data items. This queue will overflow after a couple
|
|
of WMI events are received without retrieving the associated WMI event data.
|
|
|
|
Conversion rules for ACPI data types
|
|
------------------------------------
|
|
|
|
Consumers of the ACPI-WMI interface use binary buffers to exchange data with the WMI driver core,
|
|
with the internal structure of the buffer being only know to the consumers. The WMI driver core is
|
|
thus responsible for converting the data inside the buffer into an appropriate ACPI data type for
|
|
consumption by the ACPI firmware. Additionally, any data returned by the various ACPI methods needs
|
|
to be converted back into a binary buffer.
|
|
|
|
The layout of said buffers is defined by the MOF description of the WMI method or data block in
|
|
question [1]_:
|
|
|
|
=============== ======================================================================= =========
|
|
Data Type Layout Alignment
|
|
=============== ======================================================================= =========
|
|
``string`` Starts with an unsigned 16-bit little endian integer specifying 2 bytes
|
|
the length of the string data in bytes, followed by the string data
|
|
encoded as UTF-16LE with **optional** NULL termination and padding.
|
|
Keep in mind that some firmware implementations might depend on the
|
|
terminating NULL character to be present. Also the padding should
|
|
always be performed with NULL characters.
|
|
``boolean`` Single byte where 0 means ``false`` and nonzero means ``true``. 1 byte
|
|
``sint8`` Signed 8-bit integer. 1 byte
|
|
``uint8`` Unsigned 8-bit integer. 1 byte
|
|
``sint16`` Signed 16-bit little endian integer. 2 bytes
|
|
``uint16`` Unsigned 16-bit little endian integer. 2 bytes
|
|
``sint32`` Signed 32-bit little endian integer. 4 bytes
|
|
``uint32`` Unsigned 32-bit little endian integer. 4 bytes
|
|
``sint64`` Signed 64-bit little endian integer. 8 bytes
|
|
``uint64`` Unsigned 64-bit little endian integer. 8 bytes
|
|
``datetime`` A fixed-length 25-character UTF-16LE string with the format 2 bytes
|
|
*yyyymmddhhmmss.mmmmmmsutc* where *yyyy* is the 4-digit year, *mm* is
|
|
the 2-digit month, *dd* is the 2-digit day, *hh* is the 2-digit hour
|
|
based on a 24-hour clock, *mm* is the 2-digit minute, *ss* is the
|
|
2-digit second, *mmmmmm* is the 6-digit microsecond, *s* is a plus or
|
|
minus character depending on whether *utc* is a positive or negative
|
|
offset from UTC (or a colon if the date is an interval). Unpopulated
|
|
fields should be filled with asterisks.
|
|
=============== ======================================================================= =========
|
|
|
|
Arrays should be aligned based on the alignment of their base type, while objects should be
|
|
aligned based on the largest alignment of an element inside them.
|
|
|
|
All buffers returned by the WMI driver core are 8-byte aligned. When converting ACPI data types
|
|
into such buffers the following conversion rules apply:
|
|
|
|
=============== ============================================================
|
|
ACPI Data Type Converted into
|
|
=============== ============================================================
|
|
Buffer Copied as-is.
|
|
Integer Converted into a ``uint32``.
|
|
String Converted into a ``string`` with a terminating NULL character
|
|
to match the behavior the of the Windows driver.
|
|
Package Each element inside the package is converted with alignment
|
|
of the resulting data types being respected. Nested packages
|
|
are not allowed.
|
|
=============== ============================================================
|
|
|
|
The Windows driver does attempt to handle nested packages, but this results in internal data
|
|
structures (``_ACPI_METHOD_ARGUMENT_V1``) erroneously being copied into the resulting buffer.
|
|
ACPI firmware implementations should thus not return nested packages from ACPI methods
|
|
associated with the ACPI-WMI interface.
|
|
|
|
References
|
|
==========
|
|
|
|
.. [1] https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/driver-defined-wmi-data-items
|