]> err.no Git - linux-2.6/blobdiff - drivers/acpi/namespace/nswalk.c
Merge branch 'for-2.6.21' of master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[linux-2.6] / drivers / acpi / namespace / nswalk.c
index f9a7277dca6ea916490038997eeab5a00a325cf5..94eb8f332d941bb67a0175e85f17d4560ecd4f4d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
-
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 
-
 #define _COMPONENT          ACPI_NAMESPACE
-        ACPI_MODULE_NAME    ("nswalk")
-
+ACPI_MODULE_NAME("nswalk")
 
 /*******************************************************************************
  *
  *              within Scope is returned.
  *
  ******************************************************************************/
-
-struct acpi_namespace_node *
-acpi_ns_get_next_node (
-       acpi_object_type                type,
-       struct acpi_namespace_node      *parent_node,
-       struct acpi_namespace_node      *child_node)
+struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type,
+                                                 struct acpi_namespace_node
+                                                 *parent_node,
+                                                 struct acpi_namespace_node
+                                                 *child_node)
 {
-       struct acpi_namespace_node      *next_node = NULL;
-
-
-       ACPI_FUNCTION_ENTRY ();
+       struct acpi_namespace_node *next_node = NULL;
 
+       ACPI_FUNCTION_ENTRY();
 
        if (!child_node) {
+
                /* It's really the parent's _scope_ that we want */
 
                if (parent_node->child) {
@@ -92,12 +87,13 @@ acpi_ns_get_next_node (
        else {
                /* Start search at the NEXT node */
 
-               next_node = acpi_ns_get_next_valid_node (child_node);
+               next_node = acpi_ns_get_next_valid_node(child_node);
        }
 
        /* If any type is OK, we are done */
 
        if (type == ACPI_TYPE_ANY) {
+
                /* next_node is NULL if we are at the end-of-list */
 
                return (next_node);
@@ -106,6 +102,7 @@ acpi_ns_get_next_node (
        /* Must search for the node -- but within this scope only */
 
        while (next_node) {
+
                /* If type matches, we are done */
 
                if (next_node->type == type) {
@@ -114,7 +111,7 @@ acpi_ns_get_next_node (
 
                /* Otherwise, move on to the next node */
 
-               next_node = acpi_ns_get_next_valid_node (next_node);
+               next_node = acpi_ns_get_next_valid_node(next_node);
        }
 
        /* Not found */
@@ -122,7 +119,6 @@ acpi_ns_get_next_node (
        return (NULL);
 }
 
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_walk_namespace
@@ -130,7 +126,7 @@ acpi_ns_get_next_node (
  * PARAMETERS:  Type                - acpi_object_type to search for
  *              start_node          - Handle in namespace where search begins
  *              max_depth           - Depth to which search is to reach
- *              unlock_before_callback- Whether to unlock the NS before invoking
+ *              Flags               - Whether to unlock the NS before invoking
  *                                    the callback routine
  *              user_function       - Called when an object of "Type" is found
  *              Context             - Passed to user function
@@ -154,25 +150,21 @@ acpi_ns_get_next_node (
  ******************************************************************************/
 
 acpi_status
-acpi_ns_walk_namespace (
-       acpi_object_type                type,
-       acpi_handle                     start_node,
-       u32                             max_depth,
-       u8                              unlock_before_callback,
-       acpi_walk_callback              user_function,
-       void                            *context,
-       void                            **return_value)
+acpi_ns_walk_namespace(acpi_object_type type,
+                      acpi_handle start_node,
+                      u32 max_depth,
+                      u32 flags,
+                      acpi_walk_callback user_function,
+                      void *context, void **return_value)
 {
-       acpi_status                     status;
-       acpi_status                     mutex_status;
-       struct acpi_namespace_node      *child_node;
-       struct acpi_namespace_node      *parent_node;
-       acpi_object_type                child_type;
-       u32                             level;
-
-
-       ACPI_FUNCTION_TRACE ("ns_walk_namespace");
+       acpi_status status;
+       acpi_status mutex_status;
+       struct acpi_namespace_node *child_node;
+       struct acpi_namespace_node *parent_node;
+       acpi_object_type child_type;
+       u32 level;
 
+       ACPI_FUNCTION_TRACE(ns_walk_namespace);
 
        /* Special case for the namespace Root Node */
 
@@ -183,9 +175,9 @@ acpi_ns_walk_namespace (
        /* Null child means "get first node" */
 
        parent_node = start_node;
-       child_node  = NULL;
-       child_type  = ACPI_TYPE_ANY;
-       level       = 1;
+       child_node = NULL;
+       child_type = ACPI_TYPE_ANY;
+       level = 1;
 
        /*
         * Traverse the tree of nodes until we bubble back up to where we
@@ -193,38 +185,62 @@ acpi_ns_walk_namespace (
         * bubbled up to (and passed) the original parent handle (start_entry)
         */
        while (level > 0) {
+
                /* Get the next node in this scope.  Null if not found */
 
                status = AE_OK;
-               child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node);
+               child_node =
+                   acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
+                                         child_node);
                if (child_node) {
-                       /*
-                        * Found node, Get the type if we are not
-                        * searching for ANY
-                        */
+
+                       /* Found next child, get the type if we are not searching for ANY */
+
                        if (type != ACPI_TYPE_ANY) {
                                child_type = child_node->type;
                        }
 
-                       if (child_type == type) {
+                       /*
+                        * Ignore all temporary namespace nodes (created during control
+                        * method execution) unless told otherwise. These temporary nodes
+                        * can cause a race condition because they can be deleted during the
+                        * execution of the user function (if the namespace is unlocked before
+                        * invocation of the user function.) Only the debugger namespace dump
+                        * will examine the temporary nodes.
+                        */
+                       if ((child_node->flags & ANOBJ_TEMPORARY) &&
+                           !(flags & ACPI_NS_WALK_TEMP_NODES)) {
+                               status = AE_CTRL_DEPTH;
+                       }
+
+                       /* Type must match requested type */
+
+                       else if (child_type == type) {
                                /*
-                                * Found a matching node, invoke the user
-                                * callback function
+                                * Found a matching node, invoke the user callback function.
+                                * Unlock the namespace if flag is set.
                                 */
-                               if (unlock_before_callback) {
-                                       mutex_status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE (mutex_status)) {
-                                               return_ACPI_STATUS (mutex_status);
+                               if (flags & ACPI_NS_WALK_UNLOCK) {
+                                       mutex_status =
+                                           acpi_ut_release_mutex
+                                           (ACPI_MTX_NAMESPACE);
+                                       if (ACPI_FAILURE(mutex_status)) {
+                                               return_ACPI_STATUS
+                                                   (mutex_status);
                                        }
                                }
 
-                               status = user_function (child_node, level,
-                                                context, return_value);
-
-                               if (unlock_before_callback) {
-                                       mutex_status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE (mutex_status)) {
-                                               return_ACPI_STATUS (mutex_status);
+                               status =
+                                   user_function(child_node, level, context,
+                                                 return_value);
+
+                               if (flags & ACPI_NS_WALK_UNLOCK) {
+                                       mutex_status =
+                                           acpi_ut_acquire_mutex
+                                           (ACPI_MTX_NAMESPACE);
+                                       if (ACPI_FAILURE(mutex_status)) {
+                                               return_ACPI_STATUS
+                                                   (mutex_status);
                                        }
                                }
 
@@ -239,51 +255,45 @@ acpi_ns_walk_namespace (
 
                                        /* Exit now, with OK status */
 
-                                       return_ACPI_STATUS (AE_OK);
+                                       return_ACPI_STATUS(AE_OK);
 
                                default:
 
                                        /* All others are valid exceptions */
 
-                                       return_ACPI_STATUS (status);
+                                       return_ACPI_STATUS(status);
                                }
                        }
 
                        /*
-                        * Depth first search:
-                        * Attempt to go down another level in the namespace
-                        * if we are allowed to.  Don't go any further if we
-                        * have reached the caller specified maximum depth
-                        * or if the user function has specified that the
-                        * maximum depth has been reached.
+                        * Depth first search: Attempt to go down another level in the
+                        * namespace if we are allowed to.  Don't go any further if we have
+                        * reached the caller specified maximum depth or if the user
+                        * function has specified that the maximum depth has been reached.
                         */
                        if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
-                               if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) {
-                                       /*
-                                        * There is at least one child of this
-                                        * node, visit the onde
-                                        */
+                               if (acpi_ns_get_next_node
+                                   (ACPI_TYPE_ANY, child_node, NULL)) {
+
+                                       /* There is at least one child of this node, visit it */
+
                                        level++;
                                        parent_node = child_node;
                                        child_node = NULL;
                                }
                        }
-               }
-               else {
+               } else {
                        /*
-                        * No more children of this node (acpi_ns_get_next_node
-                        * failed), go back upwards in the namespace tree to
-                        * the node's parent.
+                        * No more children of this node (acpi_ns_get_next_node failed), go
+                        * back upwards in the namespace tree to the node's parent.
                         */
                        level--;
                        child_node = parent_node;
-                       parent_node = acpi_ns_get_parent_node (parent_node);
+                       parent_node = acpi_ns_get_parent_node(parent_node);
                }
        }
 
        /* Complete walk, not terminated by user function */
 
-       return_ACPI_STATUS (AE_OK);
+       return_ACPI_STATUS(AE_OK);
 }
-
-