nsaccess.c revision 69450
118316Swollman/*******************************************************************************
218316Swollman *
318316Swollman * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
418316Swollman *              $Revision: 113 $
518316Swollman *
618316Swollman ******************************************************************************/
718316Swollman
818316Swollman/******************************************************************************
918316Swollman *
1018316Swollman * 1. Copyright Notice
1118316Swollman *
1218316Swollman * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
1318316Swollman * reserved.
1418316Swollman *
1518316Swollman * 2. License
1618316Swollman *
1718316Swollman * 2.1. This is your license from Intel Corp. under its intellectual property
1818316Swollman * rights.  You may have additional license terms from the party that provided
1918316Swollman * you this software, covering your right to use that party's intellectual
2018316Swollman * property rights.
2118316Swollman *
2218316Swollman * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2318316Swollman * copy of the source code appearing in this file ("Covered Code") an
2418316Swollman * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2518316Swollman * base code distributed originally by Intel ("Original Intel Code") to copy,
2618316Swollman * make derivatives, distribute, use and display any portion of the Covered
2718316Swollman * Code in any form, with the right to sublicense such rights; and
2846303Smarkm *
2950476Speter * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3018316Swollman * license (with the right to sublicense), under only those claims of Intel
3118316Swollman * patents that are infringed by the Original Intel Code, to make, use, sell,
3218316Swollman * offer to sell, and import the Covered Code and derivative works thereof
3346303Smarkm * solely to the minimum extent necessary to exercise the above copyright
3418316Swollman * license, and in no event shall the patent license extend to any additions
3518316Swollman * to or modifications of the Original Intel Code.  No other license or right
3618316Swollman * is granted directly or by implication, estoppel or otherwise;
3746303Smarkm *
3818316Swollman * The above copyright and patent license is granted only if the following
3946303Smarkm * conditions are met:
4018316Swollman *
41190710Sphk * 3. Conditions
42126250Sbms *
43190710Sphk * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44126250Sbms * Redistribution of source code of any substantial portion of the Covered
4546303Smarkm * Code or modification with rights to further distribute source must include
46126250Sbms * the above Copyright Notice, the above License, this list of Conditions,
47126250Sbms * and the following Disclaimer and Export Compliance provision.  In addition,
48126250Sbms * Licensee must cause all Covered Code to which Licensee contributes to
49126250Sbms * contain a file documenting the changes Licensee made to create that Covered
50163999Strhodes * Code and the date of any change.  Licensee must include in that file the
51163999Strhodes * documentation of any changes made by any predecessor Licensee.  Licensee
5246303Smarkm * must include a prominent statement that the modification is derived,
5346303Smarkm * directly or indirectly, from Original Intel Code.
5418316Swollman *
5518316Swollman * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5618316Swollman * Redistribution of source code of any substantial portion of the Covered
57190715Sphk * Code or modification without rights to further distribute source must
5818316Swollman * include the following Disclaimer and Export Compliance provision in the
59190715Sphk * documentation and/or other materials provided with distribution.  In
6046303Smarkm * addition, Licensee may not authorize further sublicense of source of any
6118316Swollman * portion of the Covered Code, and must include terms to the effect that the
6218316Swollman * license from Licensee to its licensee is limited to the intellectual
63190715Sphk * property embodied in the software Licensee provides to its licensee, and
6418316Swollman * not to intellectual property embodied in modifications its licensee may
65190715Sphk * make.
66190715Sphk *
6718316Swollman * 3.3. Redistribution of Executable. Redistribution in executable form of any
6818316Swollman * substantial portion of the Covered Code or modification must reproduce the
6937908Scharnier * above Copyright Notice, and the following Disclaimer and Export Compliance
7018316Swollman * provision in the documentation and/or other materials provided with the
71272872Shrs * distribution.
7218316Swollman *
7318316Swollman * 3.4. Intel retains all right, title, and interest in and to the Original
74190715Sphk * Intel Code.
75190715Sphk *
7646303Smarkm * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7718316Swollman * Intel shall be used in advertising or otherwise to promote the sale, use or
7818316Swollman * other dealings in products derived from or relating to the Covered Code
7918316Swollman * without prior written authorization from Intel.
8018316Swollman *
8118316Swollman * 4. Disclaimer and Export Compliance
82190715Sphk *
8364131Ssheldonh * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8464131Ssheldonh * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8564131Ssheldonh * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8618316Swollman * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87190715Sphk * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8846303Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89190715Sphk * PARTICULAR PURPOSE.
90190715Sphk *
9118316Swollman * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92190716Sphk * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9318316Swollman * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9418316Swollman * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9518316Swollman * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9618316Swollman * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9718316Swollman * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9818316Swollman * LIMITED REMEDY.
99190715Sphk *
100190715Sphk * 4.3. Licensee shall not export, either directly or indirectly, any of this
10118316Swollman * software or system incorporating such software without first obtaining any
10218316Swollman * required license or other approval from the U. S. Department of Commerce or
10318316Swollman * any other agency or department of the United States Government.  In the
10418316Swollman * event Licensee exports any such software from the United States or
10518316Swollman * re-exports any such software from a foreign destination, Licensee shall
10618316Swollman * ensure that the distribution and export/re-export of the software is in
10718316Swollman * compliance with all laws, regulations, orders, or other restrictions of the
10818316Swollman * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10946303Smarkm * any of its subsidiaries will export/re-export any technical data, process,
11018316Swollman * software, or service, directly or indirectly, to any country for which the
11118316Swollman * United States government or any agency thereof requires an export license,
11218316Swollman * other governmental approval, or letter of assurance, without first obtaining
11319896Swollman * such license, approval or letter.
11418316Swollman *
11518316Swollman *****************************************************************************/
11618316Swollman
11718316Swollman#define __NSACCESS_C__
11818316Swollman
11919896Swollman#include "acpi.h"
12019896Swollman#include "amlcode.h"
12119896Swollman#include "acinterp.h"
12219896Swollman#include "acnamesp.h"
12319896Swollman#include "acdispat.h"
124126250Sbms
12518316Swollman
12618316Swollman#define _COMPONENT          NAMESPACE
12718316Swollman        MODULE_NAME         ("nsaccess")
12818316Swollman
12918316Swollman
13018316Swollman/*******************************************************************************
13118316Swollman *
13218316Swollman * FUNCTION:    AcpiNsRootInitialize
13318316Swollman *
13418316Swollman * PARAMETERS:  None
13518316Swollman *
13618316Swollman * RETURN:      Status
13718316Swollman *
13818316Swollman * DESCRIPTION: Allocate and initialize the default root named objects
13918316Swollman *
140272872Shrs * MUTEX:       Locks namespace for entire execution
14118316Swollman *
142272872Shrs ******************************************************************************/
143272872Shrs
144272872ShrsACPI_STATUS
14518316SwollmanAcpiNsRootInitialize (void)
14618316Swollman{
14718316Swollman    ACPI_STATUS             Status = AE_OK;
14818316Swollman    PREDEFINED_NAMES        *InitVal = NULL;
14918316Swollman    ACPI_NAMESPACE_NODE     *NewNode;
15018316Swollman    ACPI_OPERAND_OBJECT     *ObjDesc;
15118316Swollman
15218316Swollman
15318316Swollman    FUNCTION_TRACE ("NsRootInitialize");
15418316Swollman
15518316Swollman
15618316Swollman    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
15718316Swollman
15818316Swollman    /*
15918316Swollman     * The global root ptr is initially NULL, so a non-NULL value indicates
16046303Smarkm     * that AcpiNsRootInitialize() has already been called; just return.
16118316Swollman     */
16246303Smarkm
16346303Smarkm    if (AcpiGbl_RootNode)
16446303Smarkm    {
16518316Swollman        Status = AE_OK;
16618316Swollman        goto UnlockAndExit;
16718316Swollman    }
16818316Swollman
16918316Swollman
17018316Swollman    /*
17118316Swollman     * Tell the rest of the subsystem that the root is initialized
17218316Swollman     * (This is OK because the namespace is locked)
17318316Swollman     */
17418316Swollman
17518316Swollman    AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct;
17618316Swollman
17718316Swollman
17818316Swollman    /* Enter the pre-defined names in the name table */
17918316Swollman
18018316Swollman    DEBUG_PRINT (ACPI_INFO,
18118316Swollman        ("Entering predefined name table entries into namespace\n"));
18218316Swollman
18318316Swollman    for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++)
18418316Swollman    {
18518316Swollman        Status = AcpiNsLookup (NULL, InitVal->Name,
18618316Swollman                                (OBJECT_TYPE_INTERNAL) InitVal->Type,
18718316Swollman                                IMODE_LOAD_PASS2, NS_NO_UPSEARCH,
18818316Swollman                                NULL, &NewNode);
18918316Swollman
19018316Swollman        if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */
19118316Swollman        {
19218316Swollman            DEBUG_PRINT (ACPI_ERROR,
19319896Swollman                ("Could not create predefined name %s, %s\n",
19418316Swollman                InitVal->Name, AcpiCmFormatException (Status)));
19518316Swollman        }
19618316Swollman
19718316Swollman        /*
19818316Swollman         * Name entered successfully.
19918316Swollman         * If entry in PreDefinedNames[] specifies an
20018316Swollman         * initial value, create the initial value.
20118316Swollman         */
20219896Swollman
20318316Swollman        if (InitVal->Val)
20418316Swollman        {
20518316Swollman            /*
20618316Swollman             * Entry requests an initial value, allocate a
20746303Smarkm             * descriptor for it.
20819896Swollman             */
20918316Swollman
21018316Swollman            ObjDesc = AcpiCmCreateInternalObject (
21146303Smarkm                            (OBJECT_TYPE_INTERNAL) InitVal->Type);
21246303Smarkm
21346303Smarkm            if (!ObjDesc)
21418316Swollman            {
21518316Swollman                Status = AE_NO_MEMORY;
21618316Swollman                goto UnlockAndExit;
21746303Smarkm            }
21818316Swollman
21946303Smarkm            /*
22046303Smarkm             * Convert value string from table entry to
22146303Smarkm             * internal representation. Only types actually
22246303Smarkm             * used for initial values are implemented here.
22346303Smarkm             */
22418316Swollman
22518316Swollman            switch (InitVal->Type)
22646303Smarkm            {
22746303Smarkm
22846303Smarkm            case ACPI_TYPE_NUMBER:
229163999Strhodes
23046303Smarkm                ObjDesc->Number.Value =
23146303Smarkm                        (ACPI_INTEGER) STRTOUL (InitVal->Val, NULL, 10);
23218316Swollman                break;
23318316Swollman
23418316Swollman
23518316Swollman            case ACPI_TYPE_STRING:
23618316Swollman
23718316Swollman                ObjDesc->String.Length =
23818316Swollman                        (UINT16) STRLEN (InitVal->Val);
23918316Swollman
24018316Swollman                /*
24118316Swollman                 * Allocate a buffer for the string.  All
24218316Swollman                 * String.Pointers must be allocated buffers!
24320342Swollman                 * (makes deletion simpler)
24420342Swollman                 */
24518316Swollman                ObjDesc->String.Pointer = AcpiCmAllocate (
24618316Swollman                                                (ObjDesc->String.Length + 1));
247163999Strhodes                if (!ObjDesc->String.Pointer)
24846303Smarkm                {
24918316Swollman                    AcpiCmRemoveReference (ObjDesc);
25046303Smarkm                    Status = AE_NO_MEMORY;
25146303Smarkm                    goto UnlockAndExit;
25246303Smarkm                }
25318316Swollman
25446303Smarkm                STRCPY (ObjDesc->String.Pointer, InitVal->Val);
25518316Swollman                break;
25618316Swollman
25718316Swollman
25818316Swollman            case ACPI_TYPE_MUTEX:
25918316Swollman
26018316Swollman                ObjDesc->Mutex.SyncLevel =
26118316Swollman                        (UINT16) STRTOUL (InitVal->Val, NULL, 10);
26218316Swollman
26318316Swollman                if (STRCMP (InitVal->Name, "_GL_") == 0)
26418316Swollman                {
26518316Swollman                    /*
26618316Swollman                     * Create a counting semaphore for the
26718316Swollman                     * global lock
26818316Swollman                     */
26918316Swollman                    Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT,
27018316Swollman                                            1, &ObjDesc->Mutex.Semaphore);
27118316Swollman
27218316Swollman                    if (ACPI_FAILURE (Status))
27318316Swollman                    {
27418316Swollman                        goto UnlockAndExit;
27518316Swollman                    }
27618316Swollman                    /*
27718316Swollman                     * We just created the mutex for the
27818316Swollman                     * global lock, save it
27918316Swollman                     */
28018316Swollman
28118316Swollman                    AcpiGbl_GlobalLockSemaphore = ObjDesc->Mutex.Semaphore;
28218316Swollman                }
28318316Swollman
28418316Swollman                else
28518316Swollman                {
28618316Swollman                    /* Create a mutex */
28718316Swollman
28818316Swollman                    Status = AcpiOsCreateSemaphore (1, 1,
28918316Swollman                                        &ObjDesc->Mutex.Semaphore);
29018316Swollman
29118316Swollman                    if (ACPI_FAILURE (Status))
29218316Swollman                    {
29318316Swollman                        goto UnlockAndExit;
29420342Swollman                    }
29546303Smarkm                }
29620342Swollman                break;
29718316Swollman
29846303Smarkm
29920342Swollman            default:
30018316Swollman                REPORT_ERROR (("Unsupported initial type value %X\n",
30118316Swollman                    InitVal->Type));
302126250Sbms                AcpiCmRemoveReference (ObjDesc);
303126250Sbms                ObjDesc = NULL;
304126250Sbms                continue;
30518316Swollman            }
306110670Sache
307110670Sache            /* Store pointer to value descriptor in the Node */
308110670Sache
30918316Swollman            AcpiNsAttachObject (NewNode, ObjDesc,
310110670Sache                                ObjDesc->Common.Type);
31118316Swollman        }
31218316Swollman    }
31318316Swollman
31418316Swollman
31518316SwollmanUnlockAndExit:
31618316Swollman    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
31718316Swollman    return_ACPI_STATUS (Status);
31818316Swollman}
31918316Swollman
32018316Swollman
32118316Swollman/*******************************************************************************
32218316Swollman *
32318316Swollman * FUNCTION:    AcpiNsLookup
32418316Swollman *
32518316Swollman * PARAMETERS:  PrefixNode  - Search scope if name is not fully qualified
32618316Swollman *              Pathname        - Search pathname, in internal format
32718316Swollman *                                (as represented in the AML stream)
32820342Swollman *              Type            - Type associated with name
32946303Smarkm *              InterpreterMode - IMODE_LOAD_PASS2 => add name if not found
33020342Swollman *              Flags           - Flags describing the search restrictions
33146303Smarkm *              WalkState       - Current state of the walk
33218316Swollman *              ReturnNode  - Where the Node is placed (if found
33318316Swollman *                                or created successfully)
33419896Swollman *
33519896Swollman * RETURN:      Status
33618316Swollman *
33718316Swollman * DESCRIPTION: Find or enter the passed name in the name space.
33818316Swollman *              Log an error if name not found in Exec mode.
33918316Swollman *
34018316Swollman * MUTEX:       Assumes namespace is locked.
34118316Swollman *
34218316Swollman ******************************************************************************/
34318316Swollman
34418316SwollmanACPI_STATUS
34518316SwollmanAcpiNsLookup (
34618316Swollman    ACPI_GENERIC_STATE      *ScopeInfo,
34718316Swollman    NATIVE_CHAR             *Pathname,
34818316Swollman    OBJECT_TYPE_INTERNAL    Type,
34918316Swollman    OPERATING_MODE          InterpreterMode,
35018316Swollman    UINT32                  Flags,
35118316Swollman    ACPI_WALK_STATE         *WalkState,
35218316Swollman    ACPI_NAMESPACE_NODE     **ReturnNode)
35318316Swollman{
35418316Swollman    ACPI_STATUS             Status;
35518316Swollman    ACPI_NAMESPACE_NODE      *PrefixNode;
35618316Swollman    ACPI_NAMESPACE_NODE     *CurrentNode = NULL;
35718316Swollman    ACPI_NAMESPACE_NODE     *ScopeToPush = NULL;
35818316Swollman    ACPI_NAMESPACE_NODE     *ThisNode = NULL;
35918316Swollman    UINT32                  NumSegments;
36019896Swollman    ACPI_NAME               SimpleName;
36118316Swollman    BOOLEAN                 NullNamePath = FALSE;
36246303Smarkm    OBJECT_TYPE_INTERNAL    TypeToCheckFor;
36346303Smarkm    OBJECT_TYPE_INTERNAL    ThisSearchType;
36446303Smarkm
36546303Smarkm    DEBUG_ONLY_MEMBERS      (UINT32 i)
36618316Swollman
36718316Swollman
36818316Swollman    FUNCTION_TRACE ("NsLookup");
36918316Swollman
37018316Swollman
37146303Smarkm    if (!ReturnNode)
37246303Smarkm    {
37346303Smarkm        return_ACPI_STATUS (AE_BAD_PARAMETER);
37446303Smarkm    }
37546303Smarkm
37646303Smarkm
37746303Smarkm    AcpiGbl_NsLookupCount++;
37818316Swollman
37946303Smarkm    *ReturnNode = ENTRY_NOT_FOUND;
38046303Smarkm
38146303Smarkm
38246303Smarkm    if (!AcpiGbl_RootNode)
38346303Smarkm    {
38446303Smarkm        return (AE_NO_NAMESPACE);
38546303Smarkm    }
38646303Smarkm
38746303Smarkm    /*
38846303Smarkm     * Get the prefix scope.
38946303Smarkm     * A null scope means use the root scope
39046303Smarkm     */
39146303Smarkm
39246303Smarkm    if ((!ScopeInfo) ||
39346303Smarkm        (!ScopeInfo->Scope.Node))
39446303Smarkm    {
39546303Smarkm        PrefixNode = AcpiGbl_RootNode;
39618316Swollman    }
39718316Swollman    else
39818316Swollman    {
39918316Swollman        PrefixNode = ScopeInfo->Scope.Node;
40018316Swollman    }
40118316Swollman
40220342Swollman
40320342Swollman    /*
40418316Swollman     * This check is explicitly split provide relax the TypeToCheckFor
40518316Swollman     * conditions for BankFieldDefn.  Originally, both BankFieldDefn and
40619896Swollman     * DefFieldDefn caused TypeToCheckFor to be set to ACPI_TYPE_REGION,
40719896Swollman     * but the BankFieldDefn may also check for a Field definition as well
40846303Smarkm     * as an OperationRegion.
40918316Swollman     */
41018316Swollman
41118316Swollman    if (INTERNAL_TYPE_DEF_FIELD_DEFN == Type)
41218316Swollman    {
41318316Swollman        /* DefFieldDefn defines fields in a Region */
41418316Swollman
41518316Swollman        TypeToCheckFor = ACPI_TYPE_REGION;
41618316Swollman    }
41718316Swollman
41818316Swollman    else if (INTERNAL_TYPE_BANK_FIELD_DEFN == Type)
41918316Swollman    {
42018316Swollman        /* BankFieldDefn defines data fields in a Field Object */
421229778Suqs
42246303Smarkm        TypeToCheckFor = ACPI_TYPE_ANY;
42346303Smarkm    }
42446303Smarkm
42546303Smarkm    else
42646303Smarkm    {
42746303Smarkm        TypeToCheckFor = Type;
42846303Smarkm    }
42946303Smarkm
43046303Smarkm
43146303Smarkm    /* TBD: [Restructure] - Move the pathname stuff into a new procedure */
43246303Smarkm
43346303Smarkm    /* Examine the name pointer */
43418316Swollman
43518316Swollman    if (!Pathname)
43618316Swollman    {
43718316Swollman        /*  8-12-98 ASL Grammar Update supports null NamePath   */
43818316Swollman
43918316Swollman        NullNamePath = TRUE;
44018316Swollman        NumSegments = 0;
44118316Swollman        ThisNode = AcpiGbl_RootNode;
44218316Swollman
44318316Swollman        DEBUG_PRINT (TRACE_NAMES,
44418316Swollman            ("NsLookup: Null Pathname (Zero segments),  Flags=%x\n", Flags));
44518316Swollman    }
44618316Swollman
44718316Swollman    else
44818316Swollman    {
44929314Sdanny        /*
45018316Swollman         * Valid name pointer (Internal name format)
45118316Swollman         *
45218316Swollman         * Check for prefixes.  As represented in the AML stream, a
453229778Suqs         * Pathname consists of an optional scope prefix followed by
45418316Swollman         * a segment part.
45518316Swollman         *
45618316Swollman         * If present, the scope prefix is either a RootPrefix (in
45718316Swollman         * which case the name is fully qualified), or zero or more
45818316Swollman         * ParentPrefixes (in which case the name's scope is relative
45918316Swollman         * to the current scope).
46018316Swollman         *
46118316Swollman         * The segment part consists of either:
46218316Swollman         *  - A single 4-byte name segment, or
46318316Swollman         *  - A DualNamePrefix followed by two 4-byte name segments, or
46418316Swollman         *  - A MultiNamePrefixOp, followed by a byte indicating the
46518316Swollman         *    number of segments and the segments themselves.
46618316Swollman         */
46718316Swollman
46818316Swollman        if (*Pathname == AML_ROOT_PREFIX)
46918316Swollman        {
47018316Swollman            /* Pathname is fully qualified, look in root name table */
47118316Swollman
47218316Swollman            CurrentNode = AcpiGbl_RootNode;
47318316Swollman
47418316Swollman            /* point to segment part */
47518316Swollman
47618316Swollman            Pathname++;
47718316Swollman
47818316Swollman            DEBUG_PRINT (TRACE_NAMES,
47918316Swollman                ("NsLookup: Searching from root [%p]\n",
48018316Swollman                CurrentNode));
48118316Swollman
48218316Swollman            /* Direct reference to root, "\" */
48318316Swollman
48418316Swollman            if (!(*Pathname))
48518316Swollman            {
48618316Swollman                ThisNode = AcpiGbl_RootNode;
48718316Swollman                goto CheckForNewScopeAndExit;
48818316Swollman            }
48918316Swollman        }
49018316Swollman
49118316Swollman        else
49218316Swollman        {
49318316Swollman            /* Pathname is relative to current scope, start there */
49418316Swollman
49518316Swollman            CurrentNode = PrefixNode;
49618316Swollman
49718316Swollman            DEBUG_PRINT (TRACE_NAMES,
49818316Swollman                ("NsLookup: Searching relative to pfx scope [%p]\n",
49918316Swollman                PrefixNode));
50018316Swollman
50118316Swollman            /*
50218316Swollman             * Handle up-prefix (carat).  More than one prefix
50318316Swollman             * is supported
50446303Smarkm             */
50518316Swollman
50618316Swollman            while (*Pathname == AML_PARENT_PREFIX)
50718316Swollman            {
50818316Swollman                /* Point to segment part or next ParentPrefix */
50918316Swollman
51018316Swollman                Pathname++;
51118316Swollman
51218316Swollman                /*  Backup to the parent's scope  */
51318316Swollman
51418316Swollman                ThisNode = AcpiNsGetParentObject (CurrentNode);
51518316Swollman                if (!ThisNode)
51618316Swollman                {
51718316Swollman                    /* Current scope has no parent scope */
51818316Swollman
51918316Swollman                    REPORT_ERROR (("Too many parent prefixes (^) - reached root\n"));
52018316Swollman                    return_ACPI_STATUS (AE_NOT_FOUND);
52118316Swollman                }
52218316Swollman
52318316Swollman                CurrentNode = ThisNode;
52418316Swollman            }
52518316Swollman        }
52618316Swollman
52718316Swollman
52818316Swollman        /*
52918316Swollman         * Examine the name prefix opcode, if any,
53018316Swollman         * to determine the number of segments
53118316Swollman         */
53218316Swollman
53318316Swollman        if (*Pathname == AML_DUAL_NAME_PREFIX)
53418316Swollman        {
53518316Swollman            NumSegments = 2;
53618316Swollman
53718316Swollman            /* point to first segment */
53818316Swollman
539190711Sphk            Pathname++;
540190711Sphk
541190711Sphk            DEBUG_PRINT (TRACE_NAMES,
54218316Swollman                ("NsLookup: Dual Pathname (2 segments, Flags=%X)\n", Flags));
54318316Swollman        }
54418316Swollman
54518316Swollman        else if (*Pathname == AML_MULTI_NAME_PREFIX_OP)
54618316Swollman        {
54718316Swollman            NumSegments = (UINT32)* (UINT8 *) ++Pathname;
54818316Swollman
54918316Swollman            /* point to first segment */
55018316Swollman
55118316Swollman            Pathname++;
55218316Swollman
553190715Sphk            DEBUG_PRINT (TRACE_NAMES,
55446303Smarkm                ("NsLookup: Multi Pathname (%d Segments, Flags=%X) \n",
55518316Swollman                NumSegments, Flags));
55618316Swollman        }
55718316Swollman
55818316Swollman        else
55918316Swollman        {
56019896Swollman            /*
56118316Swollman             * No Dual or Multi prefix, hence there is only one
56218316Swollman             * segment and Pathname is already pointing to it.
56318316Swollman             */
56418316Swollman            NumSegments = 1;
565190715Sphk
56618316Swollman            DEBUG_PRINT (TRACE_NAMES,
56718316Swollman                ("NsLookup: Simple Pathname (1 segment, Flags=%X)\n", Flags));
56818316Swollman        }
56918316Swollman
57018316Swollman#ifdef ACPI_DEBUG
57118316Swollman
57218316Swollman        /* TBD: [Restructure] Make this a procedure */
57318316Swollman
57418316Swollman        /* Debug only: print the entire name that we are about to lookup */
57518316Swollman
57618316Swollman        DEBUG_PRINT (TRACE_NAMES, ("NsLookup: ["));
57718316Swollman
57818316Swollman        for (i = 0; i < NumSegments; i++)
57918316Swollman        {
58018316Swollman            DEBUG_PRINT_RAW (TRACE_NAMES, ("%4.4s/", &Pathname[i * 4]));
58118316Swollman        }
58218316Swollman        DEBUG_PRINT_RAW (TRACE_NAMES, ("]\n"));
58318316Swollman#endif
58418316Swollman    }
58518316Swollman
58618316Swollman
58718316Swollman    /*
58818316Swollman     * Search namespace for each segment of the name.
58918316Swollman     * Loop through and verify/add each name segment.
590190711Sphk     */
59118316Swollman
59218316Swollman
59318316Swollman    while (NumSegments-- && CurrentNode)
59418316Swollman    {
59518316Swollman        /*
59618316Swollman         * Search for the current name segment under the current
59718316Swollman         * named object.  The Type is significant only at the last (topmost)
59818316Swollman         * level.  (We don't care about the types along the path, only
59918316Swollman         * the type of the final target object.)
60018316Swollman         */
60118316Swollman        ThisSearchType = ACPI_TYPE_ANY;
60218316Swollman        if (!NumSegments)
60318316Swollman        {
60418316Swollman            ThisSearchType = Type;
60518316Swollman        }
60618316Swollman
60746303Smarkm        /* Pluck and ACPI name from the front of the pathname */
60818316Swollman
60918316Swollman        MOVE_UNALIGNED32_TO_32 (&SimpleName, Pathname);
61018316Swollman
61118316Swollman        /* Try to find the ACPI name */
61218316Swollman
61318316Swollman        Status = AcpiNsSearchAndEnter (SimpleName, WalkState,
61418316Swollman                                        CurrentNode, InterpreterMode,
61518316Swollman                                        ThisSearchType, Flags,
61618316Swollman                                        &ThisNode);
61719896Swollman
61818316Swollman        if (ACPI_FAILURE (Status))
61918316Swollman        {
62019896Swollman            if (Status == AE_NOT_FOUND)
62119896Swollman            {
62219896Swollman                /* Name not found in ACPI namespace  */
62319896Swollman
62419896Swollman                DEBUG_PRINT (TRACE_NAMES,
62519896Swollman                    ("NsLookup: Name [%4.4s] not found in scope %X\n",
62619896Swollman                    &SimpleName, CurrentNode));
62718316Swollman            }
62818316Swollman
62918316Swollman            return_ACPI_STATUS (Status);
63018316Swollman        }
63118316Swollman
63218316Swollman
63318316Swollman        /*
63418316Swollman         * If 1) This is the last segment (NumSegments == 0)
63518316Swollman         *    2) and looking for a specific type
63619896Swollman         *       (Not checking for TYPE_ANY)
63718316Swollman         *    3) Which is not an alias
63818316Swollman         *    4) which is not a local type (TYPE_DEF_ANY)
63918316Swollman         *    5) which is not a local type (TYPE_SCOPE)
64018316Swollman         *    6) which is not a local type (TYPE_INDEX_FIELD_DEFN)
64118316Swollman         *    7) and type of object is known (not TYPE_ANY)
64218316Swollman         *    8) and object does not match request
64318316Swollman         *
64418316Swollman         * Then we have a type mismatch.  Just warn and ignore it.
64518316Swollman         */
64618316Swollman        if ((NumSegments        == 0)                               &&
64718316Swollman            (TypeToCheckFor     != ACPI_TYPE_ANY)                   &&
64818316Swollman            (TypeToCheckFor     != INTERNAL_TYPE_ALIAS)             &&
64918316Swollman            (TypeToCheckFor     != INTERNAL_TYPE_DEF_ANY)           &&
65018316Swollman            (TypeToCheckFor     != INTERNAL_TYPE_SCOPE)             &&
65118316Swollman            (TypeToCheckFor     != INTERNAL_TYPE_INDEX_FIELD_DEFN)  &&
65218316Swollman            (ThisNode->Type     != ACPI_TYPE_ANY)                   &&
65318316Swollman            (ThisNode->Type     != TypeToCheckFor))
65418316Swollman        {
655126250Sbms            /* Complain about a type mismatch */
65618316Swollman
65718316Swollman            REPORT_WARNING (
65818316Swollman                ("NsLookup: %4.4s, type 0x%X, checking for type 0x%X\n",
65918316Swollman                &SimpleName, ThisNode->Type, TypeToCheckFor));
66018316Swollman        }
66118316Swollman
66218316Swollman        /*
663126250Sbms         * If this is the last name segment and we are not looking for a
66418316Swollman         * specific type, but the type of found object is known, use that type
665126250Sbms         * to see if it opens a scope.
66618316Swollman         */
667126250Sbms
668126250Sbms        if ((0 == NumSegments) && (ACPI_TYPE_ANY == Type))
669126250Sbms        {
670126250Sbms            Type = ThisNode->Type;
67118316Swollman        }
67218316Swollman
67318316Swollman        if ((NumSegments || AcpiNsOpensScope (Type)) &&
67418316Swollman            (ThisNode->Child == NULL))
67518316Swollman        {
67618316Swollman            /*
67718316Swollman             * More segments or the type implies enclosed scope,
67818316Swollman             * and the next scope has not been allocated.
67918316Swollman             */
68018316Swollman
68118316Swollman            DEBUG_PRINT (ACPI_INFO,
68218316Swollman                ("NsLookup: Load mode=%d  ThisNode=%x\n",
68318316Swollman                InterpreterMode, ThisNode));
68418316Swollman        }
68518316Swollman
68618316Swollman        CurrentNode = ThisNode;
68718316Swollman
68818316Swollman        /* point to next name segment */
68918316Swollman
69018316Swollman        Pathname += ACPI_NAME_SIZE;
69146303Smarkm    }
69218316Swollman
69318316Swollman
69418316Swollman    /*
69519896Swollman     * Always check if we need to open a new scope
69618316Swollman     */
69718316Swollman
69818316SwollmanCheckForNewScopeAndExit:
69918316Swollman
70018316Swollman    if (!(Flags & NS_DONT_OPEN_SCOPE) && (WalkState))
70118316Swollman    {
702190711Sphk        /*
70319896Swollman         * If entry is a type which opens a scope,
70419896Swollman         * push the new scope on the scope stack.
70519896Swollman         */
70618316Swollman
70718316Swollman        if (AcpiNsOpensScope (TypeToCheckFor))
70818316Swollman        {
70918316Swollman            /*  8-12-98 ASL Grammar Update supports null NamePath   */
71018316Swollman
71118316Swollman            if (NullNamePath)
71218316Swollman            {
71318316Swollman                /* TBD: [Investigate] - is this the correct thing to do? */
71418316Swollman
71518316Swollman                ScopeToPush = NULL;
71618316Swollman            }
71718316Swollman            else
71818316Swollman            {
71918316Swollman                ScopeToPush = ThisNode;
72018316Swollman            }
72118316Swollman
72218316Swollman            Status = AcpiDsScopeStackPush (ScopeToPush, Type,
72318316Swollman                                            WalkState);
72418316Swollman            if (ACPI_FAILURE (Status))
725180993Sphk            {
726180993Sphk                return_ACPI_STATUS (Status);
72718316Swollman            }
72818316Swollman
72918316Swollman            DEBUG_PRINT (ACPI_INFO,
73018316Swollman                ("NsLookup: Set global scope to %p\n", ScopeToPush));
731180993Sphk        }
732180993Sphk    }
733180993Sphk
734180993Sphk    *ReturnNode = ThisNode;
735180993Sphk    return_ACPI_STATUS (AE_OK);
736180993Sphk}
737126250Sbms
738180993Sphk