1*95b482a8SLen Brown /****************************************************************************** 2*95b482a8SLen Brown * 3*95b482a8SLen Brown * Module Name: uteval - Object evaluation 4*95b482a8SLen Brown * 5*95b482a8SLen Brown *****************************************************************************/ 6*95b482a8SLen Brown 7*95b482a8SLen Brown /* 8*95b482a8SLen Brown * Copyright (C) 2000 - 2008, Intel Corp. 9*95b482a8SLen Brown * All rights reserved. 10*95b482a8SLen Brown * 11*95b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 12*95b482a8SLen Brown * modification, are permitted provided that the following conditions 13*95b482a8SLen Brown * are met: 14*95b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 15*95b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 16*95b482a8SLen Brown * without modification. 17*95b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*95b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 19*95b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 20*95b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 21*95b482a8SLen Brown * binary redistribution. 22*95b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 23*95b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 24*95b482a8SLen Brown * from this software without specific prior written permission. 25*95b482a8SLen Brown * 26*95b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 27*95b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 28*95b482a8SLen Brown * Software Foundation. 29*95b482a8SLen Brown * 30*95b482a8SLen Brown * NO WARRANTY 31*95b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*95b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*95b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*95b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*95b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*95b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*95b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*95b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*95b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*95b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*95b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 42*95b482a8SLen Brown */ 43*95b482a8SLen Brown 44*95b482a8SLen Brown #include <acpi/acpi.h> 45*95b482a8SLen Brown #include <acpi/accommon.h> 46*95b482a8SLen Brown #include <acpi/acnamesp.h> 47*95b482a8SLen Brown #include <acpi/acinterp.h> 48*95b482a8SLen Brown 49*95b482a8SLen Brown #define _COMPONENT ACPI_UTILITIES 50*95b482a8SLen Brown ACPI_MODULE_NAME("uteval") 51*95b482a8SLen Brown 52*95b482a8SLen Brown /* Local prototypes */ 53*95b482a8SLen Brown static void 54*95b482a8SLen Brown acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length); 55*95b482a8SLen Brown 56*95b482a8SLen Brown static acpi_status 57*95b482a8SLen Brown acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, 58*95b482a8SLen Brown struct acpi_compatible_id *one_cid); 59*95b482a8SLen Brown 60*95b482a8SLen Brown /* 61*95b482a8SLen Brown * Strings supported by the _OSI predefined (internal) method. 62*95b482a8SLen Brown */ 63*95b482a8SLen Brown static char *acpi_interfaces_supported[] = { 64*95b482a8SLen Brown /* Operating System Vendor Strings */ 65*95b482a8SLen Brown 66*95b482a8SLen Brown "Windows 2000", /* Windows 2000 */ 67*95b482a8SLen Brown "Windows 2001", /* Windows XP */ 68*95b482a8SLen Brown "Windows 2001 SP1", /* Windows XP SP1 */ 69*95b482a8SLen Brown "Windows 2001 SP2", /* Windows XP SP2 */ 70*95b482a8SLen Brown "Windows 2001.1", /* Windows Server 2003 */ 71*95b482a8SLen Brown "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */ 72*95b482a8SLen Brown "Windows 2006", /* Windows Vista - Added 03/2006 */ 73*95b482a8SLen Brown 74*95b482a8SLen Brown /* Feature Group Strings */ 75*95b482a8SLen Brown 76*95b482a8SLen Brown "Extended Address Space Descriptor" 77*95b482a8SLen Brown /* 78*95b482a8SLen Brown * All "optional" feature group strings (features that are implemented 79*95b482a8SLen Brown * by the host) should be implemented in the host version of 80*95b482a8SLen Brown * acpi_os_validate_interface and should not be added here. 81*95b482a8SLen Brown */ 82*95b482a8SLen Brown }; 83*95b482a8SLen Brown 84*95b482a8SLen Brown /******************************************************************************* 85*95b482a8SLen Brown * 86*95b482a8SLen Brown * FUNCTION: acpi_ut_osi_implementation 87*95b482a8SLen Brown * 88*95b482a8SLen Brown * PARAMETERS: walk_state - Current walk state 89*95b482a8SLen Brown * 90*95b482a8SLen Brown * RETURN: Status 91*95b482a8SLen Brown * 92*95b482a8SLen Brown * DESCRIPTION: Implementation of the _OSI predefined control method 93*95b482a8SLen Brown * 94*95b482a8SLen Brown ******************************************************************************/ 95*95b482a8SLen Brown 96*95b482a8SLen Brown acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) 97*95b482a8SLen Brown { 98*95b482a8SLen Brown acpi_status status; 99*95b482a8SLen Brown union acpi_operand_object *string_desc; 100*95b482a8SLen Brown union acpi_operand_object *return_desc; 101*95b482a8SLen Brown u32 i; 102*95b482a8SLen Brown 103*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_osi_implementation); 104*95b482a8SLen Brown 105*95b482a8SLen Brown /* Validate the string input argument */ 106*95b482a8SLen Brown 107*95b482a8SLen Brown string_desc = walk_state->arguments[0].object; 108*95b482a8SLen Brown if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { 109*95b482a8SLen Brown return_ACPI_STATUS(AE_TYPE); 110*95b482a8SLen Brown } 111*95b482a8SLen Brown 112*95b482a8SLen Brown /* Create a return object */ 113*95b482a8SLen Brown 114*95b482a8SLen Brown return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); 115*95b482a8SLen Brown if (!return_desc) { 116*95b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 117*95b482a8SLen Brown } 118*95b482a8SLen Brown 119*95b482a8SLen Brown /* Default return value is SUPPORTED */ 120*95b482a8SLen Brown 121*95b482a8SLen Brown return_desc->integer.value = ACPI_UINT32_MAX; 122*95b482a8SLen Brown walk_state->return_desc = return_desc; 123*95b482a8SLen Brown 124*95b482a8SLen Brown /* Compare input string to static table of supported interfaces */ 125*95b482a8SLen Brown 126*95b482a8SLen Brown for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { 127*95b482a8SLen Brown if (!ACPI_STRCMP 128*95b482a8SLen Brown (string_desc->string.pointer, 129*95b482a8SLen Brown acpi_interfaces_supported[i])) { 130*95b482a8SLen Brown 131*95b482a8SLen Brown /* The interface is supported */ 132*95b482a8SLen Brown 133*95b482a8SLen Brown return_ACPI_STATUS(AE_OK); 134*95b482a8SLen Brown } 135*95b482a8SLen Brown } 136*95b482a8SLen Brown 137*95b482a8SLen Brown /* 138*95b482a8SLen Brown * Did not match the string in the static table, call the host OSL to 139*95b482a8SLen Brown * check for a match with one of the optional strings (such as 140*95b482a8SLen Brown * "Module Device", "3.0 Thermal Model", etc.) 141*95b482a8SLen Brown */ 142*95b482a8SLen Brown status = acpi_os_validate_interface(string_desc->string.pointer); 143*95b482a8SLen Brown if (ACPI_SUCCESS(status)) { 144*95b482a8SLen Brown 145*95b482a8SLen Brown /* The interface is supported */ 146*95b482a8SLen Brown 147*95b482a8SLen Brown return_ACPI_STATUS(AE_OK); 148*95b482a8SLen Brown } 149*95b482a8SLen Brown 150*95b482a8SLen Brown /* The interface is not supported */ 151*95b482a8SLen Brown 152*95b482a8SLen Brown return_desc->integer.value = 0; 153*95b482a8SLen Brown return_ACPI_STATUS(AE_OK); 154*95b482a8SLen Brown } 155*95b482a8SLen Brown 156*95b482a8SLen Brown /******************************************************************************* 157*95b482a8SLen Brown * 158*95b482a8SLen Brown * FUNCTION: acpi_osi_invalidate 159*95b482a8SLen Brown * 160*95b482a8SLen Brown * PARAMETERS: interface_string 161*95b482a8SLen Brown * 162*95b482a8SLen Brown * RETURN: Status 163*95b482a8SLen Brown * 164*95b482a8SLen Brown * DESCRIPTION: invalidate string in pre-defiend _OSI string list 165*95b482a8SLen Brown * 166*95b482a8SLen Brown ******************************************************************************/ 167*95b482a8SLen Brown 168*95b482a8SLen Brown acpi_status acpi_osi_invalidate(char *interface) 169*95b482a8SLen Brown { 170*95b482a8SLen Brown int i; 171*95b482a8SLen Brown 172*95b482a8SLen Brown for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { 173*95b482a8SLen Brown if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) { 174*95b482a8SLen Brown *acpi_interfaces_supported[i] = '\0'; 175*95b482a8SLen Brown return AE_OK; 176*95b482a8SLen Brown } 177*95b482a8SLen Brown } 178*95b482a8SLen Brown return AE_NOT_FOUND; 179*95b482a8SLen Brown } 180*95b482a8SLen Brown 181*95b482a8SLen Brown /******************************************************************************* 182*95b482a8SLen Brown * 183*95b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_object 184*95b482a8SLen Brown * 185*95b482a8SLen Brown * PARAMETERS: prefix_node - Starting node 186*95b482a8SLen Brown * Path - Path to object from starting node 187*95b482a8SLen Brown * expected_return_types - Bitmap of allowed return types 188*95b482a8SLen Brown * return_desc - Where a return value is stored 189*95b482a8SLen Brown * 190*95b482a8SLen Brown * RETURN: Status 191*95b482a8SLen Brown * 192*95b482a8SLen Brown * DESCRIPTION: Evaluates a namespace object and verifies the type of the 193*95b482a8SLen Brown * return object. Common code that simplifies accessing objects 194*95b482a8SLen Brown * that have required return objects of fixed types. 195*95b482a8SLen Brown * 196*95b482a8SLen Brown * NOTE: Internal function, no parameter validation 197*95b482a8SLen Brown * 198*95b482a8SLen Brown ******************************************************************************/ 199*95b482a8SLen Brown 200*95b482a8SLen Brown acpi_status 201*95b482a8SLen Brown acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, 202*95b482a8SLen Brown char *path, 203*95b482a8SLen Brown u32 expected_return_btypes, 204*95b482a8SLen Brown union acpi_operand_object **return_desc) 205*95b482a8SLen Brown { 206*95b482a8SLen Brown struct acpi_evaluate_info *info; 207*95b482a8SLen Brown acpi_status status; 208*95b482a8SLen Brown u32 return_btype; 209*95b482a8SLen Brown 210*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_object); 211*95b482a8SLen Brown 212*95b482a8SLen Brown /* Allocate the evaluation information block */ 213*95b482a8SLen Brown 214*95b482a8SLen Brown info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 215*95b482a8SLen Brown if (!info) { 216*95b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 217*95b482a8SLen Brown } 218*95b482a8SLen Brown 219*95b482a8SLen Brown info->prefix_node = prefix_node; 220*95b482a8SLen Brown info->pathname = path; 221*95b482a8SLen Brown 222*95b482a8SLen Brown /* Evaluate the object/method */ 223*95b482a8SLen Brown 224*95b482a8SLen Brown status = acpi_ns_evaluate(info); 225*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 226*95b482a8SLen Brown if (status == AE_NOT_FOUND) { 227*95b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 228*95b482a8SLen Brown "[%4.4s.%s] was not found\n", 229*95b482a8SLen Brown acpi_ut_get_node_name(prefix_node), 230*95b482a8SLen Brown path)); 231*95b482a8SLen Brown } else { 232*95b482a8SLen Brown ACPI_ERROR_METHOD("Method execution failed", 233*95b482a8SLen Brown prefix_node, path, status); 234*95b482a8SLen Brown } 235*95b482a8SLen Brown 236*95b482a8SLen Brown goto cleanup; 237*95b482a8SLen Brown } 238*95b482a8SLen Brown 239*95b482a8SLen Brown /* Did we get a return object? */ 240*95b482a8SLen Brown 241*95b482a8SLen Brown if (!info->return_object) { 242*95b482a8SLen Brown if (expected_return_btypes) { 243*95b482a8SLen Brown ACPI_ERROR_METHOD("No object was returned from", 244*95b482a8SLen Brown prefix_node, path, AE_NOT_EXIST); 245*95b482a8SLen Brown 246*95b482a8SLen Brown status = AE_NOT_EXIST; 247*95b482a8SLen Brown } 248*95b482a8SLen Brown 249*95b482a8SLen Brown goto cleanup; 250*95b482a8SLen Brown } 251*95b482a8SLen Brown 252*95b482a8SLen Brown /* Map the return object type to the bitmapped type */ 253*95b482a8SLen Brown 254*95b482a8SLen Brown switch (ACPI_GET_OBJECT_TYPE(info->return_object)) { 255*95b482a8SLen Brown case ACPI_TYPE_INTEGER: 256*95b482a8SLen Brown return_btype = ACPI_BTYPE_INTEGER; 257*95b482a8SLen Brown break; 258*95b482a8SLen Brown 259*95b482a8SLen Brown case ACPI_TYPE_BUFFER: 260*95b482a8SLen Brown return_btype = ACPI_BTYPE_BUFFER; 261*95b482a8SLen Brown break; 262*95b482a8SLen Brown 263*95b482a8SLen Brown case ACPI_TYPE_STRING: 264*95b482a8SLen Brown return_btype = ACPI_BTYPE_STRING; 265*95b482a8SLen Brown break; 266*95b482a8SLen Brown 267*95b482a8SLen Brown case ACPI_TYPE_PACKAGE: 268*95b482a8SLen Brown return_btype = ACPI_BTYPE_PACKAGE; 269*95b482a8SLen Brown break; 270*95b482a8SLen Brown 271*95b482a8SLen Brown default: 272*95b482a8SLen Brown return_btype = 0; 273*95b482a8SLen Brown break; 274*95b482a8SLen Brown } 275*95b482a8SLen Brown 276*95b482a8SLen Brown if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { 277*95b482a8SLen Brown /* 278*95b482a8SLen Brown * We received a return object, but one was not expected. This can 279*95b482a8SLen Brown * happen frequently if the "implicit return" feature is enabled. 280*95b482a8SLen Brown * Just delete the return object and return AE_OK. 281*95b482a8SLen Brown */ 282*95b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 283*95b482a8SLen Brown goto cleanup; 284*95b482a8SLen Brown } 285*95b482a8SLen Brown 286*95b482a8SLen Brown /* Is the return object one of the expected types? */ 287*95b482a8SLen Brown 288*95b482a8SLen Brown if (!(expected_return_btypes & return_btype)) { 289*95b482a8SLen Brown ACPI_ERROR_METHOD("Return object type is incorrect", 290*95b482a8SLen Brown prefix_node, path, AE_TYPE); 291*95b482a8SLen Brown 292*95b482a8SLen Brown ACPI_ERROR((AE_INFO, 293*95b482a8SLen Brown "Type returned from %s was incorrect: %s, expected Btypes: %X", 294*95b482a8SLen Brown path, 295*95b482a8SLen Brown acpi_ut_get_object_type_name(info->return_object), 296*95b482a8SLen Brown expected_return_btypes)); 297*95b482a8SLen Brown 298*95b482a8SLen Brown /* On error exit, we must delete the return object */ 299*95b482a8SLen Brown 300*95b482a8SLen Brown acpi_ut_remove_reference(info->return_object); 301*95b482a8SLen Brown status = AE_TYPE; 302*95b482a8SLen Brown goto cleanup; 303*95b482a8SLen Brown } 304*95b482a8SLen Brown 305*95b482a8SLen Brown /* Object type is OK, return it */ 306*95b482a8SLen Brown 307*95b482a8SLen Brown *return_desc = info->return_object; 308*95b482a8SLen Brown 309*95b482a8SLen Brown cleanup: 310*95b482a8SLen Brown ACPI_FREE(info); 311*95b482a8SLen Brown return_ACPI_STATUS(status); 312*95b482a8SLen Brown } 313*95b482a8SLen Brown 314*95b482a8SLen Brown /******************************************************************************* 315*95b482a8SLen Brown * 316*95b482a8SLen Brown * FUNCTION: acpi_ut_evaluate_numeric_object 317*95b482a8SLen Brown * 318*95b482a8SLen Brown * PARAMETERS: object_name - Object name to be evaluated 319*95b482a8SLen Brown * device_node - Node for the device 320*95b482a8SLen Brown * Address - Where the value is returned 321*95b482a8SLen Brown * 322*95b482a8SLen Brown * RETURN: Status 323*95b482a8SLen Brown * 324*95b482a8SLen Brown * DESCRIPTION: Evaluates a numeric namespace object for a selected device 325*95b482a8SLen Brown * and stores result in *Address. 326*95b482a8SLen Brown * 327*95b482a8SLen Brown * NOTE: Internal function, no parameter validation 328*95b482a8SLen Brown * 329*95b482a8SLen Brown ******************************************************************************/ 330*95b482a8SLen Brown 331*95b482a8SLen Brown acpi_status 332*95b482a8SLen Brown acpi_ut_evaluate_numeric_object(char *object_name, 333*95b482a8SLen Brown struct acpi_namespace_node *device_node, 334*95b482a8SLen Brown acpi_integer * address) 335*95b482a8SLen Brown { 336*95b482a8SLen Brown union acpi_operand_object *obj_desc; 337*95b482a8SLen Brown acpi_status status; 338*95b482a8SLen Brown 339*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); 340*95b482a8SLen Brown 341*95b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, object_name, 342*95b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 343*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 344*95b482a8SLen Brown return_ACPI_STATUS(status); 345*95b482a8SLen Brown } 346*95b482a8SLen Brown 347*95b482a8SLen Brown /* Get the returned Integer */ 348*95b482a8SLen Brown 349*95b482a8SLen Brown *address = obj_desc->integer.value; 350*95b482a8SLen Brown 351*95b482a8SLen Brown /* On exit, we must delete the return object */ 352*95b482a8SLen Brown 353*95b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 354*95b482a8SLen Brown return_ACPI_STATUS(status); 355*95b482a8SLen Brown } 356*95b482a8SLen Brown 357*95b482a8SLen Brown /******************************************************************************* 358*95b482a8SLen Brown * 359*95b482a8SLen Brown * FUNCTION: acpi_ut_copy_id_string 360*95b482a8SLen Brown * 361*95b482a8SLen Brown * PARAMETERS: Destination - Where to copy the string 362*95b482a8SLen Brown * Source - Source string 363*95b482a8SLen Brown * max_length - Length of the destination buffer 364*95b482a8SLen Brown * 365*95b482a8SLen Brown * RETURN: None 366*95b482a8SLen Brown * 367*95b482a8SLen Brown * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. 368*95b482a8SLen Brown * Performs removal of a leading asterisk if present -- workaround 369*95b482a8SLen Brown * for a known issue on a bunch of machines. 370*95b482a8SLen Brown * 371*95b482a8SLen Brown ******************************************************************************/ 372*95b482a8SLen Brown 373*95b482a8SLen Brown static void 374*95b482a8SLen Brown acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length) 375*95b482a8SLen Brown { 376*95b482a8SLen Brown 377*95b482a8SLen Brown /* 378*95b482a8SLen Brown * Workaround for ID strings that have a leading asterisk. This construct 379*95b482a8SLen Brown * is not allowed by the ACPI specification (ID strings must be 380*95b482a8SLen Brown * alphanumeric), but enough existing machines have this embedded in their 381*95b482a8SLen Brown * ID strings that the following code is useful. 382*95b482a8SLen Brown */ 383*95b482a8SLen Brown if (*source == '*') { 384*95b482a8SLen Brown source++; 385*95b482a8SLen Brown } 386*95b482a8SLen Brown 387*95b482a8SLen Brown /* Do the actual copy */ 388*95b482a8SLen Brown 389*95b482a8SLen Brown ACPI_STRNCPY(destination, source, max_length); 390*95b482a8SLen Brown } 391*95b482a8SLen Brown 392*95b482a8SLen Brown /******************************************************************************* 393*95b482a8SLen Brown * 394*95b482a8SLen Brown * FUNCTION: acpi_ut_execute_HID 395*95b482a8SLen Brown * 396*95b482a8SLen Brown * PARAMETERS: device_node - Node for the device 397*95b482a8SLen Brown * Hid - Where the HID is returned 398*95b482a8SLen Brown * 399*95b482a8SLen Brown * RETURN: Status 400*95b482a8SLen Brown * 401*95b482a8SLen Brown * DESCRIPTION: Executes the _HID control method that returns the hardware 402*95b482a8SLen Brown * ID of the device. 403*95b482a8SLen Brown * 404*95b482a8SLen Brown * NOTE: Internal function, no parameter validation 405*95b482a8SLen Brown * 406*95b482a8SLen Brown ******************************************************************************/ 407*95b482a8SLen Brown 408*95b482a8SLen Brown acpi_status 409*95b482a8SLen Brown acpi_ut_execute_HID(struct acpi_namespace_node *device_node, 410*95b482a8SLen Brown struct acpica_device_id *hid) 411*95b482a8SLen Brown { 412*95b482a8SLen Brown union acpi_operand_object *obj_desc; 413*95b482a8SLen Brown acpi_status status; 414*95b482a8SLen Brown 415*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_HID); 416*95b482a8SLen Brown 417*95b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, 418*95b482a8SLen Brown ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, 419*95b482a8SLen Brown &obj_desc); 420*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 421*95b482a8SLen Brown return_ACPI_STATUS(status); 422*95b482a8SLen Brown } 423*95b482a8SLen Brown 424*95b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { 425*95b482a8SLen Brown 426*95b482a8SLen Brown /* Convert the Numeric HID to string */ 427*95b482a8SLen Brown 428*95b482a8SLen Brown acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, 429*95b482a8SLen Brown hid->value); 430*95b482a8SLen Brown } else { 431*95b482a8SLen Brown /* Copy the String HID from the returned object */ 432*95b482a8SLen Brown 433*95b482a8SLen Brown acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer, 434*95b482a8SLen Brown sizeof(hid->value)); 435*95b482a8SLen Brown } 436*95b482a8SLen Brown 437*95b482a8SLen Brown /* On exit, we must delete the return object */ 438*95b482a8SLen Brown 439*95b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 440*95b482a8SLen Brown return_ACPI_STATUS(status); 441*95b482a8SLen Brown } 442*95b482a8SLen Brown 443*95b482a8SLen Brown /******************************************************************************* 444*95b482a8SLen Brown * 445*95b482a8SLen Brown * FUNCTION: acpi_ut_translate_one_cid 446*95b482a8SLen Brown * 447*95b482a8SLen Brown * PARAMETERS: obj_desc - _CID object, must be integer or string 448*95b482a8SLen Brown * one_cid - Where the CID string is returned 449*95b482a8SLen Brown * 450*95b482a8SLen Brown * RETURN: Status 451*95b482a8SLen Brown * 452*95b482a8SLen Brown * DESCRIPTION: Return a numeric or string _CID value as a string. 453*95b482a8SLen Brown * (Compatible ID) 454*95b482a8SLen Brown * 455*95b482a8SLen Brown * NOTE: Assumes a maximum _CID string length of 456*95b482a8SLen Brown * ACPI_MAX_CID_LENGTH. 457*95b482a8SLen Brown * 458*95b482a8SLen Brown ******************************************************************************/ 459*95b482a8SLen Brown 460*95b482a8SLen Brown static acpi_status 461*95b482a8SLen Brown acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, 462*95b482a8SLen Brown struct acpi_compatible_id *one_cid) 463*95b482a8SLen Brown { 464*95b482a8SLen Brown 465*95b482a8SLen Brown switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { 466*95b482a8SLen Brown case ACPI_TYPE_INTEGER: 467*95b482a8SLen Brown 468*95b482a8SLen Brown /* Convert the Numeric CID to string */ 469*95b482a8SLen Brown 470*95b482a8SLen Brown acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, 471*95b482a8SLen Brown one_cid->value); 472*95b482a8SLen Brown return (AE_OK); 473*95b482a8SLen Brown 474*95b482a8SLen Brown case ACPI_TYPE_STRING: 475*95b482a8SLen Brown 476*95b482a8SLen Brown if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { 477*95b482a8SLen Brown return (AE_AML_STRING_LIMIT); 478*95b482a8SLen Brown } 479*95b482a8SLen Brown 480*95b482a8SLen Brown /* Copy the String CID from the returned object */ 481*95b482a8SLen Brown 482*95b482a8SLen Brown acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer, 483*95b482a8SLen Brown ACPI_MAX_CID_LENGTH); 484*95b482a8SLen Brown return (AE_OK); 485*95b482a8SLen Brown 486*95b482a8SLen Brown default: 487*95b482a8SLen Brown 488*95b482a8SLen Brown return (AE_TYPE); 489*95b482a8SLen Brown } 490*95b482a8SLen Brown } 491*95b482a8SLen Brown 492*95b482a8SLen Brown /******************************************************************************* 493*95b482a8SLen Brown * 494*95b482a8SLen Brown * FUNCTION: acpi_ut_execute_CID 495*95b482a8SLen Brown * 496*95b482a8SLen Brown * PARAMETERS: device_node - Node for the device 497*95b482a8SLen Brown * return_cid_list - Where the CID list is returned 498*95b482a8SLen Brown * 499*95b482a8SLen Brown * RETURN: Status 500*95b482a8SLen Brown * 501*95b482a8SLen Brown * DESCRIPTION: Executes the _CID control method that returns one or more 502*95b482a8SLen Brown * compatible hardware IDs for the device. 503*95b482a8SLen Brown * 504*95b482a8SLen Brown * NOTE: Internal function, no parameter validation 505*95b482a8SLen Brown * 506*95b482a8SLen Brown ******************************************************************************/ 507*95b482a8SLen Brown 508*95b482a8SLen Brown acpi_status 509*95b482a8SLen Brown acpi_ut_execute_CID(struct acpi_namespace_node * device_node, 510*95b482a8SLen Brown struct acpi_compatible_id_list ** return_cid_list) 511*95b482a8SLen Brown { 512*95b482a8SLen Brown union acpi_operand_object *obj_desc; 513*95b482a8SLen Brown acpi_status status; 514*95b482a8SLen Brown u32 count; 515*95b482a8SLen Brown u32 size; 516*95b482a8SLen Brown struct acpi_compatible_id_list *cid_list; 517*95b482a8SLen Brown u32 i; 518*95b482a8SLen Brown 519*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_CID); 520*95b482a8SLen Brown 521*95b482a8SLen Brown /* Evaluate the _CID method for this device */ 522*95b482a8SLen Brown 523*95b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, 524*95b482a8SLen Brown ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING 525*95b482a8SLen Brown | ACPI_BTYPE_PACKAGE, &obj_desc); 526*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 527*95b482a8SLen Brown return_ACPI_STATUS(status); 528*95b482a8SLen Brown } 529*95b482a8SLen Brown 530*95b482a8SLen Brown /* Get the number of _CIDs returned */ 531*95b482a8SLen Brown 532*95b482a8SLen Brown count = 1; 533*95b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { 534*95b482a8SLen Brown count = obj_desc->package.count; 535*95b482a8SLen Brown } 536*95b482a8SLen Brown 537*95b482a8SLen Brown /* Allocate a worst-case buffer for the _CIDs */ 538*95b482a8SLen Brown 539*95b482a8SLen Brown size = (((count - 1) * sizeof(struct acpi_compatible_id)) + 540*95b482a8SLen Brown sizeof(struct acpi_compatible_id_list)); 541*95b482a8SLen Brown 542*95b482a8SLen Brown cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); 543*95b482a8SLen Brown if (!cid_list) { 544*95b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 545*95b482a8SLen Brown } 546*95b482a8SLen Brown 547*95b482a8SLen Brown /* Init CID list */ 548*95b482a8SLen Brown 549*95b482a8SLen Brown cid_list->count = count; 550*95b482a8SLen Brown cid_list->size = size; 551*95b482a8SLen Brown 552*95b482a8SLen Brown /* 553*95b482a8SLen Brown * A _CID can return either a single compatible ID or a package of 554*95b482a8SLen Brown * compatible IDs. Each compatible ID can be one of the following: 555*95b482a8SLen Brown * 1) Integer (32 bit compressed EISA ID) or 556*95b482a8SLen Brown * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") 557*95b482a8SLen Brown */ 558*95b482a8SLen Brown 559*95b482a8SLen Brown /* The _CID object can be either a single CID or a package (list) of CIDs */ 560*95b482a8SLen Brown 561*95b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { 562*95b482a8SLen Brown 563*95b482a8SLen Brown /* Translate each package element */ 564*95b482a8SLen Brown 565*95b482a8SLen Brown for (i = 0; i < count; i++) { 566*95b482a8SLen Brown status = 567*95b482a8SLen Brown acpi_ut_translate_one_cid(obj_desc->package. 568*95b482a8SLen Brown elements[i], 569*95b482a8SLen Brown &cid_list->id[i]); 570*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 571*95b482a8SLen Brown break; 572*95b482a8SLen Brown } 573*95b482a8SLen Brown } 574*95b482a8SLen Brown } else { 575*95b482a8SLen Brown /* Only one CID, translate to a string */ 576*95b482a8SLen Brown 577*95b482a8SLen Brown status = acpi_ut_translate_one_cid(obj_desc, cid_list->id); 578*95b482a8SLen Brown } 579*95b482a8SLen Brown 580*95b482a8SLen Brown /* Cleanup on error */ 581*95b482a8SLen Brown 582*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 583*95b482a8SLen Brown ACPI_FREE(cid_list); 584*95b482a8SLen Brown } else { 585*95b482a8SLen Brown *return_cid_list = cid_list; 586*95b482a8SLen Brown } 587*95b482a8SLen Brown 588*95b482a8SLen Brown /* On exit, we must delete the _CID return object */ 589*95b482a8SLen Brown 590*95b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 591*95b482a8SLen Brown return_ACPI_STATUS(status); 592*95b482a8SLen Brown } 593*95b482a8SLen Brown 594*95b482a8SLen Brown /******************************************************************************* 595*95b482a8SLen Brown * 596*95b482a8SLen Brown * FUNCTION: acpi_ut_execute_UID 597*95b482a8SLen Brown * 598*95b482a8SLen Brown * PARAMETERS: device_node - Node for the device 599*95b482a8SLen Brown * Uid - Where the UID is returned 600*95b482a8SLen Brown * 601*95b482a8SLen Brown * RETURN: Status 602*95b482a8SLen Brown * 603*95b482a8SLen Brown * DESCRIPTION: Executes the _UID control method that returns the hardware 604*95b482a8SLen Brown * ID of the device. 605*95b482a8SLen Brown * 606*95b482a8SLen Brown * NOTE: Internal function, no parameter validation 607*95b482a8SLen Brown * 608*95b482a8SLen Brown ******************************************************************************/ 609*95b482a8SLen Brown 610*95b482a8SLen Brown acpi_status 611*95b482a8SLen Brown acpi_ut_execute_UID(struct acpi_namespace_node *device_node, 612*95b482a8SLen Brown struct acpica_device_id *uid) 613*95b482a8SLen Brown { 614*95b482a8SLen Brown union acpi_operand_object *obj_desc; 615*95b482a8SLen Brown acpi_status status; 616*95b482a8SLen Brown 617*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_UID); 618*95b482a8SLen Brown 619*95b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, 620*95b482a8SLen Brown ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, 621*95b482a8SLen Brown &obj_desc); 622*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 623*95b482a8SLen Brown return_ACPI_STATUS(status); 624*95b482a8SLen Brown } 625*95b482a8SLen Brown 626*95b482a8SLen Brown if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { 627*95b482a8SLen Brown 628*95b482a8SLen Brown /* Convert the Numeric UID to string */ 629*95b482a8SLen Brown 630*95b482a8SLen Brown acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, 631*95b482a8SLen Brown uid->value); 632*95b482a8SLen Brown } else { 633*95b482a8SLen Brown /* Copy the String UID from the returned object */ 634*95b482a8SLen Brown 635*95b482a8SLen Brown acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer, 636*95b482a8SLen Brown sizeof(uid->value)); 637*95b482a8SLen Brown } 638*95b482a8SLen Brown 639*95b482a8SLen Brown /* On exit, we must delete the return object */ 640*95b482a8SLen Brown 641*95b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 642*95b482a8SLen Brown return_ACPI_STATUS(status); 643*95b482a8SLen Brown } 644*95b482a8SLen Brown 645*95b482a8SLen Brown /******************************************************************************* 646*95b482a8SLen Brown * 647*95b482a8SLen Brown * FUNCTION: acpi_ut_execute_STA 648*95b482a8SLen Brown * 649*95b482a8SLen Brown * PARAMETERS: device_node - Node for the device 650*95b482a8SLen Brown * Flags - Where the status flags are returned 651*95b482a8SLen Brown * 652*95b482a8SLen Brown * RETURN: Status 653*95b482a8SLen Brown * 654*95b482a8SLen Brown * DESCRIPTION: Executes _STA for selected device and stores results in 655*95b482a8SLen Brown * *Flags. 656*95b482a8SLen Brown * 657*95b482a8SLen Brown * NOTE: Internal function, no parameter validation 658*95b482a8SLen Brown * 659*95b482a8SLen Brown ******************************************************************************/ 660*95b482a8SLen Brown 661*95b482a8SLen Brown acpi_status 662*95b482a8SLen Brown acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) 663*95b482a8SLen Brown { 664*95b482a8SLen Brown union acpi_operand_object *obj_desc; 665*95b482a8SLen Brown acpi_status status; 666*95b482a8SLen Brown 667*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_STA); 668*95b482a8SLen Brown 669*95b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, 670*95b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 671*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 672*95b482a8SLen Brown if (AE_NOT_FOUND == status) { 673*95b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 674*95b482a8SLen Brown "_STA on %4.4s was not found, assuming device is present\n", 675*95b482a8SLen Brown acpi_ut_get_node_name(device_node))); 676*95b482a8SLen Brown 677*95b482a8SLen Brown *flags = ACPI_UINT32_MAX; 678*95b482a8SLen Brown status = AE_OK; 679*95b482a8SLen Brown } 680*95b482a8SLen Brown 681*95b482a8SLen Brown return_ACPI_STATUS(status); 682*95b482a8SLen Brown } 683*95b482a8SLen Brown 684*95b482a8SLen Brown /* Extract the status flags */ 685*95b482a8SLen Brown 686*95b482a8SLen Brown *flags = (u32) obj_desc->integer.value; 687*95b482a8SLen Brown 688*95b482a8SLen Brown /* On exit, we must delete the return object */ 689*95b482a8SLen Brown 690*95b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 691*95b482a8SLen Brown return_ACPI_STATUS(status); 692*95b482a8SLen Brown } 693*95b482a8SLen Brown 694*95b482a8SLen Brown /******************************************************************************* 695*95b482a8SLen Brown * 696*95b482a8SLen Brown * FUNCTION: acpi_ut_execute_Sxds 697*95b482a8SLen Brown * 698*95b482a8SLen Brown * PARAMETERS: device_node - Node for the device 699*95b482a8SLen Brown * Flags - Where the status flags are returned 700*95b482a8SLen Brown * 701*95b482a8SLen Brown * RETURN: Status 702*95b482a8SLen Brown * 703*95b482a8SLen Brown * DESCRIPTION: Executes _STA for selected device and stores results in 704*95b482a8SLen Brown * *Flags. 705*95b482a8SLen Brown * 706*95b482a8SLen Brown * NOTE: Internal function, no parameter validation 707*95b482a8SLen Brown * 708*95b482a8SLen Brown ******************************************************************************/ 709*95b482a8SLen Brown 710*95b482a8SLen Brown acpi_status 711*95b482a8SLen Brown acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) 712*95b482a8SLen Brown { 713*95b482a8SLen Brown union acpi_operand_object *obj_desc; 714*95b482a8SLen Brown acpi_status status; 715*95b482a8SLen Brown u32 i; 716*95b482a8SLen Brown 717*95b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_execute_sxds); 718*95b482a8SLen Brown 719*95b482a8SLen Brown for (i = 0; i < 4; i++) { 720*95b482a8SLen Brown highest[i] = 0xFF; 721*95b482a8SLen Brown status = acpi_ut_evaluate_object(device_node, 722*95b482a8SLen Brown ACPI_CAST_PTR(char, 723*95b482a8SLen Brown acpi_gbl_highest_dstate_names 724*95b482a8SLen Brown [i]), 725*95b482a8SLen Brown ACPI_BTYPE_INTEGER, &obj_desc); 726*95b482a8SLen Brown if (ACPI_FAILURE(status)) { 727*95b482a8SLen Brown if (status != AE_NOT_FOUND) { 728*95b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 729*95b482a8SLen Brown "%s on Device %4.4s, %s\n", 730*95b482a8SLen Brown ACPI_CAST_PTR(char, 731*95b482a8SLen Brown acpi_gbl_highest_dstate_names 732*95b482a8SLen Brown [i]), 733*95b482a8SLen Brown acpi_ut_get_node_name 734*95b482a8SLen Brown (device_node), 735*95b482a8SLen Brown acpi_format_exception 736*95b482a8SLen Brown (status))); 737*95b482a8SLen Brown 738*95b482a8SLen Brown return_ACPI_STATUS(status); 739*95b482a8SLen Brown } 740*95b482a8SLen Brown } else { 741*95b482a8SLen Brown /* Extract the Dstate value */ 742*95b482a8SLen Brown 743*95b482a8SLen Brown highest[i] = (u8) obj_desc->integer.value; 744*95b482a8SLen Brown 745*95b482a8SLen Brown /* Delete the return object */ 746*95b482a8SLen Brown 747*95b482a8SLen Brown acpi_ut_remove_reference(obj_desc); 748*95b482a8SLen Brown } 749*95b482a8SLen Brown } 750*95b482a8SLen Brown 751*95b482a8SLen Brown return_ACPI_STATUS(AE_OK); 752*95b482a8SLen Brown } 753