Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/wmi: Update driver development guide

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>

authored by

Armin Wolf and committed by
Ilpo Järvinen
2177a022 926a2665

+121 -23
+68
Documentation/wmi/acpi-interface.rst
··· 104 104 time an ACPI notification is received, since some ACPI implementations use a 105 105 queue to store WMI event data items. This queue will overflow after a couple 106 106 of WMI events are received without retrieving the associated WMI event data. 107 + 108 + Conversion rules for ACPI data types 109 + ------------------------------------ 110 + 111 + Consumers of the ACPI-WMI interface use binary buffers to exchange data with the WMI driver core, 112 + with the internal structure of the buffer being only know to the consumers. The WMI driver core is 113 + thus responsible for converting the data inside the buffer into an appropriate ACPI data type for 114 + consumption by the ACPI firmware. Additionally, any data returned by the various ACPI methods needs 115 + to be converted back into a binary buffer. 116 + 117 + The layout of said buffers is defined by the MOF description of the WMI method or data block in 118 + question [1]_: 119 + 120 + =============== ======================================================================= ========= 121 + Data Type Layout Alignment 122 + =============== ======================================================================= ========= 123 + ``string`` Starts with an unsigned 16-bit little endian integer specifying 2 bytes 124 + the length of the string data in bytes, followed by the string data 125 + encoded as UTF-16LE with **optional** NULL termination and padding. 126 + Keep in mind that some firmware implementations might depend on the 127 + terminating NULL character to be present. Also the padding should 128 + always be performed with NULL characters. 129 + ``boolean`` Single byte where 0 means ``false`` and nonzero means ``true``. 1 byte 130 + ``sint8`` Signed 8-bit integer. 1 byte 131 + ``uint8`` Unsigned 8-bit integer. 1 byte 132 + ``sint16`` Signed 16-bit little endian integer. 2 bytes 133 + ``uint16`` Unsigned 16-bit little endian integer. 2 bytes 134 + ``sint32`` Signed 32-bit little endian integer. 4 bytes 135 + ``uint32`` Unsigned 32-bit little endian integer. 4 bytes 136 + ``sint64`` Signed 64-bit little endian integer. 8 bytes 137 + ``uint64`` Unsigned 64-bit little endian integer. 8 bytes 138 + ``datetime`` A fixed-length 25-character UTF-16LE string with the format 2 bytes 139 + *yyyymmddhhmmss.mmmmmmsutc* where *yyyy* is the 4-digit year, *mm* is 140 + the 2-digit month, *dd* is the 2-digit day, *hh* is the 2-digit hour 141 + based on a 24-hour clock, *mm* is the 2-digit minute, *ss* is the 142 + 2-digit second, *mmmmmm* is the 6-digit microsecond, *s* is a plus or 143 + minus character depending on whether *utc* is a positive or negative 144 + offset from UTC (or a colon if the date is an interval). Unpopulated 145 + fields should be filled with asterisks. 146 + =============== ======================================================================= ========= 147 + 148 + Arrays should be aligned based on the alignment of their base type, while objects should be 149 + aligned based on the largest alignment of an element inside them. 150 + 151 + All buffers returned by the WMI driver core are 8-byte aligned. When converting ACPI data types 152 + into such buffers the following conversion rules apply: 153 + 154 + =============== ============================================================ 155 + ACPI Data Type Converted into 156 + =============== ============================================================ 157 + Buffer Copied as-is. 158 + Integer Converted into a ``uint32``. 159 + String Converted into a ``string`` with a terminating NULL character 160 + to match the behavior the of the Windows driver. 161 + Package Each element inside the package is converted with alignment 162 + of the resulting data types being respected. Nested packages 163 + are not allowed. 164 + =============== ============================================================ 165 + 166 + The Windows driver does attempt to handle nested packages, but this results in internal data 167 + structures (``_ACPI_METHOD_ARGUMENT_V1``) erroneously being copied into the resulting buffer. 168 + ACPI firmware implementations should thus not return nested packages from ACPI methods 169 + associated with the ACPI-WMI interface. 170 + 171 + References 172 + ========== 173 + 174 + .. [1] https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/driver-defined-wmi-data-items
+53 -23
Documentation/wmi/driver-development-guide.rst
··· 70 70 .probe = foo_probe, 71 71 .remove = foo_remove, /* optional, devres is preferred */ 72 72 .shutdown = foo_shutdown, /* optional, called during shutdown */ 73 - .notify = foo_notify, /* optional, for event handling */ 73 + .notify_new = foo_notify, /* optional, for event handling */ 74 74 .no_notify_data = true, /* optional, enables events containing no additional data */ 75 75 .no_singleton = true, /* required for new WMI drivers */ 76 76 }; ··· 90 90 or kexec. Most WMI drivers need no special shutdown handling and can thus omit this callback. 91 91 92 92 Please note that new WMI drivers are required to be able to be instantiated multiple times, 93 - and are forbidden from using any deprecated GUID-based WMI functions. This means that the 94 - WMI driver should be prepared for the scenario that multiple matching WMI devices are present 95 - on a given machine. 93 + and are forbidden from using any deprecated GUID-based or ACPI-based WMI functions. This means 94 + that the WMI driver should be prepared for the scenario that multiple matching WMI devices are 95 + present on a given machine. 96 96 97 97 Because of this, WMI drivers should use the state container design pattern as described in 98 98 Documentation/driver-api/driver-model/design-patterns.rst. ··· 104 104 WMI method drivers 105 105 ------------------ 106 106 107 - WMI drivers can call WMI device methods using wmidev_evaluate_method(), the 108 - structure of the ACPI buffer passed to this function is device-specific and usually 109 - needs some tinkering to get right. Looking at the ACPI tables containing the WMI 110 - device usually helps here. The method id and instance number passed to this function 111 - are also device-specific, looking at the decoded Binary MOF is usually enough to 112 - find the right values. 107 + WMI drivers can call WMI device methods using wmidev_invoke_method(). For each WMI method 108 + invocation the WMI driver needs to provide the instance number and the method ID, as well as 109 + a buffer with the method arguments and optionally a buffer for the results. 113 110 114 - The maximum instance number can be retrieved during runtime using wmidev_instance_count(). 111 + The layout of said buffers is device-specific and described by the Binary MOF data associated 112 + with a given WMI device. Said Binary MOF data also describes the method ID of a given WMI method 113 + with the ``WmiMethodId`` qualifier. WMI devices exposing WMI methods usually expose only a single 114 + instance (instance number 0), but in theory can expose multiple instances as well. In such a case 115 + the number of instances can be retrieved using wmidev_instance_count(). 115 116 116 - Take a look at drivers/platform/x86/inspur_platform_profile.c for an example WMI method driver. 117 + Take a look at drivers/platform/x86/intel/wmi/thunderbolt.c for an example WMI method driver. 117 118 118 119 WMI data block drivers 119 120 ---------------------- 120 121 121 - WMI drivers can query WMI device data blocks using wmidev_block_query(), the 122 - structure of the returned ACPI object is again device-specific. Some WMI devices 123 - also allow for setting data blocks using wmidev_block_set(). 122 + WMI drivers can query WMI data blocks using wmidev_query_block(), the layout of the returned 123 + buffer is again device-specific and described by the Binary MOF data. Some WMI data blocks are 124 + also writeable and can be set using wmidev_set_block(). The number of data block instances can 125 + again be retrieved using wmidev_instance_count(). 124 126 125 - The maximum instance number can also be retrieved using wmidev_instance_count(). 126 - 127 - Take a look at drivers/platform/x86/intel/wmi/sbl-fw-update.c for an example 128 - WMI data block driver. 127 + Take a look at drivers/platform/x86/intel/wmi/sbl-fw-update.c for an example WMI data block driver. 129 128 130 129 WMI event drivers 131 130 ----------------- 132 131 133 - WMI drivers can receive WMI events via the notify() callback inside the struct wmi_driver. 132 + WMI drivers can receive WMI events via the notify_new() callback inside the struct wmi_driver. 134 133 The WMI subsystem will then take care of setting up the WMI event accordingly. Please note that 135 - the structure of the ACPI object passed to this callback is device-specific, and freeing the 136 - ACPI object is being done by the WMI subsystem, not the driver. 134 + the layout of the buffer passed to this callback is device-specific, and freeing of the buffer 135 + is done by the WMI subsystem itself, not the driver. 137 136 138 - The WMI driver core will take care that the notify() callback will only be called after 137 + The WMI driver core will take care that the notify_new() callback will only be called after 139 138 the probe() callback has been called, and that no events are being received by the driver 140 139 right before and after calling its remove() or shutdown() callback. 141 140 ··· 145 146 the ``no_notify_data`` flag inside struct wmi_driver should be set to ``true``. 146 147 147 148 Take a look at drivers/platform/x86/xiaomi-wmi.c for an example WMI event driver. 149 + 150 + Exchanging data with the WMI driver core 151 + ---------------------------------------- 152 + 153 + WMI drivers can exchange data with the WMI driver core using struct wmi_buffer. The internal 154 + structure of those buffers is device-specific and only known by the WMI driver. Because of this 155 + the WMI driver itself is responsible for parsing and validating the data received from its 156 + WMI device. 157 + 158 + The structure of said buffers is described by the MOF data associated with the WMI device in 159 + question. When such a buffer contains multiple data items it usually makes sense to define a 160 + C structure and use it during parsing. Since the WMI driver core guarantees that all buffers 161 + received from a WMI device are aligned on an 8-byte boundary, WMI drivers can simply perform 162 + a cast between the WMI buffer data and this C structure. 163 + 164 + This however should only be done after the size of the buffer was verified to be large enough 165 + to hold the whole C structure. WMI drivers should reject undersized buffers as they are usually 166 + sent by the WMI device to signal an internal error. Oversized buffers however should be accepted 167 + to emulate the behavior of the Windows WMI implementation. 168 + 169 + When defining a C structure for parsing WMI buffers the alignment of the data items should be 170 + respected. This is especially important for 64-bit integers as those have different alignments 171 + on 64-bit (8-byte alignment) and 32-bit (4-byte alignment) architectures. It is thus a good idea 172 + to manually specify the alignment of such data items or mark the whole structure as packed when 173 + appropriate. Integer data items in general are little-endian integers and should be marked as 174 + such using ``__le64`` and friends. When parsing WMI string data items the struct wmi_string should 175 + be used as WMI strings have a different layout than C strings. 176 + 177 + See Documentation/wmi/acpi-interface.rst for more information regarding the binary format 178 + of WMI data items. 148 179 149 180 Handling multiple WMI devices at once 150 181 ------------------------------------- ··· 200 171 When developing WMI drivers, there are a couple of things which should be avoided: 201 172 202 173 - usage of the deprecated GUID-based WMI interface which uses GUIDs instead of WMI device structs 174 + - usage of the deprecated ACPI-based WMI interface which uses ACPI objects instead of plain buffers 203 175 - bypassing of the WMI subsystem when talking to WMI devices 204 176 - WMI drivers which cannot be instantiated multiple times. 205 177