^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: nswalk - Functions for walking the ACPI namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define _COMPONENT ACPI_NAMESPACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ACPI_MODULE_NAME("nswalk")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * FUNCTION: acpi_ns_get_next_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * PARAMETERS: parent_node - Parent node whose children we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * getting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * child_node - Previous child that was found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * The NEXT child will be returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * none is found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * DESCRIPTION: Return the next peer node within the namespace. If Handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * is valid, Scope is ignored. Otherwise, the first node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * within Scope is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *parent_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct acpi_namespace_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *child_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (!child_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* It's really the parent's _scope_ that we want */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return (parent_node->child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Otherwise just return the next peer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return (child_node->peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * FUNCTION: acpi_ns_get_next_node_typed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * PARAMETERS: type - Type of node to be searched for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * parent_node - Parent node whose children we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * getting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * child_node - Previous child that was found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * The NEXT child will be returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * none is found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * DESCRIPTION: Return the next peer node within the namespace. If Handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * is valid, Scope is ignored. Otherwise, the first node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * within Scope is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) acpi_namespace_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *parent_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) acpi_namespace_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *child_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct acpi_namespace_node *next_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) next_node = acpi_ns_get_next_node(parent_node, child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* If any type is OK, we are done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (type == ACPI_TYPE_ANY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* next_node is NULL if we are at the end-of-list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return (next_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Must search for the node -- but within this scope only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) while (next_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* If type matches, we are done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (next_node->type == type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return (next_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Otherwise, move on to the next peer node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) next_node = next_node->peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * FUNCTION: acpi_ns_walk_namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * PARAMETERS: type - acpi_object_type to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * start_node - Handle in namespace where search begins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * max_depth - Depth to which search is to reach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * flags - Whether to unlock the NS before invoking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * the callback routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * descending_callback - Called during tree descent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * when an object of "Type" is found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * ascending_callback - Called during tree ascent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * when an object of "Type" is found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * context - Passed to user function(s) above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * return_value - from the user_function if terminated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * early. Otherwise, returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * RETURNS: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * starting (and ending) at the node specified by start_handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * The callback function is called whenever a node that matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * the type parameter is found. If the callback function returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * a non-zero value, the search is terminated immediately and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * this value is returned to the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * The point of this procedure is to provide a generic namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * walk routine that can be called from multiple places to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * provide multiple services; the callback function(s) can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * tailored to each task, whether it is a print function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * a compare function, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) acpi_ns_walk_namespace(acpi_object_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) acpi_handle start_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u32 max_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u32 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) acpi_walk_callback descending_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) acpi_walk_callback ascending_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) void *context, void **return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) acpi_status mutex_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct acpi_namespace_node *child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct acpi_namespace_node *parent_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) acpi_object_type child_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u32 level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 node_previously_visited = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ACPI_FUNCTION_TRACE(ns_walk_namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Special case for the namespace Root Node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (start_node == ACPI_ROOT_OBJECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) start_node = acpi_gbl_root_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (!start_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return_ACPI_STATUS(AE_NO_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Null child means "get first node" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) parent_node = start_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) child_node = acpi_ns_get_next_node(parent_node, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) child_type = ACPI_TYPE_ANY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Traverse the tree of nodes until we bubble back up to where we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * started. When Level is zero, the loop is done because we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * bubbled up to (and passed) the original parent handle (start_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) while (level > 0 && child_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Found next child, get the type if we are not searching for ANY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (type != ACPI_TYPE_ANY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) child_type = child_node->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * Ignore all temporary namespace nodes (created during control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * method execution) unless told otherwise. These temporary nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * can cause a race condition because they can be deleted during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * the execution of the user function (if the namespace is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * unlocked before invocation of the user function.) Only the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * debugger namespace dump will examine the temporary nodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if ((child_node->flags & ANOBJ_TEMPORARY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) !(flags & ACPI_NS_WALK_TEMP_NODES)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) status = AE_CTRL_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Type must match requested type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) else if (child_type == type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Found a matching node, invoke the user callback function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Unlock the namespace if flag is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (flags & ACPI_NS_WALK_UNLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) mutex_status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ACPI_FAILURE(mutex_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return_ACPI_STATUS(mutex_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * Invoke the user function, either descending, ascending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * or both.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!node_previously_visited) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (descending_callback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) descending_callback(child_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) level, context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ascending_callback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ascending_callback(child_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) level, context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (flags & ACPI_NS_WALK_UNLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mutex_status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (ACPI_FAILURE(mutex_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return_ACPI_STATUS(mutex_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case AE_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case AE_CTRL_DEPTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Just keep going */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case AE_CTRL_TERMINATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Exit now, with OK status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* All others are valid exceptions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Depth first search: Attempt to go down another level in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * namespace if we are allowed to. Don't go any further if we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * reached the caller specified maximum depth or if the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * function has specified that the maximum depth has been reached.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (!node_previously_visited &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) (level < max_depth) && (status != AE_CTRL_DEPTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (child_node->child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* There is at least one child of this node, visit it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) level++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) parent_node = child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) child_node =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) acpi_ns_get_next_node(parent_node, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* No more children, re-visit this node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!node_previously_visited) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) node_previously_visited = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* No more children, visit peers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) child_node = acpi_ns_get_next_node(parent_node, child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (child_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) node_previously_visited = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* No peers, re-visit parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * No more children of this node (acpi_ns_get_next_node failed), go
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * back upwards in the namespace tree to the node's parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) level--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) child_node = parent_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) parent_node = parent_node->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) node_previously_visited = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Complete walk, not terminated by user function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }