xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/nssearch.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /*******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: nssearch - Namespace search
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  ******************************************************************************/
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <acpi/acpi.h>
9*4882a593Smuzhiyun #include "accommon.h"
10*4882a593Smuzhiyun #include "acnamesp.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #ifdef ACPI_ASL_COMPILER
13*4882a593Smuzhiyun #include "amlcode.h"
14*4882a593Smuzhiyun #endif
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define _COMPONENT          ACPI_NAMESPACE
17*4882a593Smuzhiyun ACPI_MODULE_NAME("nssearch")
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* Local prototypes */
20*4882a593Smuzhiyun static acpi_status
21*4882a593Smuzhiyun acpi_ns_search_parent_tree(u32 target_name,
22*4882a593Smuzhiyun 			   struct acpi_namespace_node *node,
23*4882a593Smuzhiyun 			   acpi_object_type type,
24*4882a593Smuzhiyun 			   struct acpi_namespace_node **return_node);
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /*******************************************************************************
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * FUNCTION:    acpi_ns_search_one_scope
29*4882a593Smuzhiyun  *
30*4882a593Smuzhiyun  * PARAMETERS:  target_name     - Ascii ACPI name to search for
31*4882a593Smuzhiyun  *              parent_node     - Starting node where search will begin
32*4882a593Smuzhiyun  *              type            - Object type to match
33*4882a593Smuzhiyun  *              return_node     - Where the matched Named obj is returned
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * RETURN:      Status
36*4882a593Smuzhiyun  *
37*4882a593Smuzhiyun  * DESCRIPTION: Search a single level of the namespace. Performs a
38*4882a593Smuzhiyun  *              simple search of the specified level, and does not add
39*4882a593Smuzhiyun  *              entries or search parents.
40*4882a593Smuzhiyun  *
41*4882a593Smuzhiyun  *
42*4882a593Smuzhiyun  *      Named object lists are built (and subsequently dumped) in the
43*4882a593Smuzhiyun  *      order in which the names are encountered during the namespace load;
44*4882a593Smuzhiyun  *
45*4882a593Smuzhiyun  *      All namespace searching is linear in this implementation, but
46*4882a593Smuzhiyun  *      could be easily modified to support any improved search
47*4882a593Smuzhiyun  *      algorithm. However, the linear search was chosen for simplicity
48*4882a593Smuzhiyun  *      and because the trees are small and the other interpreter
49*4882a593Smuzhiyun  *      execution overhead is relatively high.
50*4882a593Smuzhiyun  *
51*4882a593Smuzhiyun  *      Note: CPU execution analysis has shown that the AML interpreter spends
52*4882a593Smuzhiyun  *      a very small percentage of its time searching the namespace. Therefore,
53*4882a593Smuzhiyun  *      the linear search seems to be sufficient, as there would seem to be
54*4882a593Smuzhiyun  *      little value in improving the search.
55*4882a593Smuzhiyun  *
56*4882a593Smuzhiyun  ******************************************************************************/
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun acpi_status
acpi_ns_search_one_scope(u32 target_name,struct acpi_namespace_node * parent_node,acpi_object_type type,struct acpi_namespace_node ** return_node)59*4882a593Smuzhiyun acpi_ns_search_one_scope(u32 target_name,
60*4882a593Smuzhiyun 			 struct acpi_namespace_node *parent_node,
61*4882a593Smuzhiyun 			 acpi_object_type type,
62*4882a593Smuzhiyun 			 struct acpi_namespace_node **return_node)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ns_search_one_scope);
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #ifdef ACPI_DEBUG_OUTPUT
69*4882a593Smuzhiyun 	if (ACPI_LV_NAMES & acpi_dbg_level) {
70*4882a593Smuzhiyun 		char *scope_name;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 		scope_name = acpi_ns_get_normalized_pathname(parent_node, TRUE);
73*4882a593Smuzhiyun 		if (scope_name) {
74*4882a593Smuzhiyun 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
75*4882a593Smuzhiyun 					  "Searching %s (%p) For [%4.4s] (%s)\n",
76*4882a593Smuzhiyun 					  scope_name, parent_node,
77*4882a593Smuzhiyun 					  ACPI_CAST_PTR(char, &target_name),
78*4882a593Smuzhiyun 					  acpi_ut_get_type_name(type)));
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 			ACPI_FREE(scope_name);
81*4882a593Smuzhiyun 		}
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun #endif
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	/*
86*4882a593Smuzhiyun 	 * Search for name at this namespace level, which is to say that we
87*4882a593Smuzhiyun 	 * must search for the name among the children of this object
88*4882a593Smuzhiyun 	 */
89*4882a593Smuzhiyun 	node = parent_node->child;
90*4882a593Smuzhiyun 	while (node) {
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 		/* Check for match against the name */
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 		if (node->name.integer == target_name) {
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 			/* Resolve a control method alias if any */
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 			if (acpi_ns_get_type(node) ==
99*4882a593Smuzhiyun 			    ACPI_TYPE_LOCAL_METHOD_ALIAS) {
100*4882a593Smuzhiyun 				node =
101*4882a593Smuzhiyun 				    ACPI_CAST_PTR(struct acpi_namespace_node,
102*4882a593Smuzhiyun 						  node->object);
103*4882a593Smuzhiyun 			}
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 			/* Found matching entry */
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
108*4882a593Smuzhiyun 					  "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
109*4882a593Smuzhiyun 					  ACPI_CAST_PTR(char, &target_name),
110*4882a593Smuzhiyun 					  acpi_ut_get_type_name(node->type),
111*4882a593Smuzhiyun 					  node,
112*4882a593Smuzhiyun 					  acpi_ut_get_node_name(parent_node),
113*4882a593Smuzhiyun 					  parent_node));
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 			*return_node = node;
116*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_OK);
117*4882a593Smuzhiyun 		}
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 		/* Didn't match name, move on to the next peer object */
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 		node = node->peer;
122*4882a593Smuzhiyun 	}
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	/* Searched entire namespace level, not found */
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
127*4882a593Smuzhiyun 			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
128*4882a593Smuzhiyun 			  "%p first child %p\n",
129*4882a593Smuzhiyun 			  ACPI_CAST_PTR(char, &target_name),
130*4882a593Smuzhiyun 			  acpi_ut_get_type_name(type),
131*4882a593Smuzhiyun 			  acpi_ut_get_node_name(parent_node), parent_node,
132*4882a593Smuzhiyun 			  parent_node->child));
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_NOT_FOUND);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /*******************************************************************************
138*4882a593Smuzhiyun  *
139*4882a593Smuzhiyun  * FUNCTION:    acpi_ns_search_parent_tree
140*4882a593Smuzhiyun  *
141*4882a593Smuzhiyun  * PARAMETERS:  target_name     - Ascii ACPI name to search for
142*4882a593Smuzhiyun  *              node            - Starting node where search will begin
143*4882a593Smuzhiyun  *              type            - Object type to match
144*4882a593Smuzhiyun  *              return_node     - Where the matched Node is returned
145*4882a593Smuzhiyun  *
146*4882a593Smuzhiyun  * RETURN:      Status
147*4882a593Smuzhiyun  *
148*4882a593Smuzhiyun  * DESCRIPTION: Called when a name has not been found in the current namespace
149*4882a593Smuzhiyun  *              level. Before adding it or giving up, ACPI scope rules require
150*4882a593Smuzhiyun  *              searching enclosing scopes in cases identified by acpi_ns_local().
151*4882a593Smuzhiyun  *
152*4882a593Smuzhiyun  *              "A name is located by finding the matching name in the current
153*4882a593Smuzhiyun  *              name space, and then in the parent name space. If the parent
154*4882a593Smuzhiyun  *              name space does not contain the name, the search continues
155*4882a593Smuzhiyun  *              recursively until either the name is found or the name space
156*4882a593Smuzhiyun  *              does not have a parent (the root of the name space). This
157*4882a593Smuzhiyun  *              indicates that the name is not found" (From ACPI Specification,
158*4882a593Smuzhiyun  *              section 5.3)
159*4882a593Smuzhiyun  *
160*4882a593Smuzhiyun  ******************************************************************************/
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun static acpi_status
acpi_ns_search_parent_tree(u32 target_name,struct acpi_namespace_node * node,acpi_object_type type,struct acpi_namespace_node ** return_node)163*4882a593Smuzhiyun acpi_ns_search_parent_tree(u32 target_name,
164*4882a593Smuzhiyun 			   struct acpi_namespace_node *node,
165*4882a593Smuzhiyun 			   acpi_object_type type,
166*4882a593Smuzhiyun 			   struct acpi_namespace_node **return_node)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	acpi_status status;
169*4882a593Smuzhiyun 	struct acpi_namespace_node *parent_node;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ns_search_parent_tree);
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	parent_node = node->parent;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	/*
176*4882a593Smuzhiyun 	 * If there is no parent (i.e., we are at the root) or type is "local",
177*4882a593Smuzhiyun 	 * we won't be searching the parent tree.
178*4882a593Smuzhiyun 	 */
179*4882a593Smuzhiyun 	if (!parent_node) {
180*4882a593Smuzhiyun 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
181*4882a593Smuzhiyun 				  ACPI_CAST_PTR(char, &target_name)));
182*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NOT_FOUND);
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if (acpi_ns_local(type)) {
186*4882a593Smuzhiyun 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
187*4882a593Smuzhiyun 				  "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
188*4882a593Smuzhiyun 				  ACPI_CAST_PTR(char, &target_name),
189*4882a593Smuzhiyun 				  acpi_ut_get_type_name(type)));
190*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NOT_FOUND);
191*4882a593Smuzhiyun 	}
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/* Search the parent tree */
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
196*4882a593Smuzhiyun 			  "Searching parent [%4.4s] for [%4.4s]\n",
197*4882a593Smuzhiyun 			  acpi_ut_get_node_name(parent_node),
198*4882a593Smuzhiyun 			  ACPI_CAST_PTR(char, &target_name)));
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	/* Search parents until target is found or we have backed up to the root */
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	while (parent_node) {
203*4882a593Smuzhiyun 		/*
204*4882a593Smuzhiyun 		 * Search parent scope. Use TYPE_ANY because we don't care about the
205*4882a593Smuzhiyun 		 * object type at this point, we only care about the existence of
206*4882a593Smuzhiyun 		 * the actual name we are searching for. Typechecking comes later.
207*4882a593Smuzhiyun 		 */
208*4882a593Smuzhiyun 		status =
209*4882a593Smuzhiyun 		    acpi_ns_search_one_scope(target_name, parent_node,
210*4882a593Smuzhiyun 					     ACPI_TYPE_ANY, return_node);
211*4882a593Smuzhiyun 		if (ACPI_SUCCESS(status)) {
212*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
213*4882a593Smuzhiyun 		}
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 		/* Not found here, go up another level (until we reach the root) */
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 		parent_node = parent_node->parent;
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	/* Not found in parent tree */
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_NOT_FOUND);
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun /*******************************************************************************
226*4882a593Smuzhiyun  *
227*4882a593Smuzhiyun  * FUNCTION:    acpi_ns_search_and_enter
228*4882a593Smuzhiyun  *
229*4882a593Smuzhiyun  * PARAMETERS:  target_name         - Ascii ACPI name to search for (4 chars)
230*4882a593Smuzhiyun  *              walk_state          - Current state of the walk
231*4882a593Smuzhiyun  *              node                - Starting node where search will begin
232*4882a593Smuzhiyun  *              interpreter_mode    - Add names only in ACPI_MODE_LOAD_PASS_x.
233*4882a593Smuzhiyun  *                                    Otherwise,search only.
234*4882a593Smuzhiyun  *              type                - Object type to match
235*4882a593Smuzhiyun  *              flags               - Flags describing the search restrictions
236*4882a593Smuzhiyun  *              return_node         - Where the Node is returned
237*4882a593Smuzhiyun  *
238*4882a593Smuzhiyun  * RETURN:      Status
239*4882a593Smuzhiyun  *
240*4882a593Smuzhiyun  * DESCRIPTION: Search for a name segment in a single namespace level,
241*4882a593Smuzhiyun  *              optionally adding it if it is not found. If the passed
242*4882a593Smuzhiyun  *              Type is not Any and the type previously stored in the
243*4882a593Smuzhiyun  *              entry was Any (i.e. unknown), update the stored type.
244*4882a593Smuzhiyun  *
245*4882a593Smuzhiyun  *              In ACPI_IMODE_EXECUTE, search only.
246*4882a593Smuzhiyun  *              In other modes, search and add if not found.
247*4882a593Smuzhiyun  *
248*4882a593Smuzhiyun  ******************************************************************************/
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun acpi_status
acpi_ns_search_and_enter(u32 target_name,struct acpi_walk_state * walk_state,struct acpi_namespace_node * node,acpi_interpreter_mode interpreter_mode,acpi_object_type type,u32 flags,struct acpi_namespace_node ** return_node)251*4882a593Smuzhiyun acpi_ns_search_and_enter(u32 target_name,
252*4882a593Smuzhiyun 			 struct acpi_walk_state *walk_state,
253*4882a593Smuzhiyun 			 struct acpi_namespace_node *node,
254*4882a593Smuzhiyun 			 acpi_interpreter_mode interpreter_mode,
255*4882a593Smuzhiyun 			 acpi_object_type type,
256*4882a593Smuzhiyun 			 u32 flags, struct acpi_namespace_node **return_node)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	acpi_status status;
259*4882a593Smuzhiyun 	struct acpi_namespace_node *new_node;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ns_search_and_enter);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	/* Parameter validation */
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	if (!node || !target_name || !return_node) {
266*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
267*4882a593Smuzhiyun 			    "Null parameter: Node %p Name 0x%X ReturnNode %p",
268*4882a593Smuzhiyun 			    node, target_name, return_node));
269*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_BAD_PARAMETER);
270*4882a593Smuzhiyun 	}
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	/*
273*4882a593Smuzhiyun 	 * Name must consist of valid ACPI characters. We will repair the name if
274*4882a593Smuzhiyun 	 * necessary because we don't want to abort because of this, but we want
275*4882a593Smuzhiyun 	 * all namespace names to be printable. A warning message is appropriate.
276*4882a593Smuzhiyun 	 *
277*4882a593Smuzhiyun 	 * This issue came up because there are in fact machines that exhibit
278*4882a593Smuzhiyun 	 * this problem, and we want to be able to enable ACPI support for them,
279*4882a593Smuzhiyun 	 * even though there are a few bad names.
280*4882a593Smuzhiyun 	 */
281*4882a593Smuzhiyun 	acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name));
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	/* Try to find the name in the namespace level specified by the caller */
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	*return_node = ACPI_ENTRY_NOT_FOUND;
286*4882a593Smuzhiyun 	status = acpi_ns_search_one_scope(target_name, node, type, return_node);
287*4882a593Smuzhiyun 	if (status != AE_NOT_FOUND) {
288*4882a593Smuzhiyun 		/*
289*4882a593Smuzhiyun 		 * If we found it AND the request specifies that a find is an error,
290*4882a593Smuzhiyun 		 * return the error
291*4882a593Smuzhiyun 		 */
292*4882a593Smuzhiyun 		if (status == AE_OK) {
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 			/* The node was found in the namespace */
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 			/*
297*4882a593Smuzhiyun 			 * If the namespace override feature is enabled for this node,
298*4882a593Smuzhiyun 			 * delete any existing attached sub-object and make the node
299*4882a593Smuzhiyun 			 * look like a new node that is owned by the override table.
300*4882a593Smuzhiyun 			 */
301*4882a593Smuzhiyun 			if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
302*4882a593Smuzhiyun 				ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
303*4882a593Smuzhiyun 						  "Namespace override: %4.4s pass %u type %X Owner %X\n",
304*4882a593Smuzhiyun 						  ACPI_CAST_PTR(char,
305*4882a593Smuzhiyun 								&target_name),
306*4882a593Smuzhiyun 						  interpreter_mode,
307*4882a593Smuzhiyun 						  (*return_node)->type,
308*4882a593Smuzhiyun 						  walk_state->owner_id));
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 				acpi_ns_delete_children(*return_node);
311*4882a593Smuzhiyun 				if (acpi_gbl_runtime_namespace_override) {
312*4882a593Smuzhiyun 					acpi_ut_remove_reference((*return_node)->object);
313*4882a593Smuzhiyun 					(*return_node)->object = NULL;
314*4882a593Smuzhiyun 					(*return_node)->owner_id =
315*4882a593Smuzhiyun 					    walk_state->owner_id;
316*4882a593Smuzhiyun 				} else {
317*4882a593Smuzhiyun 					acpi_ns_remove_node(*return_node);
318*4882a593Smuzhiyun 					*return_node = ACPI_ENTRY_NOT_FOUND;
319*4882a593Smuzhiyun 				}
320*4882a593Smuzhiyun 			}
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 			/* Return an error if we don't expect to find the object */
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 			else if (flags & ACPI_NS_ERROR_IF_FOUND) {
325*4882a593Smuzhiyun 				status = AE_ALREADY_EXISTS;
326*4882a593Smuzhiyun 			}
327*4882a593Smuzhiyun 		}
328*4882a593Smuzhiyun #ifdef ACPI_ASL_COMPILER
329*4882a593Smuzhiyun 		if (*return_node && (*return_node)->type == ACPI_TYPE_ANY) {
330*4882a593Smuzhiyun 			(*return_node)->flags |= ANOBJ_IS_EXTERNAL;
331*4882a593Smuzhiyun 		}
332*4882a593Smuzhiyun #endif
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 		/* Either found it or there was an error: finished either way */
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	/*
340*4882a593Smuzhiyun 	 * The name was not found. If we are NOT performing the first pass
341*4882a593Smuzhiyun 	 * (name entry) of loading the namespace, search the parent tree (all the
342*4882a593Smuzhiyun 	 * way to the root if necessary.) We don't want to perform the parent
343*4882a593Smuzhiyun 	 * search when the namespace is actually being loaded. We want to perform
344*4882a593Smuzhiyun 	 * the search when namespace references are being resolved (load pass 2)
345*4882a593Smuzhiyun 	 * and during the execution phase.
346*4882a593Smuzhiyun 	 */
347*4882a593Smuzhiyun 	if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) &&
348*4882a593Smuzhiyun 	    (flags & ACPI_NS_SEARCH_PARENT)) {
349*4882a593Smuzhiyun 		/*
350*4882a593Smuzhiyun 		 * Not found at this level - search parent tree according to the
351*4882a593Smuzhiyun 		 * ACPI specification
352*4882a593Smuzhiyun 		 */
353*4882a593Smuzhiyun 		status =
354*4882a593Smuzhiyun 		    acpi_ns_search_parent_tree(target_name, node, type,
355*4882a593Smuzhiyun 					       return_node);
356*4882a593Smuzhiyun 		if (ACPI_SUCCESS(status)) {
357*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
358*4882a593Smuzhiyun 		}
359*4882a593Smuzhiyun 	}
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	/* In execute mode, just search, never add names. Exit now */
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	if (interpreter_mode == ACPI_IMODE_EXECUTE) {
364*4882a593Smuzhiyun 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
365*4882a593Smuzhiyun 				  "%4.4s Not found in %p [Not adding]\n",
366*4882a593Smuzhiyun 				  ACPI_CAST_PTR(char, &target_name), node));
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NOT_FOUND);
369*4882a593Smuzhiyun 	}
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	/* Create the new named object */
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	new_node = acpi_ns_create_node(target_name);
374*4882a593Smuzhiyun 	if (!new_node) {
375*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NO_MEMORY);
376*4882a593Smuzhiyun 	}
377*4882a593Smuzhiyun #ifdef ACPI_ASL_COMPILER
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	/* Node is an object defined by an External() statement */
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	if (flags & ACPI_NS_EXTERNAL ||
382*4882a593Smuzhiyun 	    (walk_state && walk_state->opcode == AML_SCOPE_OP)) {
383*4882a593Smuzhiyun 		new_node->flags |= ANOBJ_IS_EXTERNAL;
384*4882a593Smuzhiyun 	}
385*4882a593Smuzhiyun #endif
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	if (flags & ACPI_NS_TEMPORARY) {
388*4882a593Smuzhiyun 		new_node->flags |= ANOBJ_TEMPORARY;
389*4882a593Smuzhiyun 	}
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	/* Install the new object into the parent's list of children */
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	acpi_ns_install_node(walk_state, node, new_node, type);
394*4882a593Smuzhiyun 	*return_node = new_node;
395*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_OK);
396*4882a593Smuzhiyun }
397