Home | History | Annotate | Line # | Download | only in namespace
nsprepkg.c revision 1.1.1.8
      1 /******************************************************************************
      2  *
      3  * Module Name: nsprepkg - Validation of package objects for predefined names
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2017, 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.h"
     45 #include "accommon.h"
     46 #include "acnamesp.h"
     47 #include "acpredef.h"
     48 
     49 
     50 #define _COMPONENT          ACPI_NAMESPACE
     51         ACPI_MODULE_NAME    ("nsprepkg")
     52 
     53 
     54 /* Local prototypes */
     55 
     56 static ACPI_STATUS
     57 AcpiNsCheckPackageList (
     58     ACPI_EVALUATE_INFO          *Info,
     59     const ACPI_PREDEFINED_INFO  *Package,
     60     ACPI_OPERAND_OBJECT         **Elements,
     61     UINT32                      Count);
     62 
     63 static ACPI_STATUS
     64 AcpiNsCheckPackageElements (
     65     ACPI_EVALUATE_INFO          *Info,
     66     ACPI_OPERAND_OBJECT         **Elements,
     67     UINT8                       Type1,
     68     UINT32                      Count1,
     69     UINT8                       Type2,
     70     UINT32                      Count2,
     71     UINT32                      StartIndex);
     72 
     73 static ACPI_STATUS
     74 AcpiNsCustomPackage (
     75     ACPI_EVALUATE_INFO          *Info,
     76     ACPI_OPERAND_OBJECT         **Elements,
     77     UINT32                      Count);
     78 
     79 
     80 /*******************************************************************************
     81  *
     82  * FUNCTION:    AcpiNsCheckPackage
     83  *
     84  * PARAMETERS:  Info                - Method execution information block
     85  *              ReturnObjectPtr     - Pointer to the object returned from the
     86  *                                    evaluation of a method or object
     87  *
     88  * RETURN:      Status
     89  *
     90  * DESCRIPTION: Check a returned package object for the correct count and
     91  *              correct type of all sub-objects.
     92  *
     93  ******************************************************************************/
     94 
     95 ACPI_STATUS
     96 AcpiNsCheckPackage (
     97     ACPI_EVALUATE_INFO          *Info,
     98     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
     99 {
    100     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
    101     const ACPI_PREDEFINED_INFO  *Package;
    102     ACPI_OPERAND_OBJECT         **Elements;
    103     ACPI_STATUS                 Status = AE_OK;
    104     UINT32                      ExpectedCount;
    105     UINT32                      Count;
    106     UINT32                      i;
    107 
    108 
    109     ACPI_FUNCTION_NAME (NsCheckPackage);
    110 
    111 
    112     /* The package info for this name is in the next table entry */
    113 
    114     Package = Info->Predefined + 1;
    115 
    116     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
    117         "%s Validating return Package of Type %X, Count %X\n",
    118         Info->FullPathname, Package->RetInfo.Type,
    119         ReturnObject->Package.Count));
    120 
    121     /*
    122      * For variable-length Packages, we can safely remove all embedded
    123      * and trailing NULL package elements
    124      */
    125     AcpiNsRemoveNullElements (Info, Package->RetInfo.Type, ReturnObject);
    126 
    127     /* Extract package count and elements array */
    128 
    129     Elements = ReturnObject->Package.Elements;
    130     Count = ReturnObject->Package.Count;
    131 
    132     /*
    133      * Most packages must have at least one element. The only exception
    134      * is the variable-length package (ACPI_PTYPE1_VAR).
    135      */
    136     if (!Count)
    137     {
    138         if (Package->RetInfo.Type == ACPI_PTYPE1_VAR)
    139         {
    140             return (AE_OK);
    141         }
    142 
    143         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
    144             "Return Package has no elements (empty)"));
    145 
    146         return (AE_AML_OPERAND_VALUE);
    147     }
    148 
    149     /*
    150      * Decode the type of the expected package contents
    151      *
    152      * PTYPE1 packages contain no subpackages
    153      * PTYPE2 packages contain subpackages
    154      */
    155     switch (Package->RetInfo.Type)
    156     {
    157     case ACPI_PTYPE_CUSTOM:
    158 
    159         Status = AcpiNsCustomPackage (Info, Elements, Count);
    160         break;
    161 
    162     case ACPI_PTYPE1_FIXED:
    163         /*
    164          * The package count is fixed and there are no subpackages
    165          *
    166          * If package is too small, exit.
    167          * If package is larger than expected, issue warning but continue
    168          */
    169         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
    170         if (Count < ExpectedCount)
    171         {
    172             goto PackageTooSmall;
    173         }
    174         else if (Count > ExpectedCount)
    175         {
    176             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
    177                 "%s: Return Package is larger than needed - "
    178                 "found %u, expected %u\n",
    179                 Info->FullPathname, Count, ExpectedCount));
    180         }
    181 
    182         /* Validate all elements of the returned package */
    183 
    184         Status = AcpiNsCheckPackageElements (Info, Elements,
    185             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
    186             Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
    187         break;
    188 
    189     case ACPI_PTYPE1_VAR:
    190         /*
    191          * The package count is variable, there are no subpackages, and all
    192          * elements must be of the same type
    193          */
    194         for (i = 0; i < Count; i++)
    195         {
    196             Status = AcpiNsCheckObjectType (Info, Elements,
    197                 Package->RetInfo.ObjectType1, i);
    198             if (ACPI_FAILURE (Status))
    199             {
    200                 return (Status);
    201             }
    202 
    203             Elements++;
    204         }
    205         break;
    206 
    207     case ACPI_PTYPE1_OPTION:
    208         /*
    209          * The package count is variable, there are no subpackages. There are
    210          * a fixed number of required elements, and a variable number of
    211          * optional elements.
    212          *
    213          * Check if package is at least as large as the minimum required
    214          */
    215         ExpectedCount = Package->RetInfo3.Count;
    216         if (Count < ExpectedCount)
    217         {
    218             goto PackageTooSmall;
    219         }
    220 
    221         /* Variable number of sub-objects */
    222 
    223         for (i = 0; i < Count; i++)
    224         {
    225             if (i < Package->RetInfo3.Count)
    226             {
    227                 /* These are the required package elements (0, 1, or 2) */
    228 
    229                 Status = AcpiNsCheckObjectType (Info, Elements,
    230                     Package->RetInfo3.ObjectType[i], i);
    231                 if (ACPI_FAILURE (Status))
    232                 {
    233                     return (Status);
    234                 }
    235             }
    236             else
    237             {
    238                 /* These are the optional package elements */
    239 
    240                 Status = AcpiNsCheckObjectType (Info, Elements,
    241                     Package->RetInfo3.TailObjectType, i);
    242                 if (ACPI_FAILURE (Status))
    243                 {
    244                     return (Status);
    245                 }
    246             }
    247 
    248             Elements++;
    249         }
    250         break;
    251 
    252     case ACPI_PTYPE2_REV_FIXED:
    253 
    254         /* First element is the (Integer) revision */
    255 
    256         Status = AcpiNsCheckObjectType (
    257             Info, Elements, ACPI_RTYPE_INTEGER, 0);
    258         if (ACPI_FAILURE (Status))
    259         {
    260             return (Status);
    261         }
    262 
    263         Elements++;
    264         Count--;
    265 
    266         /* Examine the subpackages */
    267 
    268         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
    269         break;
    270 
    271     case ACPI_PTYPE2_PKG_COUNT:
    272 
    273         /* First element is the (Integer) count of subpackages to follow */
    274 
    275         Status = AcpiNsCheckObjectType (
    276             Info, Elements, ACPI_RTYPE_INTEGER, 0);
    277         if (ACPI_FAILURE (Status))
    278         {
    279             return (Status);
    280         }
    281 
    282         /*
    283          * Count cannot be larger than the parent package length, but allow it
    284          * to be smaller. The >= accounts for the Integer above.
    285          */
    286         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
    287         if (ExpectedCount >= Count)
    288         {
    289             goto PackageTooSmall;
    290         }
    291 
    292         Count = ExpectedCount;
    293         Elements++;
    294 
    295         /* Examine the subpackages */
    296 
    297         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
    298         break;
    299 
    300     case ACPI_PTYPE2:
    301     case ACPI_PTYPE2_FIXED:
    302     case ACPI_PTYPE2_MIN:
    303     case ACPI_PTYPE2_COUNT:
    304     case ACPI_PTYPE2_FIX_VAR:
    305         /*
    306          * These types all return a single Package that consists of a
    307          * variable number of subpackages.
    308          *
    309          * First, ensure that the first element is a subpackage. If not,
    310          * the BIOS may have incorrectly returned the object as a single
    311          * package instead of a Package of Packages (a common error if
    312          * there is only one entry). We may be able to repair this by
    313          * wrapping the returned Package with a new outer Package.
    314          */
    315         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
    316         {
    317             /* Create the new outer package and populate it */
    318 
    319             Status = AcpiNsWrapWithPackage (
    320                 Info, ReturnObject, ReturnObjectPtr);
    321             if (ACPI_FAILURE (Status))
    322             {
    323                 return (Status);
    324             }
    325 
    326             /* Update locals to point to the new package (of 1 element) */
    327 
    328             ReturnObject = *ReturnObjectPtr;
    329             Elements = ReturnObject->Package.Elements;
    330             Count = 1;
    331         }
    332 
    333         /* Examine the subpackages */
    334 
    335         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
    336         break;
    337 
    338     case ACPI_PTYPE2_VAR_VAR:
    339         /*
    340          * Returns a variable list of packages, each with a variable list
    341          * of objects.
    342          */
    343         break;
    344 
    345     case ACPI_PTYPE2_UUID_PAIR:
    346 
    347         /* The package must contain pairs of (UUID + type) */
    348 
    349         if (Count & 1)
    350         {
    351             ExpectedCount = Count + 1;
    352             goto PackageTooSmall;
    353         }
    354 
    355         while (Count > 0)
    356         {
    357             Status = AcpiNsCheckObjectType(Info, Elements,
    358                 Package->RetInfo.ObjectType1, 0);
    359             if (ACPI_FAILURE(Status))
    360             {
    361                 return (Status);
    362             }
    363 
    364             /* Validate length of the UUID buffer */
    365 
    366             if ((*Elements)->Buffer.Length != 16)
    367             {
    368                 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
    369                     Info->NodeFlags, "Invalid length for UUID Buffer"));
    370                 return (AE_AML_OPERAND_VALUE);
    371             }
    372 
    373             Status = AcpiNsCheckObjectType(Info, Elements + 1,
    374                 Package->RetInfo.ObjectType2, 0);
    375             if (ACPI_FAILURE(Status))
    376             {
    377                 return (Status);
    378             }
    379 
    380             Elements += 2;
    381             Count -= 2;
    382         }
    383         break;
    384 
    385     default:
    386 
    387         /* Should not get here if predefined info table is correct */
    388 
    389         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
    390             "Invalid internal return type in table entry: %X",
    391             Package->RetInfo.Type));
    392 
    393         return (AE_AML_INTERNAL);
    394     }
    395 
    396     return (Status);
    397 
    398 
    399 PackageTooSmall:
    400 
    401     /* Error exit for the case with an incorrect package count */
    402 
    403     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
    404         "Return Package is too small - found %u elements, expected %u",
    405         Count, ExpectedCount));
    406 
    407     return (AE_AML_OPERAND_VALUE);
    408 }
    409 
    410 
    411 /*******************************************************************************
    412  *
    413  * FUNCTION:    AcpiNsCheckPackageList
    414  *
    415  * PARAMETERS:  Info            - Method execution information block
    416  *              Package         - Pointer to package-specific info for method
    417  *              Elements        - Element list of parent package. All elements
    418  *                                of this list should be of type Package.
    419  *              Count           - Count of subpackages
    420  *
    421  * RETURN:      Status
    422  *
    423  * DESCRIPTION: Examine a list of subpackages
    424  *
    425  ******************************************************************************/
    426 
    427 static ACPI_STATUS
    428 AcpiNsCheckPackageList (
    429     ACPI_EVALUATE_INFO          *Info,
    430     const ACPI_PREDEFINED_INFO  *Package,
    431     ACPI_OPERAND_OBJECT         **Elements,
    432     UINT32                      Count)
    433 {
    434     ACPI_OPERAND_OBJECT         *SubPackage;
    435     ACPI_OPERAND_OBJECT         **SubElements;
    436     ACPI_STATUS                 Status;
    437     UINT32                      ExpectedCount;
    438     UINT32                      i;
    439     UINT32                      j;
    440 
    441 
    442     /*
    443      * Validate each subpackage in the parent Package
    444      *
    445      * NOTE: assumes list of subpackages contains no NULL elements.
    446      * Any NULL elements should have been removed by earlier call
    447      * to AcpiNsRemoveNullElements.
    448      */
    449     for (i = 0; i < Count; i++)
    450     {
    451         SubPackage = *Elements;
    452         SubElements = SubPackage->Package.Elements;
    453         Info->ParentPackage = SubPackage;
    454 
    455         /* Each sub-object must be of type Package */
    456 
    457         Status = AcpiNsCheckObjectType (Info, &SubPackage,
    458             ACPI_RTYPE_PACKAGE, i);
    459         if (ACPI_FAILURE (Status))
    460         {
    461             return (Status);
    462         }
    463 
    464         /* Examine the different types of expected subpackages */
    465 
    466         Info->ParentPackage = SubPackage;
    467         switch (Package->RetInfo.Type)
    468         {
    469         case ACPI_PTYPE2:
    470         case ACPI_PTYPE2_PKG_COUNT:
    471         case ACPI_PTYPE2_REV_FIXED:
    472 
    473             /* Each subpackage has a fixed number of elements */
    474 
    475             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
    476             if (SubPackage->Package.Count < ExpectedCount)
    477             {
    478                 goto PackageTooSmall;
    479             }
    480 
    481             Status = AcpiNsCheckPackageElements (Info, SubElements,
    482                 Package->RetInfo.ObjectType1,
    483                 Package->RetInfo.Count1,
    484                 Package->RetInfo.ObjectType2,
    485                 Package->RetInfo.Count2, 0);
    486             if (ACPI_FAILURE (Status))
    487             {
    488                 return (Status);
    489             }
    490             break;
    491 
    492         case ACPI_PTYPE2_FIX_VAR:
    493             /*
    494              * Each subpackage has a fixed number of elements and an
    495              * optional element
    496              */
    497             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
    498             if (SubPackage->Package.Count < ExpectedCount)
    499             {
    500                 goto PackageTooSmall;
    501             }
    502 
    503             Status = AcpiNsCheckPackageElements (Info, SubElements,
    504                 Package->RetInfo.ObjectType1,
    505                 Package->RetInfo.Count1,
    506                 Package->RetInfo.ObjectType2,
    507                 SubPackage->Package.Count - Package->RetInfo.Count1, 0);
    508             if (ACPI_FAILURE (Status))
    509             {
    510                 return (Status);
    511             }
    512             break;
    513 
    514         case ACPI_PTYPE2_VAR_VAR:
    515             /*
    516              * Each subpackage has a fixed or variable number of elements
    517              */
    518             break;
    519 
    520         case ACPI_PTYPE2_FIXED:
    521 
    522             /* Each subpackage has a fixed length */
    523 
    524             ExpectedCount = Package->RetInfo2.Count;
    525             if (SubPackage->Package.Count < ExpectedCount)
    526             {
    527                 goto PackageTooSmall;
    528             }
    529 
    530             /* Check the type of each subpackage element */
    531 
    532             for (j = 0; j < ExpectedCount; j++)
    533             {
    534                 Status = AcpiNsCheckObjectType (Info, &SubElements[j],
    535                     Package->RetInfo2.ObjectType[j], j);
    536                 if (ACPI_FAILURE (Status))
    537                 {
    538                     return (Status);
    539                 }
    540             }
    541             break;
    542 
    543         case ACPI_PTYPE2_MIN:
    544 
    545             /* Each subpackage has a variable but minimum length */
    546 
    547             ExpectedCount = Package->RetInfo.Count1;
    548             if (SubPackage->Package.Count < ExpectedCount)
    549             {
    550                 goto PackageTooSmall;
    551             }
    552 
    553             /* Check the type of each subpackage element */
    554 
    555             Status = AcpiNsCheckPackageElements (Info, SubElements,
    556                 Package->RetInfo.ObjectType1,
    557                 SubPackage->Package.Count, 0, 0, 0);
    558             if (ACPI_FAILURE (Status))
    559             {
    560                 return (Status);
    561             }
    562             break;
    563 
    564         case ACPI_PTYPE2_COUNT:
    565             /*
    566              * First element is the (Integer) count of elements, including
    567              * the count field (the ACPI name is NumElements)
    568              */
    569             Status = AcpiNsCheckObjectType (Info, SubElements,
    570                 ACPI_RTYPE_INTEGER, 0);
    571             if (ACPI_FAILURE (Status))
    572             {
    573                 return (Status);
    574             }
    575 
    576             /*
    577              * Make sure package is large enough for the Count and is
    578              * is as large as the minimum size
    579              */
    580             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
    581             if (SubPackage->Package.Count < ExpectedCount)
    582             {
    583                 goto PackageTooSmall;
    584             }
    585 
    586             if (SubPackage->Package.Count < Package->RetInfo.Count1)
    587             {
    588                 ExpectedCount = Package->RetInfo.Count1;
    589                 goto PackageTooSmall;
    590             }
    591 
    592             if (ExpectedCount == 0)
    593             {
    594                 /*
    595                  * Either the NumEntries element was originally zero or it was
    596                  * a NULL element and repaired to an Integer of value zero.
    597                  * In either case, repair it by setting NumEntries to be the
    598                  * actual size of the subpackage.
    599                  */
    600                 ExpectedCount = SubPackage->Package.Count;
    601                 (*SubElements)->Integer.Value = ExpectedCount;
    602             }
    603 
    604             /* Check the type of each subpackage element */
    605 
    606             Status = AcpiNsCheckPackageElements (Info, (SubElements + 1),
    607                 Package->RetInfo.ObjectType1,
    608                 (ExpectedCount - 1), 0, 0, 1);
    609             if (ACPI_FAILURE (Status))
    610             {
    611                 return (Status);
    612             }
    613             break;
    614 
    615         default: /* Should not get here, type was validated by caller */
    616 
    617             ACPI_ERROR ((AE_INFO, "Invalid Package type: %X",
    618                 Package->RetInfo.Type));
    619             return (AE_AML_INTERNAL);
    620         }
    621 
    622         Elements++;
    623     }
    624 
    625     return (AE_OK);
    626 
    627 
    628 PackageTooSmall:
    629 
    630     /* The subpackage count was smaller than required */
    631 
    632     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
    633         "Return SubPackage[%u] is too small - found %u elements, expected %u",
    634         i, SubPackage->Package.Count, ExpectedCount));
    635 
    636     return (AE_AML_OPERAND_VALUE);
    637 }
    638 
    639 
    640 /*******************************************************************************
    641  *
    642  * FUNCTION:    AcpiNsCustomPackage
    643  *
    644  * PARAMETERS:  Info                - Method execution information block
    645  *              Elements            - Pointer to the package elements array
    646  *              Count               - Element count for the package
    647  *
    648  * RETURN:      Status
    649  *
    650  * DESCRIPTION: Check a returned package object for the correct count and
    651  *              correct type of all sub-objects.
    652  *
    653  * NOTE: Currently used for the _BIX method only. When needed for two or more
    654  * methods, probably a detect/dispatch mechanism will be required.
    655  *
    656  ******************************************************************************/
    657 
    658 static ACPI_STATUS
    659 AcpiNsCustomPackage (
    660     ACPI_EVALUATE_INFO          *Info,
    661     ACPI_OPERAND_OBJECT         **Elements,
    662     UINT32                      Count)
    663 {
    664     UINT32                      ExpectedCount;
    665     UINT32                      Version;
    666     ACPI_STATUS                 Status = AE_OK;
    667 
    668 
    669     ACPI_FUNCTION_NAME (NsCustomPackage);
    670 
    671 
    672     /* Get version number, must be Integer */
    673 
    674     if ((*Elements)->Common.Type != ACPI_TYPE_INTEGER)
    675     {
    676         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
    677             "Return Package has invalid object type for version number"));
    678         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    679     }
    680 
    681     Version = (UINT32) (*Elements)->Integer.Value;
    682     ExpectedCount = 21;         /* Version 1 */
    683 
    684     if (Version == 0)
    685     {
    686         ExpectedCount = 20;     /* Version 0 */
    687     }
    688 
    689     if (Count < ExpectedCount)
    690     {
    691         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
    692             "Return Package is too small - found %u elements, expected %u",
    693             Count, ExpectedCount));
    694         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
    695     }
    696     else if (Count > ExpectedCount)
    697     {
    698         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
    699             "%s: Return Package is larger than needed - "
    700             "found %u, expected %u\n",
    701             Info->FullPathname, Count, ExpectedCount));
    702     }
    703 
    704     /* Validate all elements of the returned package */
    705 
    706     Status = AcpiNsCheckPackageElements (Info, Elements,
    707         ACPI_RTYPE_INTEGER, 16,
    708         ACPI_RTYPE_STRING, 4, 0);
    709     if (ACPI_FAILURE (Status))
    710     {
    711         return_ACPI_STATUS (Status);
    712     }
    713 
    714     /* Version 1 has a single trailing integer */
    715 
    716     if (Version > 0)
    717     {
    718         Status = AcpiNsCheckPackageElements (Info, Elements + 20,
    719             ACPI_RTYPE_INTEGER, 1, 0, 0, 20);
    720     }
    721 
    722     return_ACPI_STATUS (Status);
    723 }
    724 
    725 
    726 /*******************************************************************************
    727  *
    728  * FUNCTION:    AcpiNsCheckPackageElements
    729  *
    730  * PARAMETERS:  Info            - Method execution information block
    731  *              Elements        - Pointer to the package elements array
    732  *              Type1           - Object type for first group
    733  *              Count1          - Count for first group
    734  *              Type2           - Object type for second group
    735  *              Count2          - Count for second group
    736  *              StartIndex      - Start of the first group of elements
    737  *
    738  * RETURN:      Status
    739  *
    740  * DESCRIPTION: Check that all elements of a package are of the correct object
    741  *              type. Supports up to two groups of different object types.
    742  *
    743  ******************************************************************************/
    744 
    745 static ACPI_STATUS
    746 AcpiNsCheckPackageElements (
    747     ACPI_EVALUATE_INFO          *Info,
    748     ACPI_OPERAND_OBJECT         **Elements,
    749     UINT8                       Type1,
    750     UINT32                      Count1,
    751     UINT8                       Type2,
    752     UINT32                      Count2,
    753     UINT32                      StartIndex)
    754 {
    755     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
    756     ACPI_STATUS                 Status;
    757     UINT32                      i;
    758 
    759 
    760     /*
    761      * Up to two groups of package elements are supported by the data
    762      * structure. All elements in each group must be of the same type.
    763      * The second group can have a count of zero.
    764      */
    765     for (i = 0; i < Count1; i++)
    766     {
    767         Status = AcpiNsCheckObjectType (Info, ThisElement,
    768             Type1, i + StartIndex);
    769         if (ACPI_FAILURE (Status))
    770         {
    771             return (Status);
    772         }
    773 
    774         ThisElement++;
    775     }
    776 
    777     for (i = 0; i < Count2; i++)
    778     {
    779         Status = AcpiNsCheckObjectType (Info, ThisElement,
    780             Type2, (i + Count1 + StartIndex));
    781         if (ACPI_FAILURE (Status))
    782         {
    783             return (Status);
    784         }
    785 
    786         ThisElement++;
    787     }
    788 
    789     return (AE_OK);
    790 }
    791