Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /****************************************************************************** |
2 | * | |
3 | * Module Name: nsxfname - Public interfaces to the ACPI subsystem | |
4 | * ACPI Namespace oriented interfaces | |
5 | * | |
6 | *****************************************************************************/ | |
7 | ||
8 | /* | |
9 | * Copyright (C) 2000 - 2005, R. Byron Moore | |
10 | * All rights reserved. | |
11 | * | |
12 | * Redistribution and use in source and binary forms, with or without | |
13 | * modification, are permitted provided that the following conditions | |
14 | * are met: | |
15 | * 1. Redistributions of source code must retain the above copyright | |
16 | * notice, this list of conditions, and the following disclaimer, | |
17 | * without modification. | |
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | |
19 | * substantially similar to the "NO WARRANTY" disclaimer below | |
20 | * ("Disclaimer") and any redistribution must be conditioned upon | |
21 | * including a substantially similar Disclaimer requirement for further | |
22 | * binary redistribution. | |
23 | * 3. Neither the names of the above-listed copyright holders nor the names | |
24 | * of any contributors may be used to endorse or promote products derived | |
25 | * from this software without specific prior written permission. | |
26 | * | |
27 | * Alternatively, this software may be distributed under the terms of the | |
28 | * GNU General Public License ("GPL") version 2 as published by the Free | |
29 | * Software Foundation. | |
30 | * | |
31 | * NO WARRANTY | |
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | |
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
42 | * POSSIBILITY OF SUCH DAMAGES. | |
43 | */ | |
44 | ||
45 | #include <linux/module.h> | |
46 | ||
47 | #include <acpi/acpi.h> | |
48 | #include <acpi/acnamesp.h> | |
49 | ||
50 | ||
51 | #define _COMPONENT ACPI_NAMESPACE | |
52 | ACPI_MODULE_NAME ("nsxfname") | |
53 | ||
54 | ||
55 | /****************************************************************************** | |
56 | * | |
57 | * FUNCTION: acpi_get_handle | |
58 | * | |
59 | * PARAMETERS: Parent - Object to search under (search scope). | |
60 | * path_name - Pointer to an asciiz string containing the | |
61 | * name | |
62 | * ret_handle - Where the return handle is placed | |
63 | * | |
64 | * RETURN: Status | |
65 | * | |
66 | * DESCRIPTION: This routine will search for a caller specified name in the | |
67 | * name space. The caller can restrict the search region by | |
68 | * specifying a non NULL parent. The parent value is itself a | |
69 | * namespace handle. | |
70 | * | |
71 | ******************************************************************************/ | |
72 | ||
73 | acpi_status | |
74 | acpi_get_handle ( | |
75 | acpi_handle parent, | |
76 | acpi_string pathname, | |
77 | acpi_handle *ret_handle) | |
78 | { | |
79 | acpi_status status; | |
80 | struct acpi_namespace_node *node = NULL; | |
81 | struct acpi_namespace_node *prefix_node = NULL; | |
82 | ||
83 | ||
84 | ACPI_FUNCTION_ENTRY (); | |
85 | ||
86 | ||
87 | /* Parameter Validation */ | |
88 | ||
89 | if (!ret_handle || !pathname) { | |
90 | return (AE_BAD_PARAMETER); | |
91 | } | |
92 | ||
93 | /* Convert a parent handle to a prefix node */ | |
94 | ||
95 | if (parent) { | |
96 | status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); | |
97 | if (ACPI_FAILURE (status)) { | |
98 | return (status); | |
99 | } | |
100 | ||
101 | prefix_node = acpi_ns_map_handle_to_node (parent); | |
102 | if (!prefix_node) { | |
103 | (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | |
104 | return (AE_BAD_PARAMETER); | |
105 | } | |
106 | ||
107 | status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | |
108 | if (ACPI_FAILURE (status)) { | |
109 | return (status); | |
110 | } | |
111 | } | |
112 | ||
113 | /* Special case for root, since we can't search for it */ | |
114 | ||
115 | if (ACPI_STRCMP (pathname, ACPI_NS_ROOT_PATH) == 0) { | |
116 | *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node); | |
117 | return (AE_OK); | |
118 | } | |
119 | ||
120 | /* | |
121 | * Find the Node and convert to a handle | |
122 | */ | |
123 | status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH, | |
124 | &node); | |
125 | ||
126 | *ret_handle = NULL; | |
127 | if (ACPI_SUCCESS (status)) { | |
128 | *ret_handle = acpi_ns_convert_entry_to_handle (node); | |
129 | } | |
130 | ||
131 | return (status); | |
132 | } | |
133 | EXPORT_SYMBOL(acpi_get_handle); | |
134 | ||
135 | ||
136 | /****************************************************************************** | |
137 | * | |
138 | * FUNCTION: acpi_get_name | |
139 | * | |
140 | * PARAMETERS: Handle - Handle to be converted to a pathname | |
141 | * name_type - Full pathname or single segment | |
142 | * Buffer - Buffer for returned path | |
143 | * | |
144 | * RETURN: Pointer to a string containing the fully qualified Name. | |
145 | * | |
146 | * DESCRIPTION: This routine returns the fully qualified name associated with | |
147 | * the Handle parameter. This and the acpi_pathname_to_handle are | |
148 | * complementary functions. | |
149 | * | |
150 | ******************************************************************************/ | |
151 | ||
152 | acpi_status | |
153 | acpi_get_name ( | |
154 | acpi_handle handle, | |
155 | u32 name_type, | |
156 | struct acpi_buffer *buffer) | |
157 | { | |
158 | acpi_status status; | |
159 | struct acpi_namespace_node *node; | |
160 | ||
161 | ||
162 | /* Parameter validation */ | |
163 | ||
164 | if (name_type > ACPI_NAME_TYPE_MAX) { | |
165 | return (AE_BAD_PARAMETER); | |
166 | } | |
167 | ||
168 | status = acpi_ut_validate_buffer (buffer); | |
169 | if (ACPI_FAILURE (status)) { | |
170 | return (status); | |
171 | } | |
172 | ||
173 | if (name_type == ACPI_FULL_PATHNAME) { | |
174 | /* Get the full pathname (From the namespace root) */ | |
175 | ||
176 | status = acpi_ns_handle_to_pathname (handle, buffer); | |
177 | return (status); | |
178 | } | |
179 | ||
180 | /* | |
181 | * Wants the single segment ACPI name. | |
182 | * Validate handle and convert to a namespace Node | |
183 | */ | |
184 | status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); | |
185 | if (ACPI_FAILURE (status)) { | |
186 | return (status); | |
187 | } | |
188 | ||
189 | node = acpi_ns_map_handle_to_node (handle); | |
190 | if (!node) { | |
191 | status = AE_BAD_PARAMETER; | |
192 | goto unlock_and_exit; | |
193 | } | |
194 | ||
195 | /* Validate/Allocate/Clear caller buffer */ | |
196 | ||
197 | status = acpi_ut_initialize_buffer (buffer, ACPI_PATH_SEGMENT_LENGTH); | |
198 | if (ACPI_FAILURE (status)) { | |
199 | goto unlock_and_exit; | |
200 | } | |
201 | ||
202 | /* Just copy the ACPI name from the Node and zero terminate it */ | |
203 | ||
204 | ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node), | |
205 | ACPI_NAME_SIZE); | |
206 | ((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0; | |
207 | status = AE_OK; | |
208 | ||
209 | ||
210 | unlock_and_exit: | |
211 | ||
212 | (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | |
213 | return (status); | |
214 | } | |
215 | EXPORT_SYMBOL(acpi_get_name); | |
216 | ||
217 | ||
218 | /****************************************************************************** | |
219 | * | |
220 | * FUNCTION: acpi_get_object_info | |
221 | * | |
222 | * PARAMETERS: Handle - Object Handle | |
223 | * Info - Where the info is returned | |
224 | * | |
225 | * RETURN: Status | |
226 | * | |
227 | * DESCRIPTION: Returns information about an object as gleaned from the | |
228 | * namespace node and possibly by running several standard | |
229 | * control methods (Such as in the case of a device.) | |
230 | * | |
231 | ******************************************************************************/ | |
232 | ||
233 | acpi_status | |
234 | acpi_get_object_info ( | |
235 | acpi_handle handle, | |
236 | struct acpi_buffer *buffer) | |
237 | { | |
238 | acpi_status status; | |
239 | struct acpi_namespace_node *node; | |
240 | struct acpi_device_info *info; | |
241 | struct acpi_device_info *return_info; | |
242 | struct acpi_compatible_id_list *cid_list = NULL; | |
243 | acpi_size size; | |
244 | ||
245 | ||
246 | /* Parameter validation */ | |
247 | ||
248 | if (!handle || !buffer) { | |
249 | return (AE_BAD_PARAMETER); | |
250 | } | |
251 | ||
252 | status = acpi_ut_validate_buffer (buffer); | |
253 | if (ACPI_FAILURE (status)) { | |
254 | return (status); | |
255 | } | |
256 | ||
257 | info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_device_info)); | |
258 | if (!info) { | |
259 | return (AE_NO_MEMORY); | |
260 | } | |
261 | ||
262 | status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); | |
263 | if (ACPI_FAILURE (status)) { | |
264 | goto cleanup; | |
265 | } | |
266 | ||
267 | node = acpi_ns_map_handle_to_node (handle); | |
268 | if (!node) { | |
269 | (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | |
270 | goto cleanup; | |
271 | } | |
272 | ||
273 | /* Init return structure */ | |
274 | ||
275 | size = sizeof (struct acpi_device_info); | |
276 | ||
277 | info->type = node->type; | |
278 | info->name = node->name.integer; | |
279 | info->valid = 0; | |
280 | ||
281 | status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | |
282 | if (ACPI_FAILURE (status)) { | |
283 | goto cleanup; | |
284 | } | |
285 | ||
286 | /* If not a device, we are all done */ | |
287 | ||
288 | if (info->type == ACPI_TYPE_DEVICE) { | |
289 | /* | |
290 | * Get extra info for ACPI Devices objects only: | |
291 | * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. | |
292 | * | |
293 | * Note: none of these methods are required, so they may or may | |
294 | * not be present for this device. The Info->Valid bitfield is used | |
295 | * to indicate which methods were found and ran successfully. | |
296 | */ | |
297 | ||
298 | /* Execute the Device._HID method */ | |
299 | ||
300 | status = acpi_ut_execute_HID (node, &info->hardware_id); | |
301 | if (ACPI_SUCCESS (status)) { | |
302 | info->valid |= ACPI_VALID_HID; | |
303 | } | |
304 | ||
305 | /* Execute the Device._UID method */ | |
306 | ||
307 | status = acpi_ut_execute_UID (node, &info->unique_id); | |
308 | if (ACPI_SUCCESS (status)) { | |
309 | info->valid |= ACPI_VALID_UID; | |
310 | } | |
311 | ||
312 | /* Execute the Device._CID method */ | |
313 | ||
314 | status = acpi_ut_execute_CID (node, &cid_list); | |
315 | if (ACPI_SUCCESS (status)) { | |
316 | size += ((acpi_size) cid_list->count - 1) * | |
317 | sizeof (struct acpi_compatible_id); | |
318 | info->valid |= ACPI_VALID_CID; | |
319 | } | |
320 | ||
321 | /* Execute the Device._STA method */ | |
322 | ||
323 | status = acpi_ut_execute_STA (node, &info->current_status); | |
324 | if (ACPI_SUCCESS (status)) { | |
325 | info->valid |= ACPI_VALID_STA; | |
326 | } | |
327 | ||
328 | /* Execute the Device._ADR method */ | |
329 | ||
330 | status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, | |
331 | &info->address); | |
332 | if (ACPI_SUCCESS (status)) { | |
333 | info->valid |= ACPI_VALID_ADR; | |
334 | } | |
335 | ||
336 | /* Execute the Device._sx_d methods */ | |
337 | ||
338 | status = acpi_ut_execute_sxds (node, info->highest_dstates); | |
339 | if (ACPI_SUCCESS (status)) { | |
340 | info->valid |= ACPI_VALID_SXDS; | |
341 | } | |
342 | } | |
343 | ||
344 | /* Validate/Allocate/Clear caller buffer */ | |
345 | ||
346 | status = acpi_ut_initialize_buffer (buffer, size); | |
347 | if (ACPI_FAILURE (status)) { | |
348 | goto cleanup; | |
349 | } | |
350 | ||
351 | /* Populate the return buffer */ | |
352 | ||
353 | return_info = buffer->pointer; | |
354 | ACPI_MEMCPY (return_info, info, sizeof (struct acpi_device_info)); | |
355 | ||
356 | if (cid_list) { | |
357 | ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size); | |
358 | } | |
359 | ||
360 | ||
361 | cleanup: | |
362 | ACPI_MEM_FREE (info); | |
363 | if (cid_list) { | |
364 | ACPI_MEM_FREE (cid_list); | |
365 | } | |
366 | return (status); | |
367 | } | |
368 | EXPORT_SYMBOL(acpi_get_object_info); | |
369 |