xref: /titanic_50/usr/src/uts/intel/io/acpica/namespace/nsprepkg.c (revision 385cc6b4ad1792caef3f84eb61eed3f27085801f)
1*385cc6b4SJerry Jelinek /******************************************************************************
2*385cc6b4SJerry Jelinek  *
3*385cc6b4SJerry Jelinek  * Module Name: nsprepkg - Validation of package objects for predefined names
4*385cc6b4SJerry Jelinek  *
5*385cc6b4SJerry Jelinek  *****************************************************************************/
6*385cc6b4SJerry Jelinek 
7*385cc6b4SJerry Jelinek /*
8*385cc6b4SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
9*385cc6b4SJerry Jelinek  * All rights reserved.
10*385cc6b4SJerry Jelinek  *
11*385cc6b4SJerry Jelinek  * Redistribution and use in source and binary forms, with or without
12*385cc6b4SJerry Jelinek  * modification, are permitted provided that the following conditions
13*385cc6b4SJerry Jelinek  * are met:
14*385cc6b4SJerry Jelinek  * 1. Redistributions of source code must retain the above copyright
15*385cc6b4SJerry Jelinek  *    notice, this list of conditions, and the following disclaimer,
16*385cc6b4SJerry Jelinek  *    without modification.
17*385cc6b4SJerry Jelinek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*385cc6b4SJerry Jelinek  *    substantially similar to the "NO WARRANTY" disclaimer below
19*385cc6b4SJerry Jelinek  *    ("Disclaimer") and any redistribution must be conditioned upon
20*385cc6b4SJerry Jelinek  *    including a substantially similar Disclaimer requirement for further
21*385cc6b4SJerry Jelinek  *    binary redistribution.
22*385cc6b4SJerry Jelinek  * 3. Neither the names of the above-listed copyright holders nor the names
23*385cc6b4SJerry Jelinek  *    of any contributors may be used to endorse or promote products derived
24*385cc6b4SJerry Jelinek  *    from this software without specific prior written permission.
25*385cc6b4SJerry Jelinek  *
26*385cc6b4SJerry Jelinek  * Alternatively, this software may be distributed under the terms of the
27*385cc6b4SJerry Jelinek  * GNU General Public License ("GPL") version 2 as published by the Free
28*385cc6b4SJerry Jelinek  * Software Foundation.
29*385cc6b4SJerry Jelinek  *
30*385cc6b4SJerry Jelinek  * NO WARRANTY
31*385cc6b4SJerry Jelinek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*385cc6b4SJerry Jelinek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*385cc6b4SJerry Jelinek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*385cc6b4SJerry Jelinek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*385cc6b4SJerry Jelinek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*385cc6b4SJerry Jelinek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*385cc6b4SJerry Jelinek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*385cc6b4SJerry Jelinek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*385cc6b4SJerry Jelinek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*385cc6b4SJerry Jelinek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*385cc6b4SJerry Jelinek  * POSSIBILITY OF SUCH DAMAGES.
42*385cc6b4SJerry Jelinek  */
43*385cc6b4SJerry Jelinek 
44*385cc6b4SJerry Jelinek #include "acpi.h"
45*385cc6b4SJerry Jelinek #include "accommon.h"
46*385cc6b4SJerry Jelinek #include "acnamesp.h"
47*385cc6b4SJerry Jelinek #include "acpredef.h"
48*385cc6b4SJerry Jelinek 
49*385cc6b4SJerry Jelinek 
50*385cc6b4SJerry Jelinek #define _COMPONENT          ACPI_NAMESPACE
51*385cc6b4SJerry Jelinek         ACPI_MODULE_NAME    ("nsprepkg")
52*385cc6b4SJerry Jelinek 
53*385cc6b4SJerry Jelinek 
54*385cc6b4SJerry Jelinek /* Local prototypes */
55*385cc6b4SJerry Jelinek 
56*385cc6b4SJerry Jelinek static ACPI_STATUS
57*385cc6b4SJerry Jelinek AcpiNsCheckPackageList (
58*385cc6b4SJerry Jelinek     ACPI_EVALUATE_INFO          *Info,
59*385cc6b4SJerry Jelinek     const ACPI_PREDEFINED_INFO  *Package,
60*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **Elements,
61*385cc6b4SJerry Jelinek     UINT32                      Count);
62*385cc6b4SJerry Jelinek 
63*385cc6b4SJerry Jelinek static ACPI_STATUS
64*385cc6b4SJerry Jelinek AcpiNsCheckPackageElements (
65*385cc6b4SJerry Jelinek     ACPI_EVALUATE_INFO          *Info,
66*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **Elements,
67*385cc6b4SJerry Jelinek     UINT8                       Type1,
68*385cc6b4SJerry Jelinek     UINT32                      Count1,
69*385cc6b4SJerry Jelinek     UINT8                       Type2,
70*385cc6b4SJerry Jelinek     UINT32                      Count2,
71*385cc6b4SJerry Jelinek     UINT32                      StartIndex);
72*385cc6b4SJerry Jelinek 
73*385cc6b4SJerry Jelinek static ACPI_STATUS
74*385cc6b4SJerry Jelinek AcpiNsCustomPackage (
75*385cc6b4SJerry Jelinek     ACPI_EVALUATE_INFO          *Info,
76*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **Elements,
77*385cc6b4SJerry Jelinek     UINT32                      Count);
78*385cc6b4SJerry Jelinek 
79*385cc6b4SJerry Jelinek 
80*385cc6b4SJerry Jelinek /*******************************************************************************
81*385cc6b4SJerry Jelinek  *
82*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiNsCheckPackage
83*385cc6b4SJerry Jelinek  *
84*385cc6b4SJerry Jelinek  * PARAMETERS:  Info                - Method execution information block
85*385cc6b4SJerry Jelinek  *              ReturnObjectPtr     - Pointer to the object returned from the
86*385cc6b4SJerry Jelinek  *                                    evaluation of a method or object
87*385cc6b4SJerry Jelinek  *
88*385cc6b4SJerry Jelinek  * RETURN:      Status
89*385cc6b4SJerry Jelinek  *
90*385cc6b4SJerry Jelinek  * DESCRIPTION: Check a returned package object for the correct count and
91*385cc6b4SJerry Jelinek  *              correct type of all sub-objects.
92*385cc6b4SJerry Jelinek  *
93*385cc6b4SJerry Jelinek  ******************************************************************************/
94*385cc6b4SJerry Jelinek 
95*385cc6b4SJerry Jelinek ACPI_STATUS
AcpiNsCheckPackage(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)96*385cc6b4SJerry Jelinek AcpiNsCheckPackage (
97*385cc6b4SJerry Jelinek     ACPI_EVALUATE_INFO          *Info,
98*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
99*385cc6b4SJerry Jelinek {
100*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
101*385cc6b4SJerry Jelinek     const ACPI_PREDEFINED_INFO  *Package;
102*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **Elements;
103*385cc6b4SJerry Jelinek     ACPI_STATUS                 Status = AE_OK;
104*385cc6b4SJerry Jelinek     UINT32                      ExpectedCount;
105*385cc6b4SJerry Jelinek     UINT32                      Count;
106*385cc6b4SJerry Jelinek     UINT32                      i;
107*385cc6b4SJerry Jelinek 
108*385cc6b4SJerry Jelinek 
109*385cc6b4SJerry Jelinek     ACPI_FUNCTION_NAME (NsCheckPackage);
110*385cc6b4SJerry Jelinek 
111*385cc6b4SJerry Jelinek 
112*385cc6b4SJerry Jelinek     /* The package info for this name is in the next table entry */
113*385cc6b4SJerry Jelinek 
114*385cc6b4SJerry Jelinek     Package = Info->Predefined + 1;
115*385cc6b4SJerry Jelinek 
116*385cc6b4SJerry Jelinek     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
117*385cc6b4SJerry Jelinek         "%s Validating return Package of Type %X, Count %X\n",
118*385cc6b4SJerry Jelinek         Info->FullPathname, Package->RetInfo.Type,
119*385cc6b4SJerry Jelinek         ReturnObject->Package.Count));
120*385cc6b4SJerry Jelinek 
121*385cc6b4SJerry Jelinek     /*
122*385cc6b4SJerry Jelinek      * For variable-length Packages, we can safely remove all embedded
123*385cc6b4SJerry Jelinek      * and trailing NULL package elements
124*385cc6b4SJerry Jelinek      */
125*385cc6b4SJerry Jelinek     AcpiNsRemoveNullElements (Info, Package->RetInfo.Type, ReturnObject);
126*385cc6b4SJerry Jelinek 
127*385cc6b4SJerry Jelinek     /* Extract package count and elements array */
128*385cc6b4SJerry Jelinek 
129*385cc6b4SJerry Jelinek     Elements = ReturnObject->Package.Elements;
130*385cc6b4SJerry Jelinek     Count = ReturnObject->Package.Count;
131*385cc6b4SJerry Jelinek 
132*385cc6b4SJerry Jelinek     /*
133*385cc6b4SJerry Jelinek      * Most packages must have at least one element. The only exception
134*385cc6b4SJerry Jelinek      * is the variable-length package (ACPI_PTYPE1_VAR).
135*385cc6b4SJerry Jelinek      */
136*385cc6b4SJerry Jelinek     if (!Count)
137*385cc6b4SJerry Jelinek     {
138*385cc6b4SJerry Jelinek         if (Package->RetInfo.Type == ACPI_PTYPE1_VAR)
139*385cc6b4SJerry Jelinek         {
140*385cc6b4SJerry Jelinek             return (AE_OK);
141*385cc6b4SJerry Jelinek         }
142*385cc6b4SJerry Jelinek 
143*385cc6b4SJerry Jelinek         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
144*385cc6b4SJerry Jelinek             "Return Package has no elements (empty)"));
145*385cc6b4SJerry Jelinek 
146*385cc6b4SJerry Jelinek         return (AE_AML_OPERAND_VALUE);
147*385cc6b4SJerry Jelinek     }
148*385cc6b4SJerry Jelinek 
149*385cc6b4SJerry Jelinek     /*
150*385cc6b4SJerry Jelinek      * Decode the type of the expected package contents
151*385cc6b4SJerry Jelinek      *
152*385cc6b4SJerry Jelinek      * PTYPE1 packages contain no subpackages
153*385cc6b4SJerry Jelinek      * PTYPE2 packages contain subpackages
154*385cc6b4SJerry Jelinek      */
155*385cc6b4SJerry Jelinek     switch (Package->RetInfo.Type)
156*385cc6b4SJerry Jelinek     {
157*385cc6b4SJerry Jelinek     case ACPI_PTYPE_CUSTOM:
158*385cc6b4SJerry Jelinek 
159*385cc6b4SJerry Jelinek         Status = AcpiNsCustomPackage (Info, Elements, Count);
160*385cc6b4SJerry Jelinek         break;
161*385cc6b4SJerry Jelinek 
162*385cc6b4SJerry Jelinek     case ACPI_PTYPE1_FIXED:
163*385cc6b4SJerry Jelinek         /*
164*385cc6b4SJerry Jelinek          * The package count is fixed and there are no subpackages
165*385cc6b4SJerry Jelinek          *
166*385cc6b4SJerry Jelinek          * If package is too small, exit.
167*385cc6b4SJerry Jelinek          * If package is larger than expected, issue warning but continue
168*385cc6b4SJerry Jelinek          */
169*385cc6b4SJerry Jelinek         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
170*385cc6b4SJerry Jelinek         if (Count < ExpectedCount)
171*385cc6b4SJerry Jelinek         {
172*385cc6b4SJerry Jelinek             goto PackageTooSmall;
173*385cc6b4SJerry Jelinek         }
174*385cc6b4SJerry Jelinek         else if (Count > ExpectedCount)
175*385cc6b4SJerry Jelinek         {
176*385cc6b4SJerry Jelinek             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
177*385cc6b4SJerry Jelinek                 "%s: Return Package is larger than needed - "
178*385cc6b4SJerry Jelinek                 "found %u, expected %u\n",
179*385cc6b4SJerry Jelinek                 Info->FullPathname, Count, ExpectedCount));
180*385cc6b4SJerry Jelinek         }
181*385cc6b4SJerry Jelinek 
182*385cc6b4SJerry Jelinek         /* Validate all elements of the returned package */
183*385cc6b4SJerry Jelinek 
184*385cc6b4SJerry Jelinek         Status = AcpiNsCheckPackageElements (Info, Elements,
185*385cc6b4SJerry Jelinek             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
186*385cc6b4SJerry Jelinek             Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
187*385cc6b4SJerry Jelinek         break;
188*385cc6b4SJerry Jelinek 
189*385cc6b4SJerry Jelinek     case ACPI_PTYPE1_VAR:
190*385cc6b4SJerry Jelinek         /*
191*385cc6b4SJerry Jelinek          * The package count is variable, there are no subpackages, and all
192*385cc6b4SJerry Jelinek          * elements must be of the same type
193*385cc6b4SJerry Jelinek          */
194*385cc6b4SJerry Jelinek         for (i = 0; i < Count; i++)
195*385cc6b4SJerry Jelinek         {
196*385cc6b4SJerry Jelinek             Status = AcpiNsCheckObjectType (Info, Elements,
197*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType1, i);
198*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
199*385cc6b4SJerry Jelinek             {
200*385cc6b4SJerry Jelinek                 return (Status);
201*385cc6b4SJerry Jelinek             }
202*385cc6b4SJerry Jelinek 
203*385cc6b4SJerry Jelinek             Elements++;
204*385cc6b4SJerry Jelinek         }
205*385cc6b4SJerry Jelinek         break;
206*385cc6b4SJerry Jelinek 
207*385cc6b4SJerry Jelinek     case ACPI_PTYPE1_OPTION:
208*385cc6b4SJerry Jelinek         /*
209*385cc6b4SJerry Jelinek          * The package count is variable, there are no subpackages. There are
210*385cc6b4SJerry Jelinek          * a fixed number of required elements, and a variable number of
211*385cc6b4SJerry Jelinek          * optional elements.
212*385cc6b4SJerry Jelinek          *
213*385cc6b4SJerry Jelinek          * Check if package is at least as large as the minimum required
214*385cc6b4SJerry Jelinek          */
215*385cc6b4SJerry Jelinek         ExpectedCount = Package->RetInfo3.Count;
216*385cc6b4SJerry Jelinek         if (Count < ExpectedCount)
217*385cc6b4SJerry Jelinek         {
218*385cc6b4SJerry Jelinek             goto PackageTooSmall;
219*385cc6b4SJerry Jelinek         }
220*385cc6b4SJerry Jelinek 
221*385cc6b4SJerry Jelinek         /* Variable number of sub-objects */
222*385cc6b4SJerry Jelinek 
223*385cc6b4SJerry Jelinek         for (i = 0; i < Count; i++)
224*385cc6b4SJerry Jelinek         {
225*385cc6b4SJerry Jelinek             if (i < Package->RetInfo3.Count)
226*385cc6b4SJerry Jelinek             {
227*385cc6b4SJerry Jelinek                 /* These are the required package elements (0, 1, or 2) */
228*385cc6b4SJerry Jelinek 
229*385cc6b4SJerry Jelinek                 Status = AcpiNsCheckObjectType (Info, Elements,
230*385cc6b4SJerry Jelinek                     Package->RetInfo3.ObjectType[i], i);
231*385cc6b4SJerry Jelinek                 if (ACPI_FAILURE (Status))
232*385cc6b4SJerry Jelinek                 {
233*385cc6b4SJerry Jelinek                     return (Status);
234*385cc6b4SJerry Jelinek                 }
235*385cc6b4SJerry Jelinek             }
236*385cc6b4SJerry Jelinek             else
237*385cc6b4SJerry Jelinek             {
238*385cc6b4SJerry Jelinek                 /* These are the optional package elements */
239*385cc6b4SJerry Jelinek 
240*385cc6b4SJerry Jelinek                 Status = AcpiNsCheckObjectType (Info, Elements,
241*385cc6b4SJerry Jelinek                     Package->RetInfo3.TailObjectType, i);
242*385cc6b4SJerry Jelinek                 if (ACPI_FAILURE (Status))
243*385cc6b4SJerry Jelinek                 {
244*385cc6b4SJerry Jelinek                     return (Status);
245*385cc6b4SJerry Jelinek                 }
246*385cc6b4SJerry Jelinek             }
247*385cc6b4SJerry Jelinek 
248*385cc6b4SJerry Jelinek             Elements++;
249*385cc6b4SJerry Jelinek         }
250*385cc6b4SJerry Jelinek         break;
251*385cc6b4SJerry Jelinek 
252*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_REV_FIXED:
253*385cc6b4SJerry Jelinek 
254*385cc6b4SJerry Jelinek         /* First element is the (Integer) revision */
255*385cc6b4SJerry Jelinek 
256*385cc6b4SJerry Jelinek         Status = AcpiNsCheckObjectType (
257*385cc6b4SJerry Jelinek             Info, Elements, ACPI_RTYPE_INTEGER, 0);
258*385cc6b4SJerry Jelinek         if (ACPI_FAILURE (Status))
259*385cc6b4SJerry Jelinek         {
260*385cc6b4SJerry Jelinek             return (Status);
261*385cc6b4SJerry Jelinek         }
262*385cc6b4SJerry Jelinek 
263*385cc6b4SJerry Jelinek         Elements++;
264*385cc6b4SJerry Jelinek         Count--;
265*385cc6b4SJerry Jelinek 
266*385cc6b4SJerry Jelinek         /* Examine the subpackages */
267*385cc6b4SJerry Jelinek 
268*385cc6b4SJerry Jelinek         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
269*385cc6b4SJerry Jelinek         break;
270*385cc6b4SJerry Jelinek 
271*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_PKG_COUNT:
272*385cc6b4SJerry Jelinek 
273*385cc6b4SJerry Jelinek         /* First element is the (Integer) count of subpackages to follow */
274*385cc6b4SJerry Jelinek 
275*385cc6b4SJerry Jelinek         Status = AcpiNsCheckObjectType (
276*385cc6b4SJerry Jelinek             Info, Elements, ACPI_RTYPE_INTEGER, 0);
277*385cc6b4SJerry Jelinek         if (ACPI_FAILURE (Status))
278*385cc6b4SJerry Jelinek         {
279*385cc6b4SJerry Jelinek             return (Status);
280*385cc6b4SJerry Jelinek         }
281*385cc6b4SJerry Jelinek 
282*385cc6b4SJerry Jelinek         /*
283*385cc6b4SJerry Jelinek          * Count cannot be larger than the parent package length, but allow it
284*385cc6b4SJerry Jelinek          * to be smaller. The >= accounts for the Integer above.
285*385cc6b4SJerry Jelinek          */
286*385cc6b4SJerry Jelinek         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
287*385cc6b4SJerry Jelinek         if (ExpectedCount >= Count)
288*385cc6b4SJerry Jelinek         {
289*385cc6b4SJerry Jelinek             goto PackageTooSmall;
290*385cc6b4SJerry Jelinek         }
291*385cc6b4SJerry Jelinek 
292*385cc6b4SJerry Jelinek         Count = ExpectedCount;
293*385cc6b4SJerry Jelinek         Elements++;
294*385cc6b4SJerry Jelinek 
295*385cc6b4SJerry Jelinek         /* Examine the subpackages */
296*385cc6b4SJerry Jelinek 
297*385cc6b4SJerry Jelinek         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
298*385cc6b4SJerry Jelinek         break;
299*385cc6b4SJerry Jelinek 
300*385cc6b4SJerry Jelinek     case ACPI_PTYPE2:
301*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_FIXED:
302*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_MIN:
303*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_COUNT:
304*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_FIX_VAR:
305*385cc6b4SJerry Jelinek         /*
306*385cc6b4SJerry Jelinek          * These types all return a single Package that consists of a
307*385cc6b4SJerry Jelinek          * variable number of subpackages.
308*385cc6b4SJerry Jelinek          *
309*385cc6b4SJerry Jelinek          * First, ensure that the first element is a subpackage. If not,
310*385cc6b4SJerry Jelinek          * the BIOS may have incorrectly returned the object as a single
311*385cc6b4SJerry Jelinek          * package instead of a Package of Packages (a common error if
312*385cc6b4SJerry Jelinek          * there is only one entry). We may be able to repair this by
313*385cc6b4SJerry Jelinek          * wrapping the returned Package with a new outer Package.
314*385cc6b4SJerry Jelinek          */
315*385cc6b4SJerry Jelinek         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
316*385cc6b4SJerry Jelinek         {
317*385cc6b4SJerry Jelinek             /* Create the new outer package and populate it */
318*385cc6b4SJerry Jelinek 
319*385cc6b4SJerry Jelinek             Status = AcpiNsWrapWithPackage (
320*385cc6b4SJerry Jelinek                 Info, ReturnObject, ReturnObjectPtr);
321*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
322*385cc6b4SJerry Jelinek             {
323*385cc6b4SJerry Jelinek                 return (Status);
324*385cc6b4SJerry Jelinek             }
325*385cc6b4SJerry Jelinek 
326*385cc6b4SJerry Jelinek             /* Update locals to point to the new package (of 1 element) */
327*385cc6b4SJerry Jelinek 
328*385cc6b4SJerry Jelinek             ReturnObject = *ReturnObjectPtr;
329*385cc6b4SJerry Jelinek             Elements = ReturnObject->Package.Elements;
330*385cc6b4SJerry Jelinek             Count = 1;
331*385cc6b4SJerry Jelinek         }
332*385cc6b4SJerry Jelinek 
333*385cc6b4SJerry Jelinek         /* Examine the subpackages */
334*385cc6b4SJerry Jelinek 
335*385cc6b4SJerry Jelinek         Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
336*385cc6b4SJerry Jelinek         break;
337*385cc6b4SJerry Jelinek 
338*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_VAR_VAR:
339*385cc6b4SJerry Jelinek         /*
340*385cc6b4SJerry Jelinek          * Returns a variable list of packages, each with a variable list
341*385cc6b4SJerry Jelinek          * of objects.
342*385cc6b4SJerry Jelinek          */
343*385cc6b4SJerry Jelinek         break;
344*385cc6b4SJerry Jelinek 
345*385cc6b4SJerry Jelinek     case ACPI_PTYPE2_UUID_PAIR:
346*385cc6b4SJerry Jelinek 
347*385cc6b4SJerry Jelinek         /* The package must contain pairs of (UUID + type) */
348*385cc6b4SJerry Jelinek 
349*385cc6b4SJerry Jelinek         if (Count & 1)
350*385cc6b4SJerry Jelinek         {
351*385cc6b4SJerry Jelinek             ExpectedCount = Count + 1;
352*385cc6b4SJerry Jelinek             goto PackageTooSmall;
353*385cc6b4SJerry Jelinek         }
354*385cc6b4SJerry Jelinek 
355*385cc6b4SJerry Jelinek         while (Count > 0)
356*385cc6b4SJerry Jelinek         {
357*385cc6b4SJerry Jelinek             Status = AcpiNsCheckObjectType(Info, Elements,
358*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType1, 0);
359*385cc6b4SJerry Jelinek             if (ACPI_FAILURE(Status))
360*385cc6b4SJerry Jelinek             {
361*385cc6b4SJerry Jelinek                 return (Status);
362*385cc6b4SJerry Jelinek             }
363*385cc6b4SJerry Jelinek 
364*385cc6b4SJerry Jelinek             /* Validate length of the UUID buffer */
365*385cc6b4SJerry Jelinek 
366*385cc6b4SJerry Jelinek             if ((*Elements)->Buffer.Length != 16)
367*385cc6b4SJerry Jelinek             {
368*385cc6b4SJerry Jelinek                 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
369*385cc6b4SJerry Jelinek                     Info->NodeFlags, "Invalid length for UUID Buffer"));
370*385cc6b4SJerry Jelinek                 return (AE_AML_OPERAND_VALUE);
371*385cc6b4SJerry Jelinek             }
372*385cc6b4SJerry Jelinek 
373*385cc6b4SJerry Jelinek             Status = AcpiNsCheckObjectType(Info, Elements + 1,
374*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType2, 0);
375*385cc6b4SJerry Jelinek             if (ACPI_FAILURE(Status))
376*385cc6b4SJerry Jelinek             {
377*385cc6b4SJerry Jelinek                 return (Status);
378*385cc6b4SJerry Jelinek             }
379*385cc6b4SJerry Jelinek 
380*385cc6b4SJerry Jelinek             Elements += 2;
381*385cc6b4SJerry Jelinek             Count -= 2;
382*385cc6b4SJerry Jelinek         }
383*385cc6b4SJerry Jelinek         break;
384*385cc6b4SJerry Jelinek 
385*385cc6b4SJerry Jelinek     default:
386*385cc6b4SJerry Jelinek 
387*385cc6b4SJerry Jelinek         /* Should not get here if predefined info table is correct */
388*385cc6b4SJerry Jelinek 
389*385cc6b4SJerry Jelinek         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
390*385cc6b4SJerry Jelinek             "Invalid internal return type in table entry: %X",
391*385cc6b4SJerry Jelinek             Package->RetInfo.Type));
392*385cc6b4SJerry Jelinek 
393*385cc6b4SJerry Jelinek         return (AE_AML_INTERNAL);
394*385cc6b4SJerry Jelinek     }
395*385cc6b4SJerry Jelinek 
396*385cc6b4SJerry Jelinek     return (Status);
397*385cc6b4SJerry Jelinek 
398*385cc6b4SJerry Jelinek 
399*385cc6b4SJerry Jelinek PackageTooSmall:
400*385cc6b4SJerry Jelinek 
401*385cc6b4SJerry Jelinek     /* Error exit for the case with an incorrect package count */
402*385cc6b4SJerry Jelinek 
403*385cc6b4SJerry Jelinek     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
404*385cc6b4SJerry Jelinek         "Return Package is too small - found %u elements, expected %u",
405*385cc6b4SJerry Jelinek         Count, ExpectedCount));
406*385cc6b4SJerry Jelinek 
407*385cc6b4SJerry Jelinek     return (AE_AML_OPERAND_VALUE);
408*385cc6b4SJerry Jelinek }
409*385cc6b4SJerry Jelinek 
410*385cc6b4SJerry Jelinek 
411*385cc6b4SJerry Jelinek /*******************************************************************************
412*385cc6b4SJerry Jelinek  *
413*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiNsCheckPackageList
414*385cc6b4SJerry Jelinek  *
415*385cc6b4SJerry Jelinek  * PARAMETERS:  Info            - Method execution information block
416*385cc6b4SJerry Jelinek  *              Package         - Pointer to package-specific info for method
417*385cc6b4SJerry Jelinek  *              Elements        - Element list of parent package. All elements
418*385cc6b4SJerry Jelinek  *                                of this list should be of type Package.
419*385cc6b4SJerry Jelinek  *              Count           - Count of subpackages
420*385cc6b4SJerry Jelinek  *
421*385cc6b4SJerry Jelinek  * RETURN:      Status
422*385cc6b4SJerry Jelinek  *
423*385cc6b4SJerry Jelinek  * DESCRIPTION: Examine a list of subpackages
424*385cc6b4SJerry Jelinek  *
425*385cc6b4SJerry Jelinek  ******************************************************************************/
426*385cc6b4SJerry Jelinek 
427*385cc6b4SJerry Jelinek static ACPI_STATUS
AcpiNsCheckPackageList(ACPI_EVALUATE_INFO * Info,const ACPI_PREDEFINED_INFO * Package,ACPI_OPERAND_OBJECT ** Elements,UINT32 Count)428*385cc6b4SJerry Jelinek AcpiNsCheckPackageList (
429*385cc6b4SJerry Jelinek     ACPI_EVALUATE_INFO          *Info,
430*385cc6b4SJerry Jelinek     const ACPI_PREDEFINED_INFO  *Package,
431*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **Elements,
432*385cc6b4SJerry Jelinek     UINT32                      Count)
433*385cc6b4SJerry Jelinek {
434*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         *SubPackage;
435*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **SubElements;
436*385cc6b4SJerry Jelinek     ACPI_STATUS                 Status;
437*385cc6b4SJerry Jelinek     UINT32                      ExpectedCount;
438*385cc6b4SJerry Jelinek     UINT32                      i;
439*385cc6b4SJerry Jelinek     UINT32                      j;
440*385cc6b4SJerry Jelinek 
441*385cc6b4SJerry Jelinek 
442*385cc6b4SJerry Jelinek     /*
443*385cc6b4SJerry Jelinek      * Validate each subpackage in the parent Package
444*385cc6b4SJerry Jelinek      *
445*385cc6b4SJerry Jelinek      * NOTE: assumes list of subpackages contains no NULL elements.
446*385cc6b4SJerry Jelinek      * Any NULL elements should have been removed by earlier call
447*385cc6b4SJerry Jelinek      * to AcpiNsRemoveNullElements.
448*385cc6b4SJerry Jelinek      */
449*385cc6b4SJerry Jelinek     for (i = 0; i < Count; i++)
450*385cc6b4SJerry Jelinek     {
451*385cc6b4SJerry Jelinek         SubPackage = *Elements;
452*385cc6b4SJerry Jelinek         SubElements = SubPackage->Package.Elements;
453*385cc6b4SJerry Jelinek         Info->ParentPackage = SubPackage;
454*385cc6b4SJerry Jelinek 
455*385cc6b4SJerry Jelinek         /* Each sub-object must be of type Package */
456*385cc6b4SJerry Jelinek 
457*385cc6b4SJerry Jelinek         Status = AcpiNsCheckObjectType (Info, &SubPackage,
458*385cc6b4SJerry Jelinek             ACPI_RTYPE_PACKAGE, i);
459*385cc6b4SJerry Jelinek         if (ACPI_FAILURE (Status))
460*385cc6b4SJerry Jelinek         {
461*385cc6b4SJerry Jelinek             return (Status);
462*385cc6b4SJerry Jelinek         }
463*385cc6b4SJerry Jelinek 
464*385cc6b4SJerry Jelinek         /* Examine the different types of expected subpackages */
465*385cc6b4SJerry Jelinek 
466*385cc6b4SJerry Jelinek         Info->ParentPackage = SubPackage;
467*385cc6b4SJerry Jelinek         switch (Package->RetInfo.Type)
468*385cc6b4SJerry Jelinek         {
469*385cc6b4SJerry Jelinek         case ACPI_PTYPE2:
470*385cc6b4SJerry Jelinek         case ACPI_PTYPE2_PKG_COUNT:
471*385cc6b4SJerry Jelinek         case ACPI_PTYPE2_REV_FIXED:
472*385cc6b4SJerry Jelinek 
473*385cc6b4SJerry Jelinek             /* Each subpackage has a fixed number of elements */
474*385cc6b4SJerry Jelinek 
475*385cc6b4SJerry Jelinek             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
476*385cc6b4SJerry Jelinek             if (SubPackage->Package.Count < ExpectedCount)
477*385cc6b4SJerry Jelinek             {
478*385cc6b4SJerry Jelinek                 goto PackageTooSmall;
479*385cc6b4SJerry Jelinek             }
480*385cc6b4SJerry Jelinek 
481*385cc6b4SJerry Jelinek             Status = AcpiNsCheckPackageElements (Info, SubElements,
482*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType1,
483*385cc6b4SJerry Jelinek                 Package->RetInfo.Count1,
484*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType2,
485*385cc6b4SJerry Jelinek                 Package->RetInfo.Count2, 0);
486*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
487*385cc6b4SJerry Jelinek             {
488*385cc6b4SJerry Jelinek                 return (Status);
489*385cc6b4SJerry Jelinek             }
490*385cc6b4SJerry Jelinek             break;
491*385cc6b4SJerry Jelinek 
492*385cc6b4SJerry Jelinek         case ACPI_PTYPE2_FIX_VAR:
493*385cc6b4SJerry Jelinek             /*
494*385cc6b4SJerry Jelinek              * Each subpackage has a fixed number of elements and an
495*385cc6b4SJerry Jelinek              * optional element
496*385cc6b4SJerry Jelinek              */
497*385cc6b4SJerry Jelinek             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
498*385cc6b4SJerry Jelinek             if (SubPackage->Package.Count < ExpectedCount)
499*385cc6b4SJerry Jelinek             {
500*385cc6b4SJerry Jelinek                 goto PackageTooSmall;
501*385cc6b4SJerry Jelinek             }
502*385cc6b4SJerry Jelinek 
503*385cc6b4SJerry Jelinek             Status = AcpiNsCheckPackageElements (Info, SubElements,
504*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType1,
505*385cc6b4SJerry Jelinek                 Package->RetInfo.Count1,
506*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType2,
507*385cc6b4SJerry Jelinek                 SubPackage->Package.Count - Package->RetInfo.Count1, 0);
508*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
509*385cc6b4SJerry Jelinek             {
510*385cc6b4SJerry Jelinek                 return (Status);
511*385cc6b4SJerry Jelinek             }
512*385cc6b4SJerry Jelinek             break;
513*385cc6b4SJerry Jelinek 
514*385cc6b4SJerry Jelinek         case ACPI_PTYPE2_VAR_VAR:
515*385cc6b4SJerry Jelinek             /*
516*385cc6b4SJerry Jelinek              * Each subpackage has a fixed or variable number of elements
517*385cc6b4SJerry Jelinek              */
518*385cc6b4SJerry Jelinek             break;
519*385cc6b4SJerry Jelinek 
520*385cc6b4SJerry Jelinek         case ACPI_PTYPE2_FIXED:
521*385cc6b4SJerry Jelinek 
522*385cc6b4SJerry Jelinek             /* Each subpackage has a fixed length */
523*385cc6b4SJerry Jelinek 
524*385cc6b4SJerry Jelinek             ExpectedCount = Package->RetInfo2.Count;
525*385cc6b4SJerry Jelinek             if (SubPackage->Package.Count < ExpectedCount)
526*385cc6b4SJerry Jelinek             {
527*385cc6b4SJerry Jelinek                 goto PackageTooSmall;
528*385cc6b4SJerry Jelinek             }
529*385cc6b4SJerry Jelinek 
530*385cc6b4SJerry Jelinek             /* Check the type of each subpackage element */
531*385cc6b4SJerry Jelinek 
532*385cc6b4SJerry Jelinek             for (j = 0; j < ExpectedCount; j++)
533*385cc6b4SJerry Jelinek             {
534*385cc6b4SJerry Jelinek                 Status = AcpiNsCheckObjectType (Info, &SubElements[j],
535*385cc6b4SJerry Jelinek                     Package->RetInfo2.ObjectType[j], j);
536*385cc6b4SJerry Jelinek                 if (ACPI_FAILURE (Status))
537*385cc6b4SJerry Jelinek                 {
538*385cc6b4SJerry Jelinek                     return (Status);
539*385cc6b4SJerry Jelinek                 }
540*385cc6b4SJerry Jelinek             }
541*385cc6b4SJerry Jelinek             break;
542*385cc6b4SJerry Jelinek 
543*385cc6b4SJerry Jelinek         case ACPI_PTYPE2_MIN:
544*385cc6b4SJerry Jelinek 
545*385cc6b4SJerry Jelinek             /* Each subpackage has a variable but minimum length */
546*385cc6b4SJerry Jelinek 
547*385cc6b4SJerry Jelinek             ExpectedCount = Package->RetInfo.Count1;
548*385cc6b4SJerry Jelinek             if (SubPackage->Package.Count < ExpectedCount)
549*385cc6b4SJerry Jelinek             {
550*385cc6b4SJerry Jelinek                 goto PackageTooSmall;
551*385cc6b4SJerry Jelinek             }
552*385cc6b4SJerry Jelinek 
553*385cc6b4SJerry Jelinek             /* Check the type of each subpackage element */
554*385cc6b4SJerry Jelinek 
555*385cc6b4SJerry Jelinek             Status = AcpiNsCheckPackageElements (Info, SubElements,
556*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType1,
557*385cc6b4SJerry Jelinek                 SubPackage->Package.Count, 0, 0, 0);
558*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
559*385cc6b4SJerry Jelinek             {
560*385cc6b4SJerry Jelinek                 return (Status);
561*385cc6b4SJerry Jelinek             }
562*385cc6b4SJerry Jelinek             break;
563*385cc6b4SJerry Jelinek 
564*385cc6b4SJerry Jelinek         case ACPI_PTYPE2_COUNT:
565*385cc6b4SJerry Jelinek             /*
566*385cc6b4SJerry Jelinek              * First element is the (Integer) count of elements, including
567*385cc6b4SJerry Jelinek              * the count field (the ACPI name is NumElements)
568*385cc6b4SJerry Jelinek              */
569*385cc6b4SJerry Jelinek             Status = AcpiNsCheckObjectType (Info, SubElements,
570*385cc6b4SJerry Jelinek                 ACPI_RTYPE_INTEGER, 0);
571*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
572*385cc6b4SJerry Jelinek             {
573*385cc6b4SJerry Jelinek                 return (Status);
574*385cc6b4SJerry Jelinek             }
575*385cc6b4SJerry Jelinek 
576*385cc6b4SJerry Jelinek             /*
577*385cc6b4SJerry Jelinek              * Make sure package is large enough for the Count and is
578*385cc6b4SJerry Jelinek              * is as large as the minimum size
579*385cc6b4SJerry Jelinek              */
580*385cc6b4SJerry Jelinek             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
581*385cc6b4SJerry Jelinek             if (SubPackage->Package.Count < ExpectedCount)
582*385cc6b4SJerry Jelinek             {
583*385cc6b4SJerry Jelinek                 goto PackageTooSmall;
584*385cc6b4SJerry Jelinek             }
585*385cc6b4SJerry Jelinek 
586*385cc6b4SJerry Jelinek             if (SubPackage->Package.Count < Package->RetInfo.Count1)
587*385cc6b4SJerry Jelinek             {
588*385cc6b4SJerry Jelinek                 ExpectedCount = Package->RetInfo.Count1;
589*385cc6b4SJerry Jelinek                 goto PackageTooSmall;
590*385cc6b4SJerry Jelinek             }
591*385cc6b4SJerry Jelinek 
592*385cc6b4SJerry Jelinek             if (ExpectedCount == 0)
593*385cc6b4SJerry Jelinek             {
594*385cc6b4SJerry Jelinek                 /*
595*385cc6b4SJerry Jelinek                  * Either the NumEntries element was originally zero or it was
596*385cc6b4SJerry Jelinek                  * a NULL element and repaired to an Integer of value zero.
597*385cc6b4SJerry Jelinek                  * In either case, repair it by setting NumEntries to be the
598*385cc6b4SJerry Jelinek                  * actual size of the subpackage.
599*385cc6b4SJerry Jelinek                  */
600*385cc6b4SJerry Jelinek                 ExpectedCount = SubPackage->Package.Count;
601*385cc6b4SJerry Jelinek                 (*SubElements)->Integer.Value = ExpectedCount;
602*385cc6b4SJerry Jelinek             }
603*385cc6b4SJerry Jelinek 
604*385cc6b4SJerry Jelinek             /* Check the type of each subpackage element */
605*385cc6b4SJerry Jelinek 
606*385cc6b4SJerry Jelinek             Status = AcpiNsCheckPackageElements (Info, (SubElements + 1),
607*385cc6b4SJerry Jelinek                 Package->RetInfo.ObjectType1,
608*385cc6b4SJerry Jelinek                 (ExpectedCount - 1), 0, 0, 1);
609*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
610*385cc6b4SJerry Jelinek             {
611*385cc6b4SJerry Jelinek                 return (Status);
612*385cc6b4SJerry Jelinek             }
613*385cc6b4SJerry Jelinek             break;
614*385cc6b4SJerry Jelinek 
615*385cc6b4SJerry Jelinek         default: /* Should not get here, type was validated by caller */
616*385cc6b4SJerry Jelinek 
617*385cc6b4SJerry Jelinek             return (AE_AML_INTERNAL);
618*385cc6b4SJerry Jelinek         }
619*385cc6b4SJerry Jelinek 
620*385cc6b4SJerry Jelinek         Elements++;
621*385cc6b4SJerry Jelinek     }
622*385cc6b4SJerry Jelinek 
623*385cc6b4SJerry Jelinek     return (AE_OK);
624*385cc6b4SJerry Jelinek 
625*385cc6b4SJerry Jelinek 
626*385cc6b4SJerry Jelinek PackageTooSmall:
627*385cc6b4SJerry Jelinek 
628*385cc6b4SJerry Jelinek     /* The subpackage count was smaller than required */
629*385cc6b4SJerry Jelinek 
630*385cc6b4SJerry Jelinek     ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
631*385cc6b4SJerry Jelinek         "Return SubPackage[%u] is too small - found %u elements, expected %u",
632*385cc6b4SJerry Jelinek         i, SubPackage->Package.Count, ExpectedCount));
633*385cc6b4SJerry Jelinek 
634*385cc6b4SJerry Jelinek     return (AE_AML_OPERAND_VALUE);
635*385cc6b4SJerry Jelinek }
636*385cc6b4SJerry Jelinek 
637*385cc6b4SJerry Jelinek 
638*385cc6b4SJerry Jelinek /*******************************************************************************
639*385cc6b4SJerry Jelinek  *
640*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiNsCustomPackage
641*385cc6b4SJerry Jelinek  *
642*385cc6b4SJerry Jelinek  * PARAMETERS:  Info                - Method execution information block
643*385cc6b4SJerry Jelinek  *              Elements            - Pointer to the package elements array
644*385cc6b4SJerry Jelinek  *              Count               - Element count for the package
645*385cc6b4SJerry Jelinek  *
646*385cc6b4SJerry Jelinek  * RETURN:      Status
647*385cc6b4SJerry Jelinek  *
648*385cc6b4SJerry Jelinek  * DESCRIPTION: Check a returned package object for the correct count and
649*385cc6b4SJerry Jelinek  *              correct type of all sub-objects.
650*385cc6b4SJerry Jelinek  *
651*385cc6b4SJerry Jelinek  * NOTE: Currently used for the _BIX method only. When needed for two or more
652*385cc6b4SJerry Jelinek  * methods, probably a detect/dispatch mechanism will be required.
653*385cc6b4SJerry Jelinek  *
654*385cc6b4SJerry Jelinek  ******************************************************************************/
655*385cc6b4SJerry Jelinek 
656*385cc6b4SJerry Jelinek static ACPI_STATUS
AcpiNsCustomPackage(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** Elements,UINT32 Count)657*385cc6b4SJerry Jelinek AcpiNsCustomPackage (
658*385cc6b4SJerry Jelinek     ACPI_EVALUATE_INFO          *Info,
659*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **Elements,
660*385cc6b4SJerry Jelinek     UINT32                      Count)
661*385cc6b4SJerry Jelinek {
662*385cc6b4SJerry Jelinek     UINT32                      ExpectedCount;
663*385cc6b4SJerry Jelinek     UINT32                      Version;
664*385cc6b4SJerry Jelinek     ACPI_STATUS                 Status = AE_OK;
665*385cc6b4SJerry Jelinek 
666*385cc6b4SJerry Jelinek 
667*385cc6b4SJerry Jelinek     ACPI_FUNCTION_NAME (NsCustomPackage);
668*385cc6b4SJerry Jelinek 
669*385cc6b4SJerry Jelinek 
670*385cc6b4SJerry Jelinek     /* Get version number, must be Integer */
671*385cc6b4SJerry Jelinek 
672*385cc6b4SJerry Jelinek     if ((*Elements)->Common.Type != ACPI_TYPE_INTEGER)
673*385cc6b4SJerry Jelinek     {
674*385cc6b4SJerry Jelinek         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
675*385cc6b4SJerry Jelinek             "Return Package has invalid object type for version number"));
676*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
677*385cc6b4SJerry Jelinek     }
678*385cc6b4SJerry Jelinek 
679*385cc6b4SJerry Jelinek     Version = (UINT32) (*Elements)->Integer.Value;
680*385cc6b4SJerry Jelinek     ExpectedCount = 21;         /* Version 1 */
681*385cc6b4SJerry Jelinek 
682*385cc6b4SJerry Jelinek     if (Version == 0)
683*385cc6b4SJerry Jelinek     {
684*385cc6b4SJerry Jelinek         ExpectedCount = 20;     /* Version 0 */
685*385cc6b4SJerry Jelinek     }
686*385cc6b4SJerry Jelinek 
687*385cc6b4SJerry Jelinek     if (Count < ExpectedCount)
688*385cc6b4SJerry Jelinek     {
689*385cc6b4SJerry Jelinek         ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
690*385cc6b4SJerry Jelinek             "Return Package is too small - found %u elements, expected %u",
691*385cc6b4SJerry Jelinek             Count, ExpectedCount));
692*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
693*385cc6b4SJerry Jelinek     }
694*385cc6b4SJerry Jelinek     else if (Count > ExpectedCount)
695*385cc6b4SJerry Jelinek     {
696*385cc6b4SJerry Jelinek         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
697*385cc6b4SJerry Jelinek             "%s: Return Package is larger than needed - "
698*385cc6b4SJerry Jelinek             "found %u, expected %u\n",
699*385cc6b4SJerry Jelinek             Info->FullPathname, Count, ExpectedCount));
700*385cc6b4SJerry Jelinek     }
701*385cc6b4SJerry Jelinek 
702*385cc6b4SJerry Jelinek     /* Validate all elements of the returned package */
703*385cc6b4SJerry Jelinek 
704*385cc6b4SJerry Jelinek     Status = AcpiNsCheckPackageElements (Info, Elements,
705*385cc6b4SJerry Jelinek         ACPI_RTYPE_INTEGER, 16,
706*385cc6b4SJerry Jelinek         ACPI_RTYPE_STRING, 4, 0);
707*385cc6b4SJerry Jelinek     if (ACPI_FAILURE (Status))
708*385cc6b4SJerry Jelinek     {
709*385cc6b4SJerry Jelinek         return_ACPI_STATUS (Status);
710*385cc6b4SJerry Jelinek     }
711*385cc6b4SJerry Jelinek 
712*385cc6b4SJerry Jelinek     /* Version 1 has a single trailing integer */
713*385cc6b4SJerry Jelinek 
714*385cc6b4SJerry Jelinek     if (Version > 0)
715*385cc6b4SJerry Jelinek     {
716*385cc6b4SJerry Jelinek         Status = AcpiNsCheckPackageElements (Info, Elements + 20,
717*385cc6b4SJerry Jelinek             ACPI_RTYPE_INTEGER, 1, 0, 0, 20);
718*385cc6b4SJerry Jelinek     }
719*385cc6b4SJerry Jelinek 
720*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
721*385cc6b4SJerry Jelinek }
722*385cc6b4SJerry Jelinek 
723*385cc6b4SJerry Jelinek 
724*385cc6b4SJerry Jelinek /*******************************************************************************
725*385cc6b4SJerry Jelinek  *
726*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiNsCheckPackageElements
727*385cc6b4SJerry Jelinek  *
728*385cc6b4SJerry Jelinek  * PARAMETERS:  Info            - Method execution information block
729*385cc6b4SJerry Jelinek  *              Elements        - Pointer to the package elements array
730*385cc6b4SJerry Jelinek  *              Type1           - Object type for first group
731*385cc6b4SJerry Jelinek  *              Count1          - Count for first group
732*385cc6b4SJerry Jelinek  *              Type2           - Object type for second group
733*385cc6b4SJerry Jelinek  *              Count2          - Count for second group
734*385cc6b4SJerry Jelinek  *              StartIndex      - Start of the first group of elements
735*385cc6b4SJerry Jelinek  *
736*385cc6b4SJerry Jelinek  * RETURN:      Status
737*385cc6b4SJerry Jelinek  *
738*385cc6b4SJerry Jelinek  * DESCRIPTION: Check that all elements of a package are of the correct object
739*385cc6b4SJerry Jelinek  *              type. Supports up to two groups of different object types.
740*385cc6b4SJerry Jelinek  *
741*385cc6b4SJerry Jelinek  ******************************************************************************/
742*385cc6b4SJerry Jelinek 
743*385cc6b4SJerry Jelinek static ACPI_STATUS
AcpiNsCheckPackageElements(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** Elements,UINT8 Type1,UINT32 Count1,UINT8 Type2,UINT32 Count2,UINT32 StartIndex)744*385cc6b4SJerry Jelinek AcpiNsCheckPackageElements (
745*385cc6b4SJerry Jelinek     ACPI_EVALUATE_INFO          *Info,
746*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **Elements,
747*385cc6b4SJerry Jelinek     UINT8                       Type1,
748*385cc6b4SJerry Jelinek     UINT32                      Count1,
749*385cc6b4SJerry Jelinek     UINT8                       Type2,
750*385cc6b4SJerry Jelinek     UINT32                      Count2,
751*385cc6b4SJerry Jelinek     UINT32                      StartIndex)
752*385cc6b4SJerry Jelinek {
753*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
754*385cc6b4SJerry Jelinek     ACPI_STATUS                 Status;
755*385cc6b4SJerry Jelinek     UINT32                      i;
756*385cc6b4SJerry Jelinek 
757*385cc6b4SJerry Jelinek 
758*385cc6b4SJerry Jelinek     /*
759*385cc6b4SJerry Jelinek      * Up to two groups of package elements are supported by the data
760*385cc6b4SJerry Jelinek      * structure. All elements in each group must be of the same type.
761*385cc6b4SJerry Jelinek      * The second group can have a count of zero.
762*385cc6b4SJerry Jelinek      */
763*385cc6b4SJerry Jelinek     for (i = 0; i < Count1; i++)
764*385cc6b4SJerry Jelinek     {
765*385cc6b4SJerry Jelinek         Status = AcpiNsCheckObjectType (Info, ThisElement,
766*385cc6b4SJerry Jelinek             Type1, i + StartIndex);
767*385cc6b4SJerry Jelinek         if (ACPI_FAILURE (Status))
768*385cc6b4SJerry Jelinek         {
769*385cc6b4SJerry Jelinek             return (Status);
770*385cc6b4SJerry Jelinek         }
771*385cc6b4SJerry Jelinek 
772*385cc6b4SJerry Jelinek         ThisElement++;
773*385cc6b4SJerry Jelinek     }
774*385cc6b4SJerry Jelinek 
775*385cc6b4SJerry Jelinek     for (i = 0; i < Count2; i++)
776*385cc6b4SJerry Jelinek     {
777*385cc6b4SJerry Jelinek         Status = AcpiNsCheckObjectType (Info, ThisElement,
778*385cc6b4SJerry Jelinek             Type2, (i + Count1 + StartIndex));
779*385cc6b4SJerry Jelinek         if (ACPI_FAILURE (Status))
780*385cc6b4SJerry Jelinek         {
781*385cc6b4SJerry Jelinek             return (Status);
782*385cc6b4SJerry Jelinek         }
783*385cc6b4SJerry Jelinek 
784*385cc6b4SJerry Jelinek         ThisElement++;
785*385cc6b4SJerry Jelinek     }
786*385cc6b4SJerry Jelinek 
787*385cc6b4SJerry Jelinek     return (AE_OK);
788*385cc6b4SJerry Jelinek }
789