Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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