1*9980SDana.Myers@Sun.COM /******************************************************************************
2*9980SDana.Myers@Sun.COM  *
3*9980SDana.Myers@Sun.COM  * Module Name: nspredef - Validation of ACPI predefined methods and objects
4*9980SDana.Myers@Sun.COM  *
5*9980SDana.Myers@Sun.COM  *****************************************************************************/
6*9980SDana.Myers@Sun.COM 
7*9980SDana.Myers@Sun.COM /******************************************************************************
8*9980SDana.Myers@Sun.COM  *
9*9980SDana.Myers@Sun.COM  * 1. Copyright Notice
10*9980SDana.Myers@Sun.COM  *
11*9980SDana.Myers@Sun.COM  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12*9980SDana.Myers@Sun.COM  * All rights reserved.
13*9980SDana.Myers@Sun.COM  *
14*9980SDana.Myers@Sun.COM  * 2. License
15*9980SDana.Myers@Sun.COM  *
16*9980SDana.Myers@Sun.COM  * 2.1. This is your license from Intel Corp. under its intellectual property
17*9980SDana.Myers@Sun.COM  * rights.  You may have additional license terms from the party that provided
18*9980SDana.Myers@Sun.COM  * you this software, covering your right to use that party's intellectual
19*9980SDana.Myers@Sun.COM  * property rights.
20*9980SDana.Myers@Sun.COM  *
21*9980SDana.Myers@Sun.COM  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22*9980SDana.Myers@Sun.COM  * copy of the source code appearing in this file ("Covered Code") an
23*9980SDana.Myers@Sun.COM  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24*9980SDana.Myers@Sun.COM  * base code distributed originally by Intel ("Original Intel Code") to copy,
25*9980SDana.Myers@Sun.COM  * make derivatives, distribute, use and display any portion of the Covered
26*9980SDana.Myers@Sun.COM  * Code in any form, with the right to sublicense such rights; and
27*9980SDana.Myers@Sun.COM  *
28*9980SDana.Myers@Sun.COM  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29*9980SDana.Myers@Sun.COM  * license (with the right to sublicense), under only those claims of Intel
30*9980SDana.Myers@Sun.COM  * patents that are infringed by the Original Intel Code, to make, use, sell,
31*9980SDana.Myers@Sun.COM  * offer to sell, and import the Covered Code and derivative works thereof
32*9980SDana.Myers@Sun.COM  * solely to the minimum extent necessary to exercise the above copyright
33*9980SDana.Myers@Sun.COM  * license, and in no event shall the patent license extend to any additions
34*9980SDana.Myers@Sun.COM  * to or modifications of the Original Intel Code.  No other license or right
35*9980SDana.Myers@Sun.COM  * is granted directly or by implication, estoppel or otherwise;
36*9980SDana.Myers@Sun.COM  *
37*9980SDana.Myers@Sun.COM  * The above copyright and patent license is granted only if the following
38*9980SDana.Myers@Sun.COM  * conditions are met:
39*9980SDana.Myers@Sun.COM  *
40*9980SDana.Myers@Sun.COM  * 3. Conditions
41*9980SDana.Myers@Sun.COM  *
42*9980SDana.Myers@Sun.COM  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43*9980SDana.Myers@Sun.COM  * Redistribution of source code of any substantial portion of the Covered
44*9980SDana.Myers@Sun.COM  * Code or modification with rights to further distribute source must include
45*9980SDana.Myers@Sun.COM  * the above Copyright Notice, the above License, this list of Conditions,
46*9980SDana.Myers@Sun.COM  * and the following Disclaimer and Export Compliance provision.  In addition,
47*9980SDana.Myers@Sun.COM  * Licensee must cause all Covered Code to which Licensee contributes to
48*9980SDana.Myers@Sun.COM  * contain a file documenting the changes Licensee made to create that Covered
49*9980SDana.Myers@Sun.COM  * Code and the date of any change.  Licensee must include in that file the
50*9980SDana.Myers@Sun.COM  * documentation of any changes made by any predecessor Licensee.  Licensee
51*9980SDana.Myers@Sun.COM  * must include a prominent statement that the modification is derived,
52*9980SDana.Myers@Sun.COM  * directly or indirectly, from Original Intel Code.
53*9980SDana.Myers@Sun.COM  *
54*9980SDana.Myers@Sun.COM  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55*9980SDana.Myers@Sun.COM  * Redistribution of source code of any substantial portion of the Covered
56*9980SDana.Myers@Sun.COM  * Code or modification without rights to further distribute source must
57*9980SDana.Myers@Sun.COM  * include the following Disclaimer and Export Compliance provision in the
58*9980SDana.Myers@Sun.COM  * documentation and/or other materials provided with distribution.  In
59*9980SDana.Myers@Sun.COM  * addition, Licensee may not authorize further sublicense of source of any
60*9980SDana.Myers@Sun.COM  * portion of the Covered Code, and must include terms to the effect that the
61*9980SDana.Myers@Sun.COM  * license from Licensee to its licensee is limited to the intellectual
62*9980SDana.Myers@Sun.COM  * property embodied in the software Licensee provides to its licensee, and
63*9980SDana.Myers@Sun.COM  * not to intellectual property embodied in modifications its licensee may
64*9980SDana.Myers@Sun.COM  * make.
65*9980SDana.Myers@Sun.COM  *
66*9980SDana.Myers@Sun.COM  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67*9980SDana.Myers@Sun.COM  * substantial portion of the Covered Code or modification must reproduce the
68*9980SDana.Myers@Sun.COM  * above Copyright Notice, and the following Disclaimer and Export Compliance
69*9980SDana.Myers@Sun.COM  * provision in the documentation and/or other materials provided with the
70*9980SDana.Myers@Sun.COM  * distribution.
71*9980SDana.Myers@Sun.COM  *
72*9980SDana.Myers@Sun.COM  * 3.4. Intel retains all right, title, and interest in and to the Original
73*9980SDana.Myers@Sun.COM  * Intel Code.
74*9980SDana.Myers@Sun.COM  *
75*9980SDana.Myers@Sun.COM  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76*9980SDana.Myers@Sun.COM  * Intel shall be used in advertising or otherwise to promote the sale, use or
77*9980SDana.Myers@Sun.COM  * other dealings in products derived from or relating to the Covered Code
78*9980SDana.Myers@Sun.COM  * without prior written authorization from Intel.
79*9980SDana.Myers@Sun.COM  *
80*9980SDana.Myers@Sun.COM  * 4. Disclaimer and Export Compliance
81*9980SDana.Myers@Sun.COM  *
82*9980SDana.Myers@Sun.COM  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83*9980SDana.Myers@Sun.COM  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84*9980SDana.Myers@Sun.COM  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85*9980SDana.Myers@Sun.COM  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86*9980SDana.Myers@Sun.COM  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87*9980SDana.Myers@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88*9980SDana.Myers@Sun.COM  * PARTICULAR PURPOSE.
89*9980SDana.Myers@Sun.COM  *
90*9980SDana.Myers@Sun.COM  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91*9980SDana.Myers@Sun.COM  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92*9980SDana.Myers@Sun.COM  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93*9980SDana.Myers@Sun.COM  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94*9980SDana.Myers@Sun.COM  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95*9980SDana.Myers@Sun.COM  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96*9980SDana.Myers@Sun.COM  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97*9980SDana.Myers@Sun.COM  * LIMITED REMEDY.
98*9980SDana.Myers@Sun.COM  *
99*9980SDana.Myers@Sun.COM  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100*9980SDana.Myers@Sun.COM  * software or system incorporating such software without first obtaining any
101*9980SDana.Myers@Sun.COM  * required license or other approval from the U. S. Department of Commerce or
102*9980SDana.Myers@Sun.COM  * any other agency or department of the United States Government.  In the
103*9980SDana.Myers@Sun.COM  * event Licensee exports any such software from the United States or
104*9980SDana.Myers@Sun.COM  * re-exports any such software from a foreign destination, Licensee shall
105*9980SDana.Myers@Sun.COM  * ensure that the distribution and export/re-export of the software is in
106*9980SDana.Myers@Sun.COM  * compliance with all laws, regulations, orders, or other restrictions of the
107*9980SDana.Myers@Sun.COM  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108*9980SDana.Myers@Sun.COM  * any of its subsidiaries will export/re-export any technical data, process,
109*9980SDana.Myers@Sun.COM  * software, or service, directly or indirectly, to any country for which the
110*9980SDana.Myers@Sun.COM  * United States government or any agency thereof requires an export license,
111*9980SDana.Myers@Sun.COM  * other governmental approval, or letter of assurance, without first obtaining
112*9980SDana.Myers@Sun.COM  * such license, approval or letter.
113*9980SDana.Myers@Sun.COM  *
114*9980SDana.Myers@Sun.COM  *****************************************************************************/
115*9980SDana.Myers@Sun.COM 
116*9980SDana.Myers@Sun.COM #define __NSPREDEF_C__
117*9980SDana.Myers@Sun.COM 
118*9980SDana.Myers@Sun.COM #include "acpi.h"
119*9980SDana.Myers@Sun.COM #include "accommon.h"
120*9980SDana.Myers@Sun.COM #include "acnamesp.h"
121*9980SDana.Myers@Sun.COM #include "acpredef.h"
122*9980SDana.Myers@Sun.COM 
123*9980SDana.Myers@Sun.COM 
124*9980SDana.Myers@Sun.COM #define _COMPONENT          ACPI_NAMESPACE
125*9980SDana.Myers@Sun.COM         ACPI_MODULE_NAME    ("nspredef")
126*9980SDana.Myers@Sun.COM 
127*9980SDana.Myers@Sun.COM 
128*9980SDana.Myers@Sun.COM /*******************************************************************************
129*9980SDana.Myers@Sun.COM  *
130*9980SDana.Myers@Sun.COM  * This module validates predefined ACPI objects that appear in the namespace,
131*9980SDana.Myers@Sun.COM  * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
132*9980SDana.Myers@Sun.COM  * validation is to detect problems with BIOS-exposed predefined ACPI objects
133*9980SDana.Myers@Sun.COM  * before the results are returned to the ACPI-related drivers.
134*9980SDana.Myers@Sun.COM  *
135*9980SDana.Myers@Sun.COM  * There are several areas that are validated:
136*9980SDana.Myers@Sun.COM  *
137*9980SDana.Myers@Sun.COM  *  1) The number of input arguments as defined by the method/object in the
138*9980SDana.Myers@Sun.COM  *      ASL is validated against the ACPI specification.
139*9980SDana.Myers@Sun.COM  *  2) The type of the return object (if any) is validated against the ACPI
140*9980SDana.Myers@Sun.COM  *      specification.
141*9980SDana.Myers@Sun.COM  *  3) For returned package objects, the count of package elements is
142*9980SDana.Myers@Sun.COM  *      validated, as well as the type of each package element. Nested
143*9980SDana.Myers@Sun.COM  *      packages are supported.
144*9980SDana.Myers@Sun.COM  *
145*9980SDana.Myers@Sun.COM  * For any problems found, a warning message is issued.
146*9980SDana.Myers@Sun.COM  *
147*9980SDana.Myers@Sun.COM  ******************************************************************************/
148*9980SDana.Myers@Sun.COM 
149*9980SDana.Myers@Sun.COM /* Local prototypes */
150*9980SDana.Myers@Sun.COM 
151*9980SDana.Myers@Sun.COM static ACPI_STATUS
152*9980SDana.Myers@Sun.COM AcpiNsCheckPackage (
153*9980SDana.Myers@Sun.COM     char                        *Pathname,
154*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
155*9980SDana.Myers@Sun.COM     const ACPI_PREDEFINED_INFO  *Predefined);
156*9980SDana.Myers@Sun.COM 
157*9980SDana.Myers@Sun.COM static ACPI_STATUS
158*9980SDana.Myers@Sun.COM AcpiNsCheckPackageElements (
159*9980SDana.Myers@Sun.COM     char                        *Pathname,
160*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **Elements,
161*9980SDana.Myers@Sun.COM     UINT8                       Type1,
162*9980SDana.Myers@Sun.COM     UINT32                      Count1,
163*9980SDana.Myers@Sun.COM     UINT8                       Type2,
164*9980SDana.Myers@Sun.COM     UINT32                      Count2,
165*9980SDana.Myers@Sun.COM     UINT32                      StartIndex);
166*9980SDana.Myers@Sun.COM 
167*9980SDana.Myers@Sun.COM static ACPI_STATUS
168*9980SDana.Myers@Sun.COM AcpiNsCheckObjectType (
169*9980SDana.Myers@Sun.COM     char                        *Pathname,
170*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
171*9980SDana.Myers@Sun.COM     UINT32                      ExpectedBtypes,
172*9980SDana.Myers@Sun.COM     UINT32                      PackageIndex);
173*9980SDana.Myers@Sun.COM 
174*9980SDana.Myers@Sun.COM static ACPI_STATUS
175*9980SDana.Myers@Sun.COM AcpiNsCheckReference (
176*9980SDana.Myers@Sun.COM     char                        *Pathname,
177*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *ReturnObject);
178*9980SDana.Myers@Sun.COM 
179*9980SDana.Myers@Sun.COM static ACPI_STATUS
180*9980SDana.Myers@Sun.COM AcpiNsRepairObject (
181*9980SDana.Myers@Sun.COM     UINT32                      ExpectedBtypes,
182*9980SDana.Myers@Sun.COM     UINT32                      PackageIndex,
183*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
184*9980SDana.Myers@Sun.COM 
185*9980SDana.Myers@Sun.COM /*
186*9980SDana.Myers@Sun.COM  * Names for the types that can be returned by the predefined objects.
187*9980SDana.Myers@Sun.COM  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
188*9980SDana.Myers@Sun.COM  */
189*9980SDana.Myers@Sun.COM static const char   *AcpiRtypeNames[] =
190*9980SDana.Myers@Sun.COM {
191*9980SDana.Myers@Sun.COM     "/Integer",
192*9980SDana.Myers@Sun.COM     "/String",
193*9980SDana.Myers@Sun.COM     "/Buffer",
194*9980SDana.Myers@Sun.COM     "/Package",
195*9980SDana.Myers@Sun.COM     "/Reference",
196*9980SDana.Myers@Sun.COM };
197*9980SDana.Myers@Sun.COM 
198*9980SDana.Myers@Sun.COM #define ACPI_NOT_PACKAGE    ACPI_UINT32_MAX
199*9980SDana.Myers@Sun.COM 
200*9980SDana.Myers@Sun.COM 
201*9980SDana.Myers@Sun.COM /*******************************************************************************
202*9980SDana.Myers@Sun.COM  *
203*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCheckPredefinedNames
204*9980SDana.Myers@Sun.COM  *
205*9980SDana.Myers@Sun.COM  * PARAMETERS:  Node            - Namespace node for the method/object
206*9980SDana.Myers@Sun.COM  *              ReturnObjectPtr - Pointer to the object returned from the
207*9980SDana.Myers@Sun.COM  *                                evaluation of a method or object
208*9980SDana.Myers@Sun.COM  *
209*9980SDana.Myers@Sun.COM  * RETURN:      Status
210*9980SDana.Myers@Sun.COM  *
211*9980SDana.Myers@Sun.COM  * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
212*9980SDana.Myers@Sun.COM  *
213*9980SDana.Myers@Sun.COM  ******************************************************************************/
214*9980SDana.Myers@Sun.COM 
215*9980SDana.Myers@Sun.COM ACPI_STATUS
216*9980SDana.Myers@Sun.COM AcpiNsCheckPredefinedNames (
217*9980SDana.Myers@Sun.COM     ACPI_NAMESPACE_NODE         *Node,
218*9980SDana.Myers@Sun.COM     UINT32                      UserParamCount,
219*9980SDana.Myers@Sun.COM     ACPI_STATUS                 ReturnStatus,
220*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
221*9980SDana.Myers@Sun.COM {
222*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
223*9980SDana.Myers@Sun.COM     ACPI_STATUS                 Status = AE_OK;
224*9980SDana.Myers@Sun.COM     const ACPI_PREDEFINED_INFO  *Predefined;
225*9980SDana.Myers@Sun.COM     char                        *Pathname;
226*9980SDana.Myers@Sun.COM 
227*9980SDana.Myers@Sun.COM 
228*9980SDana.Myers@Sun.COM     /* Match the name for this method/object against the predefined list */
229*9980SDana.Myers@Sun.COM 
230*9980SDana.Myers@Sun.COM     Predefined = AcpiNsCheckForPredefinedName (Node);
231*9980SDana.Myers@Sun.COM 
232*9980SDana.Myers@Sun.COM     /* Get the full pathname to the object, for use in error messages */
233*9980SDana.Myers@Sun.COM 
234*9980SDana.Myers@Sun.COM     Pathname = AcpiNsGetExternalPathname (Node);
235*9980SDana.Myers@Sun.COM     if (!Pathname)
236*9980SDana.Myers@Sun.COM     {
237*9980SDana.Myers@Sun.COM         return (AE_OK); /* Could not get pathname, ignore */
238*9980SDana.Myers@Sun.COM     }
239*9980SDana.Myers@Sun.COM 
240*9980SDana.Myers@Sun.COM     /*
241*9980SDana.Myers@Sun.COM      * Check that the parameter count for this method matches the ASL
242*9980SDana.Myers@Sun.COM      * definition. For predefined names, ensure that both the caller and
243*9980SDana.Myers@Sun.COM      * the method itself are in accordance with the ACPI specification.
244*9980SDana.Myers@Sun.COM      */
245*9980SDana.Myers@Sun.COM     AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
246*9980SDana.Myers@Sun.COM 
247*9980SDana.Myers@Sun.COM     /* If not a predefined name, we cannot validate the return object */
248*9980SDana.Myers@Sun.COM 
249*9980SDana.Myers@Sun.COM     if (!Predefined)
250*9980SDana.Myers@Sun.COM     {
251*9980SDana.Myers@Sun.COM         goto Exit;
252*9980SDana.Myers@Sun.COM     }
253*9980SDana.Myers@Sun.COM 
254*9980SDana.Myers@Sun.COM     /* If the method failed, we cannot validate the return object */
255*9980SDana.Myers@Sun.COM 
256*9980SDana.Myers@Sun.COM     if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
257*9980SDana.Myers@Sun.COM     {
258*9980SDana.Myers@Sun.COM         goto Exit;
259*9980SDana.Myers@Sun.COM     }
260*9980SDana.Myers@Sun.COM 
261*9980SDana.Myers@Sun.COM     /*
262*9980SDana.Myers@Sun.COM      * Only validate the return value on the first successful evaluation of
263*9980SDana.Myers@Sun.COM      * the method. This ensures that any warnings will only be emitted during
264*9980SDana.Myers@Sun.COM      * the very first evaluation of the method/object.
265*9980SDana.Myers@Sun.COM      */
266*9980SDana.Myers@Sun.COM     if (Node->Flags & ANOBJ_EVALUATED)
267*9980SDana.Myers@Sun.COM     {
268*9980SDana.Myers@Sun.COM         goto Exit;
269*9980SDana.Myers@Sun.COM     }
270*9980SDana.Myers@Sun.COM 
271*9980SDana.Myers@Sun.COM     /* Mark the node as having been successfully evaluated */
272*9980SDana.Myers@Sun.COM 
273*9980SDana.Myers@Sun.COM     Node->Flags |= ANOBJ_EVALUATED;
274*9980SDana.Myers@Sun.COM 
275*9980SDana.Myers@Sun.COM     /*
276*9980SDana.Myers@Sun.COM      * If there is no return value, check if we require a return value for
277*9980SDana.Myers@Sun.COM      * this predefined name. Either one return value is expected, or none,
278*9980SDana.Myers@Sun.COM      * for both methods and other objects.
279*9980SDana.Myers@Sun.COM      *
280*9980SDana.Myers@Sun.COM      * Exit now if there is no return object. Warning if one was expected.
281*9980SDana.Myers@Sun.COM      */
282*9980SDana.Myers@Sun.COM     if (!ReturnObject)
283*9980SDana.Myers@Sun.COM     {
284*9980SDana.Myers@Sun.COM         if ((Predefined->Info.ExpectedBtypes) &&
285*9980SDana.Myers@Sun.COM             (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
286*9980SDana.Myers@Sun.COM         {
287*9980SDana.Myers@Sun.COM             ACPI_ERROR ((AE_INFO,
288*9980SDana.Myers@Sun.COM                 "%s: Missing expected return value", Pathname));
289*9980SDana.Myers@Sun.COM 
290*9980SDana.Myers@Sun.COM             Status = AE_AML_NO_RETURN_VALUE;
291*9980SDana.Myers@Sun.COM         }
292*9980SDana.Myers@Sun.COM         goto Exit;
293*9980SDana.Myers@Sun.COM     }
294*9980SDana.Myers@Sun.COM 
295*9980SDana.Myers@Sun.COM     /*
296*9980SDana.Myers@Sun.COM      * We have a return value, but if one wasn't expected, just exit, this is
297*9980SDana.Myers@Sun.COM      * not a problem
298*9980SDana.Myers@Sun.COM      *
299*9980SDana.Myers@Sun.COM      * For example, if the "Implicit Return" feature is enabled, methods will
300*9980SDana.Myers@Sun.COM      * always return a value
301*9980SDana.Myers@Sun.COM      */
302*9980SDana.Myers@Sun.COM     if (!Predefined->Info.ExpectedBtypes)
303*9980SDana.Myers@Sun.COM     {
304*9980SDana.Myers@Sun.COM         goto Exit;
305*9980SDana.Myers@Sun.COM     }
306*9980SDana.Myers@Sun.COM 
307*9980SDana.Myers@Sun.COM     /*
308*9980SDana.Myers@Sun.COM      * Check that the type of the return object is what is expected for
309*9980SDana.Myers@Sun.COM      * this predefined name
310*9980SDana.Myers@Sun.COM      */
311*9980SDana.Myers@Sun.COM     Status = AcpiNsCheckObjectType (Pathname, ReturnObjectPtr,
312*9980SDana.Myers@Sun.COM                 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE);
313*9980SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status))
314*9980SDana.Myers@Sun.COM     {
315*9980SDana.Myers@Sun.COM         goto Exit;
316*9980SDana.Myers@Sun.COM     }
317*9980SDana.Myers@Sun.COM 
318*9980SDana.Myers@Sun.COM     /* For returned Package objects, check the type of all sub-objects */
319*9980SDana.Myers@Sun.COM 
320*9980SDana.Myers@Sun.COM     if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE)
321*9980SDana.Myers@Sun.COM     {
322*9980SDana.Myers@Sun.COM         Status = AcpiNsCheckPackage (Pathname, ReturnObjectPtr, Predefined);
323*9980SDana.Myers@Sun.COM     }
324*9980SDana.Myers@Sun.COM 
325*9980SDana.Myers@Sun.COM Exit:
326*9980SDana.Myers@Sun.COM     ACPI_FREE (Pathname);
327*9980SDana.Myers@Sun.COM     return (Status);
328*9980SDana.Myers@Sun.COM }
329*9980SDana.Myers@Sun.COM 
330*9980SDana.Myers@Sun.COM 
331*9980SDana.Myers@Sun.COM /*******************************************************************************
332*9980SDana.Myers@Sun.COM  *
333*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCheckParameterCount
334*9980SDana.Myers@Sun.COM  *
335*9980SDana.Myers@Sun.COM  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
336*9980SDana.Myers@Sun.COM  *              Node            - Namespace node for the method/object
337*9980SDana.Myers@Sun.COM  *              UserParamCount  - Number of args passed in by the caller
338*9980SDana.Myers@Sun.COM  *              Predefined      - Pointer to entry in predefined name table
339*9980SDana.Myers@Sun.COM  *
340*9980SDana.Myers@Sun.COM  * RETURN:      None
341*9980SDana.Myers@Sun.COM  *
342*9980SDana.Myers@Sun.COM  * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
343*9980SDana.Myers@Sun.COM  *              predefined name is what is expected (i.e., what is defined in
344*9980SDana.Myers@Sun.COM  *              the ACPI specification for this predefined name.)
345*9980SDana.Myers@Sun.COM  *
346*9980SDana.Myers@Sun.COM  ******************************************************************************/
347*9980SDana.Myers@Sun.COM 
348*9980SDana.Myers@Sun.COM void
349*9980SDana.Myers@Sun.COM AcpiNsCheckParameterCount (
350*9980SDana.Myers@Sun.COM     char                        *Pathname,
351*9980SDana.Myers@Sun.COM     ACPI_NAMESPACE_NODE         *Node,
352*9980SDana.Myers@Sun.COM     UINT32                      UserParamCount,
353*9980SDana.Myers@Sun.COM     const ACPI_PREDEFINED_INFO  *Predefined)
354*9980SDana.Myers@Sun.COM {
355*9980SDana.Myers@Sun.COM     UINT32                      ParamCount;
356*9980SDana.Myers@Sun.COM     UINT32                      RequiredParamsCurrent;
357*9980SDana.Myers@Sun.COM     UINT32                      RequiredParamsOld;
358*9980SDana.Myers@Sun.COM 
359*9980SDana.Myers@Sun.COM 
360*9980SDana.Myers@Sun.COM     /* Methods have 0-7 parameters. All other types have zero. */
361*9980SDana.Myers@Sun.COM 
362*9980SDana.Myers@Sun.COM     ParamCount = 0;
363*9980SDana.Myers@Sun.COM     if (Node->Type == ACPI_TYPE_METHOD)
364*9980SDana.Myers@Sun.COM     {
365*9980SDana.Myers@Sun.COM         ParamCount = Node->Object->Method.ParamCount;
366*9980SDana.Myers@Sun.COM     }
367*9980SDana.Myers@Sun.COM 
368*9980SDana.Myers@Sun.COM     /* Argument count check for non-predefined methods/objects */
369*9980SDana.Myers@Sun.COM 
370*9980SDana.Myers@Sun.COM     if (!Predefined)
371*9980SDana.Myers@Sun.COM     {
372*9980SDana.Myers@Sun.COM         /*
373*9980SDana.Myers@Sun.COM          * Warning if too few or too many arguments have been passed by the
374*9980SDana.Myers@Sun.COM          * caller. An incorrect number of arguments may not cause the method
375*9980SDana.Myers@Sun.COM          * to fail. However, the method will fail if there are too few
376*9980SDana.Myers@Sun.COM          * arguments and the method attempts to use one of the missing ones.
377*9980SDana.Myers@Sun.COM          */
378*9980SDana.Myers@Sun.COM         if (UserParamCount < ParamCount)
379*9980SDana.Myers@Sun.COM         {
380*9980SDana.Myers@Sun.COM             ACPI_WARNING ((AE_INFO,
381*9980SDana.Myers@Sun.COM                 "%s: Insufficient arguments - needs %d, found %d",
382*9980SDana.Myers@Sun.COM                 Pathname, ParamCount, UserParamCount));
383*9980SDana.Myers@Sun.COM         }
384*9980SDana.Myers@Sun.COM         else if (UserParamCount > ParamCount)
385*9980SDana.Myers@Sun.COM         {
386*9980SDana.Myers@Sun.COM             ACPI_WARNING ((AE_INFO,
387*9980SDana.Myers@Sun.COM                 "%s: Excess arguments - needs %d, found %d",
388*9980SDana.Myers@Sun.COM                 Pathname, ParamCount, UserParamCount));
389*9980SDana.Myers@Sun.COM         }
390*9980SDana.Myers@Sun.COM         return;
391*9980SDana.Myers@Sun.COM     }
392*9980SDana.Myers@Sun.COM 
393*9980SDana.Myers@Sun.COM     /* Allow two different legal argument counts (_SCP, etc.) */
394*9980SDana.Myers@Sun.COM 
395*9980SDana.Myers@Sun.COM     RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
396*9980SDana.Myers@Sun.COM     RequiredParamsOld = Predefined->Info.ParamCount >> 4;
397*9980SDana.Myers@Sun.COM 
398*9980SDana.Myers@Sun.COM     if (UserParamCount != ACPI_UINT32_MAX)
399*9980SDana.Myers@Sun.COM     {
400*9980SDana.Myers@Sun.COM         /* Validate the user-supplied parameter count */
401*9980SDana.Myers@Sun.COM 
402*9980SDana.Myers@Sun.COM         if ((UserParamCount != RequiredParamsCurrent) &&
403*9980SDana.Myers@Sun.COM             (UserParamCount != RequiredParamsOld))
404*9980SDana.Myers@Sun.COM         {
405*9980SDana.Myers@Sun.COM             ACPI_WARNING ((AE_INFO,
406*9980SDana.Myers@Sun.COM                 "%s: Parameter count mismatch - "
407*9980SDana.Myers@Sun.COM                 "caller passed %d, ACPI requires %d",
408*9980SDana.Myers@Sun.COM                 Pathname, UserParamCount, RequiredParamsCurrent));
409*9980SDana.Myers@Sun.COM         }
410*9980SDana.Myers@Sun.COM     }
411*9980SDana.Myers@Sun.COM 
412*9980SDana.Myers@Sun.COM     /*
413*9980SDana.Myers@Sun.COM      * Only validate the argument count on the first successful evaluation of
414*9980SDana.Myers@Sun.COM      * the method. This ensures that any warnings will only be emitted during
415*9980SDana.Myers@Sun.COM      * the very first evaluation of the method/object.
416*9980SDana.Myers@Sun.COM      */
417*9980SDana.Myers@Sun.COM     if (Node->Flags & ANOBJ_EVALUATED)
418*9980SDana.Myers@Sun.COM     {
419*9980SDana.Myers@Sun.COM         return;
420*9980SDana.Myers@Sun.COM     }
421*9980SDana.Myers@Sun.COM 
422*9980SDana.Myers@Sun.COM     /*
423*9980SDana.Myers@Sun.COM      * Check that the ASL-defined parameter count is what is expected for
424*9980SDana.Myers@Sun.COM      * this predefined name.
425*9980SDana.Myers@Sun.COM      */
426*9980SDana.Myers@Sun.COM     if ((ParamCount != RequiredParamsCurrent) &&
427*9980SDana.Myers@Sun.COM         (ParamCount != RequiredParamsOld))
428*9980SDana.Myers@Sun.COM     {
429*9980SDana.Myers@Sun.COM         ACPI_WARNING ((AE_INFO,
430*9980SDana.Myers@Sun.COM             "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d",
431*9980SDana.Myers@Sun.COM             Pathname, ParamCount, RequiredParamsCurrent));
432*9980SDana.Myers@Sun.COM     }
433*9980SDana.Myers@Sun.COM }
434*9980SDana.Myers@Sun.COM 
435*9980SDana.Myers@Sun.COM 
436*9980SDana.Myers@Sun.COM /*******************************************************************************
437*9980SDana.Myers@Sun.COM  *
438*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCheckForPredefinedName
439*9980SDana.Myers@Sun.COM  *
440*9980SDana.Myers@Sun.COM  * PARAMETERS:  Node            - Namespace node for the method/object
441*9980SDana.Myers@Sun.COM  *
442*9980SDana.Myers@Sun.COM  * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
443*9980SDana.Myers@Sun.COM  *
444*9980SDana.Myers@Sun.COM  * DESCRIPTION: Check an object name against the predefined object list.
445*9980SDana.Myers@Sun.COM  *
446*9980SDana.Myers@Sun.COM  ******************************************************************************/
447*9980SDana.Myers@Sun.COM 
448*9980SDana.Myers@Sun.COM const ACPI_PREDEFINED_INFO *
449*9980SDana.Myers@Sun.COM AcpiNsCheckForPredefinedName (
450*9980SDana.Myers@Sun.COM     ACPI_NAMESPACE_NODE         *Node)
451*9980SDana.Myers@Sun.COM {
452*9980SDana.Myers@Sun.COM     const ACPI_PREDEFINED_INFO  *ThisName;
453*9980SDana.Myers@Sun.COM 
454*9980SDana.Myers@Sun.COM 
455*9980SDana.Myers@Sun.COM     /* Quick check for a predefined name, first character must be underscore */
456*9980SDana.Myers@Sun.COM 
457*9980SDana.Myers@Sun.COM     if (Node->Name.Ascii[0] != '_')
458*9980SDana.Myers@Sun.COM     {
459*9980SDana.Myers@Sun.COM         return (NULL);
460*9980SDana.Myers@Sun.COM     }
461*9980SDana.Myers@Sun.COM 
462*9980SDana.Myers@Sun.COM     /* Search info table for a predefined method/object name */
463*9980SDana.Myers@Sun.COM 
464*9980SDana.Myers@Sun.COM     ThisName = PredefinedNames;
465*9980SDana.Myers@Sun.COM     while (ThisName->Info.Name[0])
466*9980SDana.Myers@Sun.COM     {
467*9980SDana.Myers@Sun.COM         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
468*9980SDana.Myers@Sun.COM         {
469*9980SDana.Myers@Sun.COM             /* Return pointer to this table entry */
470*9980SDana.Myers@Sun.COM 
471*9980SDana.Myers@Sun.COM             return (ThisName);
472*9980SDana.Myers@Sun.COM         }
473*9980SDana.Myers@Sun.COM 
474*9980SDana.Myers@Sun.COM         /*
475*9980SDana.Myers@Sun.COM          * Skip next entry in the table if this name returns a Package
476*9980SDana.Myers@Sun.COM          * (next entry contains the package info)
477*9980SDana.Myers@Sun.COM          */
478*9980SDana.Myers@Sun.COM         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
479*9980SDana.Myers@Sun.COM         {
480*9980SDana.Myers@Sun.COM             ThisName++;
481*9980SDana.Myers@Sun.COM         }
482*9980SDana.Myers@Sun.COM 
483*9980SDana.Myers@Sun.COM         ThisName++;
484*9980SDana.Myers@Sun.COM     }
485*9980SDana.Myers@Sun.COM 
486*9980SDana.Myers@Sun.COM     return (NULL);
487*9980SDana.Myers@Sun.COM }
488*9980SDana.Myers@Sun.COM 
489*9980SDana.Myers@Sun.COM 
490*9980SDana.Myers@Sun.COM /*******************************************************************************
491*9980SDana.Myers@Sun.COM  *
492*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCheckPackage
493*9980SDana.Myers@Sun.COM  *
494*9980SDana.Myers@Sun.COM  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
495*9980SDana.Myers@Sun.COM  *              ReturnObjectPtr - Pointer to the object returned from the
496*9980SDana.Myers@Sun.COM  *                                evaluation of a method or object
497*9980SDana.Myers@Sun.COM  *              Predefined      - Pointer to entry in predefined name table
498*9980SDana.Myers@Sun.COM  *
499*9980SDana.Myers@Sun.COM  * RETURN:      Status
500*9980SDana.Myers@Sun.COM  *
501*9980SDana.Myers@Sun.COM  * DESCRIPTION: Check a returned package object for the correct count and
502*9980SDana.Myers@Sun.COM  *              correct type of all sub-objects.
503*9980SDana.Myers@Sun.COM  *
504*9980SDana.Myers@Sun.COM  ******************************************************************************/
505*9980SDana.Myers@Sun.COM 
506*9980SDana.Myers@Sun.COM static ACPI_STATUS
507*9980SDana.Myers@Sun.COM AcpiNsCheckPackage (
508*9980SDana.Myers@Sun.COM     char                        *Pathname,
509*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
510*9980SDana.Myers@Sun.COM     const ACPI_PREDEFINED_INFO  *Predefined)
511*9980SDana.Myers@Sun.COM {
512*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
513*9980SDana.Myers@Sun.COM     const ACPI_PREDEFINED_INFO  *Package;
514*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *SubPackage;
515*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **Elements;
516*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **SubElements;
517*9980SDana.Myers@Sun.COM     ACPI_STATUS                 Status;
518*9980SDana.Myers@Sun.COM     UINT32                      ExpectedCount;
519*9980SDana.Myers@Sun.COM     UINT32                      Count;
520*9980SDana.Myers@Sun.COM     UINT32                      i;
521*9980SDana.Myers@Sun.COM     UINT32                      j;
522*9980SDana.Myers@Sun.COM 
523*9980SDana.Myers@Sun.COM 
524*9980SDana.Myers@Sun.COM     ACPI_FUNCTION_NAME (NsCheckPackage);
525*9980SDana.Myers@Sun.COM 
526*9980SDana.Myers@Sun.COM 
527*9980SDana.Myers@Sun.COM     /* The package info for this name is in the next table entry */
528*9980SDana.Myers@Sun.COM 
529*9980SDana.Myers@Sun.COM     Package = Predefined + 1;
530*9980SDana.Myers@Sun.COM 
531*9980SDana.Myers@Sun.COM     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
532*9980SDana.Myers@Sun.COM         "%s Validating return Package of Type %X, Count %X\n",
533*9980SDana.Myers@Sun.COM         Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
534*9980SDana.Myers@Sun.COM 
535*9980SDana.Myers@Sun.COM     /* Extract package count and elements array */
536*9980SDana.Myers@Sun.COM 
537*9980SDana.Myers@Sun.COM     Elements = ReturnObject->Package.Elements;
538*9980SDana.Myers@Sun.COM     Count = ReturnObject->Package.Count;
539*9980SDana.Myers@Sun.COM 
540*9980SDana.Myers@Sun.COM     /* The package must have at least one element, else invalid */
541*9980SDana.Myers@Sun.COM 
542*9980SDana.Myers@Sun.COM     if (!Count)
543*9980SDana.Myers@Sun.COM     {
544*9980SDana.Myers@Sun.COM         ACPI_WARNING ((AE_INFO,
545*9980SDana.Myers@Sun.COM             "%s: Return Package has no elements (empty)", Pathname));
546*9980SDana.Myers@Sun.COM 
547*9980SDana.Myers@Sun.COM         return (AE_AML_OPERAND_VALUE);
548*9980SDana.Myers@Sun.COM     }
549*9980SDana.Myers@Sun.COM 
550*9980SDana.Myers@Sun.COM     /*
551*9980SDana.Myers@Sun.COM      * Decode the type of the expected package contents
552*9980SDana.Myers@Sun.COM      *
553*9980SDana.Myers@Sun.COM      * PTYPE1 packages contain no subpackages
554*9980SDana.Myers@Sun.COM      * PTYPE2 packages contain sub-packages
555*9980SDana.Myers@Sun.COM      */
556*9980SDana.Myers@Sun.COM     switch (Package->RetInfo.Type)
557*9980SDana.Myers@Sun.COM     {
558*9980SDana.Myers@Sun.COM     case ACPI_PTYPE1_FIXED:
559*9980SDana.Myers@Sun.COM 
560*9980SDana.Myers@Sun.COM         /*
561*9980SDana.Myers@Sun.COM          * The package count is fixed and there are no sub-packages
562*9980SDana.Myers@Sun.COM          *
563*9980SDana.Myers@Sun.COM          * If package is too small, exit.
564*9980SDana.Myers@Sun.COM          * If package is larger than expected, issue warning but continue
565*9980SDana.Myers@Sun.COM          */
566*9980SDana.Myers@Sun.COM         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
567*9980SDana.Myers@Sun.COM         if (Count < ExpectedCount)
568*9980SDana.Myers@Sun.COM         {
569*9980SDana.Myers@Sun.COM             goto PackageTooSmall;
570*9980SDana.Myers@Sun.COM         }
571*9980SDana.Myers@Sun.COM         else if (Count > ExpectedCount)
572*9980SDana.Myers@Sun.COM         {
573*9980SDana.Myers@Sun.COM             ACPI_WARNING ((AE_INFO,
574*9980SDana.Myers@Sun.COM                 "%s: Return Package is larger than needed - "
575*9980SDana.Myers@Sun.COM                 "found %u, expected %u", Pathname, Count, ExpectedCount));
576*9980SDana.Myers@Sun.COM         }
577*9980SDana.Myers@Sun.COM 
578*9980SDana.Myers@Sun.COM         /* Validate all elements of the returned package */
579*9980SDana.Myers@Sun.COM 
580*9980SDana.Myers@Sun.COM         Status = AcpiNsCheckPackageElements (Pathname, Elements,
581*9980SDana.Myers@Sun.COM                     Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
582*9980SDana.Myers@Sun.COM                     Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
583*9980SDana.Myers@Sun.COM         if (ACPI_FAILURE (Status))
584*9980SDana.Myers@Sun.COM         {
585*9980SDana.Myers@Sun.COM             return (Status);
586*9980SDana.Myers@Sun.COM         }
587*9980SDana.Myers@Sun.COM         break;
588*9980SDana.Myers@Sun.COM 
589*9980SDana.Myers@Sun.COM 
590*9980SDana.Myers@Sun.COM     case ACPI_PTYPE1_VAR:
591*9980SDana.Myers@Sun.COM 
592*9980SDana.Myers@Sun.COM         /*
593*9980SDana.Myers@Sun.COM          * The package count is variable, there are no sub-packages, and all
594*9980SDana.Myers@Sun.COM          * elements must be of the same type
595*9980SDana.Myers@Sun.COM          */
596*9980SDana.Myers@Sun.COM         for (i = 0; i < Count; i++)
597*9980SDana.Myers@Sun.COM         {
598*9980SDana.Myers@Sun.COM             Status = AcpiNsCheckObjectType (Pathname, Elements,
599*9980SDana.Myers@Sun.COM                         Package->RetInfo.ObjectType1, i);
600*9980SDana.Myers@Sun.COM             if (ACPI_FAILURE (Status))
601*9980SDana.Myers@Sun.COM             {
602*9980SDana.Myers@Sun.COM                 return (Status);
603*9980SDana.Myers@Sun.COM             }
604*9980SDana.Myers@Sun.COM             Elements++;
605*9980SDana.Myers@Sun.COM         }
606*9980SDana.Myers@Sun.COM         break;
607*9980SDana.Myers@Sun.COM 
608*9980SDana.Myers@Sun.COM 
609*9980SDana.Myers@Sun.COM     case ACPI_PTYPE1_OPTION:
610*9980SDana.Myers@Sun.COM 
611*9980SDana.Myers@Sun.COM         /*
612*9980SDana.Myers@Sun.COM          * The package count is variable, there are no sub-packages. There are
613*9980SDana.Myers@Sun.COM          * a fixed number of required elements, and a variable number of
614*9980SDana.Myers@Sun.COM          * optional elements.
615*9980SDana.Myers@Sun.COM          *
616*9980SDana.Myers@Sun.COM          * Check if package is at least as large as the minimum required
617*9980SDana.Myers@Sun.COM          */
618*9980SDana.Myers@Sun.COM         ExpectedCount = Package->RetInfo3.Count;
619*9980SDana.Myers@Sun.COM         if (Count < ExpectedCount)
620*9980SDana.Myers@Sun.COM         {
621*9980SDana.Myers@Sun.COM             goto PackageTooSmall;
622*9980SDana.Myers@Sun.COM         }
623*9980SDana.Myers@Sun.COM 
624*9980SDana.Myers@Sun.COM         /* Variable number of sub-objects */
625*9980SDana.Myers@Sun.COM 
626*9980SDana.Myers@Sun.COM         for (i = 0; i < Count; i++)
627*9980SDana.Myers@Sun.COM         {
628*9980SDana.Myers@Sun.COM             if (i < Package->RetInfo3.Count)
629*9980SDana.Myers@Sun.COM             {
630*9980SDana.Myers@Sun.COM                 /* These are the required package elements (0, 1, or 2) */
631*9980SDana.Myers@Sun.COM 
632*9980SDana.Myers@Sun.COM                 Status = AcpiNsCheckObjectType (Pathname, Elements,
633*9980SDana.Myers@Sun.COM                             Package->RetInfo3.ObjectType[i], i);
634*9980SDana.Myers@Sun.COM                 if (ACPI_FAILURE (Status))
635*9980SDana.Myers@Sun.COM                 {
636*9980SDana.Myers@Sun.COM                     return (Status);
637*9980SDana.Myers@Sun.COM                 }
638*9980SDana.Myers@Sun.COM             }
639*9980SDana.Myers@Sun.COM             else
640*9980SDana.Myers@Sun.COM             {
641*9980SDana.Myers@Sun.COM                 /* These are the optional package elements */
642*9980SDana.Myers@Sun.COM 
643*9980SDana.Myers@Sun.COM                 Status = AcpiNsCheckObjectType (Pathname, Elements,
644*9980SDana.Myers@Sun.COM                             Package->RetInfo3.TailObjectType, i);
645*9980SDana.Myers@Sun.COM                 if (ACPI_FAILURE (Status))
646*9980SDana.Myers@Sun.COM                 {
647*9980SDana.Myers@Sun.COM                     return (Status);
648*9980SDana.Myers@Sun.COM                 }
649*9980SDana.Myers@Sun.COM             }
650*9980SDana.Myers@Sun.COM             Elements++;
651*9980SDana.Myers@Sun.COM         }
652*9980SDana.Myers@Sun.COM         break;
653*9980SDana.Myers@Sun.COM 
654*9980SDana.Myers@Sun.COM 
655*9980SDana.Myers@Sun.COM     case ACPI_PTYPE2_PKG_COUNT:
656*9980SDana.Myers@Sun.COM 
657*9980SDana.Myers@Sun.COM         /* First element is the (Integer) count of sub-packages to follow */
658*9980SDana.Myers@Sun.COM 
659*9980SDana.Myers@Sun.COM         Status = AcpiNsCheckObjectType (Pathname, Elements,
660*9980SDana.Myers@Sun.COM                     ACPI_RTYPE_INTEGER, 0);
661*9980SDana.Myers@Sun.COM         if (ACPI_FAILURE (Status))
662*9980SDana.Myers@Sun.COM         {
663*9980SDana.Myers@Sun.COM             return (Status);
664*9980SDana.Myers@Sun.COM         }
665*9980SDana.Myers@Sun.COM 
666*9980SDana.Myers@Sun.COM         /*
667*9980SDana.Myers@Sun.COM          * Count cannot be larger than the parent package length, but allow it
668*9980SDana.Myers@Sun.COM          * to be smaller. The >= accounts for the Integer above.
669*9980SDana.Myers@Sun.COM          */
670*9980SDana.Myers@Sun.COM         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
671*9980SDana.Myers@Sun.COM         if (ExpectedCount >= Count)
672*9980SDana.Myers@Sun.COM         {
673*9980SDana.Myers@Sun.COM             goto PackageTooSmall;
674*9980SDana.Myers@Sun.COM         }
675*9980SDana.Myers@Sun.COM 
676*9980SDana.Myers@Sun.COM         Count = ExpectedCount;
677*9980SDana.Myers@Sun.COM         Elements++;
678*9980SDana.Myers@Sun.COM 
679*9980SDana.Myers@Sun.COM         /* Now we can walk the sub-packages */
680*9980SDana.Myers@Sun.COM 
681*9980SDana.Myers@Sun.COM         /*lint -fallthrough */
682*9980SDana.Myers@Sun.COM 
683*9980SDana.Myers@Sun.COM 
684*9980SDana.Myers@Sun.COM     case ACPI_PTYPE2:
685*9980SDana.Myers@Sun.COM     case ACPI_PTYPE2_FIXED:
686*9980SDana.Myers@Sun.COM     case ACPI_PTYPE2_MIN:
687*9980SDana.Myers@Sun.COM     case ACPI_PTYPE2_COUNT:
688*9980SDana.Myers@Sun.COM 
689*9980SDana.Myers@Sun.COM         /*
690*9980SDana.Myers@Sun.COM          * These types all return a single package that consists of a variable
691*9980SDana.Myers@Sun.COM          * number of sub-packages
692*9980SDana.Myers@Sun.COM          */
693*9980SDana.Myers@Sun.COM         for (i = 0; i < Count; i++)
694*9980SDana.Myers@Sun.COM         {
695*9980SDana.Myers@Sun.COM             SubPackage = *Elements;
696*9980SDana.Myers@Sun.COM             SubElements = SubPackage->Package.Elements;
697*9980SDana.Myers@Sun.COM 
698*9980SDana.Myers@Sun.COM             /* Each sub-object must be of type Package */
699*9980SDana.Myers@Sun.COM 
700*9980SDana.Myers@Sun.COM             Status = AcpiNsCheckObjectType (Pathname, &SubPackage,
701*9980SDana.Myers@Sun.COM                         ACPI_RTYPE_PACKAGE, i);
702*9980SDana.Myers@Sun.COM             if (ACPI_FAILURE (Status))
703*9980SDana.Myers@Sun.COM             {
704*9980SDana.Myers@Sun.COM                 return (Status);
705*9980SDana.Myers@Sun.COM             }
706*9980SDana.Myers@Sun.COM 
707*9980SDana.Myers@Sun.COM             /* Examine the different types of sub-packages */
708*9980SDana.Myers@Sun.COM 
709*9980SDana.Myers@Sun.COM             switch (Package->RetInfo.Type)
710*9980SDana.Myers@Sun.COM             {
711*9980SDana.Myers@Sun.COM             case ACPI_PTYPE2:
712*9980SDana.Myers@Sun.COM             case ACPI_PTYPE2_PKG_COUNT:
713*9980SDana.Myers@Sun.COM 
714*9980SDana.Myers@Sun.COM                 /* Each subpackage has a fixed number of elements */
715*9980SDana.Myers@Sun.COM 
716*9980SDana.Myers@Sun.COM                 ExpectedCount =
717*9980SDana.Myers@Sun.COM                     Package->RetInfo.Count1 + Package->RetInfo.Count2;
718*9980SDana.Myers@Sun.COM                 if (SubPackage->Package.Count != ExpectedCount)
719*9980SDana.Myers@Sun.COM                 {
720*9980SDana.Myers@Sun.COM                     Count = SubPackage->Package.Count;
721*9980SDana.Myers@Sun.COM                     goto PackageTooSmall;
722*9980SDana.Myers@Sun.COM                 }
723*9980SDana.Myers@Sun.COM 
724*9980SDana.Myers@Sun.COM                 Status = AcpiNsCheckPackageElements (Pathname, SubElements,
725*9980SDana.Myers@Sun.COM                             Package->RetInfo.ObjectType1,
726*9980SDana.Myers@Sun.COM                             Package->RetInfo.Count1,
727*9980SDana.Myers@Sun.COM                             Package->RetInfo.ObjectType2,
728*9980SDana.Myers@Sun.COM                             Package->RetInfo.Count2, 0);
729*9980SDana.Myers@Sun.COM                 if (ACPI_FAILURE (Status))
730*9980SDana.Myers@Sun.COM                 {
731*9980SDana.Myers@Sun.COM                     return (Status);
732*9980SDana.Myers@Sun.COM                 }
733*9980SDana.Myers@Sun.COM                 break;
734*9980SDana.Myers@Sun.COM 
735*9980SDana.Myers@Sun.COM             case ACPI_PTYPE2_FIXED:
736*9980SDana.Myers@Sun.COM 
737*9980SDana.Myers@Sun.COM                 /* Each sub-package has a fixed length */
738*9980SDana.Myers@Sun.COM 
739*9980SDana.Myers@Sun.COM                 ExpectedCount = Package->RetInfo2.Count;
740*9980SDana.Myers@Sun.COM                 if (SubPackage->Package.Count < ExpectedCount)
741*9980SDana.Myers@Sun.COM                 {
742*9980SDana.Myers@Sun.COM                     Count = SubPackage->Package.Count;
743*9980SDana.Myers@Sun.COM                     goto PackageTooSmall;
744*9980SDana.Myers@Sun.COM                 }
745*9980SDana.Myers@Sun.COM 
746*9980SDana.Myers@Sun.COM                 /* Check the type of each sub-package element */
747*9980SDana.Myers@Sun.COM 
748*9980SDana.Myers@Sun.COM                 for (j = 0; j < ExpectedCount; j++)
749*9980SDana.Myers@Sun.COM                 {
750*9980SDana.Myers@Sun.COM                     Status = AcpiNsCheckObjectType (Pathname, &SubElements[j],
751*9980SDana.Myers@Sun.COM                                 Package->RetInfo2.ObjectType[j], j);
752*9980SDana.Myers@Sun.COM                     if (ACPI_FAILURE (Status))
753*9980SDana.Myers@Sun.COM                     {
754*9980SDana.Myers@Sun.COM                         return (Status);
755*9980SDana.Myers@Sun.COM                     }
756*9980SDana.Myers@Sun.COM                 }
757*9980SDana.Myers@Sun.COM                 break;
758*9980SDana.Myers@Sun.COM 
759*9980SDana.Myers@Sun.COM             case ACPI_PTYPE2_MIN:
760*9980SDana.Myers@Sun.COM 
761*9980SDana.Myers@Sun.COM                 /* Each sub-package has a variable but minimum length */
762*9980SDana.Myers@Sun.COM 
763*9980SDana.Myers@Sun.COM                 ExpectedCount = Package->RetInfo.Count1;
764*9980SDana.Myers@Sun.COM                 if (SubPackage->Package.Count < ExpectedCount)
765*9980SDana.Myers@Sun.COM                 {
766*9980SDana.Myers@Sun.COM                     Count = SubPackage->Package.Count;
767*9980SDana.Myers@Sun.COM                     goto PackageTooSmall;
768*9980SDana.Myers@Sun.COM                 }
769*9980SDana.Myers@Sun.COM 
770*9980SDana.Myers@Sun.COM                 /* Check the type of each sub-package element */
771*9980SDana.Myers@Sun.COM 
772*9980SDana.Myers@Sun.COM                 Status = AcpiNsCheckPackageElements (Pathname, SubElements,
773*9980SDana.Myers@Sun.COM                             Package->RetInfo.ObjectType1,
774*9980SDana.Myers@Sun.COM                             SubPackage->Package.Count, 0, 0, 0);
775*9980SDana.Myers@Sun.COM                 if (ACPI_FAILURE (Status))
776*9980SDana.Myers@Sun.COM                 {
777*9980SDana.Myers@Sun.COM                     return (Status);
778*9980SDana.Myers@Sun.COM                 }
779*9980SDana.Myers@Sun.COM                 break;
780*9980SDana.Myers@Sun.COM 
781*9980SDana.Myers@Sun.COM             case ACPI_PTYPE2_COUNT:
782*9980SDana.Myers@Sun.COM 
783*9980SDana.Myers@Sun.COM                 /* First element is the (Integer) count of elements to follow */
784*9980SDana.Myers@Sun.COM 
785*9980SDana.Myers@Sun.COM                 Status = AcpiNsCheckObjectType (Pathname, SubElements,
786*9980SDana.Myers@Sun.COM                             ACPI_RTYPE_INTEGER, 0);
787*9980SDana.Myers@Sun.COM                 if (ACPI_FAILURE (Status))
788*9980SDana.Myers@Sun.COM                 {
789*9980SDana.Myers@Sun.COM                     return (Status);
790*9980SDana.Myers@Sun.COM                 }
791*9980SDana.Myers@Sun.COM 
792*9980SDana.Myers@Sun.COM                 /* Make sure package is large enough for the Count */
793*9980SDana.Myers@Sun.COM 
794*9980SDana.Myers@Sun.COM                 ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
795*9980SDana.Myers@Sun.COM                 if (SubPackage->Package.Count < ExpectedCount)
796*9980SDana.Myers@Sun.COM                 {
797*9980SDana.Myers@Sun.COM                     Count = SubPackage->Package.Count;
798*9980SDana.Myers@Sun.COM                     goto PackageTooSmall;
799*9980SDana.Myers@Sun.COM                 }
800*9980SDana.Myers@Sun.COM 
801*9980SDana.Myers@Sun.COM                 /* Check the type of each sub-package element */
802*9980SDana.Myers@Sun.COM 
803*9980SDana.Myers@Sun.COM                 Status = AcpiNsCheckPackageElements (Pathname,
804*9980SDana.Myers@Sun.COM                             (SubElements + 1),
805*9980SDana.Myers@Sun.COM                             Package->RetInfo.ObjectType1,
806*9980SDana.Myers@Sun.COM                             (ExpectedCount - 1), 0, 0, 1);
807*9980SDana.Myers@Sun.COM                 if (ACPI_FAILURE (Status))
808*9980SDana.Myers@Sun.COM                 {
809*9980SDana.Myers@Sun.COM                     return (Status);
810*9980SDana.Myers@Sun.COM                 }
811*9980SDana.Myers@Sun.COM                 break;
812*9980SDana.Myers@Sun.COM 
813*9980SDana.Myers@Sun.COM             default:
814*9980SDana.Myers@Sun.COM                 break;
815*9980SDana.Myers@Sun.COM             }
816*9980SDana.Myers@Sun.COM 
817*9980SDana.Myers@Sun.COM             Elements++;
818*9980SDana.Myers@Sun.COM         }
819*9980SDana.Myers@Sun.COM         break;
820*9980SDana.Myers@Sun.COM 
821*9980SDana.Myers@Sun.COM 
822*9980SDana.Myers@Sun.COM     default:
823*9980SDana.Myers@Sun.COM 
824*9980SDana.Myers@Sun.COM         /* Should not get here if predefined info table is correct */
825*9980SDana.Myers@Sun.COM 
826*9980SDana.Myers@Sun.COM         ACPI_WARNING ((AE_INFO,
827*9980SDana.Myers@Sun.COM             "%s: Invalid internal return type in table entry: %X",
828*9980SDana.Myers@Sun.COM             Pathname, Package->RetInfo.Type));
829*9980SDana.Myers@Sun.COM 
830*9980SDana.Myers@Sun.COM         return (AE_AML_INTERNAL);
831*9980SDana.Myers@Sun.COM     }
832*9980SDana.Myers@Sun.COM 
833*9980SDana.Myers@Sun.COM     return (AE_OK);
834*9980SDana.Myers@Sun.COM 
835*9980SDana.Myers@Sun.COM 
836*9980SDana.Myers@Sun.COM PackageTooSmall:
837*9980SDana.Myers@Sun.COM 
838*9980SDana.Myers@Sun.COM     /* Error exit for the case with an incorrect package count */
839*9980SDana.Myers@Sun.COM 
840*9980SDana.Myers@Sun.COM     ACPI_WARNING ((AE_INFO, "%s: Return Package is too small - "
841*9980SDana.Myers@Sun.COM         "found %u, expected %u", Pathname, Count, ExpectedCount));
842*9980SDana.Myers@Sun.COM 
843*9980SDana.Myers@Sun.COM     return (AE_AML_OPERAND_VALUE);
844*9980SDana.Myers@Sun.COM }
845*9980SDana.Myers@Sun.COM 
846*9980SDana.Myers@Sun.COM 
847*9980SDana.Myers@Sun.COM /*******************************************************************************
848*9980SDana.Myers@Sun.COM  *
849*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCheckPackageElements
850*9980SDana.Myers@Sun.COM  *
851*9980SDana.Myers@Sun.COM  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
852*9980SDana.Myers@Sun.COM  *              Elements        - Pointer to the package elements array
853*9980SDana.Myers@Sun.COM  *              Type1           - Object type for first group
854*9980SDana.Myers@Sun.COM  *              Count1          - Count for first group
855*9980SDana.Myers@Sun.COM  *              Type2           - Object type for second group
856*9980SDana.Myers@Sun.COM  *              Count2          - Count for second group
857*9980SDana.Myers@Sun.COM  *              StartIndex      - Start of the first group of elements
858*9980SDana.Myers@Sun.COM  *
859*9980SDana.Myers@Sun.COM  * RETURN:      Status
860*9980SDana.Myers@Sun.COM  *
861*9980SDana.Myers@Sun.COM  * DESCRIPTION: Check that all elements of a package are of the correct object
862*9980SDana.Myers@Sun.COM  *              type. Supports up to two groups of different object types.
863*9980SDana.Myers@Sun.COM  *
864*9980SDana.Myers@Sun.COM  ******************************************************************************/
865*9980SDana.Myers@Sun.COM 
866*9980SDana.Myers@Sun.COM static ACPI_STATUS
867*9980SDana.Myers@Sun.COM AcpiNsCheckPackageElements (
868*9980SDana.Myers@Sun.COM     char                        *Pathname,
869*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **Elements,
870*9980SDana.Myers@Sun.COM     UINT8                       Type1,
871*9980SDana.Myers@Sun.COM     UINT32                      Count1,
872*9980SDana.Myers@Sun.COM     UINT8                       Type2,
873*9980SDana.Myers@Sun.COM     UINT32                      Count2,
874*9980SDana.Myers@Sun.COM     UINT32                      StartIndex)
875*9980SDana.Myers@Sun.COM {
876*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
877*9980SDana.Myers@Sun.COM     ACPI_STATUS                 Status;
878*9980SDana.Myers@Sun.COM     UINT32                      i;
879*9980SDana.Myers@Sun.COM 
880*9980SDana.Myers@Sun.COM 
881*9980SDana.Myers@Sun.COM     /*
882*9980SDana.Myers@Sun.COM      * Up to two groups of package elements are supported by the data
883*9980SDana.Myers@Sun.COM      * structure. All elements in each group must be of the same type.
884*9980SDana.Myers@Sun.COM      * The second group can have a count of zero.
885*9980SDana.Myers@Sun.COM      */
886*9980SDana.Myers@Sun.COM     for (i = 0; i < Count1; i++)
887*9980SDana.Myers@Sun.COM     {
888*9980SDana.Myers@Sun.COM         Status = AcpiNsCheckObjectType (Pathname, ThisElement,
889*9980SDana.Myers@Sun.COM                     Type1, i + StartIndex);
890*9980SDana.Myers@Sun.COM         if (ACPI_FAILURE (Status))
891*9980SDana.Myers@Sun.COM         {
892*9980SDana.Myers@Sun.COM             return (Status);
893*9980SDana.Myers@Sun.COM         }
894*9980SDana.Myers@Sun.COM         ThisElement++;
895*9980SDana.Myers@Sun.COM     }
896*9980SDana.Myers@Sun.COM 
897*9980SDana.Myers@Sun.COM     for (i = 0; i < Count2; i++)
898*9980SDana.Myers@Sun.COM     {
899*9980SDana.Myers@Sun.COM         Status = AcpiNsCheckObjectType (Pathname, ThisElement,
900*9980SDana.Myers@Sun.COM                     Type2, (i + Count1 + StartIndex));
901*9980SDana.Myers@Sun.COM         if (ACPI_FAILURE (Status))
902*9980SDana.Myers@Sun.COM         {
903*9980SDana.Myers@Sun.COM             return (Status);
904*9980SDana.Myers@Sun.COM         }
905*9980SDana.Myers@Sun.COM         ThisElement++;
906*9980SDana.Myers@Sun.COM     }
907*9980SDana.Myers@Sun.COM 
908*9980SDana.Myers@Sun.COM     return (AE_OK);
909*9980SDana.Myers@Sun.COM }
910*9980SDana.Myers@Sun.COM 
911*9980SDana.Myers@Sun.COM 
912*9980SDana.Myers@Sun.COM /*******************************************************************************
913*9980SDana.Myers@Sun.COM  *
914*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCheckObjectType
915*9980SDana.Myers@Sun.COM  *
916*9980SDana.Myers@Sun.COM  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
917*9980SDana.Myers@Sun.COM  *              ReturnObjectPtr - Pointer to the object returned from the
918*9980SDana.Myers@Sun.COM  *                                evaluation of a method or object
919*9980SDana.Myers@Sun.COM  *              ExpectedBtypes  - Bitmap of expected return type(s)
920*9980SDana.Myers@Sun.COM  *              PackageIndex    - Index of object within parent package (if
921*9980SDana.Myers@Sun.COM  *                                applicable - ACPI_NOT_PACKAGE otherwise)
922*9980SDana.Myers@Sun.COM  *
923*9980SDana.Myers@Sun.COM  * RETURN:      Status
924*9980SDana.Myers@Sun.COM  *
925*9980SDana.Myers@Sun.COM  * DESCRIPTION: Check the type of the return object against the expected object
926*9980SDana.Myers@Sun.COM  *              type(s). Use of Btype allows multiple expected object types.
927*9980SDana.Myers@Sun.COM  *
928*9980SDana.Myers@Sun.COM  ******************************************************************************/
929*9980SDana.Myers@Sun.COM 
930*9980SDana.Myers@Sun.COM static ACPI_STATUS
931*9980SDana.Myers@Sun.COM AcpiNsCheckObjectType (
932*9980SDana.Myers@Sun.COM     char                        *Pathname,
933*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
934*9980SDana.Myers@Sun.COM     UINT32                      ExpectedBtypes,
935*9980SDana.Myers@Sun.COM     UINT32                      PackageIndex)
936*9980SDana.Myers@Sun.COM {
937*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
938*9980SDana.Myers@Sun.COM     ACPI_STATUS                 Status = AE_OK;
939*9980SDana.Myers@Sun.COM     UINT32                      ReturnBtype;
940*9980SDana.Myers@Sun.COM     char                        TypeBuffer[48]; /* Room for 5 types */
941*9980SDana.Myers@Sun.COM     UINT32                      ThisRtype;
942*9980SDana.Myers@Sun.COM     UINT32                      i;
943*9980SDana.Myers@Sun.COM     UINT32                      j;
944*9980SDana.Myers@Sun.COM 
945*9980SDana.Myers@Sun.COM 
946*9980SDana.Myers@Sun.COM     /*
947*9980SDana.Myers@Sun.COM      * If we get a NULL ReturnObject here, it is a NULL package element,
948*9980SDana.Myers@Sun.COM      * and this is always an error.
949*9980SDana.Myers@Sun.COM      */
950*9980SDana.Myers@Sun.COM     if (!ReturnObject)
951*9980SDana.Myers@Sun.COM     {
952*9980SDana.Myers@Sun.COM         goto TypeErrorExit;
953*9980SDana.Myers@Sun.COM     }
954*9980SDana.Myers@Sun.COM 
955*9980SDana.Myers@Sun.COM     /* A Namespace node should not get here, but make sure */
956*9980SDana.Myers@Sun.COM 
957*9980SDana.Myers@Sun.COM     if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
958*9980SDana.Myers@Sun.COM     {
959*9980SDana.Myers@Sun.COM         ACPI_WARNING ((AE_INFO,
960*9980SDana.Myers@Sun.COM             "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
961*9980SDana.Myers@Sun.COM             Pathname, ReturnObject->Node.Name.Ascii,
962*9980SDana.Myers@Sun.COM             AcpiUtGetTypeName (ReturnObject->Node.Type)));
963*9980SDana.Myers@Sun.COM         return (AE_AML_OPERAND_TYPE);
964*9980SDana.Myers@Sun.COM     }
965*9980SDana.Myers@Sun.COM 
966*9980SDana.Myers@Sun.COM     /*
967*9980SDana.Myers@Sun.COM      * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
968*9980SDana.Myers@Sun.COM      * The bitmapped type allows multiple possible return types.
969*9980SDana.Myers@Sun.COM      *
970*9980SDana.Myers@Sun.COM      * Note, the cases below must handle all of the possible types returned
971*9980SDana.Myers@Sun.COM      * from all of the predefined names (including elements of returned
972*9980SDana.Myers@Sun.COM      * packages)
973*9980SDana.Myers@Sun.COM      */
974*9980SDana.Myers@Sun.COM     switch (ReturnObject->Common.Type)
975*9980SDana.Myers@Sun.COM     {
976*9980SDana.Myers@Sun.COM     case ACPI_TYPE_INTEGER:
977*9980SDana.Myers@Sun.COM         ReturnBtype = ACPI_RTYPE_INTEGER;
978*9980SDana.Myers@Sun.COM         break;
979*9980SDana.Myers@Sun.COM 
980*9980SDana.Myers@Sun.COM     case ACPI_TYPE_BUFFER:
981*9980SDana.Myers@Sun.COM         ReturnBtype = ACPI_RTYPE_BUFFER;
982*9980SDana.Myers@Sun.COM         break;
983*9980SDana.Myers@Sun.COM 
984*9980SDana.Myers@Sun.COM     case ACPI_TYPE_STRING:
985*9980SDana.Myers@Sun.COM         ReturnBtype = ACPI_RTYPE_STRING;
986*9980SDana.Myers@Sun.COM         break;
987*9980SDana.Myers@Sun.COM 
988*9980SDana.Myers@Sun.COM     case ACPI_TYPE_PACKAGE:
989*9980SDana.Myers@Sun.COM         ReturnBtype = ACPI_RTYPE_PACKAGE;
990*9980SDana.Myers@Sun.COM         break;
991*9980SDana.Myers@Sun.COM 
992*9980SDana.Myers@Sun.COM     case ACPI_TYPE_LOCAL_REFERENCE:
993*9980SDana.Myers@Sun.COM         ReturnBtype = ACPI_RTYPE_REFERENCE;
994*9980SDana.Myers@Sun.COM         break;
995*9980SDana.Myers@Sun.COM 
996*9980SDana.Myers@Sun.COM     default:
997*9980SDana.Myers@Sun.COM         /* Not one of the supported objects, must be incorrect */
998*9980SDana.Myers@Sun.COM 
999*9980SDana.Myers@Sun.COM         goto TypeErrorExit;
1000*9980SDana.Myers@Sun.COM     }
1001*9980SDana.Myers@Sun.COM 
1002*9980SDana.Myers@Sun.COM     /* Is the object one of the expected types? */
1003*9980SDana.Myers@Sun.COM 
1004*9980SDana.Myers@Sun.COM     if (!(ReturnBtype & ExpectedBtypes))
1005*9980SDana.Myers@Sun.COM     {
1006*9980SDana.Myers@Sun.COM         /* Type mismatch -- attempt repair of the returned object */
1007*9980SDana.Myers@Sun.COM 
1008*9980SDana.Myers@Sun.COM         Status = AcpiNsRepairObject (ExpectedBtypes, PackageIndex,
1009*9980SDana.Myers@Sun.COM                     ReturnObjectPtr);
1010*9980SDana.Myers@Sun.COM         if (ACPI_SUCCESS (Status))
1011*9980SDana.Myers@Sun.COM         {
1012*9980SDana.Myers@Sun.COM             return (Status);
1013*9980SDana.Myers@Sun.COM         }
1014*9980SDana.Myers@Sun.COM         goto TypeErrorExit;
1015*9980SDana.Myers@Sun.COM     }
1016*9980SDana.Myers@Sun.COM 
1017*9980SDana.Myers@Sun.COM     /* For reference objects, check that the reference type is correct */
1018*9980SDana.Myers@Sun.COM 
1019*9980SDana.Myers@Sun.COM     if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1020*9980SDana.Myers@Sun.COM     {
1021*9980SDana.Myers@Sun.COM         Status = AcpiNsCheckReference (Pathname, ReturnObject);
1022*9980SDana.Myers@Sun.COM     }
1023*9980SDana.Myers@Sun.COM 
1024*9980SDana.Myers@Sun.COM     return (Status);
1025*9980SDana.Myers@Sun.COM 
1026*9980SDana.Myers@Sun.COM 
1027*9980SDana.Myers@Sun.COM TypeErrorExit:
1028*9980SDana.Myers@Sun.COM 
1029*9980SDana.Myers@Sun.COM     /* Create a string with all expected types for this predefined object */
1030*9980SDana.Myers@Sun.COM 
1031*9980SDana.Myers@Sun.COM     j = 1;
1032*9980SDana.Myers@Sun.COM     TypeBuffer[0] = 0;
1033*9980SDana.Myers@Sun.COM     ThisRtype = ACPI_RTYPE_INTEGER;
1034*9980SDana.Myers@Sun.COM 
1035*9980SDana.Myers@Sun.COM     for (i = 0; i < ACPI_NUM_RTYPES; i++)
1036*9980SDana.Myers@Sun.COM     {
1037*9980SDana.Myers@Sun.COM         /* If one of the expected types, concatenate the name of this type */
1038*9980SDana.Myers@Sun.COM 
1039*9980SDana.Myers@Sun.COM         if (ExpectedBtypes & ThisRtype)
1040*9980SDana.Myers@Sun.COM         {
1041*9980SDana.Myers@Sun.COM             ACPI_STRCAT (TypeBuffer, &AcpiRtypeNames[i][j]);
1042*9980SDana.Myers@Sun.COM             j = 0;              /* Use name separator from now on */
1043*9980SDana.Myers@Sun.COM         }
1044*9980SDana.Myers@Sun.COM         ThisRtype <<= 1;    /* Next Rtype */
1045*9980SDana.Myers@Sun.COM     }
1046*9980SDana.Myers@Sun.COM 
1047*9980SDana.Myers@Sun.COM     if (PackageIndex == ACPI_NOT_PACKAGE)
1048*9980SDana.Myers@Sun.COM     {
1049*9980SDana.Myers@Sun.COM         ACPI_WARNING ((AE_INFO,
1050*9980SDana.Myers@Sun.COM             "%s: Return type mismatch - found %s, expected %s",
1051*9980SDana.Myers@Sun.COM             Pathname, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1052*9980SDana.Myers@Sun.COM     }
1053*9980SDana.Myers@Sun.COM     else
1054*9980SDana.Myers@Sun.COM     {
1055*9980SDana.Myers@Sun.COM         ACPI_WARNING ((AE_INFO,
1056*9980SDana.Myers@Sun.COM             "%s: Return Package type mismatch at index %u - "
1057*9980SDana.Myers@Sun.COM             "found %s, expected %s", Pathname, PackageIndex,
1058*9980SDana.Myers@Sun.COM             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1059*9980SDana.Myers@Sun.COM     }
1060*9980SDana.Myers@Sun.COM 
1061*9980SDana.Myers@Sun.COM     return (AE_AML_OPERAND_TYPE);
1062*9980SDana.Myers@Sun.COM }
1063*9980SDana.Myers@Sun.COM 
1064*9980SDana.Myers@Sun.COM 
1065*9980SDana.Myers@Sun.COM /*******************************************************************************
1066*9980SDana.Myers@Sun.COM  *
1067*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCheckReference
1068*9980SDana.Myers@Sun.COM  *
1069*9980SDana.Myers@Sun.COM  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
1070*9980SDana.Myers@Sun.COM  *              ReturnObject    - Object returned from the evaluation of a
1071*9980SDana.Myers@Sun.COM  *                                method or object
1072*9980SDana.Myers@Sun.COM  *
1073*9980SDana.Myers@Sun.COM  * RETURN:      Status
1074*9980SDana.Myers@Sun.COM  *
1075*9980SDana.Myers@Sun.COM  * DESCRIPTION: Check a returned reference object for the correct reference
1076*9980SDana.Myers@Sun.COM  *              type. The only reference type that can be returned from a
1077*9980SDana.Myers@Sun.COM  *              predefined method is a named reference. All others are invalid.
1078*9980SDana.Myers@Sun.COM  *
1079*9980SDana.Myers@Sun.COM  ******************************************************************************/
1080*9980SDana.Myers@Sun.COM 
1081*9980SDana.Myers@Sun.COM static ACPI_STATUS
1082*9980SDana.Myers@Sun.COM AcpiNsCheckReference (
1083*9980SDana.Myers@Sun.COM     char                        *Pathname,
1084*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *ReturnObject)
1085*9980SDana.Myers@Sun.COM {
1086*9980SDana.Myers@Sun.COM 
1087*9980SDana.Myers@Sun.COM     /*
1088*9980SDana.Myers@Sun.COM      * Check the reference object for the correct reference type (opcode).
1089*9980SDana.Myers@Sun.COM      * The only type of reference that can be converted to an ACPI_OBJECT is
1090*9980SDana.Myers@Sun.COM      * a reference to a named object (reference class: NAME)
1091*9980SDana.Myers@Sun.COM      */
1092*9980SDana.Myers@Sun.COM     if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1093*9980SDana.Myers@Sun.COM     {
1094*9980SDana.Myers@Sun.COM         return (AE_OK);
1095*9980SDana.Myers@Sun.COM     }
1096*9980SDana.Myers@Sun.COM 
1097*9980SDana.Myers@Sun.COM     ACPI_WARNING ((AE_INFO,
1098*9980SDana.Myers@Sun.COM         "%s: Return type mismatch - "
1099*9980SDana.Myers@Sun.COM         "unexpected reference object type [%s] %2.2X",
1100*9980SDana.Myers@Sun.COM         Pathname, AcpiUtGetReferenceName (ReturnObject),
1101*9980SDana.Myers@Sun.COM         ReturnObject->Reference.Class));
1102*9980SDana.Myers@Sun.COM 
1103*9980SDana.Myers@Sun.COM     return (AE_AML_OPERAND_TYPE);
1104*9980SDana.Myers@Sun.COM }
1105*9980SDana.Myers@Sun.COM 
1106*9980SDana.Myers@Sun.COM 
1107*9980SDana.Myers@Sun.COM /*******************************************************************************
1108*9980SDana.Myers@Sun.COM  *
1109*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsRepairObject
1110*9980SDana.Myers@Sun.COM  *
1111*9980SDana.Myers@Sun.COM  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
1112*9980SDana.Myers@Sun.COM  *              PackageIndex    - Used to determine if target is in a package
1113*9980SDana.Myers@Sun.COM  *              ReturnObjectPtr - Pointer to the object returned from the
1114*9980SDana.Myers@Sun.COM  *                                evaluation of a method or object
1115*9980SDana.Myers@Sun.COM  *
1116*9980SDana.Myers@Sun.COM  * RETURN:      Status. AE_OK if repair was successful.
1117*9980SDana.Myers@Sun.COM  *
1118*9980SDana.Myers@Sun.COM  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
1119*9980SDana.Myers@Sun.COM  *              not expected.
1120*9980SDana.Myers@Sun.COM  *
1121*9980SDana.Myers@Sun.COM  ******************************************************************************/
1122*9980SDana.Myers@Sun.COM 
1123*9980SDana.Myers@Sun.COM static ACPI_STATUS
1124*9980SDana.Myers@Sun.COM AcpiNsRepairObject (
1125*9980SDana.Myers@Sun.COM     UINT32                      ExpectedBtypes,
1126*9980SDana.Myers@Sun.COM     UINT32                      PackageIndex,
1127*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
1128*9980SDana.Myers@Sun.COM {
1129*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1130*9980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT         *NewObject;
1131*9980SDana.Myers@Sun.COM     ACPI_SIZE                   Length;
1132*9980SDana.Myers@Sun.COM 
1133*9980SDana.Myers@Sun.COM 
1134*9980SDana.Myers@Sun.COM     switch (ReturnObject->Common.Type)
1135*9980SDana.Myers@Sun.COM     {
1136*9980SDana.Myers@Sun.COM     case ACPI_TYPE_BUFFER:
1137*9980SDana.Myers@Sun.COM 
1138*9980SDana.Myers@Sun.COM         if (!(ExpectedBtypes & ACPI_RTYPE_STRING))
1139*9980SDana.Myers@Sun.COM         {
1140*9980SDana.Myers@Sun.COM             return (AE_AML_OPERAND_TYPE);
1141*9980SDana.Myers@Sun.COM         }
1142*9980SDana.Myers@Sun.COM 
1143*9980SDana.Myers@Sun.COM         /*
1144*9980SDana.Myers@Sun.COM          * Have a Buffer, expected a String, convert. Use a ToString
1145*9980SDana.Myers@Sun.COM          * conversion, no transform performed on the buffer data. The best
1146*9980SDana.Myers@Sun.COM          * example of this is the _BIF method, where the string data from
1147*9980SDana.Myers@Sun.COM          * the battery is often (incorrectly) returned as buffer object(s).
1148*9980SDana.Myers@Sun.COM          */
1149*9980SDana.Myers@Sun.COM         Length = 0;
1150*9980SDana.Myers@Sun.COM         while ((Length < ReturnObject->Buffer.Length) &&
1151*9980SDana.Myers@Sun.COM                 (ReturnObject->Buffer.Pointer[Length]))
1152*9980SDana.Myers@Sun.COM         {
1153*9980SDana.Myers@Sun.COM             Length++;
1154*9980SDana.Myers@Sun.COM         }
1155*9980SDana.Myers@Sun.COM 
1156*9980SDana.Myers@Sun.COM         /* Allocate a new string object */
1157*9980SDana.Myers@Sun.COM 
1158*9980SDana.Myers@Sun.COM         NewObject = AcpiUtCreateStringObject (Length);
1159*9980SDana.Myers@Sun.COM         if (!NewObject)
1160*9980SDana.Myers@Sun.COM         {
1161*9980SDana.Myers@Sun.COM             return (AE_NO_MEMORY);
1162*9980SDana.Myers@Sun.COM         }
1163*9980SDana.Myers@Sun.COM 
1164*9980SDana.Myers@Sun.COM         /*
1165*9980SDana.Myers@Sun.COM          * Copy the raw buffer data with no transform. String is already NULL
1166*9980SDana.Myers@Sun.COM          * terminated at Length+1.
1167*9980SDana.Myers@Sun.COM          */
1168*9980SDana.Myers@Sun.COM         ACPI_MEMCPY (NewObject->String.Pointer,
1169*9980SDana.Myers@Sun.COM             ReturnObject->Buffer.Pointer, Length);
1170*9980SDana.Myers@Sun.COM 
1171*9980SDana.Myers@Sun.COM         /* Install the new return object */
1172*9980SDana.Myers@Sun.COM 
1173*9980SDana.Myers@Sun.COM         AcpiUtRemoveReference (ReturnObject);
1174*9980SDana.Myers@Sun.COM         *ReturnObjectPtr = NewObject;
1175*9980SDana.Myers@Sun.COM 
1176*9980SDana.Myers@Sun.COM         /*
1177*9980SDana.Myers@Sun.COM          * If the object is a package element, we need to:
1178*9980SDana.Myers@Sun.COM          * 1. Decrement the reference count of the orignal object, it was
1179*9980SDana.Myers@Sun.COM          *    incremented when building the package
1180*9980SDana.Myers@Sun.COM          * 2. Increment the reference count of the new object, it will be
1181*9980SDana.Myers@Sun.COM          *    decremented when releasing the package
1182*9980SDana.Myers@Sun.COM          */
1183*9980SDana.Myers@Sun.COM         if (PackageIndex != ACPI_NOT_PACKAGE)
1184*9980SDana.Myers@Sun.COM         {
1185*9980SDana.Myers@Sun.COM             AcpiUtRemoveReference (ReturnObject);
1186*9980SDana.Myers@Sun.COM             AcpiUtAddReference (NewObject);
1187*9980SDana.Myers@Sun.COM         }
1188*9980SDana.Myers@Sun.COM         return (AE_OK);
1189*9980SDana.Myers@Sun.COM 
1190*9980SDana.Myers@Sun.COM     default:
1191*9980SDana.Myers@Sun.COM         break;
1192*9980SDana.Myers@Sun.COM     }
1193*9980SDana.Myers@Sun.COM 
1194*9980SDana.Myers@Sun.COM     return (AE_AML_OPERAND_TYPE);
1195*9980SDana.Myers@Sun.COM }
1196*9980SDana.Myers@Sun.COM 
1197