nsutils.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:23k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
  4.  *                        parents and siblings and Scope manipulation
  5.  *              $Revision: 92 $
  6.  *
  7.  *****************************************************************************/
  8. /*
  9.  *  Copyright (C) 2000, 2001 R. Byron Moore
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25. #include "acpi.h"
  26. #include "acnamesp.h"
  27. #include "acinterp.h"
  28. #include "amlcode.h"
  29. #include "actables.h"
  30. #define _COMPONENT          ACPI_NAMESPACE
  31.  MODULE_NAME         ("nsutils")
  32. /*******************************************************************************
  33.  *
  34.  * FUNCTION:    Acpi_ns_valid_root_prefix
  35.  *
  36.  * PARAMETERS:  Prefix          - Character to be checked
  37.  *
  38.  * RETURN:      TRUE if a valid prefix
  39.  *
  40.  * DESCRIPTION: Check if a character is a valid ACPI Root prefix
  41.  *
  42.  ******************************************************************************/
  43. u8
  44. acpi_ns_valid_root_prefix (
  45. NATIVE_CHAR             prefix)
  46. {
  47. return ((u8) (prefix == '\'));
  48. }
  49. /*******************************************************************************
  50.  *
  51.  * FUNCTION:    Acpi_ns_valid_path_separator
  52.  *
  53.  * PARAMETERS:  Sep              - Character to be checked
  54.  *
  55.  * RETURN:      TRUE if a valid path separator
  56.  *
  57.  * DESCRIPTION: Check if a character is a valid ACPI path separator
  58.  *
  59.  ******************************************************************************/
  60. u8
  61. acpi_ns_valid_path_separator (
  62. NATIVE_CHAR             sep)
  63. {
  64. return ((u8) (sep == '.'));
  65. }
  66. /*******************************************************************************
  67.  *
  68.  * FUNCTION:    Acpi_ns_get_type
  69.  *
  70.  * PARAMETERS:  Handle              - Parent Node to be examined
  71.  *
  72.  * RETURN:      Type field from Node whose handle is passed
  73.  *
  74.  ******************************************************************************/
  75. acpi_object_type8
  76. acpi_ns_get_type (
  77. acpi_namespace_node     *node)
  78. {
  79. FUNCTION_TRACE ("Ns_get_type");
  80. if (!node) {
  81. REPORT_WARNING (("Ns_get_type: Null Node ptr"));
  82. return_VALUE (ACPI_TYPE_ANY);
  83. }
  84. return_VALUE (node->type);
  85. }
  86. /*******************************************************************************
  87.  *
  88.  * FUNCTION:    Acpi_ns_local
  89.  *
  90.  * PARAMETERS:  Type            - A namespace object type
  91.  *
  92.  * RETURN:      LOCAL if names must be found locally in objects of the
  93.  *              passed type, 0 if enclosing scopes should be searched
  94.  *
  95.  ******************************************************************************/
  96. u32
  97. acpi_ns_local (
  98. acpi_object_type8       type)
  99. {
  100. FUNCTION_TRACE ("Ns_local");
  101. if (!acpi_ut_valid_object_type (type)) {
  102. /* Type code out of range  */
  103. REPORT_WARNING (("Ns_local: Invalid Object Typen"));
  104. return_VALUE (NSP_NORMAL);
  105. }
  106. return_VALUE ((u32) acpi_gbl_ns_properties[type] & NSP_LOCAL);
  107. }
  108. /*******************************************************************************
  109.  *
  110.  * FUNCTION:    Acpi_ns_get_internal_name_length
  111.  *
  112.  * PARAMETERS:  Info            - Info struct initialized with the
  113.  *                                external name pointer.
  114.  *
  115.  * RETURN:      Status
  116.  *
  117.  * DESCRIPTION: Calculate the length of the internal (AML) namestring
  118.  *              corresponding to the external (ASL) namestring.
  119.  *
  120.  ******************************************************************************/
  121. acpi_status
  122. acpi_ns_get_internal_name_length (
  123. acpi_namestring_info    *info)
  124. {
  125. NATIVE_CHAR             *next_external_char;
  126. u32                     i;
  127. FUNCTION_ENTRY ();
  128. next_external_char = info->external_name;
  129. info->num_carats = 0;
  130. info->num_segments = 0;
  131. info->fully_qualified = FALSE;
  132. /*
  133.  * For the internal name, the required length is 4 bytes
  134.  * per segment, plus 1 each for Root_prefix, Multi_name_prefix_op,
  135.  * segment count, trailing null (which is not really needed,
  136.  * but no there's harm in putting it there)
  137.  *
  138.  * strlen() + 1 covers the first Name_seg, which has no
  139.  * path separator
  140.  */
  141. if (acpi_ns_valid_root_prefix (next_external_char[0])) {
  142. info->fully_qualified = TRUE;
  143. next_external_char++;
  144. }
  145. else {
  146. /*
  147.  * Handle Carat prefixes
  148.  */
  149. while (*next_external_char == '^') {
  150. info->num_carats++;
  151. next_external_char++;
  152. }
  153. }
  154. /*
  155.  * Determine the number of ACPI name "segments" by counting
  156.  * the number of path separators within the string.  Start
  157.  * with one segment since the segment count is (# separators)
  158.  * + 1, and zero separators is ok.
  159.  */
  160. if (*next_external_char) {
  161. info->num_segments = 1;
  162. for (i = 0; next_external_char[i]; i++) {
  163. if (acpi_ns_valid_path_separator (next_external_char[i])) {
  164. info->num_segments++;
  165. }
  166. }
  167. }
  168. info->length = (ACPI_NAME_SIZE * info->num_segments) +
  169.   4 + info->num_carats;
  170. info->next_external_char = next_external_char;
  171. return (AE_OK);
  172. }
  173. /*******************************************************************************
  174.  *
  175.  * FUNCTION:    Acpi_ns_build_internal_name
  176.  *
  177.  * PARAMETERS:  Info            - Info struct fully initialized
  178.  *
  179.  * RETURN:      Status
  180.  *
  181.  * DESCRIPTION: Construct the internal (AML) namestring
  182.  *              corresponding to the external (ASL) namestring.
  183.  *
  184.  ******************************************************************************/
  185. acpi_status
  186. acpi_ns_build_internal_name (
  187. acpi_namestring_info    *info)
  188. {
  189. u32                     num_segments = info->num_segments;
  190. NATIVE_CHAR             *internal_name = info->internal_name;
  191. NATIVE_CHAR             *external_name = info->next_external_char;
  192. NATIVE_CHAR             *result = NULL;
  193. u32                     i;
  194. FUNCTION_TRACE ("Ns_build_internal_name");
  195. /* Setup the correct prefixes, counts, and pointers */
  196. if (info->fully_qualified) {
  197. internal_name[0] = '\';
  198. if (num_segments <= 1) {
  199. result = &internal_name[1];
  200. }
  201. else if (num_segments == 2) {
  202. internal_name[1] = AML_DUAL_NAME_PREFIX;
  203. result = &internal_name[2];
  204. }
  205. else {
  206. internal_name[1] = AML_MULTI_NAME_PREFIX_OP;
  207. internal_name[2] = (char) num_segments;
  208. result = &internal_name[3];
  209. }
  210. }
  211. else {
  212. /*
  213.  * Not fully qualified.
  214.  * Handle Carats first, then append the name segments
  215.  */
  216. i = 0;
  217. if (info->num_carats) {
  218. for (i = 0; i < info->num_carats; i++) {
  219. internal_name[i] = '^';
  220. }
  221. }
  222. if (num_segments == 1) {
  223. result = &internal_name[i];
  224. }
  225. else if (num_segments == 2) {
  226. internal_name[i] = AML_DUAL_NAME_PREFIX;
  227. result = &internal_name[i+1];
  228. }
  229. else {
  230. internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
  231. internal_name[i+1] = (char) num_segments;
  232. result = &internal_name[i+2];
  233. }
  234. }
  235. /* Build the name (minus path separators) */
  236. for (; num_segments; num_segments--) {
  237. for (i = 0; i < ACPI_NAME_SIZE; i++) {
  238. if (acpi_ns_valid_path_separator (*external_name) ||
  239.    (*external_name == 0)) {
  240. /* Pad the segment with underscore(s) if segment is short */
  241. result[i] = '_';
  242. }
  243. else {
  244. /* Convert the character to uppercase and save it */
  245. result[i] = (char) TOUPPER (*external_name);
  246. external_name++;
  247. }
  248. }
  249. /* Now we must have a path separator, or the pathname is bad */
  250. if (!acpi_ns_valid_path_separator (*external_name) &&
  251. (*external_name != 0)) {
  252. return_ACPI_STATUS (AE_BAD_PARAMETER);
  253. }
  254. /* Move on the next segment */
  255. external_name++;
  256. result += ACPI_NAME_SIZE;
  257. }
  258. /* Terminate the string */
  259. *result = 0;
  260. if (info->fully_qualified) {
  261. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (abs) "\%s"n",
  262. internal_name, &internal_name[0]));
  263. }
  264. else {
  265. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (rel) "%s"n",
  266. internal_name, &internal_name[2]));
  267. }
  268. return_ACPI_STATUS (AE_OK);
  269. }
  270. /*******************************************************************************
  271.  *
  272.  * FUNCTION:    Acpi_ns_internalize_name
  273.  *
  274.  * PARAMETERS:  *External_name          - External representation of name
  275.  *              **Converted Name        - Where to return the resulting
  276.  *                                        internal represention of the name
  277.  *
  278.  * RETURN:      Status
  279.  *
  280.  * DESCRIPTION: Convert an external representation (e.g. "_PR_.CPU0")
  281.  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
  282.  *
  283.  *******************************************************************************/
  284. acpi_status
  285. acpi_ns_internalize_name (
  286. NATIVE_CHAR             *external_name,
  287. NATIVE_CHAR             **converted_name)
  288. {
  289. NATIVE_CHAR             *internal_name;
  290. acpi_namestring_info    info;
  291. acpi_status             status;
  292. FUNCTION_TRACE ("Ns_internalize_name");
  293. if ((!external_name)     ||
  294. (*external_name == 0) ||
  295. (!converted_name)) {
  296. return_ACPI_STATUS (AE_BAD_PARAMETER);
  297. }
  298. /* Get the length of the new internal name */
  299. info.external_name = external_name;
  300. acpi_ns_get_internal_name_length (&info);
  301. /* We need a segment to store the internal  name */
  302. internal_name = ACPI_MEM_CALLOCATE (info.length);
  303. if (!internal_name) {
  304. return_ACPI_STATUS (AE_NO_MEMORY);
  305. }
  306. /* Build the name */
  307. info.internal_name = internal_name;
  308. status = acpi_ns_build_internal_name (&info);
  309. if (ACPI_FAILURE (status)) {
  310. ACPI_MEM_FREE (internal_name);
  311. return_ACPI_STATUS (status);
  312. }
  313. *converted_name = internal_name;
  314. return_ACPI_STATUS (AE_OK);
  315. }
  316. /*******************************************************************************
  317.  *
  318.  * FUNCTION:    Acpi_ns_externalize_name
  319.  *
  320.  * PARAMETERS:  *Internal_name         - Internal representation of name
  321.  *              **Converted_name       - Where to return the resulting
  322.  *                                       external representation of name
  323.  *
  324.  * RETURN:      Status
  325.  *
  326.  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
  327.  *              to its external form (e.g. "_PR_.CPU0")
  328.  *
  329.  ******************************************************************************/
  330. acpi_status
  331. acpi_ns_externalize_name (
  332. u32                     internal_name_length,
  333. char                    *internal_name,
  334. u32                     *converted_name_length,
  335. char                    **converted_name)
  336. {
  337. u32                     prefix_length = 0;
  338. u32                     names_index = 0;
  339. u32                     names_count = 0;
  340. u32                     i = 0;
  341. u32                     j = 0;
  342. FUNCTION_TRACE ("Ns_externalize_name");
  343. if (!internal_name_length   ||
  344. !internal_name          ||
  345. !converted_name_length  ||
  346. !converted_name) {
  347. return_ACPI_STATUS (AE_BAD_PARAMETER);
  348. }
  349. /*
  350.  * Check for a prefix (one '' | one or more '^').
  351.  */
  352. switch (internal_name[0]) {
  353. case '\':
  354. prefix_length = 1;
  355. break;
  356. case '^':
  357. for (i = 0; i < internal_name_length; i++) {
  358. if (internal_name[i] != '^') {
  359. prefix_length = i + 1;
  360. }
  361. }
  362. if (i == internal_name_length) {
  363. prefix_length = i;
  364. }
  365. break;
  366. }
  367. /*
  368.  * Check for object names.  Note that there could be 0-255 of these
  369.  * 4-byte elements.
  370.  */
  371. if (prefix_length < internal_name_length) {
  372. switch (internal_name[prefix_length]) {
  373. /* <count> 4-byte names */
  374. case AML_MULTI_NAME_PREFIX_OP:
  375. names_index = prefix_length + 2;
  376. names_count = (u32) internal_name[prefix_length + 1];
  377. break;
  378. /* two 4-byte names */
  379. case AML_DUAL_NAME_PREFIX:
  380. names_index = prefix_length + 1;
  381. names_count = 2;
  382. break;
  383. /* Null_name */
  384. case 0:
  385. names_index = 0;
  386. names_count = 0;
  387. break;
  388. /* one 4-byte name */
  389. default:
  390. names_index = prefix_length;
  391. names_count = 1;
  392. break;
  393. }
  394. }
  395. /*
  396.  * Calculate the length of Converted_name, which equals the length
  397.  * of the prefix, length of all object names, length of any required
  398.  * punctuation ('.') between object names, plus the NULL terminator.
  399.  */
  400. *converted_name_length = prefix_length + (4 * names_count) +
  401.    ((names_count > 0) ? (names_count - 1) : 0) + 1;
  402. /*
  403.  * Check to see if we're still in bounds.  If not, there's a problem
  404.  * with Internal_name (invalid format).
  405.  */
  406. if (*converted_name_length > internal_name_length) {
  407. REPORT_ERROR (("Ns_externalize_name: Invalid internal namen"));
  408. return_ACPI_STATUS (AE_BAD_PATHNAME);
  409. }
  410. /*
  411.  * Build Converted_name...
  412.  */
  413. (*converted_name) = ACPI_MEM_CALLOCATE (*converted_name_length);
  414. if (!(*converted_name)) {
  415. return_ACPI_STATUS (AE_NO_MEMORY);
  416. }
  417. j = 0;
  418. for (i = 0; i < prefix_length; i++) {
  419. (*converted_name)[j++] = internal_name[i];
  420. }
  421. if (names_count > 0) {
  422. for (i = 0; i < names_count; i++) {
  423. if (i > 0) {
  424. (*converted_name)[j++] = '.';
  425. }
  426. (*converted_name)[j++] = internal_name[names_index++];
  427. (*converted_name)[j++] = internal_name[names_index++];
  428. (*converted_name)[j++] = internal_name[names_index++];
  429. (*converted_name)[j++] = internal_name[names_index++];
  430. }
  431. }
  432. return_ACPI_STATUS (AE_OK);
  433. }
  434. /*******************************************************************************
  435.  *
  436.  * FUNCTION:    Acpi_ns_map_handle_to_node
  437.  *
  438.  * PARAMETERS:  Handle          - Handle to be converted to an Node
  439.  *
  440.  * RETURN:      A Name table entry pointer
  441.  *
  442.  * DESCRIPTION: Convert a namespace handle to a real Node
  443.  *
  444.  ******************************************************************************/
  445. acpi_namespace_node *
  446. acpi_ns_map_handle_to_node (
  447. acpi_handle             handle)
  448. {
  449. FUNCTION_ENTRY ();
  450. /*
  451.  * Simple implementation for now;
  452.  * TBD: [Future] Real integer handles allow for more verification
  453.  * and keep all pointers within this subsystem!
  454.  */
  455. if (!handle) {
  456. return (NULL);
  457. }
  458. if (handle == ACPI_ROOT_OBJECT) {
  459. return (acpi_gbl_root_node);
  460. }
  461. /* We can at least attempt to verify the handle */
  462. if (!VALID_DESCRIPTOR_TYPE (handle, ACPI_DESC_TYPE_NAMED)) {
  463. return (NULL);
  464. }
  465. return ((acpi_namespace_node *) handle);
  466. }
  467. /*******************************************************************************
  468.  *
  469.  * FUNCTION:    Acpi_ns_convert_entry_to_handle
  470.  *
  471.  * PARAMETERS:  Node          - Node to be converted to a Handle
  472.  *
  473.  * RETURN:      An USER acpi_handle
  474.  *
  475.  * DESCRIPTION: Convert a real Node to a namespace handle
  476.  *
  477.  ******************************************************************************/
  478. acpi_handle
  479. acpi_ns_convert_entry_to_handle (
  480. acpi_namespace_node         *node)
  481. {
  482. /*
  483.  * Simple implementation for now;
  484.  * TBD: [Future] Real integer handles allow for more verification
  485.  * and keep all pointers within this subsystem!
  486.  */
  487. return ((acpi_handle) node);
  488. /* ---------------------------------------------------
  489. if (!Node)
  490. {
  491. return (NULL);
  492. }
  493. if (Node == Acpi_gbl_Root_node)
  494. {
  495. return (ACPI_ROOT_OBJECT);
  496. }
  497. return ((acpi_handle) Node);
  498. ------------------------------------------------------*/
  499. }
  500. /*******************************************************************************
  501.  *
  502.  * FUNCTION:    Acpi_ns_terminate
  503.  *
  504.  * PARAMETERS:  none
  505.  *
  506.  * RETURN:      none
  507.  *
  508.  * DESCRIPTION: free memory allocated for table storage.
  509.  *
  510.  ******************************************************************************/
  511. void
  512. acpi_ns_terminate (void)
  513. {
  514. acpi_operand_object     *obj_desc;
  515. acpi_namespace_node     *this_node;
  516. FUNCTION_TRACE ("Ns_terminate");
  517. this_node = acpi_gbl_root_node;
  518. /*
  519.  * 1) Free the entire namespace -- all objects, tables, and stacks
  520.  *
  521.  * Delete all objects linked to the root
  522.  * (additional table descriptors)
  523.  */
  524. acpi_ns_delete_namespace_subtree (this_node);
  525. /* Detach any object(s) attached to the root */
  526. obj_desc = acpi_ns_get_attached_object (this_node);
  527. if (obj_desc) {
  528. acpi_ns_detach_object (this_node);
  529. acpi_ut_remove_reference (obj_desc);
  530. }
  531. acpi_ns_delete_children (this_node);
  532. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freedn"));
  533. /*
  534.  * 2) Now we can delete the ACPI tables
  535.  */
  536. acpi_tb_delete_acpi_tables ();
  537. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freedn"));
  538. return_VOID;
  539. }
  540. /*******************************************************************************
  541.  *
  542.  * FUNCTION:    Acpi_ns_opens_scope
  543.  *
  544.  * PARAMETERS:  Type        - A valid namespace type
  545.  *
  546.  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
  547.  *              to the ACPI specification, else 0
  548.  *
  549.  ******************************************************************************/
  550. u32
  551. acpi_ns_opens_scope (
  552. acpi_object_type8       type)
  553. {
  554. FUNCTION_TRACE_U32 ("Ns_opens_scope", type);
  555. if (!acpi_ut_valid_object_type (type)) {
  556. /* type code out of range  */
  557. REPORT_WARNING (("Ns_opens_scope: Invalid Object Typen"));
  558. return_VALUE (NSP_NORMAL);
  559. }
  560. return_VALUE (((u32) acpi_gbl_ns_properties[type]) & NSP_NEWSCOPE);
  561. }
  562. /*******************************************************************************
  563.  *
  564.  * FUNCTION:    Acpi_ns_get_node
  565.  *
  566.  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
  567.  *                             (backslash) and ^ (carat) prefixes, and the
  568.  *                            . (period) to separate segments are supported.
  569.  *              Start_node  - Root of subtree to be searched, or NS_ALL for the
  570.  *                            root of the name space.  If Name is fully
  571.  *                            qualified (first s8 is ''), the passed value
  572.  *                            of Scope will not be accessed.
  573.  *              Return_node - Where the Node is returned
  574.  *
  575.  * DESCRIPTION: Look up a name relative to a given scope and return the
  576.  *              corresponding Node.  NOTE: Scope can be null.
  577.  *
  578.  * MUTEX:       Locks namespace
  579.  *
  580.  ******************************************************************************/
  581. acpi_status
  582. acpi_ns_get_node (
  583. NATIVE_CHAR             *pathname,
  584. acpi_namespace_node     *start_node,
  585. acpi_namespace_node     **return_node)
  586. {
  587. acpi_generic_state      scope_info;
  588. acpi_status             status;
  589. NATIVE_CHAR             *internal_path = NULL;
  590. FUNCTION_TRACE_PTR ("Ns_get_node", pathname);
  591. /* Ensure that the namespace has been initialized */
  592. if (!acpi_gbl_root_node) {
  593. return_ACPI_STATUS (AE_NO_NAMESPACE);
  594. }
  595. if (!pathname) {
  596. return_ACPI_STATUS (AE_BAD_PARAMETER);
  597. }
  598. /* Convert path to internal representation */
  599. status = acpi_ns_internalize_name (pathname, &internal_path);
  600. if (ACPI_FAILURE (status)) {
  601. return_ACPI_STATUS (status);
  602. }
  603. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  604. /* Setup lookup scope (search starting point) */
  605. scope_info.scope.node = start_node;
  606. /* Lookup the name in the namespace */
  607. status = acpi_ns_lookup (&scope_info, internal_path,
  608.  ACPI_TYPE_ANY, IMODE_EXECUTE,
  609.  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
  610.  NULL, return_node);
  611. if (ACPI_FAILURE (status)) {
  612. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %sn",
  613. internal_path, acpi_format_exception (status)));
  614. }
  615. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  616. /* Cleanup */
  617. ACPI_MEM_FREE (internal_path);
  618. return_ACPI_STATUS (status);
  619. }
  620. /*******************************************************************************
  621.  *
  622.  * FUNCTION:    Acpi_ns_find_parent_name
  623.  *
  624.  * PARAMETERS:  *Child_node            - Named Obj whose name is to be found
  625.  *
  626.  * RETURN:      The ACPI name
  627.  *
  628.  * DESCRIPTION: Search for the given obj in its parent scope and return the
  629.  *              name segment, or "????" if the parent name can't be found
  630.  *              (which "should not happen").
  631.  *
  632.  ******************************************************************************/
  633. acpi_name
  634. acpi_ns_find_parent_name (
  635. acpi_namespace_node     *child_node)
  636. {
  637. acpi_namespace_node     *parent_node;
  638. FUNCTION_TRACE ("Ns_find_parent_name");
  639. if (child_node) {
  640. /* Valid entry.  Get the parent Node */
  641. parent_node = acpi_ns_get_parent_object (child_node);
  642. if (parent_node) {
  643. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Parent of %p [%4.4s] is %p [%4.4s]n",
  644. child_node, (char*)&child_node->name, parent_node, (char*)&parent_node->name));
  645. if (parent_node->name) {
  646. return_VALUE (parent_node->name);
  647. }
  648. }
  649. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "unable to find parent of %p (%4.4s)n",
  650. child_node, (char*)&child_node->name));
  651. }
  652. return_VALUE (ACPI_UNKNOWN_NAME);
  653. }
  654. #if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER)
  655. /*******************************************************************************
  656.  *
  657.  * FUNCTION:    Acpi_ns_exist_downstream_sibling
  658.  *
  659.  * PARAMETERS:  *Node          - pointer to first Node to examine
  660.  *
  661.  * RETURN:      TRUE if sibling is found, FALSE otherwise
  662.  *
  663.  * DESCRIPTION: Searches remainder of scope being processed to determine
  664.  *              whether there is a downstream sibling to the current
  665.  *              object.  This function is used to determine what type of
  666.  *              line drawing character to use when displaying namespace
  667.  *              trees.
  668.  *
  669.  ******************************************************************************/
  670. u8
  671. acpi_ns_exist_downstream_sibling (
  672. acpi_namespace_node     *node)
  673. {
  674. if (!node) {
  675. return (FALSE);
  676. }
  677. if (node->name) {
  678. return (TRUE);
  679. }
  680. return (FALSE);
  681. }
  682. #endif /* ACPI_DEBUG */
  683. /*******************************************************************************
  684.  *
  685.  * FUNCTION:    Acpi_ns_get_parent_object
  686.  *
  687.  * PARAMETERS:  Node       - Current table entry
  688.  *
  689.  * RETURN:      Parent entry of the given entry
  690.  *
  691.  * DESCRIPTION: Obtain the parent entry for a given entry in the namespace.
  692.  *
  693.  ******************************************************************************/
  694. acpi_namespace_node *
  695. acpi_ns_get_parent_object (
  696. acpi_namespace_node     *node)
  697. {
  698. FUNCTION_ENTRY ();
  699. if (!node) {
  700. return (NULL);
  701. }
  702. /*
  703.  * Walk to the end of this peer list.
  704.  * The last entry is marked with a flag and the peer
  705.  * pointer is really a pointer back to the parent.
  706.  * This saves putting a parent back pointer in each and
  707.  * every named object!
  708.  */
  709. while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
  710. node = node->peer;
  711. }
  712. return (node->peer);
  713. }
  714. /*******************************************************************************
  715.  *
  716.  * FUNCTION:    Acpi_ns_get_next_valid_node
  717.  *
  718.  * PARAMETERS:  Node       - Current table entry
  719.  *
  720.  * RETURN:      Next valid Node in the linked node list.  NULL if no more valid
  721.  *              nodess
  722.  *
  723.  * DESCRIPTION: Find the next valid node within a name table.
  724.  *              Useful for implementing NULL-end-of-list loops.
  725.  *
  726.  ******************************************************************************/
  727. acpi_namespace_node *
  728. acpi_ns_get_next_valid_node (
  729. acpi_namespace_node     *node)
  730. {
  731. /* If we are at the end of this peer list, return NULL */
  732. if (node->flags & ANOBJ_END_OF_PEER_LIST) {
  733. return NULL;
  734. }
  735. /* Otherwise just return the next peer */
  736. return (node->peer);
  737. }