diff options
| author | Rong Zhang <i@rong.moe> | 2026-01-20 21:20:02 +0300 |
|---|---|---|
| committer | Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | 2026-01-21 11:49:48 +0300 |
| commit | 465dc9da8ff61a69e649ec2d402d8e06034f4585 (patch) | |
| tree | d4431d389711a610e89525b9faa71fb92d9ce5e0 | |
| parent | 2177a02246ffef9ed4a01af2942119e601312965 (diff) | |
| download | linux-465dc9da8ff61a69e649ec2d402d8e06034f4585.tar.xz | |
platform/x86: lenovo-wmi-helpers: Convert returned buffer into u32
The Windows WMI-ACPI driver converts all ACPI objects into a common
buffer format, so returning a buffer with four bytes will look like an
integer for WMI consumers under Windows.
Therefore, some devices may simply implement the corresponding ACPI
methods to always return a buffer. While lwmi_dev_evaluate_int() expects
an integer (u32), convert returned >=4B buffer into u32 to support these
devices.
Suggested-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/f1787927-b655-4321-b9d9-bc12353c72db@gmx.de/
Signed-off-by: Rong Zhang <i@rong.moe>
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Tested-by: Derek J. Clark <derekjohn.clark@gmail.com>
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/20260120182104.163424-2-i@rong.moe
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
| -rw-r--r-- | drivers/platform/x86/lenovo/wmi-helpers.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/platform/x86/lenovo/wmi-helpers.c b/drivers/platform/x86/lenovo/wmi-helpers.c index f6fef6296251..7379defac500 100644 --- a/drivers/platform/x86/lenovo/wmi-helpers.c +++ b/drivers/platform/x86/lenovo/wmi-helpers.c @@ -21,6 +21,7 @@ #include <linux/errno.h> #include <linux/export.h> #include <linux/module.h> +#include <linux/unaligned.h> #include <linux/wmi.h> #include "wmi-helpers.h" @@ -59,10 +60,24 @@ int lwmi_dev_evaluate_int(struct wmi_device *wdev, u8 instance, u32 method_id, if (!ret_obj) return -ENODATA; - if (ret_obj->type != ACPI_TYPE_INTEGER) - return -ENXIO; + switch (ret_obj->type) { + /* + * The ACPI method may simply return a buffer when a u32 + * is expected. This is valid on Windows as its WMI-ACPI + * driver converts everything to a common buffer. + */ + case ACPI_TYPE_BUFFER: + if (ret_obj->buffer.length < sizeof(u32)) + return -ENXIO; - *retval = (u32)ret_obj->integer.value; + *retval = get_unaligned_le32(ret_obj->buffer.pointer); + return 0; + case ACPI_TYPE_INTEGER: + *retval = (u32)ret_obj->integer.value; + return 0; + default: + return -ENXIO; + } } return 0; |
