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