167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 4967754Smsmith 5067754Smsmith 5177424Smsmith#define _COMPONENT ACPI_NAMESPACE 5291116Smsmith ACPI_MODULE_NAME ("nsaccess") 5367754Smsmith 5467754Smsmith 5567754Smsmith/******************************************************************************* 5667754Smsmith * 5767754Smsmith * FUNCTION: AcpiNsRootInitialize 5867754Smsmith * 5967754Smsmith * PARAMETERS: None 6067754Smsmith * 6167754Smsmith * RETURN: Status 6267754Smsmith * 6367754Smsmith * DESCRIPTION: Allocate and initialize the default root named objects 6467754Smsmith * 6567754Smsmith * MUTEX: Locks namespace for entire execution 6667754Smsmith * 6767754Smsmith ******************************************************************************/ 6867754Smsmith 6967754SmsmithACPI_STATUS 70151937SjkimAcpiNsRootInitialize ( 71151937Sjkim void) 7267754Smsmith{ 7391116Smsmith ACPI_STATUS Status; 7491116Smsmith const ACPI_PREDEFINED_NAMES *InitVal = NULL; 7591116Smsmith ACPI_NAMESPACE_NODE *NewNode; 7691116Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 77117521Snjl ACPI_STRING Val = NULL; 7867754Smsmith 7967754Smsmith 80167802Sjkim ACPI_FUNCTION_TRACE (NsRootInitialize); 8167754Smsmith 8267754Smsmith 8391116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 8491116Smsmith if (ACPI_FAILURE (Status)) 8591116Smsmith { 8691116Smsmith return_ACPI_STATUS (Status); 8791116Smsmith } 8867754Smsmith 8967754Smsmith /* 9067754Smsmith * The global root ptr is initially NULL, so a non-NULL value indicates 9167754Smsmith * that AcpiNsRootInitialize() has already been called; just return. 9267754Smsmith */ 9367754Smsmith if (AcpiGbl_RootNode) 9467754Smsmith { 9567754Smsmith Status = AE_OK; 9667754Smsmith goto UnlockAndExit; 9767754Smsmith } 9867754Smsmith 9967754Smsmith /* 10067754Smsmith * Tell the rest of the subsystem that the root is initialized 10167754Smsmith * (This is OK because the namespace is locked) 10267754Smsmith */ 10367754Smsmith AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; 10467754Smsmith 10567754Smsmith /* Enter the pre-defined names in the name table */ 10667754Smsmith 10791116Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 10891116Smsmith "Entering predefined entries into namespace\n")); 10967754Smsmith 11067754Smsmith for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) 11167754Smsmith { 112127175Snjl /* _OSI is optional for now, will be permanent later */ 113127175Snjl 114306536Sjkim if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) 115127175Snjl { 116127175Snjl continue; 117127175Snjl } 118127175Snjl 119306536Sjkim Status = AcpiNsLookup (NULL, ACPI_CAST_PTR (char, InitVal->Name), 120306536Sjkim InitVal->Type, ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, 121306536Sjkim NULL, &NewNode); 122241973Sjkim if (ACPI_FAILURE (Status)) 12367754Smsmith { 124167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 125167802Sjkim "Could not create predefined name %s", 126167802Sjkim InitVal->Name)); 127241973Sjkim continue; 12867754Smsmith } 12967754Smsmith 13067754Smsmith /* 131193267Sjkim * Name entered successfully. If entry in PreDefinedNames[] specifies 132193267Sjkim * an initial value, create the initial value. 13367754Smsmith */ 13467754Smsmith if (InitVal->Val) 13567754Smsmith { 136117521Snjl Status = AcpiOsPredefinedOverride (InitVal, &Val); 137114237Snjl if (ACPI_FAILURE (Status)) 138114237Snjl { 139167802Sjkim ACPI_ERROR ((AE_INFO, 140167802Sjkim "Could not override predefined %s", 141114237Snjl InitVal->Name)); 142114237Snjl } 143114237Snjl 144114237Snjl if (!Val) 145114237Snjl { 146114237Snjl Val = InitVal->Val; 147114237Snjl } 148114237Snjl 14967754Smsmith /* 15067754Smsmith * Entry requests an initial value, allocate a 15167754Smsmith * descriptor for it. 15267754Smsmith */ 15377424Smsmith ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); 15467754Smsmith if (!ObjDesc) 15567754Smsmith { 15667754Smsmith Status = AE_NO_MEMORY; 15767754Smsmith goto UnlockAndExit; 15867754Smsmith } 15967754Smsmith 16067754Smsmith /* 16167754Smsmith * Convert value string from table entry to 16267754Smsmith * internal representation. Only types actually 16367754Smsmith * used for initial values are implemented here. 16467754Smsmith */ 16567754Smsmith switch (InitVal->Type) 16667754Smsmith { 167102550Siwasaki case ACPI_TYPE_METHOD: 168250838Sjkim 169151937Sjkim ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val); 170102550Siwasaki ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 171102550Siwasaki 172151937Sjkim#if defined (ACPI_ASL_COMPILER) 173102550Siwasaki 174151937Sjkim /* Save the parameter count for the iASL compiler */ 175151937Sjkim 176151937Sjkim NewNode->Value = ObjDesc->Method.ParamCount; 177127175Snjl#else 178127175Snjl /* Mark this as a very SPECIAL method */ 179127175Snjl 180217365Sjkim ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY; 181217365Sjkim ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation; 182102550Siwasaki#endif 183102550Siwasaki break; 184102550Siwasaki 18571867Smsmith case ACPI_TYPE_INTEGER: 18667754Smsmith 187151937Sjkim ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val); 18867754Smsmith break; 18967754Smsmith 19067754Smsmith case ACPI_TYPE_STRING: 19167754Smsmith 192193267Sjkim /* Build an object around the static string */ 193193267Sjkim 194306536Sjkim ObjDesc->String.Length = (UINT32) strlen (Val); 195114237Snjl ObjDesc->String.Pointer = Val; 19682367Smsmith ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 19767754Smsmith break; 19867754Smsmith 19967754Smsmith case ACPI_TYPE_MUTEX: 20067754Smsmith 201107325Siwasaki ObjDesc->Mutex.Node = NewNode; 202151937Sjkim ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1); 20367754Smsmith 204167802Sjkim /* Create a mutex */ 205167802Sjkim 206167802Sjkim Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 207167802Sjkim if (ACPI_FAILURE (Status)) 20867754Smsmith { 209167802Sjkim AcpiUtRemoveReference (ObjDesc); 210167802Sjkim goto UnlockAndExit; 211167802Sjkim } 21283174Smsmith 213167802Sjkim /* Special case for ACPI Global Lock */ 214167802Sjkim 215306536Sjkim if (strcmp (InitVal->Name, "_GL_") == 0) 21667754Smsmith { 217167802Sjkim AcpiGbl_GlobalLockMutex = ObjDesc; 21867754Smsmith 219167802Sjkim /* Create additional counting semaphore for global lock */ 220167802Sjkim 221167802Sjkim Status = AcpiOsCreateSemaphore ( 222306536Sjkim 1, 0, &AcpiGbl_GlobalLockSemaphore); 22367754Smsmith if (ACPI_FAILURE (Status)) 22467754Smsmith { 225138287Smarks AcpiUtRemoveReference (ObjDesc); 22667754Smsmith goto UnlockAndExit; 22767754Smsmith } 22867754Smsmith } 22967754Smsmith break; 23067754Smsmith 23167754Smsmith default: 232127175Snjl 233204773Sjkim ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X", 23467754Smsmith InitVal->Type)); 23577424Smsmith AcpiUtRemoveReference (ObjDesc); 23667754Smsmith ObjDesc = NULL; 23767754Smsmith continue; 23867754Smsmith } 23967754Smsmith 24067754Smsmith /* Store pointer to value descriptor in the Node */ 24167754Smsmith 242138287Smarks Status = AcpiNsAttachObject (NewNode, ObjDesc, 243306536Sjkim ObjDesc->Common.Type); 24485756Smsmith 24585756Smsmith /* Remove local reference to the object */ 24685756Smsmith 24785756Smsmith AcpiUtRemoveReference (ObjDesc); 24867754Smsmith } 24967754Smsmith } 25067754Smsmith 25167754Smsmith 25267754SmsmithUnlockAndExit: 25391116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 254128212Snjl 255128212Snjl /* Save a handle to "_GPE", it is always present */ 256128212Snjl 257128212Snjl if (ACPI_SUCCESS (Status)) 258128212Snjl { 259167802Sjkim Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, 260306536Sjkim &AcpiGbl_FadtGpeDevice); 261128212Snjl } 262128212Snjl 26367754Smsmith return_ACPI_STATUS (Status); 26467754Smsmith} 26567754Smsmith 26667754Smsmith 26767754Smsmith/******************************************************************************* 26867754Smsmith * 26967754Smsmith * FUNCTION: AcpiNsLookup 27067754Smsmith * 271151937Sjkim * PARAMETERS: ScopeInfo - Current scope info block 27267754Smsmith * Pathname - Search pathname, in internal format 27367754Smsmith * (as represented in the AML stream) 27467754Smsmith * Type - Type associated with name 27567754Smsmith * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found 27667754Smsmith * Flags - Flags describing the search restrictions 27767754Smsmith * WalkState - Current state of the walk 27871867Smsmith * ReturnNode - Where the Node is placed (if found 27967754Smsmith * or created successfully) 28067754Smsmith * 28167754Smsmith * RETURN: Status 28267754Smsmith * 28367754Smsmith * DESCRIPTION: Find or enter the passed name in the name space. 28467754Smsmith * Log an error if name not found in Exec mode. 28567754Smsmith * 28667754Smsmith * MUTEX: Assumes namespace is locked. 28767754Smsmith * 28867754Smsmith ******************************************************************************/ 28967754Smsmith 29067754SmsmithACPI_STATUS 29167754SmsmithAcpiNsLookup ( 29267754Smsmith ACPI_GENERIC_STATE *ScopeInfo, 293114237Snjl char *Pathname, 29491116Smsmith ACPI_OBJECT_TYPE Type, 29591116Smsmith ACPI_INTERPRETER_MODE InterpreterMode, 29667754Smsmith UINT32 Flags, 29767754Smsmith ACPI_WALK_STATE *WalkState, 29867754Smsmith ACPI_NAMESPACE_NODE **ReturnNode) 29967754Smsmith{ 30067754Smsmith ACPI_STATUS Status; 301114237Snjl char *Path = Pathname; 30271867Smsmith ACPI_NAMESPACE_NODE *PrefixNode; 30367754Smsmith ACPI_NAMESPACE_NODE *CurrentNode = NULL; 30467754Smsmith ACPI_NAMESPACE_NODE *ThisNode = NULL; 30567754Smsmith UINT32 NumSegments; 306107325Siwasaki UINT32 NumCarats; 30767754Smsmith ACPI_NAME SimpleName; 30891116Smsmith ACPI_OBJECT_TYPE TypeToCheckFor; 30991116Smsmith ACPI_OBJECT_TYPE ThisSearchType; 310102550Siwasaki UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT; 311167802Sjkim UINT32 LocalFlags; 31267754Smsmith 31367754Smsmith 314167802Sjkim ACPI_FUNCTION_TRACE (NsLookup); 31567754Smsmith 31667754Smsmith 31767754Smsmith if (!ReturnNode) 31867754Smsmith { 31967754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 32067754Smsmith } 32167754Smsmith 322306536Sjkim LocalFlags = Flags & 323306536Sjkim ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND | 324306536Sjkim ACPI_NS_SEARCH_PARENT); 325167802Sjkim *ReturnNode = ACPI_ENTRY_NOT_FOUND; 32667754Smsmith AcpiGbl_NsLookupCount++; 32767754Smsmith 32867754Smsmith if (!AcpiGbl_RootNode) 32967754Smsmith { 33087031Smsmith return_ACPI_STATUS (AE_NO_NAMESPACE); 33167754Smsmith } 33267754Smsmith 333193267Sjkim /* Get the prefix scope. A null scope means use the root scope */ 334193267Sjkim 33567754Smsmith if ((!ScopeInfo) || 33667754Smsmith (!ScopeInfo->Scope.Node)) 33767754Smsmith { 33891116Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 33987031Smsmith "Null scope prefix, using root node (%p)\n", 34077424Smsmith AcpiGbl_RootNode)); 34169746Smsmith 34267754Smsmith PrefixNode = AcpiGbl_RootNode; 34367754Smsmith } 34467754Smsmith else 34567754Smsmith { 34667754Smsmith PrefixNode = ScopeInfo->Scope.Node; 347102550Siwasaki if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED) 348102550Siwasaki { 349167802Sjkim ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]", 350167802Sjkim PrefixNode, AcpiUtGetDescriptorName (PrefixNode))); 351102550Siwasaki return_ACPI_STATUS (AE_AML_INTERNAL); 352102550Siwasaki } 353102550Siwasaki 354167802Sjkim if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE)) 355102550Siwasaki { 356167802Sjkim /* 357167802Sjkim * This node might not be a actual "scope" node (such as a 358193267Sjkim * Device/Method, etc.) It could be a Package or other object 359193267Sjkim * node. Backup up the tree to find the containing scope node. 360167802Sjkim */ 361167802Sjkim while (!AcpiNsOpensScope (PrefixNode->Type) && 362167802Sjkim PrefixNode->Type != ACPI_TYPE_ANY) 363167802Sjkim { 364209746Sjkim PrefixNode = PrefixNode->Parent; 365167802Sjkim } 366102550Siwasaki } 36767754Smsmith } 36867754Smsmith 369193267Sjkim /* Save type. TBD: may be no longer necessary */ 37067754Smsmith 371107325Siwasaki TypeToCheckFor = Type; 37267754Smsmith 37391116Smsmith /* 37491116Smsmith * Begin examination of the actual pathname 37591116Smsmith */ 37667754Smsmith if (!Pathname) 37767754Smsmith { 37891116Smsmith /* A Null NamePath is allowed and refers to the root */ 37967754Smsmith 380167802Sjkim NumSegments = 0; 381167802Sjkim ThisNode = AcpiGbl_RootNode; 382167802Sjkim Path = ""; 38367754Smsmith 38482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 38599679Siwasaki "Null Pathname (Zero segments), Flags=%X\n", Flags)); 38667754Smsmith } 38767754Smsmith else 38867754Smsmith { 38967754Smsmith /* 39091116Smsmith * Name pointer is valid (and must be in internal name format) 39167754Smsmith * 39291116Smsmith * Check for scope prefixes: 39367754Smsmith * 39491116Smsmith * As represented in the AML stream, a namepath consists of an 39591116Smsmith * optional scope prefix followed by a name segment part. 39691116Smsmith * 39791116Smsmith * If present, the scope prefix is either a Root Prefix (in 39891116Smsmith * which case the name is fully qualified), or one or more 39991116Smsmith * Parent Prefixes (in which case the name's scope is relative 40067754Smsmith * to the current scope). 40167754Smsmith */ 402102550Siwasaki if (*Path == (UINT8) AML_ROOT_PREFIX) 40367754Smsmith { 40487031Smsmith /* Pathname is fully qualified, start from the root */ 40567754Smsmith 40691116Smsmith ThisNode = AcpiGbl_RootNode; 407102550Siwasaki SearchParentFlag = ACPI_NS_NO_UPSEARCH; 40867754Smsmith 40991116Smsmith /* Point to name segment part */ 41067754Smsmith 411102550Siwasaki Path++; 41267754Smsmith 413114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 414102550Siwasaki "Path is absolute from root [%p]\n", ThisNode)); 41567754Smsmith } 41667754Smsmith else 41767754Smsmith { 41867754Smsmith /* Pathname is relative to current scope, start there */ 41967754Smsmith 42091116Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 421107325Siwasaki "Searching relative to prefix scope [%4.4s] (%p)\n", 422123315Snjl AcpiUtGetNodeName (PrefixNode), PrefixNode)); 42367754Smsmith 42467754Smsmith /* 42591116Smsmith * Handle multiple Parent Prefixes (carat) by just getting 42691116Smsmith * the parent node for each prefix instance. 42767754Smsmith */ 42891116Smsmith ThisNode = PrefixNode; 429107325Siwasaki NumCarats = 0; 430102550Siwasaki while (*Path == (UINT8) AML_PARENT_PREFIX) 43167754Smsmith { 432102550Siwasaki /* Name is fully qualified, no search rules apply */ 433102550Siwasaki 434102550Siwasaki SearchParentFlag = ACPI_NS_NO_UPSEARCH; 435193267Sjkim 43691116Smsmith /* 43791116Smsmith * Point past this prefix to the name segment 43891116Smsmith * part or the next Parent Prefix 43991116Smsmith */ 440102550Siwasaki Path++; 44167754Smsmith 44291116Smsmith /* Backup to the parent node */ 44367754Smsmith 444107325Siwasaki NumCarats++; 445209746Sjkim ThisNode = ThisNode->Parent; 44667754Smsmith if (!ThisNode) 44767754Smsmith { 44867754Smsmith /* Current scope has no parent scope */ 44967754Smsmith 450167802Sjkim ACPI_ERROR ((AE_INFO, 451254745Sjkim "%s: Path has too many parent prefixes (^) " 452254745Sjkim "- reached beyond root node", Pathname)); 45367754Smsmith return_ACPI_STATUS (AE_NOT_FOUND); 45467754Smsmith } 45567754Smsmith } 456102550Siwasaki 457102550Siwasaki if (SearchParentFlag == ACPI_NS_NO_UPSEARCH) 458102550Siwasaki { 459102550Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 460209746Sjkim "Search scope is [%4.4s], path has %u carat(s)\n", 461123315Snjl AcpiUtGetNodeName (ThisNode), NumCarats)); 462102550Siwasaki } 46367754Smsmith } 46467754Smsmith 46567754Smsmith /* 46691116Smsmith * Determine the number of ACPI name segments in this pathname. 46791116Smsmith * 46891116Smsmith * The segment part consists of either: 46991116Smsmith * - A Null name segment (0) 47091116Smsmith * - A DualNamePrefix followed by two 4-byte name segments 47191116Smsmith * - A MultiNamePrefix followed by a byte indicating the 47291116Smsmith * number of segments and the segments themselves. 47391116Smsmith * - A single 4-byte name segment 47491116Smsmith * 47591116Smsmith * Examine the name prefix opcode, if any, to determine the number of 47691116Smsmith * segments. 47767754Smsmith */ 478102550Siwasaki switch (*Path) 47967754Smsmith { 48091116Smsmith case 0: 48191116Smsmith /* 48291116Smsmith * Null name after a root or parent prefixes. We already 48391116Smsmith * have the correct target node and there are no name segments. 48491116Smsmith */ 48591116Smsmith NumSegments = 0; 486107325Siwasaki Type = ThisNode->Type; 48787031Smsmith 48891116Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 489138287Smarks "Prefix-only Pathname (Zero name segments), Flags=%X\n", 490138287Smarks Flags)); 49191116Smsmith break; 49291116Smsmith 49391116Smsmith case AML_DUAL_NAME_PREFIX: 49491116Smsmith 495102550Siwasaki /* More than one NameSeg, search rules do not apply */ 496102550Siwasaki 497102550Siwasaki SearchParentFlag = ACPI_NS_NO_UPSEARCH; 498102550Siwasaki 49991116Smsmith /* Two segments, point to first name segment */ 50091116Smsmith 50167754Smsmith NumSegments = 2; 502102550Siwasaki Path++; 50367754Smsmith 50482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 50582367Smsmith "Dual Pathname (2 segments, Flags=%X)\n", Flags)); 50691116Smsmith break; 50787031Smsmith 50891116Smsmith case AML_MULTI_NAME_PREFIX_OP: 50991116Smsmith 510102550Siwasaki /* More than one NameSeg, search rules do not apply */ 511102550Siwasaki 512102550Siwasaki SearchParentFlag = ACPI_NS_NO_UPSEARCH; 513102550Siwasaki 51491116Smsmith /* Extract segment count, point to first name segment */ 51591116Smsmith 516102550Siwasaki Path++; 517102550Siwasaki NumSegments = (UINT32) (UINT8) *Path; 518102550Siwasaki Path++; 51967754Smsmith 52082367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 521209746Sjkim "Multi Pathname (%u Segments, Flags=%X)\n", 52267754Smsmith NumSegments, Flags)); 52391116Smsmith break; 52491116Smsmith 52591116Smsmith default: 52667754Smsmith /* 52791116Smsmith * Not a Null name, no Dual or Multi prefix, hence there is 52891116Smsmith * only one name segment and Pathname is already pointing to it. 52967754Smsmith */ 53067754Smsmith NumSegments = 1; 53167754Smsmith 53282367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 53382367Smsmith "Simple Pathname (1 segment, Flags=%X)\n", Flags)); 53491116Smsmith break; 53567754Smsmith } 53667754Smsmith 537102550Siwasaki ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path)); 53867754Smsmith } 53967754Smsmith 540102550Siwasaki 54167754Smsmith /* 542193267Sjkim * Search namespace for each segment of the name. Loop through and 543102550Siwasaki * verify (or add to the namespace) each name segment. 544102550Siwasaki * 545102550Siwasaki * The object type is significant only at the last name 546193267Sjkim * segment. (We don't care about the types along the path, only 547102550Siwasaki * the type of the final target object.) 54867754Smsmith */ 549102550Siwasaki ThisSearchType = ACPI_TYPE_ANY; 55091116Smsmith CurrentNode = ThisNode; 55191116Smsmith while (NumSegments && CurrentNode) 55267754Smsmith { 55391116Smsmith NumSegments--; 55467754Smsmith if (!NumSegments) 55567754Smsmith { 556193267Sjkim /* This is the last segment, enable typechecking */ 557193267Sjkim 55867754Smsmith ThisSearchType = Type; 559102550Siwasaki 560102550Siwasaki /* 561102550Siwasaki * Only allow automatic parent search (search rules) if the caller 562102550Siwasaki * requested it AND we have a single, non-fully-qualified NameSeg 563102550Siwasaki */ 564102550Siwasaki if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) && 565102550Siwasaki (Flags & ACPI_NS_SEARCH_PARENT)) 566102550Siwasaki { 567102550Siwasaki LocalFlags |= ACPI_NS_SEARCH_PARENT; 568102550Siwasaki } 569102550Siwasaki 570102550Siwasaki /* Set error flag according to caller */ 571102550Siwasaki 572102550Siwasaki if (Flags & ACPI_NS_ERROR_IF_FOUND) 573102550Siwasaki { 574102550Siwasaki LocalFlags |= ACPI_NS_ERROR_IF_FOUND; 575102550Siwasaki } 576306536Sjkim 577306536Sjkim /* Set override flag according to caller */ 578306536Sjkim 579306536Sjkim if (Flags & ACPI_NS_OVERRIDE_IF_FOUND) 580306536Sjkim { 581306536Sjkim LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND; 582306536Sjkim } 58367754Smsmith } 58467754Smsmith 58591116Smsmith /* Extract one ACPI name from the front of the pathname */ 58667754Smsmith 587117521Snjl ACPI_MOVE_32_TO_32 (&SimpleName, Path); 58867754Smsmith 589102550Siwasaki /* Try to find the single (4 character) ACPI name */ 59067754Smsmith 59191116Smsmith Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode, 592306536Sjkim InterpreterMode, ThisSearchType, LocalFlags, &ThisNode); 59367754Smsmith if (ACPI_FAILURE (Status)) 59467754Smsmith { 59567754Smsmith if (Status == AE_NOT_FOUND) 59667754Smsmith { 59791116Smsmith /* Name not found in ACPI namespace */ 59867754Smsmith 59983174Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 60091116Smsmith "Name [%4.4s] not found in scope [%4.4s] %p\n", 601114237Snjl (char *) &SimpleName, (char *) &CurrentNode->Name, 602102550Siwasaki CurrentNode)); 60367754Smsmith } 60467754Smsmith 605107325Siwasaki *ReturnNode = ThisNode; 60667754Smsmith return_ACPI_STATUS (Status); 60767754Smsmith } 60867754Smsmith 609193267Sjkim /* More segments to follow? */ 610193267Sjkim 611193267Sjkim if (NumSegments > 0) 61267754Smsmith { 613193267Sjkim /* 614193267Sjkim * If we have an alias to an object that opens a scope (such as a 615193267Sjkim * device or processor), we need to dereference the alias here so 616193267Sjkim * that we can access any children of the original node (via the 617193267Sjkim * remaining segments). 618193267Sjkim */ 619193267Sjkim if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS) 620193267Sjkim { 621193267Sjkim if (!ThisNode->Object) 622193267Sjkim { 623193267Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 624193267Sjkim } 62567754Smsmith 626193267Sjkim if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *) 627193267Sjkim ThisNode->Object)->Type)) 628193267Sjkim { 629193267Sjkim ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object; 630193267Sjkim } 631193267Sjkim } 63267754Smsmith } 63367754Smsmith 634193267Sjkim /* Special handling for the last segment (NumSegments == 0) */ 635193267Sjkim 636193267Sjkim else 63767754Smsmith { 638193267Sjkim /* 639193267Sjkim * Sanity typecheck of the target object: 640193267Sjkim * 641193267Sjkim * If 1) This is the last segment (NumSegments == 0) 642193267Sjkim * 2) And we are looking for a specific type 643193267Sjkim * (Not checking for TYPE_ANY) 644193267Sjkim * 3) Which is not an alias 645193267Sjkim * 4) Which is not a local type (TYPE_SCOPE) 646193267Sjkim * 5) And the type of target object is known (not TYPE_ANY) 647193267Sjkim * 6) And target object does not match what we are looking for 648193267Sjkim * 649193267Sjkim * Then we have a type mismatch. Just warn and ignore it. 650193267Sjkim */ 651193267Sjkim if ((TypeToCheckFor != ACPI_TYPE_ANY) && 652193267Sjkim (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) && 653193267Sjkim (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 654193267Sjkim (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) && 655193267Sjkim (ThisNode->Type != ACPI_TYPE_ANY) && 656193267Sjkim (ThisNode->Type != TypeToCheckFor)) 657193267Sjkim { 658193267Sjkim /* Complain about a type mismatch */ 659193267Sjkim 660193267Sjkim ACPI_WARNING ((AE_INFO, 661193267Sjkim "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", 662193267Sjkim ACPI_CAST_PTR (char, &SimpleName), 663193267Sjkim AcpiUtGetTypeName (ThisNode->Type), 664193267Sjkim AcpiUtGetTypeName (TypeToCheckFor))); 665193267Sjkim } 666193267Sjkim 667193267Sjkim /* 668193267Sjkim * If this is the last name segment and we are not looking for a 669193267Sjkim * specific type, but the type of found object is known, use that 670193267Sjkim * type to (later) see if it opens a scope. 671193267Sjkim */ 672193267Sjkim if (Type == ACPI_TYPE_ANY) 673193267Sjkim { 674193267Sjkim Type = ThisNode->Type; 675193267Sjkim } 67667754Smsmith } 67767754Smsmith 67891116Smsmith /* Point to next name segment and make this node current */ 67967754Smsmith 680102550Siwasaki Path += ACPI_NAME_SIZE; 68167754Smsmith CurrentNode = ThisNode; 68267754Smsmith } 68367754Smsmith 684193267Sjkim /* Always check if we need to open a new scope */ 685193267Sjkim 68691116Smsmith if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState)) 68767754Smsmith { 68867754Smsmith /* 68991116Smsmith * If entry is a type which opens a scope, push the new scope on the 69087031Smsmith * scope stack. 69167754Smsmith */ 692107325Siwasaki if (AcpiNsOpensScope (Type)) 69367754Smsmith { 69487031Smsmith Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState); 69567754Smsmith if (ACPI_FAILURE (Status)) 69667754Smsmith { 69767754Smsmith return_ACPI_STATUS (Status); 69867754Smsmith } 69967754Smsmith } 70067754Smsmith } 70167754Smsmith 70267754Smsmith *ReturnNode = ThisNode; 70367754Smsmith return_ACPI_STATUS (AE_OK); 70467754Smsmith} 705