128c506b8Sjruoho /*******************************************************************************
228c506b8Sjruoho *
328c506b8Sjruoho * Module Name: nssearch - Namespace search
428c506b8Sjruoho *
528c506b8Sjruoho ******************************************************************************/
628c506b8Sjruoho
7124f4c82Sjruoho /*
8*046a2985Schristos * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho * All rights reserved.
1028c506b8Sjruoho *
11124f4c82Sjruoho * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho * modification, are permitted provided that the following conditions
13124f4c82Sjruoho * are met:
14124f4c82Sjruoho * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho * notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho * without modification.
17124f4c82Sjruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho * substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho * ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho * including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho * binary redistribution.
22124f4c82Sjruoho * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho * of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho * from this software without specific prior written permission.
2528c506b8Sjruoho *
26124f4c82Sjruoho * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho * Software Foundation.
2928c506b8Sjruoho *
30124f4c82Sjruoho * NO WARRANTY
31124f4c82Sjruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho */
4328c506b8Sjruoho
4428c506b8Sjruoho #include "acpi.h"
4528c506b8Sjruoho #include "accommon.h"
4628c506b8Sjruoho #include "acnamesp.h"
4728c506b8Sjruoho
4828c506b8Sjruoho #ifdef ACPI_ASL_COMPILER
4928c506b8Sjruoho #include "amlcode.h"
5028c506b8Sjruoho #endif
5128c506b8Sjruoho
5228c506b8Sjruoho #define _COMPONENT ACPI_NAMESPACE
5328c506b8Sjruoho ACPI_MODULE_NAME ("nssearch")
5428c506b8Sjruoho
5528c506b8Sjruoho /* Local prototypes */
5628c506b8Sjruoho
5728c506b8Sjruoho static ACPI_STATUS
5828c506b8Sjruoho AcpiNsSearchParentTree (
5928c506b8Sjruoho UINT32 TargetName,
6028c506b8Sjruoho ACPI_NAMESPACE_NODE *Node,
6128c506b8Sjruoho ACPI_OBJECT_TYPE Type,
6228c506b8Sjruoho ACPI_NAMESPACE_NODE **ReturnNode);
6328c506b8Sjruoho
6428c506b8Sjruoho
6528c506b8Sjruoho /*******************************************************************************
6628c506b8Sjruoho *
6728c506b8Sjruoho * FUNCTION: AcpiNsSearchOneScope
6828c506b8Sjruoho *
6928c506b8Sjruoho * PARAMETERS: TargetName - Ascii ACPI name to search for
7028c506b8Sjruoho * ParentNode - Starting node where search will begin
7128c506b8Sjruoho * Type - Object type to match
7228c506b8Sjruoho * ReturnNode - Where the matched Named obj is returned
7328c506b8Sjruoho *
7428c506b8Sjruoho * RETURN: Status
7528c506b8Sjruoho *
7628c506b8Sjruoho * DESCRIPTION: Search a single level of the namespace. Performs a
7728c506b8Sjruoho * simple search of the specified level, and does not add
7828c506b8Sjruoho * entries or search parents.
7928c506b8Sjruoho *
8028c506b8Sjruoho *
8128c506b8Sjruoho * Named object lists are built (and subsequently dumped) in the
8228c506b8Sjruoho * order in which the names are encountered during the namespace load;
8328c506b8Sjruoho *
8428c506b8Sjruoho * All namespace searching is linear in this implementation, but
8528c506b8Sjruoho * could be easily modified to support any improved search
8628c506b8Sjruoho * algorithm. However, the linear search was chosen for simplicity
8728c506b8Sjruoho * and because the trees are small and the other interpreter
8828c506b8Sjruoho * execution overhead is relatively high.
8928c506b8Sjruoho *
9028c506b8Sjruoho * Note: CPU execution analysis has shown that the AML interpreter spends
9128c506b8Sjruoho * a very small percentage of its time searching the namespace. Therefore,
9228c506b8Sjruoho * the linear search seems to be sufficient, as there would seem to be
9328c506b8Sjruoho * little value in improving the search.
9428c506b8Sjruoho *
9528c506b8Sjruoho ******************************************************************************/
9628c506b8Sjruoho
9728c506b8Sjruoho ACPI_STATUS
AcpiNsSearchOneScope(UINT32 TargetName,ACPI_NAMESPACE_NODE * ParentNode,ACPI_OBJECT_TYPE Type,ACPI_NAMESPACE_NODE ** ReturnNode)9828c506b8Sjruoho AcpiNsSearchOneScope (
9928c506b8Sjruoho UINT32 TargetName,
10028c506b8Sjruoho ACPI_NAMESPACE_NODE *ParentNode,
10128c506b8Sjruoho ACPI_OBJECT_TYPE Type,
10228c506b8Sjruoho ACPI_NAMESPACE_NODE **ReturnNode)
10328c506b8Sjruoho {
10428c506b8Sjruoho ACPI_NAMESPACE_NODE *Node;
10528c506b8Sjruoho
10628c506b8Sjruoho
10728c506b8Sjruoho ACPI_FUNCTION_TRACE (NsSearchOneScope);
10828c506b8Sjruoho
10928c506b8Sjruoho
11028c506b8Sjruoho #ifdef ACPI_DEBUG_OUTPUT
11128c506b8Sjruoho if (ACPI_LV_NAMES & AcpiDbgLevel)
11228c506b8Sjruoho {
11328c506b8Sjruoho char *ScopeName;
11428c506b8Sjruoho
11571e38f1dSchristos ScopeName = AcpiNsGetNormalizedPathname (ParentNode, TRUE);
11628c506b8Sjruoho if (ScopeName)
11728c506b8Sjruoho {
11828c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
11928c506b8Sjruoho "Searching %s (%p) For [%4.4s] (%s)\n",
12028c506b8Sjruoho ScopeName, ParentNode, ACPI_CAST_PTR (char, &TargetName),
12128c506b8Sjruoho AcpiUtGetTypeName (Type)));
12228c506b8Sjruoho
12328c506b8Sjruoho ACPI_FREE (ScopeName);
12428c506b8Sjruoho }
12528c506b8Sjruoho }
12628c506b8Sjruoho #endif
12728c506b8Sjruoho
12828c506b8Sjruoho /*
12928c506b8Sjruoho * Search for name at this namespace level, which is to say that we
13028c506b8Sjruoho * must search for the name among the children of this object
13128c506b8Sjruoho */
13228c506b8Sjruoho Node = ParentNode->Child;
13328c506b8Sjruoho while (Node)
13428c506b8Sjruoho {
13528c506b8Sjruoho /* Check for match against the name */
13628c506b8Sjruoho
13728c506b8Sjruoho if (Node->Name.Integer == TargetName)
13828c506b8Sjruoho {
13928c506b8Sjruoho /* Resolve a control method alias if any */
14028c506b8Sjruoho
14128c506b8Sjruoho if (AcpiNsGetType (Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS)
14228c506b8Sjruoho {
14328c506b8Sjruoho Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Node->Object);
14428c506b8Sjruoho }
14528c506b8Sjruoho
14628c506b8Sjruoho /* Found matching entry */
14728c506b8Sjruoho
14828c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
14928c506b8Sjruoho "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
15028c506b8Sjruoho ACPI_CAST_PTR (char, &TargetName),
15128c506b8Sjruoho AcpiUtGetTypeName (Node->Type),
15228c506b8Sjruoho Node, AcpiUtGetNodeName (ParentNode), ParentNode));
15328c506b8Sjruoho
15428c506b8Sjruoho *ReturnNode = Node;
15528c506b8Sjruoho return_ACPI_STATUS (AE_OK);
15628c506b8Sjruoho }
15728c506b8Sjruoho
15828c506b8Sjruoho /* Didn't match name, move on to the next peer object */
15928c506b8Sjruoho
16028c506b8Sjruoho Node = Node->Peer;
16128c506b8Sjruoho }
16228c506b8Sjruoho
16328c506b8Sjruoho /* Searched entire namespace level, not found */
16428c506b8Sjruoho
16528c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
16628c506b8Sjruoho "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
16728c506b8Sjruoho "%p first child %p\n",
16828c506b8Sjruoho ACPI_CAST_PTR (char, &TargetName), AcpiUtGetTypeName (Type),
16928c506b8Sjruoho AcpiUtGetNodeName (ParentNode), ParentNode, ParentNode->Child));
17028c506b8Sjruoho
17128c506b8Sjruoho return_ACPI_STATUS (AE_NOT_FOUND);
17228c506b8Sjruoho }
17328c506b8Sjruoho
17428c506b8Sjruoho
17528c506b8Sjruoho /*******************************************************************************
17628c506b8Sjruoho *
17728c506b8Sjruoho * FUNCTION: AcpiNsSearchParentTree
17828c506b8Sjruoho *
17928c506b8Sjruoho * PARAMETERS: TargetName - Ascii ACPI name to search for
18028c506b8Sjruoho * Node - Starting node where search will begin
18128c506b8Sjruoho * Type - Object type to match
18228c506b8Sjruoho * ReturnNode - Where the matched Node is returned
18328c506b8Sjruoho *
18428c506b8Sjruoho * RETURN: Status
18528c506b8Sjruoho *
18628c506b8Sjruoho * DESCRIPTION: Called when a name has not been found in the current namespace
18728c506b8Sjruoho * level. Before adding it or giving up, ACPI scope rules require
18828c506b8Sjruoho * searching enclosing scopes in cases identified by AcpiNsLocal().
18928c506b8Sjruoho *
19028c506b8Sjruoho * "A name is located by finding the matching name in the current
19128c506b8Sjruoho * name space, and then in the parent name space. If the parent
19228c506b8Sjruoho * name space does not contain the name, the search continues
19328c506b8Sjruoho * recursively until either the name is found or the name space
19428c506b8Sjruoho * does not have a parent (the root of the name space). This
19528c506b8Sjruoho * indicates that the name is not found" (From ACPI Specification,
19628c506b8Sjruoho * section 5.3)
19728c506b8Sjruoho *
19828c506b8Sjruoho ******************************************************************************/
19928c506b8Sjruoho
20028c506b8Sjruoho static ACPI_STATUS
AcpiNsSearchParentTree(UINT32 TargetName,ACPI_NAMESPACE_NODE * Node,ACPI_OBJECT_TYPE Type,ACPI_NAMESPACE_NODE ** ReturnNode)20128c506b8Sjruoho AcpiNsSearchParentTree (
20228c506b8Sjruoho UINT32 TargetName,
20328c506b8Sjruoho ACPI_NAMESPACE_NODE *Node,
20428c506b8Sjruoho ACPI_OBJECT_TYPE Type,
20528c506b8Sjruoho ACPI_NAMESPACE_NODE **ReturnNode)
20628c506b8Sjruoho {
20728c506b8Sjruoho ACPI_STATUS Status;
20828c506b8Sjruoho ACPI_NAMESPACE_NODE *ParentNode;
20928c506b8Sjruoho
21028c506b8Sjruoho
21128c506b8Sjruoho ACPI_FUNCTION_TRACE (NsSearchParentTree);
21228c506b8Sjruoho
21328c506b8Sjruoho
21428c506b8Sjruoho ParentNode = Node->Parent;
21528c506b8Sjruoho
21628c506b8Sjruoho /*
21728c506b8Sjruoho * If there is no parent (i.e., we are at the root) or type is "local",
21828c506b8Sjruoho * we won't be searching the parent tree.
21928c506b8Sjruoho */
22028c506b8Sjruoho if (!ParentNode)
22128c506b8Sjruoho {
22228c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
22328c506b8Sjruoho ACPI_CAST_PTR (char, &TargetName)));
22428c506b8Sjruoho return_ACPI_STATUS (AE_NOT_FOUND);
22528c506b8Sjruoho }
22628c506b8Sjruoho
22728c506b8Sjruoho if (AcpiNsLocal (Type))
22828c506b8Sjruoho {
22928c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
23028c506b8Sjruoho "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
23128c506b8Sjruoho ACPI_CAST_PTR (char, &TargetName), AcpiUtGetTypeName (Type)));
23228c506b8Sjruoho return_ACPI_STATUS (AE_NOT_FOUND);
23328c506b8Sjruoho }
23428c506b8Sjruoho
23528c506b8Sjruoho /* Search the parent tree */
23628c506b8Sjruoho
23728c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
23828c506b8Sjruoho "Searching parent [%4.4s] for [%4.4s]\n",
23928c506b8Sjruoho AcpiUtGetNodeName (ParentNode), ACPI_CAST_PTR (char, &TargetName)));
24028c506b8Sjruoho
24128c506b8Sjruoho /* Search parents until target is found or we have backed up to the root */
24228c506b8Sjruoho
24328c506b8Sjruoho while (ParentNode)
24428c506b8Sjruoho {
24528c506b8Sjruoho /*
24628c506b8Sjruoho * Search parent scope. Use TYPE_ANY because we don't care about the
24728c506b8Sjruoho * object type at this point, we only care about the existence of
24828c506b8Sjruoho * the actual name we are searching for. Typechecking comes later.
24928c506b8Sjruoho */
25028c506b8Sjruoho Status = AcpiNsSearchOneScope (
25128c506b8Sjruoho TargetName, ParentNode, ACPI_TYPE_ANY, ReturnNode);
25228c506b8Sjruoho if (ACPI_SUCCESS (Status))
25328c506b8Sjruoho {
25428c506b8Sjruoho return_ACPI_STATUS (Status);
25528c506b8Sjruoho }
25628c506b8Sjruoho
25728c506b8Sjruoho /* Not found here, go up another level (until we reach the root) */
25828c506b8Sjruoho
25928c506b8Sjruoho ParentNode = ParentNode->Parent;
26028c506b8Sjruoho }
26128c506b8Sjruoho
26228c506b8Sjruoho /* Not found in parent tree */
26328c506b8Sjruoho
26428c506b8Sjruoho return_ACPI_STATUS (AE_NOT_FOUND);
26528c506b8Sjruoho }
26628c506b8Sjruoho
26728c506b8Sjruoho
26828c506b8Sjruoho /*******************************************************************************
26928c506b8Sjruoho *
27028c506b8Sjruoho * FUNCTION: AcpiNsSearchAndEnter
27128c506b8Sjruoho *
27228c506b8Sjruoho * PARAMETERS: TargetName - Ascii ACPI name to search for (4 chars)
27328c506b8Sjruoho * WalkState - Current state of the walk
27428c506b8Sjruoho * Node - Starting node where search will begin
27528c506b8Sjruoho * InterpreterMode - Add names only in ACPI_MODE_LOAD_PASS_x.
27628c506b8Sjruoho * Otherwise,search only.
27728c506b8Sjruoho * Type - Object type to match
27828c506b8Sjruoho * Flags - Flags describing the search restrictions
27928c506b8Sjruoho * ReturnNode - Where the Node is returned
28028c506b8Sjruoho *
28128c506b8Sjruoho * RETURN: Status
28228c506b8Sjruoho *
28328c506b8Sjruoho * DESCRIPTION: Search for a name segment in a single namespace level,
28428c506b8Sjruoho * optionally adding it if it is not found. If the passed
28528c506b8Sjruoho * Type is not Any and the type previously stored in the
28628c506b8Sjruoho * entry was Any (i.e. unknown), update the stored type.
28728c506b8Sjruoho *
28828c506b8Sjruoho * In ACPI_IMODE_EXECUTE, search only.
28928c506b8Sjruoho * In other modes, search and add if not found.
29028c506b8Sjruoho *
29128c506b8Sjruoho ******************************************************************************/
29228c506b8Sjruoho
29328c506b8Sjruoho ACPI_STATUS
AcpiNsSearchAndEnter(UINT32 TargetName,ACPI_WALK_STATE * WalkState,ACPI_NAMESPACE_NODE * Node,ACPI_INTERPRETER_MODE InterpreterMode,ACPI_OBJECT_TYPE Type,UINT32 Flags,ACPI_NAMESPACE_NODE ** ReturnNode)29428c506b8Sjruoho AcpiNsSearchAndEnter (
29528c506b8Sjruoho UINT32 TargetName,
29628c506b8Sjruoho ACPI_WALK_STATE *WalkState,
29728c506b8Sjruoho ACPI_NAMESPACE_NODE *Node,
29828c506b8Sjruoho ACPI_INTERPRETER_MODE InterpreterMode,
29928c506b8Sjruoho ACPI_OBJECT_TYPE Type,
30028c506b8Sjruoho UINT32 Flags,
30128c506b8Sjruoho ACPI_NAMESPACE_NODE **ReturnNode)
30228c506b8Sjruoho {
30328c506b8Sjruoho ACPI_STATUS Status;
30428c506b8Sjruoho ACPI_NAMESPACE_NODE *NewNode;
30528c506b8Sjruoho
30628c506b8Sjruoho
30728c506b8Sjruoho ACPI_FUNCTION_TRACE (NsSearchAndEnter);
30828c506b8Sjruoho
30928c506b8Sjruoho
31028c506b8Sjruoho /* Parameter validation */
31128c506b8Sjruoho
31228c506b8Sjruoho if (!Node || !TargetName || !ReturnNode)
31328c506b8Sjruoho {
31428c506b8Sjruoho ACPI_ERROR ((AE_INFO,
31528c506b8Sjruoho "Null parameter: Node %p Name 0x%X ReturnNode %p",
31628c506b8Sjruoho Node, TargetName, ReturnNode));
31728c506b8Sjruoho return_ACPI_STATUS (AE_BAD_PARAMETER);
31828c506b8Sjruoho }
31928c506b8Sjruoho
32028c506b8Sjruoho /*
32128c506b8Sjruoho * Name must consist of valid ACPI characters. We will repair the name if
32228c506b8Sjruoho * necessary because we don't want to abort because of this, but we want
32328c506b8Sjruoho * all namespace names to be printable. A warning message is appropriate.
32428c506b8Sjruoho *
32528c506b8Sjruoho * This issue came up because there are in fact machines that exhibit
32628c506b8Sjruoho * this problem, and we want to be able to enable ACPI support for them,
32728c506b8Sjruoho * even though there are a few bad names.
32828c506b8Sjruoho */
32928c506b8Sjruoho AcpiUtRepairName (ACPI_CAST_PTR (char, &TargetName));
33028c506b8Sjruoho
33128c506b8Sjruoho /* Try to find the name in the namespace level specified by the caller */
33228c506b8Sjruoho
33328c506b8Sjruoho *ReturnNode = ACPI_ENTRY_NOT_FOUND;
33428c506b8Sjruoho Status = AcpiNsSearchOneScope (TargetName, Node, Type, ReturnNode);
33528c506b8Sjruoho if (Status != AE_NOT_FOUND)
33628c506b8Sjruoho {
33728c506b8Sjruoho /*
33828c506b8Sjruoho * If we found it AND the request specifies that a find is an error,
33928c506b8Sjruoho * return the error
34028c506b8Sjruoho */
341c72da027Schristos if (Status == AE_OK)
342c72da027Schristos {
343c72da027Schristos /* The node was found in the namespace */
344c72da027Schristos
345c72da027Schristos /*
346c72da027Schristos * If the namespace override feature is enabled for this node,
347c72da027Schristos * delete any existing attached sub-object and make the node
348c72da027Schristos * look like a new node that is owned by the override table.
349c72da027Schristos */
350c72da027Schristos if (Flags & ACPI_NS_OVERRIDE_IF_FOUND)
351c72da027Schristos {
352c72da027Schristos ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
353c72da027Schristos "Namespace override: %4.4s pass %u type %X Owner %X\n",
354c72da027Schristos ACPI_CAST_PTR(char, &TargetName), InterpreterMode,
355c72da027Schristos (*ReturnNode)->Type, WalkState->OwnerId));
356c72da027Schristos
357c72da027Schristos AcpiNsDeleteChildren (*ReturnNode);
358c72da027Schristos if (AcpiGbl_RuntimeNamespaceOverride)
359c72da027Schristos {
360c72da027Schristos AcpiUtRemoveReference ((*ReturnNode)->Object);
361c72da027Schristos (*ReturnNode)->Object = NULL;
362c72da027Schristos (*ReturnNode)->OwnerId = WalkState->OwnerId;
363c72da027Schristos }
364c72da027Schristos else
365c72da027Schristos {
366c72da027Schristos AcpiNsRemoveNode (*ReturnNode);
367c72da027Schristos *ReturnNode = ACPI_ENTRY_NOT_FOUND;
368c72da027Schristos }
369c72da027Schristos }
370c72da027Schristos
371c72da027Schristos /* Return an error if we don't expect to find the object */
372c72da027Schristos
373c72da027Schristos else if (Flags & ACPI_NS_ERROR_IF_FOUND)
37428c506b8Sjruoho {
37528c506b8Sjruoho Status = AE_ALREADY_EXISTS;
37628c506b8Sjruoho }
377c72da027Schristos }
37828c506b8Sjruoho
37928c506b8Sjruoho #ifdef ACPI_ASL_COMPILER
38028c506b8Sjruoho if (*ReturnNode && (*ReturnNode)->Type == ACPI_TYPE_ANY)
38128c506b8Sjruoho {
38228c506b8Sjruoho (*ReturnNode)->Flags |= ANOBJ_IS_EXTERNAL;
38328c506b8Sjruoho }
38428c506b8Sjruoho #endif
38528c506b8Sjruoho
38628c506b8Sjruoho /* Either found it or there was an error: finished either way */
38728c506b8Sjruoho
38828c506b8Sjruoho return_ACPI_STATUS (Status);
38928c506b8Sjruoho }
39028c506b8Sjruoho
39128c506b8Sjruoho /*
39228c506b8Sjruoho * The name was not found. If we are NOT performing the first pass
39328c506b8Sjruoho * (name entry) of loading the namespace, search the parent tree (all the
39428c506b8Sjruoho * way to the root if necessary.) We don't want to perform the parent
39528c506b8Sjruoho * search when the namespace is actually being loaded. We want to perform
39628c506b8Sjruoho * the search when namespace references are being resolved (load pass 2)
39728c506b8Sjruoho * and during the execution phase.
39828c506b8Sjruoho */
39928c506b8Sjruoho if ((InterpreterMode != ACPI_IMODE_LOAD_PASS1) &&
40028c506b8Sjruoho (Flags & ACPI_NS_SEARCH_PARENT))
40128c506b8Sjruoho {
40228c506b8Sjruoho /*
40328c506b8Sjruoho * Not found at this level - search parent tree according to the
40428c506b8Sjruoho * ACPI specification
40528c506b8Sjruoho */
40628c506b8Sjruoho Status = AcpiNsSearchParentTree (TargetName, Node, Type, ReturnNode);
40728c506b8Sjruoho if (ACPI_SUCCESS (Status))
40828c506b8Sjruoho {
40928c506b8Sjruoho return_ACPI_STATUS (Status);
41028c506b8Sjruoho }
41128c506b8Sjruoho }
41228c506b8Sjruoho
41328c506b8Sjruoho /* In execute mode, just search, never add names. Exit now */
41428c506b8Sjruoho
41528c506b8Sjruoho if (InterpreterMode == ACPI_IMODE_EXECUTE)
41628c506b8Sjruoho {
41728c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
41828c506b8Sjruoho "%4.4s Not found in %p [Not adding]\n",
41928c506b8Sjruoho ACPI_CAST_PTR (char, &TargetName), Node));
42028c506b8Sjruoho
42128c506b8Sjruoho return_ACPI_STATUS (AE_NOT_FOUND);
42228c506b8Sjruoho }
42328c506b8Sjruoho
42428c506b8Sjruoho /* Create the new named object */
42528c506b8Sjruoho
42628c506b8Sjruoho NewNode = AcpiNsCreateNode (TargetName);
42728c506b8Sjruoho if (!NewNode)
42828c506b8Sjruoho {
42928c506b8Sjruoho return_ACPI_STATUS (AE_NO_MEMORY);
43028c506b8Sjruoho }
43128c506b8Sjruoho
43228c506b8Sjruoho #ifdef ACPI_ASL_COMPILER
43328c506b8Sjruoho
43428c506b8Sjruoho /* Node is an object defined by an External() statement */
43528c506b8Sjruoho
43628c506b8Sjruoho if (Flags & ACPI_NS_EXTERNAL ||
43728c506b8Sjruoho (WalkState && WalkState->Opcode == AML_SCOPE_OP))
43828c506b8Sjruoho {
43928c506b8Sjruoho NewNode->Flags |= ANOBJ_IS_EXTERNAL;
44028c506b8Sjruoho }
44128c506b8Sjruoho #endif
44228c506b8Sjruoho
44328c506b8Sjruoho if (Flags & ACPI_NS_TEMPORARY)
44428c506b8Sjruoho {
44528c506b8Sjruoho NewNode->Flags |= ANOBJ_TEMPORARY;
44628c506b8Sjruoho }
44728c506b8Sjruoho
44828c506b8Sjruoho /* Install the new object into the parent's list of children */
44928c506b8Sjruoho
45028c506b8Sjruoho AcpiNsInstallNode (WalkState, Node, NewNode, Type);
45128c506b8Sjruoho *ReturnNode = NewNode;
45228c506b8Sjruoho return_ACPI_STATUS (AE_OK);
45328c506b8Sjruoho }
454