195b482a8SLen Brown /****************************************************************************** 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: uteval - Object evaluation 495b482a8SLen Brown * 595b482a8SLen Brown *****************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 8*25f044e6SBob Moore * Copyright (C) 2000 - 2013, Intel Corp. 995b482a8SLen Brown * All rights reserved. 1095b482a8SLen Brown * 1195b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 1295b482a8SLen Brown * modification, are permitted provided that the following conditions 1395b482a8SLen Brown * are met: 1495b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 1595b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 1695b482a8SLen Brown * without modification. 1795b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1895b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 1995b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 2095b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 2195b482a8SLen Brown * binary redistribution. 2295b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 2395b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 2495b482a8SLen Brown * from this software without specific prior written permission. 2595b482a8SLen Brown * 2695b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 2795b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 2895b482a8SLen Brown * Software Foundation. 2995b482a8SLen Brown * 3095b482a8SLen Brown * NO WARRANTY 3195b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3295b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3395b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3495b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3595b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3695b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3795b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3895b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3995b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4095b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4195b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 4295b482a8SLen Brown */ 4395b482a8SLen Brown 4495b482a8SLen Brown #include <acpi/acpi.h> 45e2f7a777SLen Brown #include "accommon.h" 46e2f7a777SLen Brown #include "acnamesp.h" 4795b482a8SLen Brown 4895b482a8SLen Brown #define _COMPONENT ACPI_UTILITIES 4995b482a8SLen Brown ACPI_MODULE_NAME("uteval") 5095b482a8SLen Brown 5195b482a8SLen Brown /******************************************************************************* 5295b482a8SLen Brown * 5395b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_object 5495b482a8SLen Brown * 5595b482a8SLen Brown * PARAMETERS: prefix_node - Starting node 56ba494beeSBob Moore * path - Path to object from starting node 5795b482a8SLen Brown * expected_return_types - Bitmap of allowed return types 5895b482a8SLen Brown * return_desc - Where a return value is stored 5995b482a8SLen Brown * 6095b482a8SLen Brown * RETURN: Status 6195b482a8SLen Brown * 6295b482a8SLen Brown * DESCRIPTION: Evaluates a namespace object and verifies the type of the 6395b482a8SLen Brown * return object. Common code that simplifies accessing objects 6495b482a8SLen Brown * that have required return objects of fixed types. 6595b482a8SLen Brown * 6695b482a8SLen Brown * NOTE: Internal function, no parameter validation 6795b482a8SLen Brown * 6895b482a8SLen Brown ******************************************************************************/ 6995b482a8SLen Brown 7095b482a8SLen Brown acpi_status 7195b482a8SLen Brown acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node, 7295b482a8SLen Brown char *path, 7395b482a8SLen Brown u32 expected_return_btypes, 7495b482a8SLen Brown union acpi_operand_object **return_desc) 7595b482a8SLen Brown { 7695b482a8SLen Brown struct acpi_evaluate_info *info; 7795b482a8SLen Brown acpi_status status; 7895b482a8SLen Brown u32 return_btype; 7995b482a8SLen Brown 8095b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_object); 8195b482a8SLen Brown 8295b482a8SLen Brown /* Allocate the evaluation information block */ 8395b482a8SLen Brown 8495b482a8SLen Brown info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 8595b482a8SLen Brown if (!info) { 8695b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 8795b482a8SLen Brown } 8895b482a8SLen Brown 8995b482a8SLen Brown info->prefix_node = prefix_node; 9095b482a8SLen Brown info->pathname = path; 9195b482a8SLen Brown 9295b482a8SLen Brown /* Evaluate the object/method */ 9395b482a8SLen Brown 9495b482a8SLen Brown status = acpi_ns_evaluate(info); 9595b482a8SLen Brown if (ACPI_FAILURE(status)) { 9695b482a8SLen Brown if (status == AE_NOT_FOUND) { 9795b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 9895b482a8SLen Brown "[%4.4s.%s] was not found\n", 9995b482a8SLen Brown acpi_ut_get_node_name(prefix_node), 10095b482a8SLen Brown path)); 10195b482a8SLen Brown } else { 10295b482a8SLen Brown ACPI_ERROR_METHOD("Method execution failed", 10395b482a8SLen Brown prefix_node, path, status); 10495b482a8SLen Brown } 10595b482a8SLen Brown 10695b482a8SLen Brown goto cleanup; 10795b482a8SLen Brown } 10895b482a8SLen Brown 10995b482a8SLen Brown /* Did we get a return object? */ 11095b482a8SLen Brown 11195b482a8SLen Brown if (!info->return_object) { 11295b482a8SLen Brown if (expected_return_btypes) { 11395b482a8SLen Brown ACPI_ERROR_METHOD("No object was returned from", 11495b482a8SLen Brown prefix_node, path, AE_NOT_EXIST); 11595b482a8SLen Brown 11695b482a8SLen Brown status = AE_NOT_EXIST; 11795b482a8SLen Brown } 11895b482a8SLen Brown 11995b482a8SLen Brown goto cleanup; 12095b482a8SLen Brown } 12195b482a8SLen Brown 12295b482a8SLen Brown /* Map the return object type to the bitmapped type */ 12395b482a8SLen Brown 1243371c19cSBob Moore switch ((info->return_object)->common.type) { 12595b482a8SLen Brown case ACPI_TYPE_INTEGER: 12695b482a8SLen Brown return_btype = ACPI_BTYPE_INTEGER; 12795b482a8SLen Brown break; 12895b482a8SLen Brown 12995b482a8SLen Brown case ACPI_TYPE_BUFFER: 13095b482a8SLen Brown return_btype = ACPI_BTYPE_BUFFER; 13195b482a8SLen Brown break; 13295b482a8SLen Brown 13395b482a8SLen Brown case ACPI_TYPE_STRING: 13495b482a8SLen Brown return_btype = ACPI_BTYPE_STRING; 13595b482a8SLen Brown break; 13695b482a8SLen Brown 13795b482a8SLen Brown case ACPI_TYPE_PACKAGE: 13895b482a8SLen Brown return_btype = ACPI_BTYPE_PACKAGE; 13995b482a8SLen Brown break; 14095b482a8SLen Brown 14195b482a8SLen Brown default: 14295b482a8SLen Brown return_btype = 0; 14395b482a8SLen Brown break; 14495b482a8SLen Brown } 14595b482a8SLen Brown 14695b482a8SLen Brown if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { 14795b482a8SLen Brown /* 14895b482a8SLen Brown * We received a return object, but one was not expected. This can 14995b482a8SLen Brown * happen frequently if the "implicit return" feature is enabled. 15095b482a8SLen Brown * Just delete the return object and return AE_OK. 15195b482a8SLen Brown */ 15295b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 15395b482a8SLen Brown goto cleanup; 15495b482a8SLen Brown } 15595b482a8SLen Brown 15695b482a8SLen Brown /* Is the return object one of the expected types? */ 15795b482a8SLen Brown 15895b482a8SLen Brown if (!(expected_return_btypes & return_btype)) { 15995b482a8SLen Brown ACPI_ERROR_METHOD("Return object type is incorrect", 16095b482a8SLen Brown prefix_node, path, AE_TYPE); 16195b482a8SLen Brown 16295b482a8SLen Brown ACPI_ERROR((AE_INFO, 163f6a22b0bSBob Moore "Type returned from %s was incorrect: %s, expected Btypes: 0x%X", 16495b482a8SLen Brown path, 16595b482a8SLen Brown acpi_ut_get_object_type_name(info->return_object), 16695b482a8SLen Brown expected_return_btypes)); 16795b482a8SLen Brown 16895b482a8SLen Brown /* On error exit, we must delete the return object */ 16995b482a8SLen Brown 17095b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 17195b482a8SLen Brown status = AE_TYPE; 17295b482a8SLen Brown goto cleanup; 17395b482a8SLen Brown } 17495b482a8SLen Brown 17595b482a8SLen Brown /* Object type is OK, return it */ 17695b482a8SLen Brown 17795b482a8SLen Brown *return_desc = info->return_object; 17895b482a8SLen Brown 17995b482a8SLen Brown cleanup: 18095b482a8SLen Brown ACPI_FREE(info); 18195b482a8SLen Brown return_ACPI_STATUS(status); 18295b482a8SLen Brown } 18395b482a8SLen Brown 18495b482a8SLen Brown /******************************************************************************* 18595b482a8SLen Brown * 18695b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_numeric_object 18795b482a8SLen Brown * 18895b482a8SLen Brown * PARAMETERS: object_name - Object name to be evaluated 18995b482a8SLen Brown * device_node - Node for the device 190ba494beeSBob Moore * value - Where the value is returned 19195b482a8SLen Brown * 19295b482a8SLen Brown * RETURN: Status 19395b482a8SLen Brown * 19495b482a8SLen Brown * DESCRIPTION: Evaluates a numeric namespace object for a selected device 19515b8dd53SBob Moore * and stores result in *Value. 19695b482a8SLen Brown * 19795b482a8SLen Brown * NOTE: Internal function, no parameter validation 19895b482a8SLen Brown * 19995b482a8SLen Brown ******************************************************************************/ 20095b482a8SLen Brown 20195b482a8SLen Brown acpi_status 20295b482a8SLen Brown acpi_ut_evaluate_numeric_object(char *object_name, 20395b482a8SLen Brown struct acpi_namespace_node *device_node, 2045df7e6cbSBob Moore u64 *value) 20595b482a8SLen Brown { 20695b482a8SLen Brown union acpi_operand_object *obj_desc; 20795b482a8SLen Brown acpi_status status; 20895b482a8SLen Brown 20995b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); 21095b482a8SLen Brown 21195b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, object_name, 21295b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 21395b482a8SLen Brown if (ACPI_FAILURE(status)) { 21495b482a8SLen Brown return_ACPI_STATUS(status); 21595b482a8SLen Brown } 21695b482a8SLen Brown 21795b482a8SLen Brown /* Get the returned Integer */ 21895b482a8SLen Brown 21915b8dd53SBob Moore *value = obj_desc->integer.value; 22095b482a8SLen Brown 22195b482a8SLen Brown /* On exit, we must delete the return object */ 22295b482a8SLen Brown 22395b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 22495b482a8SLen Brown return_ACPI_STATUS(status); 22595b482a8SLen Brown } 22695b482a8SLen Brown 22795b482a8SLen Brown /******************************************************************************* 22895b482a8SLen Brown * 22995b482a8SLen Brown * FUNCTION: acpi_ut_execute_STA 23095b482a8SLen Brown * 23195b482a8SLen Brown * PARAMETERS: device_node - Node for the device 232ba494beeSBob Moore * flags - Where the status flags are returned 23395b482a8SLen Brown * 23495b482a8SLen Brown * RETURN: Status 23595b482a8SLen Brown * 23695b482a8SLen Brown * DESCRIPTION: Executes _STA for selected device and stores results in 23795b482a8SLen Brown * *Flags. 23895b482a8SLen Brown * 23995b482a8SLen Brown * NOTE: Internal function, no parameter validation 24095b482a8SLen Brown * 24195b482a8SLen Brown ******************************************************************************/ 24295b482a8SLen Brown 24395b482a8SLen Brown acpi_status 24495b482a8SLen Brown acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) 24595b482a8SLen Brown { 24695b482a8SLen Brown union acpi_operand_object *obj_desc; 24795b482a8SLen Brown acpi_status status; 24895b482a8SLen Brown 24995b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_STA); 25095b482a8SLen Brown 25195b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, 25295b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 25395b482a8SLen Brown if (ACPI_FAILURE(status)) { 25495b482a8SLen Brown if (AE_NOT_FOUND == status) { 25595b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 25695b482a8SLen Brown "_STA on %4.4s was not found, assuming device is present\n", 25795b482a8SLen Brown acpi_ut_get_node_name(device_node))); 25895b482a8SLen Brown 25995b482a8SLen Brown *flags = ACPI_UINT32_MAX; 26095b482a8SLen Brown status = AE_OK; 26195b482a8SLen Brown } 26295b482a8SLen Brown 26395b482a8SLen Brown return_ACPI_STATUS(status); 26495b482a8SLen Brown } 26595b482a8SLen Brown 26695b482a8SLen Brown /* Extract the status flags */ 26795b482a8SLen Brown 26895b482a8SLen Brown *flags = (u32) obj_desc->integer.value; 26995b482a8SLen Brown 27095b482a8SLen Brown /* On exit, we must delete the return object */ 27195b482a8SLen Brown 27295b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 27395b482a8SLen Brown return_ACPI_STATUS(status); 27495b482a8SLen Brown } 27595b482a8SLen Brown 27695b482a8SLen Brown /******************************************************************************* 27795b482a8SLen Brown * 27815b8dd53SBob Moore * FUNCTION: acpi_ut_execute_power_methods 27995b482a8SLen Brown * 28095b482a8SLen Brown * PARAMETERS: device_node - Node for the device 28115b8dd53SBob Moore * method_names - Array of power method names 28215b8dd53SBob Moore * method_count - Number of methods to execute 28315b8dd53SBob Moore * out_values - Where the power method values are returned 28495b482a8SLen Brown * 28515b8dd53SBob Moore * RETURN: Status, out_values 28695b482a8SLen Brown * 28715b8dd53SBob Moore * DESCRIPTION: Executes the specified power methods for the device and returns 28815b8dd53SBob Moore * the result(s). 28995b482a8SLen Brown * 29095b482a8SLen Brown * NOTE: Internal function, no parameter validation 29195b482a8SLen Brown * 29295b482a8SLen Brown ******************************************************************************/ 29395b482a8SLen Brown 29495b482a8SLen Brown acpi_status 29515b8dd53SBob Moore acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, 29615b8dd53SBob Moore const char **method_names, 29715b8dd53SBob Moore u8 method_count, u8 *out_values) 29895b482a8SLen Brown { 29995b482a8SLen Brown union acpi_operand_object *obj_desc; 30095b482a8SLen Brown acpi_status status; 30115b8dd53SBob Moore acpi_status final_status = AE_NOT_FOUND; 30295b482a8SLen Brown u32 i; 30395b482a8SLen Brown 30415b8dd53SBob Moore ACPI_FUNCTION_TRACE(ut_execute_power_methods); 30595b482a8SLen Brown 30615b8dd53SBob Moore for (i = 0; i < method_count; i++) { 30715b8dd53SBob Moore /* 30815b8dd53SBob Moore * Execute the power method (_sx_d or _sx_w). The only allowable 30915b8dd53SBob Moore * return type is an Integer. 31015b8dd53SBob Moore */ 31195b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, 31295b482a8SLen Brown ACPI_CAST_PTR(char, 31315b8dd53SBob Moore method_names[i]), 31495b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 31515b8dd53SBob Moore if (ACPI_SUCCESS(status)) { 31615b8dd53SBob Moore out_values[i] = (u8)obj_desc->integer.value; 31795b482a8SLen Brown 31895b482a8SLen Brown /* Delete the return object */ 31995b482a8SLen Brown 32095b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 32115b8dd53SBob Moore final_status = AE_OK; /* At least one value is valid */ 32215b8dd53SBob Moore continue; 32395b482a8SLen Brown } 32495b482a8SLen Brown 32515b8dd53SBob Moore out_values[i] = ACPI_UINT8_MAX; 32615b8dd53SBob Moore if (status == AE_NOT_FOUND) { 32715b8dd53SBob Moore continue; /* Ignore if not found */ 32815b8dd53SBob Moore } 32915b8dd53SBob Moore 33015b8dd53SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 33115b8dd53SBob Moore "Failed %s on Device %4.4s, %s\n", 33215b8dd53SBob Moore ACPI_CAST_PTR(char, method_names[i]), 33315b8dd53SBob Moore acpi_ut_get_node_name(device_node), 33415b8dd53SBob Moore acpi_format_exception(status))); 33515b8dd53SBob Moore } 33615b8dd53SBob Moore 33715b8dd53SBob Moore return_ACPI_STATUS(final_status); 33895b482a8SLen Brown } 339