13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 4*7851SDana.Myers@Sun.COM * $Revision: 1.209 $ 53446Smrj * 63446Smrj ******************************************************************************/ 73446Smrj 83446Smrj /****************************************************************************** 93446Smrj * 103446Smrj * 1. Copyright Notice 113446Smrj * 12*7851SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 133446Smrj * All rights reserved. 143446Smrj * 153446Smrj * 2. License 163446Smrj * 173446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 183446Smrj * rights. You may have additional license terms from the party that provided 193446Smrj * you this software, covering your right to use that party's intellectual 203446Smrj * property rights. 213446Smrj * 223446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 233446Smrj * copy of the source code appearing in this file ("Covered Code") an 243446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 253446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 263446Smrj * make derivatives, distribute, use and display any portion of the Covered 273446Smrj * Code in any form, with the right to sublicense such rights; and 283446Smrj * 293446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 303446Smrj * license (with the right to sublicense), under only those claims of Intel 313446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 323446Smrj * offer to sell, and import the Covered Code and derivative works thereof 333446Smrj * solely to the minimum extent necessary to exercise the above copyright 343446Smrj * license, and in no event shall the patent license extend to any additions 353446Smrj * to or modifications of the Original Intel Code. No other license or right 363446Smrj * is granted directly or by implication, estoppel or otherwise; 373446Smrj * 383446Smrj * The above copyright and patent license is granted only if the following 393446Smrj * conditions are met: 403446Smrj * 413446Smrj * 3. Conditions 423446Smrj * 433446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 443446Smrj * Redistribution of source code of any substantial portion of the Covered 453446Smrj * Code or modification with rights to further distribute source must include 463446Smrj * the above Copyright Notice, the above License, this list of Conditions, 473446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 483446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 493446Smrj * contain a file documenting the changes Licensee made to create that Covered 503446Smrj * Code and the date of any change. Licensee must include in that file the 513446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 523446Smrj * must include a prominent statement that the modification is derived, 533446Smrj * directly or indirectly, from Original Intel Code. 543446Smrj * 553446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 563446Smrj * Redistribution of source code of any substantial portion of the Covered 573446Smrj * Code or modification without rights to further distribute source must 583446Smrj * include the following Disclaimer and Export Compliance provision in the 593446Smrj * documentation and/or other materials provided with distribution. In 603446Smrj * addition, Licensee may not authorize further sublicense of source of any 613446Smrj * portion of the Covered Code, and must include terms to the effect that the 623446Smrj * license from Licensee to its licensee is limited to the intellectual 633446Smrj * property embodied in the software Licensee provides to its licensee, and 643446Smrj * not to intellectual property embodied in modifications its licensee may 653446Smrj * make. 663446Smrj * 673446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 683446Smrj * substantial portion of the Covered Code or modification must reproduce the 693446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 703446Smrj * provision in the documentation and/or other materials provided with the 713446Smrj * distribution. 723446Smrj * 733446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 743446Smrj * Intel Code. 753446Smrj * 763446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 773446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 783446Smrj * other dealings in products derived from or relating to the Covered Code 793446Smrj * without prior written authorization from Intel. 803446Smrj * 813446Smrj * 4. Disclaimer and Export Compliance 823446Smrj * 833446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 843446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 853446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 863446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 873446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 883446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 893446Smrj * PARTICULAR PURPOSE. 903446Smrj * 913446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 923446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 933446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 943446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 953446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 963446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 973446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 983446Smrj * LIMITED REMEDY. 993446Smrj * 1003446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 1013446Smrj * software or system incorporating such software without first obtaining any 1023446Smrj * required license or other approval from the U. S. Department of Commerce or 1033446Smrj * any other agency or department of the United States Government. In the 1043446Smrj * event Licensee exports any such software from the United States or 1053446Smrj * re-exports any such software from a foreign destination, Licensee shall 1063446Smrj * ensure that the distribution and export/re-export of the software is in 1073446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 1083446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1093446Smrj * any of its subsidiaries will export/re-export any technical data, process, 1103446Smrj * software, or service, directly or indirectly, to any country for which the 1113446Smrj * United States government or any agency thereof requires an export license, 1123446Smrj * other governmental approval, or letter of assurance, without first obtaining 1133446Smrj * such license, approval or letter. 1143446Smrj * 1153446Smrj *****************************************************************************/ 1163446Smrj 1173446Smrj #define __NSACCESS_C__ 1183446Smrj 1193446Smrj #include "acpi.h" 1203446Smrj #include "amlcode.h" 1213446Smrj #include "acnamesp.h" 1223446Smrj #include "acdispat.h" 1233446Smrj 1243446Smrj 1253446Smrj #define _COMPONENT ACPI_NAMESPACE 1263446Smrj ACPI_MODULE_NAME ("nsaccess") 1273446Smrj 1283446Smrj 1293446Smrj /******************************************************************************* 1303446Smrj * 1313446Smrj * FUNCTION: AcpiNsRootInitialize 1323446Smrj * 1333446Smrj * PARAMETERS: None 1343446Smrj * 1353446Smrj * RETURN: Status 1363446Smrj * 1373446Smrj * DESCRIPTION: Allocate and initialize the default root named objects 1383446Smrj * 1393446Smrj * MUTEX: Locks namespace for entire execution 1403446Smrj * 1413446Smrj ******************************************************************************/ 1423446Smrj 1433446Smrj ACPI_STATUS 1443446Smrj AcpiNsRootInitialize ( 1453446Smrj void) 1463446Smrj { 1473446Smrj ACPI_STATUS Status; 1483446Smrj const ACPI_PREDEFINED_NAMES *InitVal = NULL; 1493446Smrj ACPI_NAMESPACE_NODE *NewNode; 1503446Smrj ACPI_OPERAND_OBJECT *ObjDesc; 1513446Smrj ACPI_STRING Val = NULL; 1523446Smrj 1533446Smrj 1543446Smrj ACPI_FUNCTION_TRACE (NsRootInitialize); 1553446Smrj 1563446Smrj 1573446Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1583446Smrj if (ACPI_FAILURE (Status)) 1593446Smrj { 1603446Smrj return_ACPI_STATUS (Status); 1613446Smrj } 1623446Smrj 1633446Smrj /* 1643446Smrj * The global root ptr is initially NULL, so a non-NULL value indicates 1653446Smrj * that AcpiNsRootInitialize() has already been called; just return. 1663446Smrj */ 1673446Smrj if (AcpiGbl_RootNode) 1683446Smrj { 1693446Smrj Status = AE_OK; 1703446Smrj goto UnlockAndExit; 1713446Smrj } 1723446Smrj 1733446Smrj /* 1743446Smrj * Tell the rest of the subsystem that the root is initialized 1753446Smrj * (This is OK because the namespace is locked) 1763446Smrj */ 1773446Smrj AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; 1783446Smrj 1793446Smrj /* Enter the pre-defined names in the name table */ 1803446Smrj 1813446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 1823446Smrj "Entering predefined entries into namespace\n")); 1833446Smrj 1843446Smrj for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) 1853446Smrj { 1863446Smrj /* _OSI is optional for now, will be permanent later */ 1873446Smrj 1883446Smrj if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) 1893446Smrj { 1903446Smrj continue; 1913446Smrj } 1923446Smrj 1933446Smrj Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type, 1943446Smrj ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, 1953446Smrj NULL, &NewNode); 1963446Smrj 1973446Smrj if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */ 1983446Smrj { 1993446Smrj ACPI_EXCEPTION ((AE_INFO, Status, 2003446Smrj "Could not create predefined name %s", 2013446Smrj InitVal->Name)); 2023446Smrj } 2033446Smrj 2043446Smrj /* 2053446Smrj * Name entered successfully. 2063446Smrj * If entry in PreDefinedNames[] specifies an 2073446Smrj * initial value, create the initial value. 2083446Smrj */ 2093446Smrj if (InitVal->Val) 2103446Smrj { 2113446Smrj Status = AcpiOsPredefinedOverride (InitVal, &Val); 2123446Smrj if (ACPI_FAILURE (Status)) 2133446Smrj { 2143446Smrj ACPI_ERROR ((AE_INFO, 2153446Smrj "Could not override predefined %s", 2163446Smrj InitVal->Name)); 2173446Smrj } 2183446Smrj 2193446Smrj if (!Val) 2203446Smrj { 2213446Smrj Val = InitVal->Val; 2223446Smrj } 2233446Smrj 2243446Smrj /* 2253446Smrj * Entry requests an initial value, allocate a 2263446Smrj * descriptor for it. 2273446Smrj */ 2283446Smrj ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); 2293446Smrj if (!ObjDesc) 2303446Smrj { 2313446Smrj Status = AE_NO_MEMORY; 2323446Smrj goto UnlockAndExit; 2333446Smrj } 2343446Smrj 2353446Smrj /* 2363446Smrj * Convert value string from table entry to 2373446Smrj * internal representation. Only types actually 2383446Smrj * used for initial values are implemented here. 2393446Smrj */ 2403446Smrj switch (InitVal->Type) 2413446Smrj { 2423446Smrj case ACPI_TYPE_METHOD: 2433446Smrj ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val); 2443446Smrj ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 2453446Smrj 2463446Smrj #if defined (ACPI_ASL_COMPILER) 2473446Smrj 2483446Smrj /* Save the parameter count for the iASL compiler */ 2493446Smrj 2503446Smrj NewNode->Value = ObjDesc->Method.ParamCount; 2513446Smrj #else 2523446Smrj /* Mark this as a very SPECIAL method */ 2533446Smrj 2543446Smrj ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY; 2553446Smrj 2563446Smrj #ifndef ACPI_DUMP_APP 2573446Smrj ObjDesc->Method.Implementation = AcpiUtOsiImplementation; 2583446Smrj #endif 2593446Smrj #endif 2603446Smrj break; 2613446Smrj 2623446Smrj case ACPI_TYPE_INTEGER: 2633446Smrj 2643446Smrj ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val); 2653446Smrj break; 2663446Smrj 2673446Smrj 2683446Smrj case ACPI_TYPE_STRING: 2693446Smrj 2703446Smrj /* 2713446Smrj * Build an object around the static string 2723446Smrj */ 2733446Smrj ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val); 2743446Smrj ObjDesc->String.Pointer = Val; 2753446Smrj ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 2763446Smrj break; 2773446Smrj 2783446Smrj 2793446Smrj case ACPI_TYPE_MUTEX: 2803446Smrj 2813446Smrj ObjDesc->Mutex.Node = NewNode; 2823446Smrj ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1); 2833446Smrj 2843446Smrj /* Create a mutex */ 2853446Smrj 2863446Smrj Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 2873446Smrj if (ACPI_FAILURE (Status)) 2883446Smrj { 2893446Smrj AcpiUtRemoveReference (ObjDesc); 2903446Smrj goto UnlockAndExit; 2913446Smrj } 2923446Smrj 2933446Smrj /* Special case for ACPI Global Lock */ 2943446Smrj 2953446Smrj if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0) 2963446Smrj { 297*7851SDana.Myers@Sun.COM AcpiGbl_GlobalLockMutex = ObjDesc; 2983446Smrj 2993446Smrj /* Create additional counting semaphore for global lock */ 3003446Smrj 3013446Smrj Status = AcpiOsCreateSemaphore ( 302*7851SDana.Myers@Sun.COM 1, 0, &AcpiGbl_GlobalLockSemaphore); 3033446Smrj if (ACPI_FAILURE (Status)) 3043446Smrj { 3053446Smrj AcpiUtRemoveReference (ObjDesc); 3063446Smrj goto UnlockAndExit; 3073446Smrj } 3083446Smrj } 3093446Smrj break; 3103446Smrj 3113446Smrj 3123446Smrj default: 3133446Smrj 3143446Smrj ACPI_ERROR ((AE_INFO, "Unsupported initial type value %X", 3153446Smrj InitVal->Type)); 3163446Smrj AcpiUtRemoveReference (ObjDesc); 3173446Smrj ObjDesc = NULL; 3183446Smrj continue; 3193446Smrj } 3203446Smrj 3213446Smrj /* Store pointer to value descriptor in the Node */ 3223446Smrj 3233446Smrj Status = AcpiNsAttachObject (NewNode, ObjDesc, 3243446Smrj ACPI_GET_OBJECT_TYPE (ObjDesc)); 3253446Smrj 3263446Smrj /* Remove local reference to the object */ 3273446Smrj 3283446Smrj AcpiUtRemoveReference (ObjDesc); 3293446Smrj } 3303446Smrj } 3313446Smrj 3323446Smrj 3333446Smrj UnlockAndExit: 3343446Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 3353446Smrj 3363446Smrj /* Save a handle to "_GPE", it is always present */ 3373446Smrj 3383446Smrj if (ACPI_SUCCESS (Status)) 3393446Smrj { 3403446Smrj Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, 3413446Smrj &AcpiGbl_FadtGpeDevice); 3423446Smrj } 3433446Smrj 3443446Smrj return_ACPI_STATUS (Status); 3453446Smrj } 3463446Smrj 3473446Smrj 3483446Smrj /******************************************************************************* 3493446Smrj * 3503446Smrj * FUNCTION: AcpiNsLookup 3513446Smrj * 3523446Smrj * PARAMETERS: ScopeInfo - Current scope info block 3533446Smrj * Pathname - Search pathname, in internal format 3543446Smrj * (as represented in the AML stream) 3553446Smrj * Type - Type associated with name 3563446Smrj * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found 3573446Smrj * Flags - Flags describing the search restrictions 3583446Smrj * WalkState - Current state of the walk 3593446Smrj * ReturnNode - Where the Node is placed (if found 3603446Smrj * or created successfully) 3613446Smrj * 3623446Smrj * RETURN: Status 3633446Smrj * 3643446Smrj * DESCRIPTION: Find or enter the passed name in the name space. 3653446Smrj * Log an error if name not found in Exec mode. 3663446Smrj * 3673446Smrj * MUTEX: Assumes namespace is locked. 3683446Smrj * 3693446Smrj ******************************************************************************/ 3703446Smrj 3713446Smrj ACPI_STATUS 3723446Smrj AcpiNsLookup ( 3733446Smrj ACPI_GENERIC_STATE *ScopeInfo, 3743446Smrj char *Pathname, 3753446Smrj ACPI_OBJECT_TYPE Type, 3763446Smrj ACPI_INTERPRETER_MODE InterpreterMode, 3773446Smrj UINT32 Flags, 3783446Smrj ACPI_WALK_STATE *WalkState, 3793446Smrj ACPI_NAMESPACE_NODE **ReturnNode) 3803446Smrj { 3813446Smrj ACPI_STATUS Status; 3823446Smrj char *Path = Pathname; 3833446Smrj ACPI_NAMESPACE_NODE *PrefixNode; 3843446Smrj ACPI_NAMESPACE_NODE *CurrentNode = NULL; 3853446Smrj ACPI_NAMESPACE_NODE *ThisNode = NULL; 3863446Smrj UINT32 NumSegments; 3873446Smrj UINT32 NumCarats; 3883446Smrj ACPI_NAME SimpleName; 3893446Smrj ACPI_OBJECT_TYPE TypeToCheckFor; 3903446Smrj ACPI_OBJECT_TYPE ThisSearchType; 3913446Smrj UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT; 3923446Smrj UINT32 LocalFlags; 3933446Smrj 3943446Smrj 3953446Smrj ACPI_FUNCTION_TRACE (NsLookup); 3963446Smrj 3973446Smrj 3983446Smrj if (!ReturnNode) 3993446Smrj { 4003446Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 4013446Smrj } 4023446Smrj 4033446Smrj LocalFlags = Flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT); 4043446Smrj *ReturnNode = ACPI_ENTRY_NOT_FOUND; 4053446Smrj AcpiGbl_NsLookupCount++; 4063446Smrj 4073446Smrj if (!AcpiGbl_RootNode) 4083446Smrj { 4093446Smrj return_ACPI_STATUS (AE_NO_NAMESPACE); 4103446Smrj } 4113446Smrj 4123446Smrj /* 4133446Smrj * Get the prefix scope. 4143446Smrj * A null scope means use the root scope 4153446Smrj */ 4163446Smrj if ((!ScopeInfo) || 4173446Smrj (!ScopeInfo->Scope.Node)) 4183446Smrj { 4193446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 4203446Smrj "Null scope prefix, using root node (%p)\n", 4213446Smrj AcpiGbl_RootNode)); 4223446Smrj 4233446Smrj PrefixNode = AcpiGbl_RootNode; 4243446Smrj } 4253446Smrj else 4263446Smrj { 4273446Smrj PrefixNode = ScopeInfo->Scope.Node; 4283446Smrj if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED) 4293446Smrj { 4303446Smrj ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]", 4313446Smrj PrefixNode, AcpiUtGetDescriptorName (PrefixNode))); 4323446Smrj return_ACPI_STATUS (AE_AML_INTERNAL); 4333446Smrj } 4343446Smrj 4353446Smrj if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE)) 4363446Smrj { 4373446Smrj /* 4383446Smrj * This node might not be a actual "scope" node (such as a 4393446Smrj * Device/Method, etc.) It could be a Package or other object node. 4403446Smrj * Backup up the tree to find the containing scope node. 4413446Smrj */ 4423446Smrj while (!AcpiNsOpensScope (PrefixNode->Type) && 4433446Smrj PrefixNode->Type != ACPI_TYPE_ANY) 4443446Smrj { 4453446Smrj PrefixNode = AcpiNsGetParentNode (PrefixNode); 4463446Smrj } 4473446Smrj } 4483446Smrj } 4493446Smrj 4503446Smrj /* Save type TBD: may be no longer necessary */ 4513446Smrj 4523446Smrj TypeToCheckFor = Type; 4533446Smrj 4543446Smrj /* 4553446Smrj * Begin examination of the actual pathname 4563446Smrj */ 4573446Smrj if (!Pathname) 4583446Smrj { 4593446Smrj /* A Null NamePath is allowed and refers to the root */ 4603446Smrj 4613446Smrj NumSegments = 0; 4623446Smrj ThisNode = AcpiGbl_RootNode; 4633446Smrj Path = ""; 4643446Smrj 4653446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 4663446Smrj "Null Pathname (Zero segments), Flags=%X\n", Flags)); 4673446Smrj } 4683446Smrj else 4693446Smrj { 4703446Smrj /* 4713446Smrj * Name pointer is valid (and must be in internal name format) 4723446Smrj * 4733446Smrj * Check for scope prefixes: 4743446Smrj * 4753446Smrj * As represented in the AML stream, a namepath consists of an 4763446Smrj * optional scope prefix followed by a name segment part. 4773446Smrj * 4783446Smrj * If present, the scope prefix is either a Root Prefix (in 4793446Smrj * which case the name is fully qualified), or one or more 4803446Smrj * Parent Prefixes (in which case the name's scope is relative 4813446Smrj * to the current scope). 4823446Smrj */ 4833446Smrj if (*Path == (UINT8) AML_ROOT_PREFIX) 4843446Smrj { 4853446Smrj /* Pathname is fully qualified, start from the root */ 4863446Smrj 4873446Smrj ThisNode = AcpiGbl_RootNode; 4883446Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 4893446Smrj 4903446Smrj /* Point to name segment part */ 4913446Smrj 4923446Smrj Path++; 4933446Smrj 4943446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 4953446Smrj "Path is absolute from root [%p]\n", ThisNode)); 4963446Smrj } 4973446Smrj else 4983446Smrj { 4993446Smrj /* Pathname is relative to current scope, start there */ 5003446Smrj 5013446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 5023446Smrj "Searching relative to prefix scope [%4.4s] (%p)\n", 5033446Smrj AcpiUtGetNodeName (PrefixNode), PrefixNode)); 5043446Smrj 5053446Smrj /* 5063446Smrj * Handle multiple Parent Prefixes (carat) by just getting 5073446Smrj * the parent node for each prefix instance. 5083446Smrj */ 5093446Smrj ThisNode = PrefixNode; 5103446Smrj NumCarats = 0; 5113446Smrj while (*Path == (UINT8) AML_PARENT_PREFIX) 5123446Smrj { 5133446Smrj /* Name is fully qualified, no search rules apply */ 5143446Smrj 5153446Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 5163446Smrj /* 5173446Smrj * Point past this prefix to the name segment 5183446Smrj * part or the next Parent Prefix 5193446Smrj */ 5203446Smrj Path++; 5213446Smrj 5223446Smrj /* Backup to the parent node */ 5233446Smrj 5243446Smrj NumCarats++; 5253446Smrj ThisNode = AcpiNsGetParentNode (ThisNode); 5263446Smrj if (!ThisNode) 5273446Smrj { 5283446Smrj /* Current scope has no parent scope */ 5293446Smrj 5303446Smrj ACPI_ERROR ((AE_INFO, 5313446Smrj "ACPI path has too many parent prefixes (^) - reached beyond root node")); 5323446Smrj return_ACPI_STATUS (AE_NOT_FOUND); 5333446Smrj } 5343446Smrj } 5353446Smrj 5363446Smrj if (SearchParentFlag == ACPI_NS_NO_UPSEARCH) 5373446Smrj { 5383446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 5393446Smrj "Search scope is [%4.4s], path has %d carat(s)\n", 5403446Smrj AcpiUtGetNodeName (ThisNode), NumCarats)); 5413446Smrj } 5423446Smrj } 5433446Smrj 5443446Smrj /* 5453446Smrj * Determine the number of ACPI name segments in this pathname. 5463446Smrj * 5473446Smrj * The segment part consists of either: 5483446Smrj * - A Null name segment (0) 5493446Smrj * - A DualNamePrefix followed by two 4-byte name segments 5503446Smrj * - A MultiNamePrefix followed by a byte indicating the 5513446Smrj * number of segments and the segments themselves. 5523446Smrj * - A single 4-byte name segment 5533446Smrj * 5543446Smrj * Examine the name prefix opcode, if any, to determine the number of 5553446Smrj * segments. 5563446Smrj */ 5573446Smrj switch (*Path) 5583446Smrj { 5593446Smrj case 0: 5603446Smrj /* 5613446Smrj * Null name after a root or parent prefixes. We already 5623446Smrj * have the correct target node and there are no name segments. 5633446Smrj */ 5643446Smrj NumSegments = 0; 5653446Smrj Type = ThisNode->Type; 5663446Smrj 5673446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 5683446Smrj "Prefix-only Pathname (Zero name segments), Flags=%X\n", 5693446Smrj Flags)); 5703446Smrj break; 5713446Smrj 5723446Smrj case AML_DUAL_NAME_PREFIX: 5733446Smrj 5743446Smrj /* More than one NameSeg, search rules do not apply */ 5753446Smrj 5763446Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 5773446Smrj 5783446Smrj /* Two segments, point to first name segment */ 5793446Smrj 5803446Smrj NumSegments = 2; 5813446Smrj Path++; 5823446Smrj 5833446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 5843446Smrj "Dual Pathname (2 segments, Flags=%X)\n", Flags)); 5853446Smrj break; 5863446Smrj 5873446Smrj case AML_MULTI_NAME_PREFIX_OP: 5883446Smrj 5893446Smrj /* More than one NameSeg, search rules do not apply */ 5903446Smrj 5913446Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 5923446Smrj 5933446Smrj /* Extract segment count, point to first name segment */ 5943446Smrj 5953446Smrj Path++; 5963446Smrj NumSegments = (UINT32) (UINT8) *Path; 5973446Smrj Path++; 5983446Smrj 5993446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 6003446Smrj "Multi Pathname (%d Segments, Flags=%X)\n", 6013446Smrj NumSegments, Flags)); 6023446Smrj break; 6033446Smrj 6043446Smrj default: 6053446Smrj /* 6063446Smrj * Not a Null name, no Dual or Multi prefix, hence there is 6073446Smrj * only one name segment and Pathname is already pointing to it. 6083446Smrj */ 6093446Smrj NumSegments = 1; 6103446Smrj 6113446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 6123446Smrj "Simple Pathname (1 segment, Flags=%X)\n", Flags)); 6133446Smrj break; 6143446Smrj } 6153446Smrj 6163446Smrj ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path)); 6173446Smrj } 6183446Smrj 6193446Smrj 6203446Smrj /* 6213446Smrj * Search namespace for each segment of the name. Loop through and 6223446Smrj * verify (or add to the namespace) each name segment. 6233446Smrj * 6243446Smrj * The object type is significant only at the last name 6253446Smrj * segment. (We don't care about the types along the path, only 6263446Smrj * the type of the final target object.) 6273446Smrj */ 6283446Smrj ThisSearchType = ACPI_TYPE_ANY; 6293446Smrj CurrentNode = ThisNode; 6303446Smrj while (NumSegments && CurrentNode) 6313446Smrj { 6323446Smrj NumSegments--; 6333446Smrj if (!NumSegments) 6343446Smrj { 6353446Smrj /* 6363446Smrj * This is the last segment, enable typechecking 6373446Smrj */ 6383446Smrj ThisSearchType = Type; 6393446Smrj 6403446Smrj /* 6413446Smrj * Only allow automatic parent search (search rules) if the caller 6423446Smrj * requested it AND we have a single, non-fully-qualified NameSeg 6433446Smrj */ 6443446Smrj if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) && 6453446Smrj (Flags & ACPI_NS_SEARCH_PARENT)) 6463446Smrj { 6473446Smrj LocalFlags |= ACPI_NS_SEARCH_PARENT; 6483446Smrj } 6493446Smrj 6503446Smrj /* Set error flag according to caller */ 6513446Smrj 6523446Smrj if (Flags & ACPI_NS_ERROR_IF_FOUND) 6533446Smrj { 6543446Smrj LocalFlags |= ACPI_NS_ERROR_IF_FOUND; 6553446Smrj } 6563446Smrj } 6573446Smrj 6583446Smrj /* Extract one ACPI name from the front of the pathname */ 6593446Smrj 6603446Smrj ACPI_MOVE_32_TO_32 (&SimpleName, Path); 6613446Smrj 6623446Smrj /* Try to find the single (4 character) ACPI name */ 6633446Smrj 6643446Smrj Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode, 6653446Smrj InterpreterMode, ThisSearchType, LocalFlags, &ThisNode); 6663446Smrj if (ACPI_FAILURE (Status)) 6673446Smrj { 6683446Smrj if (Status == AE_NOT_FOUND) 6693446Smrj { 6703446Smrj /* Name not found in ACPI namespace */ 6713446Smrj 6723446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 6733446Smrj "Name [%4.4s] not found in scope [%4.4s] %p\n", 6743446Smrj (char *) &SimpleName, (char *) &CurrentNode->Name, 6753446Smrj CurrentNode)); 6763446Smrj } 6773446Smrj 6783446Smrj *ReturnNode = ThisNode; 6793446Smrj return_ACPI_STATUS (Status); 6803446Smrj } 6813446Smrj 682*7851SDana.Myers@Sun.COM /* More segments to follow? */ 683*7851SDana.Myers@Sun.COM 684*7851SDana.Myers@Sun.COM if (NumSegments > 0) 6853446Smrj { 686*7851SDana.Myers@Sun.COM /* 687*7851SDana.Myers@Sun.COM * If we have an alias to an object that opens a scope (such as a 688*7851SDana.Myers@Sun.COM * device or processor), we need to dereference the alias here so that 689*7851SDana.Myers@Sun.COM * we can access any children of the original node (via the remaining 690*7851SDana.Myers@Sun.COM * segments). 691*7851SDana.Myers@Sun.COM */ 692*7851SDana.Myers@Sun.COM if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS) 693*7851SDana.Myers@Sun.COM { 694*7851SDana.Myers@Sun.COM if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *) ThisNode->Object)->Type)) 695*7851SDana.Myers@Sun.COM { 696*7851SDana.Myers@Sun.COM ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object; 697*7851SDana.Myers@Sun.COM } 698*7851SDana.Myers@Sun.COM } 6993446Smrj } 7003446Smrj 701*7851SDana.Myers@Sun.COM /* Special handling for the last segment (NumSegments == 0) */ 702*7851SDana.Myers@Sun.COM 703*7851SDana.Myers@Sun.COM else 7043446Smrj { 705*7851SDana.Myers@Sun.COM /* 706*7851SDana.Myers@Sun.COM * Sanity typecheck of the target object: 707*7851SDana.Myers@Sun.COM * 708*7851SDana.Myers@Sun.COM * If 1) This is the last segment (NumSegments == 0) 709*7851SDana.Myers@Sun.COM * 2) And we are looking for a specific type 710*7851SDana.Myers@Sun.COM * (Not checking for TYPE_ANY) 711*7851SDana.Myers@Sun.COM * 3) Which is not an alias 712*7851SDana.Myers@Sun.COM * 4) Which is not a local type (TYPE_SCOPE) 713*7851SDana.Myers@Sun.COM * 5) And the type of target object is known (not TYPE_ANY) 714*7851SDana.Myers@Sun.COM * 6) And target object does not match what we are looking for 715*7851SDana.Myers@Sun.COM * 716*7851SDana.Myers@Sun.COM * Then we have a type mismatch. Just warn and ignore it. 717*7851SDana.Myers@Sun.COM */ 718*7851SDana.Myers@Sun.COM if ((TypeToCheckFor != ACPI_TYPE_ANY) && 719*7851SDana.Myers@Sun.COM (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) && 720*7851SDana.Myers@Sun.COM (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 721*7851SDana.Myers@Sun.COM (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) && 722*7851SDana.Myers@Sun.COM (ThisNode->Type != ACPI_TYPE_ANY) && 723*7851SDana.Myers@Sun.COM (ThisNode->Type != TypeToCheckFor)) 724*7851SDana.Myers@Sun.COM { 725*7851SDana.Myers@Sun.COM /* Complain about a type mismatch */ 726*7851SDana.Myers@Sun.COM 727*7851SDana.Myers@Sun.COM ACPI_WARNING ((AE_INFO, 728*7851SDana.Myers@Sun.COM "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", 729*7851SDana.Myers@Sun.COM ACPI_CAST_PTR (char, &SimpleName), 730*7851SDana.Myers@Sun.COM AcpiUtGetTypeName (ThisNode->Type), 731*7851SDana.Myers@Sun.COM AcpiUtGetTypeName (TypeToCheckFor))); 732*7851SDana.Myers@Sun.COM } 733*7851SDana.Myers@Sun.COM 734*7851SDana.Myers@Sun.COM /* 735*7851SDana.Myers@Sun.COM * If this is the last name segment and we are not looking for a 736*7851SDana.Myers@Sun.COM * specific type, but the type of found object is known, use that type 737*7851SDana.Myers@Sun.COM * to (later) see if it opens a scope. 738*7851SDana.Myers@Sun.COM */ 739*7851SDana.Myers@Sun.COM if (Type == ACPI_TYPE_ANY) 740*7851SDana.Myers@Sun.COM { 741*7851SDana.Myers@Sun.COM Type = ThisNode->Type; 742*7851SDana.Myers@Sun.COM } 7433446Smrj } 7443446Smrj 7453446Smrj /* Point to next name segment and make this node current */ 7463446Smrj 7473446Smrj Path += ACPI_NAME_SIZE; 7483446Smrj CurrentNode = ThisNode; 7493446Smrj } 7503446Smrj 7513446Smrj /* 7523446Smrj * Always check if we need to open a new scope 7533446Smrj */ 7543446Smrj if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState)) 7553446Smrj { 7563446Smrj /* 7573446Smrj * If entry is a type which opens a scope, push the new scope on the 7583446Smrj * scope stack. 7593446Smrj */ 7603446Smrj if (AcpiNsOpensScope (Type)) 7613446Smrj { 7623446Smrj Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState); 7633446Smrj if (ACPI_FAILURE (Status)) 7643446Smrj { 7653446Smrj return_ACPI_STATUS (Status); 7663446Smrj } 7673446Smrj } 7683446Smrj } 7693446Smrj 7703446Smrj *ReturnNode = ThisNode; 7713446Smrj return_ACPI_STATUS (AE_OK); 7723446Smrj } 7733446Smrj 774