1 /******************************************************************************
   2  *
   3  * Module Name: nspredef - Validation of ACPI predefined methods and objects
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 #define ACPI_CREATE_PREDEFINED_TABLE
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 #include "acnamesp.h"
  49 #include "acpredef.h"
  50 
  51 
  52 #define _COMPONENT          ACPI_NAMESPACE
  53         ACPI_MODULE_NAME    ("nspredef")
  54 
  55 
  56 /*******************************************************************************
  57  *
  58  * This module validates predefined ACPI objects that appear in the namespace,
  59  * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
  60  * validation is to detect problems with BIOS-exposed predefined ACPI objects
  61  * before the results are returned to the ACPI-related drivers.
  62  *
  63  * There are several areas that are validated:
  64  *
  65  *  1) The number of input arguments as defined by the method/object in the
  66  *      ASL is validated against the ACPI specification.
  67  *  2) The type of the return object (if any) is validated against the ACPI
  68  *      specification.
  69  *  3) For returned package objects, the count of package elements is
  70  *      validated, as well as the type of each package element. Nested
  71  *      packages are supported.
  72  *
  73  * For any problems found, a warning message is issued.
  74  *
  75  ******************************************************************************/
  76 
  77 
  78 /* Local prototypes */
  79 
  80 static ACPI_STATUS
  81 AcpiNsCheckPackage (
  82     ACPI_PREDEFINED_DATA        *Data,
  83     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
  84 
  85 static ACPI_STATUS
  86 AcpiNsCheckPackageList (
  87     ACPI_PREDEFINED_DATA        *Data,
  88     const ACPI_PREDEFINED_INFO  *Package,
  89     ACPI_OPERAND_OBJECT         **Elements,
  90     UINT32                      Count);
  91 
  92 static ACPI_STATUS
  93 AcpiNsCheckPackageElements (
  94     ACPI_PREDEFINED_DATA        *Data,
  95     ACPI_OPERAND_OBJECT         **Elements,
  96     UINT8                       Type1,
  97     UINT32                      Count1,
  98     UINT8                       Type2,
  99     UINT32                      Count2,
 100     UINT32                      StartIndex);
 101 
 102 static ACPI_STATUS
 103 AcpiNsCheckObjectType (
 104     ACPI_PREDEFINED_DATA        *Data,
 105     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
 106     UINT32                      ExpectedBtypes,
 107     UINT32                      PackageIndex);
 108 
 109 static ACPI_STATUS
 110 AcpiNsCheckReference (
 111     ACPI_PREDEFINED_DATA        *Data,
 112     ACPI_OPERAND_OBJECT         *ReturnObject);
 113 
 114 static void
 115 AcpiNsGetExpectedTypes (
 116     char                        *Buffer,
 117     UINT32                      ExpectedBtypes);
 118 
 119 /*
 120  * Names for the types that can be returned by the predefined objects.
 121  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
 122  */
 123 static const char   *AcpiRtypeNames[] =
 124 {
 125     "/Integer",
 126     "/String",
 127     "/Buffer",
 128     "/Package",
 129     "/Reference",
 130 };
 131 
 132 
 133 /*******************************************************************************
 134  *
 135  * FUNCTION:    AcpiNsCheckPredefinedNames
 136  *
 137  * PARAMETERS:  Node            - Namespace node for the method/object
 138  *              UserParamCount  - Number of parameters actually passed
 139  *              ReturnStatus    - Status from the object evaluation
 140  *              ReturnObjectPtr - Pointer to the object returned from the
 141  *                                evaluation of a method or object
 142  *
 143  * RETURN:      Status
 144  *
 145  * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
 146  *
 147  ******************************************************************************/
 148 
 149 ACPI_STATUS
 150 AcpiNsCheckPredefinedNames (
 151     ACPI_NAMESPACE_NODE         *Node,
 152     UINT32                      UserParamCount,
 153     ACPI_STATUS                 ReturnStatus,
 154     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
 155 {
 156     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
 157     ACPI_STATUS                 Status = AE_OK;
 158     const ACPI_PREDEFINED_INFO  *Predefined;
 159     char                        *Pathname;
 160     ACPI_PREDEFINED_DATA        *Data;
 161 
 162 
 163     /* Match the name for this method/object against the predefined list */
 164 
 165     Predefined = AcpiNsCheckForPredefinedName (Node);
 166 
 167     /* Get the full pathname to the object, for use in warning messages */
 168 
 169     Pathname = AcpiNsGetExternalPathname (Node);
 170     if (!Pathname)
 171     {
 172         return (AE_OK); /* Could not get pathname, ignore */
 173     }
 174 
 175     /*
 176      * Check that the parameter count for this method matches the ASL
 177      * definition. For predefined names, ensure that both the caller and
 178      * the method itself are in accordance with the ACPI specification.
 179      */
 180     AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
 181 
 182     /* If not a predefined name, we cannot validate the return object */
 183 
 184     if (!Predefined)
 185     {
 186         goto Cleanup;
 187     }
 188 
 189     /*
 190      * If the method failed or did not actually return an object, we cannot
 191      * validate the return object
 192      */
 193     if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
 194     {
 195         goto Cleanup;
 196     }
 197 
 198     /*
 199      * If there is no return value, check if we require a return value for
 200      * this predefined name. Either one return value is expected, or none,
 201      * for both methods and other objects.
 202      *
 203      * Exit now if there is no return object. Warning if one was expected.
 204      */
 205     if (!ReturnObject)
 206     {
 207         if ((Predefined->Info.ExpectedBtypes) &&
 208             (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
 209         {
 210             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
 211                 "Missing expected return value"));
 212 
 213             Status = AE_AML_NO_RETURN_VALUE;
 214         }
 215         goto Cleanup;
 216     }
 217 
 218     /*
 219      * 1) We have a return value, but if one wasn't expected, just exit, this is
 220      * not a problem. For example, if the "Implicit Return" feature is
 221      * enabled, methods will always return a value.
 222      *
 223      * 2) If the return value can be of any type, then we cannot perform any
 224      * validation, exit.
 225      */
 226     if ((!Predefined->Info.ExpectedBtypes) ||
 227         (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL))
 228     {
 229         goto Cleanup;
 230     }
 231 
 232     /* Create the parameter data block for object validation */
 233 
 234     Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA));
 235     if (!Data)
 236     {
 237         goto Cleanup;
 238     }
 239     Data->Predefined = Predefined;
 240     Data->NodeFlags = Node->Flags;
 241     Data->Pathname = Pathname;
 242 
 243     /*
 244      * Check that the type of the main return object is what is expected
 245      * for this predefined name
 246      */
 247     Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
 248                 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
 249     if (ACPI_FAILURE (Status))
 250     {
 251         goto Exit;
 252     }
 253 
 254     /*
 255      * For returned Package objects, check the type of all sub-objects.
 256      * Note: Package may have been newly created by call above.
 257      */
 258     if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
 259     {
 260         Data->ParentPackage = *ReturnObjectPtr;
 261         Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
 262         if (ACPI_FAILURE (Status))
 263         {
 264             goto Exit;
 265         }
 266     }
 267 
 268     /*
 269      * The return object was OK, or it was successfully repaired above.
 270      * Now make some additional checks such as verifying that package
 271      * objects are sorted correctly (if required) or buffer objects have
 272      * the correct data width (bytes vs. dwords). These repairs are
 273      * performed on a per-name basis, i.e., the code is specific to
 274      * particular predefined names.
 275      */
 276     Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr);
 277 
 278 Exit:
 279     /*
 280      * If the object validation failed or if we successfully repaired one
 281      * or more objects, mark the parent node to suppress further warning
 282      * messages during the next evaluation of the same method/object.
 283      */
 284     if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED))
 285     {
 286         Node->Flags |= ANOBJ_EVALUATED;
 287     }
 288     ACPI_FREE (Data);
 289 
 290 Cleanup:
 291     ACPI_FREE (Pathname);
 292     return (Status);
 293 }
 294 
 295 
 296 /*******************************************************************************
 297  *
 298  * FUNCTION:    AcpiNsCheckParameterCount
 299  *
 300  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
 301  *              Node            - Namespace node for the method/object
 302  *              UserParamCount  - Number of args passed in by the caller
 303  *              Predefined      - Pointer to entry in predefined name table
 304  *
 305  * RETURN:      None
 306  *
 307  * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
 308  *              predefined name is what is expected (i.e., what is defined in
 309  *              the ACPI specification for this predefined name.)
 310  *
 311  ******************************************************************************/
 312 
 313 void
 314 AcpiNsCheckParameterCount (
 315     char                        *Pathname,
 316     ACPI_NAMESPACE_NODE         *Node,
 317     UINT32                      UserParamCount,
 318     const ACPI_PREDEFINED_INFO  *Predefined)
 319 {
 320     UINT32                      ParamCount;
 321     UINT32                      RequiredParamsCurrent;
 322     UINT32                      RequiredParamsOld;
 323 
 324 
 325     /* Methods have 0-7 parameters. All other types have zero. */
 326 
 327     ParamCount = 0;
 328     if (Node->Type == ACPI_TYPE_METHOD)
 329     {
 330         ParamCount = Node->Object->Method.ParamCount;
 331     }
 332 
 333     if (!Predefined)
 334     {
 335         /*
 336          * Check the parameter count for non-predefined methods/objects.
 337          *
 338          * Warning if too few or too many arguments have been passed by the
 339          * caller. An incorrect number of arguments may not cause the method
 340          * to fail. However, the method will fail if there are too few
 341          * arguments and the method attempts to use one of the missing ones.
 342          */
 343         if (UserParamCount < ParamCount)
 344         {
 345             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
 346                 "Insufficient arguments - needs %u, found %u",
 347                 ParamCount, UserParamCount));
 348         }
 349         else if (UserParamCount > ParamCount)
 350         {
 351             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
 352                 "Excess arguments - needs %u, found %u",
 353                 ParamCount, UserParamCount));
 354         }
 355         return;
 356     }
 357 
 358     /*
 359      * Validate the user-supplied parameter count.
 360      * Allow two different legal argument counts (_SCP, etc.)
 361      */
 362     RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
 363     RequiredParamsOld = Predefined->Info.ParamCount >> 4;
 364 
 365     if (UserParamCount != ACPI_UINT32_MAX)
 366     {
 367         if ((UserParamCount != RequiredParamsCurrent) &&
 368             (UserParamCount != RequiredParamsOld))
 369         {
 370             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
 371                 "Parameter count mismatch - "
 372                 "caller passed %u, ACPI requires %u",
 373                 UserParamCount, RequiredParamsCurrent));
 374         }
 375     }
 376 
 377     /*
 378      * Check that the ASL-defined parameter count is what is expected for
 379      * this predefined name (parameter count as defined by the ACPI
 380      * specification)
 381      */
 382     if ((ParamCount != RequiredParamsCurrent) &&
 383         (ParamCount != RequiredParamsOld))
 384     {
 385         ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags,
 386             "Parameter count mismatch - ASL declared %u, ACPI requires %u",
 387             ParamCount, RequiredParamsCurrent));
 388     }
 389 }
 390 
 391 
 392 /*******************************************************************************
 393  *
 394  * FUNCTION:    AcpiNsCheckForPredefinedName
 395  *
 396  * PARAMETERS:  Node            - Namespace node for the method/object
 397  *
 398  * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
 399  *
 400  * DESCRIPTION: Check an object name against the predefined object list.
 401  *
 402  ******************************************************************************/
 403 
 404 const ACPI_PREDEFINED_INFO *
 405 AcpiNsCheckForPredefinedName (
 406     ACPI_NAMESPACE_NODE         *Node)
 407 {
 408     const ACPI_PREDEFINED_INFO  *ThisName;
 409 
 410 
 411     /* Quick check for a predefined name, first character must be underscore */
 412 
 413     if (Node->Name.Ascii[0] != '_')
 414     {
 415         return (NULL);
 416     }
 417 
 418     /* Search info table for a predefined method/object name */
 419 
 420     ThisName = PredefinedNames;
 421     while (ThisName->Info.Name[0])
 422     {
 423         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
 424         {
 425             return (ThisName);
 426         }
 427 
 428         /*
 429          * Skip next entry in the table if this name returns a Package
 430          * (next entry contains the package info)
 431          */
 432         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
 433         {
 434             ThisName++;
 435         }
 436 
 437         ThisName++;
 438     }
 439 
 440     return (NULL); /* Not found */
 441 }
 442 
 443 
 444 /*******************************************************************************
 445  *
 446  * FUNCTION:    AcpiNsCheckPackage
 447  *
 448  * PARAMETERS:  Data            - Pointer to validation data structure
 449  *              ReturnObjectPtr - Pointer to the object returned from the
 450  *                                evaluation of a method or object
 451  *
 452  * RETURN:      Status
 453  *
 454  * DESCRIPTION: Check a returned package object for the correct count and
 455  *              correct type of all sub-objects.
 456  *
 457  ******************************************************************************/
 458 
 459 static ACPI_STATUS
 460 AcpiNsCheckPackage (
 461     ACPI_PREDEFINED_DATA        *Data,
 462     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
 463 {
 464     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
 465     const ACPI_PREDEFINED_INFO  *Package;
 466     ACPI_OPERAND_OBJECT         **Elements;
 467     ACPI_STATUS                 Status = AE_OK;
 468     UINT32                      ExpectedCount;
 469     UINT32                      Count;
 470     UINT32                      i;
 471 
 472 
 473     ACPI_FUNCTION_NAME (NsCheckPackage);
 474 
 475 
 476     /* The package info for this name is in the next table entry */
 477 
 478     Package = Data->Predefined + 1;
 479 
 480     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 481         "%s Validating return Package of Type %X, Count %X\n",
 482         Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
 483 
 484     /*
 485      * For variable-length Packages, we can safely remove all embedded
 486      * and trailing NULL package elements
 487      */
 488     AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject);
 489 
 490     /* Extract package count and elements array */
 491 
 492     Elements = ReturnObject->Package.Elements;
 493     Count = ReturnObject->Package.Count;
 494 
 495     /* The package must have at least one element, else invalid */
 496 
 497     if (!Count)
 498     {
 499         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
 500             "Return Package has no elements (empty)"));
 501 
 502         return (AE_AML_OPERAND_VALUE);
 503     }
 504 
 505     /*
 506      * Decode the type of the expected package contents
 507      *
 508      * PTYPE1 packages contain no subpackages
 509      * PTYPE2 packages contain sub-packages
 510      */
 511     switch (Package->RetInfo.Type)
 512     {
 513     case ACPI_PTYPE1_FIXED:
 514 
 515         /*
 516          * The package count is fixed and there are no sub-packages
 517          *
 518          * If package is too small, exit.
 519          * If package is larger than expected, issue warning but continue
 520          */
 521         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
 522         if (Count < ExpectedCount)
 523         {
 524             goto PackageTooSmall;
 525         }
 526         else if (Count > ExpectedCount)
 527         {
 528             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
 529                 "%s: Return Package is larger than needed - "
 530                 "found %u, expected %u\n",
 531                 Data->Pathname, Count, ExpectedCount));
 532         }
 533 
 534         /* Validate all elements of the returned package */
 535 
 536         Status = AcpiNsCheckPackageElements (Data, Elements,
 537                     Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
 538                     Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
 539         break;
 540 
 541 
 542     case ACPI_PTYPE1_VAR:
 543 
 544         /*
 545          * The package count is variable, there are no sub-packages, and all
 546          * elements must be of the same type
 547          */
 548         for (i = 0; i < Count; i++)
 549         {
 550             Status = AcpiNsCheckObjectType (Data, Elements,
 551                         Package->RetInfo.ObjectType1, i);
 552             if (ACPI_FAILURE (Status))
 553             {
 554                 return (Status);
 555             }
 556             Elements++;
 557         }
 558         break;
 559 
 560 
 561     case ACPI_PTYPE1_OPTION:
 562 
 563         /*
 564          * The package count is variable, there are no sub-packages. There are
 565          * a fixed number of required elements, and a variable number of
 566          * optional elements.
 567          *
 568          * Check if package is at least as large as the minimum required
 569          */
 570         ExpectedCount = Package->RetInfo3.Count;
 571         if (Count < ExpectedCount)
 572         {
 573             goto PackageTooSmall;
 574         }
 575 
 576         /* Variable number of sub-objects */
 577 
 578         for (i = 0; i < Count; i++)
 579         {
 580             if (i < Package->RetInfo3.Count)
 581             {
 582                 /* These are the required package elements (0, 1, or 2) */
 583 
 584                 Status = AcpiNsCheckObjectType (Data, Elements,
 585                             Package->RetInfo3.ObjectType[i], i);
 586                 if (ACPI_FAILURE (Status))
 587                 {
 588                     return (Status);
 589                 }
 590             }
 591             else
 592             {
 593                 /* These are the optional package elements */
 594 
 595                 Status = AcpiNsCheckObjectType (Data, Elements,
 596                             Package->RetInfo3.TailObjectType, i);
 597                 if (ACPI_FAILURE (Status))
 598                 {
 599                     return (Status);
 600                 }
 601             }
 602             Elements++;
 603         }
 604         break;
 605 
 606 
 607     case ACPI_PTYPE2_REV_FIXED:
 608 
 609         /* First element is the (Integer) revision */
 610 
 611         Status = AcpiNsCheckObjectType (Data, Elements,
 612                     ACPI_RTYPE_INTEGER, 0);
 613         if (ACPI_FAILURE (Status))
 614         {
 615             return (Status);
 616         }
 617 
 618         Elements++;
 619         Count--;
 620 
 621         /* Examine the sub-packages */
 622 
 623         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
 624         break;
 625 
 626 
 627     case ACPI_PTYPE2_PKG_COUNT:
 628 
 629         /* First element is the (Integer) count of sub-packages to follow */
 630 
 631         Status = AcpiNsCheckObjectType (Data, Elements,
 632                     ACPI_RTYPE_INTEGER, 0);
 633         if (ACPI_FAILURE (Status))
 634         {
 635             return (Status);
 636         }
 637 
 638         /*
 639          * Count cannot be larger than the parent package length, but allow it
 640          * to be smaller. The >= accounts for the Integer above.
 641          */
 642         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
 643         if (ExpectedCount >= Count)
 644         {
 645             goto PackageTooSmall;
 646         }
 647 
 648         Count = ExpectedCount;
 649         Elements++;
 650 
 651         /* Examine the sub-packages */
 652 
 653         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
 654         break;
 655 
 656 
 657     case ACPI_PTYPE2:
 658     case ACPI_PTYPE2_FIXED:
 659     case ACPI_PTYPE2_MIN:
 660     case ACPI_PTYPE2_COUNT:
 661 
 662         /*
 663          * These types all return a single Package that consists of a
 664          * variable number of sub-Packages.
 665          *
 666          * First, ensure that the first element is a sub-Package. If not,
 667          * the BIOS may have incorrectly returned the object as a single
 668          * package instead of a Package of Packages (a common error if
 669          * there is only one entry). We may be able to repair this by
 670          * wrapping the returned Package with a new outer Package.
 671          */
 672         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
 673         {
 674             /* Create the new outer package and populate it */
 675 
 676             Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr);
 677             if (ACPI_FAILURE (Status))
 678             {
 679                 return (Status);
 680             }
 681 
 682             /* Update locals to point to the new package (of 1 element) */
 683 
 684             ReturnObject = *ReturnObjectPtr;
 685             Elements = ReturnObject->Package.Elements;
 686             Count = 1;
 687         }
 688 
 689         /* Examine the sub-packages */
 690 
 691         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
 692         break;
 693 
 694 
 695     default:
 696 
 697         /* Should not get here if predefined info table is correct */
 698 
 699         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
 700             "Invalid internal return type in table entry: %X",
 701             Package->RetInfo.Type));
 702 
 703         return (AE_AML_INTERNAL);
 704     }
 705 
 706     return (Status);
 707 
 708 
 709 PackageTooSmall:
 710 
 711     /* Error exit for the case with an incorrect package count */
 712 
 713     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
 714         "Return Package is too small - found %u elements, expected %u",
 715         Count, ExpectedCount));
 716 
 717     return (AE_AML_OPERAND_VALUE);
 718 }
 719 
 720 
 721 /*******************************************************************************
 722  *
 723  * FUNCTION:    AcpiNsCheckPackageList
 724  *
 725  * PARAMETERS:  Data            - Pointer to validation data structure
 726  *              Package         - Pointer to package-specific info for method
 727  *              Elements        - Element list of parent package. All elements
 728  *                                of this list should be of type Package.
 729  *              Count           - Count of subpackages
 730  *
 731  * RETURN:      Status
 732  *
 733  * DESCRIPTION: Examine a list of subpackages
 734  *
 735  ******************************************************************************/
 736 
 737 static ACPI_STATUS
 738 AcpiNsCheckPackageList (
 739     ACPI_PREDEFINED_DATA        *Data,
 740     const ACPI_PREDEFINED_INFO  *Package,
 741     ACPI_OPERAND_OBJECT         **Elements,
 742     UINT32                      Count)
 743 {
 744     ACPI_OPERAND_OBJECT         *SubPackage;
 745     ACPI_OPERAND_OBJECT         **SubElements;
 746     ACPI_STATUS                 Status;
 747     UINT32                      ExpectedCount;
 748     UINT32                      i;
 749     UINT32                      j;
 750 
 751 
 752     /*
 753      * Validate each sub-Package in the parent Package
 754      *
 755      * NOTE: assumes list of sub-packages contains no NULL elements.
 756      * Any NULL elements should have been removed by earlier call
 757      * to AcpiNsRemoveNullElements.
 758      */
 759     for (i = 0; i < Count; i++)
 760     {
 761         SubPackage = *Elements;
 762         SubElements = SubPackage->Package.Elements;
 763         Data->ParentPackage = SubPackage;
 764 
 765         /* Each sub-object must be of type Package */
 766 
 767         Status = AcpiNsCheckObjectType (Data, &SubPackage,
 768                     ACPI_RTYPE_PACKAGE, i);
 769         if (ACPI_FAILURE (Status))
 770         {
 771             return (Status);
 772         }
 773 
 774         /* Examine the different types of expected sub-packages */
 775 
 776         Data->ParentPackage = SubPackage;
 777         switch (Package->RetInfo.Type)
 778         {
 779         case ACPI_PTYPE2:
 780         case ACPI_PTYPE2_PKG_COUNT:
 781         case ACPI_PTYPE2_REV_FIXED:
 782 
 783             /* Each subpackage has a fixed number of elements */
 784 
 785             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
 786             if (SubPackage->Package.Count < ExpectedCount)
 787             {
 788                 goto PackageTooSmall;
 789             }
 790 
 791             Status = AcpiNsCheckPackageElements (Data, SubElements,
 792                         Package->RetInfo.ObjectType1,
 793                         Package->RetInfo.Count1,
 794                         Package->RetInfo.ObjectType2,
 795                         Package->RetInfo.Count2, 0);
 796             if (ACPI_FAILURE (Status))
 797             {
 798                 return (Status);
 799             }
 800             break;
 801 
 802 
 803         case ACPI_PTYPE2_FIXED:
 804 
 805             /* Each sub-package has a fixed length */
 806 
 807             ExpectedCount = Package->RetInfo2.Count;
 808             if (SubPackage->Package.Count < ExpectedCount)
 809             {
 810                 goto PackageTooSmall;
 811             }
 812 
 813             /* Check the type of each sub-package element */
 814 
 815             for (j = 0; j < ExpectedCount; j++)
 816             {
 817                 Status = AcpiNsCheckObjectType (Data, &SubElements[j],
 818                             Package->RetInfo2.ObjectType[j], j);
 819                 if (ACPI_FAILURE (Status))
 820                 {
 821                     return (Status);
 822                 }
 823             }
 824             break;
 825 
 826 
 827         case ACPI_PTYPE2_MIN:
 828 
 829             /* Each sub-package has a variable but minimum length */
 830 
 831             ExpectedCount = Package->RetInfo.Count1;
 832             if (SubPackage->Package.Count < ExpectedCount)
 833             {
 834                 goto PackageTooSmall;
 835             }
 836 
 837             /* Check the type of each sub-package element */
 838 
 839             Status = AcpiNsCheckPackageElements (Data, SubElements,
 840                         Package->RetInfo.ObjectType1,
 841                         SubPackage->Package.Count, 0, 0, 0);
 842             if (ACPI_FAILURE (Status))
 843             {
 844                 return (Status);
 845             }
 846             break;
 847 
 848 
 849         case ACPI_PTYPE2_COUNT:
 850 
 851             /*
 852              * First element is the (Integer) count of elements, including
 853              * the count field (the ACPI name is NumElements)
 854              */
 855             Status = AcpiNsCheckObjectType (Data, SubElements,
 856                         ACPI_RTYPE_INTEGER, 0);
 857             if (ACPI_FAILURE (Status))
 858             {
 859                 return (Status);
 860             }
 861 
 862             /*
 863              * Make sure package is large enough for the Count and is
 864              * is as large as the minimum size
 865              */
 866             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
 867             if (SubPackage->Package.Count < ExpectedCount)
 868             {
 869                 goto PackageTooSmall;
 870             }
 871             if (SubPackage->Package.Count < Package->RetInfo.Count1)
 872             {
 873                 ExpectedCount = Package->RetInfo.Count1;
 874                 goto PackageTooSmall;
 875             }
 876             if (ExpectedCount == 0)
 877             {
 878                 /*
 879                  * Either the NumEntries element was originally zero or it was
 880                  * a NULL element and repaired to an Integer of value zero.
 881                  * In either case, repair it by setting NumEntries to be the
 882                  * actual size of the subpackage.
 883                  */
 884                 ExpectedCount = SubPackage->Package.Count;
 885                 (*SubElements)->Integer.Value = ExpectedCount;
 886             }
 887 
 888             /* Check the type of each sub-package element */
 889 
 890             Status = AcpiNsCheckPackageElements (Data, (SubElements + 1),
 891                         Package->RetInfo.ObjectType1,
 892                         (ExpectedCount - 1), 0, 0, 1);
 893             if (ACPI_FAILURE (Status))
 894             {
 895                 return (Status);
 896             }
 897             break;
 898 
 899 
 900         default: /* Should not get here, type was validated by caller */
 901 
 902             return (AE_AML_INTERNAL);
 903         }
 904 
 905         Elements++;
 906     }
 907 
 908     return (AE_OK);
 909 
 910 
 911 PackageTooSmall:
 912 
 913     /* The sub-package count was smaller than required */
 914 
 915     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
 916         "Return Sub-Package[%u] is too small - found %u elements, expected %u",
 917         i, SubPackage->Package.Count, ExpectedCount));
 918 
 919     return (AE_AML_OPERAND_VALUE);
 920 }
 921 
 922 
 923 /*******************************************************************************
 924  *
 925  * FUNCTION:    AcpiNsCheckPackageElements
 926  *
 927  * PARAMETERS:  Data            - Pointer to validation data structure
 928  *              Elements        - Pointer to the package elements array
 929  *              Type1           - Object type for first group
 930  *              Count1          - Count for first group
 931  *              Type2           - Object type for second group
 932  *              Count2          - Count for second group
 933  *              StartIndex      - Start of the first group of elements
 934  *
 935  * RETURN:      Status
 936  *
 937  * DESCRIPTION: Check that all elements of a package are of the correct object
 938  *              type. Supports up to two groups of different object types.
 939  *
 940  ******************************************************************************/
 941 
 942 static ACPI_STATUS
 943 AcpiNsCheckPackageElements (
 944     ACPI_PREDEFINED_DATA        *Data,
 945     ACPI_OPERAND_OBJECT         **Elements,
 946     UINT8                       Type1,
 947     UINT32                      Count1,
 948     UINT8                       Type2,
 949     UINT32                      Count2,
 950     UINT32                      StartIndex)
 951 {
 952     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
 953     ACPI_STATUS                 Status;
 954     UINT32                      i;
 955 
 956 
 957     /*
 958      * Up to two groups of package elements are supported by the data
 959      * structure. All elements in each group must be of the same type.
 960      * The second group can have a count of zero.
 961      */
 962     for (i = 0; i < Count1; i++)
 963     {
 964         Status = AcpiNsCheckObjectType (Data, ThisElement,
 965                     Type1, i + StartIndex);
 966         if (ACPI_FAILURE (Status))
 967         {
 968             return (Status);
 969         }
 970         ThisElement++;
 971     }
 972 
 973     for (i = 0; i < Count2; i++)
 974     {
 975         Status = AcpiNsCheckObjectType (Data, ThisElement,
 976                     Type2, (i + Count1 + StartIndex));
 977         if (ACPI_FAILURE (Status))
 978         {
 979             return (Status);
 980         }
 981         ThisElement++;
 982     }
 983 
 984     return (AE_OK);
 985 }
 986 
 987 
 988 /*******************************************************************************
 989  *
 990  * FUNCTION:    AcpiNsCheckObjectType
 991  *
 992  * PARAMETERS:  Data            - Pointer to validation data structure
 993  *              ReturnObjectPtr - Pointer to the object returned from the
 994  *                                evaluation of a method or object
 995  *              ExpectedBtypes  - Bitmap of expected return type(s)
 996  *              PackageIndex    - Index of object within parent package (if
 997  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
 998  *                                otherwise)
 999  *
1000  * RETURN:      Status
1001  *
1002  * DESCRIPTION: Check the type of the return object against the expected object
1003  *              type(s). Use of Btype allows multiple expected object types.
1004  *
1005  ******************************************************************************/
1006 
1007 static ACPI_STATUS
1008 AcpiNsCheckObjectType (
1009     ACPI_PREDEFINED_DATA        *Data,
1010     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
1011     UINT32                      ExpectedBtypes,
1012     UINT32                      PackageIndex)
1013 {
1014     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1015     ACPI_STATUS                 Status = AE_OK;
1016     UINT32                      ReturnBtype;
1017     char                        TypeBuffer[48]; /* Room for 5 types */
1018 
1019 
1020     /*
1021      * If we get a NULL ReturnObject here, it is a NULL package element.
1022      * Since all extraneous NULL package elements were removed earlier by a
1023      * call to AcpiNsRemoveNullElements, this is an unexpected NULL element.
1024      * We will attempt to repair it.
1025      */
1026     if (!ReturnObject)
1027     {
1028         Status = AcpiNsRepairNullElement (Data, ExpectedBtypes,
1029                     PackageIndex, ReturnObjectPtr);
1030         if (ACPI_SUCCESS (Status))
1031         {
1032             return (AE_OK); /* Repair was successful */
1033         }
1034         goto TypeErrorExit;
1035     }
1036 
1037     /* A Namespace node should not get here, but make sure */
1038 
1039     if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
1040     {
1041         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1042             "Invalid return type - Found a Namespace node [%4.4s] type %s",
1043             ReturnObject->Node.Name.Ascii,
1044             AcpiUtGetTypeName (ReturnObject->Node.Type)));
1045         return (AE_AML_OPERAND_TYPE);
1046     }
1047 
1048     /*
1049      * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
1050      * The bitmapped type allows multiple possible return types.
1051      *
1052      * Note, the cases below must handle all of the possible types returned
1053      * from all of the predefined names (including elements of returned
1054      * packages)
1055      */
1056     switch (ReturnObject->Common.Type)
1057     {
1058     case ACPI_TYPE_INTEGER:
1059         ReturnBtype = ACPI_RTYPE_INTEGER;
1060         break;
1061 
1062     case ACPI_TYPE_BUFFER:
1063         ReturnBtype = ACPI_RTYPE_BUFFER;
1064         break;
1065 
1066     case ACPI_TYPE_STRING:
1067         ReturnBtype = ACPI_RTYPE_STRING;
1068         break;
1069 
1070     case ACPI_TYPE_PACKAGE:
1071         ReturnBtype = ACPI_RTYPE_PACKAGE;
1072         break;
1073 
1074     case ACPI_TYPE_LOCAL_REFERENCE:
1075         ReturnBtype = ACPI_RTYPE_REFERENCE;
1076         break;
1077 
1078     default:
1079         /* Not one of the supported objects, must be incorrect */
1080 
1081         goto TypeErrorExit;
1082     }
1083 
1084     /* Is the object one of the expected types? */
1085 
1086     if (ReturnBtype & ExpectedBtypes)
1087     {
1088         /* For reference objects, check that the reference type is correct */
1089 
1090         if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1091         {
1092             Status = AcpiNsCheckReference (Data, ReturnObject);
1093         }
1094 
1095         return (Status);
1096     }
1097 
1098     /* Type mismatch -- attempt repair of the returned object */
1099 
1100     Status = AcpiNsRepairObject (Data, ExpectedBtypes,
1101                 PackageIndex, ReturnObjectPtr);
1102     if (ACPI_SUCCESS (Status))
1103     {
1104         return (AE_OK); /* Repair was successful */
1105     }
1106 
1107 
1108 TypeErrorExit:
1109 
1110     /* Create a string with all expected types for this predefined object */
1111 
1112     AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);
1113 
1114     if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
1115     {
1116         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1117             "Return type mismatch - found %s, expected %s",
1118             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1119     }
1120     else
1121     {
1122         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1123             "Return Package type mismatch at index %u - "
1124             "found %s, expected %s", PackageIndex,
1125             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1126     }
1127 
1128     return (AE_AML_OPERAND_TYPE);
1129 }
1130 
1131 
1132 /*******************************************************************************
1133  *
1134  * FUNCTION:    AcpiNsCheckReference
1135  *
1136  * PARAMETERS:  Data            - Pointer to validation data structure
1137  *              ReturnObject    - Object returned from the evaluation of a
1138  *                                method or object
1139  *
1140  * RETURN:      Status
1141  *
1142  * DESCRIPTION: Check a returned reference object for the correct reference
1143  *              type. The only reference type that can be returned from a
1144  *              predefined method is a named reference. All others are invalid.
1145  *
1146  ******************************************************************************/
1147 
1148 static ACPI_STATUS
1149 AcpiNsCheckReference (
1150     ACPI_PREDEFINED_DATA        *Data,
1151     ACPI_OPERAND_OBJECT         *ReturnObject)
1152 {
1153 
1154     /*
1155      * Check the reference object for the correct reference type (opcode).
1156      * The only type of reference that can be converted to an ACPI_OBJECT is
1157      * a reference to a named object (reference class: NAME)
1158      */
1159     if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1160     {
1161         return (AE_OK);
1162     }
1163 
1164     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1165         "Return type mismatch - unexpected reference object type [%s] %2.2X",
1166         AcpiUtGetReferenceName (ReturnObject),
1167         ReturnObject->Reference.Class));
1168 
1169     return (AE_AML_OPERAND_TYPE);
1170 }
1171 
1172 
1173 /*******************************************************************************
1174  *
1175  * FUNCTION:    AcpiNsGetExpectedTypes
1176  *
1177  * PARAMETERS:  Buffer          - Pointer to where the string is returned
1178  *              ExpectedBtypes  - Bitmap of expected return type(s)
1179  *
1180  * RETURN:      Buffer is populated with type names.
1181  *
1182  * DESCRIPTION: Translate the expected types bitmap into a string of ascii
1183  *              names of expected types, for use in warning messages.
1184  *
1185  ******************************************************************************/
1186 
1187 static void
1188 AcpiNsGetExpectedTypes (
1189     char                        *Buffer,
1190     UINT32                      ExpectedBtypes)
1191 {
1192     UINT32                      ThisRtype;
1193     UINT32                      i;
1194     UINT32                      j;
1195 
1196 
1197     j = 1;
1198     Buffer[0] = 0;
1199     ThisRtype = ACPI_RTYPE_INTEGER;
1200 
1201     for (i = 0; i < ACPI_NUM_RTYPES; i++)
1202     {
1203         /* If one of the expected types, concatenate the name of this type */
1204 
1205         if (ExpectedBtypes & ThisRtype)
1206         {
1207             ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
1208             j = 0;              /* Use name separator from now on */
1209         }
1210         ThisRtype <<= 1;    /* Next Rtype */
1211     }
1212 }