1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /******************************************************************************* 3 * 4 * Module Name: nsxfobj - Public interfaces to the ACPI subsystem 5 * ACPI Object oriented interfaces 6 * 7 ******************************************************************************/ 8 9 #define EXPORT_ACPI_INTERFACES 10 11 #include <acpi/acpi.h> 12 #include "accommon.h" 13 #include "acnamesp.h" 14 15 #define _COMPONENT ACPI_NAMESPACE 16 ACPI_MODULE_NAME("nsxfobj") 17 18 /******************************************************************************* 19 * 20 * FUNCTION: acpi_get_type 21 * 22 * PARAMETERS: handle - Handle of object whose type is desired 23 * ret_type - Where the type will be placed 24 * 25 * RETURN: Status 26 * 27 * DESCRIPTION: This routine returns the type associated with a particular 28 * handle 29 * 30 ******************************************************************************/ 31 acpi_status acpi_get_type(acpi_handle handle, acpi_object_type *ret_type) 32 { 33 struct acpi_namespace_node *node; 34 acpi_status status; 35 36 /* Parameter Validation */ 37 38 if (!ret_type) { 39 return (AE_BAD_PARAMETER); 40 } 41 42 /* Special case for the predefined Root Node (return type ANY) */ 43 44 if (handle == ACPI_ROOT_OBJECT) { 45 *ret_type = ACPI_TYPE_ANY; 46 return (AE_OK); 47 } 48 49 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 50 if (ACPI_FAILURE(status)) { 51 return (status); 52 } 53 54 /* Convert and validate the handle */ 55 56 node = acpi_ns_validate_handle(handle); 57 if (!node) { 58 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 59 return (AE_BAD_PARAMETER); 60 } 61 62 *ret_type = node->type; 63 64 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 65 return (status); 66 } 67 68 ACPI_EXPORT_SYMBOL(acpi_get_type) 69 70 /******************************************************************************* 71 * 72 * FUNCTION: acpi_get_parent 73 * 74 * PARAMETERS: handle - Handle of object whose parent is desired 75 * ret_handle - Where the parent handle will be placed 76 * 77 * RETURN: Status 78 * 79 * DESCRIPTION: Returns a handle to the parent of the object represented by 80 * Handle. 81 * 82 ******************************************************************************/ 83 acpi_status acpi_get_parent(acpi_handle handle, acpi_handle *ret_handle) 84 { 85 struct acpi_namespace_node *node; 86 struct acpi_namespace_node *parent_node; 87 acpi_status status; 88 89 if (!ret_handle) { 90 return (AE_BAD_PARAMETER); 91 } 92 93 /* Special case for the predefined Root Node (no parent) */ 94 95 if (handle == ACPI_ROOT_OBJECT) { 96 return (AE_NULL_ENTRY); 97 } 98 99 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 100 if (ACPI_FAILURE(status)) { 101 return (status); 102 } 103 104 /* Convert and validate the handle */ 105 106 node = acpi_ns_validate_handle(handle); 107 if (!node) { 108 status = AE_BAD_PARAMETER; 109 goto unlock_and_exit; 110 } 111 112 /* Get the parent entry */ 113 114 parent_node = node->parent; 115 *ret_handle = ACPI_CAST_PTR(acpi_handle, parent_node); 116 117 /* Return exception if parent is null */ 118 119 if (!parent_node) { 120 status = AE_NULL_ENTRY; 121 } 122 123 unlock_and_exit: 124 125 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 126 return (status); 127 } 128 129 ACPI_EXPORT_SYMBOL(acpi_get_parent) 130 131 /******************************************************************************* 132 * 133 * FUNCTION: acpi_get_next_object 134 * 135 * PARAMETERS: type - Type of object to be searched for 136 * parent - Parent object whose children we are getting 137 * last_child - Previous child that was found. 138 * The NEXT child will be returned 139 * ret_handle - Where handle to the next object is placed 140 * 141 * RETURN: Status 142 * 143 * DESCRIPTION: Return the next peer object within the namespace. If Handle is 144 * valid, Scope is ignored. Otherwise, the first object within 145 * Scope is returned. 146 * 147 ******************************************************************************/ 148 acpi_status 149 acpi_get_next_object(acpi_object_type type, 150 acpi_handle parent, 151 acpi_handle child, acpi_handle *ret_handle) 152 { 153 acpi_status status; 154 struct acpi_namespace_node *node; 155 struct acpi_namespace_node *parent_node = NULL; 156 struct acpi_namespace_node *child_node = NULL; 157 158 /* Parameter validation */ 159 160 if (type > ACPI_TYPE_EXTERNAL_MAX) { 161 return (AE_BAD_PARAMETER); 162 } 163 164 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 165 if (ACPI_FAILURE(status)) { 166 return (status); 167 } 168 169 /* If null handle, use the parent */ 170 171 if (!child) { 172 173 /* Start search at the beginning of the specified scope */ 174 175 parent_node = acpi_ns_validate_handle(parent); 176 if (!parent_node) { 177 status = AE_BAD_PARAMETER; 178 goto unlock_and_exit; 179 } 180 } else { 181 /* Non-null handle, ignore the parent */ 182 /* Convert and validate the handle */ 183 184 child_node = acpi_ns_validate_handle(child); 185 if (!child_node) { 186 status = AE_BAD_PARAMETER; 187 goto unlock_and_exit; 188 } 189 } 190 191 /* Internal function does the real work */ 192 193 node = acpi_ns_get_next_node_typed(type, parent_node, child_node); 194 if (!node) { 195 status = AE_NOT_FOUND; 196 goto unlock_and_exit; 197 } 198 199 if (ret_handle) { 200 *ret_handle = ACPI_CAST_PTR(acpi_handle, node); 201 } 202 203 unlock_and_exit: 204 205 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 206 return (status); 207 } 208 209 ACPI_EXPORT_SYMBOL(acpi_get_next_object) 210