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