nsxfobj.c revision 91116
167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
467754Smsmith *                         ACPI Object oriented interfaces
591116Smsmith *              $Revision: 108 $
667754Smsmith *
767754Smsmith ******************************************************************************/
867754Smsmith
967754Smsmith/******************************************************************************
1067754Smsmith *
1167754Smsmith * 1. Copyright Notice
1267754Smsmith *
1391116Smsmith * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
1470243Smsmith * All rights reserved.
1567754Smsmith *
1667754Smsmith * 2. License
1767754Smsmith *
1867754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1967754Smsmith * rights.  You may have additional license terms from the party that provided
2067754Smsmith * you this software, covering your right to use that party's intellectual
2167754Smsmith * property rights.
2267754Smsmith *
2367754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2467754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2567754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2667754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2767754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2867754Smsmith * Code in any form, with the right to sublicense such rights; and
2967754Smsmith *
3067754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3167754Smsmith * license (with the right to sublicense), under only those claims of Intel
3267754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3367754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3467754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3567754Smsmith * license, and in no event shall the patent license extend to any additions
3667754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3767754Smsmith * is granted directly or by implication, estoppel or otherwise;
3867754Smsmith *
3967754Smsmith * The above copyright and patent license is granted only if the following
4067754Smsmith * conditions are met:
4167754Smsmith *
4267754Smsmith * 3. Conditions
4367754Smsmith *
4467754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4567754Smsmith * Redistribution of source code of any substantial portion of the Covered
4667754Smsmith * Code or modification with rights to further distribute source must include
4767754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4867754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4967754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
5067754Smsmith * contain a file documenting the changes Licensee made to create that Covered
5167754Smsmith * Code and the date of any change.  Licensee must include in that file the
5267754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5367754Smsmith * must include a prominent statement that the modification is derived,
5467754Smsmith * directly or indirectly, from Original Intel Code.
5567754Smsmith *
5667754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5767754Smsmith * Redistribution of source code of any substantial portion of the Covered
5867754Smsmith * Code or modification without rights to further distribute source must
5967754Smsmith * include the following Disclaimer and Export Compliance provision in the
6067754Smsmith * documentation and/or other materials provided with distribution.  In
6167754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6267754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6367754Smsmith * license from Licensee to its licensee is limited to the intellectual
6467754Smsmith * property embodied in the software Licensee provides to its licensee, and
6567754Smsmith * not to intellectual property embodied in modifications its licensee may
6667754Smsmith * make.
6767754Smsmith *
6867754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6967754Smsmith * substantial portion of the Covered Code or modification must reproduce the
7067754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
7167754Smsmith * provision in the documentation and/or other materials provided with the
7267754Smsmith * distribution.
7367754Smsmith *
7467754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7567754Smsmith * Intel Code.
7667754Smsmith *
7767754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7867754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7967754Smsmith * other dealings in products derived from or relating to the Covered Code
8067754Smsmith * without prior written authorization from Intel.
8167754Smsmith *
8267754Smsmith * 4. Disclaimer and Export Compliance
8367754Smsmith *
8467754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8567754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8667754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8767754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8867754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8967754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
9067754Smsmith * PARTICULAR PURPOSE.
9167754Smsmith *
9267754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9367754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9467754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9567754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9667754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9767754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9867754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9967754Smsmith * LIMITED REMEDY.
10067754Smsmith *
10167754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10267754Smsmith * software or system incorporating such software without first obtaining any
10367754Smsmith * required license or other approval from the U. S. Department of Commerce or
10467754Smsmith * any other agency or department of the United States Government.  In the
10567754Smsmith * event Licensee exports any such software from the United States or
10667754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10767754Smsmith * ensure that the distribution and export/re-export of the software is in
10867754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10967754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
11067754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
11167754Smsmith * software, or service, directly or indirectly, to any country for which the
11267754Smsmith * United States government or any agency thereof requires an export license,
11367754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11467754Smsmith * such license, approval or letter.
11567754Smsmith *
11667754Smsmith *****************************************************************************/
11767754Smsmith
11867754Smsmith
11967754Smsmith#define __NSXFOBJ_C__
12067754Smsmith
12167754Smsmith#include "acpi.h"
12267754Smsmith#include "acinterp.h"
12367754Smsmith#include "acnamesp.h"
12467754Smsmith#include "acdispat.h"
12567754Smsmith
12667754Smsmith
12777424Smsmith#define _COMPONENT          ACPI_NAMESPACE
12891116Smsmith        ACPI_MODULE_NAME    ("nsxfobj")
12967754Smsmith
13067754Smsmith
13167754Smsmith/*******************************************************************************
13267754Smsmith *
13367754Smsmith * FUNCTION:    AcpiEvaluateObject
13467754Smsmith *
13567754Smsmith * PARAMETERS:  Handle              - Object handle (optional)
13667754Smsmith *              *Pathname           - Object pathname (optional)
13787031Smsmith *              **ExternalParams    - List of parameters to pass to method,
13884491Smsmith *                                    terminated by NULL.  May be NULL
13984491Smsmith *                                    if no parameters are being passed.
14084491Smsmith *              *ReturnBuffer       - Where to put method's return value (if
14167754Smsmith *                                    any).  If NULL, no value is returned.
14267754Smsmith *
14367754Smsmith * RETURN:      Status
14467754Smsmith *
14567754Smsmith * DESCRIPTION: Find and evaluate the given object, passing the given
14667754Smsmith *              parameters if necessary.  One of "Handle" or "Pathname" must
14767754Smsmith *              be valid (non-null)
14867754Smsmith *
14967754Smsmith ******************************************************************************/
15067754Smsmith
15167754SmsmithACPI_STATUS
15267754SmsmithAcpiEvaluateObject (
15367754Smsmith    ACPI_HANDLE             Handle,
15467754Smsmith    ACPI_STRING             Pathname,
15584491Smsmith    ACPI_OBJECT_LIST        *ExternalParams,
15667754Smsmith    ACPI_BUFFER             *ReturnBuffer)
15767754Smsmith{
15867754Smsmith    ACPI_STATUS             Status;
15984491Smsmith    ACPI_OPERAND_OBJECT     **InternalParams = NULL;
16084491Smsmith    ACPI_OPERAND_OBJECT     *InternalReturnObj = NULL;
16191116Smsmith    ACPI_SIZE               BufferSpaceNeeded;
16267754Smsmith    UINT32                  i;
16367754Smsmith
16467754Smsmith
16591116Smsmith    ACPI_FUNCTION_TRACE ("AcpiEvaluateObject");
16667754Smsmith
16767754Smsmith
16867754Smsmith    /*
16967754Smsmith     * If there are parameters to be passed to the object
17067754Smsmith     * (which must be a control method), the external objects
17167754Smsmith     * must be converted to internal objects
17267754Smsmith     */
17384491Smsmith    if (ExternalParams && ExternalParams->Count)
17467754Smsmith    {
17567754Smsmith        /*
17667754Smsmith         * Allocate a new parameter block for the internal objects
17767754Smsmith         * Add 1 to count to allow for null terminated internal list
17867754Smsmith         */
17991116Smsmith        InternalParams = ACPI_MEM_CALLOCATE ((ExternalParams->Count + 1) *
18091116Smsmith                                                sizeof (void *));
18184491Smsmith        if (!InternalParams)
18267754Smsmith        {
18367754Smsmith            return_ACPI_STATUS (AE_NO_MEMORY);
18467754Smsmith        }
18567754Smsmith
18667754Smsmith        /*
18767754Smsmith         * Convert each external object in the list to an
18867754Smsmith         * internal object
18967754Smsmith         */
19084491Smsmith        for (i = 0; i < ExternalParams->Count; i++)
19167754Smsmith        {
19284491Smsmith            Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i],
19384491Smsmith                                                &InternalParams[i]);
19467754Smsmith            if (ACPI_FAILURE (Status))
19567754Smsmith            {
19684491Smsmith                AcpiUtDeleteInternalObjectList (InternalParams);
19767754Smsmith                return_ACPI_STATUS (Status);
19867754Smsmith            }
19967754Smsmith        }
20084491Smsmith        InternalParams[ExternalParams->Count] = NULL;
20167754Smsmith    }
20267754Smsmith
20367754Smsmith    /*
20467754Smsmith     * Three major cases:
20567754Smsmith     * 1) Fully qualified pathname
20667754Smsmith     * 2) No handle, not fully qualified pathname (error)
20767754Smsmith     * 3) Valid handle
20867754Smsmith     */
20967754Smsmith    if ((Pathname) &&
21067754Smsmith        (AcpiNsValidRootPrefix (Pathname[0])))
21167754Smsmith    {
21267754Smsmith        /*
21367754Smsmith         *  The path is fully qualified, just evaluate by name
21467754Smsmith         */
21591116Smsmith        Status = AcpiNsEvaluateByName (Pathname, InternalParams,
21691116Smsmith                    &InternalReturnObj);
21767754Smsmith    }
21867754Smsmith    else if (!Handle)
21967754Smsmith    {
22067754Smsmith        /*
22167754Smsmith         * A handle is optional iff a fully qualified pathname
22267754Smsmith         * is specified.  Since we've already handled fully
22367754Smsmith         * qualified names above, this is an error
22467754Smsmith         */
22567754Smsmith        if (!Pathname)
22667754Smsmith        {
22791116Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
22891116Smsmith                "Both Handle and Pathname are NULL\n"));
22967754Smsmith        }
23067754Smsmith        else
23167754Smsmith        {
23291116Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
23391116Smsmith                "Handle is NULL and Pathname is relative\n"));
23467754Smsmith        }
23567754Smsmith
23667754Smsmith        Status = AE_BAD_PARAMETER;
23767754Smsmith    }
23867754Smsmith    else
23967754Smsmith    {
24067754Smsmith        /*
24167754Smsmith         * We get here if we have a handle -- and if we have a
24267754Smsmith         * pathname it is relative.  The handle will be validated
24367754Smsmith         * in the lower procedures
24467754Smsmith         */
24567754Smsmith        if (!Pathname)
24667754Smsmith        {
24767754Smsmith            /*
24867754Smsmith             * The null pathname case means the handle is for
24967754Smsmith             * the actual object to be evaluated
25067754Smsmith             */
25191116Smsmith            Status = AcpiNsEvaluateByHandle (Handle, InternalParams,
25291116Smsmith                            &InternalReturnObj);
25367754Smsmith        }
25467754Smsmith        else
25567754Smsmith        {
25667754Smsmith           /*
25767754Smsmith            * Both a Handle and a relative Pathname
25867754Smsmith            */
25984491Smsmith            Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams,
26091116Smsmith                            &InternalReturnObj);
26167754Smsmith        }
26267754Smsmith    }
26367754Smsmith
26467754Smsmith
26567754Smsmith    /*
26667754Smsmith     * If we are expecting a return value, and all went well above,
26767754Smsmith     * copy the return value to an external object.
26867754Smsmith     */
26967754Smsmith    if (ReturnBuffer)
27067754Smsmith    {
27191116Smsmith        if (!InternalReturnObj)
27267754Smsmith        {
27391116Smsmith            ReturnBuffer->Length = 0;
27491116Smsmith        }
27591116Smsmith        else
27691116Smsmith        {
27791116Smsmith            if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED)
27867754Smsmith            {
27967754Smsmith                /*
28091116Smsmith                 * If we received a NS Node as a return object, this means that
28191116Smsmith                 * the object we are evaluating has nothing interesting to
28291116Smsmith                 * return (such as a mutex, etc.)  We return an error because
28391116Smsmith                 * these types are essentially unsupported by this interface.
28491116Smsmith                 * We don't check up front because this makes it easier to add
28591116Smsmith                 * support for various types at a later date if necessary.
28667754Smsmith                 */
28767754Smsmith                Status = AE_TYPE;
28891116Smsmith                InternalReturnObj = NULL;   /* No need to delete a NS Node */
28991116Smsmith                ReturnBuffer->Length = 0;
29067754Smsmith            }
29167754Smsmith
29267754Smsmith            if (ACPI_SUCCESS (Status))
29367754Smsmith            {
29467754Smsmith                /*
29567754Smsmith                 * Find out how large a buffer is needed
29667754Smsmith                 * to contain the returned object
29767754Smsmith                 */
29884491Smsmith                Status = AcpiUtGetObjectSize (InternalReturnObj,
29967754Smsmith                                                &BufferSpaceNeeded);
30067754Smsmith                if (ACPI_SUCCESS (Status))
30167754Smsmith                {
30291116Smsmith                    /* Validate/Allocate/Clear caller buffer */
30391116Smsmith
30491116Smsmith                    Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded);
30591116Smsmith                    if (ACPI_FAILURE (Status))
30667754Smsmith                    {
30767754Smsmith                        /*
30891116Smsmith                         * Caller's buffer is too small or a new one can't be allocated
30967754Smsmith                         */
31082367Smsmith                        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
31191116Smsmith                            "Needed buffer size %X, %s\n",
31291116Smsmith                            BufferSpaceNeeded, AcpiFormatException (Status)));
31367754Smsmith                    }
31467754Smsmith                    else
31567754Smsmith                    {
31667754Smsmith                        /*
31767754Smsmith                         *  We have enough space for the object, build it
31867754Smsmith                         */
31984491Smsmith                        Status = AcpiUtCopyIobjectToEobject (InternalReturnObj,
32067754Smsmith                                        ReturnBuffer);
32167754Smsmith                    }
32267754Smsmith                }
32367754Smsmith            }
32467754Smsmith        }
32567754Smsmith    }
32667754Smsmith
32767754Smsmith    /* Delete the return and parameter objects */
32867754Smsmith
32984491Smsmith    if (InternalReturnObj)
33067754Smsmith    {
33167754Smsmith        /*
33267754Smsmith         * Delete the internal return object. (Or at least
33367754Smsmith         * decrement the reference count by one)
33467754Smsmith         */
33584491Smsmith        AcpiUtRemoveReference (InternalReturnObj);
33667754Smsmith    }
33767754Smsmith
33867754Smsmith    /*
33967754Smsmith     * Free the input parameter list (if we created one),
34067754Smsmith     */
34184491Smsmith    if (InternalParams)
34267754Smsmith    {
34367754Smsmith        /* Free the allocated parameter block */
34467754Smsmith
34584491Smsmith        AcpiUtDeleteInternalObjectList (InternalParams);
34667754Smsmith    }
34767754Smsmith
34867754Smsmith    return_ACPI_STATUS (Status);
34967754Smsmith}
35067754Smsmith
35167754Smsmith
35267754Smsmith/*******************************************************************************
35367754Smsmith *
35467754Smsmith * FUNCTION:    AcpiGetNextObject
35567754Smsmith *
35667754Smsmith * PARAMETERS:  Type            - Type of object to be searched for
35767754Smsmith *              Parent          - Parent object whose children we are getting
35867754Smsmith *              LastChild       - Previous child that was found.
35967754Smsmith *                                The NEXT child will be returned
36067754Smsmith *              RetHandle       - Where handle to the next object is placed
36167754Smsmith *
36267754Smsmith * RETURN:      Status
36367754Smsmith *
36467754Smsmith * DESCRIPTION: Return the next peer object within the namespace.  If Handle is
36567754Smsmith *              valid, Scope is ignored.  Otherwise, the first object within
36667754Smsmith *              Scope is returned.
36767754Smsmith *
36867754Smsmith ******************************************************************************/
36967754Smsmith
37067754SmsmithACPI_STATUS
37167754SmsmithAcpiGetNextObject (
37267754Smsmith    ACPI_OBJECT_TYPE        Type,
37367754Smsmith    ACPI_HANDLE             Parent,
37467754Smsmith    ACPI_HANDLE             Child,
37567754Smsmith    ACPI_HANDLE             *RetHandle)
37667754Smsmith{
37791116Smsmith    ACPI_STATUS             Status;
37867754Smsmith    ACPI_NAMESPACE_NODE     *Node;
37967754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode = NULL;
38067754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode = NULL;
38167754Smsmith
38267754Smsmith
38367754Smsmith    /* Parameter validation */
38467754Smsmith
38567754Smsmith    if (Type > ACPI_TYPE_MAX)
38667754Smsmith    {
38767754Smsmith        return (AE_BAD_PARAMETER);
38867754Smsmith    }
38967754Smsmith
39091116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
39191116Smsmith    if (ACPI_FAILURE (Status))
39291116Smsmith    {
39391116Smsmith        return (Status);
39491116Smsmith    }
39567754Smsmith
39667754Smsmith    /* If null handle, use the parent */
39767754Smsmith
39867754Smsmith    if (!Child)
39967754Smsmith    {
40067754Smsmith        /* Start search at the beginning of the specified scope */
40167754Smsmith
40285756Smsmith        ParentNode = AcpiNsMapHandleToNode (Parent);
40367754Smsmith        if (!ParentNode)
40467754Smsmith        {
40567754Smsmith            Status = AE_BAD_PARAMETER;
40667754Smsmith            goto UnlockAndExit;
40767754Smsmith        }
40867754Smsmith    }
40967754Smsmith    else
41067754Smsmith    {
41191116Smsmith        /* Non-null handle, ignore the parent */
41267754Smsmith        /* Convert and validate the handle */
41367754Smsmith
41485756Smsmith        ChildNode = AcpiNsMapHandleToNode (Child);
41567754Smsmith        if (!ChildNode)
41667754Smsmith        {
41767754Smsmith            Status = AE_BAD_PARAMETER;
41867754Smsmith            goto UnlockAndExit;
41967754Smsmith        }
42067754Smsmith    }
42167754Smsmith
42267754Smsmith    /* Internal function does the real work */
42367754Smsmith
42491116Smsmith    Node = AcpiNsGetNextNode (Type, ParentNode, ChildNode);
42567754Smsmith    if (!Node)
42667754Smsmith    {
42767754Smsmith        Status = AE_NOT_FOUND;
42867754Smsmith        goto UnlockAndExit;
42967754Smsmith    }
43067754Smsmith
43167754Smsmith    if (RetHandle)
43267754Smsmith    {
43367754Smsmith        *RetHandle = AcpiNsConvertEntryToHandle (Node);
43467754Smsmith    }
43567754Smsmith
43667754Smsmith
43767754SmsmithUnlockAndExit:
43867754Smsmith
43991116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
44067754Smsmith    return (Status);
44167754Smsmith}
44267754Smsmith
44367754Smsmith
44467754Smsmith/*******************************************************************************
44567754Smsmith *
44667754Smsmith * FUNCTION:    AcpiGetType
44767754Smsmith *
44867754Smsmith * PARAMETERS:  Handle          - Handle of object whose type is desired
44967754Smsmith *              *RetType        - Where the type will be placed
45067754Smsmith *
45167754Smsmith * RETURN:      Status
45267754Smsmith *
45367754Smsmith * DESCRIPTION: This routine returns the type associatd with a particular handle
45467754Smsmith *
45567754Smsmith ******************************************************************************/
45667754Smsmith
45767754SmsmithACPI_STATUS
45867754SmsmithAcpiGetType (
45967754Smsmith    ACPI_HANDLE             Handle,
46067754Smsmith    ACPI_OBJECT_TYPE        *RetType)
46167754Smsmith{
46267754Smsmith    ACPI_NAMESPACE_NODE     *Node;
46391116Smsmith    ACPI_STATUS             Status;
46467754Smsmith
46567754Smsmith
46667754Smsmith    /* Parameter Validation */
46767754Smsmith
46867754Smsmith    if (!RetType)
46967754Smsmith    {
47067754Smsmith        return (AE_BAD_PARAMETER);
47167754Smsmith    }
47267754Smsmith
47367754Smsmith    /*
47467754Smsmith     * Special case for the predefined Root Node
47567754Smsmith     * (return type ANY)
47667754Smsmith     */
47767754Smsmith    if (Handle == ACPI_ROOT_OBJECT)
47867754Smsmith    {
47967754Smsmith        *RetType = ACPI_TYPE_ANY;
48067754Smsmith        return (AE_OK);
48167754Smsmith    }
48267754Smsmith
48391116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
48491116Smsmith    if (ACPI_FAILURE (Status))
48591116Smsmith    {
48691116Smsmith        return (Status);
48791116Smsmith    }
48867754Smsmith
48967754Smsmith    /* Convert and validate the handle */
49067754Smsmith
49185756Smsmith    Node = AcpiNsMapHandleToNode (Handle);
49267754Smsmith    if (!Node)
49367754Smsmith    {
49491116Smsmith        (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
49567754Smsmith        return (AE_BAD_PARAMETER);
49667754Smsmith    }
49767754Smsmith
49867754Smsmith    *RetType = Node->Type;
49967754Smsmith
50067754Smsmith
50191116Smsmith    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
50291116Smsmith    return (Status);
50367754Smsmith}
50467754Smsmith
50567754Smsmith
50667754Smsmith/*******************************************************************************
50767754Smsmith *
50867754Smsmith * FUNCTION:    AcpiGetParent
50967754Smsmith *
51067754Smsmith * PARAMETERS:  Handle          - Handle of object whose parent is desired
51167754Smsmith *              RetHandle       - Where the parent handle will be placed
51267754Smsmith *
51367754Smsmith * RETURN:      Status
51467754Smsmith *
51567754Smsmith * DESCRIPTION: Returns a handle to the parent of the object represented by
51667754Smsmith *              Handle.
51767754Smsmith *
51867754Smsmith ******************************************************************************/
51967754Smsmith
52067754SmsmithACPI_STATUS
52167754SmsmithAcpiGetParent (
52267754Smsmith    ACPI_HANDLE             Handle,
52367754Smsmith    ACPI_HANDLE             *RetHandle)
52467754Smsmith{
52567754Smsmith    ACPI_NAMESPACE_NODE     *Node;
52691116Smsmith    ACPI_STATUS             Status;
52767754Smsmith
52867754Smsmith
52967754Smsmith    if (!RetHandle)
53067754Smsmith    {
53167754Smsmith        return (AE_BAD_PARAMETER);
53267754Smsmith    }
53367754Smsmith
53467754Smsmith    /* Special case for the predefined Root Node (no parent) */
53567754Smsmith
53667754Smsmith    if (Handle == ACPI_ROOT_OBJECT)
53767754Smsmith    {
53867754Smsmith        return (AE_NULL_ENTRY);
53967754Smsmith    }
54067754Smsmith
54191116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
54291116Smsmith    if (ACPI_FAILURE (Status))
54391116Smsmith    {
54491116Smsmith        return (Status);
54591116Smsmith    }
54667754Smsmith
54767754Smsmith    /* Convert and validate the handle */
54867754Smsmith
54985756Smsmith    Node = AcpiNsMapHandleToNode (Handle);
55067754Smsmith    if (!Node)
55167754Smsmith    {
55267754Smsmith        Status = AE_BAD_PARAMETER;
55367754Smsmith        goto UnlockAndExit;
55467754Smsmith    }
55567754Smsmith
55667754Smsmith    /* Get the parent entry */
55767754Smsmith
55867754Smsmith    *RetHandle =
55991116Smsmith        AcpiNsConvertEntryToHandle (AcpiNsGetParentNode (Node));
56067754Smsmith
56167754Smsmith    /* Return exeption if parent is null */
56267754Smsmith
56391116Smsmith    if (!AcpiNsGetParentNode (Node))
56467754Smsmith    {
56567754Smsmith        Status = AE_NULL_ENTRY;
56667754Smsmith    }
56767754Smsmith
56867754Smsmith
56967754SmsmithUnlockAndExit:
57067754Smsmith
57191116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
57267754Smsmith    return (Status);
57367754Smsmith}
57467754Smsmith
57567754Smsmith
57667754Smsmith/*******************************************************************************
57767754Smsmith *
57867754Smsmith * FUNCTION:    AcpiWalkNamespace
57967754Smsmith *
58067754Smsmith * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
58167754Smsmith *              StartObject         - Handle in namespace where search begins
58267754Smsmith *              MaxDepth            - Depth to which search is to reach
58367754Smsmith *              UserFunction        - Called when an object of "Type" is found
58467754Smsmith *              Context             - Passed to user function
58567754Smsmith *              ReturnValue         - Location where return value of
58667754Smsmith *                                    UserFunction is put if terminated early
58767754Smsmith *
58867754Smsmith * RETURNS      Return value from the UserFunction if terminated early.
58967754Smsmith *              Otherwise, returns NULL.
59067754Smsmith *
59167754Smsmith * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
59267754Smsmith *              starting (and ending) at the object specified by StartHandle.
59367754Smsmith *              The UserFunction is called whenever an object that matches
59467754Smsmith *              the type parameter is found.  If the user function returns
59567754Smsmith *              a non-zero value, the search is terminated immediately and this
59667754Smsmith *              value is returned to the caller.
59767754Smsmith *
59867754Smsmith *              The point of this procedure is to provide a generic namespace
59967754Smsmith *              walk routine that can be called from multiple places to
60067754Smsmith *              provide multiple services;  the User Function can be tailored
60167754Smsmith *              to each task, whether it is a print function, a compare
60267754Smsmith *              function, etc.
60367754Smsmith *
60467754Smsmith ******************************************************************************/
60567754Smsmith
60667754SmsmithACPI_STATUS
60767754SmsmithAcpiWalkNamespace (
60867754Smsmith    ACPI_OBJECT_TYPE        Type,
60967754Smsmith    ACPI_HANDLE             StartObject,
61067754Smsmith    UINT32                  MaxDepth,
61177424Smsmith    ACPI_WALK_CALLBACK      UserFunction,
61267754Smsmith    void                    *Context,
61367754Smsmith    void                    **ReturnValue)
61467754Smsmith{
61567754Smsmith    ACPI_STATUS             Status;
61667754Smsmith
61767754Smsmith
61891116Smsmith    ACPI_FUNCTION_TRACE ("AcpiWalkNamespace");
61967754Smsmith
62067754Smsmith
62167754Smsmith    /* Parameter validation */
62267754Smsmith
62367754Smsmith    if ((Type > ACPI_TYPE_MAX)  ||
62467754Smsmith        (!MaxDepth)             ||
62567754Smsmith        (!UserFunction))
62667754Smsmith    {
62767754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
62867754Smsmith    }
62967754Smsmith
63067754Smsmith    /*
63167754Smsmith     * Lock the namespace around the walk.
63267754Smsmith     * The namespace will be unlocked/locked around each call
63367754Smsmith     * to the user function - since this function
63467754Smsmith     * must be allowed to make Acpi calls itself.
63567754Smsmith     */
63691116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
63791116Smsmith    if (ACPI_FAILURE (Status))
63891116Smsmith    {
63991116Smsmith        return_ACPI_STATUS (Status);
64091116Smsmith    }
64167754Smsmith
64291116Smsmith    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK,
64391116Smsmith                    UserFunction, Context, ReturnValue);
64467754Smsmith
64591116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
64667754Smsmith    return_ACPI_STATUS (Status);
64767754Smsmith}
64867754Smsmith
64967754Smsmith
65067754Smsmith/*******************************************************************************
65167754Smsmith *
65267754Smsmith * FUNCTION:    AcpiNsGetDeviceCallback
65367754Smsmith *
65467754Smsmith * PARAMETERS:  Callback from AcpiGetDevice
65567754Smsmith *
65667754Smsmith * RETURN:      Status
65767754Smsmith *
65867754Smsmith * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
65967754Smsmith *              present devices, or if they specified a HID, it filters based
66067754Smsmith *              on that.
66167754Smsmith *
66267754Smsmith ******************************************************************************/
66367754Smsmith
66467754Smsmithstatic ACPI_STATUS
66567754SmsmithAcpiNsGetDeviceCallback (
66667754Smsmith    ACPI_HANDLE             ObjHandle,
66767754Smsmith    UINT32                  NestingLevel,
66867754Smsmith    void                    *Context,
66967754Smsmith    void                    **ReturnValue)
67067754Smsmith{
67167754Smsmith    ACPI_STATUS             Status;
67267754Smsmith    ACPI_NAMESPACE_NODE     *Node;
67367754Smsmith    UINT32                  Flags;
67487031Smsmith    ACPI_DEVICE_ID          Hid;
67587031Smsmith    ACPI_DEVICE_ID          Cid;
67667754Smsmith    ACPI_GET_DEVICES_INFO   *Info;
67767754Smsmith
67867754Smsmith
67967754Smsmith    Info = Context;
68067754Smsmith
68191116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
68291116Smsmith    if (ACPI_FAILURE (Status))
68391116Smsmith    {
68491116Smsmith        return (Status);
68591116Smsmith    }
68691116Smsmith
68785756Smsmith    Node = AcpiNsMapHandleToNode (ObjHandle);
68891116Smsmith    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
68991116Smsmith    if (ACPI_FAILURE (Status))
69091116Smsmith    {
69191116Smsmith        return (Status);
69291116Smsmith    }
69373561Smsmith
69467754Smsmith    if (!Node)
69567754Smsmith    {
69667754Smsmith        return (AE_BAD_PARAMETER);
69767754Smsmith    }
69867754Smsmith
69967754Smsmith    /*
70067754Smsmith     * Run _STA to determine if device is present
70167754Smsmith     */
70277424Smsmith    Status = AcpiUtExecute_STA (Node, &Flags);
70367754Smsmith    if (ACPI_FAILURE (Status))
70467754Smsmith    {
70577424Smsmith        return (AE_CTRL_DEPTH);
70667754Smsmith    }
70767754Smsmith
70867754Smsmith    if (!(Flags & 0x01))
70967754Smsmith    {
71087031Smsmith        /* Don't return at the device or children of the device if not there */
71167754Smsmith        return (AE_CTRL_DEPTH);
71267754Smsmith    }
71367754Smsmith
71467754Smsmith    /*
71587031Smsmith     * Filter based on device HID & CID
71667754Smsmith     */
71767754Smsmith    if (Info->Hid != NULL)
71867754Smsmith    {
71987031Smsmith        Status = AcpiUtExecute_HID (Node, &Hid);
72067754Smsmith        if (Status == AE_NOT_FOUND)
72167754Smsmith        {
72267754Smsmith            return (AE_OK);
72367754Smsmith        }
72467754Smsmith        else if (ACPI_FAILURE (Status))
72567754Smsmith        {
72677424Smsmith            return (AE_CTRL_DEPTH);
72767754Smsmith        }
72867754Smsmith
72991116Smsmith        if (ACPI_STRNCMP (Hid.Buffer, Info->Hid, sizeof (Hid.Buffer)) != 0)
73067754Smsmith        {
73187031Smsmith            Status = AcpiUtExecute_CID (Node, &Cid);
73287031Smsmith            if (Status == AE_NOT_FOUND)
73387031Smsmith            {
73487031Smsmith                return (AE_OK);
73587031Smsmith            }
73687031Smsmith            else if (ACPI_FAILURE (Status))
73787031Smsmith            {
73887031Smsmith                return (AE_CTRL_DEPTH);
73987031Smsmith            }
74087031Smsmith
74187031Smsmith            /* TBD: Handle CID packages */
74287031Smsmith
74391116Smsmith            if (ACPI_STRNCMP (Cid.Buffer, Info->Hid, sizeof (Cid.Buffer)) != 0)
74487031Smsmith            {
74587031Smsmith                return (AE_OK);
74687031Smsmith            }
74767754Smsmith        }
74867754Smsmith    }
74967754Smsmith
75067754Smsmith    Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue);
75167754Smsmith    return (AE_OK);
75267754Smsmith}
75367754Smsmith
75467754Smsmith
75567754Smsmith/*******************************************************************************
75667754Smsmith *
75767754Smsmith * FUNCTION:    AcpiGetDevices
75867754Smsmith *
75967754Smsmith * PARAMETERS:  HID                 - HID to search for. Can be NULL.
76067754Smsmith *              UserFunction        - Called when a matching object is found
76167754Smsmith *              Context             - Passed to user function
76267754Smsmith *              ReturnValue         - Location where return value of
76367754Smsmith *                                    UserFunction is put if terminated early
76467754Smsmith *
76567754Smsmith * RETURNS      Return value from the UserFunction if terminated early.
76667754Smsmith *              Otherwise, returns NULL.
76767754Smsmith *
76867754Smsmith * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
76967754Smsmith *              starting (and ending) at the object specified by StartHandle.
77067754Smsmith *              The UserFunction is called whenever an object that matches
77167754Smsmith *              the type parameter is found.  If the user function returns
77267754Smsmith *              a non-zero value, the search is terminated immediately and this
77367754Smsmith *              value is returned to the caller.
77467754Smsmith *
77567754Smsmith *              This is a wrapper for WalkNamespace, but the callback performs
77667754Smsmith *              additional filtering. Please see AcpiGetDeviceCallback.
77767754Smsmith *
77867754Smsmith ******************************************************************************/
77967754Smsmith
78067754SmsmithACPI_STATUS
78167754SmsmithAcpiGetDevices (
78267754Smsmith    NATIVE_CHAR             *HID,
78377424Smsmith    ACPI_WALK_CALLBACK      UserFunction,
78467754Smsmith    void                    *Context,
78567754Smsmith    void                    **ReturnValue)
78667754Smsmith{
78767754Smsmith    ACPI_STATUS             Status;
78867754Smsmith    ACPI_GET_DEVICES_INFO   Info;
78967754Smsmith
79067754Smsmith
79191116Smsmith    ACPI_FUNCTION_TRACE ("AcpiGetDevices");
79267754Smsmith
79367754Smsmith
79467754Smsmith    /* Parameter validation */
79567754Smsmith
79667754Smsmith    if (!UserFunction)
79767754Smsmith    {
79867754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
79967754Smsmith    }
80067754Smsmith
80167754Smsmith    /*
80267754Smsmith     * We're going to call their callback from OUR callback, so we need
80367754Smsmith     * to know what it is, and their context parameter.
80467754Smsmith     */
80567754Smsmith    Info.Context      = Context;
80667754Smsmith    Info.UserFunction = UserFunction;
80767754Smsmith    Info.Hid          = HID;
80867754Smsmith
80967754Smsmith    /*
81067754Smsmith     * Lock the namespace around the walk.
81167754Smsmith     * The namespace will be unlocked/locked around each call
81267754Smsmith     * to the user function - since this function
81367754Smsmith     * must be allowed to make Acpi calls itself.
81467754Smsmith     */
81591116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
81691116Smsmith    if (ACPI_FAILURE (Status))
81791116Smsmith    {
81891116Smsmith        return_ACPI_STATUS (Status);
81991116Smsmith    }
82091116Smsmith
82167754Smsmith    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE,
82267754Smsmith                                    ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
82391116Smsmith                                    ACPI_NS_WALK_UNLOCK,
82467754Smsmith                                    AcpiNsGetDeviceCallback, &Info,
82567754Smsmith                                    ReturnValue);
82667754Smsmith
82791116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
82867754Smsmith    return_ACPI_STATUS (Status);
82969450Smsmith}
83087031Smsmith
83187031Smsmith
83287031Smsmith/*******************************************************************************
83387031Smsmith *
83487031Smsmith * FUNCTION:    AcpiAttachData
83587031Smsmith *
83691116Smsmith * PARAMETERS:
83787031Smsmith *
83887031Smsmith * RETURN:      Status
83987031Smsmith *
84091116Smsmith * DESCRIPTION:
84187031Smsmith *
84287031Smsmith ******************************************************************************/
84387031Smsmith
84487031SmsmithACPI_STATUS
84587031SmsmithAcpiAttachData (
84687031Smsmith    ACPI_HANDLE             ObjHandle,
84787031Smsmith    ACPI_OBJECT_HANDLER     Handler,
84887031Smsmith    void                    *Data)
84987031Smsmith{
85087031Smsmith    ACPI_NAMESPACE_NODE     *Node;
85187031Smsmith    ACPI_STATUS             Status;
85287031Smsmith
85387031Smsmith
85487031Smsmith    /* Parameter validation */
85587031Smsmith
85687031Smsmith    if (!ObjHandle  ||
85787031Smsmith        !Handler    ||
85887031Smsmith        !Data)
85987031Smsmith    {
86087031Smsmith        return (AE_BAD_PARAMETER);
86187031Smsmith    }
86287031Smsmith
86391116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
86491116Smsmith    if (ACPI_FAILURE (Status))
86591116Smsmith    {
86691116Smsmith        return (Status);
86791116Smsmith    }
86887031Smsmith
86987031Smsmith    /* Convert and validate the handle */
87087031Smsmith
87187031Smsmith    Node = AcpiNsMapHandleToNode (ObjHandle);
87287031Smsmith    if (!Node)
87387031Smsmith    {
87487031Smsmith        Status = AE_BAD_PARAMETER;
87587031Smsmith        goto UnlockAndExit;
87687031Smsmith    }
87787031Smsmith
87887031Smsmith    Status = AcpiNsAttachData (Node, Handler, Data);
87987031Smsmith
88087031SmsmithUnlockAndExit:
88191116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
88287031Smsmith    return (Status);
88387031Smsmith}
88487031Smsmith
88587031Smsmith
88687031Smsmith/*******************************************************************************
88787031Smsmith *
88887031Smsmith * FUNCTION:    AcpiDetachData
88987031Smsmith *
89091116Smsmith * PARAMETERS:
89187031Smsmith *
89287031Smsmith * RETURN:      Status
89387031Smsmith *
89491116Smsmith * DESCRIPTION:
89587031Smsmith *
89687031Smsmith ******************************************************************************/
89787031Smsmith
89887031SmsmithACPI_STATUS
89987031SmsmithAcpiDetachData (
90087031Smsmith    ACPI_HANDLE             ObjHandle,
90187031Smsmith    ACPI_OBJECT_HANDLER     Handler)
90287031Smsmith{
90387031Smsmith    ACPI_NAMESPACE_NODE     *Node;
90487031Smsmith    ACPI_STATUS             Status;
90587031Smsmith
90687031Smsmith
90787031Smsmith    /* Parameter validation */
90887031Smsmith
90987031Smsmith    if (!ObjHandle  ||
91087031Smsmith        !Handler)
91187031Smsmith    {
91287031Smsmith        return (AE_BAD_PARAMETER);
91387031Smsmith    }
91487031Smsmith
91591116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
91691116Smsmith    if (ACPI_FAILURE (Status))
91791116Smsmith    {
91891116Smsmith        return (Status);
91991116Smsmith    }
92087031Smsmith
92187031Smsmith    /* Convert and validate the handle */
92287031Smsmith
92387031Smsmith    Node = AcpiNsMapHandleToNode (ObjHandle);
92487031Smsmith    if (!Node)
92587031Smsmith    {
92687031Smsmith        Status = AE_BAD_PARAMETER;
92787031Smsmith        goto UnlockAndExit;
92887031Smsmith    }
92987031Smsmith
93087031Smsmith    Status = AcpiNsDetachData (Node, Handler);
93187031Smsmith
93287031SmsmithUnlockAndExit:
93391116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
93487031Smsmith    return (Status);
93587031Smsmith}
93687031Smsmith
93787031Smsmith
93887031Smsmith/*******************************************************************************
93987031Smsmith *
94087031Smsmith * FUNCTION:    AcpiGetData
94187031Smsmith *
94291116Smsmith * PARAMETERS:
94387031Smsmith *
94487031Smsmith * RETURN:      Status
94587031Smsmith *
94691116Smsmith * DESCRIPTION:
94787031Smsmith *
94887031Smsmith ******************************************************************************/
94987031Smsmith
95087031SmsmithACPI_STATUS
95187031SmsmithAcpiGetData (
95287031Smsmith    ACPI_HANDLE             ObjHandle,
95387031Smsmith    ACPI_OBJECT_HANDLER     Handler,
95487031Smsmith    void                    **Data)
95587031Smsmith{
95687031Smsmith    ACPI_NAMESPACE_NODE     *Node;
95787031Smsmith    ACPI_STATUS             Status;
95887031Smsmith
95987031Smsmith
96087031Smsmith    /* Parameter validation */
96187031Smsmith
96287031Smsmith    if (!ObjHandle  ||
96387031Smsmith        !Handler    ||
96487031Smsmith        !Data)
96587031Smsmith    {
96687031Smsmith        return (AE_BAD_PARAMETER);
96787031Smsmith    }
96887031Smsmith
96991116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
97091116Smsmith    if (ACPI_FAILURE (Status))
97191116Smsmith    {
97291116Smsmith        return (Status);
97391116Smsmith    }
97487031Smsmith
97587031Smsmith    /* Convert and validate the handle */
97687031Smsmith
97787031Smsmith    Node = AcpiNsMapHandleToNode (ObjHandle);
97887031Smsmith    if (!Node)
97987031Smsmith    {
98087031Smsmith        Status = AE_BAD_PARAMETER;
98187031Smsmith        goto UnlockAndExit;
98287031Smsmith    }
98387031Smsmith
98487031Smsmith    Status = AcpiNsGetAttachedData (Node, Handler, Data);
98587031Smsmith
98687031SmsmithUnlockAndExit:
98791116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
98887031Smsmith    return (Status);
98987031Smsmith}
99087031Smsmith
99187031Smsmith
992