From: Armin Wolf Date: Mon, 6 Apr 2026 20:32:32 +0000 (+0200) Subject: platform/wmi: Add wmidev_invoke_procedure() X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=7e2d964f417ec13763eecfecc5d2813f63cb8da0;p=thirdparty%2Flinux.git platform/wmi: Add wmidev_invoke_procedure() Some WMI methods return no values, so the whole postprocessing of the result data is not needed for them. Add a special function for calling such WMI methods to prepare for future changes of the main wmidev_invoke_method() function. Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20260406203237.2970-2-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- diff --git a/Documentation/wmi/driver-development-guide.rst b/Documentation/wmi/driver-development-guide.rst index fbc2d9b12fe9f..5b94402874c4f 100644 --- a/Documentation/wmi/driver-development-guide.rst +++ b/Documentation/wmi/driver-development-guide.rst @@ -106,7 +106,8 @@ WMI method drivers WMI drivers can call WMI device methods using wmidev_invoke_method(). For each WMI method invocation the WMI driver needs to provide the instance number and the method ID, as well as -a buffer with the method arguments and optionally a buffer for the results. +a buffer with the method arguments and optionally a buffer for the results. When calling WMI +methods that do not return any values, wmidev_invoke_procedure() should be used instead. The layout of said buffers is device-specific and described by the Binary MOF data associated with a given WMI device. Said Binary MOF data also describes the method ID of a given WMI method diff --git a/drivers/platform/wmi/core.c b/drivers/platform/wmi/core.c index b8e6b9a421c62..7cc5ca11a60d0 100644 --- a/drivers/platform/wmi/core.c +++ b/drivers/platform/wmi/core.c @@ -427,6 +427,50 @@ int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id, } EXPORT_SYMBOL_GPL(wmidev_invoke_method); +/** + * wmidev_invoke_procedure - Invoke a WMI method that does not return values + * @wdev: A wmi bus device from a driver + * @instance: Instance index + * @method_id: Method ID to call + * @in: Mandatory WMI buffer containing input for the method call + * + * Invoke a WMI method that does not return any values. Use wmidev_invoke_method() + * for WMI methods that do return values. + * + * Return: 0 on success or negative error code on failure. + */ +int wmidev_invoke_procedure(struct wmi_device *wdev, u8 instance, u32 method_id, + const struct wmi_buffer *in) +{ + struct wmi_block *wblock = container_of(wdev, struct wmi_block, dev); + struct acpi_buffer ain; + acpi_status status; + int ret; + + if (wblock->gblock.flags & ACPI_WMI_STRING) { + ret = wmi_marshal_string(in, &ain); + if (ret < 0) + return ret; + } else { + if (in->length > U32_MAX) + return -E2BIG; + + ain.length = in->length; + ain.pointer = in->data; + } + + status = wmidev_evaluate_method(wdev, instance, method_id, &ain, NULL); + + if (wblock->gblock.flags & ACPI_WMI_STRING) + kfree(ain.pointer); + + if (ACPI_FAILURE(status)) + return -EIO; + + return 0; +} +EXPORT_SYMBOL_GPL(wmidev_invoke_procedure); + static acpi_status __query_block(struct wmi_block *wblock, u8 instance, struct acpi_buffer *out) { diff --git a/include/linux/wmi.h b/include/linux/wmi.h index 75cb0c7cfe571..b00950dc1231a 100644 --- a/include/linux/wmi.h +++ b/include/linux/wmi.h @@ -70,6 +70,9 @@ ssize_t wmi_string_from_utf8s(struct wmi_string *str, size_t max_chars, const u8 int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id, const struct wmi_buffer *in, struct wmi_buffer *out); +int wmidev_invoke_procedure(struct wmi_device *wdev, u8 instance, u32 method_id, + const struct wmi_buffer *in); + int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *out); int wmidev_set_block(struct wmi_device *wdev, u8 instance, const struct wmi_buffer *in);