1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4100966Siwasaki *                         ACPI Object evaluation interfaces
5100966Siwasaki *
6100966Siwasaki ******************************************************************************/
7100966Siwasaki
8316303Sjkim/******************************************************************************
9316303Sjkim *
10316303Sjkim * 1. Copyright Notice
11316303Sjkim *
12316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
13100966Siwasaki * All rights reserved.
14100966Siwasaki *
15316303Sjkim * 2. License
16316303Sjkim *
17316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
18316303Sjkim * rights. You may have additional license terms from the party that provided
19316303Sjkim * you this software, covering your right to use that party's intellectual
20316303Sjkim * property rights.
21316303Sjkim *
22316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23316303Sjkim * copy of the source code appearing in this file ("Covered Code") an
24316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
26316303Sjkim * make derivatives, distribute, use and display any portion of the Covered
27316303Sjkim * Code in any form, with the right to sublicense such rights; and
28316303Sjkim *
29316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30316303Sjkim * license (with the right to sublicense), under only those claims of Intel
31316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
32316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof
33316303Sjkim * solely to the minimum extent necessary to exercise the above copyright
34316303Sjkim * license, and in no event shall the patent license extend to any additions
35316303Sjkim * to or modifications of the Original Intel Code. No other license or right
36316303Sjkim * is granted directly or by implication, estoppel or otherwise;
37316303Sjkim *
38316303Sjkim * The above copyright and patent license is granted only if the following
39316303Sjkim * conditions are met:
40316303Sjkim *
41316303Sjkim * 3. Conditions
42316303Sjkim *
43316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44316303Sjkim * Redistribution of source code of any substantial portion of the Covered
45316303Sjkim * Code or modification with rights to further distribute source must include
46316303Sjkim * the above Copyright Notice, the above License, this list of Conditions,
47316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition,
48316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
49316303Sjkim * contain a file documenting the changes Licensee made to create that Covered
50316303Sjkim * Code and the date of any change. Licensee must include in that file the
51316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee
52316303Sjkim * must include a prominent statement that the modification is derived,
53316303Sjkim * directly or indirectly, from Original Intel Code.
54316303Sjkim *
55316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56316303Sjkim * Redistribution of source code of any substantial portion of the Covered
57316303Sjkim * Code or modification without rights to further distribute source must
58316303Sjkim * include the following Disclaimer and Export Compliance provision in the
59316303Sjkim * documentation and/or other materials provided with distribution. In
60316303Sjkim * addition, Licensee may not authorize further sublicense of source of any
61316303Sjkim * portion of the Covered Code, and must include terms to the effect that the
62316303Sjkim * license from Licensee to its licensee is limited to the intellectual
63316303Sjkim * property embodied in the software Licensee provides to its licensee, and
64316303Sjkim * not to intellectual property embodied in modifications its licensee may
65316303Sjkim * make.
66316303Sjkim *
67316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
68316303Sjkim * substantial portion of the Covered Code or modification must reproduce the
69316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
70316303Sjkim * provision in the documentation and/or other materials provided with the
71316303Sjkim * distribution.
72316303Sjkim *
73316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
74316303Sjkim * Intel Code.
75316303Sjkim *
76316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
78316303Sjkim * other dealings in products derived from or relating to the Covered Code
79316303Sjkim * without prior written authorization from Intel.
80316303Sjkim *
81316303Sjkim * 4. Disclaimer and Export Compliance
82316303Sjkim *
83316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89316303Sjkim * PARTICULAR PURPOSE.
90316303Sjkim *
91316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98316303Sjkim * LIMITED REMEDY.
99316303Sjkim *
100316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
101316303Sjkim * software or system incorporating such software without first obtaining any
102316303Sjkim * required license or other approval from the U. S. Department of Commerce or
103316303Sjkim * any other agency or department of the United States Government. In the
104316303Sjkim * event Licensee exports any such software from the United States or
105316303Sjkim * re-exports any such software from a foreign destination, Licensee shall
106316303Sjkim * ensure that the distribution and export/re-export of the software is in
107316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
108316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109316303Sjkim * any of its subsidiaries will export/re-export any technical data, process,
110316303Sjkim * software, or service, directly or indirectly, to any country for which the
111316303Sjkim * United States government or any agency thereof requires an export license,
112316303Sjkim * other governmental approval, or letter of assurance, without first obtaining
113316303Sjkim * such license, approval or letter.
114316303Sjkim *
115316303Sjkim *****************************************************************************
116316303Sjkim *
117316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
118316303Sjkim * following license:
119316303Sjkim *
120217365Sjkim * Redistribution and use in source and binary forms, with or without
121217365Sjkim * modification, are permitted provided that the following conditions
122217365Sjkim * are met:
123217365Sjkim * 1. Redistributions of source code must retain the above copyright
124217365Sjkim *    notice, this list of conditions, and the following disclaimer,
125217365Sjkim *    without modification.
126217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
128217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
129217365Sjkim *    including a substantially similar Disclaimer requirement for further
130217365Sjkim *    binary redistribution.
131217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
132217365Sjkim *    of any contributors may be used to endorse or promote products derived
133217365Sjkim *    from this software without specific prior written permission.
134100966Siwasaki *
135316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146316303Sjkim *
147316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
148217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
149217365Sjkim * Software Foundation.
150100966Siwasaki *
151316303Sjkim *****************************************************************************/
152100966Siwasaki
153272444Sjkim#define EXPORT_ACPI_INTERFACES
154100966Siwasaki
155193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
156193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
157193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
158193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
159100966Siwasaki
160100966Siwasaki
161100966Siwasaki#define _COMPONENT          ACPI_NAMESPACE
162100966Siwasaki        ACPI_MODULE_NAME    ("nsxfeval")
163100966Siwasaki
164193267Sjkim/* Local prototypes */
165100966Siwasaki
166193267Sjkimstatic void
167193267SjkimAcpiNsResolveReferences (
168193267Sjkim    ACPI_EVALUATE_INFO      *Info);
169193267Sjkim
170193267Sjkim
171100966Siwasaki/*******************************************************************************
172100966Siwasaki *
173100966Siwasaki * FUNCTION:    AcpiEvaluateObjectTyped
174100966Siwasaki *
175100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
176151937Sjkim *              Pathname            - Object pathname (optional)
177327557Sjkim *              ExternalParams      - List of parameters to pass to a method,
178241973Sjkim *                                    terminated by NULL. May be NULL
179100966Siwasaki *                                    if no parameters are being passed.
180327557Sjkim *              ReturnBuffer        - Where to put the object return value (if
181327557Sjkim *                                    any). Required.
182100966Siwasaki *              ReturnType          - Expected type of return object
183100966Siwasaki *
184100966Siwasaki * RETURN:      Status
185100966Siwasaki *
186100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
187241973Sjkim *              parameters if necessary. One of "Handle" or "Pathname" must
188100966Siwasaki *              be valid (non-null)
189100966Siwasaki *
190100966Siwasaki ******************************************************************************/
191100966Siwasaki
192100966SiwasakiACPI_STATUS
193100966SiwasakiAcpiEvaluateObjectTyped (
194100966Siwasaki    ACPI_HANDLE             Handle,
195100966Siwasaki    ACPI_STRING             Pathname,
196100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
197100966Siwasaki    ACPI_BUFFER             *ReturnBuffer,
198100966Siwasaki    ACPI_OBJECT_TYPE        ReturnType)
199100966Siwasaki{
200100966Siwasaki    ACPI_STATUS             Status;
201272444Sjkim    BOOLEAN                 FreeBufferOnError = FALSE;
202322877Sjkim    ACPI_HANDLE             TargetHandle;
203322877Sjkim    char                    *FullPathname;
204100966Siwasaki
205100966Siwasaki
206167802Sjkim    ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
207100966Siwasaki
208100966Siwasaki
209100966Siwasaki    /* Return buffer must be valid */
210100966Siwasaki
211100966Siwasaki    if (!ReturnBuffer)
212100966Siwasaki    {
213100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
214100966Siwasaki    }
215100966Siwasaki
216100966Siwasaki    if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
217100966Siwasaki    {
218272444Sjkim        FreeBufferOnError = TRUE;
219100966Siwasaki    }
220100966Siwasaki
221327557Sjkim    /* Get a handle here, in order to build an error message if needed */
222327557Sjkim
223327557Sjkim    TargetHandle = Handle;
224327557Sjkim    if (Pathname)
225322877Sjkim    {
226327557Sjkim        Status = AcpiGetHandle (Handle, Pathname, &TargetHandle);
227327557Sjkim        if (ACPI_FAILURE (Status))
228327557Sjkim        {
229327557Sjkim            return_ACPI_STATUS (Status);
230327557Sjkim        }
231322877Sjkim    }
232322877Sjkim
233322877Sjkim    FullPathname = AcpiNsGetExternalPathname (TargetHandle);
234322877Sjkim    if (!FullPathname)
235322877Sjkim    {
236322877Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
237322877Sjkim    }
238322877Sjkim
239100966Siwasaki    /* Evaluate the object */
240100966Siwasaki
241322877Sjkim    Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams,
242322877Sjkim        ReturnBuffer);
243100966Siwasaki    if (ACPI_FAILURE (Status))
244100966Siwasaki    {
245322877Sjkim        goto Exit;
246100966Siwasaki    }
247100966Siwasaki
248322877Sjkim    /* Type ANY means "don't care about return value type" */
249100966Siwasaki
250100966Siwasaki    if (ReturnType == ACPI_TYPE_ANY)
251100966Siwasaki    {
252322877Sjkim        goto Exit;
253100966Siwasaki    }
254100966Siwasaki
255100966Siwasaki    if (ReturnBuffer->Length == 0)
256100966Siwasaki    {
257100966Siwasaki        /* Error because caller specifically asked for a return value */
258100966Siwasaki
259322877Sjkim        ACPI_ERROR ((AE_INFO, "%s did not return any object",
260322877Sjkim            FullPathname));
261322877Sjkim        Status = AE_NULL_OBJECT;
262322877Sjkim        goto Exit;
263100966Siwasaki    }
264100966Siwasaki
265100966Siwasaki    /* Examine the object type returned from EvaluateObject */
266100966Siwasaki
267100966Siwasaki    if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
268100966Siwasaki    {
269322877Sjkim        goto Exit;
270100966Siwasaki    }
271100966Siwasaki
272100966Siwasaki    /* Return object type does not match requested type */
273100966Siwasaki
274167802Sjkim    ACPI_ERROR ((AE_INFO,
275322877Sjkim        "Incorrect return type from %s - received [%s], requested [%s]",
276322877Sjkim        FullPathname,
277100966Siwasaki        AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
278100966Siwasaki        AcpiUtGetTypeName (ReturnType)));
279100966Siwasaki
280272444Sjkim    if (FreeBufferOnError)
281100966Siwasaki    {
282272444Sjkim        /*
283272444Sjkim         * Free a buffer created via ACPI_ALLOCATE_BUFFER.
284272444Sjkim         * Note: We use AcpiOsFree here because AcpiOsAllocate was used
285272444Sjkim         * to allocate the buffer. This purposefully bypasses the
286272444Sjkim         * (optionally enabled) allocation tracking mechanism since we
287272444Sjkim         * only want to track internal allocations.
288272444Sjkim         */
289100966Siwasaki        AcpiOsFree (ReturnBuffer->Pointer);
290100966Siwasaki        ReturnBuffer->Pointer = NULL;
291100966Siwasaki    }
292100966Siwasaki
293100966Siwasaki    ReturnBuffer->Length = 0;
294322877Sjkim    Status = AE_TYPE;
295322877Sjkim
296322877SjkimExit:
297322877Sjkim    ACPI_FREE (FullPathname);
298322877Sjkim    return_ACPI_STATUS (Status);
299100966Siwasaki}
300100966Siwasaki
301167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
302100966Siwasaki
303167802Sjkim
304100966Siwasaki/*******************************************************************************
305100966Siwasaki *
306100966Siwasaki * FUNCTION:    AcpiEvaluateObject
307100966Siwasaki *
308100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
309128212Snjl *              Pathname            - Object pathname (optional)
310128212Snjl *              ExternalParams      - List of parameters to pass to method,
311241973Sjkim *                                    terminated by NULL. May be NULL
312100966Siwasaki *                                    if no parameters are being passed.
313128212Snjl *              ReturnBuffer        - Where to put method's return value (if
314241973Sjkim *                                    any). If NULL, no value is returned.
315100966Siwasaki *
316100966Siwasaki * RETURN:      Status
317100966Siwasaki *
318100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
319241973Sjkim *              parameters if necessary. One of "Handle" or "Pathname" must
320100966Siwasaki *              be valid (non-null)
321100966Siwasaki *
322100966Siwasaki ******************************************************************************/
323100966Siwasaki
324100966SiwasakiACPI_STATUS
325100966SiwasakiAcpiEvaluateObject (
326100966Siwasaki    ACPI_HANDLE             Handle,
327100966Siwasaki    ACPI_STRING             Pathname,
328100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
329100966Siwasaki    ACPI_BUFFER             *ReturnBuffer)
330100966Siwasaki{
331100966Siwasaki    ACPI_STATUS             Status;
332167802Sjkim    ACPI_EVALUATE_INFO      *Info;
333100966Siwasaki    ACPI_SIZE               BufferSpaceNeeded;
334100966Siwasaki    UINT32                  i;
335100966Siwasaki
336100966Siwasaki
337167802Sjkim    ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
338100966Siwasaki
339100966Siwasaki
340167802Sjkim    /* Allocate and initialize the evaluation information block */
341129684Snjl
342167802Sjkim    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
343167802Sjkim    if (!Info)
344167802Sjkim    {
345167802Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
346167802Sjkim    }
347167802Sjkim
348167802Sjkim    /* Convert and validate the device handle */
349167802Sjkim
350200553Sjkim    Info->PrefixNode = AcpiNsValidateHandle (Handle);
351167802Sjkim    if (!Info->PrefixNode)
352167802Sjkim    {
353167802Sjkim        Status = AE_BAD_PARAMETER;
354167802Sjkim        goto Cleanup;
355167802Sjkim    }
356167802Sjkim
357100966Siwasaki    /*
358249663Sjkim     * Get the actual namespace node for the target object.
359249663Sjkim     * Handles these cases:
360249663Sjkim     *
361249663Sjkim     * 1) Null node, valid pathname from root (absolute path)
362249663Sjkim     * 2) Node and valid pathname (path relative to Node)
363249663Sjkim     * 3) Node, Null pathname
364100966Siwasaki     */
365249663Sjkim    if ((Pathname) &&
366249663Sjkim        (ACPI_IS_ROOT_PREFIX (Pathname[0])))
367249663Sjkim    {
368249663Sjkim        /* The path is fully qualified, just evaluate by name */
369249663Sjkim
370249663Sjkim        Info->PrefixNode = NULL;
371249663Sjkim    }
372249663Sjkim    else if (!Handle)
373249663Sjkim    {
374249663Sjkim        /*
375249663Sjkim         * A handle is optional iff a fully qualified pathname is specified.
376249663Sjkim         * Since we've already handled fully qualified names above, this is
377249663Sjkim         * an error.
378249663Sjkim         */
379249663Sjkim        if (!Pathname)
380249663Sjkim        {
381249663Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
382249663Sjkim                "Both Handle and Pathname are NULL"));
383249663Sjkim        }
384249663Sjkim        else
385249663Sjkim        {
386249663Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
387249663Sjkim                "Null Handle with relative pathname [%s]", Pathname));
388249663Sjkim        }
389249663Sjkim
390249663Sjkim        Status = AE_BAD_PARAMETER;
391249663Sjkim        goto Cleanup;
392249663Sjkim    }
393249663Sjkim
394249663Sjkim    Info->RelativePathname = Pathname;
395249663Sjkim
396249663Sjkim    /*
397249663Sjkim     * Convert all external objects passed as arguments to the
398249663Sjkim     * internal version(s).
399249663Sjkim     */
400100966Siwasaki    if (ExternalParams && ExternalParams->Count)
401100966Siwasaki    {
402249663Sjkim        Info->ParamCount = (UINT16) ExternalParams->Count;
403249663Sjkim
404249663Sjkim        /* Warn on impossible argument count */
405249663Sjkim
406249663Sjkim        if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
407249663Sjkim        {
408249663Sjkim            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
409249663Sjkim                "Excess arguments (%u) - using only %u",
410249663Sjkim                Info->ParamCount, ACPI_METHOD_NUM_ARGS));
411249663Sjkim
412249663Sjkim            Info->ParamCount = ACPI_METHOD_NUM_ARGS;
413249663Sjkim        }
414249663Sjkim
415100966Siwasaki        /*
416100966Siwasaki         * Allocate a new parameter block for the internal objects
417100966Siwasaki         * Add 1 to count to allow for null terminated internal list
418100966Siwasaki         */
419167802Sjkim        Info->Parameters = ACPI_ALLOCATE_ZEROED (
420249663Sjkim            ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
421167802Sjkim        if (!Info->Parameters)
422100966Siwasaki        {
423167802Sjkim            Status = AE_NO_MEMORY;
424167802Sjkim            goto Cleanup;
425100966Siwasaki        }
426100966Siwasaki
427167802Sjkim        /* Convert each external object in the list to an internal object */
428167802Sjkim
429249663Sjkim        for (i = 0; i < Info->ParamCount; i++)
430100966Siwasaki        {
431167802Sjkim            Status = AcpiUtCopyEobjectToIobject (
432249663Sjkim                &ExternalParams->Pointer[i], &Info->Parameters[i]);
433100966Siwasaki            if (ACPI_FAILURE (Status))
434100966Siwasaki            {
435167802Sjkim                goto Cleanup;
436100966Siwasaki            }
437100966Siwasaki        }
438249663Sjkim
439249663Sjkim        Info->Parameters[Info->ParamCount] = NULL;
440100966Siwasaki    }
441100966Siwasaki
442249663Sjkim
443298714Sjkim#ifdef _FUTURE_FEATURE
444249663Sjkim
445100966Siwasaki    /*
446249663Sjkim     * Begin incoming argument count analysis. Check for too few args
447249663Sjkim     * and too many args.
448100966Siwasaki     */
449249663Sjkim    switch (AcpiNsGetType (Info->Node))
450100966Siwasaki    {
451249663Sjkim    case ACPI_TYPE_METHOD:
452167802Sjkim
453249663Sjkim        /* Check incoming argument count against the method definition */
454249663Sjkim
455249663Sjkim        if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
456249663Sjkim        {
457249663Sjkim            ACPI_ERROR ((AE_INFO,
458249663Sjkim                "Insufficient arguments (%u) - %u are required",
459249663Sjkim                Info->ParamCount,
460249663Sjkim                Info->ObjDesc->Method.ParamCount));
461249663Sjkim
462249663Sjkim            Status = AE_MISSING_ARGUMENTS;
463249663Sjkim            goto Cleanup;
464249663Sjkim        }
465249663Sjkim
466249663Sjkim        else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
467249663Sjkim        {
468249663Sjkim            ACPI_WARNING ((AE_INFO,
469249663Sjkim                "Excess arguments (%u) - only %u are required",
470249663Sjkim                Info->ParamCount,
471249663Sjkim                Info->ObjDesc->Method.ParamCount));
472249663Sjkim
473249663Sjkim            /* Just pass the required number of arguments */
474249663Sjkim
475249663Sjkim            Info->ParamCount = Info->ObjDesc->Method.ParamCount;
476249663Sjkim        }
477249663Sjkim
478100966Siwasaki        /*
479249663Sjkim         * Any incoming external objects to be passed as arguments to the
480249663Sjkim         * method must be converted to internal objects
481100966Siwasaki         */
482249663Sjkim        if (Info->ParamCount)
483100966Siwasaki        {
484249663Sjkim            /*
485249663Sjkim             * Allocate a new parameter block for the internal objects
486249663Sjkim             * Add 1 to count to allow for null terminated internal list
487249663Sjkim             */
488249663Sjkim            Info->Parameters = ACPI_ALLOCATE_ZEROED (
489249663Sjkim                ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
490249663Sjkim            if (!Info->Parameters)
491249663Sjkim            {
492249663Sjkim                Status = AE_NO_MEMORY;
493249663Sjkim                goto Cleanup;
494249663Sjkim            }
495249663Sjkim
496249663Sjkim            /* Convert each external object in the list to an internal object */
497249663Sjkim
498249663Sjkim            for (i = 0; i < Info->ParamCount; i++)
499249663Sjkim            {
500249663Sjkim                Status = AcpiUtCopyEobjectToIobject (
501249663Sjkim                    &ExternalParams->Pointer[i], &Info->Parameters[i]);
502249663Sjkim                if (ACPI_FAILURE (Status))
503249663Sjkim                {
504249663Sjkim                    goto Cleanup;
505249663Sjkim                }
506249663Sjkim            }
507249663Sjkim
508249663Sjkim            Info->Parameters[Info->ParamCount] = NULL;
509100966Siwasaki        }
510249663Sjkim        break;
511249663Sjkim
512249663Sjkim    default:
513249663Sjkim
514249663Sjkim        /* Warn if arguments passed to an object that is not a method */
515249663Sjkim
516249663Sjkim        if (Info->ParamCount)
517100966Siwasaki        {
518249663Sjkim            ACPI_WARNING ((AE_INFO,
519249663Sjkim                "%u arguments were passed to a non-method ACPI object",
520249663Sjkim                Info->ParamCount));
521100966Siwasaki        }
522249663Sjkim        break;
523100966Siwasaki    }
524167802Sjkim
525249663Sjkim#endif
526100966Siwasaki
527249663Sjkim
528249663Sjkim    /* Now we can evaluate the object */
529249663Sjkim
530249663Sjkim    Status = AcpiNsEvaluate (Info);
531249663Sjkim
532100966Siwasaki    /*
533100966Siwasaki     * If we are expecting a return value, and all went well above,
534100966Siwasaki     * copy the return value to an external object.
535100966Siwasaki     */
536298714Sjkim    if (!ReturnBuffer)
537100966Siwasaki    {
538298714Sjkim        goto CleanupReturnObject;
539298714Sjkim    }
540100966Siwasaki
541298714Sjkim    if (!Info->ReturnObject)
542298714Sjkim    {
543298714Sjkim        ReturnBuffer->Length = 0;
544298714Sjkim        goto Cleanup;
545298714Sjkim    }
546193267Sjkim
547298714Sjkim    if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
548298714Sjkim        ACPI_DESC_TYPE_NAMED)
549298714Sjkim    {
550298714Sjkim        /*
551298714Sjkim         * If we received a NS Node as a return object, this means that
552298714Sjkim         * the object we are evaluating has nothing interesting to
553298714Sjkim         * return (such as a mutex, etc.)  We return an error because
554298714Sjkim         * these types are essentially unsupported by this interface.
555298714Sjkim         * We don't check up front because this makes it easier to add
556298714Sjkim         * support for various types at a later date if necessary.
557298714Sjkim         */
558298714Sjkim        Status = AE_TYPE;
559298714Sjkim        Info->ReturnObject = NULL;   /* No need to delete a NS Node */
560298714Sjkim        ReturnBuffer->Length = 0;
561298714Sjkim    }
562193267Sjkim
563298714Sjkim    if (ACPI_FAILURE (Status))
564298714Sjkim    {
565298714Sjkim        goto CleanupReturnObject;
566298714Sjkim    }
567167802Sjkim
568298714Sjkim    /* Dereference Index and RefOf references */
569100966Siwasaki
570298714Sjkim    AcpiNsResolveReferences (Info);
571167802Sjkim
572298714Sjkim    /* Get the size of the returned object */
573298714Sjkim
574298714Sjkim    Status = AcpiUtGetObjectSize (Info->ReturnObject,
575298714Sjkim        &BufferSpaceNeeded);
576298714Sjkim    if (ACPI_SUCCESS (Status))
577298714Sjkim    {
578298714Sjkim        /* Validate/Allocate/Clear caller buffer */
579298714Sjkim
580298714Sjkim        Status = AcpiUtInitializeBuffer (ReturnBuffer,
581298714Sjkim            BufferSpaceNeeded);
582298714Sjkim        if (ACPI_FAILURE (Status))
583298714Sjkim        {
584298714Sjkim            /*
585298714Sjkim             * Caller's buffer is too small or a new one can't
586298714Sjkim             * be allocated
587298714Sjkim             */
588298714Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
589298714Sjkim                "Needed buffer size %X, %s\n",
590298714Sjkim                (UINT32) BufferSpaceNeeded,
591298714Sjkim                AcpiFormatException (Status)));
592100966Siwasaki        }
593298714Sjkim        else
594298714Sjkim        {
595298714Sjkim            /* We have enough space for the object, build it */
596298714Sjkim
597298714Sjkim            Status = AcpiUtCopyIobjectToEobject (
598298714Sjkim                Info->ReturnObject, ReturnBuffer);
599298714Sjkim        }
600100966Siwasaki    }
601100966Siwasaki
602298714SjkimCleanupReturnObject:
603298714Sjkim
604167802Sjkim    if (Info->ReturnObject)
605100966Siwasaki    {
606129684Snjl        /*
607167802Sjkim         * Delete the internal return object. NOTE: Interpreter must be
608167802Sjkim         * locked to avoid race condition.
609100966Siwasaki         */
610167802Sjkim        AcpiExEnterInterpreter ();
611167802Sjkim
612167802Sjkim        /* Remove one reference on the return object (should delete it) */
613167802Sjkim
614167802Sjkim        AcpiUtRemoveReference (Info->ReturnObject);
615167802Sjkim        AcpiExExitInterpreter ();
616100966Siwasaki    }
617100966Siwasaki
618167802Sjkim
619167802SjkimCleanup:
620167802Sjkim
621167802Sjkim    /* Free the input parameter list (if we created one) */
622167802Sjkim
623167802Sjkim    if (Info->Parameters)
624100966Siwasaki    {
625100966Siwasaki        /* Free the allocated parameter block */
626100966Siwasaki
627167802Sjkim        AcpiUtDeleteInternalObjectList (Info->Parameters);
628100966Siwasaki    }
629100966Siwasaki
630167802Sjkim    ACPI_FREE (Info);
631100966Siwasaki    return_ACPI_STATUS (Status);
632100966Siwasaki}
633100966Siwasaki
634167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
635100966Siwasaki
636167802Sjkim
637100966Siwasaki/*******************************************************************************
638100966Siwasaki *
639193267Sjkim * FUNCTION:    AcpiNsResolveReferences
640193267Sjkim *
641193267Sjkim * PARAMETERS:  Info                    - Evaluation info block
642193267Sjkim *
643193267Sjkim * RETURN:      Info->ReturnObject is replaced with the dereferenced object
644193267Sjkim *
645193267Sjkim * DESCRIPTION: Dereference certain reference objects. Called before an
646193267Sjkim *              internal return object is converted to an external ACPI_OBJECT.
647193267Sjkim *
648193267Sjkim * Performs an automatic dereference of Index and RefOf reference objects.
649193267Sjkim * These reference objects are not supported by the ACPI_OBJECT, so this is a
650193267Sjkim * last resort effort to return something useful. Also, provides compatibility
651193267Sjkim * with other ACPI implementations.
652193267Sjkim *
653193267Sjkim * NOTE: does not handle references within returned package objects or nested
654193267Sjkim * references, but this support could be added later if found to be necessary.
655193267Sjkim *
656193267Sjkim ******************************************************************************/
657193267Sjkim
658193267Sjkimstatic void
659193267SjkimAcpiNsResolveReferences (
660193267Sjkim    ACPI_EVALUATE_INFO      *Info)
661193267Sjkim{
662193267Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
663193267Sjkim    ACPI_NAMESPACE_NODE     *Node;
664193267Sjkim
665193267Sjkim
666193267Sjkim    /* We are interested in reference objects only */
667193267Sjkim
668193267Sjkim    if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
669193267Sjkim    {
670193267Sjkim        return;
671193267Sjkim    }
672193267Sjkim
673193267Sjkim    /*
674193267Sjkim     * Two types of references are supported - those created by Index and
675193267Sjkim     * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
676193267Sjkim     * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
677193267Sjkim     * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
678193267Sjkim     * an ACPI_OBJECT.
679193267Sjkim     */
680193267Sjkim    switch (Info->ReturnObject->Reference.Class)
681193267Sjkim    {
682193267Sjkim    case ACPI_REFCLASS_INDEX:
683193267Sjkim
684193267Sjkim        ObjDesc = *(Info->ReturnObject->Reference.Where);
685193267Sjkim        break;
686193267Sjkim
687193267Sjkim    case ACPI_REFCLASS_REFOF:
688193267Sjkim
689193267Sjkim        Node = Info->ReturnObject->Reference.Object;
690193267Sjkim        if (Node)
691193267Sjkim        {
692193267Sjkim            ObjDesc = Node->Object;
693193267Sjkim        }
694193267Sjkim        break;
695193267Sjkim
696193267Sjkim    default:
697250838Sjkim
698193267Sjkim        return;
699193267Sjkim    }
700193267Sjkim
701193267Sjkim    /* Replace the existing reference object */
702193267Sjkim
703193267Sjkim    if (ObjDesc)
704193267Sjkim    {
705193267Sjkim        AcpiUtAddReference (ObjDesc);
706193267Sjkim        AcpiUtRemoveReference (Info->ReturnObject);
707193267Sjkim        Info->ReturnObject = ObjDesc;
708193267Sjkim    }
709193267Sjkim
710193267Sjkim    return;
711193267Sjkim}
712193267Sjkim
713193267Sjkim
714193267Sjkim/*******************************************************************************
715193267Sjkim *
716100966Siwasaki * FUNCTION:    AcpiWalkNamespace
717100966Siwasaki *
718100966Siwasaki * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
719100966Siwasaki *              StartObject         - Handle in namespace where search begins
720100966Siwasaki *              MaxDepth            - Depth to which search is to reach
721253690Sjkim *              DescendingCallback  - Called during tree descent
722199337Sjkim *                                    when an object of "Type" is found
723253690Sjkim *              AscendingCallback   - Called during tree ascent
724199337Sjkim *                                    when an object of "Type" is found
725199337Sjkim *              Context             - Passed to user function(s) above
726100966Siwasaki *              ReturnValue         - Location where return value of
727100966Siwasaki *                                    UserFunction is put if terminated early
728100966Siwasaki *
729100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
730100966Siwasaki *              Otherwise, returns NULL.
731100966Siwasaki *
732100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
733100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
734199337Sjkim *              The callback function is called whenever an object that matches
735199337Sjkim *              the type parameter is found. If the callback function returns
736100966Siwasaki *              a non-zero value, the search is terminated immediately and this
737100966Siwasaki *              value is returned to the caller.
738100966Siwasaki *
739100966Siwasaki *              The point of this procedure is to provide a generic namespace
740100966Siwasaki *              walk routine that can be called from multiple places to
741199337Sjkim *              provide multiple services; the callback function(s) can be
742199337Sjkim *              tailored to each task, whether it is a print function,
743199337Sjkim *              a compare function, etc.
744100966Siwasaki *
745100966Siwasaki ******************************************************************************/
746100966Siwasaki
747100966SiwasakiACPI_STATUS
748100966SiwasakiAcpiWalkNamespace (
749100966Siwasaki    ACPI_OBJECT_TYPE        Type,
750100966Siwasaki    ACPI_HANDLE             StartObject,
751100966Siwasaki    UINT32                  MaxDepth,
752253690Sjkim    ACPI_WALK_CALLBACK      DescendingCallback,
753253690Sjkim    ACPI_WALK_CALLBACK      AscendingCallback,
754100966Siwasaki    void                    *Context,
755100966Siwasaki    void                    **ReturnValue)
756100966Siwasaki{
757100966Siwasaki    ACPI_STATUS             Status;
758100966Siwasaki
759100966Siwasaki
760167802Sjkim    ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
761100966Siwasaki
762100966Siwasaki
763100966Siwasaki    /* Parameter validation */
764100966Siwasaki
765167802Sjkim    if ((Type > ACPI_TYPE_LOCAL_MAX) ||
766167802Sjkim        (!MaxDepth)                  ||
767253690Sjkim        (!DescendingCallback && !AscendingCallback))
768100966Siwasaki    {
769100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
770100966Siwasaki    }
771100966Siwasaki
772100966Siwasaki    /*
773193267Sjkim     * Need to acquire the namespace reader lock to prevent interference
774193267Sjkim     * with any concurrent table unloads (which causes the deletion of
775193267Sjkim     * namespace objects). We cannot allow the deletion of a namespace node
776193267Sjkim     * while the user function is using it. The exception to this are the
777193267Sjkim     * nodes created and deleted during control method execution -- these
778193267Sjkim     * nodes are marked as temporary nodes and are ignored by the namespace
779193267Sjkim     * walk. Thus, control methods can be executed while holding the
780193267Sjkim     * namespace deletion lock (and the user function can execute control
781193267Sjkim     * methods.)
782100966Siwasaki     */
783193267Sjkim    Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
784193267Sjkim    if (ACPI_FAILURE (Status))
785193267Sjkim    {
786241973Sjkim        return_ACPI_STATUS (Status);
787193267Sjkim    }
788193267Sjkim
789193267Sjkim    /*
790193267Sjkim     * Lock the namespace around the walk. The namespace will be
791193267Sjkim     * unlocked/locked around each call to the user function - since the user
792193267Sjkim     * function must be allowed to make ACPICA calls itself (for example, it
793193267Sjkim     * will typically execute control methods during device enumeration.)
794193267Sjkim     */
795100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
796100966Siwasaki    if (ACPI_FAILURE (Status))
797100966Siwasaki    {
798193267Sjkim        goto UnlockAndExit;
799100966Siwasaki    }
800100966Siwasaki
801254745Sjkim    /* Now we can validate the starting node */
802254745Sjkim
803254745Sjkim    if (!AcpiNsValidateHandle (StartObject))
804254745Sjkim    {
805254745Sjkim        Status = AE_BAD_PARAMETER;
806254745Sjkim        goto UnlockAndExit2;
807254745Sjkim    }
808254745Sjkim
809151937Sjkim    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
810298714Sjkim        ACPI_NS_WALK_UNLOCK, DescendingCallback,
811298714Sjkim        AscendingCallback, Context, ReturnValue);
812100966Siwasaki
813254745SjkimUnlockAndExit2:
814100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
815193267Sjkim
816193267SjkimUnlockAndExit:
817193267Sjkim    (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
818100966Siwasaki    return_ACPI_STATUS (Status);
819100966Siwasaki}
820100966Siwasaki
821167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
822100966Siwasaki
823167802Sjkim
824100966Siwasaki/*******************************************************************************
825100966Siwasaki *
826100966Siwasaki * FUNCTION:    AcpiNsGetDeviceCallback
827100966Siwasaki *
828100966Siwasaki * PARAMETERS:  Callback from AcpiGetDevice
829100966Siwasaki *
830100966Siwasaki * RETURN:      Status
831100966Siwasaki *
832100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
833100966Siwasaki *              present devices, or if they specified a HID, it filters based
834100966Siwasaki *              on that.
835100966Siwasaki *
836100966Siwasaki ******************************************************************************/
837100966Siwasaki
838100966Siwasakistatic ACPI_STATUS
839100966SiwasakiAcpiNsGetDeviceCallback (
840100966Siwasaki    ACPI_HANDLE             ObjHandle,
841100966Siwasaki    UINT32                  NestingLevel,
842100966Siwasaki    void                    *Context,
843100966Siwasaki    void                    **ReturnValue)
844100966Siwasaki{
845117521Snjl    ACPI_GET_DEVICES_INFO   *Info = Context;
846100966Siwasaki    ACPI_STATUS             Status;
847100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
848100966Siwasaki    UINT32                  Flags;
849241973Sjkim    ACPI_PNP_DEVICE_ID      *Hid;
850241973Sjkim    ACPI_PNP_DEVICE_ID_LIST *Cid;
851193267Sjkim    UINT32                  i;
852193267Sjkim    BOOLEAN                 Found;
853197104Sjkim    int                     NoMatch;
854100966Siwasaki
855100966Siwasaki
856100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
857100966Siwasaki    if (ACPI_FAILURE (Status))
858100966Siwasaki    {
859100966Siwasaki        return (Status);
860100966Siwasaki    }
861100966Siwasaki
862200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
863100966Siwasaki    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
864100966Siwasaki    if (ACPI_FAILURE (Status))
865100966Siwasaki    {
866100966Siwasaki        return (Status);
867100966Siwasaki    }
868100966Siwasaki
869100966Siwasaki    if (!Node)
870100966Siwasaki    {
871100966Siwasaki        return (AE_BAD_PARAMETER);
872100966Siwasaki    }
873100966Siwasaki
874202771Sjkim    /*
875202771Sjkim     * First, filter based on the device HID and CID.
876202771Sjkim     *
877202771Sjkim     * 01/2010: For this case where a specific HID is requested, we don't
878202771Sjkim     * want to run _STA until we have an actual HID match. Thus, we will
879202771Sjkim     * not unnecessarily execute _STA on devices for which the caller
880202771Sjkim     * doesn't care about. Previously, _STA was executed unconditionally
881202771Sjkim     * on all devices found here.
882202771Sjkim     *
883202771Sjkim     * A side-effect of this change is that now we will continue to search
884202771Sjkim     * for a matching HID even under device trees where the parent device
885202771Sjkim     * would have returned a _STA that indicates it is not present or
886202771Sjkim     * not functioning (thus aborting the search on that branch).
887202771Sjkim     */
888100966Siwasaki    if (Info->Hid != NULL)
889100966Siwasaki    {
890100966Siwasaki        Status = AcpiUtExecute_HID (Node, &Hid);
891100966Siwasaki        if (Status == AE_NOT_FOUND)
892100966Siwasaki        {
893100966Siwasaki            return (AE_OK);
894100966Siwasaki        }
895100966Siwasaki        else if (ACPI_FAILURE (Status))
896100966Siwasaki        {
897100966Siwasaki            return (AE_CTRL_DEPTH);
898100966Siwasaki        }
899100966Siwasaki
900284583Sjkim        NoMatch = strcmp (Hid->String, Info->Hid);
901197104Sjkim        ACPI_FREE (Hid);
902197104Sjkim
903197104Sjkim        if (NoMatch)
904100966Siwasaki        {
905193267Sjkim            /*
906193267Sjkim             * HID does not match, attempt match within the
907193267Sjkim             * list of Compatible IDs (CIDs)
908193267Sjkim             */
909100966Siwasaki            Status = AcpiUtExecute_CID (Node, &Cid);
910100966Siwasaki            if (Status == AE_NOT_FOUND)
911100966Siwasaki            {
912100966Siwasaki                return (AE_OK);
913100966Siwasaki            }
914100966Siwasaki            else if (ACPI_FAILURE (Status))
915100966Siwasaki            {
916100966Siwasaki                return (AE_CTRL_DEPTH);
917100966Siwasaki            }
918100966Siwasaki
919117521Snjl            /* Walk the CID list */
920100966Siwasaki
921193267Sjkim            Found = FALSE;
922117521Snjl            for (i = 0; i < Cid->Count; i++)
923100966Siwasaki            {
924284583Sjkim                if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
925117521Snjl                {
926193267Sjkim                    /* Found a matching CID */
927193267Sjkim
928193267Sjkim                    Found = TRUE;
929193267Sjkim                    break;
930117521Snjl                }
931100966Siwasaki            }
932193267Sjkim
933167802Sjkim            ACPI_FREE (Cid);
934193267Sjkim            if (!Found)
935193267Sjkim            {
936193267Sjkim                return (AE_OK);
937193267Sjkim            }
938100966Siwasaki        }
939100966Siwasaki    }
940100966Siwasaki
941202771Sjkim    /* Run _STA to determine if device is present */
942202771Sjkim
943202771Sjkim    Status = AcpiUtExecute_STA (Node, &Flags);
944202771Sjkim    if (ACPI_FAILURE (Status))
945202771Sjkim    {
946202771Sjkim        return (AE_CTRL_DEPTH);
947202771Sjkim    }
948202771Sjkim
949202771Sjkim    if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
950202771Sjkim        !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
951202771Sjkim    {
952202771Sjkim        /*
953202771Sjkim         * Don't examine the children of the device only when the
954202771Sjkim         * device is neither present nor functional. See ACPI spec,
955202771Sjkim         * description of _STA for more information.
956202771Sjkim         */
957202771Sjkim        return (AE_CTRL_DEPTH);
958202771Sjkim    }
959202771Sjkim
960193267Sjkim    /* We have a valid device, invoke the user function */
961193267Sjkim
962298714Sjkim    Status = Info->UserFunction (ObjHandle, NestingLevel,
963298714Sjkim        Info->Context, ReturnValue);
964100966Siwasaki    return (Status);
965100966Siwasaki}
966100966Siwasaki
967100966Siwasaki
968100966Siwasaki/*******************************************************************************
969100966Siwasaki *
970100966Siwasaki * FUNCTION:    AcpiGetDevices
971100966Siwasaki *
972100966Siwasaki * PARAMETERS:  HID                 - HID to search for. Can be NULL.
973100966Siwasaki *              UserFunction        - Called when a matching object is found
974100966Siwasaki *              Context             - Passed to user function
975100966Siwasaki *              ReturnValue         - Location where return value of
976100966Siwasaki *                                    UserFunction is put if terminated early
977100966Siwasaki *
978100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
979100966Siwasaki *              Otherwise, returns NULL.
980100966Siwasaki *
981100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
982100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
983117521Snjl *              The UserFunction is called whenever an object of type
984241973Sjkim *              Device is found. If the user function returns
985100966Siwasaki *              a non-zero value, the search is terminated immediately and this
986100966Siwasaki *              value is returned to the caller.
987100966Siwasaki *
988100966Siwasaki *              This is a wrapper for WalkNamespace, but the callback performs
989193267Sjkim *              additional filtering. Please see AcpiNsGetDeviceCallback.
990100966Siwasaki *
991100966Siwasaki ******************************************************************************/
992100966Siwasaki
993100966SiwasakiACPI_STATUS
994100966SiwasakiAcpiGetDevices (
995114237Snjl    char                    *HID,
996100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
997100966Siwasaki    void                    *Context,
998100966Siwasaki    void                    **ReturnValue)
999100966Siwasaki{
1000100966Siwasaki    ACPI_STATUS             Status;
1001100966Siwasaki    ACPI_GET_DEVICES_INFO   Info;
1002100966Siwasaki
1003100966Siwasaki
1004167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetDevices);
1005100966Siwasaki
1006100966Siwasaki
1007100966Siwasaki    /* Parameter validation */
1008100966Siwasaki
1009100966Siwasaki    if (!UserFunction)
1010100966Siwasaki    {
1011100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
1012100966Siwasaki    }
1013100966Siwasaki
1014100966Siwasaki    /*
1015100966Siwasaki     * We're going to call their callback from OUR callback, so we need
1016100966Siwasaki     * to know what it is, and their context parameter.
1017100966Siwasaki     */
1018298714Sjkim    Info.Hid = HID;
1019298714Sjkim    Info.Context = Context;
1020100966Siwasaki    Info.UserFunction = UserFunction;
1021100966Siwasaki
1022100966Siwasaki    /*
1023100966Siwasaki     * Lock the namespace around the walk.
1024100966Siwasaki     * The namespace will be unlocked/locked around each call
1025100966Siwasaki     * to the user function - since this function
1026100966Siwasaki     * must be allowed to make Acpi calls itself.
1027100966Siwasaki     */
1028100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1029100966Siwasaki    if (ACPI_FAILURE (Status))
1030100966Siwasaki    {
1031100966Siwasaki        return_ACPI_STATUS (Status);
1032100966Siwasaki    }
1033100966Siwasaki
1034167802Sjkim    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1035298714Sjkim        ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1036298714Sjkim        AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
1037100966Siwasaki
1038100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1039100966Siwasaki    return_ACPI_STATUS (Status);
1040100966Siwasaki}
1041100966Siwasaki
1042167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices)
1043100966Siwasaki
1044167802Sjkim
1045100966Siwasaki/*******************************************************************************
1046100966Siwasaki *
1047100966Siwasaki * FUNCTION:    AcpiAttachData
1048100966Siwasaki *
1049114237Snjl * PARAMETERS:  ObjHandle           - Namespace node
1050107325Siwasaki *              Handler             - Handler for this attachment
1051107325Siwasaki *              Data                - Pointer to data to be attached
1052100966Siwasaki *
1053100966Siwasaki * RETURN:      Status
1054100966Siwasaki *
1055107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
1056100966Siwasaki *
1057100966Siwasaki ******************************************************************************/
1058100966Siwasaki
1059100966SiwasakiACPI_STATUS
1060100966SiwasakiAcpiAttachData (
1061100966Siwasaki    ACPI_HANDLE             ObjHandle,
1062100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
1063100966Siwasaki    void                    *Data)
1064100966Siwasaki{
1065100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
1066100966Siwasaki    ACPI_STATUS             Status;
1067100966Siwasaki
1068100966Siwasaki
1069100966Siwasaki    /* Parameter validation */
1070100966Siwasaki
1071100966Siwasaki    if (!ObjHandle  ||
1072100966Siwasaki        !Handler    ||
1073100966Siwasaki        !Data)
1074100966Siwasaki    {
1075100966Siwasaki        return (AE_BAD_PARAMETER);
1076100966Siwasaki    }
1077100966Siwasaki
1078100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1079100966Siwasaki    if (ACPI_FAILURE (Status))
1080100966Siwasaki    {
1081100966Siwasaki        return (Status);
1082100966Siwasaki    }
1083100966Siwasaki
1084100966Siwasaki    /* Convert and validate the handle */
1085100966Siwasaki
1086200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
1087100966Siwasaki    if (!Node)
1088100966Siwasaki    {
1089100966Siwasaki        Status = AE_BAD_PARAMETER;
1090100966Siwasaki        goto UnlockAndExit;
1091100966Siwasaki    }
1092100966Siwasaki
1093100966Siwasaki    Status = AcpiNsAttachData (Node, Handler, Data);
1094100966Siwasaki
1095100966SiwasakiUnlockAndExit:
1096100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1097100966Siwasaki    return (Status);
1098100966Siwasaki}
1099100966Siwasaki
1100167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData)
1101100966Siwasaki
1102167802Sjkim
1103100966Siwasaki/*******************************************************************************
1104100966Siwasaki *
1105100966Siwasaki * FUNCTION:    AcpiDetachData
1106100966Siwasaki *
1107107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node handle
1108107325Siwasaki *              Handler             - Handler used in call to AcpiAttachData
1109100966Siwasaki *
1110100966Siwasaki * RETURN:      Status
1111100966Siwasaki *
1112107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node.
1113100966Siwasaki *
1114100966Siwasaki ******************************************************************************/
1115100966Siwasaki
1116100966SiwasakiACPI_STATUS
1117100966SiwasakiAcpiDetachData (
1118100966Siwasaki    ACPI_HANDLE             ObjHandle,
1119100966Siwasaki    ACPI_OBJECT_HANDLER     Handler)
1120100966Siwasaki{
1121100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
1122100966Siwasaki    ACPI_STATUS             Status;
1123100966Siwasaki
1124100966Siwasaki
1125100966Siwasaki    /* Parameter validation */
1126100966Siwasaki
1127100966Siwasaki    if (!ObjHandle  ||
1128100966Siwasaki        !Handler)
1129100966Siwasaki    {
1130100966Siwasaki        return (AE_BAD_PARAMETER);
1131100966Siwasaki    }
1132100966Siwasaki
1133100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1134100966Siwasaki    if (ACPI_FAILURE (Status))
1135100966Siwasaki    {
1136100966Siwasaki        return (Status);
1137100966Siwasaki    }
1138100966Siwasaki
1139100966Siwasaki    /* Convert and validate the handle */
1140100966Siwasaki
1141200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
1142100966Siwasaki    if (!Node)
1143100966Siwasaki    {
1144100966Siwasaki        Status = AE_BAD_PARAMETER;
1145100966Siwasaki        goto UnlockAndExit;
1146100966Siwasaki    }
1147100966Siwasaki
1148100966Siwasaki    Status = AcpiNsDetachData (Node, Handler);
1149100966Siwasaki
1150100966SiwasakiUnlockAndExit:
1151100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1152100966Siwasaki    return (Status);
1153100966Siwasaki}
1154100966Siwasaki
1155167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData)
1156100966Siwasaki
1157167802Sjkim
1158100966Siwasaki/*******************************************************************************
1159100966Siwasaki *
1160100966Siwasaki * FUNCTION:    AcpiGetData
1161100966Siwasaki *
1162107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node
1163107325Siwasaki *              Handler             - Handler used in call to AttachData
1164107325Siwasaki *              Data                - Where the data is returned
1165100966Siwasaki *
1166100966Siwasaki * RETURN:      Status
1167100966Siwasaki *
1168107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
1169100966Siwasaki *
1170100966Siwasaki ******************************************************************************/
1171100966Siwasaki
1172100966SiwasakiACPI_STATUS
1173100966SiwasakiAcpiGetData (
1174100966Siwasaki    ACPI_HANDLE             ObjHandle,
1175100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
1176100966Siwasaki    void                    **Data)
1177100966Siwasaki{
1178100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
1179100966Siwasaki    ACPI_STATUS             Status;
1180100966Siwasaki
1181100966Siwasaki
1182100966Siwasaki    /* Parameter validation */
1183100966Siwasaki
1184100966Siwasaki    if (!ObjHandle  ||
1185100966Siwasaki        !Handler    ||
1186100966Siwasaki        !Data)
1187100966Siwasaki    {
1188100966Siwasaki        return (AE_BAD_PARAMETER);
1189100966Siwasaki    }
1190100966Siwasaki
1191100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1192100966Siwasaki    if (ACPI_FAILURE (Status))
1193100966Siwasaki    {
1194100966Siwasaki        return (Status);
1195100966Siwasaki    }
1196100966Siwasaki
1197100966Siwasaki    /* Convert and validate the handle */
1198100966Siwasaki
1199200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
1200100966Siwasaki    if (!Node)
1201100966Siwasaki    {
1202100966Siwasaki        Status = AE_BAD_PARAMETER;
1203100966Siwasaki        goto UnlockAndExit;
1204100966Siwasaki    }
1205100966Siwasaki
1206100966Siwasaki    Status = AcpiNsGetAttachedData (Node, Handler, Data);
1207100966Siwasaki
1208100966SiwasakiUnlockAndExit:
1209100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1210100966Siwasaki    return (Status);
1211100966Siwasaki}
1212100966Siwasaki
1213167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData)
1214