1 /****************************************************************************** 2 * 3 * Module Name: nspredef - Validation of ACPI predefined methods and objects 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 #define __NSPREDEF_C__ 117 118 #include "acpi.h" 119 #include "accommon.h" 120 #include "acnamesp.h" 121 #include "acpredef.h" 122 123 124 #define _COMPONENT ACPI_NAMESPACE 125 ACPI_MODULE_NAME ("nspredef") 126 127 128 /******************************************************************************* 129 * 130 * This module validates predefined ACPI objects that appear in the namespace, 131 * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this 132 * validation is to detect problems with BIOS-exposed predefined ACPI objects 133 * before the results are returned to the ACPI-related drivers. 134 * 135 * There are several areas that are validated: 136 * 137 * 1) The number of input arguments as defined by the method/object in the 138 * ASL is validated against the ACPI specification. 139 * 2) The type of the return object (if any) is validated against the ACPI 140 * specification. 141 * 3) For returned package objects, the count of package elements is 142 * validated, as well as the type of each package element. Nested 143 * packages are supported. 144 * 145 * For any problems found, a warning message is issued. 146 * 147 ******************************************************************************/ 148 149 /* Local prototypes */ 150 151 static ACPI_STATUS 152 AcpiNsCheckPackage ( 153 char *Pathname, 154 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 155 const ACPI_PREDEFINED_INFO *Predefined); 156 157 static ACPI_STATUS 158 AcpiNsCheckPackageElements ( 159 char *Pathname, 160 ACPI_OPERAND_OBJECT **Elements, 161 UINT8 Type1, 162 UINT32 Count1, 163 UINT8 Type2, 164 UINT32 Count2, 165 UINT32 StartIndex); 166 167 static ACPI_STATUS 168 AcpiNsCheckObjectType ( 169 char *Pathname, 170 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 171 UINT32 ExpectedBtypes, 172 UINT32 PackageIndex); 173 174 static ACPI_STATUS 175 AcpiNsCheckReference ( 176 char *Pathname, 177 ACPI_OPERAND_OBJECT *ReturnObject); 178 179 static ACPI_STATUS 180 AcpiNsRepairObject ( 181 UINT32 ExpectedBtypes, 182 UINT32 PackageIndex, 183 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 184 185 /* 186 * Names for the types that can be returned by the predefined objects. 187 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 188 */ 189 static const char *AcpiRtypeNames[] = 190 { 191 "/Integer", 192 "/String", 193 "/Buffer", 194 "/Package", 195 "/Reference", 196 }; 197 198 #define ACPI_NOT_PACKAGE ACPI_UINT32_MAX 199 200 201 /******************************************************************************* 202 * 203 * FUNCTION: AcpiNsCheckPredefinedNames 204 * 205 * PARAMETERS: Node - Namespace node for the method/object 206 * ReturnObjectPtr - Pointer to the object returned from the 207 * evaluation of a method or object 208 * 209 * RETURN: Status 210 * 211 * DESCRIPTION: Check an ACPI name for a match in the predefined name list. 212 * 213 ******************************************************************************/ 214 215 ACPI_STATUS 216 AcpiNsCheckPredefinedNames ( 217 ACPI_NAMESPACE_NODE *Node, 218 UINT32 UserParamCount, 219 ACPI_STATUS ReturnStatus, 220 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 221 { 222 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 223 ACPI_STATUS Status = AE_OK; 224 const ACPI_PREDEFINED_INFO *Predefined; 225 char *Pathname; 226 227 228 /* Match the name for this method/object against the predefined list */ 229 230 Predefined = AcpiNsCheckForPredefinedName (Node); 231 232 /* Get the full pathname to the object, for use in error messages */ 233 234 Pathname = AcpiNsGetExternalPathname (Node); 235 if (!Pathname) 236 { 237 return (AE_OK); /* Could not get pathname, ignore */ 238 } 239 240 /* 241 * Check that the parameter count for this method matches the ASL 242 * definition. For predefined names, ensure that both the caller and 243 * the method itself are in accordance with the ACPI specification. 244 */ 245 AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined); 246 247 /* If not a predefined name, we cannot validate the return object */ 248 249 if (!Predefined) 250 { 251 goto Exit; 252 } 253 254 /* If the method failed, we cannot validate the return object */ 255 256 if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) 257 { 258 goto Exit; 259 } 260 261 /* 262 * Only validate the return value on the first successful evaluation of 263 * the method. This ensures that any warnings will only be emitted during 264 * the very first evaluation of the method/object. 265 */ 266 if (Node->Flags & ANOBJ_EVALUATED) 267 { 268 goto Exit; 269 } 270 271 /* Mark the node as having been successfully evaluated */ 272 273 Node->Flags |= ANOBJ_EVALUATED; 274 275 /* 276 * If there is no return value, check if we require a return value for 277 * this predefined name. Either one return value is expected, or none, 278 * for both methods and other objects. 279 * 280 * Exit now if there is no return object. Warning if one was expected. 281 */ 282 if (!ReturnObject) 283 { 284 if ((Predefined->Info.ExpectedBtypes) && 285 (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) 286 { 287 ACPI_ERROR ((AE_INFO, 288 "%s: Missing expected return value", Pathname)); 289 290 Status = AE_AML_NO_RETURN_VALUE; 291 } 292 goto Exit; 293 } 294 295 /* 296 * We have a return value, but if one wasn't expected, just exit, this is 297 * not a problem 298 * 299 * For example, if the "Implicit Return" feature is enabled, methods will 300 * always return a value 301 */ 302 if (!Predefined->Info.ExpectedBtypes) 303 { 304 goto Exit; 305 } 306 307 /* 308 * Check that the type of the return object is what is expected for 309 * this predefined name 310 */ 311 Status = AcpiNsCheckObjectType (Pathname, ReturnObjectPtr, 312 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE); 313 if (ACPI_FAILURE (Status)) 314 { 315 goto Exit; 316 } 317 318 /* For returned Package objects, check the type of all sub-objects */ 319 320 if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE) 321 { 322 Status = AcpiNsCheckPackage (Pathname, ReturnObjectPtr, Predefined); 323 } 324 325 Exit: 326 ACPI_FREE (Pathname); 327 return (Status); 328 } 329 330 331 /******************************************************************************* 332 * 333 * FUNCTION: AcpiNsCheckParameterCount 334 * 335 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 336 * Node - Namespace node for the method/object 337 * UserParamCount - Number of args passed in by the caller 338 * Predefined - Pointer to entry in predefined name table 339 * 340 * RETURN: None 341 * 342 * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a 343 * predefined name is what is expected (i.e., what is defined in 344 * the ACPI specification for this predefined name.) 345 * 346 ******************************************************************************/ 347 348 void 349 AcpiNsCheckParameterCount ( 350 char *Pathname, 351 ACPI_NAMESPACE_NODE *Node, 352 UINT32 UserParamCount, 353 const ACPI_PREDEFINED_INFO *Predefined) 354 { 355 UINT32 ParamCount; 356 UINT32 RequiredParamsCurrent; 357 UINT32 RequiredParamsOld; 358 359 360 /* Methods have 0-7 parameters. All other types have zero. */ 361 362 ParamCount = 0; 363 if (Node->Type == ACPI_TYPE_METHOD) 364 { 365 ParamCount = Node->Object->Method.ParamCount; 366 } 367 368 /* Argument count check for non-predefined methods/objects */ 369 370 if (!Predefined) 371 { 372 /* 373 * Warning if too few or too many arguments have been passed by the 374 * caller. An incorrect number of arguments may not cause the method 375 * to fail. However, the method will fail if there are too few 376 * arguments and the method attempts to use one of the missing ones. 377 */ 378 if (UserParamCount < ParamCount) 379 { 380 ACPI_WARNING ((AE_INFO, 381 "%s: Insufficient arguments - needs %d, found %d", 382 Pathname, ParamCount, UserParamCount)); 383 } 384 else if (UserParamCount > ParamCount) 385 { 386 ACPI_WARNING ((AE_INFO, 387 "%s: Excess arguments - needs %d, found %d", 388 Pathname, ParamCount, UserParamCount)); 389 } 390 return; 391 } 392 393 /* Allow two different legal argument counts (_SCP, etc.) */ 394 395 RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F; 396 RequiredParamsOld = Predefined->Info.ParamCount >> 4; 397 398 if (UserParamCount != ACPI_UINT32_MAX) 399 { 400 /* Validate the user-supplied parameter count */ 401 402 if ((UserParamCount != RequiredParamsCurrent) && 403 (UserParamCount != RequiredParamsOld)) 404 { 405 ACPI_WARNING ((AE_INFO, 406 "%s: Parameter count mismatch - " 407 "caller passed %d, ACPI requires %d", 408 Pathname, UserParamCount, RequiredParamsCurrent)); 409 } 410 } 411 412 /* 413 * Only validate the argument count on the first successful evaluation of 414 * the method. This ensures that any warnings will only be emitted during 415 * the very first evaluation of the method/object. 416 */ 417 if (Node->Flags & ANOBJ_EVALUATED) 418 { 419 return; 420 } 421 422 /* 423 * Check that the ASL-defined parameter count is what is expected for 424 * this predefined name. 425 */ 426 if ((ParamCount != RequiredParamsCurrent) && 427 (ParamCount != RequiredParamsOld)) 428 { 429 ACPI_WARNING ((AE_INFO, 430 "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", 431 Pathname, ParamCount, RequiredParamsCurrent)); 432 } 433 } 434 435 436 /******************************************************************************* 437 * 438 * FUNCTION: AcpiNsCheckForPredefinedName 439 * 440 * PARAMETERS: Node - Namespace node for the method/object 441 * 442 * RETURN: Pointer to entry in predefined table. NULL indicates not found. 443 * 444 * DESCRIPTION: Check an object name against the predefined object list. 445 * 446 ******************************************************************************/ 447 448 const ACPI_PREDEFINED_INFO * 449 AcpiNsCheckForPredefinedName ( 450 ACPI_NAMESPACE_NODE *Node) 451 { 452 const ACPI_PREDEFINED_INFO *ThisName; 453 454 455 /* Quick check for a predefined name, first character must be underscore */ 456 457 if (Node->Name.Ascii[0] != '_') 458 { 459 return (NULL); 460 } 461 462 /* Search info table for a predefined method/object name */ 463 464 ThisName = PredefinedNames; 465 while (ThisName->Info.Name[0]) 466 { 467 if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name)) 468 { 469 /* Return pointer to this table entry */ 470 471 return (ThisName); 472 } 473 474 /* 475 * Skip next entry in the table if this name returns a Package 476 * (next entry contains the package info) 477 */ 478 if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) 479 { 480 ThisName++; 481 } 482 483 ThisName++; 484 } 485 486 return (NULL); 487 } 488 489 490 /******************************************************************************* 491 * 492 * FUNCTION: AcpiNsCheckPackage 493 * 494 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 495 * ReturnObjectPtr - Pointer to the object returned from the 496 * evaluation of a method or object 497 * Predefined - Pointer to entry in predefined name table 498 * 499 * RETURN: Status 500 * 501 * DESCRIPTION: Check a returned package object for the correct count and 502 * correct type of all sub-objects. 503 * 504 ******************************************************************************/ 505 506 static ACPI_STATUS 507 AcpiNsCheckPackage ( 508 char *Pathname, 509 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 510 const ACPI_PREDEFINED_INFO *Predefined) 511 { 512 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 513 const ACPI_PREDEFINED_INFO *Package; 514 ACPI_OPERAND_OBJECT *SubPackage; 515 ACPI_OPERAND_OBJECT **Elements; 516 ACPI_OPERAND_OBJECT **SubElements; 517 ACPI_STATUS Status; 518 UINT32 ExpectedCount; 519 UINT32 Count; 520 UINT32 i; 521 UINT32 j; 522 523 524 ACPI_FUNCTION_NAME (NsCheckPackage); 525 526 527 /* The package info for this name is in the next table entry */ 528 529 Package = Predefined + 1; 530 531 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 532 "%s Validating return Package of Type %X, Count %X\n", 533 Pathname, Package->RetInfo.Type, ReturnObject->Package.Count)); 534 535 /* Extract package count and elements array */ 536 537 Elements = ReturnObject->Package.Elements; 538 Count = ReturnObject->Package.Count; 539 540 /* The package must have at least one element, else invalid */ 541 542 if (!Count) 543 { 544 ACPI_WARNING ((AE_INFO, 545 "%s: Return Package has no elements (empty)", Pathname)); 546 547 return (AE_AML_OPERAND_VALUE); 548 } 549 550 /* 551 * Decode the type of the expected package contents 552 * 553 * PTYPE1 packages contain no subpackages 554 * PTYPE2 packages contain sub-packages 555 */ 556 switch (Package->RetInfo.Type) 557 { 558 case ACPI_PTYPE1_FIXED: 559 560 /* 561 * The package count is fixed and there are no sub-packages 562 * 563 * If package is too small, exit. 564 * If package is larger than expected, issue warning but continue 565 */ 566 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 567 if (Count < ExpectedCount) 568 { 569 goto PackageTooSmall; 570 } 571 else if (Count > ExpectedCount) 572 { 573 ACPI_WARNING ((AE_INFO, 574 "%s: Return Package is larger than needed - " 575 "found %u, expected %u", Pathname, Count, ExpectedCount)); 576 } 577 578 /* Validate all elements of the returned package */ 579 580 Status = AcpiNsCheckPackageElements (Pathname, Elements, 581 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 582 Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0); 583 if (ACPI_FAILURE (Status)) 584 { 585 return (Status); 586 } 587 break; 588 589 590 case ACPI_PTYPE1_VAR: 591 592 /* 593 * The package count is variable, there are no sub-packages, and all 594 * elements must be of the same type 595 */ 596 for (i = 0; i < Count; i++) 597 { 598 Status = AcpiNsCheckObjectType (Pathname, Elements, 599 Package->RetInfo.ObjectType1, i); 600 if (ACPI_FAILURE (Status)) 601 { 602 return (Status); 603 } 604 Elements++; 605 } 606 break; 607 608 609 case ACPI_PTYPE1_OPTION: 610 611 /* 612 * The package count is variable, there are no sub-packages. There are 613 * a fixed number of required elements, and a variable number of 614 * optional elements. 615 * 616 * Check if package is at least as large as the minimum required 617 */ 618 ExpectedCount = Package->RetInfo3.Count; 619 if (Count < ExpectedCount) 620 { 621 goto PackageTooSmall; 622 } 623 624 /* Variable number of sub-objects */ 625 626 for (i = 0; i < Count; i++) 627 { 628 if (i < Package->RetInfo3.Count) 629 { 630 /* These are the required package elements (0, 1, or 2) */ 631 632 Status = AcpiNsCheckObjectType (Pathname, Elements, 633 Package->RetInfo3.ObjectType[i], i); 634 if (ACPI_FAILURE (Status)) 635 { 636 return (Status); 637 } 638 } 639 else 640 { 641 /* These are the optional package elements */ 642 643 Status = AcpiNsCheckObjectType (Pathname, Elements, 644 Package->RetInfo3.TailObjectType, i); 645 if (ACPI_FAILURE (Status)) 646 { 647 return (Status); 648 } 649 } 650 Elements++; 651 } 652 break; 653 654 655 case ACPI_PTYPE2_PKG_COUNT: 656 657 /* First element is the (Integer) count of sub-packages to follow */ 658 659 Status = AcpiNsCheckObjectType (Pathname, Elements, 660 ACPI_RTYPE_INTEGER, 0); 661 if (ACPI_FAILURE (Status)) 662 { 663 return (Status); 664 } 665 666 /* 667 * Count cannot be larger than the parent package length, but allow it 668 * to be smaller. The >= accounts for the Integer above. 669 */ 670 ExpectedCount = (UINT32) (*Elements)->Integer.Value; 671 if (ExpectedCount >= Count) 672 { 673 goto PackageTooSmall; 674 } 675 676 Count = ExpectedCount; 677 Elements++; 678 679 /* Now we can walk the sub-packages */ 680 681 /*lint -fallthrough */ 682 683 684 case ACPI_PTYPE2: 685 case ACPI_PTYPE2_FIXED: 686 case ACPI_PTYPE2_MIN: 687 case ACPI_PTYPE2_COUNT: 688 689 /* 690 * These types all return a single package that consists of a variable 691 * number of sub-packages 692 */ 693 for (i = 0; i < Count; i++) 694 { 695 SubPackage = *Elements; 696 SubElements = SubPackage->Package.Elements; 697 698 /* Each sub-object must be of type Package */ 699 700 Status = AcpiNsCheckObjectType (Pathname, &SubPackage, 701 ACPI_RTYPE_PACKAGE, i); 702 if (ACPI_FAILURE (Status)) 703 { 704 return (Status); 705 } 706 707 /* Examine the different types of sub-packages */ 708 709 switch (Package->RetInfo.Type) 710 { 711 case ACPI_PTYPE2: 712 case ACPI_PTYPE2_PKG_COUNT: 713 714 /* Each subpackage has a fixed number of elements */ 715 716 ExpectedCount = 717 Package->RetInfo.Count1 + Package->RetInfo.Count2; 718 if (SubPackage->Package.Count != ExpectedCount) 719 { 720 Count = SubPackage->Package.Count; 721 goto PackageTooSmall; 722 } 723 724 Status = AcpiNsCheckPackageElements (Pathname, SubElements, 725 Package->RetInfo.ObjectType1, 726 Package->RetInfo.Count1, 727 Package->RetInfo.ObjectType2, 728 Package->RetInfo.Count2, 0); 729 if (ACPI_FAILURE (Status)) 730 { 731 return (Status); 732 } 733 break; 734 735 case ACPI_PTYPE2_FIXED: 736 737 /* Each sub-package has a fixed length */ 738 739 ExpectedCount = Package->RetInfo2.Count; 740 if (SubPackage->Package.Count < ExpectedCount) 741 { 742 Count = SubPackage->Package.Count; 743 goto PackageTooSmall; 744 } 745 746 /* Check the type of each sub-package element */ 747 748 for (j = 0; j < ExpectedCount; j++) 749 { 750 Status = AcpiNsCheckObjectType (Pathname, &SubElements[j], 751 Package->RetInfo2.ObjectType[j], j); 752 if (ACPI_FAILURE (Status)) 753 { 754 return (Status); 755 } 756 } 757 break; 758 759 case ACPI_PTYPE2_MIN: 760 761 /* Each sub-package has a variable but minimum length */ 762 763 ExpectedCount = Package->RetInfo.Count1; 764 if (SubPackage->Package.Count < ExpectedCount) 765 { 766 Count = SubPackage->Package.Count; 767 goto PackageTooSmall; 768 } 769 770 /* Check the type of each sub-package element */ 771 772 Status = AcpiNsCheckPackageElements (Pathname, SubElements, 773 Package->RetInfo.ObjectType1, 774 SubPackage->Package.Count, 0, 0, 0); 775 if (ACPI_FAILURE (Status)) 776 { 777 return (Status); 778 } 779 break; 780 781 case ACPI_PTYPE2_COUNT: 782 783 /* First element is the (Integer) count of elements to follow */ 784 785 Status = AcpiNsCheckObjectType (Pathname, SubElements, 786 ACPI_RTYPE_INTEGER, 0); 787 if (ACPI_FAILURE (Status)) 788 { 789 return (Status); 790 } 791 792 /* Make sure package is large enough for the Count */ 793 794 ExpectedCount = (UINT32) (*SubElements)->Integer.Value; 795 if (SubPackage->Package.Count < ExpectedCount) 796 { 797 Count = SubPackage->Package.Count; 798 goto PackageTooSmall; 799 } 800 801 /* Check the type of each sub-package element */ 802 803 Status = AcpiNsCheckPackageElements (Pathname, 804 (SubElements + 1), 805 Package->RetInfo.ObjectType1, 806 (ExpectedCount - 1), 0, 0, 1); 807 if (ACPI_FAILURE (Status)) 808 { 809 return (Status); 810 } 811 break; 812 813 default: 814 break; 815 } 816 817 Elements++; 818 } 819 break; 820 821 822 default: 823 824 /* Should not get here if predefined info table is correct */ 825 826 ACPI_WARNING ((AE_INFO, 827 "%s: Invalid internal return type in table entry: %X", 828 Pathname, Package->RetInfo.Type)); 829 830 return (AE_AML_INTERNAL); 831 } 832 833 return (AE_OK); 834 835 836 PackageTooSmall: 837 838 /* Error exit for the case with an incorrect package count */ 839 840 ACPI_WARNING ((AE_INFO, "%s: Return Package is too small - " 841 "found %u, expected %u", Pathname, Count, ExpectedCount)); 842 843 return (AE_AML_OPERAND_VALUE); 844 } 845 846 847 /******************************************************************************* 848 * 849 * FUNCTION: AcpiNsCheckPackageElements 850 * 851 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 852 * Elements - Pointer to the package elements array 853 * Type1 - Object type for first group 854 * Count1 - Count for first group 855 * Type2 - Object type for second group 856 * Count2 - Count for second group 857 * StartIndex - Start of the first group of elements 858 * 859 * RETURN: Status 860 * 861 * DESCRIPTION: Check that all elements of a package are of the correct object 862 * type. Supports up to two groups of different object types. 863 * 864 ******************************************************************************/ 865 866 static ACPI_STATUS 867 AcpiNsCheckPackageElements ( 868 char *Pathname, 869 ACPI_OPERAND_OBJECT **Elements, 870 UINT8 Type1, 871 UINT32 Count1, 872 UINT8 Type2, 873 UINT32 Count2, 874 UINT32 StartIndex) 875 { 876 ACPI_OPERAND_OBJECT **ThisElement = Elements; 877 ACPI_STATUS Status; 878 UINT32 i; 879 880 881 /* 882 * Up to two groups of package elements are supported by the data 883 * structure. All elements in each group must be of the same type. 884 * The second group can have a count of zero. 885 */ 886 for (i = 0; i < Count1; i++) 887 { 888 Status = AcpiNsCheckObjectType (Pathname, ThisElement, 889 Type1, i + StartIndex); 890 if (ACPI_FAILURE (Status)) 891 { 892 return (Status); 893 } 894 ThisElement++; 895 } 896 897 for (i = 0; i < Count2; i++) 898 { 899 Status = AcpiNsCheckObjectType (Pathname, ThisElement, 900 Type2, (i + Count1 + StartIndex)); 901 if (ACPI_FAILURE (Status)) 902 { 903 return (Status); 904 } 905 ThisElement++; 906 } 907 908 return (AE_OK); 909 } 910 911 912 /******************************************************************************* 913 * 914 * FUNCTION: AcpiNsCheckObjectType 915 * 916 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 917 * ReturnObjectPtr - Pointer to the object returned from the 918 * evaluation of a method or object 919 * ExpectedBtypes - Bitmap of expected return type(s) 920 * PackageIndex - Index of object within parent package (if 921 * applicable - ACPI_NOT_PACKAGE otherwise) 922 * 923 * RETURN: Status 924 * 925 * DESCRIPTION: Check the type of the return object against the expected object 926 * type(s). Use of Btype allows multiple expected object types. 927 * 928 ******************************************************************************/ 929 930 static ACPI_STATUS 931 AcpiNsCheckObjectType ( 932 char *Pathname, 933 ACPI_OPERAND_OBJECT **ReturnObjectPtr, 934 UINT32 ExpectedBtypes, 935 UINT32 PackageIndex) 936 { 937 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 938 ACPI_STATUS Status = AE_OK; 939 UINT32 ReturnBtype; 940 char TypeBuffer[48]; /* Room for 5 types */ 941 UINT32 ThisRtype; 942 UINT32 i; 943 UINT32 j; 944 945 946 /* 947 * If we get a NULL ReturnObject here, it is a NULL package element, 948 * and this is always an error. 949 */ 950 if (!ReturnObject) 951 { 952 goto TypeErrorExit; 953 } 954 955 /* A Namespace node should not get here, but make sure */ 956 957 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) 958 { 959 ACPI_WARNING ((AE_INFO, 960 "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", 961 Pathname, ReturnObject->Node.Name.Ascii, 962 AcpiUtGetTypeName (ReturnObject->Node.Type))); 963 return (AE_AML_OPERAND_TYPE); 964 } 965 966 /* 967 * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. 968 * The bitmapped type allows multiple possible return types. 969 * 970 * Note, the cases below must handle all of the possible types returned 971 * from all of the predefined names (including elements of returned 972 * packages) 973 */ 974 switch (ReturnObject->Common.Type) 975 { 976 case ACPI_TYPE_INTEGER: 977 ReturnBtype = ACPI_RTYPE_INTEGER; 978 break; 979 980 case ACPI_TYPE_BUFFER: 981 ReturnBtype = ACPI_RTYPE_BUFFER; 982 break; 983 984 case ACPI_TYPE_STRING: 985 ReturnBtype = ACPI_RTYPE_STRING; 986 break; 987 988 case ACPI_TYPE_PACKAGE: 989 ReturnBtype = ACPI_RTYPE_PACKAGE; 990 break; 991 992 case ACPI_TYPE_LOCAL_REFERENCE: 993 ReturnBtype = ACPI_RTYPE_REFERENCE; 994 break; 995 996 default: 997 /* Not one of the supported objects, must be incorrect */ 998 999 goto TypeErrorExit; 1000 } 1001 1002 /* Is the object one of the expected types? */ 1003 1004 if (!(ReturnBtype & ExpectedBtypes)) 1005 { 1006 /* Type mismatch -- attempt repair of the returned object */ 1007 1008 Status = AcpiNsRepairObject (ExpectedBtypes, PackageIndex, 1009 ReturnObjectPtr); 1010 if (ACPI_SUCCESS (Status)) 1011 { 1012 return (Status); 1013 } 1014 goto TypeErrorExit; 1015 } 1016 1017 /* For reference objects, check that the reference type is correct */ 1018 1019 if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) 1020 { 1021 Status = AcpiNsCheckReference (Pathname, ReturnObject); 1022 } 1023 1024 return (Status); 1025 1026 1027 TypeErrorExit: 1028 1029 /* Create a string with all expected types for this predefined object */ 1030 1031 j = 1; 1032 TypeBuffer[0] = 0; 1033 ThisRtype = ACPI_RTYPE_INTEGER; 1034 1035 for (i = 0; i < ACPI_NUM_RTYPES; i++) 1036 { 1037 /* If one of the expected types, concatenate the name of this type */ 1038 1039 if (ExpectedBtypes & ThisRtype) 1040 { 1041 ACPI_STRCAT (TypeBuffer, &AcpiRtypeNames[i][j]); 1042 j = 0; /* Use name separator from now on */ 1043 } 1044 ThisRtype <<= 1; /* Next Rtype */ 1045 } 1046 1047 if (PackageIndex == ACPI_NOT_PACKAGE) 1048 { 1049 ACPI_WARNING ((AE_INFO, 1050 "%s: Return type mismatch - found %s, expected %s", 1051 Pathname, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1052 } 1053 else 1054 { 1055 ACPI_WARNING ((AE_INFO, 1056 "%s: Return Package type mismatch at index %u - " 1057 "found %s, expected %s", Pathname, PackageIndex, 1058 AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1059 } 1060 1061 return (AE_AML_OPERAND_TYPE); 1062 } 1063 1064 1065 /******************************************************************************* 1066 * 1067 * FUNCTION: AcpiNsCheckReference 1068 * 1069 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 1070 * ReturnObject - Object returned from the evaluation of a 1071 * method or object 1072 * 1073 * RETURN: Status 1074 * 1075 * DESCRIPTION: Check a returned reference object for the correct reference 1076 * type. The only reference type that can be returned from a 1077 * predefined method is a named reference. All others are invalid. 1078 * 1079 ******************************************************************************/ 1080 1081 static ACPI_STATUS 1082 AcpiNsCheckReference ( 1083 char *Pathname, 1084 ACPI_OPERAND_OBJECT *ReturnObject) 1085 { 1086 1087 /* 1088 * Check the reference object for the correct reference type (opcode). 1089 * The only type of reference that can be converted to an ACPI_OBJECT is 1090 * a reference to a named object (reference class: NAME) 1091 */ 1092 if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME) 1093 { 1094 return (AE_OK); 1095 } 1096 1097 ACPI_WARNING ((AE_INFO, 1098 "%s: Return type mismatch - " 1099 "unexpected reference object type [%s] %2.2X", 1100 Pathname, AcpiUtGetReferenceName (ReturnObject), 1101 ReturnObject->Reference.Class)); 1102 1103 return (AE_AML_OPERAND_TYPE); 1104 } 1105 1106 1107 /******************************************************************************* 1108 * 1109 * FUNCTION: AcpiNsRepairObject 1110 * 1111 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 1112 * PackageIndex - Used to determine if target is in a package 1113 * ReturnObjectPtr - Pointer to the object returned from the 1114 * evaluation of a method or object 1115 * 1116 * RETURN: Status. AE_OK if repair was successful. 1117 * 1118 * DESCRIPTION: Attempt to repair/convert a return object of a type that was 1119 * not expected. 1120 * 1121 ******************************************************************************/ 1122 1123 static ACPI_STATUS 1124 AcpiNsRepairObject ( 1125 UINT32 ExpectedBtypes, 1126 UINT32 PackageIndex, 1127 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 1128 { 1129 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 1130 ACPI_OPERAND_OBJECT *NewObject; 1131 ACPI_SIZE Length; 1132 1133 1134 switch (ReturnObject->Common.Type) 1135 { 1136 case ACPI_TYPE_BUFFER: 1137 1138 if (!(ExpectedBtypes & ACPI_RTYPE_STRING)) 1139 { 1140 return (AE_AML_OPERAND_TYPE); 1141 } 1142 1143 /* 1144 * Have a Buffer, expected a String, convert. Use a ToString 1145 * conversion, no transform performed on the buffer data. The best 1146 * example of this is the _BIF method, where the string data from 1147 * the battery is often (incorrectly) returned as buffer object(s). 1148 */ 1149 Length = 0; 1150 while ((Length < ReturnObject->Buffer.Length) && 1151 (ReturnObject->Buffer.Pointer[Length])) 1152 { 1153 Length++; 1154 } 1155 1156 /* Allocate a new string object */ 1157 1158 NewObject = AcpiUtCreateStringObject (Length); 1159 if (!NewObject) 1160 { 1161 return (AE_NO_MEMORY); 1162 } 1163 1164 /* 1165 * Copy the raw buffer data with no transform. String is already NULL 1166 * terminated at Length+1. 1167 */ 1168 ACPI_MEMCPY (NewObject->String.Pointer, 1169 ReturnObject->Buffer.Pointer, Length); 1170 1171 /* Install the new return object */ 1172 1173 AcpiUtRemoveReference (ReturnObject); 1174 *ReturnObjectPtr = NewObject; 1175 1176 /* 1177 * If the object is a package element, we need to: 1178 * 1. Decrement the reference count of the orignal object, it was 1179 * incremented when building the package 1180 * 2. Increment the reference count of the new object, it will be 1181 * decremented when releasing the package 1182 */ 1183 if (PackageIndex != ACPI_NOT_PACKAGE) 1184 { 1185 AcpiUtRemoveReference (ReturnObject); 1186 AcpiUtAddReference (NewObject); 1187 } 1188 return (AE_OK); 1189 1190 default: 1191 break; 1192 } 1193 1194 return (AE_AML_OPERAND_TYPE); 1195 } 1196 1197