aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2009-11-12 21:06:08 -0500
committerLen Brown <len.brown@intel.com>2009-11-24 21:31:10 -0500
commit2263576cfc6e8f6ab038126c3254404b9fcb1c33 (patch)
tree1c1bd06cc5d89978a23a19d549764d3dc8c7c6c4 /drivers/acpi/acpica
parent7d5d05d0704127c9acd24090c14731c111bd0af1 (diff)
ACPICA: Add post-order callback to acpi_walk_namespace
The existing interface only has a pre-order callback. This change adds an additional parameter for a post-order callback which will be more useful for bus scans. ACPICA BZ 779. Also update the external calls to acpi_walk_namespace. http://www.acpica.org/bugzilla/show_bug.cgi?id=779 Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r--drivers/acpi/acpica/acnamesp.h3
-rw-r--r--drivers/acpi/acpica/dsinit.c2
-rw-r--r--drivers/acpi/acpica/evgpeblk.c8
-rw-r--r--drivers/acpi/acpica/evregion.c6
-rw-r--r--drivers/acpi/acpica/nsdump.c4
-rw-r--r--drivers/acpi/acpica/nsdumpdv.c3
-rw-r--r--drivers/acpi/acpica/nsinit.c8
-rw-r--r--drivers/acpi/acpica/nswalk.c200
-rw-r--r--drivers/acpi/acpica/nsxfeval.c32
9 files changed, 155 insertions, 111 deletions
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index 09a2764c734b..168e60893a2a 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -104,7 +104,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
104 acpi_handle start_object, 104 acpi_handle start_object,
105 u32 max_depth, 105 u32 max_depth,
106 u32 flags, 106 u32 flags,
107 acpi_walk_callback user_function, 107 acpi_walk_callback pre_order_visit,
108 acpi_walk_callback post_order_visit,
108 void *context, void **return_value); 109 void *context, void **return_value);
109 110
110struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node 111struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index 3aae13f30c5e..f23fa0be6fc2 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -192,7 +192,7 @@ acpi_ds_initialize_objects(u32 table_index,
192 status = 192 status =
193 acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, 193 acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
194 ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object, 194 ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
195 &info, NULL); 195 NULL, &info, NULL);
196 if (ACPI_FAILURE(status)) { 196 if (ACPI_FAILURE(status)) {
197 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); 197 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
198 } 198 }
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index a60aaa7635f3..247920900187 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -945,8 +945,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
945 945
946 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, 946 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
947 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, 947 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
948 acpi_ev_save_method_info, gpe_block, 948 acpi_ev_save_method_info, NULL,
949 NULL); 949 gpe_block, NULL);
950 950
951 /* Return the new block */ 951 /* Return the new block */
952 952
@@ -1022,8 +1022,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
1022 status = 1022 status =
1023 acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1023 acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1024 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 1024 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1025 acpi_ev_match_prw_and_gpe, &gpe_info, 1025 acpi_ev_match_prw_and_gpe, NULL,
1026 NULL); 1026 &gpe_info, NULL);
1027 } 1027 }
1028 1028
1029 /* 1029 /*
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index c9fa040725d4..582b0af01e99 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -1025,8 +1025,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node,
1025 */ 1025 */
1026 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, 1026 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1027 ACPI_NS_WALK_UNLOCK, 1027 ACPI_NS_WALK_UNLOCK,
1028 acpi_ev_install_handler, handler_obj, 1028 acpi_ev_install_handler, NULL,
1029 NULL); 1029 handler_obj, NULL);
1030 1030
1031 unlock_and_exit: 1031 unlock_and_exit:
1032 return_ACPI_STATUS(status); 1032 return_ACPI_STATUS(status);
@@ -1062,7 +1062,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
1062 */ 1062 */
1063 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, 1063 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1064 ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, 1064 ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
1065 &space_id, NULL); 1065 NULL, &space_id, NULL);
1066 1066
1067 return_ACPI_STATUS(status); 1067 return_ACPI_STATUS(status);
1068} 1068}
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 2bad613db73a..2deb986861ca 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -634,8 +634,8 @@ acpi_ns_dump_objects(acpi_object_type type,
634 (void)acpi_ns_walk_namespace(type, start_handle, max_depth, 634 (void)acpi_ns_walk_namespace(type, start_handle, max_depth,
635 ACPI_NS_WALK_NO_UNLOCK | 635 ACPI_NS_WALK_NO_UNLOCK |
636 ACPI_NS_WALK_TEMP_NODES, 636 ACPI_NS_WALK_TEMP_NODES,
637 acpi_ns_dump_one_object, (void *)&info, 637 acpi_ns_dump_one_object, NULL,
638 NULL); 638 (void *)&info, NULL);
639} 639}
640#endif /* ACPI_FUTURE_USAGE */ 640#endif /* ACPI_FUTURE_USAGE */
641 641
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c
index 0fe87f1aef16..36be7f0e97ec 100644
--- a/drivers/acpi/acpica/nsdumpdv.c
+++ b/drivers/acpi/acpica/nsdumpdv.c
@@ -131,7 +131,8 @@ void acpi_ns_dump_root_devices(void)
131 131
132 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle, 132 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle,
133 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, 133 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
134 acpi_ns_dump_one_device, NULL, NULL); 134 acpi_ns_dump_one_device, NULL, NULL,
135 NULL);
135} 136}
136 137
137#endif 138#endif
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 1d5b360eb25b..4f8abac231d2 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -96,7 +96,7 @@ acpi_status acpi_ns_initialize_objects(void)
96 /* Walk entire namespace from the supplied root */ 96 /* Walk entire namespace from the supplied root */
97 97
98 status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 98 status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
99 ACPI_UINT32_MAX, acpi_ns_init_one_object, 99 ACPI_UINT32_MAX, acpi_ns_init_one_object, NULL,
100 &info, NULL); 100 &info, NULL);
101 if (ACPI_FAILURE(status)) { 101 if (ACPI_FAILURE(status)) {
102 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); 102 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
@@ -156,7 +156,8 @@ acpi_status acpi_ns_initialize_devices(void)
156 156
157 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 157 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
158 ACPI_UINT32_MAX, FALSE, 158 ACPI_UINT32_MAX, FALSE,
159 acpi_ns_find_ini_methods, &info, NULL); 159 acpi_ns_find_ini_methods, NULL, &info,
160 NULL);
160 if (ACPI_FAILURE(status)) { 161 if (ACPI_FAILURE(status)) {
161 goto error_exit; 162 goto error_exit;
162 } 163 }
@@ -189,7 +190,8 @@ acpi_status acpi_ns_initialize_devices(void)
189 190
190 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 191 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
191 ACPI_UINT32_MAX, FALSE, 192 ACPI_UINT32_MAX, FALSE,
192 acpi_ns_init_one_device, &info, NULL); 193 acpi_ns_init_one_device, NULL, &info,
194 NULL);
193 195
194 ACPI_FREE(info.evaluate_info); 196 ACPI_FREE(info.evaluate_info);
195 if (ACPI_FAILURE(status)) { 197 if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 35539df5c75d..d7e6b52b4482 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -165,24 +165,27 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
165 * max_depth - Depth to which search is to reach 165 * max_depth - Depth to which search is to reach
166 * Flags - Whether to unlock the NS before invoking 166 * Flags - Whether to unlock the NS before invoking
167 * the callback routine 167 * the callback routine
168 * user_function - Called when an object of "Type" is found 168 * pre_order_visit - Called during tree pre-order visit
169 * Context - Passed to user function 169 * when an object of "Type" is found
170 * return_value - from the user_function if terminated early. 170 * post_order_visit - Called during tree post-order visit
171 * Otherwise, returns NULL. 171 * when an object of "Type" is found
172 * Context - Passed to user function(s) above
173 * return_value - from the user_function if terminated
174 * early. Otherwise, returns NULL.
172 * RETURNS: Status 175 * RETURNS: Status
173 * 176 *
174 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 177 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
175 * starting (and ending) at the node specified by start_handle. 178 * starting (and ending) at the node specified by start_handle.
176 * The user_function is called whenever a node that matches 179 * The callback function is called whenever a node that matches
177 * the type parameter is found. If the user function returns 180 * the type parameter is found. If the callback function returns
178 * a non-zero value, the search is terminated immediately and 181 * a non-zero value, the search is terminated immediately and
179 * this value is returned to the caller. 182 * this value is returned to the caller.
180 * 183 *
181 * The point of this procedure is to provide a generic namespace 184 * The point of this procedure is to provide a generic namespace
182 * walk routine that can be called from multiple places to 185 * walk routine that can be called from multiple places to
183 * provide multiple services; the User Function can be tailored 186 * provide multiple services; the callback function(s) can be
184 * to each task, whether it is a print function, a compare 187 * tailored to each task, whether it is a print function,
185 * function, etc. 188 * a compare function, etc.
186 * 189 *
187 ******************************************************************************/ 190 ******************************************************************************/
188 191
@@ -191,7 +194,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
191 acpi_handle start_node, 194 acpi_handle start_node,
192 u32 max_depth, 195 u32 max_depth,
193 u32 flags, 196 u32 flags,
194 acpi_walk_callback user_function, 197 acpi_walk_callback pre_order_visit,
198 acpi_walk_callback post_order_visit,
195 void *context, void **return_value) 199 void *context, void **return_value)
196{ 200{
197 acpi_status status; 201 acpi_status status;
@@ -200,6 +204,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
200 struct acpi_namespace_node *parent_node; 204 struct acpi_namespace_node *parent_node;
201 acpi_object_type child_type; 205 acpi_object_type child_type;
202 u32 level; 206 u32 level;
207 u8 node_previously_visited = FALSE;
203 208
204 ACPI_FUNCTION_TRACE(ns_walk_namespace); 209 ACPI_FUNCTION_TRACE(ns_walk_namespace);
205 210
@@ -212,7 +217,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
212 /* Null child means "get first node" */ 217 /* Null child means "get first node" */
213 218
214 parent_node = start_node; 219 parent_node = start_node;
215 child_node = NULL; 220 child_node = acpi_ns_get_next_node(parent_node, NULL);
216 child_type = ACPI_TYPE_ANY; 221 child_type = ACPI_TYPE_ANY;
217 level = 1; 222 level = 1;
218 223
@@ -221,102 +226,129 @@ acpi_ns_walk_namespace(acpi_object_type type,
221 * started. When Level is zero, the loop is done because we have 226 * started. When Level is zero, the loop is done because we have
222 * bubbled up to (and passed) the original parent handle (start_entry) 227 * bubbled up to (and passed) the original parent handle (start_entry)
223 */ 228 */
224 while (level > 0) { 229 while (level > 0 && child_node) {
230 status = AE_OK;
225 231
226 /* Get the next node in this scope. Null if not found */ 232 /* Found next child, get the type if we are not searching for ANY */
227 233
228 status = AE_OK; 234 if (type != ACPI_TYPE_ANY) {
229 child_node = acpi_ns_get_next_node(parent_node, child_node); 235 child_type = child_node->type;
230 if (child_node) { 236 }
231 237
232 /* Found next child, get the type if we are not searching for ANY */ 238 /*
239 * Ignore all temporary namespace nodes (created during control
240 * method execution) unless told otherwise. These temporary nodes
241 * can cause a race condition because they can be deleted during
242 * the execution of the user function (if the namespace is
243 * unlocked before invocation of the user function.) Only the
244 * debugger namespace dump will examine the temporary nodes.
245 */
246 if ((child_node->flags & ANOBJ_TEMPORARY) &&
247 !(flags & ACPI_NS_WALK_TEMP_NODES)) {
248 status = AE_CTRL_DEPTH;
249 }
233 250
234 if (type != ACPI_TYPE_ANY) { 251 /* Type must match requested type */
235 child_type = child_node->type;
236 }
237 252
253 else if (child_type == type) {
238 /* 254 /*
239 * Ignore all temporary namespace nodes (created during control 255 * Found a matching node, invoke the user callback function.
240 * method execution) unless told otherwise. These temporary nodes 256 * Unlock the namespace if flag is set.
241 * can cause a race condition because they can be deleted during
242 * the execution of the user function (if the namespace is
243 * unlocked before invocation of the user function.) Only the
244 * debugger namespace dump will examine the temporary nodes.
245 */ 257 */
246 if ((child_node->flags & ANOBJ_TEMPORARY) && 258 if (flags & ACPI_NS_WALK_UNLOCK) {
247 !(flags & ACPI_NS_WALK_TEMP_NODES)) { 259 mutex_status =
248 status = AE_CTRL_DEPTH; 260 acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
261 if (ACPI_FAILURE(mutex_status)) {
262 return_ACPI_STATUS(mutex_status);
263 }
249 } 264 }
250 265
251 /* Type must match requested type */ 266 /*
252 267 * Invoke the user function, either pre-order or post-order
253 else if (child_type == type) { 268 * or both.
254 /* 269 */
255 * Found a matching node, invoke the user callback function. 270 if (!node_previously_visited) {
256 * Unlock the namespace if flag is set. 271 if (pre_order_visit) {
257 */ 272 status =
258 if (flags & ACPI_NS_WALK_UNLOCK) { 273 pre_order_visit(child_node, level,
259 mutex_status = 274 context,
260 acpi_ut_release_mutex 275 return_value);
261 (ACPI_MTX_NAMESPACE);
262 if (ACPI_FAILURE(mutex_status)) {
263 return_ACPI_STATUS
264 (mutex_status);
265 }
266 } 276 }
277 } else {
278 if (post_order_visit) {
279 status =
280 post_order_visit(child_node, level,
281 context,
282 return_value);
283 }
284 }
267 285
268 status = 286 if (flags & ACPI_NS_WALK_UNLOCK) {
269 user_function(child_node, level, context, 287 mutex_status =
270 return_value); 288 acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
271 289 if (ACPI_FAILURE(mutex_status)) {
272 if (flags & ACPI_NS_WALK_UNLOCK) { 290 return_ACPI_STATUS(mutex_status);
273 mutex_status =
274 acpi_ut_acquire_mutex
275 (ACPI_MTX_NAMESPACE);
276 if (ACPI_FAILURE(mutex_status)) {
277 return_ACPI_STATUS
278 (mutex_status);
279 }
280 } 291 }
292 }
281 293
282 switch (status) { 294 switch (status) {
283 case AE_OK: 295 case AE_OK:
284 case AE_CTRL_DEPTH: 296 case AE_CTRL_DEPTH:
285 297
286 /* Just keep going */ 298 /* Just keep going */
287 break; 299 break;
288 300
289 case AE_CTRL_TERMINATE: 301 case AE_CTRL_TERMINATE:
290 302
291 /* Exit now, with OK status */ 303 /* Exit now, with OK status */
292 304
293 return_ACPI_STATUS(AE_OK); 305 return_ACPI_STATUS(AE_OK);
294 306
295 default: 307 default:
296 308
297 /* All others are valid exceptions */ 309 /* All others are valid exceptions */
298 310
299 return_ACPI_STATUS(status); 311 return_ACPI_STATUS(status);
300 } 312 }
313 }
314
315 /*
316 * Depth first search: Attempt to go down another level in the
317 * namespace if we are allowed to. Don't go any further if we have
318 * reached the caller specified maximum depth or if the user
319 * function has specified that the maximum depth has been reached.
320 */
321 if (!node_previously_visited &&
322 (level < max_depth) && (status != AE_CTRL_DEPTH)) {
323 if (child_node->child) {
324
325 /* There is at least one child of this node, visit it */
326
327 level++;
328 parent_node = child_node;
329 child_node =
330 acpi_ns_get_next_node(parent_node, NULL);
331 continue;
301 } 332 }
333 }
302 334
303 /* 335 /* No more children, re-visit this node */
304 * Depth first search: Attempt to go down another level in the
305 * namespace if we are allowed to. Don't go any further if we have
306 * reached the caller specified maximum depth or if the user
307 * function has specified that the maximum depth has been reached.
308 */
309 if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
310 if (child_node->child) {
311 336
312 /* There is at least one child of this node, visit it */ 337 if (!node_previously_visited) {
338 node_previously_visited = TRUE;
339 continue;
340 }
313 341
314 level++; 342 /* No more children, visit peers */
315 parent_node = child_node; 343
316 child_node = NULL; 344 child_node = acpi_ns_get_next_node(parent_node, child_node);
317 } 345 if (child_node) {
318 } 346 node_previously_visited = FALSE;
319 } else { 347 }
348
349 /* No peers, re-visit parent */
350
351 else {
320 /* 352 /*
321 * No more children of this node (acpi_ns_get_next_node failed), go 353 * No more children of this node (acpi_ns_get_next_node failed), go
322 * back upwards in the namespace tree to the node's parent. 354 * back upwards in the namespace tree to the node's parent.
@@ -324,6 +356,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
324 level--; 356 level--;
325 child_node = parent_node; 357 child_node = parent_node;
326 parent_node = acpi_ns_get_parent_node(parent_node); 358 parent_node = acpi_ns_get_parent_node(parent_node);
359
360 node_previously_visited = TRUE;
327 } 361 }
328 } 362 }
329 363
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 4929dbdbc8f0..f2bd1da77001 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -433,8 +433,11 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
433 * PARAMETERS: Type - acpi_object_type to search for 433 * PARAMETERS: Type - acpi_object_type to search for
434 * start_object - Handle in namespace where search begins 434 * start_object - Handle in namespace where search begins
435 * max_depth - Depth to which search is to reach 435 * max_depth - Depth to which search is to reach
436 * user_function - Called when an object of "Type" is found 436 * pre_order_visit - Called during tree pre-order visit
437 * Context - Passed to user function 437 * when an object of "Type" is found
438 * post_order_visit - Called during tree post-order visit
439 * when an object of "Type" is found
440 * Context - Passed to user function(s) above
438 * return_value - Location where return value of 441 * return_value - Location where return value of
439 * user_function is put if terminated early 442 * user_function is put if terminated early
440 * 443 *
@@ -443,16 +446,16 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
443 * 446 *
444 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 447 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
445 * starting (and ending) at the object specified by start_handle. 448 * starting (and ending) at the object specified by start_handle.
446 * The user_function is called whenever an object that matches 449 * The callback function is called whenever an object that matches
447 * the type parameter is found. If the user function returns 450 * the type parameter is found. If the callback function returns
448 * a non-zero value, the search is terminated immediately and this 451 * a non-zero value, the search is terminated immediately and this
449 * value is returned to the caller. 452 * value is returned to the caller.
450 * 453 *
451 * The point of this procedure is to provide a generic namespace 454 * The point of this procedure is to provide a generic namespace
452 * walk routine that can be called from multiple places to 455 * walk routine that can be called from multiple places to
453 * provide multiple services; the User Function can be tailored 456 * provide multiple services; the callback function(s) can be
454 * to each task, whether it is a print function, a compare 457 * tailored to each task, whether it is a print function,
455 * function, etc. 458 * a compare function, etc.
456 * 459 *
457 ******************************************************************************/ 460 ******************************************************************************/
458 461
@@ -460,7 +463,8 @@ acpi_status
460acpi_walk_namespace(acpi_object_type type, 463acpi_walk_namespace(acpi_object_type type,
461 acpi_handle start_object, 464 acpi_handle start_object,
462 u32 max_depth, 465 u32 max_depth,
463 acpi_walk_callback user_function, 466 acpi_walk_callback pre_order_visit,
467 acpi_walk_callback post_order_visit,
464 void *context, void **return_value) 468 void *context, void **return_value)
465{ 469{
466 acpi_status status; 470 acpi_status status;
@@ -469,7 +473,8 @@ acpi_walk_namespace(acpi_object_type type,
469 473
470 /* Parameter validation */ 474 /* Parameter validation */
471 475
472 if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) { 476 if ((type > ACPI_TYPE_LOCAL_MAX) ||
477 (!max_depth) || (!pre_order_visit && !post_order_visit)) {
473 return_ACPI_STATUS(AE_BAD_PARAMETER); 478 return_ACPI_STATUS(AE_BAD_PARAMETER);
474 } 479 }
475 480
@@ -501,8 +506,9 @@ acpi_walk_namespace(acpi_object_type type,
501 } 506 }
502 507
503 status = acpi_ns_walk_namespace(type, start_object, max_depth, 508 status = acpi_ns_walk_namespace(type, start_object, max_depth,
504 ACPI_NS_WALK_UNLOCK, user_function, 509 ACPI_NS_WALK_UNLOCK, pre_order_visit,
505 context, return_value); 510 post_order_visit, context,
511 return_value);
506 512
507 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 513 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
508 514
@@ -681,8 +687,8 @@ acpi_get_devices(const char *HID,
681 687
682 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 688 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
683 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 689 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
684 acpi_ns_get_device_callback, &info, 690 acpi_ns_get_device_callback, NULL,
685 return_value); 691 &info, return_value);
686 692
687 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 693 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
688 return_ACPI_STATUS(status); 694 return_ACPI_STATUS(status);