1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4100966Siwasaki *                         ACPI Object evaluation interfaces
5100966Siwasaki *
6100966Siwasaki ******************************************************************************/
7100966Siwasaki
8217365Sjkim/*
9306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
10100966Siwasaki * All rights reserved.
11100966Siwasaki *
12217365Sjkim * Redistribution and use in source and binary forms, with or without
13217365Sjkim * modification, are permitted provided that the following conditions
14217365Sjkim * are met:
15217365Sjkim * 1. Redistributions of source code must retain the above copyright
16217365Sjkim *    notice, this list of conditions, and the following disclaimer,
17217365Sjkim *    without modification.
18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
20217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
21217365Sjkim *    including a substantially similar Disclaimer requirement for further
22217365Sjkim *    binary redistribution.
23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
24217365Sjkim *    of any contributors may be used to endorse or promote products derived
25217365Sjkim *    from this software without specific prior written permission.
26100966Siwasaki *
27217365Sjkim * Alternatively, this software may be distributed under the terms of the
28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
29217365Sjkim * Software Foundation.
30100966Siwasaki *
31217365Sjkim * NO WARRANTY
32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
43217365Sjkim */
44100966Siwasaki
45281075Sdim#define EXPORT_ACPI_INTERFACES
46100966Siwasaki
47193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
48193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
51100966Siwasaki
52100966Siwasaki
53100966Siwasaki#define _COMPONENT          ACPI_NAMESPACE
54100966Siwasaki        ACPI_MODULE_NAME    ("nsxfeval")
55100966Siwasaki
56193267Sjkim/* Local prototypes */
57100966Siwasaki
58193267Sjkimstatic void
59193267SjkimAcpiNsResolveReferences (
60193267Sjkim    ACPI_EVALUATE_INFO      *Info);
61193267Sjkim
62193267Sjkim
63100966Siwasaki/*******************************************************************************
64100966Siwasaki *
65100966Siwasaki * FUNCTION:    AcpiEvaluateObjectTyped
66100966Siwasaki *
67100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
68151937Sjkim *              Pathname            - Object pathname (optional)
69151937Sjkim *              ExternalParams      - List of parameters to pass to method,
70241973Sjkim *                                    terminated by NULL. May be NULL
71100966Siwasaki *                                    if no parameters are being passed.
72151937Sjkim *              ReturnBuffer        - Where to put method's return value (if
73241973Sjkim *                                    any). If NULL, no value is returned.
74100966Siwasaki *              ReturnType          - Expected type of return object
75100966Siwasaki *
76100966Siwasaki * RETURN:      Status
77100966Siwasaki *
78100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
79241973Sjkim *              parameters if necessary. One of "Handle" or "Pathname" must
80100966Siwasaki *              be valid (non-null)
81100966Siwasaki *
82100966Siwasaki ******************************************************************************/
83100966Siwasaki
84100966SiwasakiACPI_STATUS
85100966SiwasakiAcpiEvaluateObjectTyped (
86100966Siwasaki    ACPI_HANDLE             Handle,
87100966Siwasaki    ACPI_STRING             Pathname,
88100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
89100966Siwasaki    ACPI_BUFFER             *ReturnBuffer,
90100966Siwasaki    ACPI_OBJECT_TYPE        ReturnType)
91100966Siwasaki{
92100966Siwasaki    ACPI_STATUS             Status;
93281075Sdim    BOOLEAN                 FreeBufferOnError = FALSE;
94100966Siwasaki
95100966Siwasaki
96167802Sjkim    ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
97100966Siwasaki
98100966Siwasaki
99100966Siwasaki    /* Return buffer must be valid */
100100966Siwasaki
101100966Siwasaki    if (!ReturnBuffer)
102100966Siwasaki    {
103100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
104100966Siwasaki    }
105100966Siwasaki
106100966Siwasaki    if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
107100966Siwasaki    {
108281075Sdim        FreeBufferOnError = TRUE;
109100966Siwasaki    }
110100966Siwasaki
111100966Siwasaki    /* Evaluate the object */
112100966Siwasaki
113281075Sdim    Status = AcpiEvaluateObject (Handle, Pathname,
114281075Sdim        ExternalParams, ReturnBuffer);
115100966Siwasaki    if (ACPI_FAILURE (Status))
116100966Siwasaki    {
117100966Siwasaki        return_ACPI_STATUS (Status);
118100966Siwasaki    }
119100966Siwasaki
120100966Siwasaki    /* Type ANY means "don't care" */
121100966Siwasaki
122100966Siwasaki    if (ReturnType == ACPI_TYPE_ANY)
123100966Siwasaki    {
124100966Siwasaki        return_ACPI_STATUS (AE_OK);
125100966Siwasaki    }
126100966Siwasaki
127100966Siwasaki    if (ReturnBuffer->Length == 0)
128100966Siwasaki    {
129100966Siwasaki        /* Error because caller specifically asked for a return value */
130100966Siwasaki
131167802Sjkim        ACPI_ERROR ((AE_INFO, "No return value"));
132100966Siwasaki        return_ACPI_STATUS (AE_NULL_OBJECT);
133100966Siwasaki    }
134100966Siwasaki
135100966Siwasaki    /* Examine the object type returned from EvaluateObject */
136100966Siwasaki
137100966Siwasaki    if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
138100966Siwasaki    {
139100966Siwasaki        return_ACPI_STATUS (AE_OK);
140100966Siwasaki    }
141100966Siwasaki
142100966Siwasaki    /* Return object type does not match requested type */
143100966Siwasaki
144167802Sjkim    ACPI_ERROR ((AE_INFO,
145167802Sjkim        "Incorrect return type [%s] requested [%s]",
146100966Siwasaki        AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
147100966Siwasaki        AcpiUtGetTypeName (ReturnType)));
148100966Siwasaki
149281075Sdim    if (FreeBufferOnError)
150100966Siwasaki    {
151281075Sdim        /*
152281075Sdim         * Free a buffer created via ACPI_ALLOCATE_BUFFER.
153281075Sdim         * Note: We use AcpiOsFree here because AcpiOsAllocate was used
154281075Sdim         * to allocate the buffer. This purposefully bypasses the
155281075Sdim         * (optionally enabled) allocation tracking mechanism since we
156281075Sdim         * only want to track internal allocations.
157281075Sdim         */
158100966Siwasaki        AcpiOsFree (ReturnBuffer->Pointer);
159100966Siwasaki        ReturnBuffer->Pointer = NULL;
160100966Siwasaki    }
161100966Siwasaki
162100966Siwasaki    ReturnBuffer->Length = 0;
163100966Siwasaki    return_ACPI_STATUS (AE_TYPE);
164100966Siwasaki}
165100966Siwasaki
166167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
167100966Siwasaki
168167802Sjkim
169100966Siwasaki/*******************************************************************************
170100966Siwasaki *
171100966Siwasaki * FUNCTION:    AcpiEvaluateObject
172100966Siwasaki *
173100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
174128212Snjl *              Pathname            - Object pathname (optional)
175128212Snjl *              ExternalParams      - List of parameters to pass to method,
176241973Sjkim *                                    terminated by NULL. May be NULL
177100966Siwasaki *                                    if no parameters are being passed.
178128212Snjl *              ReturnBuffer        - Where to put method's return value (if
179241973Sjkim *                                    any). If NULL, no value is returned.
180100966Siwasaki *
181100966Siwasaki * RETURN:      Status
182100966Siwasaki *
183100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
184241973Sjkim *              parameters if necessary. One of "Handle" or "Pathname" must
185100966Siwasaki *              be valid (non-null)
186100966Siwasaki *
187100966Siwasaki ******************************************************************************/
188100966Siwasaki
189100966SiwasakiACPI_STATUS
190100966SiwasakiAcpiEvaluateObject (
191100966Siwasaki    ACPI_HANDLE             Handle,
192100966Siwasaki    ACPI_STRING             Pathname,
193100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
194100966Siwasaki    ACPI_BUFFER             *ReturnBuffer)
195100966Siwasaki{
196100966Siwasaki    ACPI_STATUS             Status;
197167802Sjkim    ACPI_EVALUATE_INFO      *Info;
198100966Siwasaki    ACPI_SIZE               BufferSpaceNeeded;
199100966Siwasaki    UINT32                  i;
200100966Siwasaki
201100966Siwasaki
202167802Sjkim    ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
203100966Siwasaki
204100966Siwasaki
205167802Sjkim    /* Allocate and initialize the evaluation information block */
206129684Snjl
207167802Sjkim    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
208167802Sjkim    if (!Info)
209167802Sjkim    {
210167802Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
211167802Sjkim    }
212167802Sjkim
213167802Sjkim    /* Convert and validate the device handle */
214167802Sjkim
215200553Sjkim    Info->PrefixNode = AcpiNsValidateHandle (Handle);
216167802Sjkim    if (!Info->PrefixNode)
217167802Sjkim    {
218167802Sjkim        Status = AE_BAD_PARAMETER;
219167802Sjkim        goto Cleanup;
220167802Sjkim    }
221167802Sjkim
222100966Siwasaki    /*
223249663Sjkim     * Get the actual namespace node for the target object.
224249663Sjkim     * Handles these cases:
225249663Sjkim     *
226249663Sjkim     * 1) Null node, valid pathname from root (absolute path)
227249663Sjkim     * 2) Node and valid pathname (path relative to Node)
228249663Sjkim     * 3) Node, Null pathname
229100966Siwasaki     */
230249663Sjkim    if ((Pathname) &&
231249663Sjkim        (ACPI_IS_ROOT_PREFIX (Pathname[0])))
232249663Sjkim    {
233249663Sjkim        /* The path is fully qualified, just evaluate by name */
234249663Sjkim
235249663Sjkim        Info->PrefixNode = NULL;
236249663Sjkim    }
237249663Sjkim    else if (!Handle)
238249663Sjkim    {
239249663Sjkim        /*
240249663Sjkim         * A handle is optional iff a fully qualified pathname is specified.
241249663Sjkim         * Since we've already handled fully qualified names above, this is
242249663Sjkim         * an error.
243249663Sjkim         */
244249663Sjkim        if (!Pathname)
245249663Sjkim        {
246249663Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
247249663Sjkim                "Both Handle and Pathname are NULL"));
248249663Sjkim        }
249249663Sjkim        else
250249663Sjkim        {
251249663Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
252249663Sjkim                "Null Handle with relative pathname [%s]", Pathname));
253249663Sjkim        }
254249663Sjkim
255249663Sjkim        Status = AE_BAD_PARAMETER;
256249663Sjkim        goto Cleanup;
257249663Sjkim    }
258249663Sjkim
259249663Sjkim    Info->RelativePathname = Pathname;
260249663Sjkim
261249663Sjkim    /*
262249663Sjkim     * Convert all external objects passed as arguments to the
263249663Sjkim     * internal version(s).
264249663Sjkim     */
265100966Siwasaki    if (ExternalParams && ExternalParams->Count)
266100966Siwasaki    {
267249663Sjkim        Info->ParamCount = (UINT16) ExternalParams->Count;
268249663Sjkim
269249663Sjkim        /* Warn on impossible argument count */
270249663Sjkim
271249663Sjkim        if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
272249663Sjkim        {
273249663Sjkim            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
274249663Sjkim                "Excess arguments (%u) - using only %u",
275249663Sjkim                Info->ParamCount, ACPI_METHOD_NUM_ARGS));
276249663Sjkim
277249663Sjkim            Info->ParamCount = ACPI_METHOD_NUM_ARGS;
278249663Sjkim        }
279249663Sjkim
280100966Siwasaki        /*
281100966Siwasaki         * Allocate a new parameter block for the internal objects
282100966Siwasaki         * Add 1 to count to allow for null terminated internal list
283100966Siwasaki         */
284167802Sjkim        Info->Parameters = ACPI_ALLOCATE_ZEROED (
285249663Sjkim            ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
286167802Sjkim        if (!Info->Parameters)
287100966Siwasaki        {
288167802Sjkim            Status = AE_NO_MEMORY;
289167802Sjkim            goto Cleanup;
290100966Siwasaki        }
291100966Siwasaki
292167802Sjkim        /* Convert each external object in the list to an internal object */
293167802Sjkim
294249663Sjkim        for (i = 0; i < Info->ParamCount; i++)
295100966Siwasaki        {
296167802Sjkim            Status = AcpiUtCopyEobjectToIobject (
297249663Sjkim                &ExternalParams->Pointer[i], &Info->Parameters[i]);
298100966Siwasaki            if (ACPI_FAILURE (Status))
299100966Siwasaki            {
300167802Sjkim                goto Cleanup;
301100966Siwasaki            }
302100966Siwasaki        }
303249663Sjkim
304249663Sjkim        Info->Parameters[Info->ParamCount] = NULL;
305100966Siwasaki    }
306100966Siwasaki
307249663Sjkim
308306536Sjkim#ifdef _FUTURE_FEATURE
309249663Sjkim
310100966Siwasaki    /*
311249663Sjkim     * Begin incoming argument count analysis. Check for too few args
312249663Sjkim     * and too many args.
313100966Siwasaki     */
314249663Sjkim    switch (AcpiNsGetType (Info->Node))
315100966Siwasaki    {
316249663Sjkim    case ACPI_TYPE_METHOD:
317167802Sjkim
318249663Sjkim        /* Check incoming argument count against the method definition */
319249663Sjkim
320249663Sjkim        if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
321249663Sjkim        {
322249663Sjkim            ACPI_ERROR ((AE_INFO,
323249663Sjkim                "Insufficient arguments (%u) - %u are required",
324249663Sjkim                Info->ParamCount,
325249663Sjkim                Info->ObjDesc->Method.ParamCount));
326249663Sjkim
327249663Sjkim            Status = AE_MISSING_ARGUMENTS;
328249663Sjkim            goto Cleanup;
329249663Sjkim        }
330249663Sjkim
331249663Sjkim        else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
332249663Sjkim        {
333249663Sjkim            ACPI_WARNING ((AE_INFO,
334249663Sjkim                "Excess arguments (%u) - only %u are required",
335249663Sjkim                Info->ParamCount,
336249663Sjkim                Info->ObjDesc->Method.ParamCount));
337249663Sjkim
338249663Sjkim            /* Just pass the required number of arguments */
339249663Sjkim
340249663Sjkim            Info->ParamCount = Info->ObjDesc->Method.ParamCount;
341249663Sjkim        }
342249663Sjkim
343100966Siwasaki        /*
344249663Sjkim         * Any incoming external objects to be passed as arguments to the
345249663Sjkim         * method must be converted to internal objects
346100966Siwasaki         */
347249663Sjkim        if (Info->ParamCount)
348100966Siwasaki        {
349249663Sjkim            /*
350249663Sjkim             * Allocate a new parameter block for the internal objects
351249663Sjkim             * Add 1 to count to allow for null terminated internal list
352249663Sjkim             */
353249663Sjkim            Info->Parameters = ACPI_ALLOCATE_ZEROED (
354249663Sjkim                ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
355249663Sjkim            if (!Info->Parameters)
356249663Sjkim            {
357249663Sjkim                Status = AE_NO_MEMORY;
358249663Sjkim                goto Cleanup;
359249663Sjkim            }
360249663Sjkim
361249663Sjkim            /* Convert each external object in the list to an internal object */
362249663Sjkim
363249663Sjkim            for (i = 0; i < Info->ParamCount; i++)
364249663Sjkim            {
365249663Sjkim                Status = AcpiUtCopyEobjectToIobject (
366249663Sjkim                    &ExternalParams->Pointer[i], &Info->Parameters[i]);
367249663Sjkim                if (ACPI_FAILURE (Status))
368249663Sjkim                {
369249663Sjkim                    goto Cleanup;
370249663Sjkim                }
371249663Sjkim            }
372249663Sjkim
373249663Sjkim            Info->Parameters[Info->ParamCount] = NULL;
374100966Siwasaki        }
375249663Sjkim        break;
376249663Sjkim
377249663Sjkim    default:
378249663Sjkim
379249663Sjkim        /* Warn if arguments passed to an object that is not a method */
380249663Sjkim
381249663Sjkim        if (Info->ParamCount)
382100966Siwasaki        {
383249663Sjkim            ACPI_WARNING ((AE_INFO,
384249663Sjkim                "%u arguments were passed to a non-method ACPI object",
385249663Sjkim                Info->ParamCount));
386100966Siwasaki        }
387249663Sjkim        break;
388100966Siwasaki    }
389167802Sjkim
390249663Sjkim#endif
391100966Siwasaki
392249663Sjkim
393249663Sjkim    /* Now we can evaluate the object */
394249663Sjkim
395249663Sjkim    Status = AcpiNsEvaluate (Info);
396249663Sjkim
397100966Siwasaki    /*
398100966Siwasaki     * If we are expecting a return value, and all went well above,
399100966Siwasaki     * copy the return value to an external object.
400100966Siwasaki     */
401306536Sjkim    if (!ReturnBuffer)
402100966Siwasaki    {
403306536Sjkim        goto CleanupReturnObject;
404306536Sjkim    }
405100966Siwasaki
406306536Sjkim    if (!Info->ReturnObject)
407306536Sjkim    {
408306536Sjkim        ReturnBuffer->Length = 0;
409306536Sjkim        goto Cleanup;
410306536Sjkim    }
411193267Sjkim
412306536Sjkim    if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
413306536Sjkim        ACPI_DESC_TYPE_NAMED)
414306536Sjkim    {
415306536Sjkim        /*
416306536Sjkim         * If we received a NS Node as a return object, this means that
417306536Sjkim         * the object we are evaluating has nothing interesting to
418306536Sjkim         * return (such as a mutex, etc.)  We return an error because
419306536Sjkim         * these types are essentially unsupported by this interface.
420306536Sjkim         * We don't check up front because this makes it easier to add
421306536Sjkim         * support for various types at a later date if necessary.
422306536Sjkim         */
423306536Sjkim        Status = AE_TYPE;
424306536Sjkim        Info->ReturnObject = NULL;   /* No need to delete a NS Node */
425306536Sjkim        ReturnBuffer->Length = 0;
426306536Sjkim    }
427193267Sjkim
428306536Sjkim    if (ACPI_FAILURE (Status))
429306536Sjkim    {
430306536Sjkim        goto CleanupReturnObject;
431306536Sjkim    }
432167802Sjkim
433306536Sjkim    /* Dereference Index and RefOf references */
434100966Siwasaki
435306536Sjkim    AcpiNsResolveReferences (Info);
436167802Sjkim
437306536Sjkim    /* Get the size of the returned object */
438306536Sjkim
439306536Sjkim    Status = AcpiUtGetObjectSize (Info->ReturnObject,
440306536Sjkim        &BufferSpaceNeeded);
441306536Sjkim    if (ACPI_SUCCESS (Status))
442306536Sjkim    {
443306536Sjkim        /* Validate/Allocate/Clear caller buffer */
444306536Sjkim
445306536Sjkim        Status = AcpiUtInitializeBuffer (ReturnBuffer,
446306536Sjkim            BufferSpaceNeeded);
447306536Sjkim        if (ACPI_FAILURE (Status))
448306536Sjkim        {
449306536Sjkim            /*
450306536Sjkim             * Caller's buffer is too small or a new one can't
451306536Sjkim             * be allocated
452306536Sjkim             */
453306536Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
454306536Sjkim                "Needed buffer size %X, %s\n",
455306536Sjkim                (UINT32) BufferSpaceNeeded,
456306536Sjkim                AcpiFormatException (Status)));
457100966Siwasaki        }
458306536Sjkim        else
459306536Sjkim        {
460306536Sjkim            /* We have enough space for the object, build it */
461306536Sjkim
462306536Sjkim            Status = AcpiUtCopyIobjectToEobject (
463306536Sjkim                Info->ReturnObject, ReturnBuffer);
464306536Sjkim        }
465100966Siwasaki    }
466100966Siwasaki
467306536SjkimCleanupReturnObject:
468306536Sjkim
469167802Sjkim    if (Info->ReturnObject)
470100966Siwasaki    {
471129684Snjl        /*
472167802Sjkim         * Delete the internal return object. NOTE: Interpreter must be
473167802Sjkim         * locked to avoid race condition.
474100966Siwasaki         */
475167802Sjkim        AcpiExEnterInterpreter ();
476167802Sjkim
477167802Sjkim        /* Remove one reference on the return object (should delete it) */
478167802Sjkim
479167802Sjkim        AcpiUtRemoveReference (Info->ReturnObject);
480167802Sjkim        AcpiExExitInterpreter ();
481100966Siwasaki    }
482100966Siwasaki
483167802Sjkim
484167802SjkimCleanup:
485167802Sjkim
486167802Sjkim    /* Free the input parameter list (if we created one) */
487167802Sjkim
488167802Sjkim    if (Info->Parameters)
489100966Siwasaki    {
490100966Siwasaki        /* Free the allocated parameter block */
491100966Siwasaki
492167802Sjkim        AcpiUtDeleteInternalObjectList (Info->Parameters);
493100966Siwasaki    }
494100966Siwasaki
495167802Sjkim    ACPI_FREE (Info);
496100966Siwasaki    return_ACPI_STATUS (Status);
497100966Siwasaki}
498100966Siwasaki
499167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
500100966Siwasaki
501167802Sjkim
502100966Siwasaki/*******************************************************************************
503100966Siwasaki *
504193267Sjkim * FUNCTION:    AcpiNsResolveReferences
505193267Sjkim *
506193267Sjkim * PARAMETERS:  Info                    - Evaluation info block
507193267Sjkim *
508193267Sjkim * RETURN:      Info->ReturnObject is replaced with the dereferenced object
509193267Sjkim *
510193267Sjkim * DESCRIPTION: Dereference certain reference objects. Called before an
511193267Sjkim *              internal return object is converted to an external ACPI_OBJECT.
512193267Sjkim *
513193267Sjkim * Performs an automatic dereference of Index and RefOf reference objects.
514193267Sjkim * These reference objects are not supported by the ACPI_OBJECT, so this is a
515193267Sjkim * last resort effort to return something useful. Also, provides compatibility
516193267Sjkim * with other ACPI implementations.
517193267Sjkim *
518193267Sjkim * NOTE: does not handle references within returned package objects or nested
519193267Sjkim * references, but this support could be added later if found to be necessary.
520193267Sjkim *
521193267Sjkim ******************************************************************************/
522193267Sjkim
523193267Sjkimstatic void
524193267SjkimAcpiNsResolveReferences (
525193267Sjkim    ACPI_EVALUATE_INFO      *Info)
526193267Sjkim{
527193267Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
528193267Sjkim    ACPI_NAMESPACE_NODE     *Node;
529193267Sjkim
530193267Sjkim
531193267Sjkim    /* We are interested in reference objects only */
532193267Sjkim
533193267Sjkim    if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
534193267Sjkim    {
535193267Sjkim        return;
536193267Sjkim    }
537193267Sjkim
538193267Sjkim    /*
539193267Sjkim     * Two types of references are supported - those created by Index and
540193267Sjkim     * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
541193267Sjkim     * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
542193267Sjkim     * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
543193267Sjkim     * an ACPI_OBJECT.
544193267Sjkim     */
545193267Sjkim    switch (Info->ReturnObject->Reference.Class)
546193267Sjkim    {
547193267Sjkim    case ACPI_REFCLASS_INDEX:
548193267Sjkim
549193267Sjkim        ObjDesc = *(Info->ReturnObject->Reference.Where);
550193267Sjkim        break;
551193267Sjkim
552193267Sjkim    case ACPI_REFCLASS_REFOF:
553193267Sjkim
554193267Sjkim        Node = Info->ReturnObject->Reference.Object;
555193267Sjkim        if (Node)
556193267Sjkim        {
557193267Sjkim            ObjDesc = Node->Object;
558193267Sjkim        }
559193267Sjkim        break;
560193267Sjkim
561193267Sjkim    default:
562250838Sjkim
563193267Sjkim        return;
564193267Sjkim    }
565193267Sjkim
566193267Sjkim    /* Replace the existing reference object */
567193267Sjkim
568193267Sjkim    if (ObjDesc)
569193267Sjkim    {
570193267Sjkim        AcpiUtAddReference (ObjDesc);
571193267Sjkim        AcpiUtRemoveReference (Info->ReturnObject);
572193267Sjkim        Info->ReturnObject = ObjDesc;
573193267Sjkim    }
574193267Sjkim
575193267Sjkim    return;
576193267Sjkim}
577193267Sjkim
578193267Sjkim
579193267Sjkim/*******************************************************************************
580193267Sjkim *
581100966Siwasaki * FUNCTION:    AcpiWalkNamespace
582100966Siwasaki *
583100966Siwasaki * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
584100966Siwasaki *              StartObject         - Handle in namespace where search begins
585100966Siwasaki *              MaxDepth            - Depth to which search is to reach
586253690Sjkim *              DescendingCallback  - Called during tree descent
587199337Sjkim *                                    when an object of "Type" is found
588253690Sjkim *              AscendingCallback   - Called during tree ascent
589199337Sjkim *                                    when an object of "Type" is found
590199337Sjkim *              Context             - Passed to user function(s) above
591100966Siwasaki *              ReturnValue         - Location where return value of
592100966Siwasaki *                                    UserFunction is put if terminated early
593100966Siwasaki *
594100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
595100966Siwasaki *              Otherwise, returns NULL.
596100966Siwasaki *
597100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
598100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
599199337Sjkim *              The callback function is called whenever an object that matches
600199337Sjkim *              the type parameter is found. If the callback function returns
601100966Siwasaki *              a non-zero value, the search is terminated immediately and this
602100966Siwasaki *              value is returned to the caller.
603100966Siwasaki *
604100966Siwasaki *              The point of this procedure is to provide a generic namespace
605100966Siwasaki *              walk routine that can be called from multiple places to
606199337Sjkim *              provide multiple services; the callback function(s) can be
607199337Sjkim *              tailored to each task, whether it is a print function,
608199337Sjkim *              a compare function, etc.
609100966Siwasaki *
610100966Siwasaki ******************************************************************************/
611100966Siwasaki
612100966SiwasakiACPI_STATUS
613100966SiwasakiAcpiWalkNamespace (
614100966Siwasaki    ACPI_OBJECT_TYPE        Type,
615100966Siwasaki    ACPI_HANDLE             StartObject,
616100966Siwasaki    UINT32                  MaxDepth,
617253690Sjkim    ACPI_WALK_CALLBACK      DescendingCallback,
618253690Sjkim    ACPI_WALK_CALLBACK      AscendingCallback,
619100966Siwasaki    void                    *Context,
620100966Siwasaki    void                    **ReturnValue)
621100966Siwasaki{
622100966Siwasaki    ACPI_STATUS             Status;
623100966Siwasaki
624100966Siwasaki
625167802Sjkim    ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
626100966Siwasaki
627100966Siwasaki
628100966Siwasaki    /* Parameter validation */
629100966Siwasaki
630167802Sjkim    if ((Type > ACPI_TYPE_LOCAL_MAX) ||
631167802Sjkim        (!MaxDepth)                  ||
632253690Sjkim        (!DescendingCallback && !AscendingCallback))
633100966Siwasaki    {
634100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
635100966Siwasaki    }
636100966Siwasaki
637100966Siwasaki    /*
638193267Sjkim     * Need to acquire the namespace reader lock to prevent interference
639193267Sjkim     * with any concurrent table unloads (which causes the deletion of
640193267Sjkim     * namespace objects). We cannot allow the deletion of a namespace node
641193267Sjkim     * while the user function is using it. The exception to this are the
642193267Sjkim     * nodes created and deleted during control method execution -- these
643193267Sjkim     * nodes are marked as temporary nodes and are ignored by the namespace
644193267Sjkim     * walk. Thus, control methods can be executed while holding the
645193267Sjkim     * namespace deletion lock (and the user function can execute control
646193267Sjkim     * methods.)
647100966Siwasaki     */
648193267Sjkim    Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
649193267Sjkim    if (ACPI_FAILURE (Status))
650193267Sjkim    {
651241973Sjkim        return_ACPI_STATUS (Status);
652193267Sjkim    }
653193267Sjkim
654193267Sjkim    /*
655193267Sjkim     * Lock the namespace around the walk. The namespace will be
656193267Sjkim     * unlocked/locked around each call to the user function - since the user
657193267Sjkim     * function must be allowed to make ACPICA calls itself (for example, it
658193267Sjkim     * will typically execute control methods during device enumeration.)
659193267Sjkim     */
660100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
661100966Siwasaki    if (ACPI_FAILURE (Status))
662100966Siwasaki    {
663193267Sjkim        goto UnlockAndExit;
664100966Siwasaki    }
665100966Siwasaki
666254745Sjkim    /* Now we can validate the starting node */
667254745Sjkim
668254745Sjkim    if (!AcpiNsValidateHandle (StartObject))
669254745Sjkim    {
670254745Sjkim        Status = AE_BAD_PARAMETER;
671254745Sjkim        goto UnlockAndExit2;
672254745Sjkim    }
673254745Sjkim
674151937Sjkim    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
675306536Sjkim        ACPI_NS_WALK_UNLOCK, DescendingCallback,
676306536Sjkim        AscendingCallback, Context, ReturnValue);
677100966Siwasaki
678254745SjkimUnlockAndExit2:
679100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
680193267Sjkim
681193267SjkimUnlockAndExit:
682193267Sjkim    (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
683100966Siwasaki    return_ACPI_STATUS (Status);
684100966Siwasaki}
685100966Siwasaki
686167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
687100966Siwasaki
688167802Sjkim
689100966Siwasaki/*******************************************************************************
690100966Siwasaki *
691100966Siwasaki * FUNCTION:    AcpiNsGetDeviceCallback
692100966Siwasaki *
693100966Siwasaki * PARAMETERS:  Callback from AcpiGetDevice
694100966Siwasaki *
695100966Siwasaki * RETURN:      Status
696100966Siwasaki *
697100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
698100966Siwasaki *              present devices, or if they specified a HID, it filters based
699100966Siwasaki *              on that.
700100966Siwasaki *
701100966Siwasaki ******************************************************************************/
702100966Siwasaki
703100966Siwasakistatic ACPI_STATUS
704100966SiwasakiAcpiNsGetDeviceCallback (
705100966Siwasaki    ACPI_HANDLE             ObjHandle,
706100966Siwasaki    UINT32                  NestingLevel,
707100966Siwasaki    void                    *Context,
708100966Siwasaki    void                    **ReturnValue)
709100966Siwasaki{
710117521Snjl    ACPI_GET_DEVICES_INFO   *Info = Context;
711100966Siwasaki    ACPI_STATUS             Status;
712100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
713100966Siwasaki    UINT32                  Flags;
714241973Sjkim    ACPI_PNP_DEVICE_ID      *Hid;
715241973Sjkim    ACPI_PNP_DEVICE_ID_LIST *Cid;
716193267Sjkim    UINT32                  i;
717193267Sjkim    BOOLEAN                 Found;
718197104Sjkim    int                     NoMatch;
719100966Siwasaki
720100966Siwasaki
721100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
722100966Siwasaki    if (ACPI_FAILURE (Status))
723100966Siwasaki    {
724100966Siwasaki        return (Status);
725100966Siwasaki    }
726100966Siwasaki
727200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
728100966Siwasaki    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
729100966Siwasaki    if (ACPI_FAILURE (Status))
730100966Siwasaki    {
731100966Siwasaki        return (Status);
732100966Siwasaki    }
733100966Siwasaki
734100966Siwasaki    if (!Node)
735100966Siwasaki    {
736100966Siwasaki        return (AE_BAD_PARAMETER);
737100966Siwasaki    }
738100966Siwasaki
739202771Sjkim    /*
740202771Sjkim     * First, filter based on the device HID and CID.
741202771Sjkim     *
742202771Sjkim     * 01/2010: For this case where a specific HID is requested, we don't
743202771Sjkim     * want to run _STA until we have an actual HID match. Thus, we will
744202771Sjkim     * not unnecessarily execute _STA on devices for which the caller
745202771Sjkim     * doesn't care about. Previously, _STA was executed unconditionally
746202771Sjkim     * on all devices found here.
747202771Sjkim     *
748202771Sjkim     * A side-effect of this change is that now we will continue to search
749202771Sjkim     * for a matching HID even under device trees where the parent device
750202771Sjkim     * would have returned a _STA that indicates it is not present or
751202771Sjkim     * not functioning (thus aborting the search on that branch).
752202771Sjkim     */
753100966Siwasaki    if (Info->Hid != NULL)
754100966Siwasaki    {
755100966Siwasaki        Status = AcpiUtExecute_HID (Node, &Hid);
756100966Siwasaki        if (Status == AE_NOT_FOUND)
757100966Siwasaki        {
758100966Siwasaki            return (AE_OK);
759100966Siwasaki        }
760100966Siwasaki        else if (ACPI_FAILURE (Status))
761100966Siwasaki        {
762100966Siwasaki            return (AE_CTRL_DEPTH);
763100966Siwasaki        }
764100966Siwasaki
765306536Sjkim        NoMatch = strcmp (Hid->String, Info->Hid);
766197104Sjkim        ACPI_FREE (Hid);
767197104Sjkim
768197104Sjkim        if (NoMatch)
769100966Siwasaki        {
770193267Sjkim            /*
771193267Sjkim             * HID does not match, attempt match within the
772193267Sjkim             * list of Compatible IDs (CIDs)
773193267Sjkim             */
774100966Siwasaki            Status = AcpiUtExecute_CID (Node, &Cid);
775100966Siwasaki            if (Status == AE_NOT_FOUND)
776100966Siwasaki            {
777100966Siwasaki                return (AE_OK);
778100966Siwasaki            }
779100966Siwasaki            else if (ACPI_FAILURE (Status))
780100966Siwasaki            {
781100966Siwasaki                return (AE_CTRL_DEPTH);
782100966Siwasaki            }
783100966Siwasaki
784117521Snjl            /* Walk the CID list */
785100966Siwasaki
786193267Sjkim            Found = FALSE;
787117521Snjl            for (i = 0; i < Cid->Count; i++)
788100966Siwasaki            {
789306536Sjkim                if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
790117521Snjl                {
791193267Sjkim                    /* Found a matching CID */
792193267Sjkim
793193267Sjkim                    Found = TRUE;
794193267Sjkim                    break;
795117521Snjl                }
796100966Siwasaki            }
797193267Sjkim
798167802Sjkim            ACPI_FREE (Cid);
799193267Sjkim            if (!Found)
800193267Sjkim            {
801193267Sjkim                return (AE_OK);
802193267Sjkim            }
803100966Siwasaki        }
804100966Siwasaki    }
805100966Siwasaki
806202771Sjkim    /* Run _STA to determine if device is present */
807202771Sjkim
808202771Sjkim    Status = AcpiUtExecute_STA (Node, &Flags);
809202771Sjkim    if (ACPI_FAILURE (Status))
810202771Sjkim    {
811202771Sjkim        return (AE_CTRL_DEPTH);
812202771Sjkim    }
813202771Sjkim
814202771Sjkim    if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
815202771Sjkim        !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
816202771Sjkim    {
817202771Sjkim        /*
818202771Sjkim         * Don't examine the children of the device only when the
819202771Sjkim         * device is neither present nor functional. See ACPI spec,
820202771Sjkim         * description of _STA for more information.
821202771Sjkim         */
822202771Sjkim        return (AE_CTRL_DEPTH);
823202771Sjkim    }
824202771Sjkim
825193267Sjkim    /* We have a valid device, invoke the user function */
826193267Sjkim
827306536Sjkim    Status = Info->UserFunction (ObjHandle, NestingLevel,
828306536Sjkim        Info->Context, ReturnValue);
829100966Siwasaki    return (Status);
830100966Siwasaki}
831100966Siwasaki
832100966Siwasaki
833100966Siwasaki/*******************************************************************************
834100966Siwasaki *
835100966Siwasaki * FUNCTION:    AcpiGetDevices
836100966Siwasaki *
837100966Siwasaki * PARAMETERS:  HID                 - HID to search for. Can be NULL.
838100966Siwasaki *              UserFunction        - Called when a matching object is found
839100966Siwasaki *              Context             - Passed to user function
840100966Siwasaki *              ReturnValue         - Location where return value of
841100966Siwasaki *                                    UserFunction is put if terminated early
842100966Siwasaki *
843100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
844100966Siwasaki *              Otherwise, returns NULL.
845100966Siwasaki *
846100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
847100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
848117521Snjl *              The UserFunction is called whenever an object of type
849241973Sjkim *              Device is found. If the user function returns
850100966Siwasaki *              a non-zero value, the search is terminated immediately and this
851100966Siwasaki *              value is returned to the caller.
852100966Siwasaki *
853100966Siwasaki *              This is a wrapper for WalkNamespace, but the callback performs
854193267Sjkim *              additional filtering. Please see AcpiNsGetDeviceCallback.
855100966Siwasaki *
856100966Siwasaki ******************************************************************************/
857100966Siwasaki
858100966SiwasakiACPI_STATUS
859100966SiwasakiAcpiGetDevices (
860114237Snjl    char                    *HID,
861100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
862100966Siwasaki    void                    *Context,
863100966Siwasaki    void                    **ReturnValue)
864100966Siwasaki{
865100966Siwasaki    ACPI_STATUS             Status;
866100966Siwasaki    ACPI_GET_DEVICES_INFO   Info;
867100966Siwasaki
868100966Siwasaki
869167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetDevices);
870100966Siwasaki
871100966Siwasaki
872100966Siwasaki    /* Parameter validation */
873100966Siwasaki
874100966Siwasaki    if (!UserFunction)
875100966Siwasaki    {
876100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
877100966Siwasaki    }
878100966Siwasaki
879100966Siwasaki    /*
880100966Siwasaki     * We're going to call their callback from OUR callback, so we need
881100966Siwasaki     * to know what it is, and their context parameter.
882100966Siwasaki     */
883306536Sjkim    Info.Hid = HID;
884306536Sjkim    Info.Context = Context;
885100966Siwasaki    Info.UserFunction = UserFunction;
886100966Siwasaki
887100966Siwasaki    /*
888100966Siwasaki     * Lock the namespace around the walk.
889100966Siwasaki     * The namespace will be unlocked/locked around each call
890100966Siwasaki     * to the user function - since this function
891100966Siwasaki     * must be allowed to make Acpi calls itself.
892100966Siwasaki     */
893100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
894100966Siwasaki    if (ACPI_FAILURE (Status))
895100966Siwasaki    {
896100966Siwasaki        return_ACPI_STATUS (Status);
897100966Siwasaki    }
898100966Siwasaki
899167802Sjkim    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
900306536Sjkim        ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
901306536Sjkim        AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
902100966Siwasaki
903100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
904100966Siwasaki    return_ACPI_STATUS (Status);
905100966Siwasaki}
906100966Siwasaki
907167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices)
908100966Siwasaki
909167802Sjkim
910100966Siwasaki/*******************************************************************************
911100966Siwasaki *
912100966Siwasaki * FUNCTION:    AcpiAttachData
913100966Siwasaki *
914114237Snjl * PARAMETERS:  ObjHandle           - Namespace node
915107325Siwasaki *              Handler             - Handler for this attachment
916107325Siwasaki *              Data                - Pointer to data to be attached
917100966Siwasaki *
918100966Siwasaki * RETURN:      Status
919100966Siwasaki *
920107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
921100966Siwasaki *
922100966Siwasaki ******************************************************************************/
923100966Siwasaki
924100966SiwasakiACPI_STATUS
925100966SiwasakiAcpiAttachData (
926100966Siwasaki    ACPI_HANDLE             ObjHandle,
927100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
928100966Siwasaki    void                    *Data)
929100966Siwasaki{
930100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
931100966Siwasaki    ACPI_STATUS             Status;
932100966Siwasaki
933100966Siwasaki
934100966Siwasaki    /* Parameter validation */
935100966Siwasaki
936100966Siwasaki    if (!ObjHandle  ||
937100966Siwasaki        !Handler    ||
938100966Siwasaki        !Data)
939100966Siwasaki    {
940100966Siwasaki        return (AE_BAD_PARAMETER);
941100966Siwasaki    }
942100966Siwasaki
943100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
944100966Siwasaki    if (ACPI_FAILURE (Status))
945100966Siwasaki    {
946100966Siwasaki        return (Status);
947100966Siwasaki    }
948100966Siwasaki
949100966Siwasaki    /* Convert and validate the handle */
950100966Siwasaki
951200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
952100966Siwasaki    if (!Node)
953100966Siwasaki    {
954100966Siwasaki        Status = AE_BAD_PARAMETER;
955100966Siwasaki        goto UnlockAndExit;
956100966Siwasaki    }
957100966Siwasaki
958100966Siwasaki    Status = AcpiNsAttachData (Node, Handler, Data);
959100966Siwasaki
960100966SiwasakiUnlockAndExit:
961100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
962100966Siwasaki    return (Status);
963100966Siwasaki}
964100966Siwasaki
965167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData)
966100966Siwasaki
967167802Sjkim
968100966Siwasaki/*******************************************************************************
969100966Siwasaki *
970100966Siwasaki * FUNCTION:    AcpiDetachData
971100966Siwasaki *
972107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node handle
973107325Siwasaki *              Handler             - Handler used in call to AcpiAttachData
974100966Siwasaki *
975100966Siwasaki * RETURN:      Status
976100966Siwasaki *
977107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node.
978100966Siwasaki *
979100966Siwasaki ******************************************************************************/
980100966Siwasaki
981100966SiwasakiACPI_STATUS
982100966SiwasakiAcpiDetachData (
983100966Siwasaki    ACPI_HANDLE             ObjHandle,
984100966Siwasaki    ACPI_OBJECT_HANDLER     Handler)
985100966Siwasaki{
986100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
987100966Siwasaki    ACPI_STATUS             Status;
988100966Siwasaki
989100966Siwasaki
990100966Siwasaki    /* Parameter validation */
991100966Siwasaki
992100966Siwasaki    if (!ObjHandle  ||
993100966Siwasaki        !Handler)
994100966Siwasaki    {
995100966Siwasaki        return (AE_BAD_PARAMETER);
996100966Siwasaki    }
997100966Siwasaki
998100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
999100966Siwasaki    if (ACPI_FAILURE (Status))
1000100966Siwasaki    {
1001100966Siwasaki        return (Status);
1002100966Siwasaki    }
1003100966Siwasaki
1004100966Siwasaki    /* Convert and validate the handle */
1005100966Siwasaki
1006200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
1007100966Siwasaki    if (!Node)
1008100966Siwasaki    {
1009100966Siwasaki        Status = AE_BAD_PARAMETER;
1010100966Siwasaki        goto UnlockAndExit;
1011100966Siwasaki    }
1012100966Siwasaki
1013100966Siwasaki    Status = AcpiNsDetachData (Node, Handler);
1014100966Siwasaki
1015100966SiwasakiUnlockAndExit:
1016100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1017100966Siwasaki    return (Status);
1018100966Siwasaki}
1019100966Siwasaki
1020167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData)
1021100966Siwasaki
1022167802Sjkim
1023100966Siwasaki/*******************************************************************************
1024100966Siwasaki *
1025100966Siwasaki * FUNCTION:    AcpiGetData
1026100966Siwasaki *
1027107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node
1028107325Siwasaki *              Handler             - Handler used in call to AttachData
1029107325Siwasaki *              Data                - Where the data is returned
1030100966Siwasaki *
1031100966Siwasaki * RETURN:      Status
1032100966Siwasaki *
1033107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
1034100966Siwasaki *
1035100966Siwasaki ******************************************************************************/
1036100966Siwasaki
1037100966SiwasakiACPI_STATUS
1038100966SiwasakiAcpiGetData (
1039100966Siwasaki    ACPI_HANDLE             ObjHandle,
1040100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
1041100966Siwasaki    void                    **Data)
1042100966Siwasaki{
1043100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
1044100966Siwasaki    ACPI_STATUS             Status;
1045100966Siwasaki
1046100966Siwasaki
1047100966Siwasaki    /* Parameter validation */
1048100966Siwasaki
1049100966Siwasaki    if (!ObjHandle  ||
1050100966Siwasaki        !Handler    ||
1051100966Siwasaki        !Data)
1052100966Siwasaki    {
1053100966Siwasaki        return (AE_BAD_PARAMETER);
1054100966Siwasaki    }
1055100966Siwasaki
1056100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1057100966Siwasaki    if (ACPI_FAILURE (Status))
1058100966Siwasaki    {
1059100966Siwasaki        return (Status);
1060100966Siwasaki    }
1061100966Siwasaki
1062100966Siwasaki    /* Convert and validate the handle */
1063100966Siwasaki
1064200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
1065100966Siwasaki    if (!Node)
1066100966Siwasaki    {
1067100966Siwasaki        Status = AE_BAD_PARAMETER;
1068100966Siwasaki        goto UnlockAndExit;
1069100966Siwasaki    }
1070100966Siwasaki
1071100966Siwasaki    Status = AcpiNsGetAttachedData (Node, Handler, Data);
1072100966Siwasaki
1073100966SiwasakiUnlockAndExit:
1074100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1075100966Siwasaki    return (Status);
1076100966Siwasaki}
1077100966Siwasaki
1078167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData)
1079