Unverified Commit 465dc9da authored by Rong Zhang's avatar Rong Zhang Committed by Ilpo Järvinen
Browse files

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: default avatarArmin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/f1787927-b655-4321-b9d9-bc12353c72db@gmx.de/


Signed-off-by: default avatarRong Zhang <i@rong.moe>
Reviewed-by: default avatarDerek J. Clark <derekjohn.clark@gmail.com>
Tested-by: default avatarDerek J. Clark <derekjohn.clark@gmail.com>
Reviewed-by: default avatarArmin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/20260120182104.163424-2-i@rong.moe


Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
parent 2177a022
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -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)
		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 = 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;