1*95857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 295b482a8SLen Brown /****************************************************************************** 395b482a8SLen Brown * 495b482a8SLen Brown * Module Name: uteval - Object evaluation 595b482a8SLen Brown * 6da6f8320SBob Moore * Copyright (C) 2000 - 2018, Intel Corp. 795b482a8SLen Brown * 8*95857638SErik Schmauss *****************************************************************************/ 995b482a8SLen Brown 1095b482a8SLen Brown #include <acpi/acpi.h> 11e2f7a777SLen Brown #include "accommon.h" 12e2f7a777SLen Brown #include "acnamesp.h" 1395b482a8SLen Brown 1495b482a8SLen Brown #define _COMPONENT ACPI_UTILITIES 1595b482a8SLen Brown ACPI_MODULE_NAME("uteval") 1695b482a8SLen Brown 1795b482a8SLen Brown /******************************************************************************* 1895b482a8SLen Brown * 1995b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_object 2095b482a8SLen Brown * 2195b482a8SLen Brown * PARAMETERS: prefix_node - Starting node 22ba494beeSBob Moore * path - Path to object from starting node 2395b482a8SLen Brown * expected_return_types - Bitmap of allowed return types 2495b482a8SLen Brown * return_desc - Where a return value is stored 2595b482a8SLen Brown * 2695b482a8SLen Brown * RETURN: Status 2795b482a8SLen Brown * 2895b482a8SLen Brown * DESCRIPTION: Evaluates a namespace object and verifies the type of the 2995b482a8SLen Brown * return object. Common code that simplifies accessing objects 3095b482a8SLen Brown * that have required return objects of fixed types. 3195b482a8SLen Brown * 3295b482a8SLen Brown * NOTE: Internal function, no parameter validation 3395b482a8SLen Brown * 3495b482a8SLen Brown ******************************************************************************/ 3595b482a8SLen Brown 3695b482a8SLen Brown acpi_status 3795b482a8SLen Brown acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, 380dfaaa3dSBob Moore const char *path, 3995b482a8SLen Brown u32 expected_return_btypes, 4095b482a8SLen Brown union acpi_operand_object **return_desc) 4195b482a8SLen Brown { 4295b482a8SLen Brown struct acpi_evaluate_info *info; 4395b482a8SLen Brown acpi_status status; 4495b482a8SLen Brown u32 return_btype; 4595b482a8SLen Brown 4695b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_object); 4795b482a8SLen Brown 4895b482a8SLen Brown /* Allocate the evaluation information block */ 4995b482a8SLen Brown 5095b482a8SLen Brown info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 5195b482a8SLen Brown if (!info) { 5295b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 5395b482a8SLen Brown } 5495b482a8SLen Brown 5595b482a8SLen Brown info->prefix_node = prefix_node; 5629a241ccSBob Moore info->relative_pathname = path; 5795b482a8SLen Brown 5895b482a8SLen Brown /* Evaluate the object/method */ 5995b482a8SLen Brown 6095b482a8SLen Brown status = acpi_ns_evaluate(info); 6195b482a8SLen Brown if (ACPI_FAILURE(status)) { 6295b482a8SLen Brown if (status == AE_NOT_FOUND) { 6395b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 6495b482a8SLen Brown "[%4.4s.%s] was not found\n", 6595b482a8SLen Brown acpi_ut_get_node_name(prefix_node), 6695b482a8SLen Brown path)); 6795b482a8SLen Brown } else { 6895b482a8SLen Brown ACPI_ERROR_METHOD("Method execution failed", 6995b482a8SLen Brown prefix_node, path, status); 7095b482a8SLen Brown } 7195b482a8SLen Brown 7295b482a8SLen Brown goto cleanup; 7395b482a8SLen Brown } 7495b482a8SLen Brown 7595b482a8SLen Brown /* Did we get a return object? */ 7695b482a8SLen Brown 7795b482a8SLen Brown if (!info->return_object) { 7895b482a8SLen Brown if (expected_return_btypes) { 7995b482a8SLen Brown ACPI_ERROR_METHOD("No object was returned from", 8095b482a8SLen Brown prefix_node, path, AE_NOT_EXIST); 8195b482a8SLen Brown 8295b482a8SLen Brown status = AE_NOT_EXIST; 8395b482a8SLen Brown } 8495b482a8SLen Brown 8595b482a8SLen Brown goto cleanup; 8695b482a8SLen Brown } 8795b482a8SLen Brown 8895b482a8SLen Brown /* Map the return object type to the bitmapped type */ 8995b482a8SLen Brown 903371c19cSBob Moore switch ((info->return_object)->common.type) { 9195b482a8SLen Brown case ACPI_TYPE_INTEGER: 921d1ea1b7SChao Guan 9395b482a8SLen Brown return_btype = ACPI_BTYPE_INTEGER; 9495b482a8SLen Brown break; 9595b482a8SLen Brown 9695b482a8SLen Brown case ACPI_TYPE_BUFFER: 971d1ea1b7SChao Guan 9895b482a8SLen Brown return_btype = ACPI_BTYPE_BUFFER; 9995b482a8SLen Brown break; 10095b482a8SLen Brown 10195b482a8SLen Brown case ACPI_TYPE_STRING: 1021d1ea1b7SChao Guan 10395b482a8SLen Brown return_btype = ACPI_BTYPE_STRING; 10495b482a8SLen Brown break; 10595b482a8SLen Brown 10695b482a8SLen Brown case ACPI_TYPE_PACKAGE: 1071d1ea1b7SChao Guan 10895b482a8SLen Brown return_btype = ACPI_BTYPE_PACKAGE; 10995b482a8SLen Brown break; 11095b482a8SLen Brown 11195b482a8SLen Brown default: 1121d1ea1b7SChao Guan 11395b482a8SLen Brown return_btype = 0; 11495b482a8SLen Brown break; 11595b482a8SLen Brown } 11695b482a8SLen Brown 11795b482a8SLen Brown if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { 11895b482a8SLen Brown /* 11995b482a8SLen Brown * We received a return object, but one was not expected. This can 12095b482a8SLen Brown * happen frequently if the "implicit return" feature is enabled. 12195b482a8SLen Brown * Just delete the return object and return AE_OK. 12295b482a8SLen Brown */ 12395b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 12495b482a8SLen Brown goto cleanup; 12595b482a8SLen Brown } 12695b482a8SLen Brown 12795b482a8SLen Brown /* Is the return object one of the expected types? */ 12895b482a8SLen Brown 12995b482a8SLen Brown if (!(expected_return_btypes & return_btype)) { 13095b482a8SLen Brown ACPI_ERROR_METHOD("Return object type is incorrect", 13195b482a8SLen Brown prefix_node, path, AE_TYPE); 13295b482a8SLen Brown 13395b482a8SLen Brown ACPI_ERROR((AE_INFO, 134f6a22b0bSBob Moore "Type returned from %s was incorrect: %s, expected Btypes: 0x%X", 13595b482a8SLen Brown path, 13695b482a8SLen Brown acpi_ut_get_object_type_name(info->return_object), 13795b482a8SLen Brown expected_return_btypes)); 13895b482a8SLen Brown 13995b482a8SLen Brown /* On error exit, we must delete the return object */ 14095b482a8SLen Brown 14195b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 14295b482a8SLen Brown status = AE_TYPE; 14395b482a8SLen Brown goto cleanup; 14495b482a8SLen Brown } 14595b482a8SLen Brown 14695b482a8SLen Brown /* Object type is OK, return it */ 14795b482a8SLen Brown 14895b482a8SLen Brown *return_desc = info->return_object; 14995b482a8SLen Brown 15095b482a8SLen Brown cleanup: 15195b482a8SLen Brown ACPI_FREE(info); 15295b482a8SLen Brown return_ACPI_STATUS(status); 15395b482a8SLen Brown } 15495b482a8SLen Brown 15595b482a8SLen Brown /******************************************************************************* 15695b482a8SLen Brown * 15795b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_numeric_object 15895b482a8SLen Brown * 15995b482a8SLen Brown * PARAMETERS: object_name - Object name to be evaluated 16095b482a8SLen Brown * device_node - Node for the device 161ba494beeSBob Moore * value - Where the value is returned 16295b482a8SLen Brown * 16395b482a8SLen Brown * RETURN: Status 16495b482a8SLen Brown * 16595b482a8SLen Brown * DESCRIPTION: Evaluates a numeric namespace object for a selected device 16615b8dd53SBob Moore * and stores result in *Value. 16795b482a8SLen Brown * 16895b482a8SLen Brown * NOTE: Internal function, no parameter validation 16995b482a8SLen Brown * 17095b482a8SLen Brown ******************************************************************************/ 17195b482a8SLen Brown 17295b482a8SLen Brown acpi_status 1730dfaaa3dSBob Moore acpi_ut_evaluate_numeric_object(const char *object_name, 17495b482a8SLen Brown struct acpi_namespace_node *device_node, 1755df7e6cbSBob Moore u64 *value) 17695b482a8SLen Brown { 17795b482a8SLen Brown union acpi_operand_object *obj_desc; 17895b482a8SLen Brown acpi_status status; 17995b482a8SLen Brown 18095b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); 18195b482a8SLen Brown 18295b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, object_name, 18395b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 18495b482a8SLen Brown if (ACPI_FAILURE(status)) { 18595b482a8SLen Brown return_ACPI_STATUS(status); 18695b482a8SLen Brown } 18795b482a8SLen Brown 18895b482a8SLen Brown /* Get the returned Integer */ 18995b482a8SLen Brown 19015b8dd53SBob Moore *value = obj_desc->integer.value; 19195b482a8SLen Brown 19295b482a8SLen Brown /* On exit, we must delete the return object */ 19395b482a8SLen Brown 19495b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 19595b482a8SLen Brown return_ACPI_STATUS(status); 19695b482a8SLen Brown } 19795b482a8SLen Brown 19895b482a8SLen Brown /******************************************************************************* 19995b482a8SLen Brown * 20095b482a8SLen Brown * FUNCTION: acpi_ut_execute_STA 20195b482a8SLen Brown * 20295b482a8SLen Brown * PARAMETERS: device_node - Node for the device 203ba494beeSBob Moore * flags - Where the status flags are returned 20495b482a8SLen Brown * 20595b482a8SLen Brown * RETURN: Status 20695b482a8SLen Brown * 20795b482a8SLen Brown * DESCRIPTION: Executes _STA for selected device and stores results in 208a7d5caf6SBob Moore * *Flags. If _STA does not exist, then the device is assumed 209a7d5caf6SBob Moore * to be present/functional/enabled (as per the ACPI spec). 21095b482a8SLen Brown * 21195b482a8SLen Brown * NOTE: Internal function, no parameter validation 21295b482a8SLen Brown * 21395b482a8SLen Brown ******************************************************************************/ 21495b482a8SLen Brown 21595b482a8SLen Brown acpi_status 21695b482a8SLen Brown acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) 21795b482a8SLen Brown { 21895b482a8SLen Brown union acpi_operand_object *obj_desc; 21995b482a8SLen Brown acpi_status status; 22095b482a8SLen Brown 22195b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_STA); 22295b482a8SLen Brown 22395b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, 22495b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 22595b482a8SLen Brown if (ACPI_FAILURE(status)) { 22695b482a8SLen Brown if (AE_NOT_FOUND == status) { 227a7d5caf6SBob Moore /* 228a7d5caf6SBob Moore * if _STA does not exist, then (as per the ACPI specification), 229a7d5caf6SBob Moore * the returned flags will indicate that the device is present, 230a7d5caf6SBob Moore * functional, and enabled. 231a7d5caf6SBob Moore */ 23295b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 23395b482a8SLen Brown "_STA on %4.4s was not found, assuming device is present\n", 23495b482a8SLen Brown acpi_ut_get_node_name(device_node))); 23595b482a8SLen Brown 23695b482a8SLen Brown *flags = ACPI_UINT32_MAX; 23795b482a8SLen Brown status = AE_OK; 23895b482a8SLen Brown } 23995b482a8SLen Brown 24095b482a8SLen Brown return_ACPI_STATUS(status); 24195b482a8SLen Brown } 24295b482a8SLen Brown 24395b482a8SLen Brown /* Extract the status flags */ 24495b482a8SLen Brown 24595b482a8SLen Brown *flags = (u32) obj_desc->integer.value; 24695b482a8SLen Brown 24795b482a8SLen Brown /* On exit, we must delete the return object */ 24895b482a8SLen Brown 24995b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 25095b482a8SLen Brown return_ACPI_STATUS(status); 25195b482a8SLen Brown } 25295b482a8SLen Brown 25395b482a8SLen Brown /******************************************************************************* 25495b482a8SLen Brown * 25515b8dd53SBob Moore * FUNCTION: acpi_ut_execute_power_methods 25695b482a8SLen Brown * 25795b482a8SLen Brown * PARAMETERS: device_node - Node for the device 25815b8dd53SBob Moore * method_names - Array of power method names 25915b8dd53SBob Moore * method_count - Number of methods to execute 26015b8dd53SBob Moore * out_values - Where the power method values are returned 26195b482a8SLen Brown * 26215b8dd53SBob Moore * RETURN: Status, out_values 26395b482a8SLen Brown * 26415b8dd53SBob Moore * DESCRIPTION: Executes the specified power methods for the device and returns 26515b8dd53SBob Moore * the result(s). 26695b482a8SLen Brown * 26795b482a8SLen Brown * NOTE: Internal function, no parameter validation 26895b482a8SLen Brown * 26995b482a8SLen Brown ******************************************************************************/ 27095b482a8SLen Brown 27195b482a8SLen Brown acpi_status 27215b8dd53SBob Moore acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, 27315b8dd53SBob Moore const char **method_names, 27415b8dd53SBob Moore u8 method_count, u8 *out_values) 27595b482a8SLen Brown { 27695b482a8SLen Brown union acpi_operand_object *obj_desc; 27795b482a8SLen Brown acpi_status status; 27815b8dd53SBob Moore acpi_status final_status = AE_NOT_FOUND; 27995b482a8SLen Brown u32 i; 28095b482a8SLen Brown 28115b8dd53SBob Moore ACPI_FUNCTION_TRACE(ut_execute_power_methods); 28295b482a8SLen Brown 28315b8dd53SBob Moore for (i = 0; i < method_count; i++) { 28415b8dd53SBob Moore /* 28515b8dd53SBob Moore * Execute the power method (_sx_d or _sx_w). The only allowable 28615b8dd53SBob Moore * return type is an Integer. 28715b8dd53SBob Moore */ 28895b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, 28995b482a8SLen Brown ACPI_CAST_PTR(char, 29015b8dd53SBob Moore method_names[i]), 29195b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 29215b8dd53SBob Moore if (ACPI_SUCCESS(status)) { 29315b8dd53SBob Moore out_values[i] = (u8)obj_desc->integer.value; 29495b482a8SLen Brown 29595b482a8SLen Brown /* Delete the return object */ 29695b482a8SLen Brown 29795b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 29815b8dd53SBob Moore final_status = AE_OK; /* At least one value is valid */ 29915b8dd53SBob Moore continue; 30095b482a8SLen Brown } 30195b482a8SLen Brown 30215b8dd53SBob Moore out_values[i] = ACPI_UINT8_MAX; 30315b8dd53SBob Moore if (status == AE_NOT_FOUND) { 30415b8dd53SBob Moore continue; /* Ignore if not found */ 30515b8dd53SBob Moore } 30615b8dd53SBob Moore 30715b8dd53SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 30815b8dd53SBob Moore "Failed %s on Device %4.4s, %s\n", 30915b8dd53SBob Moore ACPI_CAST_PTR(char, method_names[i]), 31015b8dd53SBob Moore acpi_ut_get_node_name(device_node), 31115b8dd53SBob Moore acpi_format_exception(status))); 31215b8dd53SBob Moore } 31315b8dd53SBob Moore 31415b8dd53SBob Moore return_ACPI_STATUS(final_status); 31595b482a8SLen Brown } 316