nsaccess.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /*******************************************************************************
  3. *
  4. * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
  5. *
  6. ******************************************************************************/
  7. #include <acpi/acpi.h>
  8. #include "accommon.h"
  9. #include "amlcode.h"
  10. #include "acnamesp.h"
  11. #include "acdispat.h"
  12. #ifdef ACPI_ASL_COMPILER
  13. #include "acdisasm.h"
  14. #endif
  15. #define _COMPONENT ACPI_NAMESPACE
  16. ACPI_MODULE_NAME("nsaccess")
  17. /*******************************************************************************
  18. *
  19. * FUNCTION: acpi_ns_root_initialize
  20. *
  21. * PARAMETERS: None
  22. *
  23. * RETURN: Status
  24. *
  25. * DESCRIPTION: Allocate and initialize the default root named objects
  26. *
  27. * MUTEX: Locks namespace for entire execution
  28. *
  29. ******************************************************************************/
  30. acpi_status acpi_ns_root_initialize(void)
  31. {
  32. acpi_status status;
  33. const struct acpi_predefined_names *init_val = NULL;
  34. struct acpi_namespace_node *new_node;
  35. union acpi_operand_object *obj_desc;
  36. acpi_string val = NULL;
  37. ACPI_FUNCTION_TRACE(ns_root_initialize);
  38. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  39. if (ACPI_FAILURE(status)) {
  40. return_ACPI_STATUS(status);
  41. }
  42. /*
  43. * The global root ptr is initially NULL, so a non-NULL value indicates
  44. * that acpi_ns_root_initialize() has already been called; just return.
  45. */
  46. if (acpi_gbl_root_node) {
  47. status = AE_OK;
  48. goto unlock_and_exit;
  49. }
  50. /*
  51. * Tell the rest of the subsystem that the root is initialized
  52. * (This is OK because the namespace is locked)
  53. */
  54. acpi_gbl_root_node = &acpi_gbl_root_node_struct;
  55. /* Enter the pre-defined names in the name table */
  56. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  57. "Entering predefined entries into namespace\n"));
  58. for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
  59. /* _OSI is optional for now, will be permanent later */
  60. if (!strcmp(init_val->name, "_OSI")
  61. && !acpi_gbl_create_osi_method) {
  62. continue;
  63. }
  64. status =
  65. acpi_ns_lookup(NULL, ACPI_CAST_PTR(char, init_val->name),
  66. init_val->type, ACPI_IMODE_LOAD_PASS2,
  67. ACPI_NS_NO_UPSEARCH, NULL, &new_node);
  68. if (ACPI_FAILURE(status)) {
  69. ACPI_EXCEPTION((AE_INFO, status,
  70. "Could not create predefined name %s",
  71. init_val->name));
  72. continue;
  73. }
  74. /*
  75. * Name entered successfully. If entry in pre_defined_names[] specifies
  76. * an initial value, create the initial value.
  77. */
  78. if (init_val->val) {
  79. status = acpi_os_predefined_override(init_val, &val);
  80. if (ACPI_FAILURE(status)) {
  81. ACPI_ERROR((AE_INFO,
  82. "Could not override predefined %s",
  83. init_val->name));
  84. }
  85. if (!val) {
  86. val = init_val->val;
  87. }
  88. /*
  89. * Entry requests an initial value, allocate a
  90. * descriptor for it.
  91. */
  92. obj_desc =
  93. acpi_ut_create_internal_object(init_val->type);
  94. if (!obj_desc) {
  95. status = AE_NO_MEMORY;
  96. goto unlock_and_exit;
  97. }
  98. /*
  99. * Convert value string from table entry to
  100. * internal representation. Only types actually
  101. * used for initial values are implemented here.
  102. */
  103. switch (init_val->type) {
  104. case ACPI_TYPE_METHOD:
  105. obj_desc->method.param_count =
  106. (u8) ACPI_TO_INTEGER(val);
  107. obj_desc->common.flags |= AOPOBJ_DATA_VALID;
  108. #if defined (ACPI_ASL_COMPILER)
  109. /* Save the parameter count for the iASL compiler */
  110. new_node->value = obj_desc->method.param_count;
  111. #else
  112. /* Mark this as a very SPECIAL method */
  113. obj_desc->method.info_flags =
  114. ACPI_METHOD_INTERNAL_ONLY;
  115. obj_desc->method.dispatch.implementation =
  116. acpi_ut_osi_implementation;
  117. #endif
  118. break;
  119. case ACPI_TYPE_INTEGER:
  120. obj_desc->integer.value = ACPI_TO_INTEGER(val);
  121. break;
  122. case ACPI_TYPE_STRING:
  123. /* Build an object around the static string */
  124. obj_desc->string.length = (u32)strlen(val);
  125. obj_desc->string.pointer = val;
  126. obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
  127. break;
  128. case ACPI_TYPE_MUTEX:
  129. obj_desc->mutex.node = new_node;
  130. obj_desc->mutex.sync_level =
  131. (u8) (ACPI_TO_INTEGER(val) - 1);
  132. /* Create a mutex */
  133. status =
  134. acpi_os_create_mutex(&obj_desc->mutex.
  135. os_mutex);
  136. if (ACPI_FAILURE(status)) {
  137. acpi_ut_remove_reference(obj_desc);
  138. goto unlock_and_exit;
  139. }
  140. /* Special case for ACPI Global Lock */
  141. if (strcmp(init_val->name, "_GL_") == 0) {
  142. acpi_gbl_global_lock_mutex = obj_desc;
  143. /* Create additional counting semaphore for global lock */
  144. status =
  145. acpi_os_create_semaphore(1, 0,
  146. &acpi_gbl_global_lock_semaphore);
  147. if (ACPI_FAILURE(status)) {
  148. acpi_ut_remove_reference
  149. (obj_desc);
  150. goto unlock_and_exit;
  151. }
  152. }
  153. break;
  154. default:
  155. ACPI_ERROR((AE_INFO,
  156. "Unsupported initial type value 0x%X",
  157. init_val->type));
  158. acpi_ut_remove_reference(obj_desc);
  159. obj_desc = NULL;
  160. continue;
  161. }
  162. /* Store pointer to value descriptor in the Node */
  163. status = acpi_ns_attach_object(new_node, obj_desc,
  164. obj_desc->common.type);
  165. /* Remove local reference to the object */
  166. acpi_ut_remove_reference(obj_desc);
  167. }
  168. }
  169. unlock_and_exit:
  170. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  171. /* Save a handle to "_GPE", it is always present */
  172. if (ACPI_SUCCESS(status)) {
  173. status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
  174. &acpi_gbl_fadt_gpe_device);
  175. }
  176. return_ACPI_STATUS(status);
  177. }
  178. /*******************************************************************************
  179. *
  180. * FUNCTION: acpi_ns_lookup
  181. *
  182. * PARAMETERS: scope_info - Current scope info block
  183. * pathname - Search pathname, in internal format
  184. * (as represented in the AML stream)
  185. * type - Type associated with name
  186. * interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
  187. * flags - Flags describing the search restrictions
  188. * walk_state - Current state of the walk
  189. * return_node - Where the Node is placed (if found
  190. * or created successfully)
  191. *
  192. * RETURN: Status
  193. *
  194. * DESCRIPTION: Find or enter the passed name in the name space.
  195. * Log an error if name not found in Exec mode.
  196. *
  197. * MUTEX: Assumes namespace is locked.
  198. *
  199. ******************************************************************************/
  200. acpi_status
  201. acpi_ns_lookup(union acpi_generic_state *scope_info,
  202. char *pathname,
  203. acpi_object_type type,
  204. acpi_interpreter_mode interpreter_mode,
  205. u32 flags,
  206. struct acpi_walk_state *walk_state,
  207. struct acpi_namespace_node **return_node)
  208. {
  209. acpi_status status;
  210. char *path = pathname;
  211. char *external_path;
  212. struct acpi_namespace_node *prefix_node;
  213. struct acpi_namespace_node *current_node = NULL;
  214. struct acpi_namespace_node *this_node = NULL;
  215. u32 num_segments;
  216. u32 num_carats;
  217. acpi_name simple_name;
  218. acpi_object_type type_to_check_for;
  219. acpi_object_type this_search_type;
  220. u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
  221. u32 local_flags;
  222. ACPI_FUNCTION_TRACE(ns_lookup);
  223. if (!return_node) {
  224. return_ACPI_STATUS(AE_BAD_PARAMETER);
  225. }
  226. local_flags = flags &
  227. ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
  228. ACPI_NS_SEARCH_PARENT);
  229. *return_node = ACPI_ENTRY_NOT_FOUND;
  230. acpi_gbl_ns_lookup_count++;
  231. if (!acpi_gbl_root_node) {
  232. return_ACPI_STATUS(AE_NO_NAMESPACE);
  233. }
  234. /* Get the prefix scope. A null scope means use the root scope */
  235. if ((!scope_info) || (!scope_info->scope.node)) {
  236. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  237. "Null scope prefix, using root node (%p)\n",
  238. acpi_gbl_root_node));
  239. prefix_node = acpi_gbl_root_node;
  240. } else {
  241. prefix_node = scope_info->scope.node;
  242. if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
  243. ACPI_DESC_TYPE_NAMED) {
  244. ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
  245. prefix_node,
  246. acpi_ut_get_descriptor_name(prefix_node)));
  247. return_ACPI_STATUS(AE_AML_INTERNAL);
  248. }
  249. if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
  250. /*
  251. * This node might not be a actual "scope" node (such as a
  252. * Device/Method, etc.) It could be a Package or other object
  253. * node. Backup up the tree to find the containing scope node.
  254. */
  255. while (!acpi_ns_opens_scope(prefix_node->type) &&
  256. prefix_node->type != ACPI_TYPE_ANY) {
  257. prefix_node = prefix_node->parent;
  258. }
  259. }
  260. }
  261. /* Save type. TBD: may be no longer necessary */
  262. type_to_check_for = type;
  263. /*
  264. * Begin examination of the actual pathname
  265. */
  266. if (!pathname) {
  267. /* A Null name_path is allowed and refers to the root */
  268. num_segments = 0;
  269. this_node = acpi_gbl_root_node;
  270. path = "";
  271. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  272. "Null Pathname (Zero segments), Flags=%X\n",
  273. flags));
  274. } else {
  275. /*
  276. * Name pointer is valid (and must be in internal name format)
  277. *
  278. * Check for scope prefixes:
  279. *
  280. * As represented in the AML stream, a namepath consists of an
  281. * optional scope prefix followed by a name segment part.
  282. *
  283. * If present, the scope prefix is either a Root Prefix (in
  284. * which case the name is fully qualified), or one or more
  285. * Parent Prefixes (in which case the name's scope is relative
  286. * to the current scope).
  287. */
  288. if (*path == (u8) AML_ROOT_PREFIX) {
  289. /* Pathname is fully qualified, start from the root */
  290. this_node = acpi_gbl_root_node;
  291. search_parent_flag = ACPI_NS_NO_UPSEARCH;
  292. /* Point to name segment part */
  293. path++;
  294. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  295. "Path is absolute from root [%p]\n",
  296. this_node));
  297. } else {
  298. /* Pathname is relative to current scope, start there */
  299. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  300. "Searching relative to prefix scope [%4.4s] (%p)\n",
  301. acpi_ut_get_node_name(prefix_node),
  302. prefix_node));
  303. /*
  304. * Handle multiple Parent Prefixes (carat) by just getting
  305. * the parent node for each prefix instance.
  306. */
  307. this_node = prefix_node;
  308. num_carats = 0;
  309. while (*path == (u8) AML_PARENT_PREFIX) {
  310. /* Name is fully qualified, no search rules apply */
  311. search_parent_flag = ACPI_NS_NO_UPSEARCH;
  312. /*
  313. * Point past this prefix to the name segment
  314. * part or the next Parent Prefix
  315. */
  316. path++;
  317. /* Backup to the parent node */
  318. num_carats++;
  319. this_node = this_node->parent;
  320. if (!this_node) {
  321. /*
  322. * Current scope has no parent scope. Externalize
  323. * the internal path for error message.
  324. */
  325. status =
  326. acpi_ns_externalize_name
  327. (ACPI_UINT32_MAX, pathname, NULL,
  328. &external_path);
  329. if (ACPI_SUCCESS(status)) {
  330. ACPI_ERROR((AE_INFO,
  331. "%s: Path has too many parent prefixes (^)",
  332. external_path));
  333. ACPI_FREE(external_path);
  334. }
  335. return_ACPI_STATUS(AE_NOT_FOUND);
  336. }
  337. }
  338. if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
  339. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  340. "Search scope is [%4.4s], path has %u carat(s)\n",
  341. acpi_ut_get_node_name
  342. (this_node), num_carats));
  343. }
  344. }
  345. /*
  346. * Determine the number of ACPI name segments in this pathname.
  347. *
  348. * The segment part consists of either:
  349. * - A Null name segment (0)
  350. * - A dual_name_prefix followed by two 4-byte name segments
  351. * - A multi_name_prefix followed by a byte indicating the
  352. * number of segments and the segments themselves.
  353. * - A single 4-byte name segment
  354. *
  355. * Examine the name prefix opcode, if any, to determine the number of
  356. * segments.
  357. */
  358. switch (*path) {
  359. case 0:
  360. /*
  361. * Null name after a root or parent prefixes. We already
  362. * have the correct target node and there are no name segments.
  363. */
  364. num_segments = 0;
  365. type = this_node->type;
  366. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  367. "Prefix-only Pathname (Zero name segments), Flags=%X\n",
  368. flags));
  369. break;
  370. case AML_DUAL_NAME_PREFIX:
  371. /* More than one name_seg, search rules do not apply */
  372. search_parent_flag = ACPI_NS_NO_UPSEARCH;
  373. /* Two segments, point to first name segment */
  374. num_segments = 2;
  375. path++;
  376. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  377. "Dual Pathname (2 segments, Flags=%X)\n",
  378. flags));
  379. break;
  380. case AML_MULTI_NAME_PREFIX:
  381. /* More than one name_seg, search rules do not apply */
  382. search_parent_flag = ACPI_NS_NO_UPSEARCH;
  383. /* Extract segment count, point to first name segment */
  384. path++;
  385. num_segments = (u32) (u8) * path;
  386. path++;
  387. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  388. "Multi Pathname (%u Segments, Flags=%X)\n",
  389. num_segments, flags));
  390. break;
  391. default:
  392. /*
  393. * Not a Null name, no Dual or Multi prefix, hence there is
  394. * only one name segment and Pathname is already pointing to it.
  395. */
  396. num_segments = 1;
  397. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  398. "Simple Pathname (1 segment, Flags=%X)\n",
  399. flags));
  400. break;
  401. }
  402. ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
  403. }
  404. /*
  405. * Search namespace for each segment of the name. Loop through and
  406. * verify (or add to the namespace) each name segment.
  407. *
  408. * The object type is significant only at the last name
  409. * segment. (We don't care about the types along the path, only
  410. * the type of the final target object.)
  411. */
  412. this_search_type = ACPI_TYPE_ANY;
  413. current_node = this_node;
  414. while (num_segments && current_node) {
  415. num_segments--;
  416. if (!num_segments) {
  417. /* This is the last segment, enable typechecking */
  418. this_search_type = type;
  419. /*
  420. * Only allow automatic parent search (search rules) if the caller
  421. * requested it AND we have a single, non-fully-qualified name_seg
  422. */
  423. if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
  424. (flags & ACPI_NS_SEARCH_PARENT)) {
  425. local_flags |= ACPI_NS_SEARCH_PARENT;
  426. }
  427. /* Set error flag according to caller */
  428. if (flags & ACPI_NS_ERROR_IF_FOUND) {
  429. local_flags |= ACPI_NS_ERROR_IF_FOUND;
  430. }
  431. /* Set override flag according to caller */
  432. if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
  433. local_flags |= ACPI_NS_OVERRIDE_IF_FOUND;
  434. }
  435. }
  436. /* Extract one ACPI name from the front of the pathname */
  437. ACPI_MOVE_32_TO_32(&simple_name, path);
  438. /* Try to find the single (4 character) ACPI name */
  439. status =
  440. acpi_ns_search_and_enter(simple_name, walk_state,
  441. current_node, interpreter_mode,
  442. this_search_type, local_flags,
  443. &this_node);
  444. if (ACPI_FAILURE(status)) {
  445. if (status == AE_NOT_FOUND) {
  446. /* Name not found in ACPI namespace */
  447. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  448. "Name [%4.4s] not found in scope [%4.4s] %p\n",
  449. (char *)&simple_name,
  450. (char *)&current_node->name,
  451. current_node));
  452. }
  453. #ifdef ACPI_EXEC_APP
  454. if ((status == AE_ALREADY_EXISTS) &&
  455. (this_node->flags & ANOBJ_NODE_EARLY_INIT)) {
  456. this_node->flags &= ~ANOBJ_NODE_EARLY_INIT;
  457. status = AE_OK;
  458. }
  459. #endif
  460. #ifdef ACPI_ASL_COMPILER
  461. /*
  462. * If this ACPI name already exists within the namespace as an
  463. * external declaration, then mark the external as a conflicting
  464. * declaration and proceed to process the current node as if it did
  465. * not exist in the namespace. If this node is not processed as
  466. * normal, then it could cause improper namespace resolution
  467. * by failing to open a new scope.
  468. */
  469. if (acpi_gbl_disasm_flag &&
  470. (status == AE_ALREADY_EXISTS) &&
  471. ((this_node->flags & ANOBJ_IS_EXTERNAL) ||
  472. (walk_state
  473. && walk_state->opcode == AML_EXTERNAL_OP))) {
  474. this_node->flags &= ~ANOBJ_IS_EXTERNAL;
  475. this_node->type = (u8)this_search_type;
  476. if (walk_state->opcode != AML_EXTERNAL_OP) {
  477. acpi_dm_mark_external_conflict
  478. (this_node);
  479. }
  480. break;
  481. }
  482. #endif
  483. *return_node = this_node;
  484. return_ACPI_STATUS(status);
  485. }
  486. /* More segments to follow? */
  487. if (num_segments > 0) {
  488. /*
  489. * If we have an alias to an object that opens a scope (such as a
  490. * device or processor), we need to dereference the alias here so
  491. * that we can access any children of the original node (via the
  492. * remaining segments).
  493. */
  494. if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
  495. if (!this_node->object) {
  496. return_ACPI_STATUS(AE_NOT_EXIST);
  497. }
  498. if (acpi_ns_opens_scope
  499. (((struct acpi_namespace_node *)
  500. this_node->object)->type)) {
  501. this_node =
  502. (struct acpi_namespace_node *)
  503. this_node->object;
  504. }
  505. }
  506. }
  507. /* Special handling for the last segment (num_segments == 0) */
  508. else {
  509. /*
  510. * Sanity typecheck of the target object:
  511. *
  512. * If 1) This is the last segment (num_segments == 0)
  513. * 2) And we are looking for a specific type
  514. * (Not checking for TYPE_ANY)
  515. * 3) Which is not an alias
  516. * 4) Which is not a local type (TYPE_SCOPE)
  517. * 5) And the type of target object is known (not TYPE_ANY)
  518. * 6) And target object does not match what we are looking for
  519. *
  520. * Then we have a type mismatch. Just warn and ignore it.
  521. */
  522. if ((type_to_check_for != ACPI_TYPE_ANY) &&
  523. (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
  524. (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
  525. && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
  526. && (this_node->type != ACPI_TYPE_ANY)
  527. && (this_node->type != type_to_check_for)) {
  528. /* Complain about a type mismatch */
  529. ACPI_WARNING((AE_INFO,
  530. "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
  531. ACPI_CAST_PTR(char, &simple_name),
  532. acpi_ut_get_type_name(this_node->
  533. type),
  534. acpi_ut_get_type_name
  535. (type_to_check_for)));
  536. }
  537. /*
  538. * If this is the last name segment and we are not looking for a
  539. * specific type, but the type of found object is known, use that
  540. * type to (later) see if it opens a scope.
  541. */
  542. if (type == ACPI_TYPE_ANY) {
  543. type = this_node->type;
  544. }
  545. }
  546. /* Point to next name segment and make this node current */
  547. path += ACPI_NAME_SIZE;
  548. current_node = this_node;
  549. }
  550. /* Always check if we need to open a new scope */
  551. if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
  552. /*
  553. * If entry is a type which opens a scope, push the new scope on the
  554. * scope stack.
  555. */
  556. if (acpi_ns_opens_scope(type)) {
  557. status =
  558. acpi_ds_scope_stack_push(this_node, type,
  559. walk_state);
  560. if (ACPI_FAILURE(status)) {
  561. return_ACPI_STATUS(status);
  562. }
  563. }
  564. }
  565. #ifdef ACPI_EXEC_APP
  566. if (flags & ACPI_NS_EARLY_INIT) {
  567. this_node->flags |= ANOBJ_NODE_EARLY_INIT;
  568. }
  569. #endif
  570. *return_node = this_node;
  571. return_ACPI_STATUS(AE_OK);
  572. }