nsxfeval.c revision 202771
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 *
12202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, 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
284200553Sjkim    Info->PrefixNode = AcpiNsValidateHandle (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
547199337Sjkim *              PreOrderVisit       - Called during tree pre-order visit
548199337Sjkim *                                    when an object of "Type" is found
549199337Sjkim *              PostOrderVisit      - Called during tree post-order visit
550199337Sjkim *                                    when an object of "Type" is found
551199337Sjkim *              Context             - Passed to user function(s) above
552100966Siwasaki *              ReturnValue         - Location where return value of
553100966Siwasaki *                                    UserFunction is put if terminated early
554100966Siwasaki *
555100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
556100966Siwasaki *              Otherwise, returns NULL.
557100966Siwasaki *
558100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
559100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
560199337Sjkim *              The callback function is called whenever an object that matches
561199337Sjkim *              the type parameter is found. If the callback function returns
562100966Siwasaki *              a non-zero value, the search is terminated immediately and this
563100966Siwasaki *              value is returned to the caller.
564100966Siwasaki *
565100966Siwasaki *              The point of this procedure is to provide a generic namespace
566100966Siwasaki *              walk routine that can be called from multiple places to
567199337Sjkim *              provide multiple services; the callback function(s) can be
568199337Sjkim *              tailored to each task, whether it is a print function,
569199337Sjkim *              a compare function, etc.
570100966Siwasaki *
571100966Siwasaki ******************************************************************************/
572100966Siwasaki
573100966SiwasakiACPI_STATUS
574100966SiwasakiAcpiWalkNamespace (
575100966Siwasaki    ACPI_OBJECT_TYPE        Type,
576100966Siwasaki    ACPI_HANDLE             StartObject,
577100966Siwasaki    UINT32                  MaxDepth,
578199337Sjkim    ACPI_WALK_CALLBACK      PreOrderVisit,
579199337Sjkim    ACPI_WALK_CALLBACK      PostOrderVisit,
580100966Siwasaki    void                    *Context,
581100966Siwasaki    void                    **ReturnValue)
582100966Siwasaki{
583100966Siwasaki    ACPI_STATUS             Status;
584100966Siwasaki
585100966Siwasaki
586167802Sjkim    ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
587100966Siwasaki
588100966Siwasaki
589100966Siwasaki    /* Parameter validation */
590100966Siwasaki
591167802Sjkim    if ((Type > ACPI_TYPE_LOCAL_MAX) ||
592167802Sjkim        (!MaxDepth)                  ||
593199337Sjkim        (!PreOrderVisit && !PostOrderVisit))
594100966Siwasaki    {
595100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
596100966Siwasaki    }
597100966Siwasaki
598100966Siwasaki    /*
599193267Sjkim     * Need to acquire the namespace reader lock to prevent interference
600193267Sjkim     * with any concurrent table unloads (which causes the deletion of
601193267Sjkim     * namespace objects). We cannot allow the deletion of a namespace node
602193267Sjkim     * while the user function is using it. The exception to this are the
603193267Sjkim     * nodes created and deleted during control method execution -- these
604193267Sjkim     * nodes are marked as temporary nodes and are ignored by the namespace
605193267Sjkim     * walk. Thus, control methods can be executed while holding the
606193267Sjkim     * namespace deletion lock (and the user function can execute control
607193267Sjkim     * methods.)
608100966Siwasaki     */
609193267Sjkim    Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
610193267Sjkim    if (ACPI_FAILURE (Status))
611193267Sjkim    {
612193267Sjkim        return (Status);
613193267Sjkim    }
614193267Sjkim
615193267Sjkim    /*
616193267Sjkim     * Lock the namespace around the walk. The namespace will be
617193267Sjkim     * unlocked/locked around each call to the user function - since the user
618193267Sjkim     * function must be allowed to make ACPICA calls itself (for example, it
619193267Sjkim     * will typically execute control methods during device enumeration.)
620193267Sjkim     */
621100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
622100966Siwasaki    if (ACPI_FAILURE (Status))
623100966Siwasaki    {
624193267Sjkim        goto UnlockAndExit;
625100966Siwasaki    }
626100966Siwasaki
627151937Sjkim    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
628199337Sjkim                ACPI_NS_WALK_UNLOCK, PreOrderVisit,
629199337Sjkim                PostOrderVisit, Context, ReturnValue);
630100966Siwasaki
631100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
632193267Sjkim
633193267SjkimUnlockAndExit:
634193267Sjkim    (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
635100966Siwasaki    return_ACPI_STATUS (Status);
636100966Siwasaki}
637100966Siwasaki
638167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
639100966Siwasaki
640167802Sjkim
641100966Siwasaki/*******************************************************************************
642100966Siwasaki *
643100966Siwasaki * FUNCTION:    AcpiNsGetDeviceCallback
644100966Siwasaki *
645100966Siwasaki * PARAMETERS:  Callback from AcpiGetDevice
646100966Siwasaki *
647100966Siwasaki * RETURN:      Status
648100966Siwasaki *
649100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
650100966Siwasaki *              present devices, or if they specified a HID, it filters based
651100966Siwasaki *              on that.
652100966Siwasaki *
653100966Siwasaki ******************************************************************************/
654100966Siwasaki
655100966Siwasakistatic ACPI_STATUS
656100966SiwasakiAcpiNsGetDeviceCallback (
657100966Siwasaki    ACPI_HANDLE             ObjHandle,
658100966Siwasaki    UINT32                  NestingLevel,
659100966Siwasaki    void                    *Context,
660100966Siwasaki    void                    **ReturnValue)
661100966Siwasaki{
662117521Snjl    ACPI_GET_DEVICES_INFO   *Info = Context;
663100966Siwasaki    ACPI_STATUS             Status;
664100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
665100966Siwasaki    UINT32                  Flags;
666197104Sjkim    ACPI_DEVICE_ID          *Hid;
667197104Sjkim    ACPI_DEVICE_ID_LIST     *Cid;
668193267Sjkim    UINT32                  i;
669193267Sjkim    BOOLEAN                 Found;
670197104Sjkim    int                     NoMatch;
671100966Siwasaki
672100966Siwasaki
673100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
674100966Siwasaki    if (ACPI_FAILURE (Status))
675100966Siwasaki    {
676100966Siwasaki        return (Status);
677100966Siwasaki    }
678100966Siwasaki
679200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
680100966Siwasaki    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
681100966Siwasaki    if (ACPI_FAILURE (Status))
682100966Siwasaki    {
683100966Siwasaki        return (Status);
684100966Siwasaki    }
685100966Siwasaki
686100966Siwasaki    if (!Node)
687100966Siwasaki    {
688100966Siwasaki        return (AE_BAD_PARAMETER);
689100966Siwasaki    }
690100966Siwasaki
691202771Sjkim    /*
692202771Sjkim     * First, filter based on the device HID and CID.
693202771Sjkim     *
694202771Sjkim     * 01/2010: For this case where a specific HID is requested, we don't
695202771Sjkim     * want to run _STA until we have an actual HID match. Thus, we will
696202771Sjkim     * not unnecessarily execute _STA on devices for which the caller
697202771Sjkim     * doesn't care about. Previously, _STA was executed unconditionally
698202771Sjkim     * on all devices found here.
699202771Sjkim     *
700202771Sjkim     * A side-effect of this change is that now we will continue to search
701202771Sjkim     * for a matching HID even under device trees where the parent device
702202771Sjkim     * would have returned a _STA that indicates it is not present or
703202771Sjkim     * not functioning (thus aborting the search on that branch).
704202771Sjkim     */
705100966Siwasaki    if (Info->Hid != NULL)
706100966Siwasaki    {
707100966Siwasaki        Status = AcpiUtExecute_HID (Node, &Hid);
708100966Siwasaki        if (Status == AE_NOT_FOUND)
709100966Siwasaki        {
710100966Siwasaki            return (AE_OK);
711100966Siwasaki        }
712100966Siwasaki        else if (ACPI_FAILURE (Status))
713100966Siwasaki        {
714100966Siwasaki            return (AE_CTRL_DEPTH);
715100966Siwasaki        }
716100966Siwasaki
717197104Sjkim        NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
718197104Sjkim        ACPI_FREE (Hid);
719197104Sjkim
720197104Sjkim        if (NoMatch)
721100966Siwasaki        {
722193267Sjkim            /*
723193267Sjkim             * HID does not match, attempt match within the
724193267Sjkim             * list of Compatible IDs (CIDs)
725193267Sjkim             */
726100966Siwasaki            Status = AcpiUtExecute_CID (Node, &Cid);
727100966Siwasaki            if (Status == AE_NOT_FOUND)
728100966Siwasaki            {
729100966Siwasaki                return (AE_OK);
730100966Siwasaki            }
731100966Siwasaki            else if (ACPI_FAILURE (Status))
732100966Siwasaki            {
733100966Siwasaki                return (AE_CTRL_DEPTH);
734100966Siwasaki            }
735100966Siwasaki
736117521Snjl            /* Walk the CID list */
737100966Siwasaki
738193267Sjkim            Found = FALSE;
739117521Snjl            for (i = 0; i < Cid->Count; i++)
740100966Siwasaki            {
741197104Sjkim                if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
742117521Snjl                {
743193267Sjkim                    /* Found a matching CID */
744193267Sjkim
745193267Sjkim                    Found = TRUE;
746193267Sjkim                    break;
747117521Snjl                }
748100966Siwasaki            }
749193267Sjkim
750167802Sjkim            ACPI_FREE (Cid);
751193267Sjkim            if (!Found)
752193267Sjkim            {
753193267Sjkim                return (AE_OK);
754193267Sjkim            }
755100966Siwasaki        }
756100966Siwasaki    }
757100966Siwasaki
758202771Sjkim    /* Run _STA to determine if device is present */
759202771Sjkim
760202771Sjkim    Status = AcpiUtExecute_STA (Node, &Flags);
761202771Sjkim    if (ACPI_FAILURE (Status))
762202771Sjkim    {
763202771Sjkim        return (AE_CTRL_DEPTH);
764202771Sjkim    }
765202771Sjkim
766202771Sjkim    if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
767202771Sjkim        !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
768202771Sjkim    {
769202771Sjkim        /*
770202771Sjkim         * Don't examine the children of the device only when the
771202771Sjkim         * device is neither present nor functional. See ACPI spec,
772202771Sjkim         * description of _STA for more information.
773202771Sjkim         */
774202771Sjkim        return (AE_CTRL_DEPTH);
775202771Sjkim    }
776202771Sjkim
777193267Sjkim    /* We have a valid device, invoke the user function */
778193267Sjkim
779151937Sjkim    Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
780151937Sjkim                ReturnValue);
781100966Siwasaki    return (Status);
782100966Siwasaki}
783100966Siwasaki
784100966Siwasaki
785100966Siwasaki/*******************************************************************************
786100966Siwasaki *
787100966Siwasaki * FUNCTION:    AcpiGetDevices
788100966Siwasaki *
789100966Siwasaki * PARAMETERS:  HID                 - HID to search for. Can be NULL.
790100966Siwasaki *              UserFunction        - Called when a matching object is found
791100966Siwasaki *              Context             - Passed to user function
792100966Siwasaki *              ReturnValue         - Location where return value of
793100966Siwasaki *                                    UserFunction is put if terminated early
794100966Siwasaki *
795100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
796100966Siwasaki *              Otherwise, returns NULL.
797100966Siwasaki *
798100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
799100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
800117521Snjl *              The UserFunction is called whenever an object of type
801117521Snjl *              Device is found.  If the user function returns
802100966Siwasaki *              a non-zero value, the search is terminated immediately and this
803100966Siwasaki *              value is returned to the caller.
804100966Siwasaki *
805100966Siwasaki *              This is a wrapper for WalkNamespace, but the callback performs
806193267Sjkim *              additional filtering. Please see AcpiNsGetDeviceCallback.
807100966Siwasaki *
808100966Siwasaki ******************************************************************************/
809100966Siwasaki
810100966SiwasakiACPI_STATUS
811100966SiwasakiAcpiGetDevices (
812114237Snjl    char                    *HID,
813100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
814100966Siwasaki    void                    *Context,
815100966Siwasaki    void                    **ReturnValue)
816100966Siwasaki{
817100966Siwasaki    ACPI_STATUS             Status;
818100966Siwasaki    ACPI_GET_DEVICES_INFO   Info;
819100966Siwasaki
820100966Siwasaki
821167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetDevices);
822100966Siwasaki
823100966Siwasaki
824100966Siwasaki    /* Parameter validation */
825100966Siwasaki
826100966Siwasaki    if (!UserFunction)
827100966Siwasaki    {
828100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
829100966Siwasaki    }
830100966Siwasaki
831100966Siwasaki    /*
832100966Siwasaki     * We're going to call their callback from OUR callback, so we need
833100966Siwasaki     * to know what it is, and their context parameter.
834100966Siwasaki     */
835167802Sjkim    Info.Hid          = HID;
836100966Siwasaki    Info.Context      = Context;
837100966Siwasaki    Info.UserFunction = UserFunction;
838100966Siwasaki
839100966Siwasaki    /*
840100966Siwasaki     * Lock the namespace around the walk.
841100966Siwasaki     * The namespace will be unlocked/locked around each call
842100966Siwasaki     * to the user function - since this function
843100966Siwasaki     * must be allowed to make Acpi calls itself.
844100966Siwasaki     */
845100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
846100966Siwasaki    if (ACPI_FAILURE (Status))
847100966Siwasaki    {
848100966Siwasaki        return_ACPI_STATUS (Status);
849100966Siwasaki    }
850100966Siwasaki
851167802Sjkim    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
852167802Sjkim                ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
853199337Sjkim                AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
854100966Siwasaki
855100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
856100966Siwasaki    return_ACPI_STATUS (Status);
857100966Siwasaki}
858100966Siwasaki
859167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices)
860100966Siwasaki
861167802Sjkim
862100966Siwasaki/*******************************************************************************
863100966Siwasaki *
864100966Siwasaki * FUNCTION:    AcpiAttachData
865100966Siwasaki *
866114237Snjl * PARAMETERS:  ObjHandle           - Namespace node
867107325Siwasaki *              Handler             - Handler for this attachment
868107325Siwasaki *              Data                - Pointer to data to be attached
869100966Siwasaki *
870100966Siwasaki * RETURN:      Status
871100966Siwasaki *
872107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
873100966Siwasaki *
874100966Siwasaki ******************************************************************************/
875100966Siwasaki
876100966SiwasakiACPI_STATUS
877100966SiwasakiAcpiAttachData (
878100966Siwasaki    ACPI_HANDLE             ObjHandle,
879100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
880100966Siwasaki    void                    *Data)
881100966Siwasaki{
882100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
883100966Siwasaki    ACPI_STATUS             Status;
884100966Siwasaki
885100966Siwasaki
886100966Siwasaki    /* Parameter validation */
887100966Siwasaki
888100966Siwasaki    if (!ObjHandle  ||
889100966Siwasaki        !Handler    ||
890100966Siwasaki        !Data)
891100966Siwasaki    {
892100966Siwasaki        return (AE_BAD_PARAMETER);
893100966Siwasaki    }
894100966Siwasaki
895100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
896100966Siwasaki    if (ACPI_FAILURE (Status))
897100966Siwasaki    {
898100966Siwasaki        return (Status);
899100966Siwasaki    }
900100966Siwasaki
901100966Siwasaki    /* Convert and validate the handle */
902100966Siwasaki
903200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
904100966Siwasaki    if (!Node)
905100966Siwasaki    {
906100966Siwasaki        Status = AE_BAD_PARAMETER;
907100966Siwasaki        goto UnlockAndExit;
908100966Siwasaki    }
909100966Siwasaki
910100966Siwasaki    Status = AcpiNsAttachData (Node, Handler, Data);
911100966Siwasaki
912100966SiwasakiUnlockAndExit:
913100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
914100966Siwasaki    return (Status);
915100966Siwasaki}
916100966Siwasaki
917167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData)
918100966Siwasaki
919167802Sjkim
920100966Siwasaki/*******************************************************************************
921100966Siwasaki *
922100966Siwasaki * FUNCTION:    AcpiDetachData
923100966Siwasaki *
924107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node handle
925107325Siwasaki *              Handler             - Handler used in call to AcpiAttachData
926100966Siwasaki *
927100966Siwasaki * RETURN:      Status
928100966Siwasaki *
929107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node.
930100966Siwasaki *
931100966Siwasaki ******************************************************************************/
932100966Siwasaki
933100966SiwasakiACPI_STATUS
934100966SiwasakiAcpiDetachData (
935100966Siwasaki    ACPI_HANDLE             ObjHandle,
936100966Siwasaki    ACPI_OBJECT_HANDLER     Handler)
937100966Siwasaki{
938100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
939100966Siwasaki    ACPI_STATUS             Status;
940100966Siwasaki
941100966Siwasaki
942100966Siwasaki    /* Parameter validation */
943100966Siwasaki
944100966Siwasaki    if (!ObjHandle  ||
945100966Siwasaki        !Handler)
946100966Siwasaki    {
947100966Siwasaki        return (AE_BAD_PARAMETER);
948100966Siwasaki    }
949100966Siwasaki
950100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
951100966Siwasaki    if (ACPI_FAILURE (Status))
952100966Siwasaki    {
953100966Siwasaki        return (Status);
954100966Siwasaki    }
955100966Siwasaki
956100966Siwasaki    /* Convert and validate the handle */
957100966Siwasaki
958200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
959100966Siwasaki    if (!Node)
960100966Siwasaki    {
961100966Siwasaki        Status = AE_BAD_PARAMETER;
962100966Siwasaki        goto UnlockAndExit;
963100966Siwasaki    }
964100966Siwasaki
965100966Siwasaki    Status = AcpiNsDetachData (Node, Handler);
966100966Siwasaki
967100966SiwasakiUnlockAndExit:
968100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
969100966Siwasaki    return (Status);
970100966Siwasaki}
971100966Siwasaki
972167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData)
973100966Siwasaki
974167802Sjkim
975100966Siwasaki/*******************************************************************************
976100966Siwasaki *
977100966Siwasaki * FUNCTION:    AcpiGetData
978100966Siwasaki *
979107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node
980107325Siwasaki *              Handler             - Handler used in call to AttachData
981107325Siwasaki *              Data                - Where the data is returned
982100966Siwasaki *
983100966Siwasaki * RETURN:      Status
984100966Siwasaki *
985107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
986100966Siwasaki *
987100966Siwasaki ******************************************************************************/
988100966Siwasaki
989100966SiwasakiACPI_STATUS
990100966SiwasakiAcpiGetData (
991100966Siwasaki    ACPI_HANDLE             ObjHandle,
992100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
993100966Siwasaki    void                    **Data)
994100966Siwasaki{
995100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
996100966Siwasaki    ACPI_STATUS             Status;
997100966Siwasaki
998100966Siwasaki
999100966Siwasaki    /* Parameter validation */
1000100966Siwasaki
1001100966Siwasaki    if (!ObjHandle  ||
1002100966Siwasaki        !Handler    ||
1003100966Siwasaki        !Data)
1004100966Siwasaki    {
1005100966Siwasaki        return (AE_BAD_PARAMETER);
1006100966Siwasaki    }
1007100966Siwasaki
1008100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1009100966Siwasaki    if (ACPI_FAILURE (Status))
1010100966Siwasaki    {
1011100966Siwasaki        return (Status);
1012100966Siwasaki    }
1013100966Siwasaki
1014100966Siwasaki    /* Convert and validate the handle */
1015100966Siwasaki
1016200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
1017100966Siwasaki    if (!Node)
1018100966Siwasaki    {
1019100966Siwasaki        Status = AE_BAD_PARAMETER;
1020100966Siwasaki        goto UnlockAndExit;
1021100966Siwasaki    }
1022100966Siwasaki
1023100966Siwasaki    Status = AcpiNsGetAttachedData (Node, Handler, Data);
1024100966Siwasaki
1025100966SiwasakiUnlockAndExit:
1026100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1027100966Siwasaki    return (Status);
1028100966Siwasaki}
1029100966Siwasaki
1030167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData)
1031100966Siwasaki
1032167802Sjkim
1033