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

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nswalk - Functions for walking the ACPI namespace
  4.  *              $Revision: 26 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "acinterp.h"
  26. #include "acnamesp.h"
  27. #define _COMPONENT          ACPI_NAMESPACE
  28.  MODULE_NAME         ("nswalk")
  29. /*******************************************************************************
  30.  *
  31.  * FUNCTION:    Acpi_ns_get_next_node
  32.  *
  33.  * PARAMETERS:  Type                - Type of node to be searched for
  34.  *              Parent_node         - Parent node whose children we are
  35.  *                                     getting
  36.  *              Child_node          - Previous child that was found.
  37.  *                                    The NEXT child will be returned
  38.  *
  39.  * RETURN:      acpi_namespace_node - Pointer to the NEXT child or NULL if
  40.  *                                    none is found.
  41.  *
  42.  * DESCRIPTION: Return the next peer node within the namespace.  If Handle
  43.  *              is valid, Scope is ignored.  Otherwise, the first node
  44.  *              within Scope is returned.
  45.  *
  46.  ******************************************************************************/
  47. acpi_namespace_node *
  48. acpi_ns_get_next_node (
  49. acpi_object_type8       type,
  50. acpi_namespace_node     *parent_node,
  51. acpi_namespace_node     *child_node)
  52. {
  53. acpi_namespace_node     *next_node = NULL;
  54. FUNCTION_ENTRY ();
  55. if (!child_node) {
  56. /* It's really the parent's _scope_ that we want */
  57. if (parent_node->child) {
  58. next_node = parent_node->child;
  59. }
  60. }
  61. else {
  62. /* Start search at the NEXT node */
  63. next_node = acpi_ns_get_next_valid_node (child_node);
  64. }
  65. /* If any type is OK, we are done */
  66. if (type == ACPI_TYPE_ANY) {
  67. /* Next_node is NULL if we are at the end-of-list */
  68. return (next_node);
  69. }
  70. /* Must search for the node -- but within this scope only */
  71. while (next_node) {
  72. /* If type matches, we are done */
  73. if (next_node->type == type) {
  74. return (next_node);
  75. }
  76. /* Otherwise, move on to the next node */
  77. next_node = acpi_ns_get_next_valid_node (next_node);
  78. }
  79. /* Not found */
  80. return (NULL);
  81. }
  82. /*******************************************************************************
  83.  *
  84.  * FUNCTION:    Acpi_ns_walk_namespace
  85.  *
  86.  * PARAMETERS:  Type                - acpi_object_type to search for
  87.  *              Start_node          - Handle in namespace where search begins
  88.  *              Max_depth           - Depth to which search is to reach
  89.  *              Unlock_before_callback- Whether to unlock the NS before invoking
  90.  *                                    the callback routine
  91.  *              User_function       - Called when an object of "Type" is found
  92.  *              Context             - Passed to user function
  93.  *              Return_value        - from the User_function if terminated early.
  94.  *                                    Otherwise, returns NULL.
  95.  * RETURNS:     Status
  96.  *
  97.  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  98.  *              starting (and ending) at the node specified by Start_handle.
  99.  *              The User_function is called whenever a node that matches
  100.  *              the type parameter is found.  If the user function returns
  101.  *              a non-zero value, the search is terminated immediately and this
  102.  *              value is returned to the caller.
  103.  *
  104.  *              The point of this procedure is to provide a generic namespace
  105.  *              walk routine that can be called from multiple places to
  106.  *              provide multiple services;  the User Function can be tailored
  107.  *              to each task, whether it is a print function, a compare
  108.  *              function, etc.
  109.  *
  110.  ******************************************************************************/
  111. acpi_status
  112. acpi_ns_walk_namespace (
  113. acpi_object_type8       type,
  114. acpi_handle             start_node,
  115. u32                     max_depth,
  116. u8                      unlock_before_callback,
  117. acpi_walk_callback      user_function,
  118. void                    *context,
  119. void                    **return_value)
  120. {
  121. acpi_status             status;
  122. acpi_namespace_node     *child_node;
  123. acpi_namespace_node     *parent_node;
  124. acpi_object_type8        child_type;
  125. u32                     level;
  126. FUNCTION_TRACE ("Ns_walk_namespace");
  127. /* Special case for the namespace Root Node */
  128. if (start_node == ACPI_ROOT_OBJECT) {
  129. start_node = acpi_gbl_root_node;
  130. }
  131. /* Null child means "get first node" */
  132. parent_node = start_node;
  133. child_node  = 0;
  134. child_type  = ACPI_TYPE_ANY;
  135. level       = 1;
  136. /*
  137.  * Traverse the tree of nodes until we bubble back up to where we
  138.  * started. When Level is zero, the loop is done because we have
  139.  * bubbled up to (and passed) the original parent handle (Start_entry)
  140.  */
  141. while (level > 0) {
  142. /* Get the next node in this scope.  Null if not found */
  143. status = AE_OK;
  144. child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node);
  145. if (child_node) {
  146. /*
  147.  * Found node, Get the type if we are not
  148.  * searching for ANY
  149.  */
  150. if (type != ACPI_TYPE_ANY) {
  151. child_type = child_node->type;
  152. }
  153. if (child_type == type) {
  154. /*
  155.  * Found a matching node, invoke the user
  156.  * callback function
  157.  */
  158. if (unlock_before_callback) {
  159. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  160. }
  161. status = user_function (child_node, level,
  162.  context, return_value);
  163. if (unlock_before_callback) {
  164. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  165. }
  166. switch (status) {
  167. case AE_OK:
  168. case AE_CTRL_DEPTH:
  169. /* Just keep going */
  170. break;
  171. case AE_CTRL_TERMINATE:
  172. /* Exit now, with OK status */
  173. return_ACPI_STATUS (AE_OK);
  174. break;
  175. default:
  176. /* All others are valid exceptions */
  177. return_ACPI_STATUS (status);
  178. break;
  179. }
  180. }
  181. /*
  182.  * Depth first search:
  183.  * Attempt to go down another level in the namespace
  184.  * if we are allowed to.  Don't go any further if we
  185.  * have reached the caller specified maximum depth
  186.  * or if the user function has specified that the
  187.  * maximum depth has been reached.
  188.  */
  189. if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
  190. if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, 0)) {
  191. /*
  192.  * There is at least one child of this
  193.  * node, visit the onde
  194.  */
  195. level++;
  196. parent_node   = child_node;
  197. child_node    = 0;
  198. }
  199. }
  200. }
  201. else {
  202. /*
  203.  * No more children of this node (Acpi_ns_get_next_node
  204.  * failed), go back upwards in the namespace tree to
  205.  * the node's parent.
  206.  */
  207. level--;
  208. child_node = parent_node;
  209. parent_node = acpi_ns_get_parent_object (parent_node);
  210. }
  211. }
  212. /* Complete walk, not terminated by user function */
  213. return_ACPI_STATUS (AE_OK);
  214. }