Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/acpica/nspredef.c need to be fixed.

0001 /******************************************************************************
0002  *
0003  * Module Name: nspredef - Validation of ACPI predefined methods and objects
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2009, 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 #define __NSPREDEF_C__
0117 
0118 #include "acpi.h"
0119 #include "accommon.h"
0120 #include "acnamesp.h"
0121 #include "acpredef.h"
0122 
0123 
0124 #define _COMPONENT          ACPI_NAMESPACE
0125         ACPI_MODULE_NAME    ("nspredef")
0126 
0127 
0128 /*******************************************************************************
0129  *
0130  * This module validates predefined ACPI objects that appear in the namespace,
0131  * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
0132  * validation is to detect problems with BIOS-exposed predefined ACPI objects
0133  * before the results are returned to the ACPI-related drivers.
0134  *
0135  * There are several areas that are validated:
0136  *
0137  *  1) The number of input arguments as defined by the method/object in the
0138  *      ASL is validated against the ACPI specification.
0139  *  2) The type of the return object (if any) is validated against the ACPI
0140  *      specification.
0141  *  3) For returned package objects, the count of package elements is
0142  *      validated, as well as the type of each package element. Nested
0143  *      packages are supported.
0144  *
0145  * For any problems found, a warning message is issued.
0146  *
0147  ******************************************************************************/
0148 
0149 
0150 /* Local prototypes */
0151 
0152 static ACPI_STATUS
0153 AcpiNsCheckPackage (
0154     ACPI_PREDEFINED_DATA        *Data,
0155     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
0156 
0157 static ACPI_STATUS
0158 AcpiNsCheckPackageElements (
0159     ACPI_PREDEFINED_DATA        *Data,
0160     ACPI_OPERAND_OBJECT         **Elements,
0161     UINT8                       Type1,
0162     UINT32                      Count1,
0163     UINT8                       Type2,
0164     UINT32                      Count2,
0165     UINT32                      StartIndex);
0166 
0167 static ACPI_STATUS
0168 AcpiNsCheckObjectType (
0169     ACPI_PREDEFINED_DATA        *Data,
0170     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
0171     UINT32                      ExpectedBtypes,
0172     UINT32                      PackageIndex);
0173 
0174 static ACPI_STATUS
0175 AcpiNsCheckReference (
0176     ACPI_PREDEFINED_DATA        *Data,
0177     ACPI_OPERAND_OBJECT         *ReturnObject);
0178 
0179 static ACPI_STATUS
0180 AcpiNsRepairObject (
0181     ACPI_PREDEFINED_DATA        *Data,
0182     UINT32                      ExpectedBtypes,
0183     UINT32                      PackageIndex,
0184     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
0185 
0186 static void
0187 AcpiNsGetExpectedTypes (
0188     char                        *Buffer,
0189     UINT32                      ExpectedBtypes);
0190 
0191 /*
0192  * Names for the types that can be returned by the predefined objects.
0193  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
0194  */
0195 static const char   *AcpiRtypeNames[] =
0196 {
0197     "/Integer",
0198     "/String",
0199     "/Buffer",
0200     "/Package",
0201     "/Reference",
0202 };
0203 
0204 /* Object is not a package element */
0205 
0206 #define ACPI_NOT_PACKAGE_ELEMENT    ACPI_UINT32_MAX
0207 
0208 /* Always emit warning message, not dependent on node flags */
0209 
0210 #define ACPI_WARN_ALWAYS            0
0211 
0212 
0213 /*******************************************************************************
0214  *
0215  * FUNCTION:    AcpiNsCheckPredefinedNames
0216  *
0217  * PARAMETERS:  Node            - Namespace node for the method/object
0218  *              UserParamCount  - Number of parameters actually passed
0219  *              ReturnStatus    - Status from the object evaluation
0220  *              ReturnObjectPtr - Pointer to the object returned from the
0221  *                                evaluation of a method or object
0222  *
0223  * RETURN:      Status
0224  *
0225  * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
0226  *
0227  ******************************************************************************/
0228 
0229 ACPI_STATUS
0230 AcpiNsCheckPredefinedNames (
0231     ACPI_NAMESPACE_NODE         *Node,
0232     UINT32                      UserParamCount,
0233     ACPI_STATUS                 ReturnStatus,
0234     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
0235 {
0236     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
0237     ACPI_STATUS                 Status = AE_OK;
0238     const ACPI_PREDEFINED_INFO  *Predefined;
0239     char                        *Pathname;
0240     ACPI_PREDEFINED_DATA        *Data;
0241 
0242 
0243     /* Match the name for this method/object against the predefined list */
0244 
0245     Predefined = AcpiNsCheckForPredefinedName (Node);
0246 
0247     /* Get the full pathname to the object, for use in warning messages */
0248 
0249     Pathname = AcpiNsGetExternalPathname (Node);
0250     if (!Pathname)
0251     {
0252         return (AE_OK); /* Could not get pathname, ignore */
0253     }
0254 
0255     /*
0256      * Check that the parameter count for this method matches the ASL
0257      * definition. For predefined names, ensure that both the caller and
0258      * the method itself are in accordance with the ACPI specification.
0259      */
0260     AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
0261 
0262     /* If not a predefined name, we cannot validate the return object */
0263 
0264     if (!Predefined)
0265     {
0266         goto Cleanup;
0267     }
0268 
0269     /*
0270      * If the method failed or did not actually return an object, we cannot
0271      * validate the return object
0272      */
0273     if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
0274     {
0275         goto Cleanup;
0276     }
0277 
0278     /*
0279      * If there is no return value, check if we require a return value for
0280      * this predefined name. Either one return value is expected, or none,
0281      * for both methods and other objects.
0282      *
0283      * Exit now if there is no return object. Warning if one was expected.
0284      */
0285     if (!ReturnObject)
0286     {
0287         if ((Predefined->Info.ExpectedBtypes) &&
0288             (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
0289         {
0290             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
0291                 "Missing expected return value"));
0292 
0293             Status = AE_AML_NO_RETURN_VALUE;
0294         }
0295         goto Cleanup;
0296     }
0297 
0298     /*
0299      * We have a return value, but if one wasn't expected, just exit, this is
0300      * not a problem. For example, if the "Implicit Return" feature is
0301      * enabled, methods will always return a value.
0302      */
0303     if (!Predefined->Info.ExpectedBtypes)
0304     {
0305         goto Cleanup;
0306     }
0307 
0308     /* Create the parameter data block for object validation */
0309 
0310     Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA));
0311     if (!Data)
0312     {
0313         goto Cleanup;
0314     }
0315     Data->Predefined = Predefined;
0316     Data->NodeFlags = Node->Flags;
0317     Data->Pathname = Pathname;
0318 
0319     /*
0320      * Check that the type of the return object is what is expected for
0321      * this predefined name
0322      */
0323     Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
0324                 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
0325     if (ACPI_FAILURE (Status))
0326     {
0327         goto CheckValidationStatus;
0328     }
0329 
0330     /* For returned Package objects, check the type of all sub-objects */
0331 
0332     if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE)
0333     {
0334         Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
0335     }
0336 
0337 
0338 CheckValidationStatus:
0339     /*
0340      * If the object validation failed or if we successfully repaired one
0341      * or more objects, mark the parent node to suppress further warning
0342      * messages during the next evaluation of the same method/object.
0343      */
0344     if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED))
0345     {
0346         Node->Flags |= ANOBJ_EVALUATED;
0347     }
0348     ACPI_FREE (Data);
0349 
0350 
0351 Cleanup:
0352     ACPI_FREE (Pathname);
0353     return (Status);
0354 }
0355 
0356 
0357 /*******************************************************************************
0358  *
0359  * FUNCTION:    AcpiNsCheckParameterCount
0360  *
0361  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
0362  *              Node            - Namespace node for the method/object
0363  *              UserParamCount  - Number of args passed in by the caller
0364  *              Predefined      - Pointer to entry in predefined name table
0365  *
0366  * RETURN:      None
0367  *
0368  * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
0369  *              predefined name is what is expected (i.e., what is defined in
0370  *              the ACPI specification for this predefined name.)
0371  *
0372  ******************************************************************************/
0373 
0374 void
0375 AcpiNsCheckParameterCount (
0376     char                        *Pathname,
0377     ACPI_NAMESPACE_NODE         *Node,
0378     UINT32                      UserParamCount,
0379     const ACPI_PREDEFINED_INFO  *Predefined)
0380 {
0381     UINT32                      ParamCount;
0382     UINT32                      RequiredParamsCurrent;
0383     UINT32                      RequiredParamsOld;
0384 
0385 
0386     /* Methods have 0-7 parameters. All other types have zero. */
0387 
0388     ParamCount = 0;
0389     if (Node->Type == ACPI_TYPE_METHOD)
0390     {
0391         ParamCount = Node->Object->Method.ParamCount;
0392     }
0393 
0394     if (!Predefined)
0395     {
0396         /*
0397          * Check the parameter count for non-predefined methods/objects.
0398          *
0399          * Warning if too few or too many arguments have been passed by the
0400          * caller. An incorrect number of arguments may not cause the method
0401          * to fail. However, the method will fail if there are too few
0402          * arguments and the method attempts to use one of the missing ones.
0403          */
0404         if (UserParamCount < ParamCount)
0405         {
0406             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
0407                 "Insufficient arguments - needs %u, found %u",
0408                 ParamCount, UserParamCount));
0409         }
0410         else if (UserParamCount > ParamCount)
0411         {
0412             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
0413                 "Excess arguments - needs %u, found %u",
0414                 ParamCount, UserParamCount));
0415         }
0416         return;
0417     }
0418 
0419     /*
0420      * Validate the user-supplied parameter count.
0421      * Allow two different legal argument counts (_SCP, etc.)
0422      */
0423     RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
0424     RequiredParamsOld = Predefined->Info.ParamCount >> 4;
0425 
0426     if (UserParamCount != ACPI_UINT32_MAX)
0427     {
0428         if ((UserParamCount != RequiredParamsCurrent) &&
0429             (UserParamCount != RequiredParamsOld))
0430         {
0431             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
0432                 "Parameter count mismatch - "
0433                 "caller passed %u, ACPI requires %u",
0434                 UserParamCount, RequiredParamsCurrent));
0435         }
0436     }
0437 
0438     /*
0439      * Check that the ASL-defined parameter count is what is expected for
0440      * this predefined name (parameter count as defined by the ACPI
0441      * specification)
0442      */
0443     if ((ParamCount != RequiredParamsCurrent) &&
0444         (ParamCount != RequiredParamsOld))
0445     {
0446         ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags,
0447             "Parameter count mismatch - ASL declared %u, ACPI requires %u",
0448             ParamCount, RequiredParamsCurrent));
0449     }
0450 }
0451 
0452 
0453 /*******************************************************************************
0454  *
0455  * FUNCTION:    AcpiNsCheckForPredefinedName
0456  *
0457  * PARAMETERS:  Node            - Namespace node for the method/object
0458  *
0459  * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
0460  *
0461  * DESCRIPTION: Check an object name against the predefined object list.
0462  *
0463  ******************************************************************************/
0464 
0465 const ACPI_PREDEFINED_INFO *
0466 AcpiNsCheckForPredefinedName (
0467     ACPI_NAMESPACE_NODE         *Node)
0468 {
0469     const ACPI_PREDEFINED_INFO  *ThisName;
0470 
0471 
0472     /* Quick check for a predefined name, first character must be underscore */
0473 
0474     if (Node->Name.Ascii[0] != '_')
0475     {
0476         return (NULL);
0477     }
0478 
0479     /* Search info table for a predefined method/object name */
0480 
0481     ThisName = PredefinedNames;
0482     while (ThisName->Info.Name[0])
0483     {
0484         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
0485         {
0486             return (ThisName);
0487         }
0488 
0489         /*
0490          * Skip next entry in the table if this name returns a Package
0491          * (next entry contains the package info)
0492          */
0493         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
0494         {
0495             ThisName++;
0496         }
0497 
0498         ThisName++;
0499     }
0500 
0501     return (NULL); /* Not found */
0502 }
0503 
0504 
0505 /*******************************************************************************
0506  *
0507  * FUNCTION:    AcpiNsCheckPackage
0508  *
0509  * PARAMETERS:  Data            - Pointer to validation data structure
0510  *              ReturnObjectPtr - Pointer to the object returned from the
0511  *                                evaluation of a method or object
0512  *
0513  * RETURN:      Status
0514  *
0515  * DESCRIPTION: Check a returned package object for the correct count and
0516  *              correct type of all sub-objects.
0517  *
0518  ******************************************************************************/
0519 
0520 static ACPI_STATUS
0521 AcpiNsCheckPackage (
0522     ACPI_PREDEFINED_DATA        *Data,
0523     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
0524 {
0525     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
0526     const ACPI_PREDEFINED_INFO  *Package;
0527     ACPI_OPERAND_OBJECT         *SubPackage;
0528     ACPI_OPERAND_OBJECT         **Elements;
0529     ACPI_OPERAND_OBJECT         **SubElements;
0530     ACPI_STATUS                 Status;
0531     UINT32                      ExpectedCount;
0532     UINT32                      Count;
0533     UINT32                      i;
0534     UINT32                      j;
0535 
0536 
0537     ACPI_FUNCTION_NAME (NsCheckPackage);
0538 
0539 
0540     /* The package info for this name is in the next table entry */
0541 
0542     Package = Data->Predefined + 1;
0543 
0544     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
0545         "%s Validating return Package of Type %X, Count %X\n",
0546         Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
0547 
0548     /* Extract package count and elements array */
0549 
0550     Elements = ReturnObject->Package.Elements;
0551     Count = ReturnObject->Package.Count;
0552 
0553     /* The package must have at least one element, else invalid */
0554 
0555     if (!Count)
0556     {
0557         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
0558             "Return Package has no elements (empty)"));
0559 
0560         return (AE_AML_OPERAND_VALUE);
0561     }
0562 
0563     /*
0564      * Decode the type of the expected package contents
0565      *
0566      * PTYPE1 packages contain no subpackages
0567      * PTYPE2 packages contain sub-packages
0568      */
0569     switch (Package->RetInfo.Type)
0570     {
0571     case ACPI_PTYPE1_FIXED:
0572 
0573         /*
0574          * The package count is fixed and there are no sub-packages
0575          *
0576          * If package is too small, exit.
0577          * If package is larger than expected, issue warning but continue
0578          */
0579         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
0580         if (Count < ExpectedCount)
0581         {
0582             goto PackageTooSmall;
0583         }
0584         else if (Count > ExpectedCount)
0585         {
0586             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
0587                 "Return Package is larger than needed - "
0588                 "found %u, expected %u", Count, ExpectedCount));
0589         }
0590 
0591         /* Validate all elements of the returned package */
0592 
0593         Status = AcpiNsCheckPackageElements (Data, Elements,
0594                     Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
0595                     Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
0596         if (ACPI_FAILURE (Status))
0597         {
0598             return (Status);
0599         }
0600         break;
0601 
0602 
0603     case ACPI_PTYPE1_VAR:
0604 
0605         /*
0606          * The package count is variable, there are no sub-packages, and all
0607          * elements must be of the same type
0608          */
0609         for (i = 0; i < Count; i++)
0610         {
0611             Status = AcpiNsCheckObjectType (Data, Elements,
0612                         Package->RetInfo.ObjectType1, i);
0613             if (ACPI_FAILURE (Status))
0614             {
0615                 return (Status);
0616             }
0617             Elements++;
0618         }
0619         break;
0620 
0621 
0622     case ACPI_PTYPE1_OPTION:
0623 
0624         /*
0625          * The package count is variable, there are no sub-packages. There are
0626          * a fixed number of required elements, and a variable number of
0627          * optional elements.
0628          *
0629          * Check if package is at least as large as the minimum required
0630          */
0631         ExpectedCount = Package->RetInfo3.Count;
0632         if (Count < ExpectedCount)
0633         {
0634             goto PackageTooSmall;
0635         }
0636 
0637         /* Variable number of sub-objects */
0638 
0639         for (i = 0; i < Count; i++)
0640         {
0641             if (i < Package->RetInfo3.Count)
0642             {
0643                 /* These are the required package elements (0, 1, or 2) */
0644 
0645                 Status = AcpiNsCheckObjectType (Data, Elements,
0646                             Package->RetInfo3.ObjectType[i], i);
0647                 if (ACPI_FAILURE (Status))
0648                 {
0649                     return (Status);
0650                 }
0651             }
0652             else
0653             {
0654                 /* These are the optional package elements */
0655 
0656                 Status = AcpiNsCheckObjectType (Data, Elements,
0657                             Package->RetInfo3.TailObjectType, i);
0658                 if (ACPI_FAILURE (Status))
0659                 {
0660                     return (Status);
0661                 }
0662             }
0663             Elements++;
0664         }
0665         break;
0666 
0667 
0668     case ACPI_PTYPE2_PKG_COUNT:
0669 
0670         /* First element is the (Integer) count of sub-packages to follow */
0671 
0672         Status = AcpiNsCheckObjectType (Data, Elements,
0673                     ACPI_RTYPE_INTEGER, 0);
0674         if (ACPI_FAILURE (Status))
0675         {
0676             return (Status);
0677         }
0678 
0679         /*
0680          * Count cannot be larger than the parent package length, but allow it
0681          * to be smaller. The >= accounts for the Integer above.
0682          */
0683         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
0684         if (ExpectedCount >= Count)
0685         {
0686             goto PackageTooSmall;
0687         }
0688 
0689         Count = ExpectedCount;
0690         Elements++;
0691 
0692         /* Now we can walk the sub-packages */
0693 
0694         /*lint -fallthrough */
0695 
0696 
0697     case ACPI_PTYPE2:
0698     case ACPI_PTYPE2_FIXED:
0699     case ACPI_PTYPE2_MIN:
0700     case ACPI_PTYPE2_COUNT:
0701 
0702         /*
0703          * These types all return a single package that consists of a variable
0704          * number of sub-packages
0705          */
0706         for (i = 0; i < Count; i++)
0707         {
0708             SubPackage = *Elements;
0709             SubElements = SubPackage->Package.Elements;
0710 
0711             /* Each sub-object must be of type Package */
0712 
0713             Status = AcpiNsCheckObjectType (Data, &SubPackage,
0714                         ACPI_RTYPE_PACKAGE, i);
0715             if (ACPI_FAILURE (Status))
0716             {
0717                 return (Status);
0718             }
0719 
0720             /* Examine the different types of sub-packages */
0721 
0722             switch (Package->RetInfo.Type)
0723             {
0724             case ACPI_PTYPE2:
0725             case ACPI_PTYPE2_PKG_COUNT:
0726 
0727                 /* Each subpackage has a fixed number of elements */
0728 
0729                 ExpectedCount =
0730                     Package->RetInfo.Count1 + Package->RetInfo.Count2;
0731                 if (SubPackage->Package.Count != ExpectedCount)
0732                 {
0733                     Count = SubPackage->Package.Count;
0734                     goto PackageTooSmall;
0735                 }
0736 
0737                 Status = AcpiNsCheckPackageElements (Data, SubElements,
0738                             Package->RetInfo.ObjectType1,
0739                             Package->RetInfo.Count1,
0740                             Package->RetInfo.ObjectType2,
0741                             Package->RetInfo.Count2, 0);
0742                 if (ACPI_FAILURE (Status))
0743                 {
0744                     return (Status);
0745                 }
0746                 break;
0747 
0748             case ACPI_PTYPE2_FIXED:
0749 
0750                 /* Each sub-package has a fixed length */
0751 
0752                 ExpectedCount = Package->RetInfo2.Count;
0753                 if (SubPackage->Package.Count < ExpectedCount)
0754                 {
0755                     Count = SubPackage->Package.Count;
0756                     goto PackageTooSmall;
0757                 }
0758 
0759                 /* Check the type of each sub-package element */
0760 
0761                 for (j = 0; j < ExpectedCount; j++)
0762                 {
0763                     Status = AcpiNsCheckObjectType (Data, &SubElements[j],
0764                                 Package->RetInfo2.ObjectType[j], j);
0765                     if (ACPI_FAILURE (Status))
0766                     {
0767                         return (Status);
0768                     }
0769                 }
0770                 break;
0771 
0772             case ACPI_PTYPE2_MIN:
0773 
0774                 /* Each sub-package has a variable but minimum length */
0775 
0776                 ExpectedCount = Package->RetInfo.Count1;
0777                 if (SubPackage->Package.Count < ExpectedCount)
0778                 {
0779                     Count = SubPackage->Package.Count;
0780                     goto PackageTooSmall;
0781                 }
0782 
0783                 /* Check the type of each sub-package element */
0784 
0785                 Status = AcpiNsCheckPackageElements (Data, SubElements,
0786                             Package->RetInfo.ObjectType1,
0787                             SubPackage->Package.Count, 0, 0, 0);
0788                 if (ACPI_FAILURE (Status))
0789                 {
0790                     return (Status);
0791                 }
0792                 break;
0793 
0794             case ACPI_PTYPE2_COUNT:
0795 
0796                 /* First element is the (Integer) count of elements to follow */
0797 
0798                 Status = AcpiNsCheckObjectType (Data, SubElements,
0799                             ACPI_RTYPE_INTEGER, 0);
0800                 if (ACPI_FAILURE (Status))
0801                 {
0802                     return (Status);
0803                 }
0804 
0805                 /* Make sure package is large enough for the Count */
0806 
0807                 ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
0808                 if (SubPackage->Package.Count < ExpectedCount)
0809                 {
0810                     Count = SubPackage->Package.Count;
0811                     goto PackageTooSmall;
0812                 }
0813 
0814                 /* Check the type of each sub-package element */
0815 
0816                 Status = AcpiNsCheckPackageElements (Data, (SubElements + 1),
0817                             Package->RetInfo.ObjectType1,
0818                             (ExpectedCount - 1), 0, 0, 1);
0819                 if (ACPI_FAILURE (Status))
0820                 {
0821                     return (Status);
0822                 }
0823                 break;
0824 
0825             default:
0826                 break;
0827             }
0828 
0829             Elements++;
0830         }
0831         break;
0832 
0833 
0834     default:
0835 
0836         /* Should not get here if predefined info table is correct */
0837 
0838         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
0839             "Invalid internal return type in table entry: %X",
0840             Package->RetInfo.Type));
0841 
0842         return (AE_AML_INTERNAL);
0843     }
0844 
0845     return (AE_OK);
0846 
0847 
0848 PackageTooSmall:
0849 
0850     /* Error exit for the case with an incorrect package count */
0851 
0852     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
0853         "Return Package is too small - found %u, expected %u",
0854         Count, ExpectedCount));
0855 
0856     return (AE_AML_OPERAND_VALUE);
0857 }
0858 
0859 
0860 /*******************************************************************************
0861  *
0862  * FUNCTION:    AcpiNsCheckPackageElements
0863  *
0864  * PARAMETERS:  Data            - Pointer to validation data structure
0865  *              Elements        - Pointer to the package elements array
0866  *              Type1           - Object type for first group
0867  *              Count1          - Count for first group
0868  *              Type2           - Object type for second group
0869  *              Count2          - Count for second group
0870  *              StartIndex      - Start of the first group of elements
0871  *
0872  * RETURN:      Status
0873  *
0874  * DESCRIPTION: Check that all elements of a package are of the correct object
0875  *              type. Supports up to two groups of different object types.
0876  *
0877  ******************************************************************************/
0878 
0879 static ACPI_STATUS
0880 AcpiNsCheckPackageElements (
0881     ACPI_PREDEFINED_DATA        *Data,
0882     ACPI_OPERAND_OBJECT         **Elements,
0883     UINT8                       Type1,
0884     UINT32                      Count1,
0885     UINT8                       Type2,
0886     UINT32                      Count2,
0887     UINT32                      StartIndex)
0888 {
0889     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
0890     ACPI_STATUS                 Status;
0891     UINT32                      i;
0892 
0893 
0894     /*
0895      * Up to two groups of package elements are supported by the data
0896      * structure. All elements in each group must be of the same type.
0897      * The second group can have a count of zero.
0898      */
0899     for (i = 0; i < Count1; i++)
0900     {
0901         Status = AcpiNsCheckObjectType (Data, ThisElement,
0902                     Type1, i + StartIndex);
0903         if (ACPI_FAILURE (Status))
0904         {
0905             return (Status);
0906         }
0907         ThisElement++;
0908     }
0909 
0910     for (i = 0; i < Count2; i++)
0911     {
0912         Status = AcpiNsCheckObjectType (Data, ThisElement,
0913                     Type2, (i + Count1 + StartIndex));
0914         if (ACPI_FAILURE (Status))
0915         {
0916             return (Status);
0917         }
0918         ThisElement++;
0919     }
0920 
0921     return (AE_OK);
0922 }
0923 
0924 
0925 /*******************************************************************************
0926  *
0927  * FUNCTION:    AcpiNsCheckObjectType
0928  *
0929  * PARAMETERS:  Data            - Pointer to validation data structure
0930  *              ReturnObjectPtr - Pointer to the object returned from the
0931  *                                evaluation of a method or object
0932  *              ExpectedBtypes  - Bitmap of expected return type(s)
0933  *              PackageIndex    - Index of object within parent package (if
0934  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
0935  *                                otherwise)
0936  *
0937  * RETURN:      Status
0938  *
0939  * DESCRIPTION: Check the type of the return object against the expected object
0940  *              type(s). Use of Btype allows multiple expected object types.
0941  *
0942  ******************************************************************************/
0943 
0944 static ACPI_STATUS
0945 AcpiNsCheckObjectType (
0946     ACPI_PREDEFINED_DATA        *Data,
0947     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
0948     UINT32                      ExpectedBtypes,
0949     UINT32                      PackageIndex)
0950 {
0951     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
0952     ACPI_STATUS                 Status = AE_OK;
0953     UINT32                      ReturnBtype;
0954     char                        TypeBuffer[48]; /* Room for 5 types */
0955 
0956 
0957     /*
0958      * If we get a NULL ReturnObject here, it is a NULL package element,
0959      * and this is always an error.
0960      */
0961     if (!ReturnObject)
0962     {
0963         goto TypeErrorExit;
0964     }
0965 
0966     /* A Namespace node should not get here, but make sure */
0967 
0968     if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
0969     {
0970         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
0971             "Invalid return type - Found a Namespace node [%4.4s] type %s",
0972             ReturnObject->Node.Name.Ascii,
0973             AcpiUtGetTypeName (ReturnObject->Node.Type)));
0974         return (AE_AML_OPERAND_TYPE);
0975     }
0976 
0977     /*
0978      * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
0979      * The bitmapped type allows multiple possible return types.
0980      *
0981      * Note, the cases below must handle all of the possible types returned
0982      * from all of the predefined names (including elements of returned
0983      * packages)
0984      */
0985     switch (ReturnObject->Common.Type)
0986     {
0987     case ACPI_TYPE_INTEGER:
0988         ReturnBtype = ACPI_RTYPE_INTEGER;
0989         break;
0990 
0991     case ACPI_TYPE_BUFFER:
0992         ReturnBtype = ACPI_RTYPE_BUFFER;
0993         break;
0994 
0995     case ACPI_TYPE_STRING:
0996         ReturnBtype = ACPI_RTYPE_STRING;
0997         break;
0998 
0999     case ACPI_TYPE_PACKAGE:
1000         ReturnBtype = ACPI_RTYPE_PACKAGE;
1001         break;
1002 
1003     case ACPI_TYPE_LOCAL_REFERENCE:
1004         ReturnBtype = ACPI_RTYPE_REFERENCE;
1005         break;
1006 
1007     default:
1008         /* Not one of the supported objects, must be incorrect */
1009 
1010         goto TypeErrorExit;
1011     }
1012 
1013     /* Is the object one of the expected types? */
1014 
1015     if (!(ReturnBtype & ExpectedBtypes))
1016     {
1017         /* Type mismatch -- attempt repair of the returned object */
1018 
1019         Status = AcpiNsRepairObject (Data, ExpectedBtypes,
1020                     PackageIndex, ReturnObjectPtr);
1021         if (ACPI_SUCCESS (Status))
1022         {
1023             return (AE_OK); /* Repair was successful */
1024         }
1025         goto TypeErrorExit;
1026     }
1027 
1028     /* For reference objects, check that the reference type is correct */
1029 
1030     if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1031     {
1032         Status = AcpiNsCheckReference (Data, ReturnObject);
1033     }
1034 
1035     return (Status);
1036 
1037 
1038 TypeErrorExit:
1039 
1040     /* Create a string with all expected types for this predefined object */
1041 
1042     AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);
1043 
1044     if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
1045     {
1046         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1047             "Return type mismatch - found %s, expected %s",
1048             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1049     }
1050     else
1051     {
1052         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1053             "Return Package type mismatch at index %u - "
1054             "found %s, expected %s", PackageIndex,
1055             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1056     }
1057 
1058     return (AE_AML_OPERAND_TYPE);
1059 }
1060 
1061 
1062 /*******************************************************************************
1063  *
1064  * FUNCTION:    AcpiNsCheckReference
1065  *
1066  * PARAMETERS:  Data            - Pointer to validation data structure
1067  *              ReturnObject    - Object returned from the evaluation of a
1068  *                                method or object
1069  *
1070  * RETURN:      Status
1071  *
1072  * DESCRIPTION: Check a returned reference object for the correct reference
1073  *              type. The only reference type that can be returned from a
1074  *              predefined method is a named reference. All others are invalid.
1075  *
1076  ******************************************************************************/
1077 
1078 static ACPI_STATUS
1079 AcpiNsCheckReference (
1080     ACPI_PREDEFINED_DATA        *Data,
1081     ACPI_OPERAND_OBJECT         *ReturnObject)
1082 {
1083 
1084     /*
1085      * Check the reference object for the correct reference type (opcode).
1086      * The only type of reference that can be converted to an ACPI_OBJECT is
1087      * a reference to a named object (reference class: NAME)
1088      */
1089     if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1090     {
1091         return (AE_OK);
1092     }
1093 
1094     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1095         "Return type mismatch - unexpected reference object type [%s] %2.2X",
1096         AcpiUtGetReferenceName (ReturnObject),
1097         ReturnObject->Reference.Class));
1098 
1099     return (AE_AML_OPERAND_TYPE);
1100 }
1101 
1102 
1103 /*******************************************************************************
1104  *
1105  * FUNCTION:    AcpiNsRepairObject
1106  *
1107  * PARAMETERS:  Data            - Pointer to validation data structure
1108  *              ExpectedBtypes  - Object types expected
1109  *              PackageIndex    - Index of object within parent package (if
1110  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
1111  *                                otherwise)
1112  *              ReturnObjectPtr - Pointer to the object returned from the
1113  *                                evaluation of a method or object
1114  *
1115  * RETURN:      Status. AE_OK if repair was successful.
1116  *
1117  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
1118  *              not expected.
1119  *
1120  ******************************************************************************/
1121 
1122 static ACPI_STATUS
1123 AcpiNsRepairObject (
1124     ACPI_PREDEFINED_DATA        *Data,
1125     UINT32                      ExpectedBtypes,
1126     UINT32                      PackageIndex,
1127     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
1128 {
1129     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1130     ACPI_OPERAND_OBJECT         *NewObject;
1131     ACPI_SIZE                   Length;
1132 
1133 
1134     switch (ReturnObject->Common.Type)
1135     {
1136     case ACPI_TYPE_BUFFER:
1137 
1138         /* Does the method/object legally return a string? */
1139 
1140         if (!(ExpectedBtypes & ACPI_RTYPE_STRING))
1141         {
1142             return (AE_AML_OPERAND_TYPE);
1143         }
1144 
1145         /*
1146          * Have a Buffer, expected a String, convert. Use a ToString
1147          * conversion, no transform performed on the buffer data. The best
1148          * example of this is the _BIF method, where the string data from
1149          * the battery is often (incorrectly) returned as buffer object(s).
1150          */
1151         Length = 0;
1152         while ((Length < ReturnObject->Buffer.Length) &&
1153                 (ReturnObject->Buffer.Pointer[Length]))
1154         {
1155             Length++;
1156         }
1157 
1158         /* Allocate a new string object */
1159 
1160         NewObject = AcpiUtCreateStringObject (Length);
1161         if (!NewObject)
1162         {
1163             return (AE_NO_MEMORY);
1164         }
1165 
1166         /*
1167          * Copy the raw buffer data with no transform. String is already NULL
1168          * terminated at Length+1.
1169          */
1170         ACPI_MEMCPY (NewObject->String.Pointer,
1171             ReturnObject->Buffer.Pointer, Length);
1172 
1173         /*
1174          * If the original object is a package element, we need to:
1175          * 1. Set the reference count of the new object to match the
1176          *    reference count of the old object.
1177          * 2. Decrement the reference count of the original object.
1178          */
1179         if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
1180         {
1181             NewObject->Common.ReferenceCount =
1182                 ReturnObject->Common.ReferenceCount;
1183 
1184             if (ReturnObject->Common.ReferenceCount > 1)
1185             {
1186                 ReturnObject->Common.ReferenceCount--;
1187             }
1188 
1189             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1190                 "Converted Buffer to expected String at index %u",
1191                 PackageIndex));
1192         }
1193         else
1194         {
1195             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1196                 "Converted Buffer to expected String"));
1197         }
1198 
1199         /* Delete old object, install the new return object */
1200 
1201         AcpiUtRemoveReference (ReturnObject);
1202         *ReturnObjectPtr = NewObject;
1203         Data->Flags |= ACPI_OBJECT_REPAIRED;
1204         return (AE_OK);
1205 
1206     default:
1207         break;
1208     }
1209 
1210     return (AE_AML_OPERAND_TYPE);
1211 }
1212 
1213 
1214 /*******************************************************************************
1215  *
1216  * FUNCTION:    AcpiNsGetExpectedTypes
1217  *
1218  * PARAMETERS:  Buffer          - Pointer to where the string is returned
1219  *              ExpectedBtypes  - Bitmap of expected return type(s)
1220  *
1221  * RETURN:      Buffer is populated with type names.
1222  *
1223  * DESCRIPTION: Translate the expected types bitmap into a string of ascii
1224  *              names of expected types, for use in warning messages.
1225  *
1226  ******************************************************************************/
1227 
1228 static void
1229 AcpiNsGetExpectedTypes (
1230     char                        *Buffer,
1231     UINT32                      ExpectedBtypes)
1232 {
1233     UINT32                      ThisRtype;
1234     UINT32                      i;
1235     UINT32                      j;
1236 
1237 
1238     j = 1;
1239     Buffer[0] = 0;
1240     ThisRtype = ACPI_RTYPE_INTEGER;
1241 
1242     for (i = 0; i < ACPI_NUM_RTYPES; i++)
1243     {
1244         /* If one of the expected types, concatenate the name of this type */
1245 
1246         if (ExpectedBtypes & ThisRtype)
1247         {
1248             ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
1249             j = 0;              /* Use name separator from now on */
1250         }
1251         ThisRtype <<= 1;    /* Next Rtype */
1252     }
1253 }