xref: /freebsd/sys/contrib/dev/acpica/components/namespace/nspredef.c (revision a159c266a93c3c4f229864954c5f963acd8f60f2)
1*a159c266SJung-uk Kim /******************************************************************************
2*a159c266SJung-uk Kim  *
3*a159c266SJung-uk Kim  * Module Name: nspredef - Validation of ACPI predefined methods and objects
4*a159c266SJung-uk Kim  *
5*a159c266SJung-uk Kim  *****************************************************************************/
6*a159c266SJung-uk Kim 
7*a159c266SJung-uk Kim /*
8*a159c266SJung-uk Kim  * Copyright (C) 2000 - 2012, Intel Corp.
9*a159c266SJung-uk Kim  * All rights reserved.
10*a159c266SJung-uk Kim  *
11*a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
13*a159c266SJung-uk Kim  * are met:
14*a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*a159c266SJung-uk Kim  *    without modification.
17*a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*a159c266SJung-uk Kim  *    binary redistribution.
22*a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*a159c266SJung-uk Kim  *    from this software without specific prior written permission.
25*a159c266SJung-uk Kim  *
26*a159c266SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*a159c266SJung-uk Kim  * Software Foundation.
29*a159c266SJung-uk Kim  *
30*a159c266SJung-uk Kim  * NO WARRANTY
31*a159c266SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*a159c266SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*a159c266SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*a159c266SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*a159c266SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*a159c266SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*a159c266SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*a159c266SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*a159c266SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*a159c266SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*a159c266SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*a159c266SJung-uk Kim  */
43*a159c266SJung-uk Kim 
44*a159c266SJung-uk Kim #define ACPI_CREATE_PREDEFINED_TABLE
45*a159c266SJung-uk Kim 
46*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpredef.h>
50*a159c266SJung-uk Kim 
51*a159c266SJung-uk Kim 
52*a159c266SJung-uk Kim #define _COMPONENT          ACPI_NAMESPACE
53*a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("nspredef")
54*a159c266SJung-uk Kim 
55*a159c266SJung-uk Kim 
56*a159c266SJung-uk Kim /*******************************************************************************
57*a159c266SJung-uk Kim  *
58*a159c266SJung-uk Kim  * This module validates predefined ACPI objects that appear in the namespace,
59*a159c266SJung-uk Kim  * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
60*a159c266SJung-uk Kim  * validation is to detect problems with BIOS-exposed predefined ACPI objects
61*a159c266SJung-uk Kim  * before the results are returned to the ACPI-related drivers.
62*a159c266SJung-uk Kim  *
63*a159c266SJung-uk Kim  * There are several areas that are validated:
64*a159c266SJung-uk Kim  *
65*a159c266SJung-uk Kim  *  1) The number of input arguments as defined by the method/object in the
66*a159c266SJung-uk Kim  *      ASL is validated against the ACPI specification.
67*a159c266SJung-uk Kim  *  2) The type of the return object (if any) is validated against the ACPI
68*a159c266SJung-uk Kim  *      specification.
69*a159c266SJung-uk Kim  *  3) For returned package objects, the count of package elements is
70*a159c266SJung-uk Kim  *      validated, as well as the type of each package element. Nested
71*a159c266SJung-uk Kim  *      packages are supported.
72*a159c266SJung-uk Kim  *
73*a159c266SJung-uk Kim  * For any problems found, a warning message is issued.
74*a159c266SJung-uk Kim  *
75*a159c266SJung-uk Kim  ******************************************************************************/
76*a159c266SJung-uk Kim 
77*a159c266SJung-uk Kim 
78*a159c266SJung-uk Kim /* Local prototypes */
79*a159c266SJung-uk Kim 
80*a159c266SJung-uk Kim static ACPI_STATUS
81*a159c266SJung-uk Kim AcpiNsCheckPackage (
82*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
83*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
84*a159c266SJung-uk Kim 
85*a159c266SJung-uk Kim static ACPI_STATUS
86*a159c266SJung-uk Kim AcpiNsCheckPackageList (
87*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
88*a159c266SJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package,
89*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **Elements,
90*a159c266SJung-uk Kim     UINT32                      Count);
91*a159c266SJung-uk Kim 
92*a159c266SJung-uk Kim static ACPI_STATUS
93*a159c266SJung-uk Kim AcpiNsCheckPackageElements (
94*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
95*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **Elements,
96*a159c266SJung-uk Kim     UINT8                       Type1,
97*a159c266SJung-uk Kim     UINT32                      Count1,
98*a159c266SJung-uk Kim     UINT8                       Type2,
99*a159c266SJung-uk Kim     UINT32                      Count2,
100*a159c266SJung-uk Kim     UINT32                      StartIndex);
101*a159c266SJung-uk Kim 
102*a159c266SJung-uk Kim static ACPI_STATUS
103*a159c266SJung-uk Kim AcpiNsCheckObjectType (
104*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
105*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
106*a159c266SJung-uk Kim     UINT32                      ExpectedBtypes,
107*a159c266SJung-uk Kim     UINT32                      PackageIndex);
108*a159c266SJung-uk Kim 
109*a159c266SJung-uk Kim static ACPI_STATUS
110*a159c266SJung-uk Kim AcpiNsCheckReference (
111*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
112*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         *ReturnObject);
113*a159c266SJung-uk Kim 
114*a159c266SJung-uk Kim static void
115*a159c266SJung-uk Kim AcpiNsGetExpectedTypes (
116*a159c266SJung-uk Kim     char                        *Buffer,
117*a159c266SJung-uk Kim     UINT32                      ExpectedBtypes);
118*a159c266SJung-uk Kim 
119*a159c266SJung-uk Kim /*
120*a159c266SJung-uk Kim  * Names for the types that can be returned by the predefined objects.
121*a159c266SJung-uk Kim  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
122*a159c266SJung-uk Kim  */
123*a159c266SJung-uk Kim static const char   *AcpiRtypeNames[] =
124*a159c266SJung-uk Kim {
125*a159c266SJung-uk Kim     "/Integer",
126*a159c266SJung-uk Kim     "/String",
127*a159c266SJung-uk Kim     "/Buffer",
128*a159c266SJung-uk Kim     "/Package",
129*a159c266SJung-uk Kim     "/Reference",
130*a159c266SJung-uk Kim };
131*a159c266SJung-uk Kim 
132*a159c266SJung-uk Kim 
133*a159c266SJung-uk Kim /*******************************************************************************
134*a159c266SJung-uk Kim  *
135*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckPredefinedNames
136*a159c266SJung-uk Kim  *
137*a159c266SJung-uk Kim  * PARAMETERS:  Node            - Namespace node for the method/object
138*a159c266SJung-uk Kim  *              UserParamCount  - Number of parameters actually passed
139*a159c266SJung-uk Kim  *              ReturnStatus    - Status from the object evaluation
140*a159c266SJung-uk Kim  *              ReturnObjectPtr - Pointer to the object returned from the
141*a159c266SJung-uk Kim  *                                evaluation of a method or object
142*a159c266SJung-uk Kim  *
143*a159c266SJung-uk Kim  * RETURN:      Status
144*a159c266SJung-uk Kim  *
145*a159c266SJung-uk Kim  * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
146*a159c266SJung-uk Kim  *
147*a159c266SJung-uk Kim  ******************************************************************************/
148*a159c266SJung-uk Kim 
149*a159c266SJung-uk Kim ACPI_STATUS
150*a159c266SJung-uk Kim AcpiNsCheckPredefinedNames (
151*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE         *Node,
152*a159c266SJung-uk Kim     UINT32                      UserParamCount,
153*a159c266SJung-uk Kim     ACPI_STATUS                 ReturnStatus,
154*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
155*a159c266SJung-uk Kim {
156*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
157*a159c266SJung-uk Kim     ACPI_STATUS                 Status = AE_OK;
158*a159c266SJung-uk Kim     const ACPI_PREDEFINED_INFO  *Predefined;
159*a159c266SJung-uk Kim     char                        *Pathname;
160*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data;
161*a159c266SJung-uk Kim 
162*a159c266SJung-uk Kim 
163*a159c266SJung-uk Kim     /* Match the name for this method/object against the predefined list */
164*a159c266SJung-uk Kim 
165*a159c266SJung-uk Kim     Predefined = AcpiNsCheckForPredefinedName (Node);
166*a159c266SJung-uk Kim 
167*a159c266SJung-uk Kim     /* Get the full pathname to the object, for use in warning messages */
168*a159c266SJung-uk Kim 
169*a159c266SJung-uk Kim     Pathname = AcpiNsGetExternalPathname (Node);
170*a159c266SJung-uk Kim     if (!Pathname)
171*a159c266SJung-uk Kim     {
172*a159c266SJung-uk Kim         return (AE_OK); /* Could not get pathname, ignore */
173*a159c266SJung-uk Kim     }
174*a159c266SJung-uk Kim 
175*a159c266SJung-uk Kim     /*
176*a159c266SJung-uk Kim      * Check that the parameter count for this method matches the ASL
177*a159c266SJung-uk Kim      * definition. For predefined names, ensure that both the caller and
178*a159c266SJung-uk Kim      * the method itself are in accordance with the ACPI specification.
179*a159c266SJung-uk Kim      */
180*a159c266SJung-uk Kim     AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
181*a159c266SJung-uk Kim 
182*a159c266SJung-uk Kim     /* If not a predefined name, we cannot validate the return object */
183*a159c266SJung-uk Kim 
184*a159c266SJung-uk Kim     if (!Predefined)
185*a159c266SJung-uk Kim     {
186*a159c266SJung-uk Kim         goto Cleanup;
187*a159c266SJung-uk Kim     }
188*a159c266SJung-uk Kim 
189*a159c266SJung-uk Kim     /*
190*a159c266SJung-uk Kim      * If the method failed or did not actually return an object, we cannot
191*a159c266SJung-uk Kim      * validate the return object
192*a159c266SJung-uk Kim      */
193*a159c266SJung-uk Kim     if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
194*a159c266SJung-uk Kim     {
195*a159c266SJung-uk Kim         goto Cleanup;
196*a159c266SJung-uk Kim     }
197*a159c266SJung-uk Kim 
198*a159c266SJung-uk Kim     /*
199*a159c266SJung-uk Kim      * If there is no return value, check if we require a return value for
200*a159c266SJung-uk Kim      * this predefined name. Either one return value is expected, or none,
201*a159c266SJung-uk Kim      * for both methods and other objects.
202*a159c266SJung-uk Kim      *
203*a159c266SJung-uk Kim      * Exit now if there is no return object. Warning if one was expected.
204*a159c266SJung-uk Kim      */
205*a159c266SJung-uk Kim     if (!ReturnObject)
206*a159c266SJung-uk Kim     {
207*a159c266SJung-uk Kim         if ((Predefined->Info.ExpectedBtypes) &&
208*a159c266SJung-uk Kim             (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
209*a159c266SJung-uk Kim         {
210*a159c266SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
211*a159c266SJung-uk Kim                 "Missing expected return value"));
212*a159c266SJung-uk Kim 
213*a159c266SJung-uk Kim             Status = AE_AML_NO_RETURN_VALUE;
214*a159c266SJung-uk Kim         }
215*a159c266SJung-uk Kim         goto Cleanup;
216*a159c266SJung-uk Kim     }
217*a159c266SJung-uk Kim 
218*a159c266SJung-uk Kim     /*
219*a159c266SJung-uk Kim      * Return value validation and possible repair.
220*a159c266SJung-uk Kim      *
221*a159c266SJung-uk Kim      * 1) Don't perform return value validation/repair if this feature
222*a159c266SJung-uk Kim      * has been disabled via a global option.
223*a159c266SJung-uk Kim      *
224*a159c266SJung-uk Kim      * 2) We have a return value, but if one wasn't expected, just exit,
225*a159c266SJung-uk Kim      * this is not a problem. For example, if the "Implicit Return"
226*a159c266SJung-uk Kim      * feature is enabled, methods will always return a value.
227*a159c266SJung-uk Kim      *
228*a159c266SJung-uk Kim      * 3) If the return value can be of any type, then we cannot perform
229*a159c266SJung-uk Kim      * any validation, just exit.
230*a159c266SJung-uk Kim      */
231*a159c266SJung-uk Kim     if (AcpiGbl_DisableAutoRepair ||
232*a159c266SJung-uk Kim         (!Predefined->Info.ExpectedBtypes) ||
233*a159c266SJung-uk Kim         (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL))
234*a159c266SJung-uk Kim     {
235*a159c266SJung-uk Kim         goto Cleanup;
236*a159c266SJung-uk Kim     }
237*a159c266SJung-uk Kim 
238*a159c266SJung-uk Kim     /* Create the parameter data block for object validation */
239*a159c266SJung-uk Kim 
240*a159c266SJung-uk Kim     Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA));
241*a159c266SJung-uk Kim     if (!Data)
242*a159c266SJung-uk Kim     {
243*a159c266SJung-uk Kim         goto Cleanup;
244*a159c266SJung-uk Kim     }
245*a159c266SJung-uk Kim     Data->Predefined = Predefined;
246*a159c266SJung-uk Kim     Data->Node = Node;
247*a159c266SJung-uk Kim     Data->NodeFlags = Node->Flags;
248*a159c266SJung-uk Kim     Data->Pathname = Pathname;
249*a159c266SJung-uk Kim 
250*a159c266SJung-uk Kim     /*
251*a159c266SJung-uk Kim      * Check that the type of the main return object is what is expected
252*a159c266SJung-uk Kim      * for this predefined name
253*a159c266SJung-uk Kim      */
254*a159c266SJung-uk Kim     Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
255*a159c266SJung-uk Kim                 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
256*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
257*a159c266SJung-uk Kim     {
258*a159c266SJung-uk Kim         goto Exit;
259*a159c266SJung-uk Kim     }
260*a159c266SJung-uk Kim 
261*a159c266SJung-uk Kim     /*
262*a159c266SJung-uk Kim      * For returned Package objects, check the type of all sub-objects.
263*a159c266SJung-uk Kim      * Note: Package may have been newly created by call above.
264*a159c266SJung-uk Kim      */
265*a159c266SJung-uk Kim     if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
266*a159c266SJung-uk Kim     {
267*a159c266SJung-uk Kim         Data->ParentPackage = *ReturnObjectPtr;
268*a159c266SJung-uk Kim         Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
269*a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
270*a159c266SJung-uk Kim         {
271*a159c266SJung-uk Kim             goto Exit;
272*a159c266SJung-uk Kim         }
273*a159c266SJung-uk Kim     }
274*a159c266SJung-uk Kim 
275*a159c266SJung-uk Kim     /*
276*a159c266SJung-uk Kim      * The return object was OK, or it was successfully repaired above.
277*a159c266SJung-uk Kim      * Now make some additional checks such as verifying that package
278*a159c266SJung-uk Kim      * objects are sorted correctly (if required) or buffer objects have
279*a159c266SJung-uk Kim      * the correct data width (bytes vs. dwords). These repairs are
280*a159c266SJung-uk Kim      * performed on a per-name basis, i.e., the code is specific to
281*a159c266SJung-uk Kim      * particular predefined names.
282*a159c266SJung-uk Kim      */
283*a159c266SJung-uk Kim     Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr);
284*a159c266SJung-uk Kim 
285*a159c266SJung-uk Kim Exit:
286*a159c266SJung-uk Kim     /*
287*a159c266SJung-uk Kim      * If the object validation failed or if we successfully repaired one
288*a159c266SJung-uk Kim      * or more objects, mark the parent node to suppress further warning
289*a159c266SJung-uk Kim      * messages during the next evaluation of the same method/object.
290*a159c266SJung-uk Kim      */
291*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED))
292*a159c266SJung-uk Kim     {
293*a159c266SJung-uk Kim         Node->Flags |= ANOBJ_EVALUATED;
294*a159c266SJung-uk Kim     }
295*a159c266SJung-uk Kim     ACPI_FREE (Data);
296*a159c266SJung-uk Kim 
297*a159c266SJung-uk Kim Cleanup:
298*a159c266SJung-uk Kim     ACPI_FREE (Pathname);
299*a159c266SJung-uk Kim     return (Status);
300*a159c266SJung-uk Kim }
301*a159c266SJung-uk Kim 
302*a159c266SJung-uk Kim 
303*a159c266SJung-uk Kim /*******************************************************************************
304*a159c266SJung-uk Kim  *
305*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckParameterCount
306*a159c266SJung-uk Kim  *
307*a159c266SJung-uk Kim  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
308*a159c266SJung-uk Kim  *              Node            - Namespace node for the method/object
309*a159c266SJung-uk Kim  *              UserParamCount  - Number of args passed in by the caller
310*a159c266SJung-uk Kim  *              Predefined      - Pointer to entry in predefined name table
311*a159c266SJung-uk Kim  *
312*a159c266SJung-uk Kim  * RETURN:      None
313*a159c266SJung-uk Kim  *
314*a159c266SJung-uk Kim  * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
315*a159c266SJung-uk Kim  *              predefined name is what is expected (i.e., what is defined in
316*a159c266SJung-uk Kim  *              the ACPI specification for this predefined name.)
317*a159c266SJung-uk Kim  *
318*a159c266SJung-uk Kim  ******************************************************************************/
319*a159c266SJung-uk Kim 
320*a159c266SJung-uk Kim void
321*a159c266SJung-uk Kim AcpiNsCheckParameterCount (
322*a159c266SJung-uk Kim     char                        *Pathname,
323*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE         *Node,
324*a159c266SJung-uk Kim     UINT32                      UserParamCount,
325*a159c266SJung-uk Kim     const ACPI_PREDEFINED_INFO  *Predefined)
326*a159c266SJung-uk Kim {
327*a159c266SJung-uk Kim     UINT32                      ParamCount;
328*a159c266SJung-uk Kim     UINT32                      RequiredParamsCurrent;
329*a159c266SJung-uk Kim     UINT32                      RequiredParamsOld;
330*a159c266SJung-uk Kim 
331*a159c266SJung-uk Kim 
332*a159c266SJung-uk Kim     /* Methods have 0-7 parameters. All other types have zero. */
333*a159c266SJung-uk Kim 
334*a159c266SJung-uk Kim     ParamCount = 0;
335*a159c266SJung-uk Kim     if (Node->Type == ACPI_TYPE_METHOD)
336*a159c266SJung-uk Kim     {
337*a159c266SJung-uk Kim         ParamCount = Node->Object->Method.ParamCount;
338*a159c266SJung-uk Kim     }
339*a159c266SJung-uk Kim 
340*a159c266SJung-uk Kim     if (!Predefined)
341*a159c266SJung-uk Kim     {
342*a159c266SJung-uk Kim         /*
343*a159c266SJung-uk Kim          * Check the parameter count for non-predefined methods/objects.
344*a159c266SJung-uk Kim          *
345*a159c266SJung-uk Kim          * Warning if too few or too many arguments have been passed by the
346*a159c266SJung-uk Kim          * caller. An incorrect number of arguments may not cause the method
347*a159c266SJung-uk Kim          * to fail. However, the method will fail if there are too few
348*a159c266SJung-uk Kim          * arguments and the method attempts to use one of the missing ones.
349*a159c266SJung-uk Kim          */
350*a159c266SJung-uk Kim         if (UserParamCount < ParamCount)
351*a159c266SJung-uk Kim         {
352*a159c266SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
353*a159c266SJung-uk Kim                 "Insufficient arguments - needs %u, found %u",
354*a159c266SJung-uk Kim                 ParamCount, UserParamCount));
355*a159c266SJung-uk Kim         }
356*a159c266SJung-uk Kim         else if (UserParamCount > ParamCount)
357*a159c266SJung-uk Kim         {
358*a159c266SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
359*a159c266SJung-uk Kim                 "Excess arguments - needs %u, found %u",
360*a159c266SJung-uk Kim                 ParamCount, UserParamCount));
361*a159c266SJung-uk Kim         }
362*a159c266SJung-uk Kim         return;
363*a159c266SJung-uk Kim     }
364*a159c266SJung-uk Kim 
365*a159c266SJung-uk Kim     /*
366*a159c266SJung-uk Kim      * Validate the user-supplied parameter count.
367*a159c266SJung-uk Kim      * Allow two different legal argument counts (_SCP, etc.)
368*a159c266SJung-uk Kim      */
369*a159c266SJung-uk Kim     RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
370*a159c266SJung-uk Kim     RequiredParamsOld = Predefined->Info.ParamCount >> 4;
371*a159c266SJung-uk Kim 
372*a159c266SJung-uk Kim     if (UserParamCount != ACPI_UINT32_MAX)
373*a159c266SJung-uk Kim     {
374*a159c266SJung-uk Kim         if ((UserParamCount != RequiredParamsCurrent) &&
375*a159c266SJung-uk Kim             (UserParamCount != RequiredParamsOld))
376*a159c266SJung-uk Kim         {
377*a159c266SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
378*a159c266SJung-uk Kim                 "Parameter count mismatch - "
379*a159c266SJung-uk Kim                 "caller passed %u, ACPI requires %u",
380*a159c266SJung-uk Kim                 UserParamCount, RequiredParamsCurrent));
381*a159c266SJung-uk Kim         }
382*a159c266SJung-uk Kim     }
383*a159c266SJung-uk Kim 
384*a159c266SJung-uk Kim     /*
385*a159c266SJung-uk Kim      * Check that the ASL-defined parameter count is what is expected for
386*a159c266SJung-uk Kim      * this predefined name (parameter count as defined by the ACPI
387*a159c266SJung-uk Kim      * specification)
388*a159c266SJung-uk Kim      */
389*a159c266SJung-uk Kim     if ((ParamCount != RequiredParamsCurrent) &&
390*a159c266SJung-uk Kim         (ParamCount != RequiredParamsOld))
391*a159c266SJung-uk Kim     {
392*a159c266SJung-uk Kim         ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags,
393*a159c266SJung-uk Kim             "Parameter count mismatch - ASL declared %u, ACPI requires %u",
394*a159c266SJung-uk Kim             ParamCount, RequiredParamsCurrent));
395*a159c266SJung-uk Kim     }
396*a159c266SJung-uk Kim }
397*a159c266SJung-uk Kim 
398*a159c266SJung-uk Kim 
399*a159c266SJung-uk Kim /*******************************************************************************
400*a159c266SJung-uk Kim  *
401*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckForPredefinedName
402*a159c266SJung-uk Kim  *
403*a159c266SJung-uk Kim  * PARAMETERS:  Node            - Namespace node for the method/object
404*a159c266SJung-uk Kim  *
405*a159c266SJung-uk Kim  * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
406*a159c266SJung-uk Kim  *
407*a159c266SJung-uk Kim  * DESCRIPTION: Check an object name against the predefined object list.
408*a159c266SJung-uk Kim  *
409*a159c266SJung-uk Kim  ******************************************************************************/
410*a159c266SJung-uk Kim 
411*a159c266SJung-uk Kim const ACPI_PREDEFINED_INFO *
412*a159c266SJung-uk Kim AcpiNsCheckForPredefinedName (
413*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE         *Node)
414*a159c266SJung-uk Kim {
415*a159c266SJung-uk Kim     const ACPI_PREDEFINED_INFO  *ThisName;
416*a159c266SJung-uk Kim 
417*a159c266SJung-uk Kim 
418*a159c266SJung-uk Kim     /* Quick check for a predefined name, first character must be underscore */
419*a159c266SJung-uk Kim 
420*a159c266SJung-uk Kim     if (Node->Name.Ascii[0] != '_')
421*a159c266SJung-uk Kim     {
422*a159c266SJung-uk Kim         return (NULL);
423*a159c266SJung-uk Kim     }
424*a159c266SJung-uk Kim 
425*a159c266SJung-uk Kim     /* Search info table for a predefined method/object name */
426*a159c266SJung-uk Kim 
427*a159c266SJung-uk Kim     ThisName = PredefinedNames;
428*a159c266SJung-uk Kim     while (ThisName->Info.Name[0])
429*a159c266SJung-uk Kim     {
430*a159c266SJung-uk Kim         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
431*a159c266SJung-uk Kim         {
432*a159c266SJung-uk Kim             return (ThisName);
433*a159c266SJung-uk Kim         }
434*a159c266SJung-uk Kim 
435*a159c266SJung-uk Kim         /*
436*a159c266SJung-uk Kim          * Skip next entry in the table if this name returns a Package
437*a159c266SJung-uk Kim          * (next entry contains the package info)
438*a159c266SJung-uk Kim          */
439*a159c266SJung-uk Kim         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
440*a159c266SJung-uk Kim         {
441*a159c266SJung-uk Kim             ThisName++;
442*a159c266SJung-uk Kim         }
443*a159c266SJung-uk Kim 
444*a159c266SJung-uk Kim         ThisName++;
445*a159c266SJung-uk Kim     }
446*a159c266SJung-uk Kim 
447*a159c266SJung-uk Kim     return (NULL); /* Not found */
448*a159c266SJung-uk Kim }
449*a159c266SJung-uk Kim 
450*a159c266SJung-uk Kim 
451*a159c266SJung-uk Kim /*******************************************************************************
452*a159c266SJung-uk Kim  *
453*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckPackage
454*a159c266SJung-uk Kim  *
455*a159c266SJung-uk Kim  * PARAMETERS:  Data            - Pointer to validation data structure
456*a159c266SJung-uk Kim  *              ReturnObjectPtr - Pointer to the object returned from the
457*a159c266SJung-uk Kim  *                                evaluation of a method or object
458*a159c266SJung-uk Kim  *
459*a159c266SJung-uk Kim  * RETURN:      Status
460*a159c266SJung-uk Kim  *
461*a159c266SJung-uk Kim  * DESCRIPTION: Check a returned package object for the correct count and
462*a159c266SJung-uk Kim  *              correct type of all sub-objects.
463*a159c266SJung-uk Kim  *
464*a159c266SJung-uk Kim  ******************************************************************************/
465*a159c266SJung-uk Kim 
466*a159c266SJung-uk Kim static ACPI_STATUS
467*a159c266SJung-uk Kim AcpiNsCheckPackage (
468*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
469*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
470*a159c266SJung-uk Kim {
471*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
472*a159c266SJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package;
473*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **Elements;
474*a159c266SJung-uk Kim     ACPI_STATUS                 Status = AE_OK;
475*a159c266SJung-uk Kim     UINT32                      ExpectedCount;
476*a159c266SJung-uk Kim     UINT32                      Count;
477*a159c266SJung-uk Kim     UINT32                      i;
478*a159c266SJung-uk Kim 
479*a159c266SJung-uk Kim 
480*a159c266SJung-uk Kim     ACPI_FUNCTION_NAME (NsCheckPackage);
481*a159c266SJung-uk Kim 
482*a159c266SJung-uk Kim 
483*a159c266SJung-uk Kim     /* The package info for this name is in the next table entry */
484*a159c266SJung-uk Kim 
485*a159c266SJung-uk Kim     Package = Data->Predefined + 1;
486*a159c266SJung-uk Kim 
487*a159c266SJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
488*a159c266SJung-uk Kim         "%s Validating return Package of Type %X, Count %X\n",
489*a159c266SJung-uk Kim         Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
490*a159c266SJung-uk Kim 
491*a159c266SJung-uk Kim     /*
492*a159c266SJung-uk Kim      * For variable-length Packages, we can safely remove all embedded
493*a159c266SJung-uk Kim      * and trailing NULL package elements
494*a159c266SJung-uk Kim      */
495*a159c266SJung-uk Kim     AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject);
496*a159c266SJung-uk Kim 
497*a159c266SJung-uk Kim     /* Extract package count and elements array */
498*a159c266SJung-uk Kim 
499*a159c266SJung-uk Kim     Elements = ReturnObject->Package.Elements;
500*a159c266SJung-uk Kim     Count = ReturnObject->Package.Count;
501*a159c266SJung-uk Kim 
502*a159c266SJung-uk Kim     /* The package must have at least one element, else invalid */
503*a159c266SJung-uk Kim 
504*a159c266SJung-uk Kim     if (!Count)
505*a159c266SJung-uk Kim     {
506*a159c266SJung-uk Kim         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
507*a159c266SJung-uk Kim             "Return Package has no elements (empty)"));
508*a159c266SJung-uk Kim 
509*a159c266SJung-uk Kim         return (AE_AML_OPERAND_VALUE);
510*a159c266SJung-uk Kim     }
511*a159c266SJung-uk Kim 
512*a159c266SJung-uk Kim     /*
513*a159c266SJung-uk Kim      * Decode the type of the expected package contents
514*a159c266SJung-uk Kim      *
515*a159c266SJung-uk Kim      * PTYPE1 packages contain no subpackages
516*a159c266SJung-uk Kim      * PTYPE2 packages contain sub-packages
517*a159c266SJung-uk Kim      */
518*a159c266SJung-uk Kim     switch (Package->RetInfo.Type)
519*a159c266SJung-uk Kim     {
520*a159c266SJung-uk Kim     case ACPI_PTYPE1_FIXED:
521*a159c266SJung-uk Kim 
522*a159c266SJung-uk Kim         /*
523*a159c266SJung-uk Kim          * The package count is fixed and there are no sub-packages
524*a159c266SJung-uk Kim          *
525*a159c266SJung-uk Kim          * If package is too small, exit.
526*a159c266SJung-uk Kim          * If package is larger than expected, issue warning but continue
527*a159c266SJung-uk Kim          */
528*a159c266SJung-uk Kim         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
529*a159c266SJung-uk Kim         if (Count < ExpectedCount)
530*a159c266SJung-uk Kim         {
531*a159c266SJung-uk Kim             goto PackageTooSmall;
532*a159c266SJung-uk Kim         }
533*a159c266SJung-uk Kim         else if (Count > ExpectedCount)
534*a159c266SJung-uk Kim         {
535*a159c266SJung-uk Kim             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
536*a159c266SJung-uk Kim                 "%s: Return Package is larger than needed - "
537*a159c266SJung-uk Kim                 "found %u, expected %u\n",
538*a159c266SJung-uk Kim                 Data->Pathname, Count, ExpectedCount));
539*a159c266SJung-uk Kim         }
540*a159c266SJung-uk Kim 
541*a159c266SJung-uk Kim         /* Validate all elements of the returned package */
542*a159c266SJung-uk Kim 
543*a159c266SJung-uk Kim         Status = AcpiNsCheckPackageElements (Data, Elements,
544*a159c266SJung-uk Kim                     Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
545*a159c266SJung-uk Kim                     Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
546*a159c266SJung-uk Kim         break;
547*a159c266SJung-uk Kim 
548*a159c266SJung-uk Kim 
549*a159c266SJung-uk Kim     case ACPI_PTYPE1_VAR:
550*a159c266SJung-uk Kim 
551*a159c266SJung-uk Kim         /*
552*a159c266SJung-uk Kim          * The package count is variable, there are no sub-packages, and all
553*a159c266SJung-uk Kim          * elements must be of the same type
554*a159c266SJung-uk Kim          */
555*a159c266SJung-uk Kim         for (i = 0; i < Count; i++)
556*a159c266SJung-uk Kim         {
557*a159c266SJung-uk Kim             Status = AcpiNsCheckObjectType (Data, Elements,
558*a159c266SJung-uk Kim                         Package->RetInfo.ObjectType1, i);
559*a159c266SJung-uk Kim             if (ACPI_FAILURE (Status))
560*a159c266SJung-uk Kim             {
561*a159c266SJung-uk Kim                 return (Status);
562*a159c266SJung-uk Kim             }
563*a159c266SJung-uk Kim             Elements++;
564*a159c266SJung-uk Kim         }
565*a159c266SJung-uk Kim         break;
566*a159c266SJung-uk Kim 
567*a159c266SJung-uk Kim 
568*a159c266SJung-uk Kim     case ACPI_PTYPE1_OPTION:
569*a159c266SJung-uk Kim 
570*a159c266SJung-uk Kim         /*
571*a159c266SJung-uk Kim          * The package count is variable, there are no sub-packages. There are
572*a159c266SJung-uk Kim          * a fixed number of required elements, and a variable number of
573*a159c266SJung-uk Kim          * optional elements.
574*a159c266SJung-uk Kim          *
575*a159c266SJung-uk Kim          * Check if package is at least as large as the minimum required
576*a159c266SJung-uk Kim          */
577*a159c266SJung-uk Kim         ExpectedCount = Package->RetInfo3.Count;
578*a159c266SJung-uk Kim         if (Count < ExpectedCount)
579*a159c266SJung-uk Kim         {
580*a159c266SJung-uk Kim             goto PackageTooSmall;
581*a159c266SJung-uk Kim         }
582*a159c266SJung-uk Kim 
583*a159c266SJung-uk Kim         /* Variable number of sub-objects */
584*a159c266SJung-uk Kim 
585*a159c266SJung-uk Kim         for (i = 0; i < Count; i++)
586*a159c266SJung-uk Kim         {
587*a159c266SJung-uk Kim             if (i < Package->RetInfo3.Count)
588*a159c266SJung-uk Kim             {
589*a159c266SJung-uk Kim                 /* These are the required package elements (0, 1, or 2) */
590*a159c266SJung-uk Kim 
591*a159c266SJung-uk Kim                 Status = AcpiNsCheckObjectType (Data, Elements,
592*a159c266SJung-uk Kim                             Package->RetInfo3.ObjectType[i], i);
593*a159c266SJung-uk Kim                 if (ACPI_FAILURE (Status))
594*a159c266SJung-uk Kim                 {
595*a159c266SJung-uk Kim                     return (Status);
596*a159c266SJung-uk Kim                 }
597*a159c266SJung-uk Kim             }
598*a159c266SJung-uk Kim             else
599*a159c266SJung-uk Kim             {
600*a159c266SJung-uk Kim                 /* These are the optional package elements */
601*a159c266SJung-uk Kim 
602*a159c266SJung-uk Kim                 Status = AcpiNsCheckObjectType (Data, Elements,
603*a159c266SJung-uk Kim                             Package->RetInfo3.TailObjectType, i);
604*a159c266SJung-uk Kim                 if (ACPI_FAILURE (Status))
605*a159c266SJung-uk Kim                 {
606*a159c266SJung-uk Kim                     return (Status);
607*a159c266SJung-uk Kim                 }
608*a159c266SJung-uk Kim             }
609*a159c266SJung-uk Kim             Elements++;
610*a159c266SJung-uk Kim         }
611*a159c266SJung-uk Kim         break;
612*a159c266SJung-uk Kim 
613*a159c266SJung-uk Kim 
614*a159c266SJung-uk Kim     case ACPI_PTYPE2_REV_FIXED:
615*a159c266SJung-uk Kim 
616*a159c266SJung-uk Kim         /* First element is the (Integer) revision */
617*a159c266SJung-uk Kim 
618*a159c266SJung-uk Kim         Status = AcpiNsCheckObjectType (Data, Elements,
619*a159c266SJung-uk Kim                     ACPI_RTYPE_INTEGER, 0);
620*a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
621*a159c266SJung-uk Kim         {
622*a159c266SJung-uk Kim             return (Status);
623*a159c266SJung-uk Kim         }
624*a159c266SJung-uk Kim 
625*a159c266SJung-uk Kim         Elements++;
626*a159c266SJung-uk Kim         Count--;
627*a159c266SJung-uk Kim 
628*a159c266SJung-uk Kim         /* Examine the sub-packages */
629*a159c266SJung-uk Kim 
630*a159c266SJung-uk Kim         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
631*a159c266SJung-uk Kim         break;
632*a159c266SJung-uk Kim 
633*a159c266SJung-uk Kim 
634*a159c266SJung-uk Kim     case ACPI_PTYPE2_PKG_COUNT:
635*a159c266SJung-uk Kim 
636*a159c266SJung-uk Kim         /* First element is the (Integer) count of sub-packages to follow */
637*a159c266SJung-uk Kim 
638*a159c266SJung-uk Kim         Status = AcpiNsCheckObjectType (Data, Elements,
639*a159c266SJung-uk Kim                     ACPI_RTYPE_INTEGER, 0);
640*a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
641*a159c266SJung-uk Kim         {
642*a159c266SJung-uk Kim             return (Status);
643*a159c266SJung-uk Kim         }
644*a159c266SJung-uk Kim 
645*a159c266SJung-uk Kim         /*
646*a159c266SJung-uk Kim          * Count cannot be larger than the parent package length, but allow it
647*a159c266SJung-uk Kim          * to be smaller. The >= accounts for the Integer above.
648*a159c266SJung-uk Kim          */
649*a159c266SJung-uk Kim         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
650*a159c266SJung-uk Kim         if (ExpectedCount >= Count)
651*a159c266SJung-uk Kim         {
652*a159c266SJung-uk Kim             goto PackageTooSmall;
653*a159c266SJung-uk Kim         }
654*a159c266SJung-uk Kim 
655*a159c266SJung-uk Kim         Count = ExpectedCount;
656*a159c266SJung-uk Kim         Elements++;
657*a159c266SJung-uk Kim 
658*a159c266SJung-uk Kim         /* Examine the sub-packages */
659*a159c266SJung-uk Kim 
660*a159c266SJung-uk Kim         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
661*a159c266SJung-uk Kim         break;
662*a159c266SJung-uk Kim 
663*a159c266SJung-uk Kim 
664*a159c266SJung-uk Kim     case ACPI_PTYPE2:
665*a159c266SJung-uk Kim     case ACPI_PTYPE2_FIXED:
666*a159c266SJung-uk Kim     case ACPI_PTYPE2_MIN:
667*a159c266SJung-uk Kim     case ACPI_PTYPE2_COUNT:
668*a159c266SJung-uk Kim     case ACPI_PTYPE2_FIX_VAR:
669*a159c266SJung-uk Kim 
670*a159c266SJung-uk Kim         /*
671*a159c266SJung-uk Kim          * These types all return a single Package that consists of a
672*a159c266SJung-uk Kim          * variable number of sub-Packages.
673*a159c266SJung-uk Kim          *
674*a159c266SJung-uk Kim          * First, ensure that the first element is a sub-Package. If not,
675*a159c266SJung-uk Kim          * the BIOS may have incorrectly returned the object as a single
676*a159c266SJung-uk Kim          * package instead of a Package of Packages (a common error if
677*a159c266SJung-uk Kim          * there is only one entry). We may be able to repair this by
678*a159c266SJung-uk Kim          * wrapping the returned Package with a new outer Package.
679*a159c266SJung-uk Kim          */
680*a159c266SJung-uk Kim         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
681*a159c266SJung-uk Kim         {
682*a159c266SJung-uk Kim             /* Create the new outer package and populate it */
683*a159c266SJung-uk Kim 
684*a159c266SJung-uk Kim             Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr);
685*a159c266SJung-uk Kim             if (ACPI_FAILURE (Status))
686*a159c266SJung-uk Kim             {
687*a159c266SJung-uk Kim                 return (Status);
688*a159c266SJung-uk Kim             }
689*a159c266SJung-uk Kim 
690*a159c266SJung-uk Kim             /* Update locals to point to the new package (of 1 element) */
691*a159c266SJung-uk Kim 
692*a159c266SJung-uk Kim             ReturnObject = *ReturnObjectPtr;
693*a159c266SJung-uk Kim             Elements = ReturnObject->Package.Elements;
694*a159c266SJung-uk Kim             Count = 1;
695*a159c266SJung-uk Kim         }
696*a159c266SJung-uk Kim 
697*a159c266SJung-uk Kim         /* Examine the sub-packages */
698*a159c266SJung-uk Kim 
699*a159c266SJung-uk Kim         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
700*a159c266SJung-uk Kim         break;
701*a159c266SJung-uk Kim 
702*a159c266SJung-uk Kim 
703*a159c266SJung-uk Kim     default:
704*a159c266SJung-uk Kim 
705*a159c266SJung-uk Kim         /* Should not get here if predefined info table is correct */
706*a159c266SJung-uk Kim 
707*a159c266SJung-uk Kim         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
708*a159c266SJung-uk Kim             "Invalid internal return type in table entry: %X",
709*a159c266SJung-uk Kim             Package->RetInfo.Type));
710*a159c266SJung-uk Kim 
711*a159c266SJung-uk Kim         return (AE_AML_INTERNAL);
712*a159c266SJung-uk Kim     }
713*a159c266SJung-uk Kim 
714*a159c266SJung-uk Kim     return (Status);
715*a159c266SJung-uk Kim 
716*a159c266SJung-uk Kim 
717*a159c266SJung-uk Kim PackageTooSmall:
718*a159c266SJung-uk Kim 
719*a159c266SJung-uk Kim     /* Error exit for the case with an incorrect package count */
720*a159c266SJung-uk Kim 
721*a159c266SJung-uk Kim     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
722*a159c266SJung-uk Kim         "Return Package is too small - found %u elements, expected %u",
723*a159c266SJung-uk Kim         Count, ExpectedCount));
724*a159c266SJung-uk Kim 
725*a159c266SJung-uk Kim     return (AE_AML_OPERAND_VALUE);
726*a159c266SJung-uk Kim }
727*a159c266SJung-uk Kim 
728*a159c266SJung-uk Kim 
729*a159c266SJung-uk Kim /*******************************************************************************
730*a159c266SJung-uk Kim  *
731*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckPackageList
732*a159c266SJung-uk Kim  *
733*a159c266SJung-uk Kim  * PARAMETERS:  Data            - Pointer to validation data structure
734*a159c266SJung-uk Kim  *              Package         - Pointer to package-specific info for method
735*a159c266SJung-uk Kim  *              Elements        - Element list of parent package. All elements
736*a159c266SJung-uk Kim  *                                of this list should be of type Package.
737*a159c266SJung-uk Kim  *              Count           - Count of subpackages
738*a159c266SJung-uk Kim  *
739*a159c266SJung-uk Kim  * RETURN:      Status
740*a159c266SJung-uk Kim  *
741*a159c266SJung-uk Kim  * DESCRIPTION: Examine a list of subpackages
742*a159c266SJung-uk Kim  *
743*a159c266SJung-uk Kim  ******************************************************************************/
744*a159c266SJung-uk Kim 
745*a159c266SJung-uk Kim static ACPI_STATUS
746*a159c266SJung-uk Kim AcpiNsCheckPackageList (
747*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
748*a159c266SJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package,
749*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **Elements,
750*a159c266SJung-uk Kim     UINT32                      Count)
751*a159c266SJung-uk Kim {
752*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         *SubPackage;
753*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **SubElements;
754*a159c266SJung-uk Kim     ACPI_STATUS                 Status;
755*a159c266SJung-uk Kim     UINT32                      ExpectedCount;
756*a159c266SJung-uk Kim     UINT32                      i;
757*a159c266SJung-uk Kim     UINT32                      j;
758*a159c266SJung-uk Kim 
759*a159c266SJung-uk Kim 
760*a159c266SJung-uk Kim     /*
761*a159c266SJung-uk Kim      * Validate each sub-Package in the parent Package
762*a159c266SJung-uk Kim      *
763*a159c266SJung-uk Kim      * NOTE: assumes list of sub-packages contains no NULL elements.
764*a159c266SJung-uk Kim      * Any NULL elements should have been removed by earlier call
765*a159c266SJung-uk Kim      * to AcpiNsRemoveNullElements.
766*a159c266SJung-uk Kim      */
767*a159c266SJung-uk Kim     for (i = 0; i < Count; i++)
768*a159c266SJung-uk Kim     {
769*a159c266SJung-uk Kim         SubPackage = *Elements;
770*a159c266SJung-uk Kim         SubElements = SubPackage->Package.Elements;
771*a159c266SJung-uk Kim         Data->ParentPackage = SubPackage;
772*a159c266SJung-uk Kim 
773*a159c266SJung-uk Kim         /* Each sub-object must be of type Package */
774*a159c266SJung-uk Kim 
775*a159c266SJung-uk Kim         Status = AcpiNsCheckObjectType (Data, &SubPackage,
776*a159c266SJung-uk Kim                     ACPI_RTYPE_PACKAGE, i);
777*a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
778*a159c266SJung-uk Kim         {
779*a159c266SJung-uk Kim             return (Status);
780*a159c266SJung-uk Kim         }
781*a159c266SJung-uk Kim 
782*a159c266SJung-uk Kim         /* Examine the different types of expected sub-packages */
783*a159c266SJung-uk Kim 
784*a159c266SJung-uk Kim         Data->ParentPackage = SubPackage;
785*a159c266SJung-uk Kim         switch (Package->RetInfo.Type)
786*a159c266SJung-uk Kim         {
787*a159c266SJung-uk Kim         case ACPI_PTYPE2:
788*a159c266SJung-uk Kim         case ACPI_PTYPE2_PKG_COUNT:
789*a159c266SJung-uk Kim         case ACPI_PTYPE2_REV_FIXED:
790*a159c266SJung-uk Kim 
791*a159c266SJung-uk Kim             /* Each subpackage has a fixed number of elements */
792*a159c266SJung-uk Kim 
793*a159c266SJung-uk Kim             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
794*a159c266SJung-uk Kim             if (SubPackage->Package.Count < ExpectedCount)
795*a159c266SJung-uk Kim             {
796*a159c266SJung-uk Kim                 goto PackageTooSmall;
797*a159c266SJung-uk Kim             }
798*a159c266SJung-uk Kim 
799*a159c266SJung-uk Kim             Status = AcpiNsCheckPackageElements (Data, SubElements,
800*a159c266SJung-uk Kim                         Package->RetInfo.ObjectType1,
801*a159c266SJung-uk Kim                         Package->RetInfo.Count1,
802*a159c266SJung-uk Kim                         Package->RetInfo.ObjectType2,
803*a159c266SJung-uk Kim                         Package->RetInfo.Count2, 0);
804*a159c266SJung-uk Kim             if (ACPI_FAILURE (Status))
805*a159c266SJung-uk Kim             {
806*a159c266SJung-uk Kim                 return (Status);
807*a159c266SJung-uk Kim             }
808*a159c266SJung-uk Kim             break;
809*a159c266SJung-uk Kim 
810*a159c266SJung-uk Kim 
811*a159c266SJung-uk Kim         case ACPI_PTYPE2_FIX_VAR:
812*a159c266SJung-uk Kim             /*
813*a159c266SJung-uk Kim              * Each subpackage has a fixed number of elements and an
814*a159c266SJung-uk Kim              * optional element
815*a159c266SJung-uk Kim              */
816*a159c266SJung-uk Kim             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
817*a159c266SJung-uk Kim             if (SubPackage->Package.Count < ExpectedCount)
818*a159c266SJung-uk Kim             {
819*a159c266SJung-uk Kim                 goto PackageTooSmall;
820*a159c266SJung-uk Kim             }
821*a159c266SJung-uk Kim 
822*a159c266SJung-uk Kim             Status = AcpiNsCheckPackageElements (Data, SubElements,
823*a159c266SJung-uk Kim                         Package->RetInfo.ObjectType1,
824*a159c266SJung-uk Kim                         Package->RetInfo.Count1,
825*a159c266SJung-uk Kim                         Package->RetInfo.ObjectType2,
826*a159c266SJung-uk Kim                         SubPackage->Package.Count - Package->RetInfo.Count1, 0);
827*a159c266SJung-uk Kim             if (ACPI_FAILURE (Status))
828*a159c266SJung-uk Kim             {
829*a159c266SJung-uk Kim                 return (Status);
830*a159c266SJung-uk Kim             }
831*a159c266SJung-uk Kim             break;
832*a159c266SJung-uk Kim 
833*a159c266SJung-uk Kim 
834*a159c266SJung-uk Kim         case ACPI_PTYPE2_FIXED:
835*a159c266SJung-uk Kim 
836*a159c266SJung-uk Kim             /* Each sub-package has a fixed length */
837*a159c266SJung-uk Kim 
838*a159c266SJung-uk Kim             ExpectedCount = Package->RetInfo2.Count;
839*a159c266SJung-uk Kim             if (SubPackage->Package.Count < ExpectedCount)
840*a159c266SJung-uk Kim             {
841*a159c266SJung-uk Kim                 goto PackageTooSmall;
842*a159c266SJung-uk Kim             }
843*a159c266SJung-uk Kim 
844*a159c266SJung-uk Kim             /* Check the type of each sub-package element */
845*a159c266SJung-uk Kim 
846*a159c266SJung-uk Kim             for (j = 0; j < ExpectedCount; j++)
847*a159c266SJung-uk Kim             {
848*a159c266SJung-uk Kim                 Status = AcpiNsCheckObjectType (Data, &SubElements[j],
849*a159c266SJung-uk Kim                             Package->RetInfo2.ObjectType[j], j);
850*a159c266SJung-uk Kim                 if (ACPI_FAILURE (Status))
851*a159c266SJung-uk Kim                 {
852*a159c266SJung-uk Kim                     return (Status);
853*a159c266SJung-uk Kim                 }
854*a159c266SJung-uk Kim             }
855*a159c266SJung-uk Kim             break;
856*a159c266SJung-uk Kim 
857*a159c266SJung-uk Kim 
858*a159c266SJung-uk Kim         case ACPI_PTYPE2_MIN:
859*a159c266SJung-uk Kim 
860*a159c266SJung-uk Kim             /* Each sub-package has a variable but minimum length */
861*a159c266SJung-uk Kim 
862*a159c266SJung-uk Kim             ExpectedCount = Package->RetInfo.Count1;
863*a159c266SJung-uk Kim             if (SubPackage->Package.Count < ExpectedCount)
864*a159c266SJung-uk Kim             {
865*a159c266SJung-uk Kim                 goto PackageTooSmall;
866*a159c266SJung-uk Kim             }
867*a159c266SJung-uk Kim 
868*a159c266SJung-uk Kim             /* Check the type of each sub-package element */
869*a159c266SJung-uk Kim 
870*a159c266SJung-uk Kim             Status = AcpiNsCheckPackageElements (Data, SubElements,
871*a159c266SJung-uk Kim                         Package->RetInfo.ObjectType1,
872*a159c266SJung-uk Kim                         SubPackage->Package.Count, 0, 0, 0);
873*a159c266SJung-uk Kim             if (ACPI_FAILURE (Status))
874*a159c266SJung-uk Kim             {
875*a159c266SJung-uk Kim                 return (Status);
876*a159c266SJung-uk Kim             }
877*a159c266SJung-uk Kim             break;
878*a159c266SJung-uk Kim 
879*a159c266SJung-uk Kim 
880*a159c266SJung-uk Kim         case ACPI_PTYPE2_COUNT:
881*a159c266SJung-uk Kim 
882*a159c266SJung-uk Kim             /*
883*a159c266SJung-uk Kim              * First element is the (Integer) count of elements, including
884*a159c266SJung-uk Kim              * the count field (the ACPI name is NumElements)
885*a159c266SJung-uk Kim              */
886*a159c266SJung-uk Kim             Status = AcpiNsCheckObjectType (Data, SubElements,
887*a159c266SJung-uk Kim                         ACPI_RTYPE_INTEGER, 0);
888*a159c266SJung-uk Kim             if (ACPI_FAILURE (Status))
889*a159c266SJung-uk Kim             {
890*a159c266SJung-uk Kim                 return (Status);
891*a159c266SJung-uk Kim             }
892*a159c266SJung-uk Kim 
893*a159c266SJung-uk Kim             /*
894*a159c266SJung-uk Kim              * Make sure package is large enough for the Count and is
895*a159c266SJung-uk Kim              * is as large as the minimum size
896*a159c266SJung-uk Kim              */
897*a159c266SJung-uk Kim             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
898*a159c266SJung-uk Kim             if (SubPackage->Package.Count < ExpectedCount)
899*a159c266SJung-uk Kim             {
900*a159c266SJung-uk Kim                 goto PackageTooSmall;
901*a159c266SJung-uk Kim             }
902*a159c266SJung-uk Kim             if (SubPackage->Package.Count < Package->RetInfo.Count1)
903*a159c266SJung-uk Kim             {
904*a159c266SJung-uk Kim                 ExpectedCount = Package->RetInfo.Count1;
905*a159c266SJung-uk Kim                 goto PackageTooSmall;
906*a159c266SJung-uk Kim             }
907*a159c266SJung-uk Kim             if (ExpectedCount == 0)
908*a159c266SJung-uk Kim             {
909*a159c266SJung-uk Kim                 /*
910*a159c266SJung-uk Kim                  * Either the NumEntries element was originally zero or it was
911*a159c266SJung-uk Kim                  * a NULL element and repaired to an Integer of value zero.
912*a159c266SJung-uk Kim                  * In either case, repair it by setting NumEntries to be the
913*a159c266SJung-uk Kim                  * actual size of the subpackage.
914*a159c266SJung-uk Kim                  */
915*a159c266SJung-uk Kim                 ExpectedCount = SubPackage->Package.Count;
916*a159c266SJung-uk Kim                 (*SubElements)->Integer.Value = ExpectedCount;
917*a159c266SJung-uk Kim             }
918*a159c266SJung-uk Kim 
919*a159c266SJung-uk Kim             /* Check the type of each sub-package element */
920*a159c266SJung-uk Kim 
921*a159c266SJung-uk Kim             Status = AcpiNsCheckPackageElements (Data, (SubElements + 1),
922*a159c266SJung-uk Kim                         Package->RetInfo.ObjectType1,
923*a159c266SJung-uk Kim                         (ExpectedCount - 1), 0, 0, 1);
924*a159c266SJung-uk Kim             if (ACPI_FAILURE (Status))
925*a159c266SJung-uk Kim             {
926*a159c266SJung-uk Kim                 return (Status);
927*a159c266SJung-uk Kim             }
928*a159c266SJung-uk Kim             break;
929*a159c266SJung-uk Kim 
930*a159c266SJung-uk Kim 
931*a159c266SJung-uk Kim         default: /* Should not get here, type was validated by caller */
932*a159c266SJung-uk Kim 
933*a159c266SJung-uk Kim             return (AE_AML_INTERNAL);
934*a159c266SJung-uk Kim         }
935*a159c266SJung-uk Kim 
936*a159c266SJung-uk Kim         Elements++;
937*a159c266SJung-uk Kim     }
938*a159c266SJung-uk Kim 
939*a159c266SJung-uk Kim     return (AE_OK);
940*a159c266SJung-uk Kim 
941*a159c266SJung-uk Kim 
942*a159c266SJung-uk Kim PackageTooSmall:
943*a159c266SJung-uk Kim 
944*a159c266SJung-uk Kim     /* The sub-package count was smaller than required */
945*a159c266SJung-uk Kim 
946*a159c266SJung-uk Kim     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
947*a159c266SJung-uk Kim         "Return Sub-Package[%u] is too small - found %u elements, expected %u",
948*a159c266SJung-uk Kim         i, SubPackage->Package.Count, ExpectedCount));
949*a159c266SJung-uk Kim 
950*a159c266SJung-uk Kim     return (AE_AML_OPERAND_VALUE);
951*a159c266SJung-uk Kim }
952*a159c266SJung-uk Kim 
953*a159c266SJung-uk Kim 
954*a159c266SJung-uk Kim /*******************************************************************************
955*a159c266SJung-uk Kim  *
956*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckPackageElements
957*a159c266SJung-uk Kim  *
958*a159c266SJung-uk Kim  * PARAMETERS:  Data            - Pointer to validation data structure
959*a159c266SJung-uk Kim  *              Elements        - Pointer to the package elements array
960*a159c266SJung-uk Kim  *              Type1           - Object type for first group
961*a159c266SJung-uk Kim  *              Count1          - Count for first group
962*a159c266SJung-uk Kim  *              Type2           - Object type for second group
963*a159c266SJung-uk Kim  *              Count2          - Count for second group
964*a159c266SJung-uk Kim  *              StartIndex      - Start of the first group of elements
965*a159c266SJung-uk Kim  *
966*a159c266SJung-uk Kim  * RETURN:      Status
967*a159c266SJung-uk Kim  *
968*a159c266SJung-uk Kim  * DESCRIPTION: Check that all elements of a package are of the correct object
969*a159c266SJung-uk Kim  *              type. Supports up to two groups of different object types.
970*a159c266SJung-uk Kim  *
971*a159c266SJung-uk Kim  ******************************************************************************/
972*a159c266SJung-uk Kim 
973*a159c266SJung-uk Kim static ACPI_STATUS
974*a159c266SJung-uk Kim AcpiNsCheckPackageElements (
975*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
976*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **Elements,
977*a159c266SJung-uk Kim     UINT8                       Type1,
978*a159c266SJung-uk Kim     UINT32                      Count1,
979*a159c266SJung-uk Kim     UINT8                       Type2,
980*a159c266SJung-uk Kim     UINT32                      Count2,
981*a159c266SJung-uk Kim     UINT32                      StartIndex)
982*a159c266SJung-uk Kim {
983*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
984*a159c266SJung-uk Kim     ACPI_STATUS                 Status;
985*a159c266SJung-uk Kim     UINT32                      i;
986*a159c266SJung-uk Kim 
987*a159c266SJung-uk Kim 
988*a159c266SJung-uk Kim     /*
989*a159c266SJung-uk Kim      * Up to two groups of package elements are supported by the data
990*a159c266SJung-uk Kim      * structure. All elements in each group must be of the same type.
991*a159c266SJung-uk Kim      * The second group can have a count of zero.
992*a159c266SJung-uk Kim      */
993*a159c266SJung-uk Kim     for (i = 0; i < Count1; i++)
994*a159c266SJung-uk Kim     {
995*a159c266SJung-uk Kim         Status = AcpiNsCheckObjectType (Data, ThisElement,
996*a159c266SJung-uk Kim                     Type1, i + StartIndex);
997*a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
998*a159c266SJung-uk Kim         {
999*a159c266SJung-uk Kim             return (Status);
1000*a159c266SJung-uk Kim         }
1001*a159c266SJung-uk Kim         ThisElement++;
1002*a159c266SJung-uk Kim     }
1003*a159c266SJung-uk Kim 
1004*a159c266SJung-uk Kim     for (i = 0; i < Count2; i++)
1005*a159c266SJung-uk Kim     {
1006*a159c266SJung-uk Kim         Status = AcpiNsCheckObjectType (Data, ThisElement,
1007*a159c266SJung-uk Kim                     Type2, (i + Count1 + StartIndex));
1008*a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
1009*a159c266SJung-uk Kim         {
1010*a159c266SJung-uk Kim             return (Status);
1011*a159c266SJung-uk Kim         }
1012*a159c266SJung-uk Kim         ThisElement++;
1013*a159c266SJung-uk Kim     }
1014*a159c266SJung-uk Kim 
1015*a159c266SJung-uk Kim     return (AE_OK);
1016*a159c266SJung-uk Kim }
1017*a159c266SJung-uk Kim 
1018*a159c266SJung-uk Kim 
1019*a159c266SJung-uk Kim /*******************************************************************************
1020*a159c266SJung-uk Kim  *
1021*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckObjectType
1022*a159c266SJung-uk Kim  *
1023*a159c266SJung-uk Kim  * PARAMETERS:  Data            - Pointer to validation data structure
1024*a159c266SJung-uk Kim  *              ReturnObjectPtr - Pointer to the object returned from the
1025*a159c266SJung-uk Kim  *                                evaluation of a method or object
1026*a159c266SJung-uk Kim  *              ExpectedBtypes  - Bitmap of expected return type(s)
1027*a159c266SJung-uk Kim  *              PackageIndex    - Index of object within parent package (if
1028*a159c266SJung-uk Kim  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
1029*a159c266SJung-uk Kim  *                                otherwise)
1030*a159c266SJung-uk Kim  *
1031*a159c266SJung-uk Kim  * RETURN:      Status
1032*a159c266SJung-uk Kim  *
1033*a159c266SJung-uk Kim  * DESCRIPTION: Check the type of the return object against the expected object
1034*a159c266SJung-uk Kim  *              type(s). Use of Btype allows multiple expected object types.
1035*a159c266SJung-uk Kim  *
1036*a159c266SJung-uk Kim  ******************************************************************************/
1037*a159c266SJung-uk Kim 
1038*a159c266SJung-uk Kim static ACPI_STATUS
1039*a159c266SJung-uk Kim AcpiNsCheckObjectType (
1040*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
1041*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
1042*a159c266SJung-uk Kim     UINT32                      ExpectedBtypes,
1043*a159c266SJung-uk Kim     UINT32                      PackageIndex)
1044*a159c266SJung-uk Kim {
1045*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1046*a159c266SJung-uk Kim     ACPI_STATUS                 Status = AE_OK;
1047*a159c266SJung-uk Kim     UINT32                      ReturnBtype;
1048*a159c266SJung-uk Kim     char                        TypeBuffer[48]; /* Room for 5 types */
1049*a159c266SJung-uk Kim 
1050*a159c266SJung-uk Kim 
1051*a159c266SJung-uk Kim     /*
1052*a159c266SJung-uk Kim      * If we get a NULL ReturnObject here, it is a NULL package element.
1053*a159c266SJung-uk Kim      * Since all extraneous NULL package elements were removed earlier by a
1054*a159c266SJung-uk Kim      * call to AcpiNsRemoveNullElements, this is an unexpected NULL element.
1055*a159c266SJung-uk Kim      * We will attempt to repair it.
1056*a159c266SJung-uk Kim      */
1057*a159c266SJung-uk Kim     if (!ReturnObject)
1058*a159c266SJung-uk Kim     {
1059*a159c266SJung-uk Kim         Status = AcpiNsRepairNullElement (Data, ExpectedBtypes,
1060*a159c266SJung-uk Kim                     PackageIndex, ReturnObjectPtr);
1061*a159c266SJung-uk Kim         if (ACPI_SUCCESS (Status))
1062*a159c266SJung-uk Kim         {
1063*a159c266SJung-uk Kim             return (AE_OK); /* Repair was successful */
1064*a159c266SJung-uk Kim         }
1065*a159c266SJung-uk Kim         goto TypeErrorExit;
1066*a159c266SJung-uk Kim     }
1067*a159c266SJung-uk Kim 
1068*a159c266SJung-uk Kim     /* A Namespace node should not get here, but make sure */
1069*a159c266SJung-uk Kim 
1070*a159c266SJung-uk Kim     if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
1071*a159c266SJung-uk Kim     {
1072*a159c266SJung-uk Kim         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1073*a159c266SJung-uk Kim             "Invalid return type - Found a Namespace node [%4.4s] type %s",
1074*a159c266SJung-uk Kim             ReturnObject->Node.Name.Ascii,
1075*a159c266SJung-uk Kim             AcpiUtGetTypeName (ReturnObject->Node.Type)));
1076*a159c266SJung-uk Kim         return (AE_AML_OPERAND_TYPE);
1077*a159c266SJung-uk Kim     }
1078*a159c266SJung-uk Kim 
1079*a159c266SJung-uk Kim     /*
1080*a159c266SJung-uk Kim      * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
1081*a159c266SJung-uk Kim      * The bitmapped type allows multiple possible return types.
1082*a159c266SJung-uk Kim      *
1083*a159c266SJung-uk Kim      * Note, the cases below must handle all of the possible types returned
1084*a159c266SJung-uk Kim      * from all of the predefined names (including elements of returned
1085*a159c266SJung-uk Kim      * packages)
1086*a159c266SJung-uk Kim      */
1087*a159c266SJung-uk Kim     switch (ReturnObject->Common.Type)
1088*a159c266SJung-uk Kim     {
1089*a159c266SJung-uk Kim     case ACPI_TYPE_INTEGER:
1090*a159c266SJung-uk Kim         ReturnBtype = ACPI_RTYPE_INTEGER;
1091*a159c266SJung-uk Kim         break;
1092*a159c266SJung-uk Kim 
1093*a159c266SJung-uk Kim     case ACPI_TYPE_BUFFER:
1094*a159c266SJung-uk Kim         ReturnBtype = ACPI_RTYPE_BUFFER;
1095*a159c266SJung-uk Kim         break;
1096*a159c266SJung-uk Kim 
1097*a159c266SJung-uk Kim     case ACPI_TYPE_STRING:
1098*a159c266SJung-uk Kim         ReturnBtype = ACPI_RTYPE_STRING;
1099*a159c266SJung-uk Kim         break;
1100*a159c266SJung-uk Kim 
1101*a159c266SJung-uk Kim     case ACPI_TYPE_PACKAGE:
1102*a159c266SJung-uk Kim         ReturnBtype = ACPI_RTYPE_PACKAGE;
1103*a159c266SJung-uk Kim         break;
1104*a159c266SJung-uk Kim 
1105*a159c266SJung-uk Kim     case ACPI_TYPE_LOCAL_REFERENCE:
1106*a159c266SJung-uk Kim         ReturnBtype = ACPI_RTYPE_REFERENCE;
1107*a159c266SJung-uk Kim         break;
1108*a159c266SJung-uk Kim 
1109*a159c266SJung-uk Kim     default:
1110*a159c266SJung-uk Kim         /* Not one of the supported objects, must be incorrect */
1111*a159c266SJung-uk Kim 
1112*a159c266SJung-uk Kim         goto TypeErrorExit;
1113*a159c266SJung-uk Kim     }
1114*a159c266SJung-uk Kim 
1115*a159c266SJung-uk Kim     /* Is the object one of the expected types? */
1116*a159c266SJung-uk Kim 
1117*a159c266SJung-uk Kim     if (ReturnBtype & ExpectedBtypes)
1118*a159c266SJung-uk Kim     {
1119*a159c266SJung-uk Kim         /* For reference objects, check that the reference type is correct */
1120*a159c266SJung-uk Kim 
1121*a159c266SJung-uk Kim         if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1122*a159c266SJung-uk Kim         {
1123*a159c266SJung-uk Kim             Status = AcpiNsCheckReference (Data, ReturnObject);
1124*a159c266SJung-uk Kim         }
1125*a159c266SJung-uk Kim 
1126*a159c266SJung-uk Kim         return (Status);
1127*a159c266SJung-uk Kim     }
1128*a159c266SJung-uk Kim 
1129*a159c266SJung-uk Kim     /* Type mismatch -- attempt repair of the returned object */
1130*a159c266SJung-uk Kim 
1131*a159c266SJung-uk Kim     Status = AcpiNsRepairObject (Data, ExpectedBtypes,
1132*a159c266SJung-uk Kim                 PackageIndex, ReturnObjectPtr);
1133*a159c266SJung-uk Kim     if (ACPI_SUCCESS (Status))
1134*a159c266SJung-uk Kim     {
1135*a159c266SJung-uk Kim         return (AE_OK); /* Repair was successful */
1136*a159c266SJung-uk Kim     }
1137*a159c266SJung-uk Kim 
1138*a159c266SJung-uk Kim 
1139*a159c266SJung-uk Kim TypeErrorExit:
1140*a159c266SJung-uk Kim 
1141*a159c266SJung-uk Kim     /* Create a string with all expected types for this predefined object */
1142*a159c266SJung-uk Kim 
1143*a159c266SJung-uk Kim     AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);
1144*a159c266SJung-uk Kim 
1145*a159c266SJung-uk Kim     if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
1146*a159c266SJung-uk Kim     {
1147*a159c266SJung-uk Kim         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1148*a159c266SJung-uk Kim             "Return type mismatch - found %s, expected %s",
1149*a159c266SJung-uk Kim             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1150*a159c266SJung-uk Kim     }
1151*a159c266SJung-uk Kim     else
1152*a159c266SJung-uk Kim     {
1153*a159c266SJung-uk Kim         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1154*a159c266SJung-uk Kim             "Return Package type mismatch at index %u - "
1155*a159c266SJung-uk Kim             "found %s, expected %s", PackageIndex,
1156*a159c266SJung-uk Kim             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1157*a159c266SJung-uk Kim     }
1158*a159c266SJung-uk Kim 
1159*a159c266SJung-uk Kim     return (AE_AML_OPERAND_TYPE);
1160*a159c266SJung-uk Kim }
1161*a159c266SJung-uk Kim 
1162*a159c266SJung-uk Kim 
1163*a159c266SJung-uk Kim /*******************************************************************************
1164*a159c266SJung-uk Kim  *
1165*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckReference
1166*a159c266SJung-uk Kim  *
1167*a159c266SJung-uk Kim  * PARAMETERS:  Data            - Pointer to validation data structure
1168*a159c266SJung-uk Kim  *              ReturnObject    - Object returned from the evaluation of a
1169*a159c266SJung-uk Kim  *                                method or object
1170*a159c266SJung-uk Kim  *
1171*a159c266SJung-uk Kim  * RETURN:      Status
1172*a159c266SJung-uk Kim  *
1173*a159c266SJung-uk Kim  * DESCRIPTION: Check a returned reference object for the correct reference
1174*a159c266SJung-uk Kim  *              type. The only reference type that can be returned from a
1175*a159c266SJung-uk Kim  *              predefined method is a named reference. All others are invalid.
1176*a159c266SJung-uk Kim  *
1177*a159c266SJung-uk Kim  ******************************************************************************/
1178*a159c266SJung-uk Kim 
1179*a159c266SJung-uk Kim static ACPI_STATUS
1180*a159c266SJung-uk Kim AcpiNsCheckReference (
1181*a159c266SJung-uk Kim     ACPI_PREDEFINED_DATA        *Data,
1182*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT         *ReturnObject)
1183*a159c266SJung-uk Kim {
1184*a159c266SJung-uk Kim 
1185*a159c266SJung-uk Kim     /*
1186*a159c266SJung-uk Kim      * Check the reference object for the correct reference type (opcode).
1187*a159c266SJung-uk Kim      * The only type of reference that can be converted to an ACPI_OBJECT is
1188*a159c266SJung-uk Kim      * a reference to a named object (reference class: NAME)
1189*a159c266SJung-uk Kim      */
1190*a159c266SJung-uk Kim     if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1191*a159c266SJung-uk Kim     {
1192*a159c266SJung-uk Kim         return (AE_OK);
1193*a159c266SJung-uk Kim     }
1194*a159c266SJung-uk Kim 
1195*a159c266SJung-uk Kim     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1196*a159c266SJung-uk Kim         "Return type mismatch - unexpected reference object type [%s] %2.2X",
1197*a159c266SJung-uk Kim         AcpiUtGetReferenceName (ReturnObject),
1198*a159c266SJung-uk Kim         ReturnObject->Reference.Class));
1199*a159c266SJung-uk Kim 
1200*a159c266SJung-uk Kim     return (AE_AML_OPERAND_TYPE);
1201*a159c266SJung-uk Kim }
1202*a159c266SJung-uk Kim 
1203*a159c266SJung-uk Kim 
1204*a159c266SJung-uk Kim /*******************************************************************************
1205*a159c266SJung-uk Kim  *
1206*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsGetExpectedTypes
1207*a159c266SJung-uk Kim  *
1208*a159c266SJung-uk Kim  * PARAMETERS:  Buffer          - Pointer to where the string is returned
1209*a159c266SJung-uk Kim  *              ExpectedBtypes  - Bitmap of expected return type(s)
1210*a159c266SJung-uk Kim  *
1211*a159c266SJung-uk Kim  * RETURN:      Buffer is populated with type names.
1212*a159c266SJung-uk Kim  *
1213*a159c266SJung-uk Kim  * DESCRIPTION: Translate the expected types bitmap into a string of ascii
1214*a159c266SJung-uk Kim  *              names of expected types, for use in warning messages.
1215*a159c266SJung-uk Kim  *
1216*a159c266SJung-uk Kim  ******************************************************************************/
1217*a159c266SJung-uk Kim 
1218*a159c266SJung-uk Kim static void
1219*a159c266SJung-uk Kim AcpiNsGetExpectedTypes (
1220*a159c266SJung-uk Kim     char                        *Buffer,
1221*a159c266SJung-uk Kim     UINT32                      ExpectedBtypes)
1222*a159c266SJung-uk Kim {
1223*a159c266SJung-uk Kim     UINT32                      ThisRtype;
1224*a159c266SJung-uk Kim     UINT32                      i;
1225*a159c266SJung-uk Kim     UINT32                      j;
1226*a159c266SJung-uk Kim 
1227*a159c266SJung-uk Kim 
1228*a159c266SJung-uk Kim     j = 1;
1229*a159c266SJung-uk Kim     Buffer[0] = 0;
1230*a159c266SJung-uk Kim     ThisRtype = ACPI_RTYPE_INTEGER;
1231*a159c266SJung-uk Kim 
1232*a159c266SJung-uk Kim     for (i = 0; i < ACPI_NUM_RTYPES; i++)
1233*a159c266SJung-uk Kim     {
1234*a159c266SJung-uk Kim         /* If one of the expected types, concatenate the name of this type */
1235*a159c266SJung-uk Kim 
1236*a159c266SJung-uk Kim         if (ExpectedBtypes & ThisRtype)
1237*a159c266SJung-uk Kim         {
1238*a159c266SJung-uk Kim             ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
1239*a159c266SJung-uk Kim             j = 0;              /* Use name separator from now on */
1240*a159c266SJung-uk Kim         }
1241*a159c266SJung-uk Kim         ThisRtype <<= 1;    /* Next Rtype */
1242*a159c266SJung-uk Kim     }
1243*a159c266SJung-uk Kim }
1244