nsaccess.c revision 129684
165793Smsmith/******************************************************************************* 265793Smsmith * 381150Sscottl * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 465793Smsmith * $Revision: 182 $ 581082Sscottl * 665793Smsmith ******************************************************************************/ 765793Smsmith 865793Smsmith/****************************************************************************** 965793Smsmith * 1065793Smsmith * 1. Copyright Notice 1165793Smsmith * 1265793Smsmith * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 1365793Smsmith * All rights reserved. 1465793Smsmith * 1565793Smsmith * 2. License 1665793Smsmith * 1765793Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1865793Smsmith * rights. You may have additional license terms from the party that provided 1965793Smsmith * you this software, covering your right to use that party's intellectual 2065793Smsmith * property rights. 2165793Smsmith * 2265793Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2365793Smsmith * copy of the source code appearing in this file ("Covered Code") an 2465793Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2565793Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2665793Smsmith * make derivatives, distribute, use and display any portion of the Covered 2765793Smsmith * Code in any form, with the right to sublicense such rights; and 2865793Smsmith * 2965793Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3065793Smsmith * license (with the right to sublicense), under only those claims of Intel 3165793Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3265793Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3365793Smsmith * solely to the minimum extent necessary to exercise the above copyright 3465793Smsmith * license, and in no event shall the patent license extend to any additions 3565793Smsmith * to or modifications of the Original Intel Code. No other license or right 3665793Smsmith * is granted directly or by implication, estoppel or otherwise; 3765793Smsmith * 3865793Smsmith * The above copyright and patent license is granted only if the following 3983114Sscottl * conditions are met: 4065793Smsmith * 4165793Smsmith * 3. Conditions 4265793Smsmith * 4365793Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4465793Smsmith * Redistribution of source code of any substantial portion of the Covered 4583114Sscottl * Code or modification with rights to further distribute source must include 4665793Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4765793Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4865793Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4965793Smsmith * contain a file documenting the changes Licensee made to create that Covered 5065793Smsmith * Code and the date of any change. Licensee must include in that file the 5165793Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5265793Smsmith * must include a prominent statement that the modification is derived, 5365793Smsmith * directly or indirectly, from Original Intel Code. 5465793Smsmith * 5565793Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5681082Sscottl * Redistribution of source code of any substantial portion of the Covered 5781082Sscottl * Code or modification without rights to further distribute source must 5881082Sscottl * include the following Disclaimer and Export Compliance provision in the 5981082Sscottl * documentation and/or other materials provided with distribution. In 6081082Sscottl * addition, Licensee may not authorize further sublicense of source of any 6181082Sscottl * portion of the Covered Code, and must include terms to the effect that the 6281082Sscottl * license from Licensee to its licensee is limited to the intellectual 6381082Sscottl * property embodied in the software Licensee provides to its licensee, and 6481082Sscottl * not to intellectual property embodied in modifications its licensee may 6581082Sscottl * make. 6681082Sscottl * 6781082Sscottl * 3.3. Redistribution of Executable. Redistribution in executable form of any 6881082Sscottl * substantial portion of the Covered Code or modification must reproduce the 6981082Sscottl * above Copyright Notice, and the following Disclaimer and Export Compliance 7081082Sscottl * provision in the documentation and/or other materials provided with the 7181082Sscottl * distribution. 7265793Smsmith * 7365793Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7465793Smsmith * Intel Code. 7565793Smsmith * 7665793Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7765793Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7865793Smsmith * other dealings in products derived from or relating to the Covered Code 7965793Smsmith * without prior written authorization from Intel. 8065793Smsmith * 8165793Smsmith * 4. Disclaimer and Export Compliance 8265793Smsmith * 8365793Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8465793Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8583114Sscottl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8683114Sscottl * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87103870Salfred * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8865793Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8965793Smsmith * PARTICULAR PURPOSE. 9065793Smsmith * 9165793Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9265793Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9365793Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9465793Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9565793Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9665793Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9783114Sscottl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9883114Sscottl * LIMITED REMEDY. 9965793Smsmith * 10083114Sscottl * 4.3. Licensee shall not export, either directly or indirectly, any of this 10183114Sscottl * software or system incorporating such software without first obtaining any 10283114Sscottl * required license or other approval from the U. S. Department of Commerce or 10383114Sscottl * any other agency or department of the United States Government. In the 10483114Sscottl * event Licensee exports any such software from the United States or 10583114Sscottl * re-exports any such software from a foreign destination, Licensee shall 10683114Sscottl * ensure that the distribution and export/re-export of the software is in 10783114Sscottl * compliance with all laws, regulations, orders, or other restrictions of the 10883114Sscottl * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109103870Salfred * any of its subsidiaries will export/re-export any technical data, process, 11065793Smsmith * software, or service, directly or indirectly, to any country for which the 11165793Smsmith * United States government or any agency thereof requires an export license, 11265793Smsmith * other governmental approval, or letter of assurance, without first obtaining 11365793Smsmith * such license, approval or letter. 11465793Smsmith * 11565793Smsmith *****************************************************************************/ 11665793Smsmith 11765793Smsmith#define __NSACCESS_C__ 11865793Smsmith 11965793Smsmith#include "acpi.h" 12065793Smsmith#include "amlcode.h" 12165793Smsmith#include "acnamesp.h" 12265793Smsmith#include "acdispat.h" 12365793Smsmith 12465793Smsmith 12565793Smsmith#define _COMPONENT ACPI_NAMESPACE 12665793Smsmith ACPI_MODULE_NAME ("nsaccess") 12765793Smsmith 12865793Smsmith 12965793Smsmith/******************************************************************************* 13065793Smsmith * 131109088Sscottl * FUNCTION: AcpiNsRootInitialize 132109088Sscottl * 133103870Salfred * PARAMETERS: None 13465793Smsmith * 13565793Smsmith * RETURN: Status 13665793Smsmith * 13765793Smsmith * DESCRIPTION: Allocate and initialize the default root named objects 13865793Smsmith * 13965793Smsmith * MUTEX: Locks namespace for entire execution 14083114Sscottl * 14183114Sscottl ******************************************************************************/ 14283114Sscottl 14383114SscottlACPI_STATUS 14483114SscottlAcpiNsRootInitialize (void) 14583114Sscottl{ 14683114Sscottl ACPI_STATUS Status; 14783114Sscottl const ACPI_PREDEFINED_NAMES *InitVal = NULL; 14883114Sscottl ACPI_NAMESPACE_NODE *NewNode; 14983114Sscottl ACPI_OPERAND_OBJECT *ObjDesc; 15083114Sscottl ACPI_STRING Val = NULL; 15183114Sscottl 15283114Sscottl 15383114Sscottl ACPI_FUNCTION_TRACE ("NsRootInitialize"); 15483114Sscottl 15583114Sscottl 156103870Salfred Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 15765793Smsmith if (ACPI_FAILURE (Status)) 15865793Smsmith { 15965793Smsmith return_ACPI_STATUS (Status); 16065793Smsmith } 16183114Sscottl 16283114Sscottl /* 163103870Salfred * The global root ptr is initially NULL, so a non-NULL value indicates 16465793Smsmith * that AcpiNsRootInitialize() has already been called; just return. 16565793Smsmith */ 16665793Smsmith if (AcpiGbl_RootNode) 16765793Smsmith { 16865793Smsmith Status = AE_OK; 16983114Sscottl goto UnlockAndExit; 17083114Sscottl } 17165793Smsmith 17283114Sscottl /* 17383114Sscottl * Tell the rest of the subsystem that the root is initialized 17483114Sscottl * (This is OK because the namespace is locked) 17583114Sscottl */ 17683114Sscottl AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; 17783114Sscottl 17883114Sscottl /* Enter the pre-defined names in the name table */ 17983114Sscottl 18083114Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 18183114Sscottl "Entering predefined entries into namespace\n")); 18283114Sscottl 18383114Sscottl for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) 18483114Sscottl { 18583114Sscottl /* _OSI is optional for now, will be permanent later */ 18683114Sscottl 18783114Sscottl if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) 18883114Sscottl { 18983114Sscottl continue; 19083114Sscottl } 19183114Sscottl 19283114Sscottl Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type, 19365793Smsmith ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, 19483114Sscottl NULL, &NewNode); 19583114Sscottl 19683114Sscottl if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */ 19783114Sscottl { 19883114Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 19965793Smsmith "Could not create predefined name %s, %s\n", 20083114Sscottl InitVal->Name, AcpiFormatException (Status))); 20183114Sscottl } 20283114Sscottl 203151086Sscottl /* 20465793Smsmith * Name entered successfully. 20583114Sscottl * If entry in PreDefinedNames[] specifies an 20683114Sscottl * initial value, create the initial value. 20765793Smsmith */ 20883114Sscottl if (InitVal->Val) 20983114Sscottl { 210151086Sscottl Status = AcpiOsPredefinedOverride (InitVal, &Val); 211151086Sscottl if (ACPI_FAILURE (Status)) 212151086Sscottl { 213151086Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 21465793Smsmith "Could not override predefined %s\n", 21583114Sscottl InitVal->Name)); 21683114Sscottl } 21783114Sscottl 21883114Sscottl if (!Val) 21983114Sscottl { 22083114Sscottl Val = InitVal->Val; 22183114Sscottl } 222151086Sscottl 223206534Semaste /* 224151086Sscottl * Entry requests an initial value, allocate a 225151086Sscottl * descriptor for it. 226206534Semaste */ 227206534Semaste ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); 228206534Semaste if (!ObjDesc) 229151086Sscottl { 230151086Sscottl Status = AE_NO_MEMORY; 231151086Sscottl goto UnlockAndExit; 232151086Sscottl } 233151086Sscottl 234151086Sscottl /* 235206534Semaste * Convert value string from table entry to 236206534Semaste * internal representation. Only types actually 23765793Smsmith * used for initial values are implemented here. 23865793Smsmith */ 23965793Smsmith switch (InitVal->Type) 24065793Smsmith { 24165793Smsmith case ACPI_TYPE_METHOD: 24265793Smsmith ObjDesc->Method.ParamCount = (UINT8) ACPI_STRTOUL 24365793Smsmith (Val, NULL, 10); 24465793Smsmith ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 24565793Smsmith 24665793Smsmith#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_APP) 24765793Smsmith 24865793Smsmith /* iASL Compiler cheats by putting parameter count in the OwnerID */ 24981082Sscottl 25081082Sscottl NewNode->OwnerId = ObjDesc->Method.ParamCount; 25181082Sscottl#else 25281082Sscottl /* Mark this as a very SPECIAL method */ 25381082Sscottl 25481082Sscottl ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY; 25581082Sscottl ObjDesc->Method.Implementation = AcpiUtOsiImplementation; 25681082Sscottl#endif 25781082Sscottl break; 25881082Sscottl 25981082Sscottl case ACPI_TYPE_INTEGER: 26081082Sscottl 26181082Sscottl ObjDesc->Integer.Value = 26281082Sscottl (ACPI_INTEGER) ACPI_STRTOUL (Val, NULL, 10); 26381082Sscottl break; 26481082Sscottl 26581082Sscottl 26681082Sscottl case ACPI_TYPE_STRING: 26781082Sscottl 26881082Sscottl /* 26981082Sscottl * Build an object around the static string 27081082Sscottl */ 27165793Smsmith ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val); 27265793Smsmith ObjDesc->String.Pointer = Val; 27365793Smsmith ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 27465793Smsmith break; 27565793Smsmith 27665793Smsmith 27765793Smsmith case ACPI_TYPE_MUTEX: 27865793Smsmith 27965793Smsmith ObjDesc->Mutex.Node = NewNode; 28065793Smsmith ObjDesc->Mutex.SyncLevel = (UINT8) ACPI_STRTOUL 28165793Smsmith (Val, NULL, 10); 28265793Smsmith 28365793Smsmith if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0) 28465793Smsmith { 28565793Smsmith /* 286206534Semaste * Create a counting semaphore for the 28765793Smsmith * global lock 28865793Smsmith */ 28965793Smsmith Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 29083114Sscottl 1, &ObjDesc->Mutex.Semaphore); 291109088Sscottl if (ACPI_FAILURE (Status)) 292151086Sscottl { 29383114Sscottl goto UnlockAndExit; 294109088Sscottl } 29583114Sscottl 29683114Sscottl /* 29783114Sscottl * We just created the mutex for the 29883114Sscottl * global lock, save it 299109088Sscottl */ 30083114Sscottl AcpiGbl_GlobalLockSemaphore = ObjDesc->Mutex.Semaphore; 30183114Sscottl } 30283114Sscottl else 30383114Sscottl { 304109088Sscottl /* Create a mutex */ 30583114Sscottl 30683114Sscottl Status = AcpiOsCreateSemaphore (1, 1, 307151086Sscottl &ObjDesc->Mutex.Semaphore); 308151086Sscottl if (ACPI_FAILURE (Status)) 309212628Semaste { 310212628Semaste goto UnlockAndExit; 311212628Semaste } 312151086Sscottl } 313151086Sscottl break; 314151086Sscottl 315103870Salfred 31665793Smsmith default: 31783114Sscottl 31865793Smsmith ACPI_REPORT_ERROR (("Unsupported initial type value %X\n", 31965793Smsmith InitVal->Type)); 32065793Smsmith AcpiUtRemoveReference (ObjDesc); 32165793Smsmith ObjDesc = NULL; 32265793Smsmith continue; 32365793Smsmith } 32483114Sscottl 32583114Sscottl /* Store pointer to value descriptor in the Node */ 32683114Sscottl 32783114Sscottl Status = AcpiNsAttachObject (NewNode, ObjDesc, ACPI_GET_OBJECT_TYPE (ObjDesc)); 32883114Sscottl 32983114Sscottl /* Remove local reference to the object */ 33083114Sscottl 33183114Sscottl AcpiUtRemoveReference (ObjDesc); 33283114Sscottl } 33383114Sscottl } 334206534Semaste 335206534Semaste 336206534SemasteUnlockAndExit: 337206534Semaste (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 338206534Semaste 339206534Semaste /* Save a handle to "_GPE", it is always present */ 340151086Sscottl 341206534Semaste if (ACPI_SUCCESS (Status)) 342151086Sscottl { 343151086Sscottl Status = AcpiNsGetNodeByPath ("\\_GPE", NULL, ACPI_NS_NO_UPSEARCH, 34465793Smsmith &AcpiGbl_FadtGpeDevice); 34565793Smsmith } 34665793Smsmith 34765793Smsmith return_ACPI_STATUS (Status); 34865793Smsmith} 34965793Smsmith 350206534Semaste 351206534Semaste/******************************************************************************* 352206534Semaste * 353206534Semaste * FUNCTION: AcpiNsLookup 354206534Semaste * 355206534Semaste * PARAMETERS: PrefixNode - Search scope if name is not fully qualified 356206534Semaste * Pathname - Search pathname, in internal format 357206534Semaste * (as represented in the AML stream) 358206534Semaste * Type - Type associated with name 359206534Semaste * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found 360206534Semaste * Flags - Flags describing the search restrictions 36183114Sscottl * WalkState - Current state of the walk 362206534Semaste * ReturnNode - Where the Node is placed (if found 363206534Semaste * or created successfully) 364206534Semaste * 365206534Semaste * RETURN: Status 366206534Semaste * 36765793Smsmith * DESCRIPTION: Find or enter the passed name in the name space. 36865793Smsmith * Log an error if name not found in Exec mode. 36965793Smsmith * 37065793Smsmith * MUTEX: Assumes namespace is locked. 37165793Smsmith * 37265793Smsmith ******************************************************************************/ 37383114Sscottl 37483114SscottlACPI_STATUS 375103870SalfredAcpiNsLookup ( 37665793Smsmith ACPI_GENERIC_STATE *ScopeInfo, 377112679Sscottl char *Pathname, 378112679Sscottl ACPI_OBJECT_TYPE Type, 379112679Sscottl ACPI_INTERPRETER_MODE InterpreterMode, 380112679Sscottl UINT32 Flags, 381112679Sscottl ACPI_WALK_STATE *WalkState, 382151086Sscottl ACPI_NAMESPACE_NODE **ReturnNode) 383151086Sscottl{ 384151086Sscottl ACPI_STATUS Status; 385151086Sscottl char *Path = Pathname; 386151086Sscottl ACPI_NAMESPACE_NODE *PrefixNode; 387151086Sscottl ACPI_NAMESPACE_NODE *CurrentNode = NULL; 388151086Sscottl ACPI_NAMESPACE_NODE *ThisNode = NULL; 389151086Sscottl UINT32 NumSegments; 39065793Smsmith UINT32 NumCarats; 39183114Sscottl ACPI_NAME SimpleName; 39283114Sscottl ACPI_OBJECT_TYPE TypeToCheckFor; 393103870Salfred ACPI_OBJECT_TYPE ThisSearchType; 39465793Smsmith UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT; 39565793Smsmith UINT32 LocalFlags = Flags & ~(ACPI_NS_ERROR_IF_FOUND | 39665793Smsmith ACPI_NS_SEARCH_PARENT); 39765793Smsmith 39865793Smsmith 399112679Sscottl ACPI_FUNCTION_TRACE ("NsLookup"); 400112679Sscottl 401103870Salfred 40265793Smsmith if (!ReturnNode) 40365793Smsmith { 404151086Sscottl return_ACPI_STATUS (AE_BAD_PARAMETER); 405151086Sscottl } 406151086Sscottl 407151086Sscottl AcpiGbl_NsLookupCount++; 408151086Sscottl *ReturnNode = ACPI_ENTRY_NOT_FOUND; 409151086Sscottl 410151086Sscottl if (!AcpiGbl_RootNode) 411151086Sscottl { 41265793Smsmith return_ACPI_STATUS (AE_NO_NAMESPACE); 41365793Smsmith } 41465793Smsmith 41583114Sscottl /* 41683114Sscottl * Get the prefix scope. 41783114Sscottl * A null scope means use the root scope 41883114Sscottl */ 41983114Sscottl if ((!ScopeInfo) || 42083114Sscottl (!ScopeInfo->Scope.Node)) 42183114Sscottl { 42283114Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 42383114Sscottl "Null scope prefix, using root node (%p)\n", 42483114Sscottl AcpiGbl_RootNode)); 425103870Salfred 42665793Smsmith PrefixNode = AcpiGbl_RootNode; 42783114Sscottl } 42865793Smsmith else 42965793Smsmith { 43065793Smsmith PrefixNode = ScopeInfo->Scope.Node; 43165793Smsmith if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED) 43283114Sscottl { 43383114Sscottl ACPI_REPORT_ERROR (("NsLookup: %p is not a namespace node [%s]\n", 43483114Sscottl PrefixNode, AcpiUtGetDescriptorName (PrefixNode))); 43583114Sscottl return_ACPI_STATUS (AE_AML_INTERNAL); 43683114Sscottl } 43783114Sscottl 43883114Sscottl /* 43983114Sscottl * This node might not be a actual "scope" node (such as a 44083114Sscottl * Device/Method, etc.) It could be a Package or other object node. 44165793Smsmith * Backup up the tree to find the containing scope node. 44265793Smsmith */ 44365793Smsmith while (!AcpiNsOpensScope (PrefixNode->Type) && 44483114Sscottl PrefixNode->Type != ACPI_TYPE_ANY) 44583114Sscottl { 44683114Sscottl PrefixNode = AcpiNsGetParentNode (PrefixNode); 44783114Sscottl } 44883114Sscottl } 44983114Sscottl 45083114Sscottl /* Save type TBD: may be no longer necessary */ 45183114Sscottl 45283114Sscottl TypeToCheckFor = Type; 45383114Sscottl 454103870Salfred /* 45565793Smsmith * Begin examination of the actual pathname 45683114Sscottl */ 45765793Smsmith if (!Pathname) 45865793Smsmith { 45965793Smsmith /* A Null NamePath is allowed and refers to the root */ 46065793Smsmith 46183114Sscottl NumSegments = 0; 46283114Sscottl ThisNode = AcpiGbl_RootNode; 46383114Sscottl Path = ""; 46483114Sscottl 46583114Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 46683114Sscottl "Null Pathname (Zero segments), Flags=%X\n", Flags)); 46783114Sscottl } 46883114Sscottl else 469151086Sscottl { 470151086Sscottl /* 47183114Sscottl * Name pointer is valid (and must be in internal name format) 472206534Semaste * 47365793Smsmith * Check for scope prefixes: 47465793Smsmith * 47583114Sscottl * As represented in the AML stream, a namepath consists of an 47683114Sscottl * optional scope prefix followed by a name segment part. 47783114Sscottl * 47883114Sscottl * If present, the scope prefix is either a Root Prefix (in 47983114Sscottl * which case the name is fully qualified), or one or more 48083114Sscottl * Parent Prefixes (in which case the name's scope is relative 481151086Sscottl * to the current scope). 48283114Sscottl */ 483151086Sscottl if (*Path == (UINT8) AML_ROOT_PREFIX) 484151086Sscottl { 485151086Sscottl /* Pathname is fully qualified, start from the root */ 486151086Sscottl 48783114Sscottl ThisNode = AcpiGbl_RootNode; 48865793Smsmith SearchParentFlag = ACPI_NS_NO_UPSEARCH; 48965793Smsmith 49065793Smsmith /* Point to name segment part */ 49183114Sscottl 49283114Sscottl Path++; 49383114Sscottl 49483114Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 49583114Sscottl "Path is absolute from root [%p]\n", ThisNode)); 49683114Sscottl } 49783114Sscottl else 49883114Sscottl { 49983114Sscottl /* Pathname is relative to current scope, start there */ 50083114Sscottl 50183114Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 50283114Sscottl "Searching relative to prefix scope [%4.4s] (%p)\n", 50383114Sscottl AcpiUtGetNodeName (PrefixNode), PrefixNode)); 50483114Sscottl 50583114Sscottl /* 50683114Sscottl * Handle multiple Parent Prefixes (carat) by just getting 50783114Sscottl * the parent node for each prefix instance. 50883114Sscottl */ 50983114Sscottl ThisNode = PrefixNode; 51083114Sscottl NumCarats = 0; 511151086Sscottl while (*Path == (UINT8) AML_PARENT_PREFIX) 512151086Sscottl { 513151086Sscottl /* Name is fully qualified, no search rules apply */ 514151086Sscottl 515151086Sscottl SearchParentFlag = ACPI_NS_NO_UPSEARCH; 516151086Sscottl /* 517151086Sscottl * Point past this prefix to the name segment 518151086Sscottl * part or the next Parent Prefix 519151086Sscottl */ 520151086Sscottl Path++; 521151086Sscottl 522151086Sscottl /* Backup to the parent node */ 523151086Sscottl 524151086Sscottl NumCarats++; 52583114Sscottl ThisNode = AcpiNsGetParentNode (ThisNode); 52665793Smsmith if (!ThisNode) 52765793Smsmith { 52865793Smsmith /* Current scope has no parent scope */ 52983114Sscottl 53083114Sscottl ACPI_REPORT_ERROR ( 53183114Sscottl ("ACPI path has too many parent prefixes (^) - reached beyond root node\n")); 53283114Sscottl return_ACPI_STATUS (AE_NOT_FOUND); 53383114Sscottl } 534151086Sscottl } 535151086Sscottl 53683114Sscottl if (SearchParentFlag == ACPI_NS_NO_UPSEARCH) 537151086Sscottl { 538151086Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 539151086Sscottl "Search scope is [%4.4s], path has %d carat(s)\n", 540151086Sscottl AcpiUtGetNodeName (ThisNode), NumCarats)); 541151086Sscottl } 54283114Sscottl } 54365793Smsmith 54465793Smsmith /* 54565793Smsmith * Determine the number of ACPI name segments in this pathname. 54665793Smsmith * 54765793Smsmith * The segment part consists of either: 54865793Smsmith * - A Null name segment (0) 549206534Semaste * - A DualNamePrefix followed by two 4-byte name segments 55083114Sscottl * - A MultiNamePrefix followed by a byte indicating the 55183114Sscottl * number of segments and the segments themselves. 55283114Sscottl * - A single 4-byte name segment 55383114Sscottl * 55483114Sscottl * Examine the name prefix opcode, if any, to determine the number of 55565793Smsmith * segments. 55665793Smsmith */ 557206534Semaste switch (*Path) 55865793Smsmith { 559206534Semaste case 0: 56065793Smsmith /* 56165793Smsmith * Null name after a root or parent prefixes. We already 56265793Smsmith * have the correct target node and there are no name segments. 56365793Smsmith */ 56465793Smsmith NumSegments = 0; 56565793Smsmith Type = ThisNode->Type; 56665793Smsmith 56765793Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 568112679Sscottl "Prefix-only Pathname (Zero name segments), Flags=%X\n", Flags)); 569112679Sscottl break; 570112679Sscottl 571112679Sscottl case AML_DUAL_NAME_PREFIX: 572112679Sscottl 573112679Sscottl /* More than one NameSeg, search rules do not apply */ 574112679Sscottl 575151086Sscottl SearchParentFlag = ACPI_NS_NO_UPSEARCH; 576151086Sscottl 577151086Sscottl /* Two segments, point to first name segment */ 578151086Sscottl 579151086Sscottl NumSegments = 2; 580151086Sscottl Path++; 58165793Smsmith 582206534Semaste ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 58365793Smsmith "Dual Pathname (2 segments, Flags=%X)\n", Flags)); 58465793Smsmith break; 58565793Smsmith 586206534Semaste case AML_MULTI_NAME_PREFIX_OP: 58783114Sscottl 588206534Semaste /* More than one NameSeg, search rules do not apply */ 589206534Semaste 590206534Semaste SearchParentFlag = ACPI_NS_NO_UPSEARCH; 59183114Sscottl 592206534Semaste /* Extract segment count, point to first name segment */ 593206534Semaste 59483114Sscottl Path++; 59583114Sscottl NumSegments = (UINT32) (UINT8) *Path; 59683114Sscottl Path++; 59783114Sscottl 59883114Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 599206534Semaste "Multi Pathname (%d Segments, Flags=%X) \n", 60083114Sscottl NumSegments, Flags)); 60183114Sscottl break; 60283114Sscottl 60383114Sscottl default: 60483114Sscottl /* 60583114Sscottl * Not a Null name, no Dual or Multi prefix, hence there is 60683114Sscottl * only one name segment and Pathname is already pointing to it. 607103870Salfred */ 60865793Smsmith NumSegments = 1; 609206534Semaste 610174412Semaste ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 611174412Semaste "Simple Pathname (1 segment, Flags=%X)\n", Flags)); 612174412Semaste break; 613174412Semaste } 614174412Semaste 615174412Semaste ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path)); 616174412Semaste } 617174412Semaste 618174412Semaste 619174412Semaste /* 620174412Semaste * Search namespace for each segment of the name. Loop through and 621174412Semaste * verify (or add to the namespace) each name segment. 622174412Semaste * 623174412Semaste * The object type is significant only at the last name 624174412Semaste * segment. (We don't care about the types along the path, only 625174412Semaste * the type of the final target object.) 626174412Semaste */ 627174412Semaste ThisSearchType = ACPI_TYPE_ANY; 628174412Semaste CurrentNode = ThisNode; 629174412Semaste while (NumSegments && CurrentNode) 630174412Semaste { 631174412Semaste NumSegments--; 632174412Semaste if (!NumSegments) 633174412Semaste { 634174412Semaste /* 635174412Semaste * This is the last segment, enable typechecking 636174412Semaste */ 637174412Semaste ThisSearchType = Type; 638174412Semaste 639174412Semaste /* 640174412Semaste * Only allow automatic parent search (search rules) if the caller 641174412Semaste * requested it AND we have a single, non-fully-qualified NameSeg 642174412Semaste */ 643174412Semaste if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) && 644174412Semaste (Flags & ACPI_NS_SEARCH_PARENT)) 645174412Semaste { 646174412Semaste LocalFlags |= ACPI_NS_SEARCH_PARENT; 647174412Semaste } 648174412Semaste 649174412Semaste /* Set error flag according to caller */ 650174412Semaste 651174412Semaste if (Flags & ACPI_NS_ERROR_IF_FOUND) 652174412Semaste { 653174412Semaste LocalFlags |= ACPI_NS_ERROR_IF_FOUND; 654174412Semaste } 655174412Semaste } 656174412Semaste 657174412Semaste /* Extract one ACPI name from the front of the pathname */ 658174412Semaste 659174412Semaste ACPI_MOVE_32_TO_32 (&SimpleName, Path); 660174412Semaste 66183114Sscottl /* Try to find the single (4 character) ACPI name */ 66265793Smsmith 66365793Smsmith Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode, 66465793Smsmith InterpreterMode, ThisSearchType, LocalFlags, &ThisNode); 66565793Smsmith if (ACPI_FAILURE (Status)) 66665793Smsmith { 66765793Smsmith if (Status == AE_NOT_FOUND) 668151086Sscottl { 66965793Smsmith /* Name not found in ACPI namespace */ 67065793Smsmith 67190275Sscottl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 672151086Sscottl "Name [%4.4s] not found in scope [%4.4s] %p\n", 673112679Sscottl (char *) &SimpleName, (char *) &CurrentNode->Name, 674151086Sscottl CurrentNode)); 675151086Sscottl } 676151086Sscottl 677151086Sscottl *ReturnNode = ThisNode; 67865793Smsmith return_ACPI_STATUS (Status); 67965793Smsmith } 68065793Smsmith 68165793Smsmith /* 68265793Smsmith * Sanity typecheck of the target object: 68365793Smsmith * 68465793Smsmith * If 1) This is the last segment (NumSegments == 0) 68565793Smsmith * 2) And we are looking for a specific type 68665793Smsmith * (Not checking for TYPE_ANY) 68765793Smsmith * 3) Which is not an alias 68865793Smsmith * 4) Which is not a local type (TYPE_SCOPE) 68965793Smsmith * 5) And the type of target object is known (not TYPE_ANY) 69065793Smsmith * 6) And target object does not match what we are looking for 69165793Smsmith * 692140669Sscottl * Then we have a type mismatch. Just warn and ignore it. 69365793Smsmith */ 69465793Smsmith if ((NumSegments == 0) && 69565793Smsmith (TypeToCheckFor != ACPI_TYPE_ANY) && 69683114Sscottl (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) && 697206534Semaste (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 69865793Smsmith (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) && 69965793Smsmith (ThisNode->Type != ACPI_TYPE_ANY) && 70065793Smsmith (ThisNode->Type != TypeToCheckFor)) 70165793Smsmith { 70265793Smsmith /* Complain about a type mismatch */ 70365793Smsmith 70465793Smsmith ACPI_REPORT_WARNING ( 70565793Smsmith ("NsLookup: Type mismatch on %4.4s (%s), searching for (%s)\n", 70665793Smsmith (char *) &SimpleName, AcpiUtGetTypeName (ThisNode->Type), 70783114Sscottl AcpiUtGetTypeName (TypeToCheckFor))); 70883114Sscottl } 70983114Sscottl 71083114Sscottl /* 71183114Sscottl * If this is the last name segment and we are not looking for a 71283114Sscottl * specific type, but the type of found object is known, use that type 71365793Smsmith * to see if it opens a scope. 71465793Smsmith */ 71565793Smsmith if ((NumSegments == 0) && (Type == ACPI_TYPE_ANY)) 71665793Smsmith { 71765793Smsmith Type = ThisNode->Type; 71865793Smsmith } 71965793Smsmith 72083114Sscottl /* Point to next name segment and make this node current */ 72183114Sscottl 72283114Sscottl Path += ACPI_NAME_SIZE; 72383114Sscottl CurrentNode = ThisNode; 72483114Sscottl } 72583114Sscottl 72665793Smsmith /* 72765793Smsmith * Always check if we need to open a new scope 72865793Smsmith */ 72965793Smsmith if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState)) 73065793Smsmith { 73165793Smsmith /* 73283114Sscottl * If entry is a type which opens a scope, push the new scope on the 73383114Sscottl * scope stack. 73483114Sscottl */ 73583114Sscottl if (AcpiNsOpensScope (Type)) 73683114Sscottl { 73783114Sscottl Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState); 73865793Smsmith if (ACPI_FAILURE (Status)) 73965793Smsmith { 74065793Smsmith return_ACPI_STATUS (Status); 74165793Smsmith } 74265793Smsmith } 74365793Smsmith } 74483114Sscottl 74583114Sscottl *ReturnNode = ThisNode; 74683114Sscottl return_ACPI_STATUS (AE_OK); 74783114Sscottl} 74883114Sscottl 749103870Salfred