diff options
author | Bob Moore <robert.moore@intel.com> | 2006-05-26 16:36:00 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-06-14 02:44:35 -0400 |
commit | 4119532c95547821dbe72d6916dfa1b2148475b3 (patch) | |
tree | 564eb8f69924fb7dc72e93526faf1547acac7d30 /drivers/acpi/namespace/nssearch.c | |
parent | b8d35192c55fb055792ff0641408eaaec7c88988 (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.c | 82 |
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 | ||
84 | acpi_status | 89 | acpi_status |
85 | acpi_ns_search_node(u32 target_name, | 90 | acpi_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 | } |