nsxfeval.c revision 197104
1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4100966Siwasaki *                         ACPI Object evaluation interfaces
5100966Siwasaki *
6100966Siwasaki ******************************************************************************/
7100966Siwasaki
8100966Siwasaki/******************************************************************************
9100966Siwasaki *
10100966Siwasaki * 1. Copyright Notice
11100966Siwasaki *
12193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
13100966Siwasaki * All rights reserved.
14100966Siwasaki *
15100966Siwasaki * 2. License
16100966Siwasaki *
17100966Siwasaki * 2.1. This is your license from Intel Corp. under its intellectual property
18100966Siwasaki * rights.  You may have additional license terms from the party that provided
19100966Siwasaki * you this software, covering your right to use that party's intellectual
20100966Siwasaki * property rights.
21100966Siwasaki *
22100966Siwasaki * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23100966Siwasaki * copy of the source code appearing in this file ("Covered Code") an
24100966Siwasaki * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25100966Siwasaki * base code distributed originally by Intel ("Original Intel Code") to copy,
26100966Siwasaki * make derivatives, distribute, use and display any portion of the Covered
27100966Siwasaki * Code in any form, with the right to sublicense such rights; and
28100966Siwasaki *
29100966Siwasaki * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30100966Siwasaki * license (with the right to sublicense), under only those claims of Intel
31100966Siwasaki * patents that are infringed by the Original Intel Code, to make, use, sell,
32100966Siwasaki * offer to sell, and import the Covered Code and derivative works thereof
33100966Siwasaki * solely to the minimum extent necessary to exercise the above copyright
34100966Siwasaki * license, and in no event shall the patent license extend to any additions
35100966Siwasaki * to or modifications of the Original Intel Code.  No other license or right
36100966Siwasaki * is granted directly or by implication, estoppel or otherwise;
37100966Siwasaki *
38100966Siwasaki * The above copyright and patent license is granted only if the following
39100966Siwasaki * conditions are met:
40100966Siwasaki *
41100966Siwasaki * 3. Conditions
42100966Siwasaki *
43100966Siwasaki * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44100966Siwasaki * Redistribution of source code of any substantial portion of the Covered
45100966Siwasaki * Code or modification with rights to further distribute source must include
46100966Siwasaki * the above Copyright Notice, the above License, this list of Conditions,
47100966Siwasaki * and the following Disclaimer and Export Compliance provision.  In addition,
48100966Siwasaki * Licensee must cause all Covered Code to which Licensee contributes to
49100966Siwasaki * contain a file documenting the changes Licensee made to create that Covered
50100966Siwasaki * Code and the date of any change.  Licensee must include in that file the
51100966Siwasaki * documentation of any changes made by any predecessor Licensee.  Licensee
52100966Siwasaki * must include a prominent statement that the modification is derived,
53100966Siwasaki * directly or indirectly, from Original Intel Code.
54100966Siwasaki *
55100966Siwasaki * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56100966Siwasaki * Redistribution of source code of any substantial portion of the Covered
57100966Siwasaki * Code or modification without rights to further distribute source must
58100966Siwasaki * include the following Disclaimer and Export Compliance provision in the
59100966Siwasaki * documentation and/or other materials provided with distribution.  In
60100966Siwasaki * addition, Licensee may not authorize further sublicense of source of any
61100966Siwasaki * portion of the Covered Code, and must include terms to the effect that the
62100966Siwasaki * license from Licensee to its licensee is limited to the intellectual
63100966Siwasaki * property embodied in the software Licensee provides to its licensee, and
64100966Siwasaki * not to intellectual property embodied in modifications its licensee may
65100966Siwasaki * make.
66100966Siwasaki *
67100966Siwasaki * 3.3. Redistribution of Executable. Redistribution in executable form of any
68100966Siwasaki * substantial portion of the Covered Code or modification must reproduce the
69100966Siwasaki * above Copyright Notice, and the following Disclaimer and Export Compliance
70100966Siwasaki * provision in the documentation and/or other materials provided with the
71100966Siwasaki * distribution.
72100966Siwasaki *
73100966Siwasaki * 3.4. Intel retains all right, title, and interest in and to the Original
74100966Siwasaki * Intel Code.
75100966Siwasaki *
76100966Siwasaki * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77100966Siwasaki * Intel shall be used in advertising or otherwise to promote the sale, use or
78100966Siwasaki * other dealings in products derived from or relating to the Covered Code
79100966Siwasaki * without prior written authorization from Intel.
80100966Siwasaki *
81100966Siwasaki * 4. Disclaimer and Export Compliance
82100966Siwasaki *
83100966Siwasaki * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84100966Siwasaki * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85100966Siwasaki * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86100966Siwasaki * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87100966Siwasaki * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88100966Siwasaki * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89100966Siwasaki * PARTICULAR PURPOSE.
90100966Siwasaki *
91100966Siwasaki * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92100966Siwasaki * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93100966Siwasaki * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94100966Siwasaki * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95100966Siwasaki * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96100966Siwasaki * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97100966Siwasaki * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98100966Siwasaki * LIMITED REMEDY.
99100966Siwasaki *
100100966Siwasaki * 4.3. Licensee shall not export, either directly or indirectly, any of this
101100966Siwasaki * software or system incorporating such software without first obtaining any
102100966Siwasaki * required license or other approval from the U. S. Department of Commerce or
103100966Siwasaki * any other agency or department of the United States Government.  In the
104100966Siwasaki * event Licensee exports any such software from the United States or
105100966Siwasaki * re-exports any such software from a foreign destination, Licensee shall
106100966Siwasaki * ensure that the distribution and export/re-export of the software is in
107100966Siwasaki * compliance with all laws, regulations, orders, or other restrictions of the
108100966Siwasaki * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109100966Siwasaki * any of its subsidiaries will export/re-export any technical data, process,
110100966Siwasaki * software, or service, directly or indirectly, to any country for which the
111100966Siwasaki * United States government or any agency thereof requires an export license,
112100966Siwasaki * other governmental approval, or letter of assurance, without first obtaining
113100966Siwasaki * such license, approval or letter.
114100966Siwasaki *
115100966Siwasaki *****************************************************************************/
116100966Siwasaki
117100966Siwasaki
118100966Siwasaki#define __NSXFEVAL_C__
119100966Siwasaki
120193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
121193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
122193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
123193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
124100966Siwasaki
125100966Siwasaki
126100966Siwasaki#define _COMPONENT          ACPI_NAMESPACE
127100966Siwasaki        ACPI_MODULE_NAME    ("nsxfeval")
128100966Siwasaki
129193267Sjkim/* Local prototypes */
130100966Siwasaki
131193267Sjkimstatic void
132193267SjkimAcpiNsResolveReferences (
133193267Sjkim    ACPI_EVALUATE_INFO      *Info);
134193267Sjkim
135193267Sjkim
136100966Siwasaki/*******************************************************************************
137100966Siwasaki *
138100966Siwasaki * FUNCTION:    AcpiEvaluateObjectTyped
139100966Siwasaki *
140100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
141151937Sjkim *              Pathname            - Object pathname (optional)
142151937Sjkim *              ExternalParams      - List of parameters to pass to method,
143100966Siwasaki *                                    terminated by NULL.  May be NULL
144100966Siwasaki *                                    if no parameters are being passed.
145151937Sjkim *              ReturnBuffer        - Where to put method's return value (if
146100966Siwasaki *                                    any).  If NULL, no value is returned.
147100966Siwasaki *              ReturnType          - Expected type of return object
148100966Siwasaki *
149100966Siwasaki * RETURN:      Status
150100966Siwasaki *
151100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
152100966Siwasaki *              parameters if necessary.  One of "Handle" or "Pathname" must
153100966Siwasaki *              be valid (non-null)
154100966Siwasaki *
155100966Siwasaki ******************************************************************************/
156100966Siwasaki
157100966SiwasakiACPI_STATUS
158100966SiwasakiAcpiEvaluateObjectTyped (
159100966Siwasaki    ACPI_HANDLE             Handle,
160100966Siwasaki    ACPI_STRING             Pathname,
161100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
162100966Siwasaki    ACPI_BUFFER             *ReturnBuffer,
163100966Siwasaki    ACPI_OBJECT_TYPE        ReturnType)
164100966Siwasaki{
165100966Siwasaki    ACPI_STATUS             Status;
166100966Siwasaki    BOOLEAN                 MustFree = FALSE;
167100966Siwasaki
168100966Siwasaki
169167802Sjkim    ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
170100966Siwasaki
171100966Siwasaki
172100966Siwasaki    /* Return buffer must be valid */
173100966Siwasaki
174100966Siwasaki    if (!ReturnBuffer)
175100966Siwasaki    {
176100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
177100966Siwasaki    }
178100966Siwasaki
179100966Siwasaki    if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
180100966Siwasaki    {
181100966Siwasaki        MustFree = TRUE;
182100966Siwasaki    }
183100966Siwasaki
184100966Siwasaki    /* Evaluate the object */
185100966Siwasaki
186100966Siwasaki    Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
187100966Siwasaki    if (ACPI_FAILURE (Status))
188100966Siwasaki    {
189100966Siwasaki        return_ACPI_STATUS (Status);
190100966Siwasaki    }
191100966Siwasaki
192100966Siwasaki    /* Type ANY means "don't care" */
193100966Siwasaki
194100966Siwasaki    if (ReturnType == ACPI_TYPE_ANY)
195100966Siwasaki    {
196100966Siwasaki        return_ACPI_STATUS (AE_OK);
197100966Siwasaki    }
198100966Siwasaki
199100966Siwasaki    if (ReturnBuffer->Length == 0)
200100966Siwasaki    {
201100966Siwasaki        /* Error because caller specifically asked for a return value */
202100966Siwasaki
203167802Sjkim        ACPI_ERROR ((AE_INFO, "No return value"));
204100966Siwasaki        return_ACPI_STATUS (AE_NULL_OBJECT);
205100966Siwasaki    }
206100966Siwasaki
207100966Siwasaki    /* Examine the object type returned from EvaluateObject */
208100966Siwasaki
209100966Siwasaki    if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
210100966Siwasaki    {
211100966Siwasaki        return_ACPI_STATUS (AE_OK);
212100966Siwasaki    }
213100966Siwasaki
214100966Siwasaki    /* Return object type does not match requested type */
215100966Siwasaki
216167802Sjkim    ACPI_ERROR ((AE_INFO,
217167802Sjkim        "Incorrect return type [%s] requested [%s]",
218100966Siwasaki        AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
219100966Siwasaki        AcpiUtGetTypeName (ReturnType)));
220100966Siwasaki
221100966Siwasaki    if (MustFree)
222100966Siwasaki    {
223100966Siwasaki        /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
224100966Siwasaki
225100966Siwasaki        AcpiOsFree (ReturnBuffer->Pointer);
226100966Siwasaki        ReturnBuffer->Pointer = NULL;
227100966Siwasaki    }
228100966Siwasaki
229100966Siwasaki    ReturnBuffer->Length = 0;
230100966Siwasaki    return_ACPI_STATUS (AE_TYPE);
231100966Siwasaki}
232100966Siwasaki
233167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
234100966Siwasaki
235167802Sjkim
236100966Siwasaki/*******************************************************************************
237100966Siwasaki *
238100966Siwasaki * FUNCTION:    AcpiEvaluateObject
239100966Siwasaki *
240100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
241128212Snjl *              Pathname            - Object pathname (optional)
242128212Snjl *              ExternalParams      - List of parameters to pass to method,
243100966Siwasaki *                                    terminated by NULL.  May be NULL
244100966Siwasaki *                                    if no parameters are being passed.
245128212Snjl *              ReturnBuffer        - Where to put method's return value (if
246100966Siwasaki *                                    any).  If NULL, no value is returned.
247100966Siwasaki *
248100966Siwasaki * RETURN:      Status
249100966Siwasaki *
250100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
251100966Siwasaki *              parameters if necessary.  One of "Handle" or "Pathname" must
252100966Siwasaki *              be valid (non-null)
253100966Siwasaki *
254100966Siwasaki ******************************************************************************/
255100966Siwasaki
256100966SiwasakiACPI_STATUS
257100966SiwasakiAcpiEvaluateObject (
258100966Siwasaki    ACPI_HANDLE             Handle,
259100966Siwasaki    ACPI_STRING             Pathname,
260100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
261100966Siwasaki    ACPI_BUFFER             *ReturnBuffer)
262100966Siwasaki{
263100966Siwasaki    ACPI_STATUS             Status;
264167802Sjkim    ACPI_EVALUATE_INFO      *Info;
265100966Siwasaki    ACPI_SIZE               BufferSpaceNeeded;
266100966Siwasaki    UINT32                  i;
267100966Siwasaki
268100966Siwasaki
269167802Sjkim    ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
270100966Siwasaki
271100966Siwasaki
272167802Sjkim    /* Allocate and initialize the evaluation information block */
273129684Snjl
274167802Sjkim    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
275167802Sjkim    if (!Info)
276167802Sjkim    {
277167802Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
278167802Sjkim    }
279167802Sjkim
280167802Sjkim    Info->Pathname = Pathname;
281167802Sjkim
282167802Sjkim    /* Convert and validate the device handle */
283167802Sjkim
284167802Sjkim    Info->PrefixNode = AcpiNsMapHandleToNode (Handle);
285167802Sjkim    if (!Info->PrefixNode)
286167802Sjkim    {
287167802Sjkim        Status = AE_BAD_PARAMETER;
288167802Sjkim        goto Cleanup;
289167802Sjkim    }
290167802Sjkim
291100966Siwasaki    /*
292167802Sjkim     * If there are parameters to be passed to a control method, the external
293167802Sjkim     * objects must all be converted to internal objects
294100966Siwasaki     */
295100966Siwasaki    if (ExternalParams && ExternalParams->Count)
296100966Siwasaki    {
297100966Siwasaki        /*
298100966Siwasaki         * Allocate a new parameter block for the internal objects
299100966Siwasaki         * Add 1 to count to allow for null terminated internal list
300100966Siwasaki         */
301167802Sjkim        Info->Parameters = ACPI_ALLOCATE_ZEROED (
302167802Sjkim            ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
303167802Sjkim        if (!Info->Parameters)
304100966Siwasaki        {
305167802Sjkim            Status = AE_NO_MEMORY;
306167802Sjkim            goto Cleanup;
307100966Siwasaki        }
308100966Siwasaki
309167802Sjkim        /* Convert each external object in the list to an internal object */
310167802Sjkim
311100966Siwasaki        for (i = 0; i < ExternalParams->Count; i++)
312100966Siwasaki        {
313167802Sjkim            Status = AcpiUtCopyEobjectToIobject (
314167802Sjkim                        &ExternalParams->Pointer[i], &Info->Parameters[i]);
315100966Siwasaki            if (ACPI_FAILURE (Status))
316100966Siwasaki            {
317167802Sjkim                goto Cleanup;
318100966Siwasaki            }
319100966Siwasaki        }
320167802Sjkim        Info->Parameters[ExternalParams->Count] = NULL;
321100966Siwasaki    }
322100966Siwasaki
323100966Siwasaki    /*
324100966Siwasaki     * Three major cases:
325100966Siwasaki     * 1) Fully qualified pathname
326100966Siwasaki     * 2) No handle, not fully qualified pathname (error)
327100966Siwasaki     * 3) Valid handle
328100966Siwasaki     */
329100966Siwasaki    if ((Pathname) &&
330100966Siwasaki        (AcpiNsValidRootPrefix (Pathname[0])))
331100966Siwasaki    {
332167802Sjkim        /* The path is fully qualified, just evaluate by name */
333167802Sjkim
334167802Sjkim        Info->PrefixNode = NULL;
335167802Sjkim        Status = AcpiNsEvaluate (Info);
336100966Siwasaki    }
337100966Siwasaki    else if (!Handle)
338100966Siwasaki    {
339100966Siwasaki        /*
340167802Sjkim         * A handle is optional iff a fully qualified pathname is specified.
341167802Sjkim         * Since we've already handled fully qualified names above, this is
342167802Sjkim         * an error
343100966Siwasaki         */
344100966Siwasaki        if (!Pathname)
345100966Siwasaki        {
346167802Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
347167802Sjkim                "Both Handle and Pathname are NULL"));
348100966Siwasaki        }
349100966Siwasaki        else
350100966Siwasaki        {
351167802Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
352167802Sjkim                "Null Handle with relative pathname [%s]", Pathname));
353100966Siwasaki        }
354100966Siwasaki
355100966Siwasaki        Status = AE_BAD_PARAMETER;
356100966Siwasaki    }
357100966Siwasaki    else
358100966Siwasaki    {
359167802Sjkim        /* We have a namespace a node and a possible relative path */
360167802Sjkim
361167802Sjkim        Status = AcpiNsEvaluate (Info);
362100966Siwasaki    }
363100966Siwasaki
364100966Siwasaki    /*
365100966Siwasaki     * If we are expecting a return value, and all went well above,
366100966Siwasaki     * copy the return value to an external object.
367100966Siwasaki     */
368100966Siwasaki    if (ReturnBuffer)
369100966Siwasaki    {
370167802Sjkim        if (!Info->ReturnObject)
371100966Siwasaki        {
372100966Siwasaki            ReturnBuffer->Length = 0;
373100966Siwasaki        }
374100966Siwasaki        else
375100966Siwasaki        {
376167802Sjkim            if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
377167802Sjkim                ACPI_DESC_TYPE_NAMED)
378100966Siwasaki            {
379100966Siwasaki                /*
380100966Siwasaki                 * If we received a NS Node as a return object, this means that
381100966Siwasaki                 * the object we are evaluating has nothing interesting to
382100966Siwasaki                 * return (such as a mutex, etc.)  We return an error because
383100966Siwasaki                 * these types are essentially unsupported by this interface.
384100966Siwasaki                 * We don't check up front because this makes it easier to add
385100966Siwasaki                 * support for various types at a later date if necessary.
386100966Siwasaki                 */
387100966Siwasaki                Status = AE_TYPE;
388167802Sjkim                Info->ReturnObject = NULL;   /* No need to delete a NS Node */
389100966Siwasaki                ReturnBuffer->Length = 0;
390100966Siwasaki            }
391100966Siwasaki
392100966Siwasaki            if (ACPI_SUCCESS (Status))
393100966Siwasaki            {
394193267Sjkim                /* Dereference Index and RefOf references */
395193267Sjkim
396193267Sjkim                AcpiNsResolveReferences (Info);
397193267Sjkim
398167802Sjkim                /* Get the size of the returned object */
399167802Sjkim
400167802Sjkim                Status = AcpiUtGetObjectSize (Info->ReturnObject,
401167802Sjkim                            &BufferSpaceNeeded);
402100966Siwasaki                if (ACPI_SUCCESS (Status))
403100966Siwasaki                {
404100966Siwasaki                    /* Validate/Allocate/Clear caller buffer */
405100966Siwasaki
406151937Sjkim                    Status = AcpiUtInitializeBuffer (ReturnBuffer,
407167802Sjkim                                BufferSpaceNeeded);
408100966Siwasaki                    if (ACPI_FAILURE (Status))
409100966Siwasaki                    {
410100966Siwasaki                        /*
411167802Sjkim                         * Caller's buffer is too small or a new one can't
412167802Sjkim                         * be allocated
413100966Siwasaki                         */
414100966Siwasaki                        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
415100966Siwasaki                            "Needed buffer size %X, %s\n",
416129684Snjl                            (UINT32) BufferSpaceNeeded,
417129684Snjl                            AcpiFormatException (Status)));
418100966Siwasaki                    }
419100966Siwasaki                    else
420100966Siwasaki                    {
421167802Sjkim                        /* We have enough space for the object, build it */
422167802Sjkim
423167802Sjkim                        Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
424167802Sjkim                                    ReturnBuffer);
425100966Siwasaki                    }
426100966Siwasaki                }
427100966Siwasaki            }
428100966Siwasaki        }
429100966Siwasaki    }
430100966Siwasaki
431167802Sjkim    if (Info->ReturnObject)
432100966Siwasaki    {
433129684Snjl        /*
434167802Sjkim         * Delete the internal return object. NOTE: Interpreter must be
435167802Sjkim         * locked to avoid race condition.
436100966Siwasaki         */
437167802Sjkim        AcpiExEnterInterpreter ();
438167802Sjkim
439167802Sjkim        /* Remove one reference on the return object (should delete it) */
440167802Sjkim
441167802Sjkim        AcpiUtRemoveReference (Info->ReturnObject);
442167802Sjkim        AcpiExExitInterpreter ();
443100966Siwasaki    }
444100966Siwasaki
445167802Sjkim
446167802SjkimCleanup:
447167802Sjkim
448167802Sjkim    /* Free the input parameter list (if we created one) */
449167802Sjkim
450167802Sjkim    if (Info->Parameters)
451100966Siwasaki    {
452100966Siwasaki        /* Free the allocated parameter block */
453100966Siwasaki
454167802Sjkim        AcpiUtDeleteInternalObjectList (Info->Parameters);
455100966Siwasaki    }
456100966Siwasaki
457167802Sjkim    ACPI_FREE (Info);
458100966Siwasaki    return_ACPI_STATUS (Status);
459100966Siwasaki}
460100966Siwasaki
461167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
462100966Siwasaki
463167802Sjkim
464100966Siwasaki/*******************************************************************************
465100966Siwasaki *
466193267Sjkim * FUNCTION:    AcpiNsResolveReferences
467193267Sjkim *
468193267Sjkim * PARAMETERS:  Info                    - Evaluation info block
469193267Sjkim *
470193267Sjkim * RETURN:      Info->ReturnObject is replaced with the dereferenced object
471193267Sjkim *
472193267Sjkim * DESCRIPTION: Dereference certain reference objects. Called before an
473193267Sjkim *              internal return object is converted to an external ACPI_OBJECT.
474193267Sjkim *
475193267Sjkim * Performs an automatic dereference of Index and RefOf reference objects.
476193267Sjkim * These reference objects are not supported by the ACPI_OBJECT, so this is a
477193267Sjkim * last resort effort to return something useful. Also, provides compatibility
478193267Sjkim * with other ACPI implementations.
479193267Sjkim *
480193267Sjkim * NOTE: does not handle references within returned package objects or nested
481193267Sjkim * references, but this support could be added later if found to be necessary.
482193267Sjkim *
483193267Sjkim ******************************************************************************/
484193267Sjkim
485193267Sjkimstatic void
486193267SjkimAcpiNsResolveReferences (
487193267Sjkim    ACPI_EVALUATE_INFO      *Info)
488193267Sjkim{
489193267Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
490193267Sjkim    ACPI_NAMESPACE_NODE     *Node;
491193267Sjkim
492193267Sjkim
493193267Sjkim    /* We are interested in reference objects only */
494193267Sjkim
495193267Sjkim    if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
496193267Sjkim    {
497193267Sjkim        return;
498193267Sjkim    }
499193267Sjkim
500193267Sjkim    /*
501193267Sjkim     * Two types of references are supported - those created by Index and
502193267Sjkim     * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
503193267Sjkim     * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
504193267Sjkim     * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
505193267Sjkim     * an ACPI_OBJECT.
506193267Sjkim     */
507193267Sjkim    switch (Info->ReturnObject->Reference.Class)
508193267Sjkim    {
509193267Sjkim    case ACPI_REFCLASS_INDEX:
510193267Sjkim
511193267Sjkim        ObjDesc = *(Info->ReturnObject->Reference.Where);
512193267Sjkim        break;
513193267Sjkim
514193267Sjkim    case ACPI_REFCLASS_REFOF:
515193267Sjkim
516193267Sjkim        Node = Info->ReturnObject->Reference.Object;
517193267Sjkim        if (Node)
518193267Sjkim        {
519193267Sjkim            ObjDesc = Node->Object;
520193267Sjkim        }
521193267Sjkim        break;
522193267Sjkim
523193267Sjkim    default:
524193267Sjkim        return;
525193267Sjkim    }
526193267Sjkim
527193267Sjkim    /* Replace the existing reference object */
528193267Sjkim
529193267Sjkim    if (ObjDesc)
530193267Sjkim    {
531193267Sjkim        AcpiUtAddReference (ObjDesc);
532193267Sjkim        AcpiUtRemoveReference (Info->ReturnObject);
533193267Sjkim        Info->ReturnObject = ObjDesc;
534193267Sjkim    }
535193267Sjkim
536193267Sjkim    return;
537193267Sjkim}
538193267Sjkim
539193267Sjkim
540193267Sjkim/*******************************************************************************
541193267Sjkim *
542100966Siwasaki * FUNCTION:    AcpiWalkNamespace
543100966Siwasaki *
544100966Siwasaki * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
545100966Siwasaki *              StartObject         - Handle in namespace where search begins
546100966Siwasaki *              MaxDepth            - Depth to which search is to reach
547100966Siwasaki *              UserFunction        - Called when an object of "Type" is found
548100966Siwasaki *              Context             - Passed to user function
549100966Siwasaki *              ReturnValue         - Location where return value of
550100966Siwasaki *                                    UserFunction is put if terminated early
551100966Siwasaki *
552100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
553100966Siwasaki *              Otherwise, returns NULL.
554100966Siwasaki *
555100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
556100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
557100966Siwasaki *              The UserFunction is called whenever an object that matches
558100966Siwasaki *              the type parameter is found.  If the user function returns
559100966Siwasaki *              a non-zero value, the search is terminated immediately and this
560100966Siwasaki *              value is returned to the caller.
561100966Siwasaki *
562100966Siwasaki *              The point of this procedure is to provide a generic namespace
563100966Siwasaki *              walk routine that can be called from multiple places to
564100966Siwasaki *              provide multiple services;  the User Function can be tailored
565100966Siwasaki *              to each task, whether it is a print function, a compare
566100966Siwasaki *              function, etc.
567100966Siwasaki *
568100966Siwasaki ******************************************************************************/
569100966Siwasaki
570100966SiwasakiACPI_STATUS
571100966SiwasakiAcpiWalkNamespace (
572100966Siwasaki    ACPI_OBJECT_TYPE        Type,
573100966Siwasaki    ACPI_HANDLE             StartObject,
574100966Siwasaki    UINT32                  MaxDepth,
575100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
576100966Siwasaki    void                    *Context,
577100966Siwasaki    void                    **ReturnValue)
578100966Siwasaki{
579100966Siwasaki    ACPI_STATUS             Status;
580100966Siwasaki
581100966Siwasaki
582167802Sjkim    ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
583100966Siwasaki
584100966Siwasaki
585100966Siwasaki    /* Parameter validation */
586100966Siwasaki
587167802Sjkim    if ((Type > ACPI_TYPE_LOCAL_MAX) ||
588167802Sjkim        (!MaxDepth)                  ||
589100966Siwasaki        (!UserFunction))
590100966Siwasaki    {
591100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
592100966Siwasaki    }
593100966Siwasaki
594100966Siwasaki    /*
595193267Sjkim     * Need to acquire the namespace reader lock to prevent interference
596193267Sjkim     * with any concurrent table unloads (which causes the deletion of
597193267Sjkim     * namespace objects). We cannot allow the deletion of a namespace node
598193267Sjkim     * while the user function is using it. The exception to this are the
599193267Sjkim     * nodes created and deleted during control method execution -- these
600193267Sjkim     * nodes are marked as temporary nodes and are ignored by the namespace
601193267Sjkim     * walk. Thus, control methods can be executed while holding the
602193267Sjkim     * namespace deletion lock (and the user function can execute control
603193267Sjkim     * methods.)
604100966Siwasaki     */
605193267Sjkim    Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
606193267Sjkim    if (ACPI_FAILURE (Status))
607193267Sjkim    {
608193267Sjkim        return (Status);
609193267Sjkim    }
610193267Sjkim
611193267Sjkim    /*
612193267Sjkim     * Lock the namespace around the walk. The namespace will be
613193267Sjkim     * unlocked/locked around each call to the user function - since the user
614193267Sjkim     * function must be allowed to make ACPICA calls itself (for example, it
615193267Sjkim     * will typically execute control methods during device enumeration.)
616193267Sjkim     */
617100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
618100966Siwasaki    if (ACPI_FAILURE (Status))
619100966Siwasaki    {
620193267Sjkim        goto UnlockAndExit;
621100966Siwasaki    }
622100966Siwasaki
623151937Sjkim    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
624193267Sjkim                ACPI_NS_WALK_UNLOCK, UserFunction, Context, ReturnValue);
625100966Siwasaki
626100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
627193267Sjkim
628193267SjkimUnlockAndExit:
629193267Sjkim    (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
630100966Siwasaki    return_ACPI_STATUS (Status);
631100966Siwasaki}
632100966Siwasaki
633167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
634100966Siwasaki
635167802Sjkim
636100966Siwasaki/*******************************************************************************
637100966Siwasaki *
638100966Siwasaki * FUNCTION:    AcpiNsGetDeviceCallback
639100966Siwasaki *
640100966Siwasaki * PARAMETERS:  Callback from AcpiGetDevice
641100966Siwasaki *
642100966Siwasaki * RETURN:      Status
643100966Siwasaki *
644100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
645100966Siwasaki *              present devices, or if they specified a HID, it filters based
646100966Siwasaki *              on that.
647100966Siwasaki *
648100966Siwasaki ******************************************************************************/
649100966Siwasaki
650100966Siwasakistatic ACPI_STATUS
651100966SiwasakiAcpiNsGetDeviceCallback (
652100966Siwasaki    ACPI_HANDLE             ObjHandle,
653100966Siwasaki    UINT32                  NestingLevel,
654100966Siwasaki    void                    *Context,
655100966Siwasaki    void                    **ReturnValue)
656100966Siwasaki{
657117521Snjl    ACPI_GET_DEVICES_INFO   *Info = Context;
658100966Siwasaki    ACPI_STATUS             Status;
659100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
660100966Siwasaki    UINT32                  Flags;
661197104Sjkim    ACPI_DEVICE_ID          *Hid;
662197104Sjkim    ACPI_DEVICE_ID_LIST     *Cid;
663193267Sjkim    UINT32                  i;
664193267Sjkim    BOOLEAN                 Found;
665197104Sjkim    int                     NoMatch;
666100966Siwasaki
667100966Siwasaki
668100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
669100966Siwasaki    if (ACPI_FAILURE (Status))
670100966Siwasaki    {
671100966Siwasaki        return (Status);
672100966Siwasaki    }
673100966Siwasaki
674100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
675100966Siwasaki    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
676100966Siwasaki    if (ACPI_FAILURE (Status))
677100966Siwasaki    {
678100966Siwasaki        return (Status);
679100966Siwasaki    }
680100966Siwasaki
681100966Siwasaki    if (!Node)
682100966Siwasaki    {
683100966Siwasaki        return (AE_BAD_PARAMETER);
684100966Siwasaki    }
685100966Siwasaki
686117521Snjl    /* Run _STA to determine if device is present */
687117521Snjl
688100966Siwasaki    Status = AcpiUtExecute_STA (Node, &Flags);
689100966Siwasaki    if (ACPI_FAILURE (Status))
690100966Siwasaki    {
691100966Siwasaki        return (AE_CTRL_DEPTH);
692100966Siwasaki    }
693100966Siwasaki
694193267Sjkim    if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
695193267Sjkim        !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
696100966Siwasaki    {
697193267Sjkim        /*
698193267Sjkim         * Don't examine the children of the device only when the
699193267Sjkim         * device is neither present nor functional. See ACPI spec,
700193267Sjkim         * description of _STA for more information.
701193267Sjkim         */
702100966Siwasaki        return (AE_CTRL_DEPTH);
703100966Siwasaki    }
704100966Siwasaki
705117521Snjl    /* Filter based on device HID & CID */
706117521Snjl
707100966Siwasaki    if (Info->Hid != NULL)
708100966Siwasaki    {
709100966Siwasaki        Status = AcpiUtExecute_HID (Node, &Hid);
710100966Siwasaki        if (Status == AE_NOT_FOUND)
711100966Siwasaki        {
712100966Siwasaki            return (AE_OK);
713100966Siwasaki        }
714100966Siwasaki        else if (ACPI_FAILURE (Status))
715100966Siwasaki        {
716100966Siwasaki            return (AE_CTRL_DEPTH);
717100966Siwasaki        }
718100966Siwasaki
719197104Sjkim        NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
720197104Sjkim        ACPI_FREE (Hid);
721197104Sjkim
722197104Sjkim        if (NoMatch)
723100966Siwasaki        {
724193267Sjkim            /*
725193267Sjkim             * HID does not match, attempt match within the
726193267Sjkim             * list of Compatible IDs (CIDs)
727193267Sjkim             */
728100966Siwasaki            Status = AcpiUtExecute_CID (Node, &Cid);
729100966Siwasaki            if (Status == AE_NOT_FOUND)
730100966Siwasaki            {
731100966Siwasaki                return (AE_OK);
732100966Siwasaki            }
733100966Siwasaki            else if (ACPI_FAILURE (Status))
734100966Siwasaki            {
735100966Siwasaki                return (AE_CTRL_DEPTH);
736100966Siwasaki            }
737100966Siwasaki
738117521Snjl            /* Walk the CID list */
739100966Siwasaki
740193267Sjkim            Found = FALSE;
741117521Snjl            for (i = 0; i < Cid->Count; i++)
742100966Siwasaki            {
743197104Sjkim                if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
744117521Snjl                {
745193267Sjkim                    /* Found a matching CID */
746193267Sjkim
747193267Sjkim                    Found = TRUE;
748193267Sjkim                    break;
749117521Snjl                }
750100966Siwasaki            }
751193267Sjkim
752167802Sjkim            ACPI_FREE (Cid);
753193267Sjkim            if (!Found)
754193267Sjkim            {
755193267Sjkim                return (AE_OK);
756193267Sjkim            }
757100966Siwasaki        }
758100966Siwasaki    }
759100966Siwasaki
760193267Sjkim    /* We have a valid device, invoke the user function */
761193267Sjkim
762151937Sjkim    Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
763151937Sjkim                ReturnValue);
764100966Siwasaki    return (Status);
765100966Siwasaki}
766100966Siwasaki
767100966Siwasaki
768100966Siwasaki/*******************************************************************************
769100966Siwasaki *
770100966Siwasaki * FUNCTION:    AcpiGetDevices
771100966Siwasaki *
772100966Siwasaki * PARAMETERS:  HID                 - HID to search for. Can be NULL.
773100966Siwasaki *              UserFunction        - Called when a matching object is found
774100966Siwasaki *              Context             - Passed to user function
775100966Siwasaki *              ReturnValue         - Location where return value of
776100966Siwasaki *                                    UserFunction is put if terminated early
777100966Siwasaki *
778100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
779100966Siwasaki *              Otherwise, returns NULL.
780100966Siwasaki *
781100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
782100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
783117521Snjl *              The UserFunction is called whenever an object of type
784117521Snjl *              Device is found.  If the user function returns
785100966Siwasaki *              a non-zero value, the search is terminated immediately and this
786100966Siwasaki *              value is returned to the caller.
787100966Siwasaki *
788100966Siwasaki *              This is a wrapper for WalkNamespace, but the callback performs
789193267Sjkim *              additional filtering. Please see AcpiNsGetDeviceCallback.
790100966Siwasaki *
791100966Siwasaki ******************************************************************************/
792100966Siwasaki
793100966SiwasakiACPI_STATUS
794100966SiwasakiAcpiGetDevices (
795114237Snjl    char                    *HID,
796100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
797100966Siwasaki    void                    *Context,
798100966Siwasaki    void                    **ReturnValue)
799100966Siwasaki{
800100966Siwasaki    ACPI_STATUS             Status;
801100966Siwasaki    ACPI_GET_DEVICES_INFO   Info;
802100966Siwasaki
803100966Siwasaki
804167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetDevices);
805100966Siwasaki
806100966Siwasaki
807100966Siwasaki    /* Parameter validation */
808100966Siwasaki
809100966Siwasaki    if (!UserFunction)
810100966Siwasaki    {
811100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
812100966Siwasaki    }
813100966Siwasaki
814100966Siwasaki    /*
815100966Siwasaki     * We're going to call their callback from OUR callback, so we need
816100966Siwasaki     * to know what it is, and their context parameter.
817100966Siwasaki     */
818167802Sjkim    Info.Hid          = HID;
819100966Siwasaki    Info.Context      = Context;
820100966Siwasaki    Info.UserFunction = UserFunction;
821100966Siwasaki
822100966Siwasaki    /*
823100966Siwasaki     * Lock the namespace around the walk.
824100966Siwasaki     * The namespace will be unlocked/locked around each call
825100966Siwasaki     * to the user function - since this function
826100966Siwasaki     * must be allowed to make Acpi calls itself.
827100966Siwasaki     */
828100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
829100966Siwasaki    if (ACPI_FAILURE (Status))
830100966Siwasaki    {
831100966Siwasaki        return_ACPI_STATUS (Status);
832100966Siwasaki    }
833100966Siwasaki
834167802Sjkim    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
835167802Sjkim                ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
836167802Sjkim                AcpiNsGetDeviceCallback, &Info, ReturnValue);
837100966Siwasaki
838100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
839100966Siwasaki    return_ACPI_STATUS (Status);
840100966Siwasaki}
841100966Siwasaki
842167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices)
843100966Siwasaki
844167802Sjkim
845100966Siwasaki/*******************************************************************************
846100966Siwasaki *
847100966Siwasaki * FUNCTION:    AcpiAttachData
848100966Siwasaki *
849114237Snjl * PARAMETERS:  ObjHandle           - Namespace node
850107325Siwasaki *              Handler             - Handler for this attachment
851107325Siwasaki *              Data                - Pointer to data to be attached
852100966Siwasaki *
853100966Siwasaki * RETURN:      Status
854100966Siwasaki *
855107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
856100966Siwasaki *
857100966Siwasaki ******************************************************************************/
858100966Siwasaki
859100966SiwasakiACPI_STATUS
860100966SiwasakiAcpiAttachData (
861100966Siwasaki    ACPI_HANDLE             ObjHandle,
862100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
863100966Siwasaki    void                    *Data)
864100966Siwasaki{
865100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
866100966Siwasaki    ACPI_STATUS             Status;
867100966Siwasaki
868100966Siwasaki
869100966Siwasaki    /* Parameter validation */
870100966Siwasaki
871100966Siwasaki    if (!ObjHandle  ||
872100966Siwasaki        !Handler    ||
873100966Siwasaki        !Data)
874100966Siwasaki    {
875100966Siwasaki        return (AE_BAD_PARAMETER);
876100966Siwasaki    }
877100966Siwasaki
878100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
879100966Siwasaki    if (ACPI_FAILURE (Status))
880100966Siwasaki    {
881100966Siwasaki        return (Status);
882100966Siwasaki    }
883100966Siwasaki
884100966Siwasaki    /* Convert and validate the handle */
885100966Siwasaki
886100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
887100966Siwasaki    if (!Node)
888100966Siwasaki    {
889100966Siwasaki        Status = AE_BAD_PARAMETER;
890100966Siwasaki        goto UnlockAndExit;
891100966Siwasaki    }
892100966Siwasaki
893100966Siwasaki    Status = AcpiNsAttachData (Node, Handler, Data);
894100966Siwasaki
895100966SiwasakiUnlockAndExit:
896100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
897100966Siwasaki    return (Status);
898100966Siwasaki}
899100966Siwasaki
900167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData)
901100966Siwasaki
902167802Sjkim
903100966Siwasaki/*******************************************************************************
904100966Siwasaki *
905100966Siwasaki * FUNCTION:    AcpiDetachData
906100966Siwasaki *
907107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node handle
908107325Siwasaki *              Handler             - Handler used in call to AcpiAttachData
909100966Siwasaki *
910100966Siwasaki * RETURN:      Status
911100966Siwasaki *
912107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node.
913100966Siwasaki *
914100966Siwasaki ******************************************************************************/
915100966Siwasaki
916100966SiwasakiACPI_STATUS
917100966SiwasakiAcpiDetachData (
918100966Siwasaki    ACPI_HANDLE             ObjHandle,
919100966Siwasaki    ACPI_OBJECT_HANDLER     Handler)
920100966Siwasaki{
921100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
922100966Siwasaki    ACPI_STATUS             Status;
923100966Siwasaki
924100966Siwasaki
925100966Siwasaki    /* Parameter validation */
926100966Siwasaki
927100966Siwasaki    if (!ObjHandle  ||
928100966Siwasaki        !Handler)
929100966Siwasaki    {
930100966Siwasaki        return (AE_BAD_PARAMETER);
931100966Siwasaki    }
932100966Siwasaki
933100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
934100966Siwasaki    if (ACPI_FAILURE (Status))
935100966Siwasaki    {
936100966Siwasaki        return (Status);
937100966Siwasaki    }
938100966Siwasaki
939100966Siwasaki    /* Convert and validate the handle */
940100966Siwasaki
941100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
942100966Siwasaki    if (!Node)
943100966Siwasaki    {
944100966Siwasaki        Status = AE_BAD_PARAMETER;
945100966Siwasaki        goto UnlockAndExit;
946100966Siwasaki    }
947100966Siwasaki
948100966Siwasaki    Status = AcpiNsDetachData (Node, Handler);
949100966Siwasaki
950100966SiwasakiUnlockAndExit:
951100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
952100966Siwasaki    return (Status);
953100966Siwasaki}
954100966Siwasaki
955167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData)
956100966Siwasaki
957167802Sjkim
958100966Siwasaki/*******************************************************************************
959100966Siwasaki *
960100966Siwasaki * FUNCTION:    AcpiGetData
961100966Siwasaki *
962107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node
963107325Siwasaki *              Handler             - Handler used in call to AttachData
964107325Siwasaki *              Data                - Where the data is returned
965100966Siwasaki *
966100966Siwasaki * RETURN:      Status
967100966Siwasaki *
968107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
969100966Siwasaki *
970100966Siwasaki ******************************************************************************/
971100966Siwasaki
972100966SiwasakiACPI_STATUS
973100966SiwasakiAcpiGetData (
974100966Siwasaki    ACPI_HANDLE             ObjHandle,
975100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
976100966Siwasaki    void                    **Data)
977100966Siwasaki{
978100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
979100966Siwasaki    ACPI_STATUS             Status;
980100966Siwasaki
981100966Siwasaki
982100966Siwasaki    /* Parameter validation */
983100966Siwasaki
984100966Siwasaki    if (!ObjHandle  ||
985100966Siwasaki        !Handler    ||
986100966Siwasaki        !Data)
987100966Siwasaki    {
988100966Siwasaki        return (AE_BAD_PARAMETER);
989100966Siwasaki    }
990100966Siwasaki
991100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
992100966Siwasaki    if (ACPI_FAILURE (Status))
993100966Siwasaki    {
994100966Siwasaki        return (Status);
995100966Siwasaki    }
996100966Siwasaki
997100966Siwasaki    /* Convert and validate the handle */
998100966Siwasaki
999100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
1000100966Siwasaki    if (!Node)
1001100966Siwasaki    {
1002100966Siwasaki        Status = AE_BAD_PARAMETER;
1003100966Siwasaki        goto UnlockAndExit;
1004100966Siwasaki    }
1005100966Siwasaki
1006100966Siwasaki    Status = AcpiNsGetAttachedData (Node, Handler, Data);
1007100966Siwasaki
1008100966SiwasakiUnlockAndExit:
1009100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1010100966Siwasaki    return (Status);
1011100966Siwasaki}
1012100966Siwasaki
1013167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData)
1014100966Siwasaki
1015167802Sjkim
1016