]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ACPI: bus: Split _OSC evaluation out of acpi_run_osc()
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 22 Dec 2025 19:14:16 +0000 (20:14 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 23 Dec 2025 16:12:00 +0000 (17:12 +0100)
Split a function for evaluating _OSC called acpi_eval_osc() out of
acpi_run_osc() to facilitate subsequent changes and add some more
parameters sanity checks to the latter.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/22963770.EfDdHjke4D@rafael.j.wysocki
drivers/acpi/bus.c

index 658c2f532dfb2557cea9b3e3fce93966f613c313..ad828dcd06577b448e6841f39a9a081c3e4ace0a 100644 (file)
@@ -196,52 +196,67 @@ static void acpi_dump_osc_data(acpi_handle handle, const guid_t *guid, int rev,
                         OSC_INVALID_REVISION_ERROR | \
                         OSC_CAPABILITIES_MASK_ERROR)
 
-acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
+static int acpi_eval_osc(acpi_handle handle, guid_t *guid, int rev,
+                        struct acpi_buffer *cap,
+                        union acpi_object in_params[at_least 4],
+                        struct acpi_buffer *output)
 {
-       u32 errors, *capbuf = context->cap.pointer;
-       acpi_status status;
        struct acpi_object_list input;
-       union acpi_object in_params[4];
        union acpi_object *out_obj;
-       guid_t guid;
-       struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
-
-       if (!context)
-               return AE_ERROR;
-       if (guid_parse(context->uuid_str, &guid))
-               return AE_ERROR;
-       context->ret.length = ACPI_ALLOCATE_BUFFER;
-       context->ret.pointer = NULL;
+       acpi_status status;
 
-       /* Setting up input parameters */
-       input.count = 4;
+       in_params[0].type = ACPI_TYPE_BUFFER;
+       in_params[0].buffer.length = sizeof(*guid);
+       in_params[0].buffer.pointer = (u8 *)guid;
+       in_params[1].type = ACPI_TYPE_INTEGER;
+       in_params[1].integer.value = rev;
+       in_params[2].type = ACPI_TYPE_INTEGER;
+       in_params[2].integer.value = cap->length / sizeof(u32);
+       in_params[3].type = ACPI_TYPE_BUFFER;
+       in_params[3].buffer.length = cap->length;
+       in_params[3].buffer.pointer = cap->pointer;
        input.pointer = in_params;
-       in_params[0].type               = ACPI_TYPE_BUFFER;
-       in_params[0].buffer.length      = 16;
-       in_params[0].buffer.pointer     = (u8 *)&guid;
-       in_params[1].type               = ACPI_TYPE_INTEGER;
-       in_params[1].integer.value      = context->rev;
-       in_params[2].type               = ACPI_TYPE_INTEGER;
-       in_params[2].integer.value      = context->cap.length/sizeof(u32);
-       in_params[3].type               = ACPI_TYPE_BUFFER;
-       in_params[3].buffer.length      = context->cap.length;
-       in_params[3].buffer.pointer     = context->cap.pointer;
-
-       status = acpi_evaluate_object(handle, "_OSC", &input, &output);
-       if (ACPI_FAILURE(status))
-               return status;
+       input.count = 4;
 
-       if (!output.length)
-               return AE_NULL_OBJECT;
+       output->length = ACPI_ALLOCATE_BUFFER;
+       output->pointer = NULL;
 
-       out_obj = output.pointer;
-       if (out_obj->type != ACPI_TYPE_BUFFER
-               || out_obj->buffer.length != context->cap.length) {
-               acpi_dump_osc_data(handle, &guid, context->rev, &context->cap);
-               acpi_handle_debug(handle, "_OSC: evaluation returned wrong type");
-               status = AE_TYPE;
-               goto out_kfree;
+       status = acpi_evaluate_object(handle, "_OSC", &input, output);
+       if (ACPI_FAILURE(status) || !output->length)
+               return -ENODATA;
+
+       out_obj = output->pointer;
+       if (out_obj->type != ACPI_TYPE_BUFFER ||
+           out_obj->buffer.length != cap->length) {
+               acpi_handle_debug(handle, "Invalid _OSC return buffer\n");
+               acpi_dump_osc_data(handle, guid, rev, cap);
+               ACPI_FREE(out_obj);
+               return -ENODATA;
        }
+
+       return 0;
+}
+
+acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
+{
+       u32 errors, *capbuf = context->cap.pointer;
+       union acpi_object in_params[4], *out_obj;
+       struct acpi_buffer output;
+       acpi_status status = AE_OK;
+       guid_t guid;
+       int ret;
+
+       if (!context || !context->cap.pointer ||
+           context->cap.length < 2 * sizeof(32) ||
+           guid_parse(context->uuid_str, &guid))
+               return AE_BAD_PARAMETER;
+
+       ret = acpi_eval_osc(handle, &guid, context->rev, &context->cap,
+                           in_params, &output);
+       if (ret)
+               return AE_ERROR;
+
+       out_obj = output.pointer;
        /* Only take defined error bits into account. */
        errors = *((u32 *)out_obj->buffer.pointer) & OSC_ERROR_MASK;
        /*