aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/namespace/nssearch.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2006-05-26 16:36:00 -0400
committerLen Brown <len.brown@intel.com>2006-06-14 02:44:35 -0400
commit4119532c95547821dbe72d6916dfa1b2148475b3 (patch)
tree564eb8f69924fb7dc72e93526faf1547acac7d30 /drivers/acpi/namespace/nssearch.c
parentb8d35192c55fb055792ff0641408eaaec7c88988 (diff)
ACPI: ACPICA 20060526
Restructured, flattened, and simplified the internal interfaces for namespace object evaluation - resulting in smaller code, less CPU stack use, and fewer interfaces. (With assistance from Mikhail Kouzmich) Fixed a problem with the CopyObject operator where the first parameter was not typed correctly for the parser, interpreter, compiler, and disassembler. Caused various errors and unexpected behavior. Fixed a problem where a ShiftLeft or ShiftRight of more than 64 bits produced incorrect results with some C compilers. Since the behavior of C compilers when the shift value is larger than the datatype width is apparently not well defined, the interpreter now detects this condition and simply returns zero as expected in all such cases. (BZ 395) Fixed problem reports (Valery Podrezov) integrated: - Update String-to-Integer conversion to match ACPI 3.0A spec http://bugzilla.kernel.org/show_bug.cgi?id=5329 Allow interpreter to handle nested method declarations http://bugzilla.kernel.org/show_bug.cgi?id=5361 Fixed problem reports (Fiodor Suietov) integrated: - acpi_terminate() doesn't free debug memory allocation list objects (BZ 355) - After Core Subsystem shutdown, acpi_subsystem_status() returns AE_OK (BZ 356) - acpi_os_unmap_memory() for RSDP can be invoked inconsistently (BZ 357) - Resource Manager should return AE_TYPE for non-device objects (BZ 358) - Incomplete cleanup branch in AcpiNsEvaluateRelative (BZ 359) - Use acpi_os_free() instead of ACPI_FREE in acpi_rs_set_srs_method_data (BZ 360) - Incomplete cleanup branch in acpi_ps_parse_aml (BZ 361) - Incomplete cleanup branch in acpi_ds_delete_walk_state (BZ 362) - acpi_get_table_header returns AE_NO_ACPI_TABLES until DSDT is loaded (BZ 365) - Status of the Global Initialization Handler call not used (BZ 366) - Incorrect object parameter to Global Initialization Handler (BZ 367) Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace/nssearch.c')
-rw-r--r--drivers/acpi/namespace/nssearch.c82
1 files changed, 46 insertions, 36 deletions
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index d2473476afa5..500e2bbcfaf7 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -56,16 +56,16 @@ acpi_ns_search_parent_tree(u32 target_name,
56 56
57/******************************************************************************* 57/*******************************************************************************
58 * 58 *
59 * FUNCTION: acpi_ns_search_node 59 * FUNCTION: acpi_ns_search_one_scope
60 * 60 *
61 * PARAMETERS: target_name - Ascii ACPI name to search for 61 * PARAMETERS: target_name - Ascii ACPI name to search for
62 * Node - Starting node where search will begin 62 * parent_node - Starting node where search will begin
63 * Type - Object type to match 63 * Type - Object type to match
64 * return_node - Where the matched Named obj is returned 64 * return_node - Where the matched Named obj is returned
65 * 65 *
66 * RETURN: Status 66 * RETURN: Status
67 * 67 *
68 * DESCRIPTION: Search a single level of the namespace. Performs a 68 * DESCRIPTION: Search a single level of the namespace. Performs a
69 * simple search of the specified level, and does not add 69 * simple search of the specified level, and does not add
70 * entries or search parents. 70 * entries or search parents.
71 * 71 *
@@ -75,32 +75,37 @@ acpi_ns_search_parent_tree(u32 target_name,
75 * 75 *
76 * All namespace searching is linear in this implementation, but 76 * All namespace searching is linear in this implementation, but
77 * could be easily modified to support any improved search 77 * could be easily modified to support any improved search
78 * algorithm. However, the linear search was chosen for simplicity 78 * algorithm. However, the linear search was chosen for simplicity
79 * and because the trees are small and the other interpreter 79 * and because the trees are small and the other interpreter
80 * execution overhead is relatively high. 80 * execution overhead is relatively high.
81 * 81 *
82 * Note: CPU execution analysis has shown that the AML interpreter spends
83 * a very small percentage of its time searching the namespace. Therefore,
84 * the linear search seems to be sufficient, as there would seem to be
85 * little value in improving the search.
86 *
82 ******************************************************************************/ 87 ******************************************************************************/
83 88
84acpi_status 89acpi_status
85acpi_ns_search_node(u32 target_name, 90acpi_ns_search_one_scope(u32 target_name,
86 struct acpi_namespace_node *node, 91 struct acpi_namespace_node *parent_node,
87 acpi_object_type type, 92 acpi_object_type type,
88 struct acpi_namespace_node **return_node) 93 struct acpi_namespace_node **return_node)
89{ 94{
90 struct acpi_namespace_node *next_node; 95 struct acpi_namespace_node *node;
91 96
92 ACPI_FUNCTION_TRACE(ns_search_node); 97 ACPI_FUNCTION_TRACE(ns_search_one_scope);
93 98
94#ifdef ACPI_DEBUG_OUTPUT 99#ifdef ACPI_DEBUG_OUTPUT
95 if (ACPI_LV_NAMES & acpi_dbg_level) { 100 if (ACPI_LV_NAMES & acpi_dbg_level) {
96 char *scope_name; 101 char *scope_name;
97 102
98 scope_name = acpi_ns_get_external_pathname(node); 103 scope_name = acpi_ns_get_external_pathname(parent_node);
99 if (scope_name) { 104 if (scope_name) {
100 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, 105 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
101 "Searching %s (%p) For [%4.4s] (%s)\n", 106 "Searching %s (%p) For [%4.4s] (%s)\n",
102 scope_name, node, ACPI_CAST_PTR(char, 107 scope_name, parent_node,
103 &target_name), 108 ACPI_CAST_PTR(char, &target_name),
104 acpi_ut_get_type_name(type))); 109 acpi_ut_get_type_name(type)));
105 110
106 ACPI_FREE(scope_name); 111 ACPI_FREE(scope_name);
@@ -112,20 +117,20 @@ acpi_ns_search_node(u32 target_name,
112 * Search for name at this namespace level, which is to say that we 117 * Search for name at this namespace level, which is to say that we
113 * must search for the name among the children of this object 118 * must search for the name among the children of this object
114 */ 119 */
115 next_node = node->child; 120 node = parent_node->child;
116 while (next_node) { 121 while (node) {
117 122
118 /* Check for match against the name */ 123 /* Check for match against the name */
119 124
120 if (next_node->name.integer == target_name) { 125 if (node->name.integer == target_name) {
121 126
122 /* Resolve a control method alias if any */ 127 /* Resolve a control method alias if any */
123 128
124 if (acpi_ns_get_type(next_node) == 129 if (acpi_ns_get_type(node) ==
125 ACPI_TYPE_LOCAL_METHOD_ALIAS) { 130 ACPI_TYPE_LOCAL_METHOD_ALIAS) {
126 next_node = 131 node =
127 ACPI_CAST_PTR(struct acpi_namespace_node, 132 ACPI_CAST_PTR(struct acpi_namespace_node,
128 next_node->object); 133 node->object);
129 } 134 }
130 135
131 /* Found matching entry */ 136 /* Found matching entry */
@@ -133,12 +138,12 @@ acpi_ns_search_node(u32 target_name,
133 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, 138 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
134 "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", 139 "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
135 ACPI_CAST_PTR(char, &target_name), 140 ACPI_CAST_PTR(char, &target_name),
136 acpi_ut_get_type_name(next_node-> 141 acpi_ut_get_type_name(node->type),
137 type), 142 node,
138 next_node, 143 acpi_ut_get_node_name(parent_node),
139 acpi_ut_get_node_name(node), node)); 144 parent_node));
140 145
141 *return_node = next_node; 146 *return_node = node;
142 return_ACPI_STATUS(AE_OK); 147 return_ACPI_STATUS(AE_OK);
143 } 148 }
144 149
@@ -146,7 +151,7 @@ acpi_ns_search_node(u32 target_name,
146 * The last entry in the list points back to the parent, 151 * The last entry in the list points back to the parent,
147 * so a flag is used to indicate the end-of-list 152 * so a flag is used to indicate the end-of-list
148 */ 153 */
149 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { 154 if (node->flags & ANOBJ_END_OF_PEER_LIST) {
150 155
151 /* Searched entire list, we are done */ 156 /* Searched entire list, we are done */
152 157
@@ -155,7 +160,7 @@ acpi_ns_search_node(u32 target_name,
155 160
156 /* Didn't match name, move on to the next peer object */ 161 /* Didn't match name, move on to the next peer object */
157 162
158 next_node = next_node->peer; 163 node = node->peer;
159 } 164 }
160 165
161 /* Searched entire namespace level, not found */ 166 /* Searched entire namespace level, not found */
@@ -164,7 +169,8 @@ acpi_ns_search_node(u32 target_name,
164 "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", 169 "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
165 ACPI_CAST_PTR(char, &target_name), 170 ACPI_CAST_PTR(char, &target_name),
166 acpi_ut_get_type_name(type), 171 acpi_ut_get_type_name(type),
167 acpi_ut_get_node_name(node), node, node->child)); 172 acpi_ut_get_node_name(parent_node), parent_node,
173 parent_node->child));
168 174
169 return_ACPI_STATUS(AE_NOT_FOUND); 175 return_ACPI_STATUS(AE_NOT_FOUND);
170} 176}
@@ -181,14 +187,14 @@ acpi_ns_search_node(u32 target_name,
181 * RETURN: Status 187 * RETURN: Status
182 * 188 *
183 * DESCRIPTION: Called when a name has not been found in the current namespace 189 * DESCRIPTION: Called when a name has not been found in the current namespace
184 * level. Before adding it or giving up, ACPI scope rules require 190 * level. Before adding it or giving up, ACPI scope rules require
185 * searching enclosing scopes in cases identified by acpi_ns_local(). 191 * searching enclosing scopes in cases identified by acpi_ns_local().
186 * 192 *
187 * "A name is located by finding the matching name in the current 193 * "A name is located by finding the matching name in the current
188 * name space, and then in the parent name space. If the parent 194 * name space, and then in the parent name space. If the parent
189 * name space does not contain the name, the search continues 195 * name space does not contain the name, the search continues
190 * recursively until either the name is found or the name space 196 * recursively until either the name is found or the name space
191 * does not have a parent (the root of the name space). This 197 * does not have a parent (the root of the name space). This
192 * indicates that the name is not found" (From ACPI Specification, 198 * indicates that the name is not found" (From ACPI Specification,
193 * section 5.3) 199 * section 5.3)
194 * 200 *
@@ -237,11 +243,12 @@ acpi_ns_search_parent_tree(u32 target_name,
237 */ 243 */
238 while (parent_node) { 244 while (parent_node) {
239 /* 245 /*
240 * Search parent scope. Use TYPE_ANY because we don't care about the 246 * Search parent scope. Use TYPE_ANY because we don't care about the
241 * object type at this point, we only care about the existence of 247 * object type at this point, we only care about the existence of
242 * the actual name we are searching for. Typechecking comes later. 248 * the actual name we are searching for. Typechecking comes later.
243 */ 249 */
244 status = acpi_ns_search_node(target_name, parent_node, 250 status =
251 acpi_ns_search_one_scope(target_name, parent_node,
245 ACPI_TYPE_ANY, return_node); 252 ACPI_TYPE_ANY, return_node);
246 if (ACPI_SUCCESS(status)) { 253 if (ACPI_SUCCESS(status)) {
247 return_ACPI_STATUS(status); 254 return_ACPI_STATUS(status);
@@ -273,7 +280,7 @@ acpi_ns_search_parent_tree(u32 target_name,
273 * RETURN: Status 280 * RETURN: Status
274 * 281 *
275 * DESCRIPTION: Search for a name segment in a single namespace level, 282 * DESCRIPTION: Search for a name segment in a single namespace level,
276 * optionally adding it if it is not found. If the passed 283 * optionally adding it if it is not found. If the passed
277 * Type is not Any and the type previously stored in the 284 * Type is not Any and the type previously stored in the
278 * entry was Any (i.e. unknown), update the stored type. 285 * entry was Any (i.e. unknown), update the stored type.
279 * 286 *
@@ -332,7 +339,7 @@ acpi_ns_search_and_enter(u32 target_name,
332 /* Try to find the name in the namespace level specified by the caller */ 339 /* Try to find the name in the namespace level specified by the caller */
333 340
334 *return_node = ACPI_ENTRY_NOT_FOUND; 341 *return_node = ACPI_ENTRY_NOT_FOUND;
335 status = acpi_ns_search_node(target_name, node, type, return_node); 342 status = acpi_ns_search_one_scope(target_name, node, type, return_node);
336 if (status != AE_NOT_FOUND) { 343 if (status != AE_NOT_FOUND) {
337 /* 344 /*
338 * If we found it AND the request specifies that a find is an error, 345 * If we found it AND the request specifies that a find is an error,
@@ -348,10 +355,10 @@ acpi_ns_search_and_enter(u32 target_name,
348 } 355 }
349 356
350 /* 357 /*
351 * The name was not found. If we are NOT performing the first pass 358 * The name was not found. If we are NOT performing the first pass
352 * (name entry) of loading the namespace, search the parent tree (all the 359 * (name entry) of loading the namespace, search the parent tree (all the
353 * way to the root if necessary.) We don't want to perform the parent 360 * way to the root if necessary.) We don't want to perform the parent
354 * search when the namespace is actually being loaded. We want to perform 361 * search when the namespace is actually being loaded. We want to perform
355 * the search when namespace references are being resolved (load pass 2) 362 * the search when namespace references are being resolved (load pass 2)
356 * and during the execution phase. 363 * and during the execution phase.
357 */ 364 */
@@ -386,6 +393,9 @@ acpi_ns_search_and_enter(u32 target_name,
386 return_ACPI_STATUS(AE_NO_MEMORY); 393 return_ACPI_STATUS(AE_NO_MEMORY);
387 } 394 }
388#ifdef ACPI_ASL_COMPILER 395#ifdef ACPI_ASL_COMPILER
396 /*
397 * Node is an object defined by an External() statement
398 */
389 if (flags & ACPI_NS_EXTERNAL) { 399 if (flags & ACPI_NS_EXTERNAL) {
390 new_node->flags |= ANOBJ_IS_EXTERNAL; 400 new_node->flags |= ANOBJ_IS_EXTERNAL;
391 } 401 }