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