nsxfobj.c revision 91116
133965Sjdp/*******************************************************************************
278828Sobrien *
3218822Sdim * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
438889Sjdp *                         ACPI Object oriented interfaces
533965Sjdp *              $Revision: 108 $
633965Sjdp *
791041Sobrien ******************************************************************************/
833965Sjdp
991041Sobrien/******************************************************************************
1091041Sobrien *
1191041Sobrien * 1. Copyright Notice
1291041Sobrien *
1333965Sjdp * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
1491041Sobrien * All rights reserved.
1591041Sobrien *
1691041Sobrien * 2. License
1791041Sobrien *
1833965Sjdp * 2.1. This is your license from Intel Corp. under its intellectual property
1991041Sobrien * rights.  You may have additional license terms from the party that provided
2091041Sobrien * you this software, covering your right to use that party's intellectual
21218822Sdim * property rights.
2233965Sjdp *
23218822Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2433965Sjdp * copy of the source code appearing in this file ("Covered Code") an
2533965Sjdp * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2633965Sjdp * base code distributed originally by Intel ("Original Intel Code") to copy,
2733965Sjdp * make derivatives, distribute, use and display any portion of the Covered
2833965Sjdp * Code in any form, with the right to sublicense such rights; and
2933965Sjdp *
3033965Sjdp * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3133965Sjdp * license (with the right to sublicense), under only those claims of Intel
3233965Sjdp * patents that are infringed by the Original Intel Code, to make, use, sell,
33218822Sdim * offer to sell, and import the Covered Code and derivative works thereof
34218822Sdim * solely to the minimum extent necessary to exercise the above copyright
35218822Sdim * license, and in no event shall the patent license extend to any additions
3633965Sjdp * to or modifications of the Original Intel Code.  No other license or right
3733965Sjdp * is granted directly or by implication, estoppel or otherwise;
3833965Sjdp *
3933965Sjdp * The above copyright and patent license is granted only if the following
4033965Sjdp * conditions are met:
4133965Sjdp *
4233965Sjdp * 3. Conditions
4333965Sjdp *
4433965Sjdp * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4533965Sjdp * Redistribution of source code of any substantial portion of the Covered
4633965Sjdp * Code or modification with rights to further distribute source must include
47130561Sobrien * the above Copyright Notice, the above License, this list of Conditions,
48130561Sobrien * and the following Disclaimer and Export Compliance provision.  In addition,
4933965Sjdp * Licensee must cause all Covered Code to which Licensee contributes to
5033965Sjdp * contain a file documenting the changes Licensee made to create that Covered
51130561Sobrien * Code and the date of any change.  Licensee must include in that file the
5233965Sjdp * documentation of any changes made by any predecessor Licensee.  Licensee
5333965Sjdp * must include a prominent statement that the modification is derived,
5433965Sjdp * directly or indirectly, from Original Intel Code.
5533965Sjdp *
5633965Sjdp * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57130561Sobrien * Redistribution of source code of any substantial portion of the Covered
58130561Sobrien * Code or modification without rights to further distribute source must
5933965Sjdp * include the following Disclaimer and Export Compliance provision in the
60130561Sobrien * documentation and/or other materials provided with distribution.  In
6133965Sjdp * addition, Licensee may not authorize further sublicense of source of any
6233965Sjdp * portion of the Covered Code, and must include terms to the effect that the
6333965Sjdp * license from Licensee to its licensee is limited to the intellectual
6433965Sjdp * property embodied in the software Licensee provides to its licensee, and
6533965Sjdp * not to intellectual property embodied in modifications its licensee may
66130561Sobrien * make.
67130561Sobrien *
6833965Sjdp * 3.3. Redistribution of Executable. Redistribution in executable form of any
6933965Sjdp * substantial portion of the Covered Code or modification must reproduce the
7033965Sjdp * above Copyright Notice, and the following Disclaimer and Export Compliance
7133965Sjdp * provision in the documentation and/or other materials provided with the
7233965Sjdp * distribution.
7377298Sobrien *
74130561Sobrien * 3.4. Intel retains all right, title, and interest in and to the Original
7533965Sjdp * Intel Code.
7633965Sjdp *
7733965Sjdp * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7833965Sjdp * Intel shall be used in advertising or otherwise to promote the sale, use or
7977298Sobrien * other dealings in products derived from or relating to the Covered Code
80130561Sobrien * without prior written authorization from Intel.
8133965Sjdp *
8233965Sjdp * 4. Disclaimer and Export Compliance
8333965Sjdp *
8433965Sjdp * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8533965Sjdp * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86130561Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8733965Sjdp * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8833965Sjdp * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8933965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
9033965Sjdp * PARTICULAR PURPOSE.
9133965Sjdp *
9233965Sjdp * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9333965Sjdp * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9433965Sjdp * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95130561Sobrien * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9633965Sjdp * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9733965Sjdp * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9833965Sjdp * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9933965Sjdp * LIMITED REMEDY.
10033965Sjdp *
10177298Sobrien * 4.3. Licensee shall not export, either directly or indirectly, any of this
102130561Sobrien * software or system incorporating such software without first obtaining any
10333965Sjdp * required license or other approval from the U. S. Department of Commerce or
10433965Sjdp * any other agency or department of the United States Government.  In the
10533965Sjdp * event Licensee exports any such software from the United States or
106218822Sdim * re-exports any such software from a foreign destination, Licensee shall
107218822Sdim * ensure that the distribution and export/re-export of the software is in
108218822Sdim * compliance with all laws, regulations, orders, or other restrictions of the
109218822Sdim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110218822Sdim * any of its subsidiaries will export/re-export any technical data, process,
111218822Sdim * software, or service, directly or indirectly, to any country for which the
112218822Sdim * United States government or any agency thereof requires an export license,
113218822Sdim * other governmental approval, or letter of assurance, without first obtaining
114218822Sdim * such license, approval or letter.
115218822Sdim *
116218822Sdim *****************************************************************************/
117218822Sdim
118218822Sdim
119218822Sdim#define __NSXFOBJ_C__
120218822Sdim
121218822Sdim#include "acpi.h"
122218822Sdim#include "acinterp.h"
123130561Sobrien#include "acnamesp.h"
124130561Sobrien#include "acdispat.h"
125130561Sobrien
126130561Sobrien
12733965Sjdp#define _COMPONENT          ACPI_NAMESPACE
12833965Sjdp        ACPI_MODULE_NAME    ("nsxfobj")
129130561Sobrien
13033965Sjdp
13133965Sjdp/*******************************************************************************
13233965Sjdp *
13333965Sjdp * FUNCTION:    AcpiEvaluateObject
13433965Sjdp *
13533965Sjdp * PARAMETERS:  Handle              - Object handle (optional)
136130561Sobrien *              *Pathname           - Object pathname (optional)
13733965Sjdp *              **ExternalParams    - List of parameters to pass to method,
13833965Sjdp *                                    terminated by NULL.  May be NULL
139130561Sobrien *                                    if no parameters are being passed.
14033965Sjdp *              *ReturnBuffer       - Where to put method's return value (if
14133965Sjdp *                                    any).  If NULL, no value is returned.
14233965Sjdp *
14333965Sjdp * RETURN:      Status
14433965Sjdp *
14533965Sjdp * DESCRIPTION: Find and evaluate the given object, passing the given
146130561Sobrien *              parameters if necessary.  One of "Handle" or "Pathname" must
14733965Sjdp *              be valid (non-null)
14833965Sjdp *
14933965Sjdp ******************************************************************************/
15033965Sjdp
15133965SjdpACPI_STATUS
15233965SjdpAcpiEvaluateObject (
153130561Sobrien    ACPI_HANDLE             Handle,
15433965Sjdp    ACPI_STRING             Pathname,
15533965Sjdp    ACPI_OBJECT_LIST        *ExternalParams,
15633965Sjdp    ACPI_BUFFER             *ReturnBuffer)
15733965Sjdp{
15833965Sjdp    ACPI_STATUS             Status;
15933965Sjdp    ACPI_OPERAND_OBJECT     **InternalParams = NULL;
16033965Sjdp    ACPI_OPERAND_OBJECT     *InternalReturnObj = NULL;
161130561Sobrien    ACPI_SIZE               BufferSpaceNeeded;
162130561Sobrien    UINT32                  i;
16333965Sjdp
164130561Sobrien
16533965Sjdp    ACPI_FUNCTION_TRACE ("AcpiEvaluateObject");
16689857Sobrien
16789857Sobrien
16889857Sobrien    /*
16989857Sobrien     * If there are parameters to be passed to the object
17089857Sobrien     * (which must be a control method), the external objects
17189857Sobrien     * must be converted to internal objects
172130561Sobrien     */
17389857Sobrien    if (ExternalParams && ExternalParams->Count)
17433965Sjdp    {
17589857Sobrien        /*
17633965Sjdp         * Allocate a new parameter block for the internal objects
17733965Sjdp         * Add 1 to count to allow for null terminated internal list
17833965Sjdp         */
179218822Sdim        InternalParams = ACPI_MEM_CALLOCATE ((ExternalParams->Count + 1) *
180218822Sdim                                                sizeof (void *));
181218822Sdim        if (!InternalParams)
182218822Sdim        {
183218822Sdim            return_ACPI_STATUS (AE_NO_MEMORY);
184218822Sdim        }
185218822Sdim
186218822Sdim        /*
187218822Sdim         * Convert each external object in the list to an
188218822Sdim         * internal object
189218822Sdim         */
190218822Sdim        for (i = 0; i < ExternalParams->Count; i++)
191218822Sdim        {
192218822Sdim            Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i],
193218822Sdim                                                &InternalParams[i]);
194218822Sdim            if (ACPI_FAILURE (Status))
195218822Sdim            {
196218822Sdim                AcpiUtDeleteInternalObjectList (InternalParams);
197218822Sdim                return_ACPI_STATUS (Status);
198218822Sdim            }
199218822Sdim        }
200218822Sdim        InternalParams[ExternalParams->Count] = NULL;
201218822Sdim    }
202218822Sdim
203218822Sdim    /*
204218822Sdim     * Three major cases:
205218822Sdim     * 1) Fully qualified pathname
206218822Sdim     * 2) No handle, not fully qualified pathname (error)
207218822Sdim     * 3) Valid handle
208218822Sdim     */
20933965Sjdp    if ((Pathname) &&
21033965Sjdp        (AcpiNsValidRootPrefix (Pathname[0])))
211130561Sobrien    {
212130561Sobrien        /*
21333965Sjdp         *  The path is fully qualified, just evaluate by name
214130561Sobrien         */
21533965Sjdp        Status = AcpiNsEvaluateByName (Pathname, InternalParams,
21689857Sobrien                    &InternalReturnObj);
21789857Sobrien    }
21889857Sobrien    else if (!Handle)
21989857Sobrien    {
22089857Sobrien        /*
22189857Sobrien         * A handle is optional iff a fully qualified pathname
22233965Sjdp         * is specified.  Since we've already handled fully
223130561Sobrien         * qualified names above, this is an error
22433965Sjdp         */
225130561Sobrien        if (!Pathname)
22633965Sjdp        {
22789857Sobrien            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
22833965Sjdp                "Both Handle and Pathname are NULL\n"));
22933965Sjdp        }
23033965Sjdp        else
23133965Sjdp        {
23233965Sjdp            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
233218822Sdim                "Handle is NULL and Pathname is relative\n"));
234218822Sdim        }
235218822Sdim
236218822Sdim        Status = AE_BAD_PARAMETER;
237218822Sdim    }
238218822Sdim    else
239218822Sdim    {
240218822Sdim        /*
241218822Sdim         * We get here if we have a handle -- and if we have a
242218822Sdim         * pathname it is relative.  The handle will be validated
243218822Sdim         * in the lower procedures
244218822Sdim         */
245218822Sdim        if (!Pathname)
246218822Sdim        {
247218822Sdim            /*
248218822Sdim             * The null pathname case means the handle is for
249218822Sdim             * the actual object to be evaluated
250218822Sdim             */
251218822Sdim            Status = AcpiNsEvaluateByHandle (Handle, InternalParams,
252218822Sdim                            &InternalReturnObj);
253218822Sdim        }
254218822Sdim        else
255218822Sdim        {
256218822Sdim           /*
257218822Sdim            * Both a Handle and a relative Pathname
258218822Sdim            */
259218822Sdim            Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams,
260218822Sdim                            &InternalReturnObj);
261218822Sdim        }
262218822Sdim    }
263218822Sdim
264218822Sdim
265218822Sdim    /*
266218822Sdim     * If we are expecting a return value, and all went well above,
26733965Sjdp     * copy the return value to an external object.
26833965Sjdp     */
269130561Sobrien    if (ReturnBuffer)
270130561Sobrien    {
27133965Sjdp        if (!InternalReturnObj)
272130561Sobrien        {
27333965Sjdp            ReturnBuffer->Length = 0;
27489857Sobrien        }
27589857Sobrien        else
27689857Sobrien        {
27789857Sobrien            if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED)
27889857Sobrien            {
27933965Sjdp                /*
280130561Sobrien                 * If we received a NS Node as a return object, this means that
28189857Sobrien                 * the object we are evaluating has nothing interesting to
28289857Sobrien                 * return (such as a mutex, etc.)  We return an error because
28333965Sjdp                 * these types are essentially unsupported by this interface.
28433965Sjdp                 * We don't check up front because this makes it easier to add
28533965Sjdp                 * support for various types at a later date if necessary.
28633965Sjdp                 */
28789857Sobrien                Status = AE_TYPE;
28833965Sjdp                InternalReturnObj = NULL;   /* No need to delete a NS Node */
28933965Sjdp                ReturnBuffer->Length = 0;
29033965Sjdp            }
29133965Sjdp
292218822Sdim            if (ACPI_SUCCESS (Status))
293218822Sdim            {
294218822Sdim                /*
295218822Sdim                 * Find out how large a buffer is needed
296218822Sdim                 * to contain the returned object
297218822Sdim                 */
298218822Sdim                Status = AcpiUtGetObjectSize (InternalReturnObj,
299218822Sdim                                                &BufferSpaceNeeded);
300218822Sdim                if (ACPI_SUCCESS (Status))
301218822Sdim                {
302218822Sdim                    /* Validate/Allocate/Clear caller buffer */
303218822Sdim
304218822Sdim                    Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded);
305218822Sdim                    if (ACPI_FAILURE (Status))
306218822Sdim                    {
307218822Sdim                        /*
308218822Sdim                         * Caller's buffer is too small or a new one can't be allocated
309218822Sdim                         */
310218822Sdim                        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
311218822Sdim                            "Needed buffer size %X, %s\n",
312218822Sdim                            BufferSpaceNeeded, AcpiFormatException (Status)));
313218822Sdim                    }
314218822Sdim                    else
315218822Sdim                    {
316218822Sdim                        /*
317218822Sdim                         *  We have enough space for the object, build it
318218822Sdim                         */
319218822Sdim                        Status = AcpiUtCopyIobjectToEobject (InternalReturnObj,
320218822Sdim                                        ReturnBuffer);
321218822Sdim                    }
322218822Sdim                }
323218822Sdim            }
324218822Sdim        }
325218822Sdim    }
326218822Sdim
327218822Sdim    /* Delete the return and parameter objects */
328218822Sdim
329218822Sdim    if (InternalReturnObj)
33033965Sjdp    {
33133965Sjdp        /*
33233965Sjdp         * Delete the internal return object. (Or at least
33333965Sjdp         * decrement the reference count by one)
33433965Sjdp         */
335130561Sobrien        AcpiUtRemoveReference (InternalReturnObj);
33633965Sjdp    }
33733965Sjdp
33833965Sjdp    /*
33933965Sjdp     * Free the input parameter list (if we created one),
34033965Sjdp     */
34133965Sjdp    if (InternalParams)
34233965Sjdp    {
343130561Sobrien        /* Free the allocated parameter block */
344130561Sobrien
34533965Sjdp        AcpiUtDeleteInternalObjectList (InternalParams);
34633965Sjdp    }
34789857Sobrien
348130561Sobrien    return_ACPI_STATUS (Status);
34933965Sjdp}
35033965Sjdp
35133965Sjdp
35233965Sjdp/*******************************************************************************
35333965Sjdp *
35433965Sjdp * FUNCTION:    AcpiGetNextObject
35533965Sjdp *
35633965Sjdp * PARAMETERS:  Type            - Type of object to be searched for
35733965Sjdp *              Parent          - Parent object whose children we are getting
35833965Sjdp *              LastChild       - Previous child that was found.
35933965Sjdp *                                The NEXT child will be returned
36077298Sobrien *              RetHandle       - Where handle to the next object is placed
36133965Sjdp *
36233965Sjdp * RETURN:      Status
36333965Sjdp *
36433965Sjdp * DESCRIPTION: Return the next peer object within the namespace.  If Handle is
36533965Sjdp *              valid, Scope is ignored.  Otherwise, the first object within
36633965Sjdp *              Scope is returned.
36733965Sjdp *
36833965Sjdp ******************************************************************************/
36933965Sjdp
37033965SjdpACPI_STATUS
37133965SjdpAcpiGetNextObject (
37233965Sjdp    ACPI_OBJECT_TYPE        Type,
37333965Sjdp    ACPI_HANDLE             Parent,
37433965Sjdp    ACPI_HANDLE             Child,
37533965Sjdp    ACPI_HANDLE             *RetHandle)
37633965Sjdp{
37733965Sjdp    ACPI_STATUS             Status;
37833965Sjdp    ACPI_NAMESPACE_NODE     *Node;
37933965Sjdp    ACPI_NAMESPACE_NODE     *ParentNode = NULL;
38033965Sjdp    ACPI_NAMESPACE_NODE     *ChildNode = NULL;
38133965Sjdp
38233965Sjdp
38333965Sjdp    /* Parameter validation */
38433965Sjdp
38533965Sjdp    if (Type > ACPI_TYPE_MAX)
38633965Sjdp    {
38733965Sjdp        return (AE_BAD_PARAMETER);
38833965Sjdp    }
38933965Sjdp
39033965Sjdp    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
391130561Sobrien    if (ACPI_FAILURE (Status))
39233965Sjdp    {
393130561Sobrien        return (Status);
39433965Sjdp    }
395130561Sobrien
39633965Sjdp    /* If null handle, use the parent */
397130561Sobrien
39833965Sjdp    if (!Child)
39933965Sjdp    {
400130561Sobrien        /* Start search at the beginning of the specified scope */
40133965Sjdp
402130561Sobrien        ParentNode = AcpiNsMapHandleToNode (Parent);
40333965Sjdp        if (!ParentNode)
404130561Sobrien        {
40533965Sjdp            Status = AE_BAD_PARAMETER;
406130561Sobrien            goto UnlockAndExit;
40733965Sjdp        }
40833965Sjdp    }
409130561Sobrien    else
41033965Sjdp    {
411130561Sobrien        /* Non-null handle, ignore the parent */
41233965Sjdp        /* Convert and validate the handle */
413130561Sobrien
41433965Sjdp        ChildNode = AcpiNsMapHandleToNode (Child);
415130561Sobrien        if (!ChildNode)
41633965Sjdp        {
41733965Sjdp            Status = AE_BAD_PARAMETER;
418130561Sobrien            goto UnlockAndExit;
41933965Sjdp        }
420130561Sobrien    }
42133965Sjdp
422130561Sobrien    /* Internal function does the real work */
42333965Sjdp
424130561Sobrien    Node = AcpiNsGetNextNode (Type, ParentNode, ChildNode);
42533965Sjdp    if (!Node)
426130561Sobrien    {
427130561Sobrien        Status = AE_NOT_FOUND;
428130561Sobrien        goto UnlockAndExit;
429130561Sobrien    }
430130561Sobrien
431130561Sobrien    if (RetHandle)
43260484Sobrien    {
433130561Sobrien        *RetHandle = AcpiNsConvertEntryToHandle (Node);
434130561Sobrien    }
435130561Sobrien
436130561Sobrien
437130561SobrienUnlockAndExit:
438130561Sobrien
43960484Sobrien    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
44077298Sobrien    return (Status);
44133965Sjdp}
44233965Sjdp
44333965Sjdp
44433965Sjdp/*******************************************************************************
44533965Sjdp *
44633965Sjdp * FUNCTION:    AcpiGetType
44733965Sjdp *
44833965Sjdp * PARAMETERS:  Handle          - Handle of object whose type is desired
44989857Sobrien *              *RetType        - Where the type will be placed
45033965Sjdp *
45133965Sjdp * RETURN:      Status
45233965Sjdp *
45333965Sjdp * DESCRIPTION: This routine returns the type associatd with a particular handle
45433965Sjdp *
45533965Sjdp ******************************************************************************/
45633965Sjdp
45789857SobrienACPI_STATUS
45833965SjdpAcpiGetType (
45989857Sobrien    ACPI_HANDLE             Handle,
46033965Sjdp    ACPI_OBJECT_TYPE        *RetType)
46189857Sobrien{
46233965Sjdp    ACPI_NAMESPACE_NODE     *Node;
46389857Sobrien    ACPI_STATUS             Status;
46433965Sjdp
46533965Sjdp
46689857Sobrien    /* Parameter Validation */
46733965Sjdp
46889857Sobrien    if (!RetType)
46933965Sjdp    {
47089857Sobrien        return (AE_BAD_PARAMETER);
47133965Sjdp    }
47289857Sobrien
47333965Sjdp    /*
47433965Sjdp     * Special case for the predefined Root Node
47589857Sobrien     * (return type ANY)
47633965Sjdp     */
47789857Sobrien    if (Handle == ACPI_ROOT_OBJECT)
47833965Sjdp    {
47989857Sobrien        *RetType = ACPI_TYPE_ANY;
48033965Sjdp        return (AE_OK);
48189857Sobrien    }
48233965Sjdp
48333965Sjdp    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
48489857Sobrien    if (ACPI_FAILURE (Status))
48533965Sjdp    {
48689857Sobrien        return (Status);
48733965Sjdp    }
48889857Sobrien
48933965Sjdp    /* Convert and validate the handle */
49089857Sobrien
49133965Sjdp    Node = AcpiNsMapHandleToNode (Handle);
492130561Sobrien    if (!Node)
49389857Sobrien    {
494130561Sobrien        (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
495130561Sobrien        return (AE_BAD_PARAMETER);
496130561Sobrien    }
497130561Sobrien
498130561Sobrien    *RetType = Node->Type;
499130561Sobrien
500130561Sobrien
501130561Sobrien    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
502130561Sobrien    return (Status);
503130561Sobrien}
504130561Sobrien
505130561Sobrien
506130561Sobrien/*******************************************************************************
507130561Sobrien *
508130561Sobrien * FUNCTION:    AcpiGetParent
509130561Sobrien *
51089857Sobrien * PARAMETERS:  Handle          - Handle of object whose parent is desired
51189857Sobrien *              RetHandle       - Where the parent handle will be placed
51233965Sjdp *
51333965Sjdp * RETURN:      Status
51433965Sjdp *
515130561Sobrien * DESCRIPTION: Returns a handle to the parent of the object represented by
516130561Sobrien *              Handle.
51733965Sjdp *
518130561Sobrien ******************************************************************************/
51933965Sjdp
52033965SjdpACPI_STATUS
521130561SobrienAcpiGetParent (
52233965Sjdp    ACPI_HANDLE             Handle,
523130561Sobrien    ACPI_HANDLE             *RetHandle)
52433965Sjdp{
52533965Sjdp    ACPI_NAMESPACE_NODE     *Node;
52633965Sjdp    ACPI_STATUS             Status;
52733965Sjdp
528130561Sobrien
52933965Sjdp    if (!RetHandle)
530130561Sobrien    {
53133965Sjdp        return (AE_BAD_PARAMETER);
53233965Sjdp    }
53333965Sjdp
53433965Sjdp    /* Special case for the predefined Root Node (no parent) */
535130561Sobrien
53633965Sjdp    if (Handle == ACPI_ROOT_OBJECT)
537130561Sobrien    {
538130561Sobrien        return (AE_NULL_ENTRY);
53933965Sjdp    }
54033965Sjdp
54133965Sjdp    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
542130561Sobrien    if (ACPI_FAILURE (Status))
54333965Sjdp    {
544130561Sobrien        return (Status);
545130561Sobrien    }
54633965Sjdp
54733965Sjdp    /* Convert and validate the handle */
54833965Sjdp
549130561Sobrien    Node = AcpiNsMapHandleToNode (Handle);
55033965Sjdp    if (!Node)
551130561Sobrien    {
552130561Sobrien        Status = AE_BAD_PARAMETER;
553130561Sobrien        goto UnlockAndExit;
55433965Sjdp    }
55533965Sjdp
55633965Sjdp    /* Get the parent entry */
557130561Sobrien
55833965Sjdp    *RetHandle =
559130561Sobrien        AcpiNsConvertEntryToHandle (AcpiNsGetParentNode (Node));
560130561Sobrien
561130561Sobrien    /* Return exeption if parent is null */
56233965Sjdp
56333965Sjdp    if (!AcpiNsGetParentNode (Node))
56433965Sjdp    {
565130561Sobrien        Status = AE_NULL_ENTRY;
56633965Sjdp    }
567130561Sobrien
56860484Sobrien
56960484SobrienUnlockAndExit:
57060484Sobrien
57160484Sobrien    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
57260484Sobrien    return (Status);
57360484Sobrien}
574130561Sobrien
57533965Sjdp
57633965Sjdp/*******************************************************************************
57733965Sjdp *
578130561Sobrien * FUNCTION:    AcpiWalkNamespace
57933965Sjdp *
580130561Sobrien * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
58160484Sobrien *              StartObject         - Handle in namespace where search begins
58260484Sobrien *              MaxDepth            - Depth to which search is to reach
58360484Sobrien *              UserFunction        - Called when an object of "Type" is found
58460484Sobrien *              Context             - Passed to user function
58560484Sobrien *              ReturnValue         - Location where return value of
58660484Sobrien *                                    UserFunction is put if terminated early
587130561Sobrien *
58833965Sjdp * RETURNS      Return value from the UserFunction if terminated early.
58933965Sjdp *              Otherwise, returns NULL.
59033965Sjdp *
591130561Sobrien * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
59233965Sjdp *              starting (and ending) at the object specified by StartHandle.
593130561Sobrien *              The UserFunction is called whenever an object that matches
59460484Sobrien *              the type parameter is found.  If the user function returns
59560484Sobrien *              a non-zero value, the search is terminated immediately and this
59660484Sobrien *              value is returned to the caller.
59760484Sobrien *
59860484Sobrien *              The point of this procedure is to provide a generic namespace
59960484Sobrien *              walk routine that can be called from multiple places to
60060484Sobrien *              provide multiple services;  the User Function can be tailored
60133965Sjdp *              to each task, whether it is a print function, a compare
60233965Sjdp *              function, etc.
60333965Sjdp *
604130561Sobrien ******************************************************************************/
60533965Sjdp
606130561SobrienACPI_STATUS
60760484SobrienAcpiWalkNamespace (
60860484Sobrien    ACPI_OBJECT_TYPE        Type,
60960484Sobrien    ACPI_HANDLE             StartObject,
61060484Sobrien    UINT32                  MaxDepth,
61160484Sobrien    ACPI_WALK_CALLBACK      UserFunction,
61260484Sobrien    void                    *Context,
61360484Sobrien    void                    **ReturnValue)
61433965Sjdp{
61533965Sjdp    ACPI_STATUS             Status;
616130561Sobrien
617130561Sobrien
61833965Sjdp    ACPI_FUNCTION_TRACE ("AcpiWalkNamespace");
619130561Sobrien
620130561Sobrien
621130561Sobrien    /* Parameter validation */
62233965Sjdp
623130561Sobrien    if ((Type > ACPI_TYPE_MAX)  ||
624130561Sobrien        (!MaxDepth)             ||
625130561Sobrien        (!UserFunction))
626130561Sobrien    {
627130561Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
628130561Sobrien    }
629130561Sobrien
630130561Sobrien    /*
63133965Sjdp     * Lock the namespace around the walk.
632130561Sobrien     * The namespace will be unlocked/locked around each call
63333965Sjdp     * to the user function - since this function
63433965Sjdp     * must be allowed to make Acpi calls itself.
63533965Sjdp     */
63633965Sjdp    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
63733965Sjdp    if (ACPI_FAILURE (Status))
63833965Sjdp    {
639130561Sobrien        return_ACPI_STATUS (Status);
640130561Sobrien    }
64133965Sjdp
642130561Sobrien    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK,
643130561Sobrien                    UserFunction, Context, ReturnValue);
644130561Sobrien
64533965Sjdp    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
646130561Sobrien    return_ACPI_STATUS (Status);
647130561Sobrien}
648130561Sobrien
649130561Sobrien
650130561Sobrien/*******************************************************************************
651130561Sobrien *
652130561Sobrien * FUNCTION:    AcpiNsGetDeviceCallback
653130561Sobrien *
65433965Sjdp * PARAMETERS:  Callback from AcpiGetDevice
655130561Sobrien *
65633965Sjdp * RETURN:      Status
65733965Sjdp *
65833965Sjdp * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
65933965Sjdp *              present devices, or if they specified a HID, it filters based
66033965Sjdp *              on that.
66133965Sjdp *
66233965Sjdp ******************************************************************************/
663130561Sobrien
664130561Sobrienstatic ACPI_STATUS
66533965SjdpAcpiNsGetDeviceCallback (
666130561Sobrien    ACPI_HANDLE             ObjHandle,
667130561Sobrien    UINT32                  NestingLevel,
668130561Sobrien    void                    *Context,
66933965Sjdp    void                    **ReturnValue)
670130561Sobrien{
671130561Sobrien    ACPI_STATUS             Status;
672130561Sobrien    ACPI_NAMESPACE_NODE     *Node;
673130561Sobrien    UINT32                  Flags;
674130561Sobrien    ACPI_DEVICE_ID          Hid;
675130561Sobrien    ACPI_DEVICE_ID          Cid;
676130561Sobrien    ACPI_GET_DEVICES_INFO   *Info;
677130561Sobrien
67833965Sjdp
679130561Sobrien    Info = Context;
68033965Sjdp
68133965Sjdp    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
68233965Sjdp    if (ACPI_FAILURE (Status))
68333965Sjdp    {
68433965Sjdp        return (Status);
68533965Sjdp    }
686130561Sobrien
687130561Sobrien    Node = AcpiNsMapHandleToNode (ObjHandle);
68833965Sjdp    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
689130561Sobrien    if (ACPI_FAILURE (Status))
690130561Sobrien    {
691130561Sobrien        return (Status);
69233965Sjdp    }
693130561Sobrien
694130561Sobrien    if (!Node)
695130561Sobrien    {
696130561Sobrien        return (AE_BAD_PARAMETER);
697130561Sobrien    }
698130561Sobrien
699130561Sobrien    /*
700130561Sobrien     * Run _STA to determine if device is present
70133965Sjdp     */
702130561Sobrien    Status = AcpiUtExecute_STA (Node, &Flags);
70333965Sjdp    if (ACPI_FAILURE (Status))
70433965Sjdp    {
70533965Sjdp        return (AE_CTRL_DEPTH);
70633965Sjdp    }
70733965Sjdp
70833965Sjdp    if (!(Flags & 0x01))
70933965Sjdp    {
710130561Sobrien        /* Don't return at the device or children of the device if not there */
71133965Sjdp        return (AE_CTRL_DEPTH);
712130561Sobrien    }
713130561Sobrien
714130561Sobrien    /*
715130561Sobrien     * Filter based on device HID & CID
716130561Sobrien     */
71733965Sjdp    if (Info->Hid != NULL)
71833965Sjdp    {
71933965Sjdp        Status = AcpiUtExecute_HID (Node, &Hid);
720130561Sobrien        if (Status == AE_NOT_FOUND)
72133965Sjdp        {
722130561Sobrien            return (AE_OK);
723130561Sobrien        }
724130561Sobrien        else if (ACPI_FAILURE (Status))
725130561Sobrien        {
726130561Sobrien            return (AE_CTRL_DEPTH);
72733965Sjdp        }
72833965Sjdp
72933965Sjdp        if (ACPI_STRNCMP (Hid.Buffer, Info->Hid, sizeof (Hid.Buffer)) != 0)
730130561Sobrien        {
73133965Sjdp            Status = AcpiUtExecute_CID (Node, &Cid);
732130561Sobrien            if (Status == AE_NOT_FOUND)
733130561Sobrien            {
734130561Sobrien                return (AE_OK);
735130561Sobrien            }
736130561Sobrien            else if (ACPI_FAILURE (Status))
737130561Sobrien            {
738130561Sobrien                return (AE_CTRL_DEPTH);
739130561Sobrien            }
740130561Sobrien
741130561Sobrien            /* TBD: Handle CID packages */
74233965Sjdp
74333965Sjdp            if (ACPI_STRNCMP (Cid.Buffer, Info->Hid, sizeof (Cid.Buffer)) != 0)
74433965Sjdp            {
74533965Sjdp                return (AE_OK);
74633965Sjdp            }
74733965Sjdp        }
748130561Sobrien    }
74933965Sjdp
750130561Sobrien    Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue);
751130561Sobrien    return (AE_OK);
752130561Sobrien}
753130561Sobrien
754130561Sobrien
755130561Sobrien/*******************************************************************************
756130561Sobrien *
757130561Sobrien * FUNCTION:    AcpiGetDevices
758130561Sobrien *
759130561Sobrien * PARAMETERS:  HID                 - HID to search for. Can be NULL.
76033965Sjdp *              UserFunction        - Called when a matching object is found
76133965Sjdp *              Context             - Passed to user function
76233965Sjdp *              ReturnValue         - Location where return value of
76333965Sjdp *                                    UserFunction is put if terminated early
76477298Sobrien *
76577298Sobrien * RETURNS      Return value from the UserFunction if terminated early.
766130561Sobrien *              Otherwise, returns NULL.
76777298Sobrien *
768130561Sobrien * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
76977298Sobrien *              starting (and ending) at the object specified by StartHandle.
77077298Sobrien *              The UserFunction is called whenever an object that matches
77177298Sobrien *              the type parameter is found.  If the user function returns
77277298Sobrien *              a non-zero value, the search is terminated immediately and this
77377298Sobrien *              value is returned to the caller.
77477298Sobrien *
77577298Sobrien *              This is a wrapper for WalkNamespace, but the callback performs
77677298Sobrien *              additional filtering. Please see AcpiGetDeviceCallback.
77777298Sobrien *
77877298Sobrien ******************************************************************************/
77977298Sobrien
780130561SobrienACPI_STATUS
78177298SobrienAcpiGetDevices (
78277298Sobrien    NATIVE_CHAR             *HID,
78377298Sobrien    ACPI_WALK_CALLBACK      UserFunction,
78477298Sobrien    void                    *Context,
785130561Sobrien    void                    **ReturnValue)
786130561Sobrien{
78777298Sobrien    ACPI_STATUS             Status;
788130561Sobrien    ACPI_GET_DEVICES_INFO   Info;
789130561Sobrien
79077298Sobrien
79177298Sobrien    ACPI_FUNCTION_TRACE ("AcpiGetDevices");
79277298Sobrien
79377298Sobrien
79477298Sobrien    /* Parameter validation */
79577298Sobrien
79677298Sobrien    if (!UserFunction)
79777298Sobrien    {
79877298Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
79977298Sobrien    }
80077298Sobrien
80177298Sobrien    /*
80277298Sobrien     * We're going to call their callback from OUR callback, so we need
80377298Sobrien     * to know what it is, and their context parameter.
80477298Sobrien     */
80577298Sobrien    Info.Context      = Context;
80677298Sobrien    Info.UserFunction = UserFunction;
80733965Sjdp    Info.Hid          = HID;
80833965Sjdp
80933965Sjdp    /*
810130561Sobrien     * Lock the namespace around the walk.
811130561Sobrien     * The namespace will be unlocked/locked around each call
812130561Sobrien     * to the user function - since this function
813130561Sobrien     * must be allowed to make Acpi calls itself.
814130561Sobrien     */
815130561Sobrien    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
81633965Sjdp    if (ACPI_FAILURE (Status))
817218822Sdim    {
81860484Sobrien        return_ACPI_STATUS (Status);
819130561Sobrien    }
82060484Sobrien
821218822Sdim    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE,
822218822Sdim                                    ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
82360484Sobrien                                    ACPI_NS_WALK_UNLOCK,
82460484Sobrien                                    AcpiNsGetDeviceCallback, &Info,
825130561Sobrien                                    ReturnValue);
82660484Sobrien
82760484Sobrien    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
82860484Sobrien    return_ACPI_STATUS (Status);
82989857Sobrien}
830130561Sobrien
83160484Sobrien
832130561Sobrien/*******************************************************************************
83333965Sjdp *
83433965Sjdp * FUNCTION:    AcpiAttachData
835130561Sobrien *
836130561Sobrien * PARAMETERS:
837130561Sobrien *
838130561Sobrien * RETURN:      Status
839130561Sobrien *
840130561Sobrien * DESCRIPTION:
841130561Sobrien *
84233965Sjdp ******************************************************************************/
84333965Sjdp
844218822SdimACPI_STATUS
845218822SdimAcpiAttachData (
84633965Sjdp    ACPI_HANDLE             ObjHandle,
847130561Sobrien    ACPI_OBJECT_HANDLER     Handler,
848130561Sobrien    void                    *Data)
849130561Sobrien{
85033965Sjdp    ACPI_NAMESPACE_NODE     *Node;
85133965Sjdp    ACPI_STATUS             Status;
85233965Sjdp
85333965Sjdp
85433965Sjdp    /* Parameter validation */
85533965Sjdp
85633965Sjdp    if (!ObjHandle  ||
857130561Sobrien        !Handler    ||
85833965Sjdp        !Data)
859130561Sobrien    {
860130561Sobrien        return (AE_BAD_PARAMETER);
86133965Sjdp    }
86233965Sjdp
86333965Sjdp    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
86433965Sjdp    if (ACPI_FAILURE (Status))
865130561Sobrien    {
86633965Sjdp        return (Status);
86733965Sjdp    }
86833965Sjdp
86933965Sjdp    /* Convert and validate the handle */
87033965Sjdp
87133965Sjdp    Node = AcpiNsMapHandleToNode (ObjHandle);
87233965Sjdp    if (!Node)
873218822Sdim    {
874218822Sdim        Status = AE_BAD_PARAMETER;
875104834Sobrien        goto UnlockAndExit;
876130561Sobrien    }
877130561Sobrien
878130561Sobrien    Status = AcpiNsAttachData (Node, Handler, Data);
87933965Sjdp
88033965SjdpUnlockAndExit:
88133965Sjdp    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
88233965Sjdp    return (Status);
88333965Sjdp}
88433965Sjdp
88533965Sjdp
88633965Sjdp/*******************************************************************************
88733965Sjdp *
888130561Sobrien * FUNCTION:    AcpiDetachData
889130561Sobrien *
890130561Sobrien * PARAMETERS:
891130561Sobrien *
892130561Sobrien * RETURN:      Status
893130561Sobrien *
89433965Sjdp * DESCRIPTION:
89533965Sjdp *
896130561Sobrien ******************************************************************************/
89733965Sjdp
89889857SobrienACPI_STATUS
89989857SobrienAcpiDetachData (
900130561Sobrien    ACPI_HANDLE             ObjHandle,
90133965Sjdp    ACPI_OBJECT_HANDLER     Handler)
902130561Sobrien{
90333965Sjdp    ACPI_NAMESPACE_NODE     *Node;
90433965Sjdp    ACPI_STATUS             Status;
90533965Sjdp
90633965Sjdp
90733965Sjdp    /* Parameter validation */
90833965Sjdp
90933965Sjdp    if (!ObjHandle  ||
91089857Sobrien        !Handler)
91133965Sjdp    {
91233965Sjdp        return (AE_BAD_PARAMETER);
91333965Sjdp    }
91489857Sobrien
91533965Sjdp    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
91633965Sjdp    if (ACPI_FAILURE (Status))
91760484Sobrien    {
918130561Sobrien        return (Status);
91933965Sjdp    }
92060484Sobrien
92160484Sobrien    /* Convert and validate the handle */
92260484Sobrien
92360484Sobrien    Node = AcpiNsMapHandleToNode (ObjHandle);
92433965Sjdp    if (!Node)
92533965Sjdp    {
92633965Sjdp        Status = AE_BAD_PARAMETER;
927130561Sobrien        goto UnlockAndExit;
928130561Sobrien    }
92933965Sjdp
93033965Sjdp    Status = AcpiNsDetachData (Node, Handler);
93133965Sjdp
932130561SobrienUnlockAndExit:
93333965Sjdp    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
93433965Sjdp    return (Status);
93560484Sobrien}
93660484Sobrien
937130561Sobrien
938130561Sobrien/*******************************************************************************
939130561Sobrien *
94060484Sobrien * FUNCTION:    AcpiGetData
94160484Sobrien *
94277298Sobrien * PARAMETERS:
94360484Sobrien *
94460484Sobrien * RETURN:      Status
94577298Sobrien *
94660484Sobrien * DESCRIPTION:
94777298Sobrien *
948218822Sdim ******************************************************************************/
94977298Sobrien
950218822SdimACPI_STATUS
95177298SobrienAcpiGetData (
952218822Sdim    ACPI_HANDLE             ObjHandle,
95377298Sobrien    ACPI_OBJECT_HANDLER     Handler,
95460484Sobrien    void                    **Data)
955130561Sobrien{
95660484Sobrien    ACPI_NAMESPACE_NODE     *Node;
95760484Sobrien    ACPI_STATUS             Status;
958130561Sobrien
95960484Sobrien
96089857Sobrien    /* Parameter validation */
96189857Sobrien
96289857Sobrien    if (!ObjHandle  ||
96391041Sobrien        !Handler    ||
96489857Sobrien        !Data)
965130561Sobrien    {
966130561Sobrien        return (AE_BAD_PARAMETER);
967130561Sobrien    }
968130561Sobrien
96989857Sobrien    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
97089857Sobrien    if (ACPI_FAILURE (Status))
97189857Sobrien    {
97289857Sobrien        return (Status);
97389857Sobrien    }
97489857Sobrien
975130561Sobrien    /* Convert and validate the handle */
97691041Sobrien
97789857Sobrien    Node = AcpiNsMapHandleToNode (ObjHandle);
97891041Sobrien    if (!Node)
97991041Sobrien    {
98089857Sobrien        Status = AE_BAD_PARAMETER;
98191041Sobrien        goto UnlockAndExit;
98289857Sobrien    }
98389857Sobrien
98489857Sobrien    Status = AcpiNsGetAttachedData (Node, Handler, Data);
985218822Sdim
986218822SdimUnlockAndExit:
987218822Sdim    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
988218822Sdim    return (Status);
989218822Sdim}
990218822Sdim
991218822Sdim
992218822Sdim