ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / acpi / namespace / nsxfname.c
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 - 2004, 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
46 #include <acpi/acpi.h>
47 #include <acpi/acnamesp.h>
48
49
50 #define _COMPONENT          ACPI_NAMESPACE
51          ACPI_MODULE_NAME    ("nsxfname")
52
53
54 /******************************************************************************
55  *
56  * FUNCTION:    acpi_get_handle
57  *
58  * PARAMETERS:  Parent          - Object to search under (search scope).
59  *              path_name       - Pointer to an asciiz string containing the
60  *                                  name
61  *              ret_handle      - Where the return handle is placed
62  *
63  * RETURN:      Status
64  *
65  * DESCRIPTION: This routine will search for a caller specified name in the
66  *              name space.  The caller can restrict the search region by
67  *              specifying a non NULL parent.  The parent value is itself a
68  *              namespace handle.
69  *
70  ******************************************************************************/
71
72 acpi_status
73 acpi_get_handle (
74         acpi_handle                     parent,
75         acpi_string                     pathname,
76         acpi_handle                     *ret_handle)
77 {
78         acpi_status                     status;
79         struct acpi_namespace_node      *node = NULL;
80         struct acpi_namespace_node      *prefix_node = NULL;
81
82
83         ACPI_FUNCTION_ENTRY ();
84
85
86         /* Parameter Validation */
87
88         if (!ret_handle || !pathname) {
89                 return (AE_BAD_PARAMETER);
90         }
91
92         /* Convert a parent handle to a prefix node */
93
94         if (parent) {
95                 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
96                 if (ACPI_FAILURE (status)) {
97                         return (status);
98                 }
99
100                 prefix_node = acpi_ns_map_handle_to_node (parent);
101                 if (!prefix_node) {
102                         (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
103                         return (AE_BAD_PARAMETER);
104                 }
105
106                 status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
107                 if (ACPI_FAILURE (status)) {
108                         return (status);
109                 }
110         }
111
112         /* Special case for root, since we can't search for it */
113
114         if (ACPI_STRCMP (pathname, ACPI_NS_ROOT_PATH) == 0) {
115                 *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node);
116                 return (AE_OK);
117         }
118
119         /*
120          *  Find the Node and convert to a handle
121          */
122         status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
123                           &node);
124
125         *ret_handle = NULL;
126         if (ACPI_SUCCESS (status)) {
127                 *ret_handle = acpi_ns_convert_entry_to_handle (node);
128         }
129
130         return (status);
131 }
132
133
134 /******************************************************************************
135  *
136  * FUNCTION:    acpi_get_name
137  *
138  * PARAMETERS:  Handle          - Handle to be converted to a pathname
139  *              name_type       - Full pathname or single segment
140  *              Buffer          - Buffer for returned path
141  *
142  * RETURN:      Pointer to a string containing the fully qualified Name.
143  *
144  * DESCRIPTION: This routine returns the fully qualified name associated with
145  *              the Handle parameter.  This and the acpi_pathname_to_handle are
146  *              complementary functions.
147  *
148  ******************************************************************************/
149
150 acpi_status
151 acpi_get_name (
152         acpi_handle                     handle,
153         u32                             name_type,
154         struct acpi_buffer              *buffer)
155 {
156         acpi_status                     status;
157         struct acpi_namespace_node      *node;
158
159
160         /* Parameter validation */
161
162         if (name_type > ACPI_NAME_TYPE_MAX) {
163                 return (AE_BAD_PARAMETER);
164         }
165
166         status = acpi_ut_validate_buffer (buffer);
167         if (ACPI_FAILURE (status)) {
168                 return (status);
169         }
170
171         if (name_type == ACPI_FULL_PATHNAME) {
172                 /* Get the full pathname (From the namespace root) */
173
174                 status = acpi_ns_handle_to_pathname (handle, buffer);
175                 return (status);
176         }
177
178         /*
179          * Wants the single segment ACPI name.
180          * Validate handle and convert to a namespace Node
181          */
182         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
183         if (ACPI_FAILURE (status)) {
184                 return (status);
185         }
186
187         node = acpi_ns_map_handle_to_node (handle);
188         if (!node) {
189                 status = AE_BAD_PARAMETER;
190                 goto unlock_and_exit;
191         }
192
193         /* Validate/Allocate/Clear caller buffer */
194
195         status = acpi_ut_initialize_buffer (buffer, ACPI_PATH_SEGMENT_LENGTH);
196         if (ACPI_FAILURE (status)) {
197                 goto unlock_and_exit;
198         }
199
200         /* Just copy the ACPI name from the Node and zero terminate it */
201
202         ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node),
203                          ACPI_NAME_SIZE);
204         ((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0;
205         status = AE_OK;
206
207
208 unlock_and_exit:
209
210         (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
211         return (status);
212 }
213
214
215 /******************************************************************************
216  *
217  * FUNCTION:    acpi_get_object_info
218  *
219  * PARAMETERS:  Handle          - Object Handle
220  *              Info            - Where the info is returned
221  *
222  * RETURN:      Status
223  *
224  * DESCRIPTION: Returns information about an object as gleaned from the
225  *              namespace node and possibly by running several standard
226  *              control methods (Such as in the case of a device.)
227  *
228  ******************************************************************************/
229
230 acpi_status
231 acpi_get_object_info (
232         acpi_handle                     handle,
233         struct acpi_buffer              *buffer)
234 {
235         acpi_status                     status;
236         struct acpi_namespace_node      *node;
237         struct acpi_device_info         info;
238         struct acpi_device_info         *return_info;
239         struct acpi_compatible_id_list *cid_list = NULL;
240         acpi_size                       size;
241
242
243         /* Parameter validation */
244
245         if (!handle || !buffer) {
246                 return (AE_BAD_PARAMETER);
247         }
248
249         status = acpi_ut_validate_buffer (buffer);
250         if (ACPI_FAILURE (status)) {
251                 return (status);
252         }
253
254         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
255         if (ACPI_FAILURE (status)) {
256                 return (status);
257         }
258
259         node = acpi_ns_map_handle_to_node (handle);
260         if (!node) {
261                 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
262                 return (AE_BAD_PARAMETER);
263         }
264
265         /* Init return structure */
266
267         size = sizeof (struct acpi_device_info);
268         ACPI_MEMSET (&info, 0, size);
269
270         info.type  = node->type;
271         info.name  = node->name.integer;
272         info.valid = 0;
273
274         status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
275         if (ACPI_FAILURE (status)) {
276                 return (status);
277         }
278
279         /* If not a device, we are all done */
280
281         if (info.type == ACPI_TYPE_DEVICE) {
282                 /*
283                  * Get extra info for ACPI Devices objects only:
284                  * Run the Device _HID, _UID, _CID, _STA, and _ADR methods.
285                  *
286                  * Note: none of these methods are required, so they may or may
287                  * not be present for this device.  The Info.Valid bitfield is used
288                  * to indicate which methods were found and ran successfully.
289                  */
290
291                 /* Execute the Device._HID method */
292
293                 status = acpi_ut_execute_HID (node, &info.hardware_id);
294                 if (ACPI_SUCCESS (status)) {
295                         info.valid |= ACPI_VALID_HID;
296                 }
297
298                 /* Execute the Device._UID method */
299
300                 status = acpi_ut_execute_UID (node, &info.unique_id);
301                 if (ACPI_SUCCESS (status)) {
302                         info.valid |= ACPI_VALID_UID;
303                 }
304
305                 /* Execute the Device._CID method */
306
307                 status = acpi_ut_execute_CID (node, &cid_list);
308                 if (ACPI_SUCCESS (status)) {
309                         size += ((acpi_size) cid_list->count - 1) *
310                                          sizeof (struct acpi_compatible_id);
311                         info.valid |= ACPI_VALID_CID;
312                 }
313
314                 /* Execute the Device._STA method */
315
316                 status = acpi_ut_execute_STA (node, &info.current_status);
317                 if (ACPI_SUCCESS (status)) {
318                         info.valid |= ACPI_VALID_STA;
319                 }
320
321                 /* Execute the Device._ADR method */
322
323                 status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
324                                   &info.address);
325                 if (ACPI_SUCCESS (status)) {
326                         info.valid |= ACPI_VALID_ADR;
327                 }
328
329                 /* Execute the Device._sx_d methods */
330
331                 status = acpi_ut_execute_sxds (node, info.highest_dstates);
332                 if (ACPI_SUCCESS (status)) {
333                         info.valid |= ACPI_VALID_STA;
334                 }
335
336                 status = AE_OK;
337         }
338
339         /* Validate/Allocate/Clear caller buffer */
340
341         status = acpi_ut_initialize_buffer (buffer, size);
342         if (ACPI_FAILURE (status)) {
343                 goto cleanup;
344         }
345
346         /* Populate the return buffer */
347
348         return_info = buffer->pointer;
349         ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info));
350
351         if (cid_list) {
352                 ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
353         }
354
355
356 cleanup:
357         if (cid_list) {
358                 ACPI_MEM_FREE (cid_list);
359         }
360         return (status);
361 }
362