nspredef.c revision 193341
1193267Sjkim/******************************************************************************
2193267Sjkim *
3193267Sjkim * Module Name: nspredef - Validation of ACPI predefined methods and objects
4193267Sjkim *
5193267Sjkim *****************************************************************************/
6193267Sjkim
7193267Sjkim/******************************************************************************
8193267Sjkim *
9193267Sjkim * 1. Copyright Notice
10193267Sjkim *
11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12193267Sjkim * All rights reserved.
13193267Sjkim *
14193267Sjkim * 2. License
15193267Sjkim *
16193267Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17193267Sjkim * rights.  You may have additional license terms from the party that provided
18193267Sjkim * you this software, covering your right to use that party's intellectual
19193267Sjkim * property rights.
20193267Sjkim *
21193267Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22193267Sjkim * copy of the source code appearing in this file ("Covered Code") an
23193267Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24193267Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25193267Sjkim * make derivatives, distribute, use and display any portion of the Covered
26193267Sjkim * Code in any form, with the right to sublicense such rights; and
27193267Sjkim *
28193267Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29193267Sjkim * license (with the right to sublicense), under only those claims of Intel
30193267Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31193267Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32193267Sjkim * solely to the minimum extent necessary to exercise the above copyright
33193267Sjkim * license, and in no event shall the patent license extend to any additions
34193267Sjkim * to or modifications of the Original Intel Code.  No other license or right
35193267Sjkim * is granted directly or by implication, estoppel or otherwise;
36193267Sjkim *
37193267Sjkim * The above copyright and patent license is granted only if the following
38193267Sjkim * conditions are met:
39193267Sjkim *
40193267Sjkim * 3. Conditions
41193267Sjkim *
42193267Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43193267Sjkim * Redistribution of source code of any substantial portion of the Covered
44193267Sjkim * Code or modification with rights to further distribute source must include
45193267Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46193267Sjkim * and the following Disclaimer and Export Compliance provision.  In addition,
47193267Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48193267Sjkim * contain a file documenting the changes Licensee made to create that Covered
49193267Sjkim * Code and the date of any change.  Licensee must include in that file the
50193267Sjkim * documentation of any changes made by any predecessor Licensee.  Licensee
51193267Sjkim * must include a prominent statement that the modification is derived,
52193267Sjkim * directly or indirectly, from Original Intel Code.
53193267Sjkim *
54193267Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55193267Sjkim * Redistribution of source code of any substantial portion of the Covered
56193267Sjkim * Code or modification without rights to further distribute source must
57193267Sjkim * include the following Disclaimer and Export Compliance provision in the
58193267Sjkim * documentation and/or other materials provided with distribution.  In
59193267Sjkim * addition, Licensee may not authorize further sublicense of source of any
60193267Sjkim * portion of the Covered Code, and must include terms to the effect that the
61193267Sjkim * license from Licensee to its licensee is limited to the intellectual
62193267Sjkim * property embodied in the software Licensee provides to its licensee, and
63193267Sjkim * not to intellectual property embodied in modifications its licensee may
64193267Sjkim * make.
65193267Sjkim *
66193267Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67193267Sjkim * substantial portion of the Covered Code or modification must reproduce the
68193267Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69193267Sjkim * provision in the documentation and/or other materials provided with the
70193267Sjkim * distribution.
71193267Sjkim *
72193267Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73193267Sjkim * Intel Code.
74193267Sjkim *
75193267Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76193267Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77193267Sjkim * other dealings in products derived from or relating to the Covered Code
78193267Sjkim * without prior written authorization from Intel.
79193267Sjkim *
80193267Sjkim * 4. Disclaimer and Export Compliance
81193267Sjkim *
82193267Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83193267Sjkim * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84193267Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85193267Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86193267Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87193267Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88193267Sjkim * PARTICULAR PURPOSE.
89193267Sjkim *
90193267Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91193267Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92193267Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93193267Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94193267Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95193267Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96193267Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97193267Sjkim * LIMITED REMEDY.
98193267Sjkim *
99193267Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100193267Sjkim * software or system incorporating such software without first obtaining any
101193267Sjkim * required license or other approval from the U. S. Department of Commerce or
102193267Sjkim * any other agency or department of the United States Government.  In the
103193267Sjkim * event Licensee exports any such software from the United States or
104193267Sjkim * re-exports any such software from a foreign destination, Licensee shall
105193267Sjkim * ensure that the distribution and export/re-export of the software is in
106193267Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107193267Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108193267Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109193267Sjkim * software, or service, directly or indirectly, to any country for which the
110193267Sjkim * United States government or any agency thereof requires an export license,
111193267Sjkim * other governmental approval, or letter of assurance, without first obtaining
112193267Sjkim * such license, approval or letter.
113193267Sjkim *
114193267Sjkim *****************************************************************************/
115193267Sjkim
116193267Sjkim#define __NSPREDEF_C__
117193267Sjkim
118193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
119193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
120193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
121193341Sjkim#include <contrib/dev/acpica/include/acpredef.h>
122193267Sjkim
123193267Sjkim
124193267Sjkim#define _COMPONENT          ACPI_NAMESPACE
125193267Sjkim        ACPI_MODULE_NAME    ("nspredef")
126193267Sjkim
127193267Sjkim
128193267Sjkim/*******************************************************************************
129193267Sjkim *
130193267Sjkim * This module validates predefined ACPI objects that appear in the namespace,
131193267Sjkim * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
132193267Sjkim * validation is to detect problems with BIOS-exposed predefined ACPI objects
133193267Sjkim * before the results are returned to the ACPI-related drivers.
134193267Sjkim *
135193267Sjkim * There are several areas that are validated:
136193267Sjkim *
137193267Sjkim *  1) The number of input arguments as defined by the method/object in the
138193267Sjkim *      ASL is validated against the ACPI specification.
139193267Sjkim *  2) The type of the return object (if any) is validated against the ACPI
140193267Sjkim *      specification.
141193267Sjkim *  3) For returned package objects, the count of package elements is
142193267Sjkim *      validated, as well as the type of each package element. Nested
143193267Sjkim *      packages are supported.
144193267Sjkim *
145193267Sjkim * For any problems found, a warning message is issued.
146193267Sjkim *
147193267Sjkim ******************************************************************************/
148193267Sjkim
149193267Sjkim/* Local prototypes */
150193267Sjkim
151193267Sjkimstatic ACPI_STATUS
152193267SjkimAcpiNsCheckPackage (
153193267Sjkim    char                        *Pathname,
154193267Sjkim    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
155193267Sjkim    const ACPI_PREDEFINED_INFO  *Predefined);
156193267Sjkim
157193267Sjkimstatic ACPI_STATUS
158193267SjkimAcpiNsCheckPackageElements (
159193267Sjkim    char                        *Pathname,
160193267Sjkim    ACPI_OPERAND_OBJECT         **Elements,
161193267Sjkim    UINT8                       Type1,
162193267Sjkim    UINT32                      Count1,
163193267Sjkim    UINT8                       Type2,
164193267Sjkim    UINT32                      Count2,
165193267Sjkim    UINT32                      StartIndex);
166193267Sjkim
167193267Sjkimstatic ACPI_STATUS
168193267SjkimAcpiNsCheckObjectType (
169193267Sjkim    char                        *Pathname,
170193267Sjkim    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
171193267Sjkim    UINT32                      ExpectedBtypes,
172193267Sjkim    UINT32                      PackageIndex);
173193267Sjkim
174193267Sjkimstatic ACPI_STATUS
175193267SjkimAcpiNsCheckReference (
176193267Sjkim    char                        *Pathname,
177193267Sjkim    ACPI_OPERAND_OBJECT         *ReturnObject);
178193267Sjkim
179193267Sjkimstatic ACPI_STATUS
180193267SjkimAcpiNsRepairObject (
181193267Sjkim    UINT32                      ExpectedBtypes,
182193267Sjkim    UINT32                      PackageIndex,
183193267Sjkim    ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
184193267Sjkim
185193267Sjkim/*
186193267Sjkim * Names for the types that can be returned by the predefined objects.
187193267Sjkim * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
188193267Sjkim */
189193267Sjkimstatic const char   *AcpiRtypeNames[] =
190193267Sjkim{
191193267Sjkim    "/Integer",
192193267Sjkim    "/String",
193193267Sjkim    "/Buffer",
194193267Sjkim    "/Package",
195193267Sjkim    "/Reference",
196193267Sjkim};
197193267Sjkim
198193267Sjkim#define ACPI_NOT_PACKAGE    ACPI_UINT32_MAX
199193267Sjkim
200193267Sjkim
201193267Sjkim/*******************************************************************************
202193267Sjkim *
203193267Sjkim * FUNCTION:    AcpiNsCheckPredefinedNames
204193267Sjkim *
205193267Sjkim * PARAMETERS:  Node            - Namespace node for the method/object
206193267Sjkim *              ReturnObjectPtr - Pointer to the object returned from the
207193267Sjkim *                                evaluation of a method or object
208193267Sjkim *
209193267Sjkim * RETURN:      Status
210193267Sjkim *
211193267Sjkim * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
212193267Sjkim *
213193267Sjkim ******************************************************************************/
214193267Sjkim
215193267SjkimACPI_STATUS
216193267SjkimAcpiNsCheckPredefinedNames (
217193267Sjkim    ACPI_NAMESPACE_NODE         *Node,
218193267Sjkim    UINT32                      UserParamCount,
219193267Sjkim    ACPI_STATUS                 ReturnStatus,
220193267Sjkim    ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
221193267Sjkim{
222193267Sjkim    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
223193267Sjkim    ACPI_STATUS                 Status = AE_OK;
224193267Sjkim    const ACPI_PREDEFINED_INFO  *Predefined;
225193267Sjkim    char                        *Pathname;
226193267Sjkim
227193267Sjkim
228193267Sjkim    /* Match the name for this method/object against the predefined list */
229193267Sjkim
230193267Sjkim    Predefined = AcpiNsCheckForPredefinedName (Node);
231193267Sjkim
232193267Sjkim    /* Get the full pathname to the object, for use in error messages */
233193267Sjkim
234193267Sjkim    Pathname = AcpiNsGetExternalPathname (Node);
235193267Sjkim    if (!Pathname)
236193267Sjkim    {
237193267Sjkim        return (AE_OK); /* Could not get pathname, ignore */
238193267Sjkim    }
239193267Sjkim
240193267Sjkim    /*
241193267Sjkim     * Check that the parameter count for this method matches the ASL
242193267Sjkim     * definition. For predefined names, ensure that both the caller and
243193267Sjkim     * the method itself are in accordance with the ACPI specification.
244193267Sjkim     */
245193267Sjkim    AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
246193267Sjkim
247193267Sjkim    /* If not a predefined name, we cannot validate the return object */
248193267Sjkim
249193267Sjkim    if (!Predefined)
250193267Sjkim    {
251193267Sjkim        goto Exit;
252193267Sjkim    }
253193267Sjkim
254193267Sjkim    /* If the method failed, we cannot validate the return object */
255193267Sjkim
256193267Sjkim    if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
257193267Sjkim    {
258193267Sjkim        goto Exit;
259193267Sjkim    }
260193267Sjkim
261193267Sjkim    /*
262193267Sjkim     * Only validate the return value on the first successful evaluation of
263193267Sjkim     * the method. This ensures that any warnings will only be emitted during
264193267Sjkim     * the very first evaluation of the method/object.
265193267Sjkim     */
266193267Sjkim    if (Node->Flags & ANOBJ_EVALUATED)
267193267Sjkim    {
268193267Sjkim        goto Exit;
269193267Sjkim    }
270193267Sjkim
271193267Sjkim    /* Mark the node as having been successfully evaluated */
272193267Sjkim
273193267Sjkim    Node->Flags |= ANOBJ_EVALUATED;
274193267Sjkim
275193267Sjkim    /*
276193267Sjkim     * If there is no return value, check if we require a return value for
277193267Sjkim     * this predefined name. Either one return value is expected, or none,
278193267Sjkim     * for both methods and other objects.
279193267Sjkim     *
280193267Sjkim     * Exit now if there is no return object. Warning if one was expected.
281193267Sjkim     */
282193267Sjkim    if (!ReturnObject)
283193267Sjkim    {
284193267Sjkim        if ((Predefined->Info.ExpectedBtypes) &&
285193267Sjkim            (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
286193267Sjkim        {
287193267Sjkim            ACPI_ERROR ((AE_INFO,
288193267Sjkim                "%s: Missing expected return value", Pathname));
289193267Sjkim
290193267Sjkim            Status = AE_AML_NO_RETURN_VALUE;
291193267Sjkim        }
292193267Sjkim        goto Exit;
293193267Sjkim    }
294193267Sjkim
295193267Sjkim    /*
296193267Sjkim     * We have a return value, but if one wasn't expected, just exit, this is
297193267Sjkim     * not a problem
298193267Sjkim     *
299193267Sjkim     * For example, if the "Implicit Return" feature is enabled, methods will
300193267Sjkim     * always return a value
301193267Sjkim     */
302193267Sjkim    if (!Predefined->Info.ExpectedBtypes)
303193267Sjkim    {
304193267Sjkim        goto Exit;
305193267Sjkim    }
306193267Sjkim
307193267Sjkim    /*
308193267Sjkim     * Check that the type of the return object is what is expected for
309193267Sjkim     * this predefined name
310193267Sjkim     */
311193267Sjkim    Status = AcpiNsCheckObjectType (Pathname, ReturnObjectPtr,
312193267Sjkim                Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE);
313193267Sjkim    if (ACPI_FAILURE (Status))
314193267Sjkim    {
315193267Sjkim        goto Exit;
316193267Sjkim    }
317193267Sjkim
318193267Sjkim    /* For returned Package objects, check the type of all sub-objects */
319193267Sjkim
320193267Sjkim    if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE)
321193267Sjkim    {
322193267Sjkim        Status = AcpiNsCheckPackage (Pathname, ReturnObjectPtr, Predefined);
323193267Sjkim    }
324193267Sjkim
325193267SjkimExit:
326193267Sjkim    ACPI_FREE (Pathname);
327193267Sjkim    return (Status);
328193267Sjkim}
329193267Sjkim
330193267Sjkim
331193267Sjkim/*******************************************************************************
332193267Sjkim *
333193267Sjkim * FUNCTION:    AcpiNsCheckParameterCount
334193267Sjkim *
335193267Sjkim * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
336193267Sjkim *              Node            - Namespace node for the method/object
337193267Sjkim *              UserParamCount  - Number of args passed in by the caller
338193267Sjkim *              Predefined      - Pointer to entry in predefined name table
339193267Sjkim *
340193267Sjkim * RETURN:      None
341193267Sjkim *
342193267Sjkim * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
343193267Sjkim *              predefined name is what is expected (i.e., what is defined in
344193267Sjkim *              the ACPI specification for this predefined name.)
345193267Sjkim *
346193267Sjkim ******************************************************************************/
347193267Sjkim
348193267Sjkimvoid
349193267SjkimAcpiNsCheckParameterCount (
350193267Sjkim    char                        *Pathname,
351193267Sjkim    ACPI_NAMESPACE_NODE         *Node,
352193267Sjkim    UINT32                      UserParamCount,
353193267Sjkim    const ACPI_PREDEFINED_INFO  *Predefined)
354193267Sjkim{
355193267Sjkim    UINT32                      ParamCount;
356193267Sjkim    UINT32                      RequiredParamsCurrent;
357193267Sjkim    UINT32                      RequiredParamsOld;
358193267Sjkim
359193267Sjkim
360193267Sjkim    /* Methods have 0-7 parameters. All other types have zero. */
361193267Sjkim
362193267Sjkim    ParamCount = 0;
363193267Sjkim    if (Node->Type == ACPI_TYPE_METHOD)
364193267Sjkim    {
365193267Sjkim        ParamCount = Node->Object->Method.ParamCount;
366193267Sjkim    }
367193267Sjkim
368193267Sjkim    /* Argument count check for non-predefined methods/objects */
369193267Sjkim
370193267Sjkim    if (!Predefined)
371193267Sjkim    {
372193267Sjkim        /*
373193267Sjkim         * Warning if too few or too many arguments have been passed by the
374193267Sjkim         * caller. An incorrect number of arguments may not cause the method
375193267Sjkim         * to fail. However, the method will fail if there are too few
376193267Sjkim         * arguments and the method attempts to use one of the missing ones.
377193267Sjkim         */
378193267Sjkim        if (UserParamCount < ParamCount)
379193267Sjkim        {
380193267Sjkim            ACPI_WARNING ((AE_INFO,
381193267Sjkim                "%s: Insufficient arguments - needs %d, found %d",
382193267Sjkim                Pathname, ParamCount, UserParamCount));
383193267Sjkim        }
384193267Sjkim        else if (UserParamCount > ParamCount)
385193267Sjkim        {
386193267Sjkim            ACPI_WARNING ((AE_INFO,
387193267Sjkim                "%s: Excess arguments - needs %d, found %d",
388193267Sjkim                Pathname, ParamCount, UserParamCount));
389193267Sjkim        }
390193267Sjkim        return;
391193267Sjkim    }
392193267Sjkim
393193267Sjkim    /* Allow two different legal argument counts (_SCP, etc.) */
394193267Sjkim
395193267Sjkim    RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
396193267Sjkim    RequiredParamsOld = Predefined->Info.ParamCount >> 4;
397193267Sjkim
398193267Sjkim    if (UserParamCount != ACPI_UINT32_MAX)
399193267Sjkim    {
400193267Sjkim        /* Validate the user-supplied parameter count */
401193267Sjkim
402193267Sjkim        if ((UserParamCount != RequiredParamsCurrent) &&
403193267Sjkim            (UserParamCount != RequiredParamsOld))
404193267Sjkim        {
405193267Sjkim            ACPI_WARNING ((AE_INFO,
406193267Sjkim                "%s: Parameter count mismatch - "
407193267Sjkim                "caller passed %d, ACPI requires %d",
408193267Sjkim                Pathname, UserParamCount, RequiredParamsCurrent));
409193267Sjkim        }
410193267Sjkim    }
411193267Sjkim
412193267Sjkim    /*
413193267Sjkim     * Only validate the argument count on the first successful evaluation of
414193267Sjkim     * the method. This ensures that any warnings will only be emitted during
415193267Sjkim     * the very first evaluation of the method/object.
416193267Sjkim     */
417193267Sjkim    if (Node->Flags & ANOBJ_EVALUATED)
418193267Sjkim    {
419193267Sjkim        return;
420193267Sjkim    }
421193267Sjkim
422193267Sjkim    /*
423193267Sjkim     * Check that the ASL-defined parameter count is what is expected for
424193267Sjkim     * this predefined name.
425193267Sjkim     */
426193267Sjkim    if ((ParamCount != RequiredParamsCurrent) &&
427193267Sjkim        (ParamCount != RequiredParamsOld))
428193267Sjkim    {
429193267Sjkim        ACPI_WARNING ((AE_INFO,
430193267Sjkim            "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d",
431193267Sjkim            Pathname, ParamCount, RequiredParamsCurrent));
432193267Sjkim    }
433193267Sjkim}
434193267Sjkim
435193267Sjkim
436193267Sjkim/*******************************************************************************
437193267Sjkim *
438193267Sjkim * FUNCTION:    AcpiNsCheckForPredefinedName
439193267Sjkim *
440193267Sjkim * PARAMETERS:  Node            - Namespace node for the method/object
441193267Sjkim *
442193267Sjkim * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
443193267Sjkim *
444193267Sjkim * DESCRIPTION: Check an object name against the predefined object list.
445193267Sjkim *
446193267Sjkim ******************************************************************************/
447193267Sjkim
448193267Sjkimconst ACPI_PREDEFINED_INFO *
449193267SjkimAcpiNsCheckForPredefinedName (
450193267Sjkim    ACPI_NAMESPACE_NODE         *Node)
451193267Sjkim{
452193267Sjkim    const ACPI_PREDEFINED_INFO  *ThisName;
453193267Sjkim
454193267Sjkim
455193267Sjkim    /* Quick check for a predefined name, first character must be underscore */
456193267Sjkim
457193267Sjkim    if (Node->Name.Ascii[0] != '_')
458193267Sjkim    {
459193267Sjkim        return (NULL);
460193267Sjkim    }
461193267Sjkim
462193267Sjkim    /* Search info table for a predefined method/object name */
463193267Sjkim
464193267Sjkim    ThisName = PredefinedNames;
465193267Sjkim    while (ThisName->Info.Name[0])
466193267Sjkim    {
467193267Sjkim        if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
468193267Sjkim        {
469193267Sjkim            /* Return pointer to this table entry */
470193267Sjkim
471193267Sjkim            return (ThisName);
472193267Sjkim        }
473193267Sjkim
474193267Sjkim        /*
475193267Sjkim         * Skip next entry in the table if this name returns a Package
476193267Sjkim         * (next entry contains the package info)
477193267Sjkim         */
478193267Sjkim        if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
479193267Sjkim        {
480193267Sjkim            ThisName++;
481193267Sjkim        }
482193267Sjkim
483193267Sjkim        ThisName++;
484193267Sjkim    }
485193267Sjkim
486193267Sjkim    return (NULL);
487193267Sjkim}
488193267Sjkim
489193267Sjkim
490193267Sjkim/*******************************************************************************
491193267Sjkim *
492193267Sjkim * FUNCTION:    AcpiNsCheckPackage
493193267Sjkim *
494193267Sjkim * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
495193267Sjkim *              ReturnObjectPtr - Pointer to the object returned from the
496193267Sjkim *                                evaluation of a method or object
497193267Sjkim *              Predefined      - Pointer to entry in predefined name table
498193267Sjkim *
499193267Sjkim * RETURN:      Status
500193267Sjkim *
501193267Sjkim * DESCRIPTION: Check a returned package object for the correct count and
502193267Sjkim *              correct type of all sub-objects.
503193267Sjkim *
504193267Sjkim ******************************************************************************/
505193267Sjkim
506193267Sjkimstatic ACPI_STATUS
507193267SjkimAcpiNsCheckPackage (
508193267Sjkim    char                        *Pathname,
509193267Sjkim    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
510193267Sjkim    const ACPI_PREDEFINED_INFO  *Predefined)
511193267Sjkim{
512193267Sjkim    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
513193267Sjkim    const ACPI_PREDEFINED_INFO  *Package;
514193267Sjkim    ACPI_OPERAND_OBJECT         *SubPackage;
515193267Sjkim    ACPI_OPERAND_OBJECT         **Elements;
516193267Sjkim    ACPI_OPERAND_OBJECT         **SubElements;
517193267Sjkim    ACPI_STATUS                 Status;
518193267Sjkim    UINT32                      ExpectedCount;
519193267Sjkim    UINT32                      Count;
520193267Sjkim    UINT32                      i;
521193267Sjkim    UINT32                      j;
522193267Sjkim
523193267Sjkim
524193267Sjkim    ACPI_FUNCTION_NAME (NsCheckPackage);
525193267Sjkim
526193267Sjkim
527193267Sjkim    /* The package info for this name is in the next table entry */
528193267Sjkim
529193267Sjkim    Package = Predefined + 1;
530193267Sjkim
531193267Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
532193267Sjkim        "%s Validating return Package of Type %X, Count %X\n",
533193267Sjkim        Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
534193267Sjkim
535193267Sjkim    /* Extract package count and elements array */
536193267Sjkim
537193267Sjkim    Elements = ReturnObject->Package.Elements;
538193267Sjkim    Count = ReturnObject->Package.Count;
539193267Sjkim
540193267Sjkim    /* The package must have at least one element, else invalid */
541193267Sjkim
542193267Sjkim    if (!Count)
543193267Sjkim    {
544193267Sjkim        ACPI_WARNING ((AE_INFO,
545193267Sjkim            "%s: Return Package has no elements (empty)", Pathname));
546193267Sjkim
547193267Sjkim        return (AE_AML_OPERAND_VALUE);
548193267Sjkim    }
549193267Sjkim
550193267Sjkim    /*
551193267Sjkim     * Decode the type of the expected package contents
552193267Sjkim     *
553193267Sjkim     * PTYPE1 packages contain no subpackages
554193267Sjkim     * PTYPE2 packages contain sub-packages
555193267Sjkim     */
556193267Sjkim    switch (Package->RetInfo.Type)
557193267Sjkim    {
558193267Sjkim    case ACPI_PTYPE1_FIXED:
559193267Sjkim
560193267Sjkim        /*
561193267Sjkim         * The package count is fixed and there are no sub-packages
562193267Sjkim         *
563193267Sjkim         * If package is too small, exit.
564193267Sjkim         * If package is larger than expected, issue warning but continue
565193267Sjkim         */
566193267Sjkim        ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
567193267Sjkim        if (Count < ExpectedCount)
568193267Sjkim        {
569193267Sjkim            goto PackageTooSmall;
570193267Sjkim        }
571193267Sjkim        else if (Count > ExpectedCount)
572193267Sjkim        {
573193267Sjkim            ACPI_WARNING ((AE_INFO,
574193267Sjkim                "%s: Return Package is larger than needed - "
575193267Sjkim                "found %u, expected %u", Pathname, Count, ExpectedCount));
576193267Sjkim        }
577193267Sjkim
578193267Sjkim        /* Validate all elements of the returned package */
579193267Sjkim
580193267Sjkim        Status = AcpiNsCheckPackageElements (Pathname, Elements,
581193267Sjkim                    Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
582193267Sjkim                    Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
583193267Sjkim        if (ACPI_FAILURE (Status))
584193267Sjkim        {
585193267Sjkim            return (Status);
586193267Sjkim        }
587193267Sjkim        break;
588193267Sjkim
589193267Sjkim
590193267Sjkim    case ACPI_PTYPE1_VAR:
591193267Sjkim
592193267Sjkim        /*
593193267Sjkim         * The package count is variable, there are no sub-packages, and all
594193267Sjkim         * elements must be of the same type
595193267Sjkim         */
596193267Sjkim        for (i = 0; i < Count; i++)
597193267Sjkim        {
598193267Sjkim            Status = AcpiNsCheckObjectType (Pathname, Elements,
599193267Sjkim                        Package->RetInfo.ObjectType1, i);
600193267Sjkim            if (ACPI_FAILURE (Status))
601193267Sjkim            {
602193267Sjkim                return (Status);
603193267Sjkim            }
604193267Sjkim            Elements++;
605193267Sjkim        }
606193267Sjkim        break;
607193267Sjkim
608193267Sjkim
609193267Sjkim    case ACPI_PTYPE1_OPTION:
610193267Sjkim
611193267Sjkim        /*
612193267Sjkim         * The package count is variable, there are no sub-packages. There are
613193267Sjkim         * a fixed number of required elements, and a variable number of
614193267Sjkim         * optional elements.
615193267Sjkim         *
616193267Sjkim         * Check if package is at least as large as the minimum required
617193267Sjkim         */
618193267Sjkim        ExpectedCount = Package->RetInfo3.Count;
619193267Sjkim        if (Count < ExpectedCount)
620193267Sjkim        {
621193267Sjkim            goto PackageTooSmall;
622193267Sjkim        }
623193267Sjkim
624193267Sjkim        /* Variable number of sub-objects */
625193267Sjkim
626193267Sjkim        for (i = 0; i < Count; i++)
627193267Sjkim        {
628193267Sjkim            if (i < Package->RetInfo3.Count)
629193267Sjkim            {
630193267Sjkim                /* These are the required package elements (0, 1, or 2) */
631193267Sjkim
632193267Sjkim                Status = AcpiNsCheckObjectType (Pathname, Elements,
633193267Sjkim                            Package->RetInfo3.ObjectType[i], i);
634193267Sjkim                if (ACPI_FAILURE (Status))
635193267Sjkim                {
636193267Sjkim                    return (Status);
637193267Sjkim                }
638193267Sjkim            }
639193267Sjkim            else
640193267Sjkim            {
641193267Sjkim                /* These are the optional package elements */
642193267Sjkim
643193267Sjkim                Status = AcpiNsCheckObjectType (Pathname, Elements,
644193267Sjkim                            Package->RetInfo3.TailObjectType, i);
645193267Sjkim                if (ACPI_FAILURE (Status))
646193267Sjkim                {
647193267Sjkim                    return (Status);
648193267Sjkim                }
649193267Sjkim            }
650193267Sjkim            Elements++;
651193267Sjkim        }
652193267Sjkim        break;
653193267Sjkim
654193267Sjkim
655193267Sjkim    case ACPI_PTYPE2_PKG_COUNT:
656193267Sjkim
657193267Sjkim        /* First element is the (Integer) count of sub-packages to follow */
658193267Sjkim
659193267Sjkim        Status = AcpiNsCheckObjectType (Pathname, Elements,
660193267Sjkim                    ACPI_RTYPE_INTEGER, 0);
661193267Sjkim        if (ACPI_FAILURE (Status))
662193267Sjkim        {
663193267Sjkim            return (Status);
664193267Sjkim        }
665193267Sjkim
666193267Sjkim        /*
667193267Sjkim         * Count cannot be larger than the parent package length, but allow it
668193267Sjkim         * to be smaller. The >= accounts for the Integer above.
669193267Sjkim         */
670193267Sjkim        ExpectedCount = (UINT32) (*Elements)->Integer.Value;
671193267Sjkim        if (ExpectedCount >= Count)
672193267Sjkim        {
673193267Sjkim            goto PackageTooSmall;
674193267Sjkim        }
675193267Sjkim
676193267Sjkim        Count = ExpectedCount;
677193267Sjkim        Elements++;
678193267Sjkim
679193267Sjkim        /* Now we can walk the sub-packages */
680193267Sjkim
681193267Sjkim        /*lint -fallthrough */
682193267Sjkim
683193267Sjkim
684193267Sjkim    case ACPI_PTYPE2:
685193267Sjkim    case ACPI_PTYPE2_FIXED:
686193267Sjkim    case ACPI_PTYPE2_MIN:
687193267Sjkim    case ACPI_PTYPE2_COUNT:
688193267Sjkim
689193267Sjkim        /*
690193267Sjkim         * These types all return a single package that consists of a variable
691193267Sjkim         * number of sub-packages
692193267Sjkim         */
693193267Sjkim        for (i = 0; i < Count; i++)
694193267Sjkim        {
695193267Sjkim            SubPackage = *Elements;
696193267Sjkim            SubElements = SubPackage->Package.Elements;
697193267Sjkim
698193267Sjkim            /* Each sub-object must be of type Package */
699193267Sjkim
700193267Sjkim            Status = AcpiNsCheckObjectType (Pathname, &SubPackage,
701193267Sjkim                        ACPI_RTYPE_PACKAGE, i);
702193267Sjkim            if (ACPI_FAILURE (Status))
703193267Sjkim            {
704193267Sjkim                return (Status);
705193267Sjkim            }
706193267Sjkim
707193267Sjkim            /* Examine the different types of sub-packages */
708193267Sjkim
709193267Sjkim            switch (Package->RetInfo.Type)
710193267Sjkim            {
711193267Sjkim            case ACPI_PTYPE2:
712193267Sjkim            case ACPI_PTYPE2_PKG_COUNT:
713193267Sjkim
714193267Sjkim                /* Each subpackage has a fixed number of elements */
715193267Sjkim
716193267Sjkim                ExpectedCount =
717193267Sjkim                    Package->RetInfo.Count1 + Package->RetInfo.Count2;
718193267Sjkim                if (SubPackage->Package.Count != ExpectedCount)
719193267Sjkim                {
720193267Sjkim                    Count = SubPackage->Package.Count;
721193267Sjkim                    goto PackageTooSmall;
722193267Sjkim                }
723193267Sjkim
724193267Sjkim                Status = AcpiNsCheckPackageElements (Pathname, SubElements,
725193267Sjkim                            Package->RetInfo.ObjectType1,
726193267Sjkim                            Package->RetInfo.Count1,
727193267Sjkim                            Package->RetInfo.ObjectType2,
728193267Sjkim                            Package->RetInfo.Count2, 0);
729193267Sjkim                if (ACPI_FAILURE (Status))
730193267Sjkim                {
731193267Sjkim                    return (Status);
732193267Sjkim                }
733193267Sjkim                break;
734193267Sjkim
735193267Sjkim            case ACPI_PTYPE2_FIXED:
736193267Sjkim
737193267Sjkim                /* Each sub-package has a fixed length */
738193267Sjkim
739193267Sjkim                ExpectedCount = Package->RetInfo2.Count;
740193267Sjkim                if (SubPackage->Package.Count < ExpectedCount)
741193267Sjkim                {
742193267Sjkim                    Count = SubPackage->Package.Count;
743193267Sjkim                    goto PackageTooSmall;
744193267Sjkim                }
745193267Sjkim
746193267Sjkim                /* Check the type of each sub-package element */
747193267Sjkim
748193267Sjkim                for (j = 0; j < ExpectedCount; j++)
749193267Sjkim                {
750193267Sjkim                    Status = AcpiNsCheckObjectType (Pathname, &SubElements[j],
751193267Sjkim                                Package->RetInfo2.ObjectType[j], j);
752193267Sjkim                    if (ACPI_FAILURE (Status))
753193267Sjkim                    {
754193267Sjkim                        return (Status);
755193267Sjkim                    }
756193267Sjkim                }
757193267Sjkim                break;
758193267Sjkim
759193267Sjkim            case ACPI_PTYPE2_MIN:
760193267Sjkim
761193267Sjkim                /* Each sub-package has a variable but minimum length */
762193267Sjkim
763193267Sjkim                ExpectedCount = Package->RetInfo.Count1;
764193267Sjkim                if (SubPackage->Package.Count < ExpectedCount)
765193267Sjkim                {
766193267Sjkim                    Count = SubPackage->Package.Count;
767193267Sjkim                    goto PackageTooSmall;
768193267Sjkim                }
769193267Sjkim
770193267Sjkim                /* Check the type of each sub-package element */
771193267Sjkim
772193267Sjkim                Status = AcpiNsCheckPackageElements (Pathname, SubElements,
773193267Sjkim                            Package->RetInfo.ObjectType1,
774193267Sjkim                            SubPackage->Package.Count, 0, 0, 0);
775193267Sjkim                if (ACPI_FAILURE (Status))
776193267Sjkim                {
777193267Sjkim                    return (Status);
778193267Sjkim                }
779193267Sjkim                break;
780193267Sjkim
781193267Sjkim            case ACPI_PTYPE2_COUNT:
782193267Sjkim
783193267Sjkim                /* First element is the (Integer) count of elements to follow */
784193267Sjkim
785193267Sjkim                Status = AcpiNsCheckObjectType (Pathname, SubElements,
786193267Sjkim                            ACPI_RTYPE_INTEGER, 0);
787193267Sjkim                if (ACPI_FAILURE (Status))
788193267Sjkim                {
789193267Sjkim                    return (Status);
790193267Sjkim                }
791193267Sjkim
792193267Sjkim                /* Make sure package is large enough for the Count */
793193267Sjkim
794193267Sjkim                ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
795193267Sjkim                if (SubPackage->Package.Count < ExpectedCount)
796193267Sjkim                {
797193267Sjkim                    Count = SubPackage->Package.Count;
798193267Sjkim                    goto PackageTooSmall;
799193267Sjkim                }
800193267Sjkim
801193267Sjkim                /* Check the type of each sub-package element */
802193267Sjkim
803193267Sjkim                Status = AcpiNsCheckPackageElements (Pathname,
804193267Sjkim                            (SubElements + 1),
805193267Sjkim                            Package->RetInfo.ObjectType1,
806193267Sjkim                            (ExpectedCount - 1), 0, 0, 1);
807193267Sjkim                if (ACPI_FAILURE (Status))
808193267Sjkim                {
809193267Sjkim                    return (Status);
810193267Sjkim                }
811193267Sjkim                break;
812193267Sjkim
813193267Sjkim            default:
814193267Sjkim                break;
815193267Sjkim            }
816193267Sjkim
817193267Sjkim            Elements++;
818193267Sjkim        }
819193267Sjkim        break;
820193267Sjkim
821193267Sjkim
822193267Sjkim    default:
823193267Sjkim
824193267Sjkim        /* Should not get here if predefined info table is correct */
825193267Sjkim
826193267Sjkim        ACPI_WARNING ((AE_INFO,
827193267Sjkim            "%s: Invalid internal return type in table entry: %X",
828193267Sjkim            Pathname, Package->RetInfo.Type));
829193267Sjkim
830193267Sjkim        return (AE_AML_INTERNAL);
831193267Sjkim    }
832193267Sjkim
833193267Sjkim    return (AE_OK);
834193267Sjkim
835193267Sjkim
836193267SjkimPackageTooSmall:
837193267Sjkim
838193267Sjkim    /* Error exit for the case with an incorrect package count */
839193267Sjkim
840193267Sjkim    ACPI_WARNING ((AE_INFO, "%s: Return Package is too small - "
841193267Sjkim        "found %u, expected %u", Pathname, Count, ExpectedCount));
842193267Sjkim
843193267Sjkim    return (AE_AML_OPERAND_VALUE);
844193267Sjkim}
845193267Sjkim
846193267Sjkim
847193267Sjkim/*******************************************************************************
848193267Sjkim *
849193267Sjkim * FUNCTION:    AcpiNsCheckPackageElements
850193267Sjkim *
851193267Sjkim * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
852193267Sjkim *              Elements        - Pointer to the package elements array
853193267Sjkim *              Type1           - Object type for first group
854193267Sjkim *              Count1          - Count for first group
855193267Sjkim *              Type2           - Object type for second group
856193267Sjkim *              Count2          - Count for second group
857193267Sjkim *              StartIndex      - Start of the first group of elements
858193267Sjkim *
859193267Sjkim * RETURN:      Status
860193267Sjkim *
861193267Sjkim * DESCRIPTION: Check that all elements of a package are of the correct object
862193267Sjkim *              type. Supports up to two groups of different object types.
863193267Sjkim *
864193267Sjkim ******************************************************************************/
865193267Sjkim
866193267Sjkimstatic ACPI_STATUS
867193267SjkimAcpiNsCheckPackageElements (
868193267Sjkim    char                        *Pathname,
869193267Sjkim    ACPI_OPERAND_OBJECT         **Elements,
870193267Sjkim    UINT8                       Type1,
871193267Sjkim    UINT32                      Count1,
872193267Sjkim    UINT8                       Type2,
873193267Sjkim    UINT32                      Count2,
874193267Sjkim    UINT32                      StartIndex)
875193267Sjkim{
876193267Sjkim    ACPI_OPERAND_OBJECT         **ThisElement = Elements;
877193267Sjkim    ACPI_STATUS                 Status;
878193267Sjkim    UINT32                      i;
879193267Sjkim
880193267Sjkim
881193267Sjkim    /*
882193267Sjkim     * Up to two groups of package elements are supported by the data
883193267Sjkim     * structure. All elements in each group must be of the same type.
884193267Sjkim     * The second group can have a count of zero.
885193267Sjkim     */
886193267Sjkim    for (i = 0; i < Count1; i++)
887193267Sjkim    {
888193267Sjkim        Status = AcpiNsCheckObjectType (Pathname, ThisElement,
889193267Sjkim                    Type1, i + StartIndex);
890193267Sjkim        if (ACPI_FAILURE (Status))
891193267Sjkim        {
892193267Sjkim            return (Status);
893193267Sjkim        }
894193267Sjkim        ThisElement++;
895193267Sjkim    }
896193267Sjkim
897193267Sjkim    for (i = 0; i < Count2; i++)
898193267Sjkim    {
899193267Sjkim        Status = AcpiNsCheckObjectType (Pathname, ThisElement,
900193267Sjkim                    Type2, (i + Count1 + StartIndex));
901193267Sjkim        if (ACPI_FAILURE (Status))
902193267Sjkim        {
903193267Sjkim            return (Status);
904193267Sjkim        }
905193267Sjkim        ThisElement++;
906193267Sjkim    }
907193267Sjkim
908193267Sjkim    return (AE_OK);
909193267Sjkim}
910193267Sjkim
911193267Sjkim
912193267Sjkim/*******************************************************************************
913193267Sjkim *
914193267Sjkim * FUNCTION:    AcpiNsCheckObjectType
915193267Sjkim *
916193267Sjkim * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
917193267Sjkim *              ReturnObjectPtr - Pointer to the object returned from the
918193267Sjkim *                                evaluation of a method or object
919193267Sjkim *              ExpectedBtypes  - Bitmap of expected return type(s)
920193267Sjkim *              PackageIndex    - Index of object within parent package (if
921193267Sjkim *                                applicable - ACPI_NOT_PACKAGE otherwise)
922193267Sjkim *
923193267Sjkim * RETURN:      Status
924193267Sjkim *
925193267Sjkim * DESCRIPTION: Check the type of the return object against the expected object
926193267Sjkim *              type(s). Use of Btype allows multiple expected object types.
927193267Sjkim *
928193267Sjkim ******************************************************************************/
929193267Sjkim
930193267Sjkimstatic ACPI_STATUS
931193267SjkimAcpiNsCheckObjectType (
932193267Sjkim    char                        *Pathname,
933193267Sjkim    ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
934193267Sjkim    UINT32                      ExpectedBtypes,
935193267Sjkim    UINT32                      PackageIndex)
936193267Sjkim{
937193267Sjkim    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
938193267Sjkim    ACPI_STATUS                 Status = AE_OK;
939193267Sjkim    UINT32                      ReturnBtype;
940193267Sjkim    char                        TypeBuffer[48]; /* Room for 5 types */
941193267Sjkim    UINT32                      ThisRtype;
942193267Sjkim    UINT32                      i;
943193267Sjkim    UINT32                      j;
944193267Sjkim
945193267Sjkim
946193267Sjkim    /*
947193267Sjkim     * If we get a NULL ReturnObject here, it is a NULL package element,
948193267Sjkim     * and this is always an error.
949193267Sjkim     */
950193267Sjkim    if (!ReturnObject)
951193267Sjkim    {
952193267Sjkim        goto TypeErrorExit;
953193267Sjkim    }
954193267Sjkim
955193267Sjkim    /* A Namespace node should not get here, but make sure */
956193267Sjkim
957193267Sjkim    if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
958193267Sjkim    {
959193267Sjkim        ACPI_WARNING ((AE_INFO,
960193267Sjkim            "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
961193267Sjkim            Pathname, ReturnObject->Node.Name.Ascii,
962193267Sjkim            AcpiUtGetTypeName (ReturnObject->Node.Type)));
963193267Sjkim        return (AE_AML_OPERAND_TYPE);
964193267Sjkim    }
965193267Sjkim
966193267Sjkim    /*
967193267Sjkim     * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
968193267Sjkim     * The bitmapped type allows multiple possible return types.
969193267Sjkim     *
970193267Sjkim     * Note, the cases below must handle all of the possible types returned
971193267Sjkim     * from all of the predefined names (including elements of returned
972193267Sjkim     * packages)
973193267Sjkim     */
974193267Sjkim    switch (ReturnObject->Common.Type)
975193267Sjkim    {
976193267Sjkim    case ACPI_TYPE_INTEGER:
977193267Sjkim        ReturnBtype = ACPI_RTYPE_INTEGER;
978193267Sjkim        break;
979193267Sjkim
980193267Sjkim    case ACPI_TYPE_BUFFER:
981193267Sjkim        ReturnBtype = ACPI_RTYPE_BUFFER;
982193267Sjkim        break;
983193267Sjkim
984193267Sjkim    case ACPI_TYPE_STRING:
985193267Sjkim        ReturnBtype = ACPI_RTYPE_STRING;
986193267Sjkim        break;
987193267Sjkim
988193267Sjkim    case ACPI_TYPE_PACKAGE:
989193267Sjkim        ReturnBtype = ACPI_RTYPE_PACKAGE;
990193267Sjkim        break;
991193267Sjkim
992193267Sjkim    case ACPI_TYPE_LOCAL_REFERENCE:
993193267Sjkim        ReturnBtype = ACPI_RTYPE_REFERENCE;
994193267Sjkim        break;
995193267Sjkim
996193267Sjkim    default:
997193267Sjkim        /* Not one of the supported objects, must be incorrect */
998193267Sjkim
999193267Sjkim        goto TypeErrorExit;
1000193267Sjkim    }
1001193267Sjkim
1002193267Sjkim    /* Is the object one of the expected types? */
1003193267Sjkim
1004193267Sjkim    if (!(ReturnBtype & ExpectedBtypes))
1005193267Sjkim    {
1006193267Sjkim        /* Type mismatch -- attempt repair of the returned object */
1007193267Sjkim
1008193267Sjkim        Status = AcpiNsRepairObject (ExpectedBtypes, PackageIndex,
1009193267Sjkim                    ReturnObjectPtr);
1010193267Sjkim        if (ACPI_SUCCESS (Status))
1011193267Sjkim        {
1012193267Sjkim            return (Status);
1013193267Sjkim        }
1014193267Sjkim        goto TypeErrorExit;
1015193267Sjkim    }
1016193267Sjkim
1017193267Sjkim    /* For reference objects, check that the reference type is correct */
1018193267Sjkim
1019193267Sjkim    if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1020193267Sjkim    {
1021193267Sjkim        Status = AcpiNsCheckReference (Pathname, ReturnObject);
1022193267Sjkim    }
1023193267Sjkim
1024193267Sjkim    return (Status);
1025193267Sjkim
1026193267Sjkim
1027193267SjkimTypeErrorExit:
1028193267Sjkim
1029193267Sjkim    /* Create a string with all expected types for this predefined object */
1030193267Sjkim
1031193267Sjkim    j = 1;
1032193267Sjkim    TypeBuffer[0] = 0;
1033193267Sjkim    ThisRtype = ACPI_RTYPE_INTEGER;
1034193267Sjkim
1035193267Sjkim    for (i = 0; i < ACPI_NUM_RTYPES; i++)
1036193267Sjkim    {
1037193267Sjkim        /* If one of the expected types, concatenate the name of this type */
1038193267Sjkim
1039193267Sjkim        if (ExpectedBtypes & ThisRtype)
1040193267Sjkim        {
1041193267Sjkim            ACPI_STRCAT (TypeBuffer, &AcpiRtypeNames[i][j]);
1042193267Sjkim            j = 0;              /* Use name separator from now on */
1043193267Sjkim        }
1044193267Sjkim        ThisRtype <<= 1;    /* Next Rtype */
1045193267Sjkim    }
1046193267Sjkim
1047193267Sjkim    if (PackageIndex == ACPI_NOT_PACKAGE)
1048193267Sjkim    {
1049193267Sjkim        ACPI_WARNING ((AE_INFO,
1050193267Sjkim            "%s: Return type mismatch - found %s, expected %s",
1051193267Sjkim            Pathname, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1052193267Sjkim    }
1053193267Sjkim    else
1054193267Sjkim    {
1055193267Sjkim        ACPI_WARNING ((AE_INFO,
1056193267Sjkim            "%s: Return Package type mismatch at index %u - "
1057193267Sjkim            "found %s, expected %s", Pathname, PackageIndex,
1058193267Sjkim            AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1059193267Sjkim    }
1060193267Sjkim
1061193267Sjkim    return (AE_AML_OPERAND_TYPE);
1062193267Sjkim}
1063193267Sjkim
1064193267Sjkim
1065193267Sjkim/*******************************************************************************
1066193267Sjkim *
1067193267Sjkim * FUNCTION:    AcpiNsCheckReference
1068193267Sjkim *
1069193267Sjkim * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
1070193267Sjkim *              ReturnObject    - Object returned from the evaluation of a
1071193267Sjkim *                                method or object
1072193267Sjkim *
1073193267Sjkim * RETURN:      Status
1074193267Sjkim *
1075193267Sjkim * DESCRIPTION: Check a returned reference object for the correct reference
1076193267Sjkim *              type. The only reference type that can be returned from a
1077193267Sjkim *              predefined method is a named reference. All others are invalid.
1078193267Sjkim *
1079193267Sjkim ******************************************************************************/
1080193267Sjkim
1081193267Sjkimstatic ACPI_STATUS
1082193267SjkimAcpiNsCheckReference (
1083193267Sjkim    char                        *Pathname,
1084193267Sjkim    ACPI_OPERAND_OBJECT         *ReturnObject)
1085193267Sjkim{
1086193267Sjkim
1087193267Sjkim    /*
1088193267Sjkim     * Check the reference object for the correct reference type (opcode).
1089193267Sjkim     * The only type of reference that can be converted to an ACPI_OBJECT is
1090193267Sjkim     * a reference to a named object (reference class: NAME)
1091193267Sjkim     */
1092193267Sjkim    if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1093193267Sjkim    {
1094193267Sjkim        return (AE_OK);
1095193267Sjkim    }
1096193267Sjkim
1097193267Sjkim    ACPI_WARNING ((AE_INFO,
1098193267Sjkim        "%s: Return type mismatch - "
1099193267Sjkim        "unexpected reference object type [%s] %2.2X",
1100193267Sjkim        Pathname, AcpiUtGetReferenceName (ReturnObject),
1101193267Sjkim        ReturnObject->Reference.Class));
1102193267Sjkim
1103193267Sjkim    return (AE_AML_OPERAND_TYPE);
1104193267Sjkim}
1105193267Sjkim
1106193267Sjkim
1107193267Sjkim/*******************************************************************************
1108193267Sjkim *
1109193267Sjkim * FUNCTION:    AcpiNsRepairObject
1110193267Sjkim *
1111193267Sjkim * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
1112193267Sjkim *              PackageIndex    - Used to determine if target is in a package
1113193267Sjkim *              ReturnObjectPtr - Pointer to the object returned from the
1114193267Sjkim *                                evaluation of a method or object
1115193267Sjkim *
1116193267Sjkim * RETURN:      Status. AE_OK if repair was successful.
1117193267Sjkim *
1118193267Sjkim * DESCRIPTION: Attempt to repair/convert a return object of a type that was
1119193267Sjkim *              not expected.
1120193267Sjkim *
1121193267Sjkim ******************************************************************************/
1122193267Sjkim
1123193267Sjkimstatic ACPI_STATUS
1124193267SjkimAcpiNsRepairObject (
1125193267Sjkim    UINT32                      ExpectedBtypes,
1126193267Sjkim    UINT32                      PackageIndex,
1127193267Sjkim    ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
1128193267Sjkim{
1129193267Sjkim    ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1130193267Sjkim    ACPI_OPERAND_OBJECT         *NewObject;
1131193267Sjkim    ACPI_SIZE                   Length;
1132193267Sjkim
1133193267Sjkim
1134193267Sjkim    switch (ReturnObject->Common.Type)
1135193267Sjkim    {
1136193267Sjkim    case ACPI_TYPE_BUFFER:
1137193267Sjkim
1138193267Sjkim        if (!(ExpectedBtypes & ACPI_RTYPE_STRING))
1139193267Sjkim        {
1140193267Sjkim            return (AE_AML_OPERAND_TYPE);
1141193267Sjkim        }
1142193267Sjkim
1143193267Sjkim        /*
1144193267Sjkim         * Have a Buffer, expected a String, convert. Use a ToString
1145193267Sjkim         * conversion, no transform performed on the buffer data. The best
1146193267Sjkim         * example of this is the _BIF method, where the string data from
1147193267Sjkim         * the battery is often (incorrectly) returned as buffer object(s).
1148193267Sjkim         */
1149193267Sjkim        Length = 0;
1150193267Sjkim        while ((Length < ReturnObject->Buffer.Length) &&
1151193267Sjkim                (ReturnObject->Buffer.Pointer[Length]))
1152193267Sjkim        {
1153193267Sjkim            Length++;
1154193267Sjkim        }
1155193267Sjkim
1156193267Sjkim        /* Allocate a new string object */
1157193267Sjkim
1158193267Sjkim        NewObject = AcpiUtCreateStringObject (Length);
1159193267Sjkim        if (!NewObject)
1160193267Sjkim        {
1161193267Sjkim            return (AE_NO_MEMORY);
1162193267Sjkim        }
1163193267Sjkim
1164193267Sjkim        /*
1165193267Sjkim         * Copy the raw buffer data with no transform. String is already NULL
1166193267Sjkim         * terminated at Length+1.
1167193267Sjkim         */
1168193267Sjkim        ACPI_MEMCPY (NewObject->String.Pointer,
1169193267Sjkim            ReturnObject->Buffer.Pointer, Length);
1170193267Sjkim
1171193267Sjkim        /* Install the new return object */
1172193267Sjkim
1173193267Sjkim        AcpiUtRemoveReference (ReturnObject);
1174193267Sjkim        *ReturnObjectPtr = NewObject;
1175193267Sjkim
1176193267Sjkim        /*
1177193267Sjkim         * If the object is a package element, we need to:
1178193267Sjkim         * 1. Decrement the reference count of the orignal object, it was
1179193267Sjkim         *    incremented when building the package
1180193267Sjkim         * 2. Increment the reference count of the new object, it will be
1181193267Sjkim         *    decremented when releasing the package
1182193267Sjkim         */
1183193267Sjkim        if (PackageIndex != ACPI_NOT_PACKAGE)
1184193267Sjkim        {
1185193267Sjkim            AcpiUtRemoveReference (ReturnObject);
1186193267Sjkim            AcpiUtAddReference (NewObject);
1187193267Sjkim        }
1188193267Sjkim        return (AE_OK);
1189193267Sjkim
1190193267Sjkim    default:
1191193267Sjkim        break;
1192193267Sjkim    }
1193193267Sjkim
1194193267Sjkim    return (AE_AML_OPERAND_TYPE);
1195193267Sjkim}
1196193267Sjkim
1197