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