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