Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:03

0001 /******************************************************************************
0002  *
0003  * Module Name: nsprepkg - Validation of package objects for predefined names
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #include "acpi.h"
0153 #include "accommon.h"
0154 #include "acnamesp.h"
0155 #include "acpredef.h"
0156 
0157 
0158 #define _COMPONENT          ACPI_NAMESPACE
0159         ACPI_MODULE_NAME    ("nsprepkg")
0160 
0161 
0162 /* Local prototypes */
0163 
0164 static ACPI_STATUS
0165 AcpiNsCheckPackageList (
0166     ACPI_EVALUATE_INFO          *Info,
0167     const ACPI_PREDEFINED_INFO  *Package,
0168     ACPI_OPERAND_OBJECT         **Elements,
0169     UINT32                      Count);
0170 
0171 static ACPI_STATUS
0172 AcpiNsCheckPackageElements (
0173     ACPI_EVALUATE_INFO          *Info,
0174     ACPI_OPERAND_OBJECT         **Elements,
0175     UINT8                       Type1,
0176     UINT32                      Count1,
0177     UINT8                       Type2,
0178     UINT32                      Count2,
0179     UINT32                      StartIndex);
0180 
0181 static ACPI_STATUS
0182 AcpiNsCustomPackage (
0183     ACPI_EVALUATE_INFO          *Info,
0184     ACPI_OPERAND_OBJECT         **Elements,
0185     UINT32                      Count);
0186 
0187 
0188 /*******************************************************************************
0189  *
0190  * FUNCTION:    AcpiNsCheckPackage
0191  *
0192  * PARAMETERS:  Info                - Method execution information block
0193  *              ReturnObjectPtr     - Pointer to the object returned from the
0194  *                                    evaluation of a method or object
0195  *
0196  * RETURN:      Status
0197  *
0198  * DESCRIPTION: Check a returned package object for the correct count and
0199  *              correct type of all sub-objects.
0200  *
0201  ******************************************************************************/
0202 
0203 ACPI_STATUS
0204 AcpiNsCheckPackage (
0205     ACPI_EVALUATE_INFO          *Info,
0206     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
0207 {
0208     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
0209     const ACPI_PREDEFINED_INFO  *Package;
0210     ACPI_OPERAND_OBJECT         **Elements;
0211     ACPI_STATUS                 Status = AE_OK;
0212     UINT32                      ExpectedCount;
0213     UINT32                      Count;
0214     UINT32                      i;
0215 
0216 
0217     ACPI_FUNCTION_TRACE (NsCheckPackage);
0218 
0219 
0220     /* The package info for this name is in the next table entry */
0221 
0222     Package = Info->Predefined + 1;
0223 
0224     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
0225         "%s Validating return Package of Type %X, Count %X\n",
0226         Info->FullPathname, Package->RetInfo.Type,
0227         ReturnObject->Package.Count));
0228 
0229     /*
0230      * For variable-length Packages, we can safely remove all embedded
0231      * and trailing NULL package elements
0232      */
0233     AcpiNsRemoveNullElements (Info, Package->RetInfo.Type, ReturnObject);
0234 
0235     /* Extract package count and elements array */
0236 
0237     Elements = ReturnObject->Package.Elements;
0238     Count = ReturnObject->Package.Count;
0239 
0240     /*
0241      * Most packages must have at least one element. The only exception
0242      * is the variable-length package (ACPI_PTYPE1_VAR).
0243      */
0244     if (!Count)
0245     {
0246         if (Package->RetInfo.Type == ACPI_PTYPE1_VAR)
0247         {
0248             return_ACPI_STATUS (AE_OK);
0249         }
0250 
0251         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
0252             "Return Package has no elements (empty)"));
0253 
0254         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
0255     }
0256 
0257     /*
0258      * Decode the type of the expected package contents
0259      *
0260      * PTYPE1 packages contain no subpackages
0261      * PTYPE2 packages contain subpackages
0262      */
0263     switch (Package->RetInfo.Type)
0264     {
0265     case ACPI_PTYPE_CUSTOM:
0266 
0267         Status = AcpiNsCustomPackage (Info, Elements, Count);
0268         break;
0269 
0270     case ACPI_PTYPE1_FIXED:
0271         /*
0272          * The package count is fixed and there are no subpackages
0273          *
0274          * If package is too small, exit.
0275          * If package is larger than expected, issue warning but continue
0276          */
0277         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
0278         if (Count < ExpectedCount)
0279         {
0280             goto PackageTooSmall;
0281         }
0282         else if (Count > ExpectedCount)
0283         {
0284             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
0285                 "%s: Return Package is larger than needed - "
0286                 "found %u, expected %u\n",
0287                 Info->FullPathname, Count, ExpectedCount));
0288         }
0289 
0290         /* Validate all elements of the returned package */
0291 
0292         Status = AcpiNsCheckPackageElements (Info, Elements,
0293             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
0294             Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
0295         break;
0296 
0297     case ACPI_PTYPE1_VAR:
0298         /*
0299          * The package count is variable, there are no subpackages, and all
0300          * elements must be of the same type
0301          */
0302         for (i = 0; i < Count; i++)
0303         {
0304             Status = AcpiNsCheckObjectType (Info, Elements,
0305                 Package->RetInfo.ObjectType1, i);
0306             if (ACPI_FAILURE (Status))
0307             {
0308                 return_ACPI_STATUS (Status);
0309             }
0310 
0311             Elements++;
0312         }
0313         break;
0314 
0315     case ACPI_PTYPE1_OPTION:
0316         /*
0317          * The package count is variable, there are no subpackages. There are
0318          * a fixed number of required elements, and a variable number of
0319          * optional elements.
0320          *
0321          * Check if package is at least as large as the minimum required
0322          */
0323         ExpectedCount = Package->RetInfo3.Count;
0324         if (Count < ExpectedCount)
0325         {
0326             goto PackageTooSmall;
0327         }
0328 
0329         /* Variable number of sub-objects */
0330 
0331         for (i = 0; i < Count; i++)
0332         {
0333             if (i < Package->RetInfo3.Count)
0334             {
0335                 /* These are the required package elements (0, 1, or 2) */
0336 
0337                 Status = AcpiNsCheckObjectType (Info, Elements,
0338                     Package->RetInfo3.ObjectType[i], i);
0339                 if (ACPI_FAILURE (Status))
0340                 {
0341                     return_ACPI_STATUS (Status);
0342                 }
0343             }
0344             else
0345             {
0346                 /* These are the optional package elements */
0347 
0348                 Status = AcpiNsCheckObjectType (Info, Elements,
0349                     Package->RetInfo3.TailObjectType, i);
0350                 if (ACPI_FAILURE (Status))
0351                 {
0352                     return_ACPI_STATUS (Status);
0353                 }
0354             }
0355 
0356             Elements++;
0357         }
0358         break;
0359 
0360     case ACPI_PTYPE2_REV_FIXED:
0361 
0362         /* First element is the (Integer) revision */
0363 
0364         Status = AcpiNsCheckObjectType (
0365             Info, Elements, ACPI_RTYPE_INTEGER, 0);
0366         if (ACPI_FAILURE (Status))
0367         {
0368             return_ACPI_STATUS (Status);
0369         }
0370 
0371         Elements++;
0372         Count--;
0373 
0374         /* Examine the subpackages */
0375 
0376         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
0377         break;
0378 
0379     case ACPI_PTYPE2_PKG_COUNT:
0380 
0381         /* First element is the (Integer) count of subpackages to follow */
0382 
0383         Status = AcpiNsCheckObjectType (
0384             Info, Elements, ACPI_RTYPE_INTEGER, 0);
0385         if (ACPI_FAILURE (Status))
0386         {
0387             return_ACPI_STATUS (Status);
0388         }
0389 
0390         /*
0391          * Count cannot be larger than the parent package length, but allow it
0392          * to be smaller. The >= accounts for the Integer above.
0393          */
0394         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
0395         if (ExpectedCount >= Count)
0396         {
0397             goto PackageTooSmall;
0398         }
0399 
0400         Count = ExpectedCount;
0401         Elements++;
0402 
0403         /* Examine the subpackages */
0404 
0405         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
0406         break;
0407 
0408     case ACPI_PTYPE2:
0409     case ACPI_PTYPE2_FIXED:
0410     case ACPI_PTYPE2_MIN:
0411     case ACPI_PTYPE2_COUNT:
0412     case ACPI_PTYPE2_FIX_VAR:
0413         /*
0414          * These types all return a single Package that consists of a
0415          * variable number of subpackages.
0416          *
0417          * First, ensure that the first element is a subpackage. If not,
0418          * the BIOS may have incorrectly returned the object as a single
0419          * package instead of a Package of Packages (a common error if
0420          * there is only one entry). We may be able to repair this by
0421          * wrapping the returned Package with a new outer Package.
0422          */
0423         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
0424         {
0425             /* Create the new outer package and populate it */
0426 
0427             Status = AcpiNsWrapWithPackage (
0428                 Info, ReturnObject, ReturnObjectPtr);
0429             if (ACPI_FAILURE (Status))
0430             {
0431                 return_ACPI_STATUS (Status);
0432             }
0433 
0434             /* Update locals to point to the new package (of 1 element) */
0435 
0436             ReturnObject = *ReturnObjectPtr;
0437             Elements = ReturnObject->Package.Elements;
0438             Count = 1;
0439         }
0440 
0441         /* Examine the subpackages */
0442 
0443         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
0444         break;
0445 
0446     case ACPI_PTYPE2_VAR_VAR:
0447         /*
0448          * Returns a variable list of packages, each with a variable list
0449          * of objects.
0450          */
0451         break;
0452 
0453     case ACPI_PTYPE2_UUID_PAIR:
0454 
0455         /* The package must contain pairs of (UUID + type) */
0456 
0457         if (Count & 1)
0458         {
0459             ExpectedCount = Count + 1;
0460             goto PackageTooSmall;
0461         }
0462 
0463         while (Count > 0)
0464         {
0465             Status = AcpiNsCheckObjectType(Info, Elements,
0466                 Package->RetInfo.ObjectType1, 0);
0467             if (ACPI_FAILURE(Status))
0468             {
0469                 return_ACPI_STATUS (Status);
0470             }
0471 
0472             /* Validate length of the UUID buffer */
0473 
0474             if ((*Elements)->Buffer.Length != 16)
0475             {
0476                 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
0477                     Info->NodeFlags, "Invalid length for UUID Buffer"));
0478                 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
0479             }
0480 
0481             Status = AcpiNsCheckObjectType(Info, Elements + 1,
0482                 Package->RetInfo.ObjectType2, 0);
0483             if (ACPI_FAILURE(Status))
0484             {
0485                 return_ACPI_STATUS (Status);
0486             }
0487 
0488             Elements += 2;
0489             Count -= 2;
0490         }
0491         break;
0492 
0493     default:
0494 
0495         /* Should not get here if predefined info table is correct */
0496 
0497         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
0498             "Invalid internal return type in table entry: %X",
0499             Package->RetInfo.Type));
0500 
0501         return_ACPI_STATUS (AE_AML_INTERNAL);
0502     }
0503 
0504     return_ACPI_STATUS (Status);
0505 
0506 
0507 PackageTooSmall:
0508 
0509     /* Error exit for the case with an incorrect package count */
0510 
0511     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
0512         "Return Package is too small - found %u elements, expected %u",
0513         Count, ExpectedCount));
0514 
0515     return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
0516 }
0517 
0518 
0519 /*******************************************************************************
0520  *
0521  * FUNCTION:    AcpiNsCheckPackageList
0522  *
0523  * PARAMETERS:  Info            - Method execution information block
0524  *              Package         - Pointer to package-specific info for method
0525  *              Elements        - Element list of parent package. All elements
0526  *                                of this list should be of type Package.
0527  *              Count           - Count of subpackages
0528  *
0529  * RETURN:      Status
0530  *
0531  * DESCRIPTION: Examine a list of subpackages
0532  *
0533  ******************************************************************************/
0534 
0535 static ACPI_STATUS
0536 AcpiNsCheckPackageList (
0537     ACPI_EVALUATE_INFO          *Info,
0538     const ACPI_PREDEFINED_INFO  *Package,
0539     ACPI_OPERAND_OBJECT         **Elements,
0540     UINT32                      Count)
0541 {
0542     ACPI_OPERAND_OBJECT         *SubPackage;
0543     ACPI_OPERAND_OBJECT         **SubElements;
0544     ACPI_STATUS                 Status;
0545     UINT32                      ExpectedCount;
0546     UINT32                      i;
0547     UINT32                      j;
0548 
0549 
0550     /*
0551      * Validate each subpackage in the parent Package
0552      *
0553      * NOTE: assumes list of subpackages contains no NULL elements.
0554      * Any NULL elements should have been removed by earlier call
0555      * to AcpiNsRemoveNullElements.
0556      */
0557     for (i = 0; i < Count; i++)
0558     {
0559         SubPackage = *Elements;
0560         SubElements = SubPackage->Package.Elements;
0561         Info->ParentPackage = SubPackage;
0562 
0563         /* Each sub-object must be of type Package */
0564 
0565         Status = AcpiNsCheckObjectType (Info, &SubPackage,
0566             ACPI_RTYPE_PACKAGE, i);
0567         if (ACPI_FAILURE (Status))
0568         {
0569             return (Status);
0570         }
0571 
0572         /* Examine the different types of expected subpackages */
0573 
0574         Info->ParentPackage = SubPackage;
0575         switch (Package->RetInfo.Type)
0576         {
0577         case ACPI_PTYPE2:
0578         case ACPI_PTYPE2_PKG_COUNT:
0579         case ACPI_PTYPE2_REV_FIXED:
0580 
0581             /* Each subpackage has a fixed number of elements */
0582 
0583             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
0584             if (SubPackage->Package.Count < ExpectedCount)
0585             {
0586                 goto PackageTooSmall;
0587             }
0588 
0589             Status = AcpiNsCheckPackageElements (Info, SubElements,
0590                 Package->RetInfo.ObjectType1,
0591                 Package->RetInfo.Count1,
0592                 Package->RetInfo.ObjectType2,
0593                 Package->RetInfo.Count2, 0);
0594             if (ACPI_FAILURE (Status))
0595             {
0596                 return (Status);
0597             }
0598             break;
0599 
0600         case ACPI_PTYPE2_FIX_VAR:
0601             /*
0602              * Each subpackage has a fixed number of elements and an
0603              * optional element
0604              */
0605             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
0606             if (SubPackage->Package.Count < ExpectedCount)
0607             {
0608                 goto PackageTooSmall;
0609             }
0610 
0611             Status = AcpiNsCheckPackageElements (Info, SubElements,
0612                 Package->RetInfo.ObjectType1,
0613                 Package->RetInfo.Count1,
0614                 Package->RetInfo.ObjectType2,
0615                 SubPackage->Package.Count - Package->RetInfo.Count1, 0);
0616             if (ACPI_FAILURE (Status))
0617             {
0618                 return (Status);
0619             }
0620             break;
0621 
0622         case ACPI_PTYPE2_VAR_VAR:
0623             /*
0624              * Each subpackage has a fixed or variable number of elements
0625              */
0626             break;
0627 
0628         case ACPI_PTYPE2_FIXED:
0629 
0630             /* Each subpackage has a fixed length */
0631 
0632             ExpectedCount = Package->RetInfo2.Count;
0633             if (SubPackage->Package.Count < ExpectedCount)
0634             {
0635                 goto PackageTooSmall;
0636             }
0637 
0638             /* Check the type of each subpackage element */
0639 
0640             for (j = 0; j < ExpectedCount; j++)
0641             {
0642                 Status = AcpiNsCheckObjectType (Info, &SubElements[j],
0643                     Package->RetInfo2.ObjectType[j], j);
0644                 if (ACPI_FAILURE (Status))
0645                 {
0646                     return (Status);
0647                 }
0648             }
0649             break;
0650 
0651         case ACPI_PTYPE2_MIN:
0652 
0653             /* Each subpackage has a variable but minimum length */
0654 
0655             ExpectedCount = Package->RetInfo.Count1;
0656             if (SubPackage->Package.Count < ExpectedCount)
0657             {
0658                 goto PackageTooSmall;
0659             }
0660 
0661             /* Check the type of each subpackage element */
0662 
0663             Status = AcpiNsCheckPackageElements (Info, SubElements,
0664                 Package->RetInfo.ObjectType1,
0665                 SubPackage->Package.Count, 0, 0, 0);
0666             if (ACPI_FAILURE (Status))
0667             {
0668                 return (Status);
0669             }
0670             break;
0671 
0672         case ACPI_PTYPE2_COUNT:
0673             /*
0674              * First element is the (Integer) count of elements, including
0675              * the count field (the ACPI name is NumElements)
0676              */
0677             Status = AcpiNsCheckObjectType (Info, SubElements,
0678                 ACPI_RTYPE_INTEGER, 0);
0679             if (ACPI_FAILURE (Status))
0680             {
0681                 return (Status);
0682             }
0683 
0684             /*
0685              * Make sure package is large enough for the Count and is
0686              * is as large as the minimum size
0687              */
0688             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
0689             if (SubPackage->Package.Count < ExpectedCount)
0690             {
0691                 goto PackageTooSmall;
0692             }
0693 
0694             if (SubPackage->Package.Count < Package->RetInfo.Count1)
0695             {
0696                 ExpectedCount = Package->RetInfo.Count1;
0697                 goto PackageTooSmall;
0698             }
0699 
0700             if (ExpectedCount == 0)
0701             {
0702                 /*
0703                  * Either the NumEntries element was originally zero or it was
0704                  * a NULL element and repaired to an Integer of value zero.
0705                  * In either case, repair it by setting NumEntries to be the
0706                  * actual size of the subpackage.
0707                  */
0708                 ExpectedCount = SubPackage->Package.Count;
0709                 (*SubElements)->Integer.Value = ExpectedCount;
0710             }
0711 
0712             /* Check the type of each subpackage element */
0713 
0714             Status = AcpiNsCheckPackageElements (Info, (SubElements + 1),
0715                 Package->RetInfo.ObjectType1,
0716                 (ExpectedCount - 1), 0, 0, 1);
0717             if (ACPI_FAILURE (Status))
0718             {
0719                 return (Status);
0720             }
0721             break;
0722 
0723         default: /* Should not get here, type was validated by caller */
0724 
0725             ACPI_ERROR ((AE_INFO, "Invalid Package type: %X",
0726                 Package->RetInfo.Type));
0727             return (AE_AML_INTERNAL);
0728         }
0729 
0730         Elements++;
0731     }
0732 
0733     return (AE_OK);
0734 
0735 
0736 PackageTooSmall:
0737 
0738     /* The subpackage count was smaller than required */
0739 
0740     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
0741         "Return SubPackage[%u] is too small - found %u elements, expected %u",
0742         i, SubPackage->Package.Count, ExpectedCount));
0743 
0744     return (AE_AML_OPERAND_VALUE);
0745 }
0746 
0747 
0748 /*******************************************************************************
0749  *
0750  * FUNCTION:    AcpiNsCustomPackage
0751  *
0752  * PARAMETERS:  Info                - Method execution information block
0753  *              Elements            - Pointer to the package elements array
0754  *              Count               - Element count for the package
0755  *
0756  * RETURN:      Status
0757  *
0758  * DESCRIPTION: Check a returned package object for the correct count and
0759  *              correct type of all sub-objects.
0760  *
0761  * NOTE: Currently used for the _BIX method only. When needed for two or more
0762  * methods, probably a detect/dispatch mechanism will be required.
0763  *
0764  ******************************************************************************/
0765 
0766 static ACPI_STATUS
0767 AcpiNsCustomPackage (
0768     ACPI_EVALUATE_INFO          *Info,
0769     ACPI_OPERAND_OBJECT         **Elements,
0770     UINT32                      Count)
0771 {
0772     UINT32                      ExpectedCount;
0773     UINT32                      Version;
0774     ACPI_STATUS                 Status = AE_OK;
0775 
0776 
0777     ACPI_FUNCTION_NAME (NsCustomPackage);
0778 
0779 
0780     /* Get version number, must be Integer */
0781 
0782     if ((*Elements)->Common.Type != ACPI_TYPE_INTEGER)
0783     {
0784         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
0785             "Return Package has invalid object type for version number"));
0786         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
0787     }
0788 
0789     Version = (UINT32) (*Elements)->Integer.Value;
0790     ExpectedCount = 21;         /* Version 1 */
0791 
0792     if (Version == 0)
0793     {
0794         ExpectedCount = 20;     /* Version 0 */
0795     }
0796 
0797     if (Count < ExpectedCount)
0798     {
0799         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
0800             "Return Package is too small - found %u elements, expected %u",
0801             Count, ExpectedCount));
0802         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
0803     }
0804     else if (Count > ExpectedCount)
0805     {
0806         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
0807             "%s: Return Package is larger than needed - "
0808             "found %u, expected %u\n",
0809             Info->FullPathname, Count, ExpectedCount));
0810     }
0811 
0812     /* Validate all elements of the returned package */
0813 
0814     Status = AcpiNsCheckPackageElements (Info, Elements,
0815         ACPI_RTYPE_INTEGER, 16,
0816         ACPI_RTYPE_STRING, 4, 0);
0817     if (ACPI_FAILURE (Status))
0818     {
0819         return_ACPI_STATUS (Status);
0820     }
0821 
0822     /* Version 1 has a single trailing integer */
0823 
0824     if (Version > 0)
0825     {
0826         Status = AcpiNsCheckPackageElements (Info, Elements + 20,
0827             ACPI_RTYPE_INTEGER, 1, 0, 0, 20);
0828     }
0829 
0830     return_ACPI_STATUS (Status);
0831 }
0832 
0833 
0834 /*******************************************************************************
0835  *
0836  * FUNCTION:    AcpiNsCheckPackageElements
0837  *
0838  * PARAMETERS:  Info            - Method execution information block
0839  *              Elements        - Pointer to the package elements array
0840  *              Type1           - Object type for first group
0841  *              Count1          - Count for first group
0842  *              Type2           - Object type for second group
0843  *              Count2          - Count for second group
0844  *              StartIndex      - Start of the first group of elements
0845  *
0846  * RETURN:      Status
0847  *
0848  * DESCRIPTION: Check that all elements of a package are of the correct object
0849  *              type. Supports up to two groups of different object types.
0850  *
0851  ******************************************************************************/
0852 
0853 static ACPI_STATUS
0854 AcpiNsCheckPackageElements (
0855     ACPI_EVALUATE_INFO          *Info,
0856     ACPI_OPERAND_OBJECT         **Elements,
0857     UINT8                       Type1,
0858     UINT32                      Count1,
0859     UINT8                       Type2,
0860     UINT32                      Count2,
0861     UINT32                      StartIndex)
0862 {
0863     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
0864     ACPI_STATUS                 Status;
0865     UINT32                      i;
0866 
0867 
0868     ACPI_FUNCTION_TRACE (NsCheckPackageElements);
0869 
0870     /*
0871      * Up to two groups of package elements are supported by the data
0872      * structure. All elements in each group must be of the same type.
0873      * The second group can have a count of zero.
0874      */
0875     for (i = 0; i < Count1; i++)
0876     {
0877         Status = AcpiNsCheckObjectType (Info, ThisElement,
0878             Type1, i + StartIndex);
0879         if (ACPI_FAILURE (Status))
0880         {
0881             return_ACPI_STATUS (Status);
0882         }
0883 
0884         ThisElement++;
0885     }
0886 
0887     for (i = 0; i < Count2; i++)
0888     {
0889         Status = AcpiNsCheckObjectType (Info, ThisElement,
0890             Type2, (i + Count1 + StartIndex));
0891         if (ACPI_FAILURE (Status))
0892         {
0893             return_ACPI_STATUS (Status);
0894         }
0895 
0896         ThisElement++;
0897     }
0898 
0899     return_ACPI_STATUS (AE_OK);
0900 }