195b482a8SLen Brown /****************************************************************************** 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: uteval - Object evaluation 495b482a8SLen Brown * 595b482a8SLen Brown *****************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 825f044e6SBob 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; 9029a241ccSBob Moore info->relative_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: 126*1d1ea1b7SChao Guan 12795b482a8SLen Brown return_btype = ACPI_BTYPE_INTEGER; 12895b482a8SLen Brown break; 12995b482a8SLen Brown 13095b482a8SLen Brown case ACPI_TYPE_BUFFER: 131*1d1ea1b7SChao Guan 13295b482a8SLen Brown return_btype = ACPI_BTYPE_BUFFER; 13395b482a8SLen Brown break; 13495b482a8SLen Brown 13595b482a8SLen Brown case ACPI_TYPE_STRING: 136*1d1ea1b7SChao Guan 13795b482a8SLen Brown return_btype = ACPI_BTYPE_STRING; 13895b482a8SLen Brown break; 13995b482a8SLen Brown 14095b482a8SLen Brown case ACPI_TYPE_PACKAGE: 141*1d1ea1b7SChao Guan 14295b482a8SLen Brown return_btype = ACPI_BTYPE_PACKAGE; 14395b482a8SLen Brown break; 14495b482a8SLen Brown 14595b482a8SLen Brown default: 146*1d1ea1b7SChao Guan 14795b482a8SLen Brown return_btype = 0; 14895b482a8SLen Brown break; 14995b482a8SLen Brown } 15095b482a8SLen Brown 15195b482a8SLen Brown if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { 15295b482a8SLen Brown /* 15395b482a8SLen Brown * We received a return object, but one was not expected. This can 15495b482a8SLen Brown * happen frequently if the "implicit return" feature is enabled. 15595b482a8SLen Brown * Just delete the return object and return AE_OK. 15695b482a8SLen Brown */ 15795b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 15895b482a8SLen Brown goto cleanup; 15995b482a8SLen Brown } 16095b482a8SLen Brown 16195b482a8SLen Brown /* Is the return object one of the expected types? */ 16295b482a8SLen Brown 16395b482a8SLen Brown if (!(expected_return_btypes & return_btype)) { 16495b482a8SLen Brown ACPI_ERROR_METHOD("Return object type is incorrect", 16595b482a8SLen Brown prefix_node, path, AE_TYPE); 16695b482a8SLen Brown 16795b482a8SLen Brown ACPI_ERROR((AE_INFO, 168f6a22b0bSBob Moore "Type returned from %s was incorrect: %s, expected Btypes: 0x%X", 16995b482a8SLen Brown path, 17095b482a8SLen Brown acpi_ut_get_object_type_name(info->return_object), 17195b482a8SLen Brown expected_return_btypes)); 17295b482a8SLen Brown 17395b482a8SLen Brown /* On error exit, we must delete the return object */ 17495b482a8SLen Brown 17595b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 17695b482a8SLen Brown status = AE_TYPE; 17795b482a8SLen Brown goto cleanup; 17895b482a8SLen Brown } 17995b482a8SLen Brown 18095b482a8SLen Brown /* Object type is OK, return it */ 18195b482a8SLen Brown 18295b482a8SLen Brown *return_desc = info->return_object; 18395b482a8SLen Brown 18495b482a8SLen Brown cleanup: 18595b482a8SLen Brown ACPI_FREE(info); 18695b482a8SLen Brown return_ACPI_STATUS(status); 18795b482a8SLen Brown } 18895b482a8SLen Brown 18995b482a8SLen Brown /******************************************************************************* 19095b482a8SLen Brown * 19195b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_numeric_object 19295b482a8SLen Brown * 19395b482a8SLen Brown * PARAMETERS: object_name - Object name to be evaluated 19495b482a8SLen Brown * device_node - Node for the device 195ba494beeSBob Moore * value - Where the value is returned 19695b482a8SLen Brown * 19795b482a8SLen Brown * RETURN: Status 19895b482a8SLen Brown * 19995b482a8SLen Brown * DESCRIPTION: Evaluates a numeric namespace object for a selected device 20015b8dd53SBob Moore * and stores result in *Value. 20195b482a8SLen Brown * 20295b482a8SLen Brown * NOTE: Internal function, no parameter validation 20395b482a8SLen Brown * 20495b482a8SLen Brown ******************************************************************************/ 20595b482a8SLen Brown 20695b482a8SLen Brown acpi_status 20795b482a8SLen Brown acpi_ut_evaluate_numeric_object(char *object_name, 20895b482a8SLen Brown struct acpi_namespace_node *device_node, 2095df7e6cbSBob Moore u64 *value) 21095b482a8SLen Brown { 21195b482a8SLen Brown union acpi_operand_object *obj_desc; 21295b482a8SLen Brown acpi_status status; 21395b482a8SLen Brown 21495b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); 21595b482a8SLen Brown 21695b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, object_name, 21795b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 21895b482a8SLen Brown if (ACPI_FAILURE(status)) { 21995b482a8SLen Brown return_ACPI_STATUS(status); 22095b482a8SLen Brown } 22195b482a8SLen Brown 22295b482a8SLen Brown /* Get the returned Integer */ 22395b482a8SLen Brown 22415b8dd53SBob Moore *value = obj_desc->integer.value; 22595b482a8SLen Brown 22695b482a8SLen Brown /* On exit, we must delete the return object */ 22795b482a8SLen Brown 22895b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 22995b482a8SLen Brown return_ACPI_STATUS(status); 23095b482a8SLen Brown } 23195b482a8SLen Brown 23295b482a8SLen Brown /******************************************************************************* 23395b482a8SLen Brown * 23495b482a8SLen Brown * FUNCTION: acpi_ut_execute_STA 23595b482a8SLen Brown * 23695b482a8SLen Brown * PARAMETERS: device_node - Node for the device 237ba494beeSBob Moore * flags - Where the status flags are returned 23895b482a8SLen Brown * 23995b482a8SLen Brown * RETURN: Status 24095b482a8SLen Brown * 24195b482a8SLen Brown * DESCRIPTION: Executes _STA for selected device and stores results in 24295b482a8SLen Brown * *Flags. 24395b482a8SLen Brown * 24495b482a8SLen Brown * NOTE: Internal function, no parameter validation 24595b482a8SLen Brown * 24695b482a8SLen Brown ******************************************************************************/ 24795b482a8SLen Brown 24895b482a8SLen Brown acpi_status 24995b482a8SLen Brown acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) 25095b482a8SLen Brown { 25195b482a8SLen Brown union acpi_operand_object *obj_desc; 25295b482a8SLen Brown acpi_status status; 25395b482a8SLen Brown 25495b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_STA); 25595b482a8SLen Brown 25695b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, 25795b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 25895b482a8SLen Brown if (ACPI_FAILURE(status)) { 25995b482a8SLen Brown if (AE_NOT_FOUND == status) { 26095b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 26195b482a8SLen Brown "_STA on %4.4s was not found, assuming device is present\n", 26295b482a8SLen Brown acpi_ut_get_node_name(device_node))); 26395b482a8SLen Brown 26495b482a8SLen Brown *flags = ACPI_UINT32_MAX; 26595b482a8SLen Brown status = AE_OK; 26695b482a8SLen Brown } 26795b482a8SLen Brown 26895b482a8SLen Brown return_ACPI_STATUS(status); 26995b482a8SLen Brown } 27095b482a8SLen Brown 27195b482a8SLen Brown /* Extract the status flags */ 27295b482a8SLen Brown 27395b482a8SLen Brown *flags = (u32) obj_desc->integer.value; 27495b482a8SLen Brown 27595b482a8SLen Brown /* On exit, we must delete the return object */ 27695b482a8SLen Brown 27795b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 27895b482a8SLen Brown return_ACPI_STATUS(status); 27995b482a8SLen Brown } 28095b482a8SLen Brown 28195b482a8SLen Brown /******************************************************************************* 28295b482a8SLen Brown * 28315b8dd53SBob Moore * FUNCTION: acpi_ut_execute_power_methods 28495b482a8SLen Brown * 28595b482a8SLen Brown * PARAMETERS: device_node - Node for the device 28615b8dd53SBob Moore * method_names - Array of power method names 28715b8dd53SBob Moore * method_count - Number of methods to execute 28815b8dd53SBob Moore * out_values - Where the power method values are returned 28995b482a8SLen Brown * 29015b8dd53SBob Moore * RETURN: Status, out_values 29195b482a8SLen Brown * 29215b8dd53SBob Moore * DESCRIPTION: Executes the specified power methods for the device and returns 29315b8dd53SBob Moore * the result(s). 29495b482a8SLen Brown * 29595b482a8SLen Brown * NOTE: Internal function, no parameter validation 29695b482a8SLen Brown * 29795b482a8SLen Brown ******************************************************************************/ 29895b482a8SLen Brown 29995b482a8SLen Brown acpi_status 30015b8dd53SBob Moore acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, 30115b8dd53SBob Moore const char **method_names, 30215b8dd53SBob Moore u8 method_count, u8 *out_values) 30395b482a8SLen Brown { 30495b482a8SLen Brown union acpi_operand_object *obj_desc; 30595b482a8SLen Brown acpi_status status; 30615b8dd53SBob Moore acpi_status final_status = AE_NOT_FOUND; 30795b482a8SLen Brown u32 i; 30895b482a8SLen Brown 30915b8dd53SBob Moore ACPI_FUNCTION_TRACE(ut_execute_power_methods); 31095b482a8SLen Brown 31115b8dd53SBob Moore for (i = 0; i < method_count; i++) { 31215b8dd53SBob Moore /* 31315b8dd53SBob Moore * Execute the power method (_sx_d or _sx_w). The only allowable 31415b8dd53SBob Moore * return type is an Integer. 31515b8dd53SBob Moore */ 31695b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, 31795b482a8SLen Brown ACPI_CAST_PTR(char, 31815b8dd53SBob Moore method_names[i]), 31995b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 32015b8dd53SBob Moore if (ACPI_SUCCESS(status)) { 32115b8dd53SBob Moore out_values[i] = (u8)obj_desc->integer.value; 32295b482a8SLen Brown 32395b482a8SLen Brown /* Delete the return object */ 32495b482a8SLen Brown 32595b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 32615b8dd53SBob Moore final_status = AE_OK; /* At least one value is valid */ 32715b8dd53SBob Moore continue; 32895b482a8SLen Brown } 32995b482a8SLen Brown 33015b8dd53SBob Moore out_values[i] = ACPI_UINT8_MAX; 33115b8dd53SBob Moore if (status == AE_NOT_FOUND) { 33215b8dd53SBob Moore continue; /* Ignore if not found */ 33315b8dd53SBob Moore } 33415b8dd53SBob Moore 33515b8dd53SBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 33615b8dd53SBob Moore "Failed %s on Device %4.4s, %s\n", 33715b8dd53SBob Moore ACPI_CAST_PTR(char, method_names[i]), 33815b8dd53SBob Moore acpi_ut_get_node_name(device_node), 33915b8dd53SBob Moore acpi_format_exception(status))); 34015b8dd53SBob Moore } 34115b8dd53SBob Moore 34215b8dd53SBob Moore return_ACPI_STATUS(final_status); 34395b482a8SLen Brown } 344