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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: nssearch - Namespace search
  4.  *              $Revision: 75 $
  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 "amlcode.h"
  26. #include "acinterp.h"
  27. #include "acnamesp.h"
  28. #define _COMPONENT          ACPI_NAMESPACE
  29.  MODULE_NAME         ("nssearch")
  30. /*******************************************************************************
  31.  *
  32.  * FUNCTION:    Acpi_ns_search_node
  33.  *
  34.  * PARAMETERS:  *Target_name        - Ascii ACPI name to search for
  35.  *              *Node               - Starting table where search will begin
  36.  *              Type                - Object type to match
  37.  *              **Return_node       - Where the matched Named obj is returned
  38.  *
  39.  * RETURN:      Status
  40.  *
  41.  * DESCRIPTION: Search a single namespace table.  Performs a simple search,
  42.  *              does not add entries or search parents.
  43.  *
  44.  *
  45.  *      Named object lists are built (and subsequently dumped) in the
  46.  *      order in which the names are encountered during the namespace load;
  47.  *
  48.  *      All namespace searching is linear in this implementation, but
  49.  *      could be easily modified to support any improved search
  50.  *      algorithm.  However, the linear search was chosen for simplicity
  51.  *      and because the trees are small and the other interpreter
  52.  *      execution overhead is relatively high.
  53.  *
  54.  ******************************************************************************/
  55. acpi_status
  56. acpi_ns_search_node (
  57. u32                     target_name,
  58. acpi_namespace_node     *node,
  59. acpi_object_type8       type,
  60. acpi_namespace_node     **return_node)
  61. {
  62. acpi_namespace_node     *next_node;
  63. FUNCTION_TRACE ("Ns_search_node");
  64. #ifdef ACPI_DEBUG
  65. if (ACPI_LV_NAMES & acpi_dbg_level) {
  66. NATIVE_CHAR         *scope_name;
  67. scope_name = acpi_ns_get_table_pathname (node);
  68. if (scope_name) {
  69. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s [%p] For %4.4s (type %X)n",
  70. scope_name, node, (char*)&target_name, type));
  71. ACPI_MEM_FREE (scope_name);
  72. }
  73. }
  74. #endif
  75. /*
  76.  * Search for name in this table, which is to say that we must search
  77.  * for the name among the children of this object
  78.  */
  79. next_node = node->child;
  80. while (next_node) {
  81. /* Check for match against the name */
  82. if (next_node->name == target_name) {
  83. /*
  84.  * Found matching entry.  Capture the type if appropriate, before
  85.  * returning the entry.
  86.  *
  87.  * The Def_field_defn and Bank_field_defn cases are actually looking up
  88.  * the Region in which the field will be defined
  89.  */
  90. if ((INTERNAL_TYPE_FIELD_DEFN == type) ||
  91. (INTERNAL_TYPE_BANK_FIELD_DEFN == type)) {
  92. type = ACPI_TYPE_REGION;
  93. }
  94. /*
  95.  * Scope, Def_any, and Index_field_defn are bogus "types" which do not
  96.  * actually have anything to do with the type of the name being
  97.  * looked up.  For any other value of Type, if the type stored in
  98.  * the entry is Any (i.e. unknown), save the actual type.
  99.  */
  100. if (type != INTERNAL_TYPE_SCOPE &&
  101. type != INTERNAL_TYPE_DEF_ANY &&
  102. type != INTERNAL_TYPE_INDEX_FIELD_DEFN &&
  103. next_node->type == ACPI_TYPE_ANY) {
  104. next_node->type = (u8) type;
  105. }
  106. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  107. "Name %4.4s (actual type %X) found at %pn",
  108. (char*)&target_name, next_node->type, next_node));
  109. *return_node = next_node;
  110. return_ACPI_STATUS (AE_OK);
  111. }
  112. /*
  113.  * The last entry in the list points back to the parent,
  114.  * so a flag is used to indicate the end-of-list
  115.  */
  116. if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
  117. /* Searched entire list, we are done */
  118. break;
  119. }
  120. /* Didn't match name, move on to the next peer object */
  121. next_node = next_node->peer;
  122. }
  123. /* Searched entire table, not found */
  124. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name %4.4s (type %X) not found at %pn",
  125. (char*)&target_name, type, next_node));
  126. return_ACPI_STATUS (AE_NOT_FOUND);
  127. }
  128. /*******************************************************************************
  129.  *
  130.  * FUNCTION:    Acpi_ns_search_parent_tree
  131.  *
  132.  * PARAMETERS:  *Target_name        - Ascii ACPI name to search for
  133.  *              *Node               - Starting table where search will begin
  134.  *              Type                - Object type to match
  135.  *              **Return_node       - Where the matched Named Obj is returned
  136.  *
  137.  * RETURN:      Status
  138.  *
  139.  * DESCRIPTION: Called when a name has not been found in the current namespace
  140.  *              table.  Before adding it or giving up, ACPI scope rules require
  141.  *              searching enclosing scopes in cases identified by Acpi_ns_local().
  142.  *
  143.  *              "A name is located by finding the matching name in the current
  144.  *              name space, and then in the parent name space. If the parent
  145.  *              name space does not contain the name, the search continues
  146.  *              recursively until either the name is found or the name space
  147.  *              does not have a parent (the root of the name space).  This
  148.  *              indicates that the name is not found" (From ACPI Specification,
  149.  *              section 5.3)
  150.  *
  151.  ******************************************************************************/
  152. static acpi_status
  153. acpi_ns_search_parent_tree (
  154. u32                     target_name,
  155. acpi_namespace_node     *node,
  156. acpi_object_type8       type,
  157. acpi_namespace_node     **return_node)
  158. {
  159. acpi_status             status;
  160. acpi_namespace_node     *parent_node;
  161. FUNCTION_TRACE ("Ns_search_parent_tree");
  162. parent_node = acpi_ns_get_parent_object (node);
  163. /*
  164.  * If there is no parent (at the root) or type is "local", we won't be
  165.  * searching the parent tree.
  166.  */
  167. if ((acpi_ns_local (type)) ||
  168. (!parent_node)) {
  169. if (!parent_node) {
  170. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parentn",
  171. (char*)&target_name));
  172. }
  173. if (acpi_ns_local (type)) {
  174. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] type %X is local(no search)n",
  175. (char*)&target_name, type));
  176. }
  177. return_ACPI_STATUS (AE_NOT_FOUND);
  178. }
  179. /* Search the parent tree */
  180. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching parent for %4.4sn", (char*)&target_name));
  181. /*
  182.  * Search parents until found the target or we have backed up to
  183.  * the root
  184.  */
  185. while (parent_node) {
  186. /* Search parent scope */
  187. /* TBD: [Investigate] Why ACPI_TYPE_ANY? */
  188. status = acpi_ns_search_node (target_name, parent_node,
  189.    ACPI_TYPE_ANY, return_node);
  190. if (ACPI_SUCCESS (status)) {
  191. return_ACPI_STATUS (status);
  192. }
  193. /*
  194.  * Not found here, go up another level
  195.  * (until we reach the root)
  196.  */
  197. parent_node = acpi_ns_get_parent_object (parent_node);
  198. }
  199. /* Not found in parent tree */
  200. return_ACPI_STATUS (AE_NOT_FOUND);
  201. }
  202. /*******************************************************************************
  203.  *
  204.  * FUNCTION:    Acpi_ns_search_and_enter
  205.  *
  206.  * PARAMETERS:  Target_name         - Ascii ACPI name to search for (4 chars)
  207.  *              Walk_state          - Current state of the walk
  208.  *              *Node               - Starting table where search will begin
  209.  *              Interpreter_mode    - Add names only in MODE_Load_pass_x.
  210.  *                                    Otherwise,search only.
  211.  *              Type                - Object type to match
  212.  *              Flags               - Flags describing the search restrictions
  213.  *              **Return_node       - Where the Node is returned
  214.  *
  215.  * RETURN:      Status
  216.  *
  217.  * DESCRIPTION: Search for a name segment in a single name table,
  218.  *              optionally adding it if it is not found.  If the passed
  219.  *              Type is not Any and the type previously stored in the
  220.  *              entry was Any (i.e. unknown), update the stored type.
  221.  *
  222.  *              In IMODE_EXECUTE, search only.
  223.  *              In other modes, search and add if not found.
  224.  *
  225.  ******************************************************************************/
  226. acpi_status
  227. acpi_ns_search_and_enter (
  228. u32                     target_name,
  229. acpi_walk_state         *walk_state,
  230. acpi_namespace_node     *node,
  231. operating_mode          interpreter_mode,
  232. acpi_object_type8       type,
  233. u32                     flags,
  234. acpi_namespace_node     **return_node)
  235. {
  236. acpi_status             status;
  237. acpi_namespace_node     *new_node;
  238. FUNCTION_TRACE ("Ns_search_and_enter");
  239. /* Parameter validation */
  240. if (!node || !target_name || !return_node) {
  241. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null param-  Table %p Name %X Return %pn",
  242. node, target_name, return_node));
  243. REPORT_ERROR (("Ns_search_and_enter: bad (null) parametern"));
  244. return_ACPI_STATUS (AE_BAD_PARAMETER);
  245. }
  246. /* Name must consist of printable characters */
  247. if (!acpi_ut_valid_acpi_name (target_name)) {
  248. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "*** Bad character in name: %08x *** n",
  249. target_name));
  250. REPORT_ERROR (("Ns_search_and_enter: Bad character in ACPI Namen"));
  251. return_ACPI_STATUS (AE_BAD_CHARACTER);
  252. }
  253. /* Try to find the name in the table specified by the caller */
  254. *return_node = ENTRY_NOT_FOUND;
  255. status = acpi_ns_search_node (target_name, node, type, return_node);
  256. if (status != AE_NOT_FOUND) {
  257. /*
  258.  * If we found it AND the request specifies that a find is an error,
  259.  * return the error
  260.  */
  261. if ((status == AE_OK) &&
  262. (flags & NS_ERROR_IF_FOUND)) {
  263. status = AE_EXIST;
  264. }
  265. /*
  266.  * Either found it or there was an error
  267.  * -- finished either way
  268.  */
  269. return_ACPI_STATUS (status);
  270. }
  271. /*
  272.  * Not found in the table.  If we are NOT performing the
  273.  * first pass (name entry) of loading the namespace, search
  274.  * the parent tree (all the way to the root if necessary.)
  275.  * We don't want to perform the parent search when the
  276.  * namespace is actually being loaded.  We want to perform
  277.  * the search when namespace references are being resolved
  278.  * (load pass 2) and during the execution phase.
  279.  */
  280. if ((interpreter_mode != IMODE_LOAD_PASS1) &&
  281. (flags & NS_SEARCH_PARENT)) {
  282. /*
  283.  * Not found in table - search parent tree according
  284.  * to ACPI specification
  285.  */
  286. status = acpi_ns_search_parent_tree (target_name, node,
  287.  type, return_node);
  288. if (ACPI_SUCCESS (status)) {
  289. return_ACPI_STATUS (status);
  290. }
  291. }
  292. /*
  293.  * In execute mode, just search, never add names.  Exit now.
  294.  */
  295. if (interpreter_mode == IMODE_EXECUTE) {
  296. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s Not found in %p [Not adding]n",
  297. (char*)&target_name, node));
  298. return_ACPI_STATUS (AE_NOT_FOUND);
  299. }
  300. /* Create the new named object */
  301. new_node = acpi_ns_create_node (target_name);
  302. if (!new_node) {
  303. return_ACPI_STATUS (AE_NO_MEMORY);
  304. }
  305. /* Install the new object into the parent's list of children */
  306. acpi_ns_install_node (walk_state, node, new_node, type);
  307. *return_node = new_node;
  308. return_ACPI_STATUS (AE_OK);
  309. }