195b482a8SLen Brown /****************************************************************************** 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: uteval - Object evaluation 495b482a8SLen Brown * 595b482a8SLen Brown *****************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 895b482a8SLen Brown * Copyright (C) 2000 - 2008, 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> 45*e2f7a777SLen Brown #include "accommon.h" 46*e2f7a777SLen Brown #include "acnamesp.h" 47*e2f7a777SLen Brown #include "acinterp.h" 4895b482a8SLen Brown 4995b482a8SLen Brown #define _COMPONENT ACPI_UTILITIES 5095b482a8SLen Brown ACPI_MODULE_NAME("uteval") 5195b482a8SLen Brown 5295b482a8SLen Brown /* Local prototypes */ 5395b482a8SLen Brown static void 5495b482a8SLen Brown acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length); 5595b482a8SLen Brown 5695b482a8SLen Brown static acpi_status 5795b482a8SLen Brown acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, 5895b482a8SLen Brown struct acpi_compatible_id *one_cid); 5995b482a8SLen Brown 6095b482a8SLen Brown /* 6195b482a8SLen Brown * Strings supported by the _OSI predefined (internal) method. 6295b482a8SLen Brown */ 6395b482a8SLen Brown static char *acpi_interfaces_supported[] = { 6495b482a8SLen Brown /* Operating System Vendor Strings */ 6595b482a8SLen Brown 6695b482a8SLen Brown "Windows 2000", /* Windows 2000 */ 6795b482a8SLen Brown "Windows 2001", /* Windows XP */ 6895b482a8SLen Brown "Windows 2001 SP1", /* Windows XP SP1 */ 6995b482a8SLen Brown "Windows 2001 SP2", /* Windows XP SP2 */ 7095b482a8SLen Brown "Windows 2001.1", /* Windows Server 2003 */ 7195b482a8SLen Brown "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */ 7295b482a8SLen Brown "Windows 2006", /* Windows Vista - Added 03/2006 */ 7395b482a8SLen Brown 7495b482a8SLen Brown /* Feature Group Strings */ 7595b482a8SLen Brown 7695b482a8SLen Brown "Extended Address Space Descriptor" 7795b482a8SLen Brown /* 7895b482a8SLen Brown * All "optional" feature group strings (features that are implemented 7995b482a8SLen Brown * by the host) should be implemented in the host version of 8095b482a8SLen Brown * acpi_os_validate_interface and should not be added here. 8195b482a8SLen Brown */ 8295b482a8SLen Brown }; 8395b482a8SLen Brown 8495b482a8SLen Brown /******************************************************************************* 8595b482a8SLen Brown * 8695b482a8SLen Brown * FUNCTION: acpi_ut_osi_implementation 8795b482a8SLen Brown * 8895b482a8SLen Brown * PARAMETERS: walk_state - Current walk state 8995b482a8SLen Brown * 9095b482a8SLen Brown * RETURN: Status 9195b482a8SLen Brown * 9295b482a8SLen Brown * DESCRIPTION: Implementation of the _OSI predefined control method 9395b482a8SLen Brown * 9495b482a8SLen Brown ******************************************************************************/ 9595b482a8SLen Brown 9695b482a8SLen Brown acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) 9795b482a8SLen Brown { 9895b482a8SLen Brown acpi_status status; 9995b482a8SLen Brown union acpi_operand_object *string_desc; 10095b482a8SLen Brown union acpi_operand_object *return_desc; 10195b482a8SLen Brown u32 i; 10295b482a8SLen Brown 10395b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_osi_implementation); 10495b482a8SLen Brown 10595b482a8SLen Brown /* Validate the string input argument */ 10695b482a8SLen Brown 10795b482a8SLen Brown string_desc = walk_state->arguments[0].object; 10895b482a8SLen Brown if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { 10995b482a8SLen Brown return_ACPI_STATUS(AE_TYPE); 11095b482a8SLen Brown } 11195b482a8SLen Brown 11295b482a8SLen Brown /* Create a return object */ 11395b482a8SLen Brown 11495b482a8SLen Brown return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); 11595b482a8SLen Brown if (!return_desc) { 11695b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 11795b482a8SLen Brown } 11895b482a8SLen Brown 11995b482a8SLen Brown /* Default return value is SUPPORTED */ 12095b482a8SLen Brown 12195b482a8SLen Brown return_desc->integer.value = ACPI_UINT32_MAX; 12295b482a8SLen Brown walk_state->return_desc = return_desc; 12395b482a8SLen Brown 12495b482a8SLen Brown /* Compare input string to static table of supported interfaces */ 12595b482a8SLen Brown 12695b482a8SLen Brown for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { 12795b482a8SLen Brown if (!ACPI_STRCMP 12895b482a8SLen Brown (string_desc->string.pointer, 12995b482a8SLen Brown acpi_interfaces_supported[i])) { 13095b482a8SLen Brown 13195b482a8SLen Brown /* The interface is supported */ 13295b482a8SLen Brown 13395b482a8SLen Brown return_ACPI_STATUS(AE_OK); 13495b482a8SLen Brown } 13595b482a8SLen Brown } 13695b482a8SLen Brown 13795b482a8SLen Brown /* 13895b482a8SLen Brown * Did not match the string in the static table, call the host OSL to 13995b482a8SLen Brown * check for a match with one of the optional strings (such as 14095b482a8SLen Brown * "Module Device", "3.0 Thermal Model", etc.) 14195b482a8SLen Brown */ 14295b482a8SLen Brown status = acpi_os_validate_interface(string_desc->string.pointer); 14395b482a8SLen Brown if (ACPI_SUCCESS(status)) { 14495b482a8SLen Brown 14595b482a8SLen Brown /* The interface is supported */ 14695b482a8SLen Brown 14795b482a8SLen Brown return_ACPI_STATUS(AE_OK); 14895b482a8SLen Brown } 14995b482a8SLen Brown 15095b482a8SLen Brown /* The interface is not supported */ 15195b482a8SLen Brown 15295b482a8SLen Brown return_desc->integer.value = 0; 15395b482a8SLen Brown return_ACPI_STATUS(AE_OK); 15495b482a8SLen Brown } 15595b482a8SLen Brown 15695b482a8SLen Brown /******************************************************************************* 15795b482a8SLen Brown * 15895b482a8SLen Brown * FUNCTION: acpi_osi_invalidate 15995b482a8SLen Brown * 16095b482a8SLen Brown * PARAMETERS: interface_string 16195b482a8SLen Brown * 16295b482a8SLen Brown * RETURN: Status 16395b482a8SLen Brown * 16495b482a8SLen Brown * DESCRIPTION: invalidate string in pre-defiend _OSI string list 16595b482a8SLen Brown * 16695b482a8SLen Brown ******************************************************************************/ 16795b482a8SLen Brown 16895b482a8SLen Brown acpi_status acpi_osi_invalidate(char *interface) 16995b482a8SLen Brown { 17095b482a8SLen Brown int i; 17195b482a8SLen Brown 17295b482a8SLen Brown for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { 17395b482a8SLen Brown if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) { 17495b482a8SLen Brown *acpi_interfaces_supported[i] = '\0'; 17595b482a8SLen Brown return AE_OK; 17695b482a8SLen Brown } 17795b482a8SLen Brown } 17895b482a8SLen Brown return AE_NOT_FOUND; 17995b482a8SLen Brown } 18095b482a8SLen Brown 18195b482a8SLen Brown /******************************************************************************* 18295b482a8SLen Brown * 18395b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_object 18495b482a8SLen Brown * 18595b482a8SLen Brown * PARAMETERS: prefix_node - Starting node 18695b482a8SLen Brown * Path - Path to object from starting node 18795b482a8SLen Brown * expected_return_types - Bitmap of allowed return types 18895b482a8SLen Brown * return_desc - Where a return value is stored 18995b482a8SLen Brown * 19095b482a8SLen Brown * RETURN: Status 19195b482a8SLen Brown * 19295b482a8SLen Brown * DESCRIPTION: Evaluates a namespace object and verifies the type of the 19395b482a8SLen Brown * return object. Common code that simplifies accessing objects 19495b482a8SLen Brown * that have required return objects of fixed types. 19595b482a8SLen Brown * 19695b482a8SLen Brown * NOTE: Internal function, no parameter validation 19795b482a8SLen Brown * 19895b482a8SLen Brown ******************************************************************************/ 19995b482a8SLen Brown 20095b482a8SLen Brown acpi_status 20195b482a8SLen Brown acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, 20295b482a8SLen Brown char *path, 20395b482a8SLen Brown u32 expected_return_btypes, 20495b482a8SLen Brown union acpi_operand_object **return_desc) 20595b482a8SLen Brown { 20695b482a8SLen Brown struct acpi_evaluate_info *info; 20795b482a8SLen Brown acpi_status status; 20895b482a8SLen Brown u32 return_btype; 20995b482a8SLen Brown 21095b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_object); 21195b482a8SLen Brown 21295b482a8SLen Brown /* Allocate the evaluation information block */ 21395b482a8SLen Brown 21495b482a8SLen Brown info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 21595b482a8SLen Brown if (!info) { 21695b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 21795b482a8SLen Brown } 21895b482a8SLen Brown 21995b482a8SLen Brown info->prefix_node = prefix_node; 22095b482a8SLen Brown info->pathname = path; 22195b482a8SLen Brown 22295b482a8SLen Brown /* Evaluate the object/method */ 22395b482a8SLen Brown 22495b482a8SLen Brown status = acpi_ns_evaluate(info); 22595b482a8SLen Brown if (ACPI_FAILURE(status)) { 22695b482a8SLen Brown if (status == AE_NOT_FOUND) { 22795b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 22895b482a8SLen Brown "[%4.4s.%s] was not found\n", 22995b482a8SLen Brown acpi_ut_get_node_name(prefix_node), 23095b482a8SLen Brown path)); 23195b482a8SLen Brown } else { 23295b482a8SLen Brown ACPI_ERROR_METHOD("Method execution failed", 23395b482a8SLen Brown prefix_node, path, status); 23495b482a8SLen Brown } 23595b482a8SLen Brown 23695b482a8SLen Brown goto cleanup; 23795b482a8SLen Brown } 23895b482a8SLen Brown 23995b482a8SLen Brown /* Did we get a return object? */ 24095b482a8SLen Brown 24195b482a8SLen Brown if (!info->return_object) { 24295b482a8SLen Brown if (expected_return_btypes) { 24395b482a8SLen Brown ACPI_ERROR_METHOD("No object was returned from", 24495b482a8SLen Brown prefix_node, path, AE_NOT_EXIST); 24595b482a8SLen Brown 24695b482a8SLen Brown status = AE_NOT_EXIST; 24795b482a8SLen Brown } 24895b482a8SLen Brown 24995b482a8SLen Brown goto cleanup; 25095b482a8SLen Brown } 25195b482a8SLen Brown 25295b482a8SLen Brown /* Map the return object type to the bitmapped type */ 25395b482a8SLen Brown 25495b482a8SLen Brown switch (ACPI_GET_OBJECT_TYPE(info->return_object)) { 25595b482a8SLen Brown case ACPI_TYPE_INTEGER: 25695b482a8SLen Brown return_btype = ACPI_BTYPE_INTEGER; 25795b482a8SLen Brown break; 25895b482a8SLen Brown 25995b482a8SLen Brown case ACPI_TYPE_BUFFER: 26095b482a8SLen Brown return_btype = ACPI_BTYPE_BUFFER; 26195b482a8SLen Brown break; 26295b482a8SLen Brown 26395b482a8SLen Brown case ACPI_TYPE_STRING: 26495b482a8SLen Brown return_btype = ACPI_BTYPE_STRING; 26595b482a8SLen Brown break; 26695b482a8SLen Brown 26795b482a8SLen Brown case ACPI_TYPE_PACKAGE: 26895b482a8SLen Brown return_btype = ACPI_BTYPE_PACKAGE; 26995b482a8SLen Brown break; 27095b482a8SLen Brown 27195b482a8SLen Brown default: 27295b482a8SLen Brown return_btype = 0; 27395b482a8SLen Brown break; 27495b482a8SLen Brown } 27595b482a8SLen Brown 27695b482a8SLen Brown if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { 27795b482a8SLen Brown /* 27895b482a8SLen Brown * We received a return object, but one was not expected. This can 27995b482a8SLen Brown * happen frequently if the "implicit return" feature is enabled. 28095b482a8SLen Brown * Just delete the return object and return AE_OK. 28195b482a8SLen Brown */ 28295b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 28395b482a8SLen Brown goto cleanup; 28495b482a8SLen Brown } 28595b482a8SLen Brown 28695b482a8SLen Brown /* Is the return object one of the expected types? */ 28795b482a8SLen Brown 28895b482a8SLen Brown if (!(expected_return_btypes & return_btype)) { 28995b482a8SLen Brown ACPI_ERROR_METHOD("Return object type is incorrect", 29095b482a8SLen Brown prefix_node, path, AE_TYPE); 29195b482a8SLen Brown 29295b482a8SLen Brown ACPI_ERROR((AE_INFO, 29395b482a8SLen Brown "Type returned from %s was incorrect: %s, expected Btypes: %X", 29495b482a8SLen Brown path, 29595b482a8SLen Brown acpi_ut_get_object_type_name(info->return_object), 29695b482a8SLen Brown expected_return_btypes)); 29795b482a8SLen Brown 29895b482a8SLen Brown /* On error exit, we must delete the return object */ 29995b482a8SLen Brown 30095b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 30195b482a8SLen Brown status = AE_TYPE; 30295b482a8SLen Brown goto cleanup; 30395b482a8SLen Brown } 30495b482a8SLen Brown 30595b482a8SLen Brown /* Object type is OK, return it */ 30695b482a8SLen Brown 30795b482a8SLen Brown *return_desc = info->return_object; 30895b482a8SLen Brown 30995b482a8SLen Brown cleanup: 31095b482a8SLen Brown ACPI_FREE(info); 31195b482a8SLen Brown return_ACPI_STATUS(status); 31295b482a8SLen Brown } 31395b482a8SLen Brown 31495b482a8SLen Brown /******************************************************************************* 31595b482a8SLen Brown * 31695b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_numeric_object 31795b482a8SLen Brown * 31895b482a8SLen Brown * PARAMETERS: object_name - Object name to be evaluated 31995b482a8SLen Brown * device_node - Node for the device 32095b482a8SLen Brown * Address - Where the value is returned 32195b482a8SLen Brown * 32295b482a8SLen Brown * RETURN: Status 32395b482a8SLen Brown * 32495b482a8SLen Brown * DESCRIPTION: Evaluates a numeric namespace object for a selected device 32595b482a8SLen Brown * and stores result in *Address. 32695b482a8SLen Brown * 32795b482a8SLen Brown * NOTE: Internal function, no parameter validation 32895b482a8SLen Brown * 32995b482a8SLen Brown ******************************************************************************/ 33095b482a8SLen Brown 33195b482a8SLen Brown acpi_status 33295b482a8SLen Brown acpi_ut_evaluate_numeric_object(char *object_name, 33395b482a8SLen Brown struct acpi_namespace_node *device_node, 33495b482a8SLen Brown acpi_integer * address) 33595b482a8SLen Brown { 33695b482a8SLen Brown union acpi_operand_object *obj_desc; 33795b482a8SLen Brown acpi_status status; 33895b482a8SLen Brown 33995b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); 34095b482a8SLen Brown 34195b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, object_name, 34295b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 34395b482a8SLen Brown if (ACPI_FAILURE(status)) { 34495b482a8SLen Brown return_ACPI_STATUS(status); 34595b482a8SLen Brown } 34695b482a8SLen Brown 34795b482a8SLen Brown /* Get the returned Integer */ 34895b482a8SLen Brown 34995b482a8SLen Brown *address = obj_desc->integer.value; 35095b482a8SLen Brown 35195b482a8SLen Brown /* On exit, we must delete the return object */ 35295b482a8SLen Brown 35395b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 35495b482a8SLen Brown return_ACPI_STATUS(status); 35595b482a8SLen Brown } 35695b482a8SLen Brown 35795b482a8SLen Brown /******************************************************************************* 35895b482a8SLen Brown * 35995b482a8SLen Brown * FUNCTION: acpi_ut_copy_id_string 36095b482a8SLen Brown * 36195b482a8SLen Brown * PARAMETERS: Destination - Where to copy the string 36295b482a8SLen Brown * Source - Source string 36395b482a8SLen Brown * max_length - Length of the destination buffer 36495b482a8SLen Brown * 36595b482a8SLen Brown * RETURN: None 36695b482a8SLen Brown * 36795b482a8SLen Brown * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. 36895b482a8SLen Brown * Performs removal of a leading asterisk if present -- workaround 36995b482a8SLen Brown * for a known issue on a bunch of machines. 37095b482a8SLen Brown * 37195b482a8SLen Brown ******************************************************************************/ 37295b482a8SLen Brown 37395b482a8SLen Brown static void 37495b482a8SLen Brown acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length) 37595b482a8SLen Brown { 37695b482a8SLen Brown 37795b482a8SLen Brown /* 37895b482a8SLen Brown * Workaround for ID strings that have a leading asterisk. This construct 37995b482a8SLen Brown * is not allowed by the ACPI specification (ID strings must be 38095b482a8SLen Brown * alphanumeric), but enough existing machines have this embedded in their 38195b482a8SLen Brown * ID strings that the following code is useful. 38295b482a8SLen Brown */ 38395b482a8SLen Brown if (*source == '*') { 38495b482a8SLen Brown source++; 38595b482a8SLen Brown } 38695b482a8SLen Brown 38795b482a8SLen Brown /* Do the actual copy */ 38895b482a8SLen Brown 38995b482a8SLen Brown ACPI_STRNCPY(destination, source, max_length); 39095b482a8SLen Brown } 39195b482a8SLen Brown 39295b482a8SLen Brown /******************************************************************************* 39395b482a8SLen Brown * 39495b482a8SLen Brown * FUNCTION: acpi_ut_execute_HID 39595b482a8SLen Brown * 39695b482a8SLen Brown * PARAMETERS: device_node - Node for the device 39795b482a8SLen Brown * Hid - Where the HID is returned 39895b482a8SLen Brown * 39995b482a8SLen Brown * RETURN: Status 40095b482a8SLen Brown * 40195b482a8SLen Brown * DESCRIPTION: Executes the _HID control method that returns the hardware 40295b482a8SLen Brown * ID of the device. 40395b482a8SLen Brown * 40495b482a8SLen Brown * NOTE: Internal function, no parameter validation 40595b482a8SLen Brown * 40695b482a8SLen Brown ******************************************************************************/ 40795b482a8SLen Brown 40895b482a8SLen Brown acpi_status 40995b482a8SLen Brown acpi_ut_execute_HID(struct acpi_namespace_node *device_node, 41095b482a8SLen Brown struct acpica_device_id *hid) 41195b482a8SLen Brown { 41295b482a8SLen Brown union acpi_operand_object *obj_desc; 41395b482a8SLen Brown acpi_status status; 41495b482a8SLen Brown 41595b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_HID); 41695b482a8SLen Brown 41795b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, 41895b482a8SLen Brown ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, 41995b482a8SLen Brown &obj_desc); 42095b482a8SLen Brown if (ACPI_FAILURE(status)) { 42195b482a8SLen Brown return_ACPI_STATUS(status); 42295b482a8SLen Brown } 42395b482a8SLen Brown 42495b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { 42595b482a8SLen Brown 42695b482a8SLen Brown /* Convert the Numeric HID to string */ 42795b482a8SLen Brown 42895b482a8SLen Brown acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, 42995b482a8SLen Brown hid->value); 43095b482a8SLen Brown } else { 43195b482a8SLen Brown /* Copy the String HID from the returned object */ 43295b482a8SLen Brown 43395b482a8SLen Brown acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer, 43495b482a8SLen Brown sizeof(hid->value)); 43595b482a8SLen Brown } 43695b482a8SLen Brown 43795b482a8SLen Brown /* On exit, we must delete the return object */ 43895b482a8SLen Brown 43995b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 44095b482a8SLen Brown return_ACPI_STATUS(status); 44195b482a8SLen Brown } 44295b482a8SLen Brown 44395b482a8SLen Brown /******************************************************************************* 44495b482a8SLen Brown * 44595b482a8SLen Brown * FUNCTION: acpi_ut_translate_one_cid 44695b482a8SLen Brown * 44795b482a8SLen Brown * PARAMETERS: obj_desc - _CID object, must be integer or string 44895b482a8SLen Brown * one_cid - Where the CID string is returned 44995b482a8SLen Brown * 45095b482a8SLen Brown * RETURN: Status 45195b482a8SLen Brown * 45295b482a8SLen Brown * DESCRIPTION: Return a numeric or string _CID value as a string. 45395b482a8SLen Brown * (Compatible ID) 45495b482a8SLen Brown * 45595b482a8SLen Brown * NOTE: Assumes a maximum _CID string length of 45695b482a8SLen Brown * ACPI_MAX_CID_LENGTH. 45795b482a8SLen Brown * 45895b482a8SLen Brown ******************************************************************************/ 45995b482a8SLen Brown 46095b482a8SLen Brown static acpi_status 46195b482a8SLen Brown acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, 46295b482a8SLen Brown struct acpi_compatible_id *one_cid) 46395b482a8SLen Brown { 46495b482a8SLen Brown 46595b482a8SLen Brown switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { 46695b482a8SLen Brown case ACPI_TYPE_INTEGER: 46795b482a8SLen Brown 46895b482a8SLen Brown /* Convert the Numeric CID to string */ 46995b482a8SLen Brown 47095b482a8SLen Brown acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, 47195b482a8SLen Brown one_cid->value); 47295b482a8SLen Brown return (AE_OK); 47395b482a8SLen Brown 47495b482a8SLen Brown case ACPI_TYPE_STRING: 47595b482a8SLen Brown 47695b482a8SLen Brown if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { 47795b482a8SLen Brown return (AE_AML_STRING_LIMIT); 47895b482a8SLen Brown } 47995b482a8SLen Brown 48095b482a8SLen Brown /* Copy the String CID from the returned object */ 48195b482a8SLen Brown 48295b482a8SLen Brown acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer, 48395b482a8SLen Brown ACPI_MAX_CID_LENGTH); 48495b482a8SLen Brown return (AE_OK); 48595b482a8SLen Brown 48695b482a8SLen Brown default: 48795b482a8SLen Brown 48895b482a8SLen Brown return (AE_TYPE); 48995b482a8SLen Brown } 49095b482a8SLen Brown } 49195b482a8SLen Brown 49295b482a8SLen Brown /******************************************************************************* 49395b482a8SLen Brown * 49495b482a8SLen Brown * FUNCTION: acpi_ut_execute_CID 49595b482a8SLen Brown * 49695b482a8SLen Brown * PARAMETERS: device_node - Node for the device 49795b482a8SLen Brown * return_cid_list - Where the CID list is returned 49895b482a8SLen Brown * 49995b482a8SLen Brown * RETURN: Status 50095b482a8SLen Brown * 50195b482a8SLen Brown * DESCRIPTION: Executes the _CID control method that returns one or more 50295b482a8SLen Brown * compatible hardware IDs for the device. 50395b482a8SLen Brown * 50495b482a8SLen Brown * NOTE: Internal function, no parameter validation 50595b482a8SLen Brown * 50695b482a8SLen Brown ******************************************************************************/ 50795b482a8SLen Brown 50895b482a8SLen Brown acpi_status 50995b482a8SLen Brown acpi_ut_execute_CID(struct acpi_namespace_node * device_node, 51095b482a8SLen Brown struct acpi_compatible_id_list ** return_cid_list) 51195b482a8SLen Brown { 51295b482a8SLen Brown union acpi_operand_object *obj_desc; 51395b482a8SLen Brown acpi_status status; 51495b482a8SLen Brown u32 count; 51595b482a8SLen Brown u32 size; 51695b482a8SLen Brown struct acpi_compatible_id_list *cid_list; 51795b482a8SLen Brown u32 i; 51895b482a8SLen Brown 51995b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_CID); 52095b482a8SLen Brown 52195b482a8SLen Brown /* Evaluate the _CID method for this device */ 52295b482a8SLen Brown 52395b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, 52495b482a8SLen Brown ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING 52595b482a8SLen Brown | ACPI_BTYPE_PACKAGE, &obj_desc); 52695b482a8SLen Brown if (ACPI_FAILURE(status)) { 52795b482a8SLen Brown return_ACPI_STATUS(status); 52895b482a8SLen Brown } 52995b482a8SLen Brown 53095b482a8SLen Brown /* Get the number of _CIDs returned */ 53195b482a8SLen Brown 53295b482a8SLen Brown count = 1; 53395b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { 53495b482a8SLen Brown count = obj_desc->package.count; 53595b482a8SLen Brown } 53695b482a8SLen Brown 53795b482a8SLen Brown /* Allocate a worst-case buffer for the _CIDs */ 53895b482a8SLen Brown 53995b482a8SLen Brown size = (((count - 1) * sizeof(struct acpi_compatible_id)) + 54095b482a8SLen Brown sizeof(struct acpi_compatible_id_list)); 54195b482a8SLen Brown 54295b482a8SLen Brown cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); 54395b482a8SLen Brown if (!cid_list) { 54495b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 54595b482a8SLen Brown } 54695b482a8SLen Brown 54795b482a8SLen Brown /* Init CID list */ 54895b482a8SLen Brown 54995b482a8SLen Brown cid_list->count = count; 55095b482a8SLen Brown cid_list->size = size; 55195b482a8SLen Brown 55295b482a8SLen Brown /* 55395b482a8SLen Brown * A _CID can return either a single compatible ID or a package of 55495b482a8SLen Brown * compatible IDs. Each compatible ID can be one of the following: 55595b482a8SLen Brown * 1) Integer (32 bit compressed EISA ID) or 55695b482a8SLen Brown * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") 55795b482a8SLen Brown */ 55895b482a8SLen Brown 55995b482a8SLen Brown /* The _CID object can be either a single CID or a package (list) of CIDs */ 56095b482a8SLen Brown 56195b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { 56295b482a8SLen Brown 56395b482a8SLen Brown /* Translate each package element */ 56495b482a8SLen Brown 56595b482a8SLen Brown for (i = 0; i < count; i++) { 56695b482a8SLen Brown status = 56795b482a8SLen Brown acpi_ut_translate_one_cid(obj_desc->package. 56895b482a8SLen Brown elements[i], 56995b482a8SLen Brown &cid_list->id[i]); 57095b482a8SLen Brown if (ACPI_FAILURE(status)) { 57195b482a8SLen Brown break; 57295b482a8SLen Brown } 57395b482a8SLen Brown } 57495b482a8SLen Brown } else { 57595b482a8SLen Brown /* Only one CID, translate to a string */ 57695b482a8SLen Brown 57795b482a8SLen Brown status = acpi_ut_translate_one_cid(obj_desc, cid_list->id); 57895b482a8SLen Brown } 57995b482a8SLen Brown 58095b482a8SLen Brown /* Cleanup on error */ 58195b482a8SLen Brown 58295b482a8SLen Brown if (ACPI_FAILURE(status)) { 58395b482a8SLen Brown ACPI_FREE(cid_list); 58495b482a8SLen Brown } else { 58595b482a8SLen Brown *return_cid_list = cid_list; 58695b482a8SLen Brown } 58795b482a8SLen Brown 58895b482a8SLen Brown /* On exit, we must delete the _CID return object */ 58995b482a8SLen Brown 59095b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 59195b482a8SLen Brown return_ACPI_STATUS(status); 59295b482a8SLen Brown } 59395b482a8SLen Brown 59495b482a8SLen Brown /******************************************************************************* 59595b482a8SLen Brown * 59695b482a8SLen Brown * FUNCTION: acpi_ut_execute_UID 59795b482a8SLen Brown * 59895b482a8SLen Brown * PARAMETERS: device_node - Node for the device 59995b482a8SLen Brown * Uid - Where the UID is returned 60095b482a8SLen Brown * 60195b482a8SLen Brown * RETURN: Status 60295b482a8SLen Brown * 60395b482a8SLen Brown * DESCRIPTION: Executes the _UID control method that returns the hardware 60495b482a8SLen Brown * ID of the device. 60595b482a8SLen Brown * 60695b482a8SLen Brown * NOTE: Internal function, no parameter validation 60795b482a8SLen Brown * 60895b482a8SLen Brown ******************************************************************************/ 60995b482a8SLen Brown 61095b482a8SLen Brown acpi_status 61195b482a8SLen Brown acpi_ut_execute_UID(struct acpi_namespace_node *device_node, 61295b482a8SLen Brown struct acpica_device_id *uid) 61395b482a8SLen Brown { 61495b482a8SLen Brown union acpi_operand_object *obj_desc; 61595b482a8SLen Brown acpi_status status; 61695b482a8SLen Brown 61795b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_UID); 61895b482a8SLen Brown 61995b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, 62095b482a8SLen Brown ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, 62195b482a8SLen Brown &obj_desc); 62295b482a8SLen Brown if (ACPI_FAILURE(status)) { 62395b482a8SLen Brown return_ACPI_STATUS(status); 62495b482a8SLen Brown } 62595b482a8SLen Brown 62695b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { 62795b482a8SLen Brown 62895b482a8SLen Brown /* Convert the Numeric UID to string */ 62995b482a8SLen Brown 63095b482a8SLen Brown acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, 63195b482a8SLen Brown uid->value); 63295b482a8SLen Brown } else { 63395b482a8SLen Brown /* Copy the String UID from the returned object */ 63495b482a8SLen Brown 63595b482a8SLen Brown acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer, 63695b482a8SLen Brown sizeof(uid->value)); 63795b482a8SLen Brown } 63895b482a8SLen Brown 63995b482a8SLen Brown /* On exit, we must delete the return object */ 64095b482a8SLen Brown 64195b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 64295b482a8SLen Brown return_ACPI_STATUS(status); 64395b482a8SLen Brown } 64495b482a8SLen Brown 64595b482a8SLen Brown /******************************************************************************* 64695b482a8SLen Brown * 64795b482a8SLen Brown * FUNCTION: acpi_ut_execute_STA 64895b482a8SLen Brown * 64995b482a8SLen Brown * PARAMETERS: device_node - Node for the device 65095b482a8SLen Brown * Flags - Where the status flags are returned 65195b482a8SLen Brown * 65295b482a8SLen Brown * RETURN: Status 65395b482a8SLen Brown * 65495b482a8SLen Brown * DESCRIPTION: Executes _STA for selected device and stores results in 65595b482a8SLen Brown * *Flags. 65695b482a8SLen Brown * 65795b482a8SLen Brown * NOTE: Internal function, no parameter validation 65895b482a8SLen Brown * 65995b482a8SLen Brown ******************************************************************************/ 66095b482a8SLen Brown 66195b482a8SLen Brown acpi_status 66295b482a8SLen Brown acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) 66395b482a8SLen Brown { 66495b482a8SLen Brown union acpi_operand_object *obj_desc; 66595b482a8SLen Brown acpi_status status; 66695b482a8SLen Brown 66795b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_STA); 66895b482a8SLen Brown 66995b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, 67095b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 67195b482a8SLen Brown if (ACPI_FAILURE(status)) { 67295b482a8SLen Brown if (AE_NOT_FOUND == status) { 67395b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 67495b482a8SLen Brown "_STA on %4.4s was not found, assuming device is present\n", 67595b482a8SLen Brown acpi_ut_get_node_name(device_node))); 67695b482a8SLen Brown 67795b482a8SLen Brown *flags = ACPI_UINT32_MAX; 67895b482a8SLen Brown status = AE_OK; 67995b482a8SLen Brown } 68095b482a8SLen Brown 68195b482a8SLen Brown return_ACPI_STATUS(status); 68295b482a8SLen Brown } 68395b482a8SLen Brown 68495b482a8SLen Brown /* Extract the status flags */ 68595b482a8SLen Brown 68695b482a8SLen Brown *flags = (u32) obj_desc->integer.value; 68795b482a8SLen Brown 68895b482a8SLen Brown /* On exit, we must delete the return object */ 68995b482a8SLen Brown 69095b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 69195b482a8SLen Brown return_ACPI_STATUS(status); 69295b482a8SLen Brown } 69395b482a8SLen Brown 69495b482a8SLen Brown /******************************************************************************* 69595b482a8SLen Brown * 69695b482a8SLen Brown * FUNCTION: acpi_ut_execute_Sxds 69795b482a8SLen Brown * 69895b482a8SLen Brown * PARAMETERS: device_node - Node for the device 69995b482a8SLen Brown * Flags - Where the status flags are returned 70095b482a8SLen Brown * 70195b482a8SLen Brown * RETURN: Status 70295b482a8SLen Brown * 70395b482a8SLen Brown * DESCRIPTION: Executes _STA for selected device and stores results in 70495b482a8SLen Brown * *Flags. 70595b482a8SLen Brown * 70695b482a8SLen Brown * NOTE: Internal function, no parameter validation 70795b482a8SLen Brown * 70895b482a8SLen Brown ******************************************************************************/ 70995b482a8SLen Brown 71095b482a8SLen Brown acpi_status 71195b482a8SLen Brown acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) 71295b482a8SLen Brown { 71395b482a8SLen Brown union acpi_operand_object *obj_desc; 71495b482a8SLen Brown acpi_status status; 71595b482a8SLen Brown u32 i; 71695b482a8SLen Brown 71795b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_sxds); 71895b482a8SLen Brown 71995b482a8SLen Brown for (i = 0; i < 4; i++) { 72095b482a8SLen Brown highest[i] = 0xFF; 72195b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, 72295b482a8SLen Brown ACPI_CAST_PTR(char, 72395b482a8SLen Brown acpi_gbl_highest_dstate_names 72495b482a8SLen Brown [i]), 72595b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 72695b482a8SLen Brown if (ACPI_FAILURE(status)) { 72795b482a8SLen Brown if (status != AE_NOT_FOUND) { 72895b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 72995b482a8SLen Brown "%s on Device %4.4s, %s\n", 73095b482a8SLen Brown ACPI_CAST_PTR(char, 73195b482a8SLen Brown acpi_gbl_highest_dstate_names 73295b482a8SLen Brown [i]), 73395b482a8SLen Brown acpi_ut_get_node_name 73495b482a8SLen Brown (device_node), 73595b482a8SLen Brown acpi_format_exception 73695b482a8SLen Brown (status))); 73795b482a8SLen Brown 73895b482a8SLen Brown return_ACPI_STATUS(status); 73995b482a8SLen Brown } 74095b482a8SLen Brown } else { 74195b482a8SLen Brown /* Extract the Dstate value */ 74295b482a8SLen Brown 74395b482a8SLen Brown highest[i] = (u8) obj_desc->integer.value; 74495b482a8SLen Brown 74595b482a8SLen Brown /* Delete the return object */ 74695b482a8SLen Brown 74795b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 74895b482a8SLen Brown } 74995b482a8SLen Brown } 75095b482a8SLen Brown 75195b482a8SLen Brown return_ACPI_STATUS(AE_OK); 75295b482a8SLen Brown } 753