--- /dev/null	ven. janv. 17 07:30:27 2014
+++ new/usr/src/common/acpica/components/namespace/nsprepkg.c	ven. janv. 17 07:30:27 2014
@@ -0,0 +1,631 @@
+/******************************************************************************
+ *
+ * Module Name: nsprepkg - Validation of package objects for predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acpredef.h"
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+        ACPI_MODULE_NAME    ("nsprepkg")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiNsCheckPackageList (
+    ACPI_EVALUATE_INFO          *Info,
+    const ACPI_PREDEFINED_INFO  *Package,
+    ACPI_OPERAND_OBJECT         **Elements,
+    UINT32                      Count);
+
+static ACPI_STATUS
+AcpiNsCheckPackageElements (
+    ACPI_EVALUATE_INFO          *Info,
+    ACPI_OPERAND_OBJECT         **Elements,
+    UINT8                       Type1,
+    UINT32                      Count1,
+    UINT8                       Type2,
+    UINT32                      Count2,
+    UINT32                      StartIndex);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiNsCheckPackage
+ *
+ * PARAMETERS:  Info                - Method execution information block
+ *              ReturnObjectPtr     - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check a returned package object for the correct count and
+ *              correct type of all sub-objects.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsCheckPackage (
+    ACPI_EVALUATE_INFO          *Info,
+    ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
+{
+    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
+    const ACPI_PREDEFINED_INFO  *Package;
+    ACPI_OPERAND_OBJECT         **Elements;
+    ACPI_STATUS                 Status = AE_OK;
+    UINT32                      ExpectedCount;
+    UINT32                      Count;
+    UINT32                      i;
+
+
+    ACPI_FUNCTION_NAME (NsCheckPackage);
+
+
+    /* The package info for this name is in the next table entry */
+
+    Package = Info->Predefined + 1;
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+        "%s Validating return Package of Type %X, Count %X\n",
+        Info->FullPathname, Package->RetInfo.Type,
+        ReturnObject->Package.Count));
+
+    /*
+     * For variable-length Packages, we can safely remove all embedded
+     * and trailing NULL package elements
+     */
+    AcpiNsRemoveNullElements (Info, Package->RetInfo.Type, ReturnObject);
+
+    /* Extract package count and elements array */
+
+    Elements = ReturnObject->Package.Elements;
+    Count = ReturnObject->Package.Count;
+
+    /*
+     * Most packages must have at least one element. The only exception
+     * is the variable-length package (ACPI_PTYPE1_VAR).
+     */
+    if (!Count)
+    {
+        if (Package->RetInfo.Type == ACPI_PTYPE1_VAR)
+        {
+            return (AE_OK);
+        }
+
+        ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+            "Return Package has no elements (empty)"));
+
+        return (AE_AML_OPERAND_VALUE);
+    }
+
+    /*
+     * Decode the type of the expected package contents
+     *
+     * PTYPE1 packages contain no subpackages
+     * PTYPE2 packages contain sub-packages
+     */
+    switch (Package->RetInfo.Type)
+    {
+    case ACPI_PTYPE1_FIXED:
+        /*
+         * The package count is fixed and there are no sub-packages
+         *
+         * If package is too small, exit.
+         * If package is larger than expected, issue warning but continue
+         */
+        ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+        if (Count < ExpectedCount)
+        {
+            goto PackageTooSmall;
+        }
+        else if (Count > ExpectedCount)
+        {
+            ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+                "%s: Return Package is larger than needed - "
+                "found %u, expected %u\n",
+                Info->FullPathname, Count, ExpectedCount));
+        }
+
+        /* Validate all elements of the returned package */
+
+        Status = AcpiNsCheckPackageElements (Info, Elements,
+                    Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
+                    Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
+        break;
+
+    case ACPI_PTYPE1_VAR:
+        /*
+         * The package count is variable, there are no sub-packages, and all
+         * elements must be of the same type
+         */
+        for (i = 0; i < Count; i++)
+        {
+            Status = AcpiNsCheckObjectType (Info, Elements,
+                        Package->RetInfo.ObjectType1, i);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+            Elements++;
+        }
+        break;
+
+    case ACPI_PTYPE1_OPTION:
+        /*
+         * The package count is variable, there are no sub-packages. There are
+         * a fixed number of required elements, and a variable number of
+         * optional elements.
+         *
+         * Check if package is at least as large as the minimum required
+         */
+        ExpectedCount = Package->RetInfo3.Count;
+        if (Count < ExpectedCount)
+        {
+            goto PackageTooSmall;
+        }
+
+        /* Variable number of sub-objects */
+
+        for (i = 0; i < Count; i++)
+        {
+            if (i < Package->RetInfo3.Count)
+            {
+                /* These are the required package elements (0, 1, or 2) */
+
+                Status = AcpiNsCheckObjectType (Info, Elements,
+                            Package->RetInfo3.ObjectType[i], i);
+                if (ACPI_FAILURE (Status))
+                {
+                    return (Status);
+                }
+            }
+            else
+            {
+                /* These are the optional package elements */
+
+                Status = AcpiNsCheckObjectType (Info, Elements,
+                            Package->RetInfo3.TailObjectType, i);
+                if (ACPI_FAILURE (Status))
+                {
+                    return (Status);
+                }
+            }
+            Elements++;
+        }
+        break;
+
+    case ACPI_PTYPE2_REV_FIXED:
+
+        /* First element is the (Integer) revision */
+
+        Status = AcpiNsCheckObjectType (Info, Elements,
+                    ACPI_RTYPE_INTEGER, 0);
+        if (ACPI_FAILURE (Status))
+        {
+            return (Status);
+        }
+
+        Elements++;
+        Count--;
+
+        /* Examine the sub-packages */
+
+        Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
+        break;
+
+    case ACPI_PTYPE2_PKG_COUNT:
+
+        /* First element is the (Integer) count of sub-packages to follow */
+
+        Status = AcpiNsCheckObjectType (Info, Elements,
+                    ACPI_RTYPE_INTEGER, 0);
+        if (ACPI_FAILURE (Status))
+        {
+            return (Status);
+        }
+
+        /*
+         * Count cannot be larger than the parent package length, but allow it
+         * to be smaller. The >= accounts for the Integer above.
+         */
+        ExpectedCount = (UINT32) (*Elements)->Integer.Value;
+        if (ExpectedCount >= Count)
+        {
+            goto PackageTooSmall;
+        }
+
+        Count = ExpectedCount;
+        Elements++;
+
+        /* Examine the sub-packages */
+
+        Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
+        break;
+
+    case ACPI_PTYPE2:
+    case ACPI_PTYPE2_FIXED:
+    case ACPI_PTYPE2_MIN:
+    case ACPI_PTYPE2_COUNT:
+    case ACPI_PTYPE2_FIX_VAR:
+        /*
+         * These types all return a single Package that consists of a
+         * variable number of sub-Packages.
+         *
+         * First, ensure that the first element is a sub-Package. If not,
+         * the BIOS may have incorrectly returned the object as a single
+         * package instead of a Package of Packages (a common error if
+         * there is only one entry). We may be able to repair this by
+         * wrapping the returned Package with a new outer Package.
+         */
+        if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
+        {
+            /* Create the new outer package and populate it */
+
+            Status = AcpiNsWrapWithPackage (Info, ReturnObject, ReturnObjectPtr);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+
+            /* Update locals to point to the new package (of 1 element) */
+
+            ReturnObject = *ReturnObjectPtr;
+            Elements = ReturnObject->Package.Elements;
+            Count = 1;
+        }
+
+        /* Examine the sub-packages */
+
+        Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
+        break;
+
+    default:
+
+        /* Should not get here if predefined info table is correct */
+
+        ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+            "Invalid internal return type in table entry: %X",
+            Package->RetInfo.Type));
+
+        return (AE_AML_INTERNAL);
+    }
+
+    return (Status);
+
+
+PackageTooSmall:
+
+    /* Error exit for the case with an incorrect package count */
+
+    ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+        "Return Package is too small - found %u elements, expected %u",
+        Count, ExpectedCount));
+
+    return (AE_AML_OPERAND_VALUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiNsCheckPackageList
+ *
+ * PARAMETERS:  Info            - Method execution information block
+ *              Package         - Pointer to package-specific info for method
+ *              Elements        - Element list of parent package. All elements
+ *                                of this list should be of type Package.
+ *              Count           - Count of subpackages
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Examine a list of subpackages
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsCheckPackageList (
+    ACPI_EVALUATE_INFO          *Info,
+    const ACPI_PREDEFINED_INFO  *Package,
+    ACPI_OPERAND_OBJECT         **Elements,
+    UINT32                      Count)
+{
+    ACPI_OPERAND_OBJECT         *SubPackage;
+    ACPI_OPERAND_OBJECT         **SubElements;
+    ACPI_STATUS                 Status;
+    UINT32                      ExpectedCount;
+    UINT32                      i;
+    UINT32                      j;
+
+
+    /*
+     * Validate each sub-Package in the parent Package
+     *
+     * NOTE: assumes list of sub-packages contains no NULL elements.
+     * Any NULL elements should have been removed by earlier call
+     * to AcpiNsRemoveNullElements.
+     */
+    for (i = 0; i < Count; i++)
+    {
+        SubPackage = *Elements;
+        SubElements = SubPackage->Package.Elements;
+        Info->ParentPackage = SubPackage;
+
+        /* Each sub-object must be of type Package */
+
+        Status = AcpiNsCheckObjectType (Info, &SubPackage,
+                    ACPI_RTYPE_PACKAGE, i);
+        if (ACPI_FAILURE (Status))
+        {
+            return (Status);
+        }
+
+        /* Examine the different types of expected sub-packages */
+
+        Info->ParentPackage = SubPackage;
+        switch (Package->RetInfo.Type)
+        {
+        case ACPI_PTYPE2:
+        case ACPI_PTYPE2_PKG_COUNT:
+        case ACPI_PTYPE2_REV_FIXED:
+
+            /* Each subpackage has a fixed number of elements */
+
+            ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+            if (SubPackage->Package.Count < ExpectedCount)
+            {
+                goto PackageTooSmall;
+            }
+
+            Status = AcpiNsCheckPackageElements (Info, SubElements,
+                        Package->RetInfo.ObjectType1,
+                        Package->RetInfo.Count1,
+                        Package->RetInfo.ObjectType2,
+                        Package->RetInfo.Count2, 0);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+            break;
+
+        case ACPI_PTYPE2_FIX_VAR:
+            /*
+             * Each subpackage has a fixed number of elements and an
+             * optional element
+             */
+            ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+            if (SubPackage->Package.Count < ExpectedCount)
+            {
+                goto PackageTooSmall;
+            }
+
+            Status = AcpiNsCheckPackageElements (Info, SubElements,
+                        Package->RetInfo.ObjectType1,
+                        Package->RetInfo.Count1,
+                        Package->RetInfo.ObjectType2,
+                        SubPackage->Package.Count - Package->RetInfo.Count1, 0);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+            break;
+
+        case ACPI_PTYPE2_FIXED:
+
+            /* Each sub-package has a fixed length */
+
+            ExpectedCount = Package->RetInfo2.Count;
+            if (SubPackage->Package.Count < ExpectedCount)
+            {
+                goto PackageTooSmall;
+            }
+
+            /* Check the type of each sub-package element */
+
+            for (j = 0; j < ExpectedCount; j++)
+            {
+                Status = AcpiNsCheckObjectType (Info, &SubElements[j],
+                            Package->RetInfo2.ObjectType[j], j);
+                if (ACPI_FAILURE (Status))
+                {
+                    return (Status);
+                }
+            }
+            break;
+
+        case ACPI_PTYPE2_MIN:
+
+            /* Each sub-package has a variable but minimum length */
+
+            ExpectedCount = Package->RetInfo.Count1;
+            if (SubPackage->Package.Count < ExpectedCount)
+            {
+                goto PackageTooSmall;
+            }
+
+            /* Check the type of each sub-package element */
+
+            Status = AcpiNsCheckPackageElements (Info, SubElements,
+                        Package->RetInfo.ObjectType1,
+                        SubPackage->Package.Count, 0, 0, 0);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+            break;
+
+        case ACPI_PTYPE2_COUNT:
+            /*
+             * First element is the (Integer) count of elements, including
+             * the count field (the ACPI name is NumElements)
+             */
+            Status = AcpiNsCheckObjectType (Info, SubElements,
+                        ACPI_RTYPE_INTEGER, 0);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+
+            /*
+             * Make sure package is large enough for the Count and is
+             * is as large as the minimum size
+             */
+            ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
+            if (SubPackage->Package.Count < ExpectedCount)
+            {
+                goto PackageTooSmall;
+            }
+            if (SubPackage->Package.Count < Package->RetInfo.Count1)
+            {
+                ExpectedCount = Package->RetInfo.Count1;
+                goto PackageTooSmall;
+            }
+            if (ExpectedCount == 0)
+            {
+                /*
+                 * Either the NumEntries element was originally zero or it was
+                 * a NULL element and repaired to an Integer of value zero.
+                 * In either case, repair it by setting NumEntries to be the
+                 * actual size of the subpackage.
+                 */
+                ExpectedCount = SubPackage->Package.Count;
+                (*SubElements)->Integer.Value = ExpectedCount;
+            }
+
+            /* Check the type of each sub-package element */
+
+            Status = AcpiNsCheckPackageElements (Info, (SubElements + 1),
+                        Package->RetInfo.ObjectType1,
+                        (ExpectedCount - 1), 0, 0, 1);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+            break;
+
+        default: /* Should not get here, type was validated by caller */
+
+            return (AE_AML_INTERNAL);
+        }
+
+        Elements++;
+    }
+
+    return (AE_OK);
+
+
+PackageTooSmall:
+
+    /* The sub-package count was smaller than required */
+
+    ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+        "Return Sub-Package[%u] is too small - found %u elements, expected %u",
+        i, SubPackage->Package.Count, ExpectedCount));
+
+    return (AE_AML_OPERAND_VALUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiNsCheckPackageElements
+ *
+ * PARAMETERS:  Info            - Method execution information block
+ *              Elements        - Pointer to the package elements array
+ *              Type1           - Object type for first group
+ *              Count1          - Count for first group
+ *              Type2           - Object type for second group
+ *              Count2          - Count for second group
+ *              StartIndex      - Start of the first group of elements
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check that all elements of a package are of the correct object
+ *              type. Supports up to two groups of different object types.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsCheckPackageElements (
+    ACPI_EVALUATE_INFO          *Info,
+    ACPI_OPERAND_OBJECT         **Elements,
+    UINT8                       Type1,
+    UINT32                      Count1,
+    UINT8                       Type2,
+    UINT32                      Count2,
+    UINT32                      StartIndex)
+{
+    ACPI_OPERAND_OBJECT         **ThisElement = Elements;
+    ACPI_STATUS                 Status;
+    UINT32                      i;
+
+
+    /*
+     * Up to two groups of package elements are supported by the data
+     * structure. All elements in each group must be of the same type.
+     * The second group can have a count of zero.
+     */
+    for (i = 0; i < Count1; i++)
+    {
+        Status = AcpiNsCheckObjectType (Info, ThisElement,
+                    Type1, i + StartIndex);
+        if (ACPI_FAILURE (Status))
+        {
+            return (Status);
+        }
+        ThisElement++;
+    }
+
+    for (i = 0; i < Count2; i++)
+    {
+        Status = AcpiNsCheckObjectType (Info, ThisElement,
+                    Type2, (i + Count1 + StartIndex));
+        if (ACPI_FAILURE (Status))
+        {
+            return (Status);
+        }
+        ThisElement++;
+    }
+
+    return (AE_OK);
+}
