The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/namespace/nsprepkg.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2  *
    3  * Module Name: nsprepkg - Validation of package objects for predefined names
    4  *
    5  *****************************************************************************/
    6 
    7 /******************************************************************************
    8  *
    9  * 1. Copyright Notice
   10  *
   11  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
   12  * All rights reserved.
   13  *
   14  * 2. License
   15  *
   16  * 2.1. This is your license from Intel Corp. under its intellectual property
   17  * rights. You may have additional license terms from the party that provided
   18  * you this software, covering your right to use that party's intellectual
   19  * property rights.
   20  *
   21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
   22  * copy of the source code appearing in this file ("Covered Code") an
   23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
   24  * base code distributed originally by Intel ("Original Intel Code") to copy,
   25  * make derivatives, distribute, use and display any portion of the Covered
   26  * Code in any form, with the right to sublicense such rights; and
   27  *
   28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
   29  * license (with the right to sublicense), under only those claims of Intel
   30  * patents that are infringed by the Original Intel Code, to make, use, sell,
   31  * offer to sell, and import the Covered Code and derivative works thereof
   32  * solely to the minimum extent necessary to exercise the above copyright
   33  * license, and in no event shall the patent license extend to any additions
   34  * to or modifications of the Original Intel Code. No other license or right
   35  * is granted directly or by implication, estoppel or otherwise;
   36  *
   37  * The above copyright and patent license is granted only if the following
   38  * conditions are met:
   39  *
   40  * 3. Conditions
   41  *
   42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
   43  * Redistribution of source code of any substantial portion of the Covered
   44  * Code or modification with rights to further distribute source must include
   45  * the above Copyright Notice, the above License, this list of Conditions,
   46  * and the following Disclaimer and Export Compliance provision. In addition,
   47  * Licensee must cause all Covered Code to which Licensee contributes to
   48  * contain a file documenting the changes Licensee made to create that Covered
   49  * Code and the date of any change. Licensee must include in that file the
   50  * documentation of any changes made by any predecessor Licensee. Licensee
   51  * must include a prominent statement that the modification is derived,
   52  * directly or indirectly, from Original Intel Code.
   53  *
   54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
   55  * Redistribution of source code of any substantial portion of the Covered
   56  * Code or modification without rights to further distribute source must
   57  * include the following Disclaimer and Export Compliance provision in the
   58  * documentation and/or other materials provided with distribution. In
   59  * addition, Licensee may not authorize further sublicense of source of any
   60  * portion of the Covered Code, and must include terms to the effect that the
   61  * license from Licensee to its licensee is limited to the intellectual
   62  * property embodied in the software Licensee provides to its licensee, and
   63  * not to intellectual property embodied in modifications its licensee may
   64  * make.
   65  *
   66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
   67  * substantial portion of the Covered Code or modification must reproduce the
   68  * above Copyright Notice, and the following Disclaimer and Export Compliance
   69  * provision in the documentation and/or other materials provided with the
   70  * distribution.
   71  *
   72  * 3.4. Intel retains all right, title, and interest in and to the Original
   73  * Intel Code.
   74  *
   75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
   76  * Intel shall be used in advertising or otherwise to promote the sale, use or
   77  * other dealings in products derived from or relating to the Covered Code
   78  * without prior written authorization from Intel.
   79  *
   80  * 4. Disclaimer and Export Compliance
   81  *
   82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
   83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
   84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
   85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
   86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
   87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
   88  * PARTICULAR PURPOSE.
   89  *
   90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
   91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
   92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
   93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
   94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
   95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
   96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
   97  * LIMITED REMEDY.
   98  *
   99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100  * software or system incorporating such software without first obtaining any
  101  * required license or other approval from the U. S. Department of Commerce or
  102  * any other agency or department of the United States Government. In the
  103  * event Licensee exports any such software from the United States or
  104  * re-exports any such software from a foreign destination, Licensee shall
  105  * ensure that the distribution and export/re-export of the software is in
  106  * compliance with all laws, regulations, orders, or other restrictions of the
  107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108  * any of its subsidiaries will export/re-export any technical data, process,
  109  * software, or service, directly or indirectly, to any country for which the
  110  * United States government or any agency thereof requires an export license,
  111  * other governmental approval, or letter of assurance, without first obtaining
  112  * such license, approval or letter.
  113  *
  114  *****************************************************************************
  115  *
  116  * Alternatively, you may choose to be licensed under the terms of the
  117  * following license:
  118  *
  119  * Redistribution and use in source and binary forms, with or without
  120  * modification, are permitted provided that the following conditions
  121  * are met:
  122  * 1. Redistributions of source code must retain the above copyright
  123  *    notice, this list of conditions, and the following disclaimer,
  124  *    without modification.
  125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  126  *    substantially similar to the "NO WARRANTY" disclaimer below
  127  *    ("Disclaimer") and any redistribution must be conditioned upon
  128  *    including a substantially similar Disclaimer requirement for further
  129  *    binary redistribution.
  130  * 3. Neither the names of the above-listed copyright holders nor the names
  131  *    of any contributors may be used to endorse or promote products derived
  132  *    from this software without specific prior written permission.
  133  *
  134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145  *
  146  * Alternatively, you may choose to be licensed under the terms of the
  147  * GNU General Public License ("GPL") version 2 as published by the Free
  148  * Software Foundation.
  149  *
  150  *****************************************************************************/
  151 
  152 #include <contrib/dev/acpica/include/acpi.h>
  153 #include <contrib/dev/acpica/include/accommon.h>
  154 #include <contrib/dev/acpica/include/acnamesp.h>
  155 #include <contrib/dev/acpica/include/acpredef.h>
  156 
  157 
  158 #define _COMPONENT          ACPI_NAMESPACE
  159         ACPI_MODULE_NAME    ("nsprepkg")
  160 
  161 
  162 /* Local prototypes */
  163 
  164 static ACPI_STATUS
  165 AcpiNsCheckPackageList (
  166     ACPI_EVALUATE_INFO          *Info,
  167     const ACPI_PREDEFINED_INFO  *Package,
  168     ACPI_OPERAND_OBJECT         **Elements,
  169     UINT32                      Count);
  170 
  171 static ACPI_STATUS
  172 AcpiNsCheckPackageElements (
  173     ACPI_EVALUATE_INFO          *Info,
  174     ACPI_OPERAND_OBJECT         **Elements,
  175     UINT8                       Type1,
  176     UINT32                      Count1,
  177     UINT8                       Type2,
  178     UINT32                      Count2,
  179     UINT32                      StartIndex);
  180 
  181 static ACPI_STATUS
  182 AcpiNsCustomPackage (
  183     ACPI_EVALUATE_INFO          *Info,
  184     ACPI_OPERAND_OBJECT         **Elements,
  185     UINT32                      Count);
  186 
  187 
  188 /*******************************************************************************
  189  *
  190  * FUNCTION:    AcpiNsCheckPackage
  191  *
  192  * PARAMETERS:  Info                - Method execution information block
  193  *              ReturnObjectPtr     - Pointer to the object returned from the
  194  *                                    evaluation of a method or object
  195  *
  196  * RETURN:      Status
  197  *
  198  * DESCRIPTION: Check a returned package object for the correct count and
  199  *              correct type of all sub-objects.
  200  *
  201  ******************************************************************************/
  202 
  203 ACPI_STATUS
  204 AcpiNsCheckPackage (
  205     ACPI_EVALUATE_INFO          *Info,
  206     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
  207 {
  208     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
  209     const ACPI_PREDEFINED_INFO  *Package;
  210     ACPI_OPERAND_OBJECT         **Elements;
  211     ACPI_STATUS                 Status = AE_OK;
  212     UINT32                      ExpectedCount;
  213     UINT32                      Count;
  214     UINT32                      i;
  215 
  216 
  217     ACPI_FUNCTION_TRACE (NsCheckPackage);
  218 
  219 
  220     /* The package info for this name is in the next table entry */
  221 
  222     Package = Info->Predefined + 1;
  223 
  224     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  225         "%s Validating return Package of Type %X, Count %X\n",
  226         Info->FullPathname, Package->RetInfo.Type,
  227         ReturnObject->Package.Count));
  228 
  229     /*
  230      * For variable-length Packages, we can safely remove all embedded
  231      * and trailing NULL package elements
  232      */
  233     AcpiNsRemoveNullElements (Info, Package->RetInfo.Type, ReturnObject);
  234 
  235     /* Extract package count and elements array */
  236 
  237     Elements = ReturnObject->Package.Elements;
  238     Count = ReturnObject->Package.Count;
  239 
  240     /*
  241      * Most packages must have at least one element. The only exception
  242      * is the variable-length package (ACPI_PTYPE1_VAR).
  243      */
  244     if (!Count)
  245     {
  246         if (Package->RetInfo.Type == ACPI_PTYPE1_VAR)
  247         {
  248             return_ACPI_STATUS (AE_OK);
  249         }
  250 
  251         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
  252             "Return Package has no elements (empty)"));
  253 
  254         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
  255     }
  256 
  257     /*
  258      * Decode the type of the expected package contents
  259      *
  260      * PTYPE1 packages contain no subpackages
  261      * PTYPE2 packages contain subpackages
  262      */
  263     switch (Package->RetInfo.Type)
  264     {
  265     case ACPI_PTYPE_CUSTOM:
  266 
  267         Status = AcpiNsCustomPackage (Info, Elements, Count);
  268         break;
  269 
  270     case ACPI_PTYPE1_FIXED:
  271         /*
  272          * The package count is fixed and there are no subpackages
  273          *
  274          * If package is too small, exit.
  275          * If package is larger than expected, issue warning but continue
  276          */
  277         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
  278         if (Count < ExpectedCount)
  279         {
  280             goto PackageTooSmall;
  281         }
  282         else if (Count > ExpectedCount)
  283         {
  284             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  285                 "%s: Return Package is larger than needed - "
  286                 "found %u, expected %u\n",
  287                 Info->FullPathname, Count, ExpectedCount));
  288         }
  289 
  290         /* Validate all elements of the returned package */
  291 
  292         Status = AcpiNsCheckPackageElements (Info, Elements,
  293             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
  294             Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
  295         break;
  296 
  297     case ACPI_PTYPE1_VAR:
  298         /*
  299          * The package count is variable, there are no subpackages, and all
  300          * elements must be of the same type
  301          */
  302         for (i = 0; i < Count; i++)
  303         {
  304             Status = AcpiNsCheckObjectType (Info, Elements,
  305                 Package->RetInfo.ObjectType1, i);
  306             if (ACPI_FAILURE (Status))
  307             {
  308                 return_ACPI_STATUS (Status);
  309             }
  310 
  311             Elements++;
  312         }
  313         break;
  314 
  315     case ACPI_PTYPE1_OPTION:
  316         /*
  317          * The package count is variable, there are no subpackages. There are
  318          * a fixed number of required elements, and a variable number of
  319          * optional elements.
  320          *
  321          * Check if package is at least as large as the minimum required
  322          */
  323         ExpectedCount = Package->RetInfo3.Count;
  324         if (Count < ExpectedCount)
  325         {
  326             goto PackageTooSmall;
  327         }
  328 
  329         /* Variable number of sub-objects */
  330 
  331         for (i = 0; i < Count; i++)
  332         {
  333             if (i < Package->RetInfo3.Count)
  334             {
  335                 /* These are the required package elements (0, 1, or 2) */
  336 
  337                 Status = AcpiNsCheckObjectType (Info, Elements,
  338                     Package->RetInfo3.ObjectType[i], i);
  339                 if (ACPI_FAILURE (Status))
  340                 {
  341                     return_ACPI_STATUS (Status);
  342                 }
  343             }
  344             else
  345             {
  346                 /* These are the optional package elements */
  347 
  348                 Status = AcpiNsCheckObjectType (Info, Elements,
  349                     Package->RetInfo3.TailObjectType, i);
  350                 if (ACPI_FAILURE (Status))
  351                 {
  352                     return_ACPI_STATUS (Status);
  353                 }
  354             }
  355 
  356             Elements++;
  357         }
  358         break;
  359 
  360     case ACPI_PTYPE2_REV_FIXED:
  361 
  362         /* First element is the (Integer) revision */
  363 
  364         Status = AcpiNsCheckObjectType (
  365             Info, Elements, ACPI_RTYPE_INTEGER, 0);
  366         if (ACPI_FAILURE (Status))
  367         {
  368             return_ACPI_STATUS (Status);
  369         }
  370 
  371         Elements++;
  372         Count--;
  373 
  374         /* Examine the subpackages */
  375 
  376         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
  377         break;
  378 
  379     case ACPI_PTYPE2_PKG_COUNT:
  380 
  381         /* First element is the (Integer) count of subpackages to follow */
  382 
  383         Status = AcpiNsCheckObjectType (
  384             Info, Elements, ACPI_RTYPE_INTEGER, 0);
  385         if (ACPI_FAILURE (Status))
  386         {
  387             return_ACPI_STATUS (Status);
  388         }
  389 
  390         /*
  391          * Count cannot be larger than the parent package length, but allow it
  392          * to be smaller. The >= accounts for the Integer above.
  393          */
  394         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
  395         if (ExpectedCount >= Count)
  396         {
  397             goto PackageTooSmall;
  398         }
  399 
  400         Count = ExpectedCount;
  401         Elements++;
  402 
  403         /* Examine the subpackages */
  404 
  405         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
  406         break;
  407 
  408     case ACPI_PTYPE2:
  409     case ACPI_PTYPE2_FIXED:
  410     case ACPI_PTYPE2_MIN:
  411     case ACPI_PTYPE2_COUNT:
  412     case ACPI_PTYPE2_FIX_VAR:
  413         /*
  414          * These types all return a single Package that consists of a
  415          * variable number of subpackages.
  416          *
  417          * First, ensure that the first element is a subpackage. If not,
  418          * the BIOS may have incorrectly returned the object as a single
  419          * package instead of a Package of Packages (a common error if
  420          * there is only one entry). We may be able to repair this by
  421          * wrapping the returned Package with a new outer Package.
  422          */
  423         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
  424         {
  425             /* Create the new outer package and populate it */
  426 
  427             Status = AcpiNsWrapWithPackage (
  428                 Info, ReturnObject, ReturnObjectPtr);
  429             if (ACPI_FAILURE (Status))
  430             {
  431                 return_ACPI_STATUS (Status);
  432             }
  433 
  434             /* Update locals to point to the new package (of 1 element) */
  435 
  436             ReturnObject = *ReturnObjectPtr;
  437             Elements = ReturnObject->Package.Elements;
  438             Count = 1;
  439         }
  440 
  441         /* Examine the subpackages */
  442 
  443         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
  444         break;
  445 
  446     case ACPI_PTYPE2_VAR_VAR:
  447         /*
  448          * Returns a variable list of packages, each with a variable list
  449          * of objects.
  450          */
  451         break;
  452 
  453     case ACPI_PTYPE2_UUID_PAIR:
  454 
  455         /* The package must contain pairs of (UUID + type) */
  456 
  457         if (Count & 1)
  458         {
  459             ExpectedCount = Count + 1;
  460             goto PackageTooSmall;
  461         }
  462 
  463         while (Count > 0)
  464         {
  465             Status = AcpiNsCheckObjectType(Info, Elements,
  466                 Package->RetInfo.ObjectType1, 0);
  467             if (ACPI_FAILURE(Status))
  468             {
  469                 return_ACPI_STATUS (Status);
  470             }
  471 
  472             /* Validate length of the UUID buffer */
  473 
  474             if ((*Elements)->Buffer.Length != 16)
  475             {
  476                 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
  477                     Info->NodeFlags, "Invalid length for UUID Buffer"));
  478                 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
  479             }
  480 
  481             Status = AcpiNsCheckObjectType(Info, Elements + 1,
  482                 Package->RetInfo.ObjectType2, 0);
  483             if (ACPI_FAILURE(Status))
  484             {
  485                 return_ACPI_STATUS (Status);
  486             }
  487 
  488             Elements += 2;
  489             Count -= 2;
  490         }
  491         break;
  492 
  493     default:
  494 
  495         /* Should not get here if predefined info table is correct */
  496 
  497         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
  498             "Invalid internal return type in table entry: %X",
  499             Package->RetInfo.Type));
  500 
  501         return_ACPI_STATUS (AE_AML_INTERNAL);
  502     }
  503 
  504     return_ACPI_STATUS (Status);
  505 
  506 
  507 PackageTooSmall:
  508 
  509     /* Error exit for the case with an incorrect package count */
  510 
  511     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
  512         "Return Package is too small - found %u elements, expected %u",
  513         Count, ExpectedCount));
  514 
  515     return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
  516 }
  517 
  518 
  519 /*******************************************************************************
  520  *
  521  * FUNCTION:    AcpiNsCheckPackageList
  522  *
  523  * PARAMETERS:  Info            - Method execution information block
  524  *              Package         - Pointer to package-specific info for method
  525  *              Elements        - Element list of parent package. All elements
  526  *                                of this list should be of type Package.
  527  *              Count           - Count of subpackages
  528  *
  529  * RETURN:      Status
  530  *
  531  * DESCRIPTION: Examine a list of subpackages
  532  *
  533  ******************************************************************************/
  534 
  535 static ACPI_STATUS
  536 AcpiNsCheckPackageList (
  537     ACPI_EVALUATE_INFO          *Info,
  538     const ACPI_PREDEFINED_INFO  *Package,
  539     ACPI_OPERAND_OBJECT         **Elements,
  540     UINT32                      Count)
  541 {
  542     ACPI_OPERAND_OBJECT         *SubPackage;
  543     ACPI_OPERAND_OBJECT         **SubElements;
  544     ACPI_STATUS                 Status;
  545     UINT32                      ExpectedCount;
  546     UINT32                      i;
  547     UINT32                      j;
  548 
  549 
  550     /*
  551      * Validate each subpackage in the parent Package
  552      *
  553      * NOTE: assumes list of subpackages contains no NULL elements.
  554      * Any NULL elements should have been removed by earlier call
  555      * to AcpiNsRemoveNullElements.
  556      */
  557     for (i = 0; i < Count; i++)
  558     {
  559         SubPackage = *Elements;
  560         SubElements = SubPackage->Package.Elements;
  561         Info->ParentPackage = SubPackage;
  562 
  563         /* Each sub-object must be of type Package */
  564 
  565         Status = AcpiNsCheckObjectType (Info, &SubPackage,
  566             ACPI_RTYPE_PACKAGE, i);
  567         if (ACPI_FAILURE (Status))
  568         {
  569             return (Status);
  570         }
  571 
  572         /* Examine the different types of expected subpackages */
  573 
  574         Info->ParentPackage = SubPackage;
  575         switch (Package->RetInfo.Type)
  576         {
  577         case ACPI_PTYPE2:
  578         case ACPI_PTYPE2_PKG_COUNT:
  579         case ACPI_PTYPE2_REV_FIXED:
  580 
  581             /* Each subpackage has a fixed number of elements */
  582 
  583             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
  584             if (SubPackage->Package.Count < ExpectedCount)
  585             {
  586                 goto PackageTooSmall;
  587             }
  588 
  589             Status = AcpiNsCheckPackageElements (Info, SubElements,
  590                 Package->RetInfo.ObjectType1,
  591                 Package->RetInfo.Count1,
  592                 Package->RetInfo.ObjectType2,
  593                 Package->RetInfo.Count2, 0);
  594             if (ACPI_FAILURE (Status))
  595             {
  596                 return (Status);
  597             }
  598             break;
  599 
  600         case ACPI_PTYPE2_FIX_VAR:
  601             /*
  602              * Each subpackage has a fixed number of elements and an
  603              * optional element
  604              */
  605             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
  606             if (SubPackage->Package.Count < ExpectedCount)
  607             {
  608                 goto PackageTooSmall;
  609             }
  610 
  611             Status = AcpiNsCheckPackageElements (Info, SubElements,
  612                 Package->RetInfo.ObjectType1,
  613                 Package->RetInfo.Count1,
  614                 Package->RetInfo.ObjectType2,
  615                 SubPackage->Package.Count - Package->RetInfo.Count1, 0);
  616             if (ACPI_FAILURE (Status))
  617             {
  618                 return (Status);
  619             }
  620             break;
  621 
  622         case ACPI_PTYPE2_VAR_VAR:
  623             /*
  624              * Each subpackage has a fixed or variable number of elements
  625              */
  626             break;
  627 
  628         case ACPI_PTYPE2_FIXED:
  629 
  630             /* Each subpackage has a fixed length */
  631 
  632             ExpectedCount = Package->RetInfo2.Count;
  633             if (SubPackage->Package.Count < ExpectedCount)
  634             {
  635                 goto PackageTooSmall;
  636             }
  637 
  638             /* Check the type of each subpackage element */
  639 
  640             for (j = 0; j < ExpectedCount; j++)
  641             {
  642                 Status = AcpiNsCheckObjectType (Info, &SubElements[j],
  643                     Package->RetInfo2.ObjectType[j], j);
  644                 if (ACPI_FAILURE (Status))
  645                 {
  646                     return (Status);
  647                 }
  648             }
  649             break;
  650 
  651         case ACPI_PTYPE2_MIN:
  652 
  653             /* Each subpackage has a variable but minimum length */
  654 
  655             ExpectedCount = Package->RetInfo.Count1;
  656             if (SubPackage->Package.Count < ExpectedCount)
  657             {
  658                 goto PackageTooSmall;
  659             }
  660 
  661             /* Check the type of each subpackage element */
  662 
  663             Status = AcpiNsCheckPackageElements (Info, SubElements,
  664                 Package->RetInfo.ObjectType1,
  665                 SubPackage->Package.Count, 0, 0, 0);
  666             if (ACPI_FAILURE (Status))
  667             {
  668                 return (Status);
  669             }
  670             break;
  671 
  672         case ACPI_PTYPE2_COUNT:
  673             /*
  674              * First element is the (Integer) count of elements, including
  675              * the count field (the ACPI name is NumElements)
  676              */
  677             Status = AcpiNsCheckObjectType (Info, SubElements,
  678                 ACPI_RTYPE_INTEGER, 0);
  679             if (ACPI_FAILURE (Status))
  680             {
  681                 return (Status);
  682             }
  683 
  684             /*
  685              * Make sure package is large enough for the Count and is
  686              * is as large as the minimum size
  687              */
  688             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
  689             if (SubPackage->Package.Count < ExpectedCount)
  690             {
  691                 goto PackageTooSmall;
  692             }
  693 
  694             if (SubPackage->Package.Count < Package->RetInfo.Count1)
  695             {
  696                 ExpectedCount = Package->RetInfo.Count1;
  697                 goto PackageTooSmall;
  698             }
  699 
  700             if (ExpectedCount == 0)
  701             {
  702                 /*
  703                  * Either the NumEntries element was originally zero or it was
  704                  * a NULL element and repaired to an Integer of value zero.
  705                  * In either case, repair it by setting NumEntries to be the
  706                  * actual size of the subpackage.
  707                  */
  708                 ExpectedCount = SubPackage->Package.Count;
  709                 (*SubElements)->Integer.Value = ExpectedCount;
  710             }
  711 
  712             /* Check the type of each subpackage element */
  713 
  714             Status = AcpiNsCheckPackageElements (Info, (SubElements + 1),
  715                 Package->RetInfo.ObjectType1,
  716                 (ExpectedCount - 1), 0, 0, 1);
  717             if (ACPI_FAILURE (Status))
  718             {
  719                 return (Status);
  720             }
  721             break;
  722 
  723         default: /* Should not get here, type was validated by caller */
  724 
  725             ACPI_ERROR ((AE_INFO, "Invalid Package type: %X",
  726                 Package->RetInfo.Type));
  727             return (AE_AML_INTERNAL);
  728         }
  729 
  730         Elements++;
  731     }
  732 
  733     return (AE_OK);
  734 
  735 
  736 PackageTooSmall:
  737 
  738     /* The subpackage count was smaller than required */
  739 
  740     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
  741         "Return SubPackage[%u] is too small - found %u elements, expected %u",
  742         i, SubPackage->Package.Count, ExpectedCount));
  743 
  744     return (AE_AML_OPERAND_VALUE);
  745 }
  746 
  747 
  748 /*******************************************************************************
  749  *
  750  * FUNCTION:    AcpiNsCustomPackage
  751  *
  752  * PARAMETERS:  Info                - Method execution information block
  753  *              Elements            - Pointer to the package elements array
  754  *              Count               - Element count for the package
  755  *
  756  * RETURN:      Status
  757  *
  758  * DESCRIPTION: Check a returned package object for the correct count and
  759  *              correct type of all sub-objects.
  760  *
  761  * NOTE: Currently used for the _BIX method only. When needed for two or more
  762  * methods, probably a detect/dispatch mechanism will be required.
  763  *
  764  ******************************************************************************/
  765 
  766 static ACPI_STATUS
  767 AcpiNsCustomPackage (
  768     ACPI_EVALUATE_INFO          *Info,
  769     ACPI_OPERAND_OBJECT         **Elements,
  770     UINT32                      Count)
  771 {
  772     UINT32                      ExpectedCount;
  773     UINT32                      Version;
  774     ACPI_STATUS                 Status = AE_OK;
  775 
  776 
  777     ACPI_FUNCTION_NAME (NsCustomPackage);
  778 
  779 
  780     /* Get version number, must be Integer */
  781 
  782     if ((*Elements)->Common.Type != ACPI_TYPE_INTEGER)
  783     {
  784         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
  785             "Return Package has invalid object type for version number"));
  786         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  787     }
  788 
  789     Version = (UINT32) (*Elements)->Integer.Value;
  790     ExpectedCount = 21;         /* Version 1 */
  791 
  792     if (Version == 0)
  793     {
  794         ExpectedCount = 20;     /* Version 0 */
  795     }
  796 
  797     if (Count < ExpectedCount)
  798     {
  799         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
  800             "Return Package is too small - found %u elements, expected %u",
  801             Count, ExpectedCount));
  802         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
  803     }
  804     else if (Count > ExpectedCount)
  805     {
  806         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  807             "%s: Return Package is larger than needed - "
  808             "found %u, expected %u\n",
  809             Info->FullPathname, Count, ExpectedCount));
  810     }
  811 
  812     /* Validate all elements of the returned package */
  813 
  814     Status = AcpiNsCheckPackageElements (Info, Elements,
  815         ACPI_RTYPE_INTEGER, 16,
  816         ACPI_RTYPE_STRING, 4, 0);
  817     if (ACPI_FAILURE (Status))
  818     {
  819         return_ACPI_STATUS (Status);
  820     }
  821 
  822     /* Version 1 has a single trailing integer */
  823 
  824     if (Version > 0)
  825     {
  826         Status = AcpiNsCheckPackageElements (Info, Elements + 20,
  827             ACPI_RTYPE_INTEGER, 1, 0, 0, 20);
  828     }
  829 
  830     return_ACPI_STATUS (Status);
  831 }
  832 
  833 
  834 /*******************************************************************************
  835  *
  836  * FUNCTION:    AcpiNsCheckPackageElements
  837  *
  838  * PARAMETERS:  Info            - Method execution information block
  839  *              Elements        - Pointer to the package elements array
  840  *              Type1           - Object type for first group
  841  *              Count1          - Count for first group
  842  *              Type2           - Object type for second group
  843  *              Count2          - Count for second group
  844  *              StartIndex      - Start of the first group of elements
  845  *
  846  * RETURN:      Status
  847  *
  848  * DESCRIPTION: Check that all elements of a package are of the correct object
  849  *              type. Supports up to two groups of different object types.
  850  *
  851  ******************************************************************************/
  852 
  853 static ACPI_STATUS
  854 AcpiNsCheckPackageElements (
  855     ACPI_EVALUATE_INFO          *Info,
  856     ACPI_OPERAND_OBJECT         **Elements,
  857     UINT8                       Type1,
  858     UINT32                      Count1,
  859     UINT8                       Type2,
  860     UINT32                      Count2,
  861     UINT32                      StartIndex)
  862 {
  863     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
  864     ACPI_STATUS                 Status;
  865     UINT32                      i;
  866 
  867 
  868     ACPI_FUNCTION_TRACE (NsCheckPackageElements);
  869 
  870     /*
  871      * Up to two groups of package elements are supported by the data
  872      * structure. All elements in each group must be of the same type.
  873      * The second group can have a count of zero.
  874      */
  875     for (i = 0; i < Count1; i++)
  876     {
  877         Status = AcpiNsCheckObjectType (Info, ThisElement,
  878             Type1, i + StartIndex);
  879         if (ACPI_FAILURE (Status))
  880         {
  881             return_ACPI_STATUS (Status);
  882         }
  883 
  884         ThisElement++;
  885     }
  886 
  887     for (i = 0; i < Count2; i++)
  888     {
  889         Status = AcpiNsCheckObjectType (Info, ThisElement,
  890             Type2, (i + Count1 + StartIndex));
  891         if (ACPI_FAILURE (Status))
  892         {
  893             return_ACPI_STATUS (Status);
  894         }
  895 
  896         ThisElement++;
  897     }
  898 
  899     return_ACPI_STATUS (AE_OK);
  900 }

Cache object: 1e391ca85368e9aff7bf524d42324e29


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.