1ae115bc7Smrj /******************************************************************************* 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 4ae115bc7Smrj * 5ae115bc7Smrj ******************************************************************************/ 6ae115bc7Smrj 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9ae115bc7Smrj * All rights reserved. 10ae115bc7Smrj * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25ae115bc7Smrj * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29ae115bc7Smrj * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43ae115bc7Smrj 44ae115bc7Smrj #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46ae115bc7Smrj #include "amlcode.h" 47ae115bc7Smrj #include "acnamesp.h" 48ae115bc7Smrj #include "acdispat.h" 49ae115bc7Smrj 50ae115bc7Smrj 51ae115bc7Smrj #define _COMPONENT ACPI_NAMESPACE 52ae115bc7Smrj ACPI_MODULE_NAME ("nsaccess") 53ae115bc7Smrj 54ae115bc7Smrj 55ae115bc7Smrj /******************************************************************************* 56ae115bc7Smrj * 57ae115bc7Smrj * FUNCTION: AcpiNsRootInitialize 58ae115bc7Smrj * 59ae115bc7Smrj * PARAMETERS: None 60ae115bc7Smrj * 61ae115bc7Smrj * RETURN: Status 62ae115bc7Smrj * 63ae115bc7Smrj * DESCRIPTION: Allocate and initialize the default root named objects 64ae115bc7Smrj * 65ae115bc7Smrj * MUTEX: Locks namespace for entire execution 66ae115bc7Smrj * 67ae115bc7Smrj ******************************************************************************/ 68ae115bc7Smrj 69ae115bc7Smrj ACPI_STATUS 70ae115bc7Smrj AcpiNsRootInitialize ( 71ae115bc7Smrj void) 72ae115bc7Smrj { 73ae115bc7Smrj ACPI_STATUS Status; 74ae115bc7Smrj const ACPI_PREDEFINED_NAMES *InitVal = NULL; 75ae115bc7Smrj ACPI_NAMESPACE_NODE *NewNode; 76ae115bc7Smrj ACPI_OPERAND_OBJECT *ObjDesc; 77ae115bc7Smrj ACPI_STRING Val = NULL; 78ae115bc7Smrj 79ae115bc7Smrj 80ae115bc7Smrj ACPI_FUNCTION_TRACE (NsRootInitialize); 81ae115bc7Smrj 82ae115bc7Smrj 83ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 84ae115bc7Smrj if (ACPI_FAILURE (Status)) 85ae115bc7Smrj { 86ae115bc7Smrj return_ACPI_STATUS (Status); 87ae115bc7Smrj } 88ae115bc7Smrj 89ae115bc7Smrj /* 90ae115bc7Smrj * The global root ptr is initially NULL, so a non-NULL value indicates 91ae115bc7Smrj * that AcpiNsRootInitialize() has already been called; just return. 92ae115bc7Smrj */ 93ae115bc7Smrj if (AcpiGbl_RootNode) 94ae115bc7Smrj { 95ae115bc7Smrj Status = AE_OK; 96ae115bc7Smrj goto UnlockAndExit; 97ae115bc7Smrj } 98ae115bc7Smrj 99ae115bc7Smrj /* 100ae115bc7Smrj * Tell the rest of the subsystem that the root is initialized 101ae115bc7Smrj * (This is OK because the namespace is locked) 102ae115bc7Smrj */ 103ae115bc7Smrj AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; 104ae115bc7Smrj 105ae115bc7Smrj /* Enter the pre-defined names in the name table */ 106ae115bc7Smrj 107ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 108ae115bc7Smrj "Entering predefined entries into namespace\n")); 109ae115bc7Smrj 110ae115bc7Smrj for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) 111ae115bc7Smrj { 112ae115bc7Smrj /* _OSI is optional for now, will be permanent later */ 113ae115bc7Smrj 114*385cc6b4SJerry Jelinek if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) 115ae115bc7Smrj { 116ae115bc7Smrj continue; 117ae115bc7Smrj } 118ae115bc7Smrj 119*385cc6b4SJerry Jelinek Status = AcpiNsLookup (NULL, ACPI_CAST_PTR (char, InitVal->Name), 120*385cc6b4SJerry Jelinek InitVal->Type, ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, 121ae115bc7Smrj NULL, &NewNode); 122*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 123ae115bc7Smrj { 124ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status, 125ae115bc7Smrj "Could not create predefined name %s", 126ae115bc7Smrj InitVal->Name)); 127*385cc6b4SJerry Jelinek continue; 128ae115bc7Smrj } 129ae115bc7Smrj 130ae115bc7Smrj /* 131aa2aa9a6SDana Myers * Name entered successfully. If entry in PreDefinedNames[] specifies 132aa2aa9a6SDana Myers * an initial value, create the initial value. 133ae115bc7Smrj */ 134ae115bc7Smrj if (InitVal->Val) 135ae115bc7Smrj { 136ae115bc7Smrj Status = AcpiOsPredefinedOverride (InitVal, &Val); 137ae115bc7Smrj if (ACPI_FAILURE (Status)) 138ae115bc7Smrj { 139ae115bc7Smrj ACPI_ERROR ((AE_INFO, 140ae115bc7Smrj "Could not override predefined %s", 141ae115bc7Smrj InitVal->Name)); 142ae115bc7Smrj } 143ae115bc7Smrj 144ae115bc7Smrj if (!Val) 145ae115bc7Smrj { 146ae115bc7Smrj Val = InitVal->Val; 147ae115bc7Smrj } 148ae115bc7Smrj 149ae115bc7Smrj /* 150ae115bc7Smrj * Entry requests an initial value, allocate a 151ae115bc7Smrj * descriptor for it. 152ae115bc7Smrj */ 153ae115bc7Smrj ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); 154ae115bc7Smrj if (!ObjDesc) 155ae115bc7Smrj { 156ae115bc7Smrj Status = AE_NO_MEMORY; 157ae115bc7Smrj goto UnlockAndExit; 158ae115bc7Smrj } 159ae115bc7Smrj 160ae115bc7Smrj /* 161ae115bc7Smrj * Convert value string from table entry to 162ae115bc7Smrj * internal representation. Only types actually 163ae115bc7Smrj * used for initial values are implemented here. 164ae115bc7Smrj */ 165ae115bc7Smrj switch (InitVal->Type) 166ae115bc7Smrj { 167ae115bc7Smrj case ACPI_TYPE_METHOD: 168*385cc6b4SJerry Jelinek 169ae115bc7Smrj ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val); 170ae115bc7Smrj ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 171ae115bc7Smrj 172ae115bc7Smrj #if defined (ACPI_ASL_COMPILER) 173ae115bc7Smrj 174ae115bc7Smrj /* Save the parameter count for the iASL compiler */ 175ae115bc7Smrj 176ae115bc7Smrj NewNode->Value = ObjDesc->Method.ParamCount; 177ae115bc7Smrj #else 178ae115bc7Smrj /* Mark this as a very SPECIAL method */ 179ae115bc7Smrj 18026f3cdf0SGordon Ross ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY; 18126f3cdf0SGordon Ross ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation; 182ae115bc7Smrj #endif 183ae115bc7Smrj break; 184ae115bc7Smrj 185ae115bc7Smrj case ACPI_TYPE_INTEGER: 186ae115bc7Smrj 187ae115bc7Smrj ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val); 188ae115bc7Smrj break; 189ae115bc7Smrj 190ae115bc7Smrj case ACPI_TYPE_STRING: 191ae115bc7Smrj 192aa2aa9a6SDana Myers /* Build an object around the static string */ 193aa2aa9a6SDana Myers 194*385cc6b4SJerry Jelinek ObjDesc->String.Length = (UINT32) strlen (Val); 195ae115bc7Smrj ObjDesc->String.Pointer = Val; 196ae115bc7Smrj ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 197ae115bc7Smrj break; 198ae115bc7Smrj 199ae115bc7Smrj case ACPI_TYPE_MUTEX: 200ae115bc7Smrj 201ae115bc7Smrj ObjDesc->Mutex.Node = NewNode; 202ae115bc7Smrj ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1); 203ae115bc7Smrj 204ae115bc7Smrj /* Create a mutex */ 205ae115bc7Smrj 206ae115bc7Smrj Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 207ae115bc7Smrj if (ACPI_FAILURE (Status)) 208ae115bc7Smrj { 209ae115bc7Smrj AcpiUtRemoveReference (ObjDesc); 210ae115bc7Smrj goto UnlockAndExit; 211ae115bc7Smrj } 212ae115bc7Smrj 213ae115bc7Smrj /* Special case for ACPI Global Lock */ 214ae115bc7Smrj 215*385cc6b4SJerry Jelinek if (strcmp (InitVal->Name, "_GL_") == 0) 216ae115bc7Smrj { 217db2bae30SDana Myers AcpiGbl_GlobalLockMutex = ObjDesc; 218ae115bc7Smrj 219ae115bc7Smrj /* Create additional counting semaphore for global lock */ 220ae115bc7Smrj 221ae115bc7Smrj Status = AcpiOsCreateSemaphore ( 222db2bae30SDana Myers 1, 0, &AcpiGbl_GlobalLockSemaphore); 223ae115bc7Smrj if (ACPI_FAILURE (Status)) 224ae115bc7Smrj { 225ae115bc7Smrj AcpiUtRemoveReference (ObjDesc); 226ae115bc7Smrj goto UnlockAndExit; 227ae115bc7Smrj } 228ae115bc7Smrj } 229ae115bc7Smrj break; 230ae115bc7Smrj 231ae115bc7Smrj default: 232ae115bc7Smrj 23326f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X", 234ae115bc7Smrj InitVal->Type)); 235ae115bc7Smrj AcpiUtRemoveReference (ObjDesc); 236ae115bc7Smrj ObjDesc = NULL; 237ae115bc7Smrj continue; 238ae115bc7Smrj } 239ae115bc7Smrj 240ae115bc7Smrj /* Store pointer to value descriptor in the Node */ 241ae115bc7Smrj 242ae115bc7Smrj Status = AcpiNsAttachObject (NewNode, ObjDesc, 243aa2aa9a6SDana Myers ObjDesc->Common.Type); 244ae115bc7Smrj 245ae115bc7Smrj /* Remove local reference to the object */ 246ae115bc7Smrj 247ae115bc7Smrj AcpiUtRemoveReference (ObjDesc); 248ae115bc7Smrj } 249ae115bc7Smrj } 250ae115bc7Smrj 251ae115bc7Smrj 252ae115bc7Smrj UnlockAndExit: 253ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 254ae115bc7Smrj 255ae115bc7Smrj /* Save a handle to "_GPE", it is always present */ 256ae115bc7Smrj 257ae115bc7Smrj if (ACPI_SUCCESS (Status)) 258ae115bc7Smrj { 259ae115bc7Smrj Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, 260ae115bc7Smrj &AcpiGbl_FadtGpeDevice); 261ae115bc7Smrj } 262ae115bc7Smrj 263ae115bc7Smrj return_ACPI_STATUS (Status); 264ae115bc7Smrj } 265ae115bc7Smrj 266ae115bc7Smrj 267ae115bc7Smrj /******************************************************************************* 268ae115bc7Smrj * 269ae115bc7Smrj * FUNCTION: AcpiNsLookup 270ae115bc7Smrj * 271ae115bc7Smrj * PARAMETERS: ScopeInfo - Current scope info block 272ae115bc7Smrj * Pathname - Search pathname, in internal format 273ae115bc7Smrj * (as represented in the AML stream) 274ae115bc7Smrj * Type - Type associated with name 275ae115bc7Smrj * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found 276ae115bc7Smrj * Flags - Flags describing the search restrictions 277ae115bc7Smrj * WalkState - Current state of the walk 278ae115bc7Smrj * ReturnNode - Where the Node is placed (if found 279ae115bc7Smrj * or created successfully) 280ae115bc7Smrj * 281ae115bc7Smrj * RETURN: Status 282ae115bc7Smrj * 283ae115bc7Smrj * DESCRIPTION: Find or enter the passed name in the name space. 284ae115bc7Smrj * Log an error if name not found in Exec mode. 285ae115bc7Smrj * 286ae115bc7Smrj * MUTEX: Assumes namespace is locked. 287ae115bc7Smrj * 288ae115bc7Smrj ******************************************************************************/ 289ae115bc7Smrj 290ae115bc7Smrj ACPI_STATUS 291ae115bc7Smrj AcpiNsLookup ( 292ae115bc7Smrj ACPI_GENERIC_STATE *ScopeInfo, 293ae115bc7Smrj char *Pathname, 294ae115bc7Smrj ACPI_OBJECT_TYPE Type, 295ae115bc7Smrj ACPI_INTERPRETER_MODE InterpreterMode, 296ae115bc7Smrj UINT32 Flags, 297ae115bc7Smrj ACPI_WALK_STATE *WalkState, 298ae115bc7Smrj ACPI_NAMESPACE_NODE **ReturnNode) 299ae115bc7Smrj { 300ae115bc7Smrj ACPI_STATUS Status; 301ae115bc7Smrj char *Path = Pathname; 302ae115bc7Smrj ACPI_NAMESPACE_NODE *PrefixNode; 303ae115bc7Smrj ACPI_NAMESPACE_NODE *CurrentNode = NULL; 304ae115bc7Smrj ACPI_NAMESPACE_NODE *ThisNode = NULL; 305ae115bc7Smrj UINT32 NumSegments; 306ae115bc7Smrj UINT32 NumCarats; 307ae115bc7Smrj ACPI_NAME SimpleName; 308ae115bc7Smrj ACPI_OBJECT_TYPE TypeToCheckFor; 309ae115bc7Smrj ACPI_OBJECT_TYPE ThisSearchType; 310ae115bc7Smrj UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT; 311ae115bc7Smrj UINT32 LocalFlags; 312ae115bc7Smrj 313ae115bc7Smrj 314ae115bc7Smrj ACPI_FUNCTION_TRACE (NsLookup); 315ae115bc7Smrj 316ae115bc7Smrj 317ae115bc7Smrj if (!ReturnNode) 318ae115bc7Smrj { 319ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 320ae115bc7Smrj } 321ae115bc7Smrj 322*385cc6b4SJerry Jelinek LocalFlags = Flags & 323*385cc6b4SJerry Jelinek ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND | 324*385cc6b4SJerry Jelinek ACPI_NS_SEARCH_PARENT); 325ae115bc7Smrj *ReturnNode = ACPI_ENTRY_NOT_FOUND; 326ae115bc7Smrj AcpiGbl_NsLookupCount++; 327ae115bc7Smrj 328ae115bc7Smrj if (!AcpiGbl_RootNode) 329ae115bc7Smrj { 330ae115bc7Smrj return_ACPI_STATUS (AE_NO_NAMESPACE); 331ae115bc7Smrj } 332ae115bc7Smrj 333aa2aa9a6SDana Myers /* Get the prefix scope. A null scope means use the root scope */ 334aa2aa9a6SDana Myers 335ae115bc7Smrj if ((!ScopeInfo) || 336ae115bc7Smrj (!ScopeInfo->Scope.Node)) 337ae115bc7Smrj { 338ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 339ae115bc7Smrj "Null scope prefix, using root node (%p)\n", 340ae115bc7Smrj AcpiGbl_RootNode)); 341ae115bc7Smrj 342ae115bc7Smrj PrefixNode = AcpiGbl_RootNode; 343ae115bc7Smrj } 344ae115bc7Smrj else 345ae115bc7Smrj { 346ae115bc7Smrj PrefixNode = ScopeInfo->Scope.Node; 347ae115bc7Smrj if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED) 348ae115bc7Smrj { 349ae115bc7Smrj ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]", 350ae115bc7Smrj PrefixNode, AcpiUtGetDescriptorName (PrefixNode))); 351ae115bc7Smrj return_ACPI_STATUS (AE_AML_INTERNAL); 352ae115bc7Smrj } 353ae115bc7Smrj 354ae115bc7Smrj if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE)) 355ae115bc7Smrj { 356ae115bc7Smrj /* 357ae115bc7Smrj * This node might not be a actual "scope" node (such as a 358aa2aa9a6SDana Myers * Device/Method, etc.) It could be a Package or other object 359aa2aa9a6SDana Myers * node. Backup up the tree to find the containing scope node. 360ae115bc7Smrj */ 361ae115bc7Smrj while (!AcpiNsOpensScope (PrefixNode->Type) && 362ae115bc7Smrj PrefixNode->Type != ACPI_TYPE_ANY) 363ae115bc7Smrj { 36426f3cdf0SGordon Ross PrefixNode = PrefixNode->Parent; 365ae115bc7Smrj } 366ae115bc7Smrj } 367ae115bc7Smrj } 368ae115bc7Smrj 369aa2aa9a6SDana Myers /* Save type. TBD: may be no longer necessary */ 370ae115bc7Smrj 371ae115bc7Smrj TypeToCheckFor = Type; 372ae115bc7Smrj 373ae115bc7Smrj /* 374ae115bc7Smrj * Begin examination of the actual pathname 375ae115bc7Smrj */ 376ae115bc7Smrj if (!Pathname) 377ae115bc7Smrj { 378ae115bc7Smrj /* A Null NamePath is allowed and refers to the root */ 379ae115bc7Smrj 380ae115bc7Smrj NumSegments = 0; 381ae115bc7Smrj ThisNode = AcpiGbl_RootNode; 382ae115bc7Smrj Path = ""; 383ae115bc7Smrj 384ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 385ae115bc7Smrj "Null Pathname (Zero segments), Flags=%X\n", Flags)); 386ae115bc7Smrj } 387ae115bc7Smrj else 388ae115bc7Smrj { 389ae115bc7Smrj /* 390ae115bc7Smrj * Name pointer is valid (and must be in internal name format) 391ae115bc7Smrj * 392ae115bc7Smrj * Check for scope prefixes: 393ae115bc7Smrj * 394ae115bc7Smrj * As represented in the AML stream, a namepath consists of an 395ae115bc7Smrj * optional scope prefix followed by a name segment part. 396ae115bc7Smrj * 397ae115bc7Smrj * If present, the scope prefix is either a Root Prefix (in 398ae115bc7Smrj * which case the name is fully qualified), or one or more 399ae115bc7Smrj * Parent Prefixes (in which case the name's scope is relative 400ae115bc7Smrj * to the current scope). 401ae115bc7Smrj */ 402ae115bc7Smrj if (*Path == (UINT8) AML_ROOT_PREFIX) 403ae115bc7Smrj { 404ae115bc7Smrj /* Pathname is fully qualified, start from the root */ 405ae115bc7Smrj 406ae115bc7Smrj ThisNode = AcpiGbl_RootNode; 407ae115bc7Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 408ae115bc7Smrj 409ae115bc7Smrj /* Point to name segment part */ 410ae115bc7Smrj 411ae115bc7Smrj Path++; 412ae115bc7Smrj 413ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 414ae115bc7Smrj "Path is absolute from root [%p]\n", ThisNode)); 415ae115bc7Smrj } 416ae115bc7Smrj else 417ae115bc7Smrj { 418ae115bc7Smrj /* Pathname is relative to current scope, start there */ 419ae115bc7Smrj 420ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 421ae115bc7Smrj "Searching relative to prefix scope [%4.4s] (%p)\n", 422ae115bc7Smrj AcpiUtGetNodeName (PrefixNode), PrefixNode)); 423ae115bc7Smrj 424ae115bc7Smrj /* 425ae115bc7Smrj * Handle multiple Parent Prefixes (carat) by just getting 426ae115bc7Smrj * the parent node for each prefix instance. 427ae115bc7Smrj */ 428ae115bc7Smrj ThisNode = PrefixNode; 429ae115bc7Smrj NumCarats = 0; 430ae115bc7Smrj while (*Path == (UINT8) AML_PARENT_PREFIX) 431ae115bc7Smrj { 432ae115bc7Smrj /* Name is fully qualified, no search rules apply */ 433ae115bc7Smrj 434ae115bc7Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 435aa2aa9a6SDana Myers 436ae115bc7Smrj /* 437ae115bc7Smrj * Point past this prefix to the name segment 438ae115bc7Smrj * part or the next Parent Prefix 439ae115bc7Smrj */ 440ae115bc7Smrj Path++; 441ae115bc7Smrj 442ae115bc7Smrj /* Backup to the parent node */ 443ae115bc7Smrj 444ae115bc7Smrj NumCarats++; 44526f3cdf0SGordon Ross ThisNode = ThisNode->Parent; 446ae115bc7Smrj if (!ThisNode) 447ae115bc7Smrj { 448ae115bc7Smrj /* Current scope has no parent scope */ 449ae115bc7Smrj 450ae115bc7Smrj ACPI_ERROR ((AE_INFO, 451*385cc6b4SJerry Jelinek "%s: Path has too many parent prefixes (^) " 452*385cc6b4SJerry Jelinek "- reached beyond root node", Pathname)); 453ae115bc7Smrj return_ACPI_STATUS (AE_NOT_FOUND); 454ae115bc7Smrj } 455ae115bc7Smrj } 456ae115bc7Smrj 457ae115bc7Smrj if (SearchParentFlag == ACPI_NS_NO_UPSEARCH) 458ae115bc7Smrj { 459ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 46026f3cdf0SGordon Ross "Search scope is [%4.4s], path has %u carat(s)\n", 461ae115bc7Smrj AcpiUtGetNodeName (ThisNode), NumCarats)); 462ae115bc7Smrj } 463ae115bc7Smrj } 464ae115bc7Smrj 465ae115bc7Smrj /* 466ae115bc7Smrj * Determine the number of ACPI name segments in this pathname. 467ae115bc7Smrj * 468ae115bc7Smrj * The segment part consists of either: 469ae115bc7Smrj * - A Null name segment (0) 470ae115bc7Smrj * - A DualNamePrefix followed by two 4-byte name segments 471ae115bc7Smrj * - A MultiNamePrefix followed by a byte indicating the 472ae115bc7Smrj * number of segments and the segments themselves. 473ae115bc7Smrj * - A single 4-byte name segment 474ae115bc7Smrj * 475ae115bc7Smrj * Examine the name prefix opcode, if any, to determine the number of 476ae115bc7Smrj * segments. 477ae115bc7Smrj */ 478ae115bc7Smrj switch (*Path) 479ae115bc7Smrj { 480ae115bc7Smrj case 0: 481ae115bc7Smrj /* 482ae115bc7Smrj * Null name after a root or parent prefixes. We already 483ae115bc7Smrj * have the correct target node and there are no name segments. 484ae115bc7Smrj */ 485ae115bc7Smrj NumSegments = 0; 486ae115bc7Smrj Type = ThisNode->Type; 487ae115bc7Smrj 488ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 489ae115bc7Smrj "Prefix-only Pathname (Zero name segments), Flags=%X\n", 490ae115bc7Smrj Flags)); 491ae115bc7Smrj break; 492ae115bc7Smrj 493ae115bc7Smrj case AML_DUAL_NAME_PREFIX: 494ae115bc7Smrj 495ae115bc7Smrj /* More than one NameSeg, search rules do not apply */ 496ae115bc7Smrj 497ae115bc7Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 498ae115bc7Smrj 499ae115bc7Smrj /* Two segments, point to first name segment */ 500ae115bc7Smrj 501ae115bc7Smrj NumSegments = 2; 502ae115bc7Smrj Path++; 503ae115bc7Smrj 504ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 505ae115bc7Smrj "Dual Pathname (2 segments, Flags=%X)\n", Flags)); 506ae115bc7Smrj break; 507ae115bc7Smrj 508ae115bc7Smrj case AML_MULTI_NAME_PREFIX_OP: 509ae115bc7Smrj 510ae115bc7Smrj /* More than one NameSeg, search rules do not apply */ 511ae115bc7Smrj 512ae115bc7Smrj SearchParentFlag = ACPI_NS_NO_UPSEARCH; 513ae115bc7Smrj 514ae115bc7Smrj /* Extract segment count, point to first name segment */ 515ae115bc7Smrj 516ae115bc7Smrj Path++; 517ae115bc7Smrj NumSegments = (UINT32) (UINT8) *Path; 518ae115bc7Smrj Path++; 519ae115bc7Smrj 520ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 52126f3cdf0SGordon Ross "Multi Pathname (%u Segments, Flags=%X)\n", 522ae115bc7Smrj NumSegments, Flags)); 523ae115bc7Smrj break; 524ae115bc7Smrj 525ae115bc7Smrj default: 526ae115bc7Smrj /* 527ae115bc7Smrj * Not a Null name, no Dual or Multi prefix, hence there is 528ae115bc7Smrj * only one name segment and Pathname is already pointing to it. 529ae115bc7Smrj */ 530ae115bc7Smrj NumSegments = 1; 531ae115bc7Smrj 532ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 533ae115bc7Smrj "Simple Pathname (1 segment, Flags=%X)\n", Flags)); 534ae115bc7Smrj break; 535ae115bc7Smrj } 536ae115bc7Smrj 537ae115bc7Smrj ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path)); 538ae115bc7Smrj } 539ae115bc7Smrj 540ae115bc7Smrj 541ae115bc7Smrj /* 542ae115bc7Smrj * Search namespace for each segment of the name. Loop through and 543ae115bc7Smrj * verify (or add to the namespace) each name segment. 544ae115bc7Smrj * 545ae115bc7Smrj * The object type is significant only at the last name 546ae115bc7Smrj * segment. (We don't care about the types along the path, only 547ae115bc7Smrj * the type of the final target object.) 548ae115bc7Smrj */ 549ae115bc7Smrj ThisSearchType = ACPI_TYPE_ANY; 550ae115bc7Smrj CurrentNode = ThisNode; 551ae115bc7Smrj while (NumSegments && CurrentNode) 552ae115bc7Smrj { 553ae115bc7Smrj NumSegments--; 554ae115bc7Smrj if (!NumSegments) 555ae115bc7Smrj { 556aa2aa9a6SDana Myers /* This is the last segment, enable typechecking */ 557aa2aa9a6SDana Myers 558ae115bc7Smrj ThisSearchType = Type; 559ae115bc7Smrj 560ae115bc7Smrj /* 561ae115bc7Smrj * Only allow automatic parent search (search rules) if the caller 562ae115bc7Smrj * requested it AND we have a single, non-fully-qualified NameSeg 563ae115bc7Smrj */ 564ae115bc7Smrj if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) && 565ae115bc7Smrj (Flags & ACPI_NS_SEARCH_PARENT)) 566ae115bc7Smrj { 567ae115bc7Smrj LocalFlags |= ACPI_NS_SEARCH_PARENT; 568ae115bc7Smrj } 569ae115bc7Smrj 570ae115bc7Smrj /* Set error flag according to caller */ 571ae115bc7Smrj 572ae115bc7Smrj if (Flags & ACPI_NS_ERROR_IF_FOUND) 573ae115bc7Smrj { 574ae115bc7Smrj LocalFlags |= ACPI_NS_ERROR_IF_FOUND; 575ae115bc7Smrj } 576*385cc6b4SJerry Jelinek 577*385cc6b4SJerry Jelinek /* Set override flag according to caller */ 578*385cc6b4SJerry Jelinek 579*385cc6b4SJerry Jelinek if (Flags & ACPI_NS_OVERRIDE_IF_FOUND) 580*385cc6b4SJerry Jelinek { 581*385cc6b4SJerry Jelinek LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND; 582*385cc6b4SJerry Jelinek } 583ae115bc7Smrj } 584ae115bc7Smrj 585ae115bc7Smrj /* Extract one ACPI name from the front of the pathname */ 586ae115bc7Smrj 587ae115bc7Smrj ACPI_MOVE_32_TO_32 (&SimpleName, Path); 588ae115bc7Smrj 589ae115bc7Smrj /* Try to find the single (4 character) ACPI name */ 590ae115bc7Smrj 591ae115bc7Smrj Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode, 592ae115bc7Smrj InterpreterMode, ThisSearchType, LocalFlags, &ThisNode); 593ae115bc7Smrj if (ACPI_FAILURE (Status)) 594ae115bc7Smrj { 595ae115bc7Smrj if (Status == AE_NOT_FOUND) 596ae115bc7Smrj { 597ae115bc7Smrj /* Name not found in ACPI namespace */ 598ae115bc7Smrj 599ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 600ae115bc7Smrj "Name [%4.4s] not found in scope [%4.4s] %p\n", 601ae115bc7Smrj (char *) &SimpleName, (char *) &CurrentNode->Name, 602ae115bc7Smrj CurrentNode)); 603ae115bc7Smrj } 604ae115bc7Smrj 605ae115bc7Smrj *ReturnNode = ThisNode; 606ae115bc7Smrj return_ACPI_STATUS (Status); 607ae115bc7Smrj } 608ae115bc7Smrj 609db2bae30SDana Myers /* More segments to follow? */ 610db2bae30SDana Myers 611db2bae30SDana Myers if (NumSegments > 0) 612db2bae30SDana Myers { 613db2bae30SDana Myers /* 614db2bae30SDana Myers * If we have an alias to an object that opens a scope (such as a 615aa2aa9a6SDana Myers * device or processor), we need to dereference the alias here so 616aa2aa9a6SDana Myers * that we can access any children of the original node (via the 617aa2aa9a6SDana Myers * remaining segments). 618db2bae30SDana Myers */ 619db2bae30SDana Myers if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS) 620db2bae30SDana Myers { 621aa2aa9a6SDana Myers if (!ThisNode->Object) 622aa2aa9a6SDana Myers { 623aa2aa9a6SDana Myers return_ACPI_STATUS (AE_NOT_EXIST); 624aa2aa9a6SDana Myers } 625aa2aa9a6SDana Myers 626aa2aa9a6SDana Myers if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *) 627aa2aa9a6SDana Myers ThisNode->Object)->Type)) 628db2bae30SDana Myers { 629db2bae30SDana Myers ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object; 630db2bae30SDana Myers } 631db2bae30SDana Myers } 632db2bae30SDana Myers } 633db2bae30SDana Myers 634db2bae30SDana Myers /* Special handling for the last segment (NumSegments == 0) */ 635db2bae30SDana Myers 636db2bae30SDana Myers else 637db2bae30SDana Myers { 638ae115bc7Smrj /* 639ae115bc7Smrj * Sanity typecheck of the target object: 640ae115bc7Smrj * 641ae115bc7Smrj * If 1) This is the last segment (NumSegments == 0) 642ae115bc7Smrj * 2) And we are looking for a specific type 643ae115bc7Smrj * (Not checking for TYPE_ANY) 644ae115bc7Smrj * 3) Which is not an alias 645ae115bc7Smrj * 4) Which is not a local type (TYPE_SCOPE) 646ae115bc7Smrj * 5) And the type of target object is known (not TYPE_ANY) 647ae115bc7Smrj * 6) And target object does not match what we are looking for 648ae115bc7Smrj * 649ae115bc7Smrj * Then we have a type mismatch. Just warn and ignore it. 650ae115bc7Smrj */ 651db2bae30SDana Myers if ((TypeToCheckFor != ACPI_TYPE_ANY) && 652ae115bc7Smrj (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) && 653ae115bc7Smrj (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 654ae115bc7Smrj (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) && 655ae115bc7Smrj (ThisNode->Type != ACPI_TYPE_ANY) && 656ae115bc7Smrj (ThisNode->Type != TypeToCheckFor)) 657ae115bc7Smrj { 658ae115bc7Smrj /* Complain about a type mismatch */ 659ae115bc7Smrj 660ae115bc7Smrj ACPI_WARNING ((AE_INFO, 661ae115bc7Smrj "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", 662ae115bc7Smrj ACPI_CAST_PTR (char, &SimpleName), 663ae115bc7Smrj AcpiUtGetTypeName (ThisNode->Type), 664ae115bc7Smrj AcpiUtGetTypeName (TypeToCheckFor))); 665ae115bc7Smrj } 666ae115bc7Smrj 667ae115bc7Smrj /* 668ae115bc7Smrj * If this is the last name segment and we are not looking for a 669aa2aa9a6SDana Myers * specific type, but the type of found object is known, use that 670aa2aa9a6SDana Myers * type to (later) see if it opens a scope. 671ae115bc7Smrj */ 672db2bae30SDana Myers if (Type == ACPI_TYPE_ANY) 673ae115bc7Smrj { 674ae115bc7Smrj Type = ThisNode->Type; 675ae115bc7Smrj } 676db2bae30SDana Myers } 677ae115bc7Smrj 678ae115bc7Smrj /* Point to next name segment and make this node current */ 679ae115bc7Smrj 680ae115bc7Smrj Path += ACPI_NAME_SIZE; 681ae115bc7Smrj CurrentNode = ThisNode; 682ae115bc7Smrj } 683ae115bc7Smrj 684aa2aa9a6SDana Myers /* Always check if we need to open a new scope */ 685aa2aa9a6SDana Myers 686ae115bc7Smrj if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState)) 687ae115bc7Smrj { 688ae115bc7Smrj /* 689ae115bc7Smrj * If entry is a type which opens a scope, push the new scope on the 690ae115bc7Smrj * scope stack. 691ae115bc7Smrj */ 692ae115bc7Smrj if (AcpiNsOpensScope (Type)) 693ae115bc7Smrj { 694ae115bc7Smrj Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState); 695ae115bc7Smrj if (ACPI_FAILURE (Status)) 696ae115bc7Smrj { 697ae115bc7Smrj return_ACPI_STATUS (Status); 698ae115bc7Smrj } 699ae115bc7Smrj } 700ae115bc7Smrj } 701ae115bc7Smrj 702ae115bc7Smrj *ReturnNode = ThisNode; 703ae115bc7Smrj return_ACPI_STATUS (AE_OK); 704ae115bc7Smrj } 705