^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: nssearch - Namespace search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #ifdef ACPI_ASL_COMPILER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "amlcode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define _COMPONENT ACPI_NAMESPACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) ACPI_MODULE_NAME("nssearch")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) acpi_ns_search_parent_tree(u32 target_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct acpi_namespace_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) acpi_object_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct acpi_namespace_node **return_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * FUNCTION: acpi_ns_search_one_scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * PARAMETERS: target_name - Ascii ACPI name to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * parent_node - Starting node where search will begin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * type - Object type to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * return_node - Where the matched Named obj is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * DESCRIPTION: Search a single level of the namespace. Performs a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * simple search of the specified level, and does not add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * entries or search parents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Named object lists are built (and subsequently dumped) in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * order in which the names are encountered during the namespace load;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * All namespace searching is linear in this implementation, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * could be easily modified to support any improved search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * algorithm. However, the linear search was chosen for simplicity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * and because the trees are small and the other interpreter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * execution overhead is relatively high.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Note: CPU execution analysis has shown that the AML interpreter spends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * a very small percentage of its time searching the namespace. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * the linear search seems to be sufficient, as there would seem to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * little value in improving the search.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) acpi_ns_search_one_scope(u32 target_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct acpi_namespace_node *parent_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) acpi_object_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct acpi_namespace_node **return_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct acpi_namespace_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ACPI_FUNCTION_TRACE(ns_search_one_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #ifdef ACPI_DEBUG_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (ACPI_LV_NAMES & acpi_dbg_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) char *scope_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) scope_name = acpi_ns_get_normalized_pathname(parent_node, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (scope_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) "Searching %s (%p) For [%4.4s] (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) scope_name, parent_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ACPI_CAST_PTR(char, &target_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) acpi_ut_get_type_name(type)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ACPI_FREE(scope_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * Search for name at this namespace level, which is to say that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * must search for the name among the children of this object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) node = parent_node->child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) while (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Check for match against the name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (node->name.integer == target_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Resolve a control method alias if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (acpi_ns_get_type(node) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ACPI_TYPE_LOCAL_METHOD_ALIAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) node =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ACPI_CAST_PTR(struct acpi_namespace_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) node->object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Found matching entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ACPI_CAST_PTR(char, &target_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) acpi_ut_get_type_name(node->type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) acpi_ut_get_node_name(parent_node),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) parent_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *return_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Didn't match name, move on to the next peer object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) node = node->peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Searched entire namespace level, not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) "%p first child %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ACPI_CAST_PTR(char, &target_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) acpi_ut_get_type_name(type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) acpi_ut_get_node_name(parent_node), parent_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) parent_node->child));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return_ACPI_STATUS(AE_NOT_FOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * FUNCTION: acpi_ns_search_parent_tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * PARAMETERS: target_name - Ascii ACPI name to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * node - Starting node where search will begin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * type - Object type to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * return_node - Where the matched Node is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * DESCRIPTION: Called when a name has not been found in the current namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * level. Before adding it or giving up, ACPI scope rules require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * searching enclosing scopes in cases identified by acpi_ns_local().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * "A name is located by finding the matching name in the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * name space, and then in the parent name space. If the parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * name space does not contain the name, the search continues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * recursively until either the name is found or the name space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * does not have a parent (the root of the name space). This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * indicates that the name is not found" (From ACPI Specification,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * section 5.3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) acpi_ns_search_parent_tree(u32 target_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct acpi_namespace_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) acpi_object_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct acpi_namespace_node **return_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct acpi_namespace_node *parent_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ACPI_FUNCTION_TRACE(ns_search_parent_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) parent_node = node->parent;
^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) * If there is no parent (i.e., we are at the root) or type is "local",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * we won't be searching the parent tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!parent_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ACPI_CAST_PTR(char, &target_name)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return_ACPI_STATUS(AE_NOT_FOUND);
^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) if (acpi_ns_local(type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ACPI_CAST_PTR(char, &target_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) acpi_ut_get_type_name(type)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return_ACPI_STATUS(AE_NOT_FOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Search the parent tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) "Searching parent [%4.4s] for [%4.4s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) acpi_ut_get_node_name(parent_node),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ACPI_CAST_PTR(char, &target_name)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Search parents until target is found or we have backed up to the root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) while (parent_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Search parent scope. Use TYPE_ANY because we don't care about the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * object type at this point, we only care about the existence of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * the actual name we are searching for. Typechecking comes later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) acpi_ns_search_one_scope(target_name, parent_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ACPI_TYPE_ANY, return_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Not found here, go up another level (until we reach the root) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) parent_node = parent_node->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* Not found in parent tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return_ACPI_STATUS(AE_NOT_FOUND);
^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) * FUNCTION: acpi_ns_search_and_enter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * PARAMETERS: target_name - Ascii ACPI name to search for (4 chars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * walk_state - Current state of the walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * node - Starting node where search will begin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * interpreter_mode - Add names only in ACPI_MODE_LOAD_PASS_x.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * Otherwise,search only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * type - Object type to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * flags - Flags describing the search restrictions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * return_node - Where the Node is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * DESCRIPTION: Search for a name segment in a single namespace level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * optionally adding it if it is not found. If the passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * Type is not Any and the type previously stored in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * entry was Any (i.e. unknown), update the stored type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * In ACPI_IMODE_EXECUTE, search only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * In other modes, search and add if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) acpi_ns_search_and_enter(u32 target_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct acpi_walk_state *walk_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct acpi_namespace_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) acpi_interpreter_mode interpreter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) acpi_object_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u32 flags, struct acpi_namespace_node **return_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct acpi_namespace_node *new_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ACPI_FUNCTION_TRACE(ns_search_and_enter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Parameter validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!node || !target_name || !return_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) "Null parameter: Node %p Name 0x%X ReturnNode %p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) node, target_name, return_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return_ACPI_STATUS(AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Name must consist of valid ACPI characters. We will repair the name if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * necessary because we don't want to abort because of this, but we want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * all namespace names to be printable. A warning message is appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * This issue came up because there are in fact machines that exhibit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * this problem, and we want to be able to enable ACPI support for them,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * even though there are a few bad names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Try to find the name in the namespace level specified by the caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *return_node = ACPI_ENTRY_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) status = acpi_ns_search_one_scope(target_name, node, type, return_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (status != AE_NOT_FOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * If we found it AND the request specifies that a find is an error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * return the error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (status == AE_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* The node was found in the namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * If the namespace override feature is enabled for this node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * delete any existing attached sub-object and make the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * look like a new node that is owned by the override table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) "Namespace override: %4.4s pass %u type %X Owner %X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ACPI_CAST_PTR(char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) &target_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) interpreter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) (*return_node)->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) walk_state->owner_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) acpi_ns_delete_children(*return_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (acpi_gbl_runtime_namespace_override) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) acpi_ut_remove_reference((*return_node)->object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) (*return_node)->object = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) (*return_node)->owner_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) walk_state->owner_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) acpi_ns_remove_node(*return_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) *return_node = ACPI_ENTRY_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* Return an error if we don't expect to find the object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) else if (flags & ACPI_NS_ERROR_IF_FOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) status = AE_ALREADY_EXISTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) #ifdef ACPI_ASL_COMPILER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (*return_node && (*return_node)->type == ACPI_TYPE_ANY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) (*return_node)->flags |= ANOBJ_IS_EXTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Either found it or there was an error: finished either way */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * The name was not found. If we are NOT performing the first pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * (name entry) of loading the namespace, search the parent tree (all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * way to the root if necessary.) We don't want to perform the parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * search when the namespace is actually being loaded. We want to perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * the search when namespace references are being resolved (load pass 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * and during the execution phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) (flags & ACPI_NS_SEARCH_PARENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * Not found at this level - search parent tree according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * ACPI specification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) acpi_ns_search_parent_tree(target_name, node, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* In execute mode, just search, never add names. Exit now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (interpreter_mode == ACPI_IMODE_EXECUTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) "%4.4s Not found in %p [Not adding]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ACPI_CAST_PTR(char, &target_name), node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return_ACPI_STATUS(AE_NOT_FOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Create the new named object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) new_node = acpi_ns_create_node(target_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!new_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return_ACPI_STATUS(AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) #ifdef ACPI_ASL_COMPILER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* Node is an object defined by an External() statement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (flags & ACPI_NS_EXTERNAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) (walk_state && walk_state->opcode == AML_SCOPE_OP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) new_node->flags |= ANOBJ_IS_EXTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (flags & ACPI_NS_TEMPORARY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) new_node->flags |= ANOBJ_TEMPORARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* Install the new object into the parent's list of children */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) acpi_ns_install_node(walk_state, node, new_node, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *return_node = new_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }