ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / acpi / namespace / nseval.c
1 /*******************************************************************************
2  *
3  * Module Name: nseval - Object evaluation interfaces -- includes control
4  *                       method lookup and execution.
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/acparser.h>
48 #include <acpi/acinterp.h>
49 #include <acpi/acnamesp.h>
50
51
52 #define _COMPONENT          ACPI_NAMESPACE
53          ACPI_MODULE_NAME    ("nseval")
54
55
56 /*******************************************************************************
57  *
58  * FUNCTION:    acpi_ns_evaluate_relative
59  *
60  * PARAMETERS:  Handle              - The relative containing object
61  *              Pathname            - Name of method to execute, If NULL, the
62  *                                    handle is the object to execute
63  *              Params              - List of parameters to pass to the method,
64  *                                    terminated by NULL.  Params itself may be
65  *                                    NULL if no parameters are being passed.
66  *              return_object       - Where to put method's return value (if
67  *                                    any).  If NULL, no value is returned.
68  *
69  * RETURN:      Status
70  *
71  * DESCRIPTION: Find and execute the requested method using the handle as a
72  *              scope
73  *
74  * MUTEX:       Locks Namespace
75  *
76  ******************************************************************************/
77
78 acpi_status
79 acpi_ns_evaluate_relative (
80         struct acpi_namespace_node      *handle,
81         char                            *pathname,
82         union acpi_operand_object       **params,
83         union acpi_operand_object       **return_object)
84 {
85         acpi_status                     status;
86         struct acpi_namespace_node      *prefix_node;
87         struct acpi_namespace_node      *node = NULL;
88         union acpi_generic_state        *scope_info;
89         char                            *internal_path = NULL;
90
91
92         ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
93
94
95         /*
96          * Must have a valid object handle
97          */
98         if (!handle) {
99                 return_ACPI_STATUS (AE_BAD_PARAMETER);
100         }
101
102         /* Build an internal name string for the method */
103
104         status = acpi_ns_internalize_name (pathname, &internal_path);
105         if (ACPI_FAILURE (status)) {
106                 return_ACPI_STATUS (status);
107         }
108
109         scope_info = acpi_ut_create_generic_state ();
110         if (!scope_info) {
111                 goto cleanup1;
112         }
113
114         /* Get the prefix handle and Node */
115
116         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
117         if (ACPI_FAILURE (status)) {
118                 goto cleanup;
119         }
120
121         prefix_node = acpi_ns_map_handle_to_node (handle);
122         if (!prefix_node) {
123                 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
124                 status = AE_BAD_PARAMETER;
125                 goto cleanup;
126         }
127
128         /* Lookup the name in the namespace */
129
130         scope_info->scope.node = prefix_node;
131         status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
132                          ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
133                          &node);
134
135         (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
136
137         if (ACPI_FAILURE (status)) {
138                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
139                         pathname, acpi_format_exception (status)));
140                 goto cleanup;
141         }
142
143         /*
144          * Now that we have a handle to the object, we can attempt
145          * to evaluate it.
146          */
147         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
148                 pathname, node, acpi_ns_get_attached_object (node)));
149
150         status = acpi_ns_evaluate_by_handle (node, params, return_object);
151
152         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
153                 pathname));
154
155 cleanup:
156         acpi_ut_delete_generic_state (scope_info);
157
158 cleanup1:
159         ACPI_MEM_FREE (internal_path);
160         return_ACPI_STATUS (status);
161 }
162
163
164 /*******************************************************************************
165  *
166  * FUNCTION:    acpi_ns_evaluate_by_name
167  *
168  * PARAMETERS:  Pathname            - Fully qualified pathname to the object
169  *              return_object       - Where to put method's return value (if
170  *                                    any).  If NULL, no value is returned.
171  *              Params              - List of parameters to pass to the method,
172  *                                    terminated by NULL.  Params itself may be
173  *                                    NULL if no parameters are being passed.
174  *
175  * RETURN:      Status
176  *
177  * DESCRIPTION: Find and execute the requested method passing the given
178  *              parameters
179  *
180  * MUTEX:       Locks Namespace
181  *
182  ******************************************************************************/
183
184 acpi_status
185 acpi_ns_evaluate_by_name (
186         char                            *pathname,
187         union acpi_operand_object       **params,
188         union acpi_operand_object       **return_object)
189 {
190         acpi_status                     status;
191         struct acpi_namespace_node      *node = NULL;
192         char                            *internal_path = NULL;
193
194
195         ACPI_FUNCTION_TRACE ("ns_evaluate_by_name");
196
197
198         /* Build an internal name string for the method */
199
200         status = acpi_ns_internalize_name (pathname, &internal_path);
201         if (ACPI_FAILURE (status)) {
202                 return_ACPI_STATUS (status);
203         }
204
205         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
206         if (ACPI_FAILURE (status)) {
207                 goto cleanup;
208         }
209
210         /* Lookup the name in the namespace */
211
212         status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
213                          ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
214                          &node);
215
216         (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
217
218         if (ACPI_FAILURE (status)) {
219                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object at [%s] was not found, status=%.4X\n",
220                         pathname, status));
221                 goto cleanup;
222         }
223
224         /*
225          * Now that we have a handle to the object, we can attempt
226          * to evaluate it.
227          */
228         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
229                 pathname, node, acpi_ns_get_attached_object (node)));
230
231         status = acpi_ns_evaluate_by_handle (node, params, return_object);
232
233         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
234                 pathname));
235
236
237 cleanup:
238
239         /* Cleanup */
240
241         if (internal_path) {
242                 ACPI_MEM_FREE (internal_path);
243         }
244
245         return_ACPI_STATUS (status);
246 }
247
248
249 /*******************************************************************************
250  *
251  * FUNCTION:    acpi_ns_evaluate_by_handle
252  *
253  * PARAMETERS:  Handle              - Method Node to execute
254  *              Params              - List of parameters to pass to the method,
255  *                                    terminated by NULL.  Params itself may be
256  *                                    NULL if no parameters are being passed.
257  *              return_object       - Where to put method's return value (if
258  *                                    any).  If NULL, no value is returned.
259  *
260  * RETURN:      Status
261  *
262  * DESCRIPTION: Execute the requested method passing the given parameters
263  *
264  * MUTEX:       Locks Namespace
265  *
266  ******************************************************************************/
267
268 acpi_status
269 acpi_ns_evaluate_by_handle (
270         struct acpi_namespace_node      *handle,
271         union acpi_operand_object       **params,
272         union acpi_operand_object       **return_object)
273 {
274         struct acpi_namespace_node      *node;
275         acpi_status                     status;
276         union acpi_operand_object       *local_return_object;
277
278
279         ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle");
280
281
282         /* Check if namespace has been initialized */
283
284         if (!acpi_gbl_root_node) {
285                 return_ACPI_STATUS (AE_NO_NAMESPACE);
286         }
287
288         /* Parameter Validation */
289
290         if (!handle) {
291                 return_ACPI_STATUS (AE_BAD_PARAMETER);
292         }
293
294         if (return_object) {
295                 /* Initialize the return value to an invalid object */
296
297                 *return_object = NULL;
298         }
299
300         /* Get the prefix handle and Node */
301
302         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
303         if (ACPI_FAILURE (status)) {
304                 return_ACPI_STATUS (status);
305         }
306
307         node = acpi_ns_map_handle_to_node (handle);
308         if (!node) {
309                 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
310                 return_ACPI_STATUS (AE_BAD_PARAMETER);
311         }
312
313         /*
314          * For a method alias, we must grab the actual method node
315          * so that proper scoping context will be established
316          * before execution.
317          */
318         if (acpi_ns_get_type (node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
319                 node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object);
320         }
321
322         /*
323          * Two major cases here:
324          * 1) The object is an actual control method -- execute it.
325          * 2) The object is not a method -- just return it's current
326          *      value
327          *
328          * In both cases, the namespace is unlocked by the
329          *  acpi_ns* procedure
330          */
331         if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) {
332                 /*
333                  * Case 1) We have an actual control method to execute
334                  */
335                 status = acpi_ns_execute_control_method (node, params,
336                                  &local_return_object);
337         }
338         else {
339                 /*
340                  * Case 2) Object is NOT a method, just return its
341                  * current value
342                  */
343                 status = acpi_ns_get_object_value (node, &local_return_object);
344         }
345
346         /*
347          * Check if there is a return value on the stack that must
348          * be dealt with
349          */
350         if (status == AE_CTRL_RETURN_VALUE) {
351                 /*
352                  * If the Method returned a value and the caller
353                  * provided a place to store a returned value, Copy
354                  * the returned value to the object descriptor provided
355                  * by the caller.
356                  */
357                 if (return_object) {
358                         /*
359                          * Valid return object, copy the pointer to
360                          * the returned object
361                          */
362                         *return_object = local_return_object;
363                 }
364
365                 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
366
367                 status = AE_OK;
368         }
369
370         /*
371          * Namespace was unlocked by the handling acpi_ns* function,
372          * so we just return
373          */
374         return_ACPI_STATUS (status);
375 }
376
377
378 /*******************************************************************************
379  *
380  * FUNCTION:    acpi_ns_execute_control_method
381  *
382  * PARAMETERS:  method_node         - The method to execute
383  *              Params              - List of parameters to pass to the method,
384  *                                    terminated by NULL.  Params itself may be
385  *                                    NULL if no parameters are being passed.
386  *              return_obj_desc     - List of result objects to be returned
387  *                                    from the method.
388  *
389  * RETURN:      Status
390  *
391  * DESCRIPTION: Execute the requested method passing the given parameters
392  *
393  * MUTEX:       Assumes namespace is locked
394  *
395  ******************************************************************************/
396
397 acpi_status
398 acpi_ns_execute_control_method (
399         struct acpi_namespace_node      *method_node,
400         union acpi_operand_object       **params,
401         union acpi_operand_object       **return_obj_desc)
402 {
403         acpi_status                     status;
404         union acpi_operand_object       *obj_desc;
405
406
407         ACPI_FUNCTION_TRACE ("ns_execute_control_method");
408
409
410         /* Verify that there is a method associated with this object */
411
412         obj_desc = acpi_ns_get_attached_object (method_node);
413         if (!obj_desc) {
414                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
415
416                 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
417                 return_ACPI_STATUS (AE_NULL_OBJECT);
418         }
419
420         ACPI_DUMP_PATHNAME (method_node, "Execute Method:",
421                 ACPI_LV_INFO, _COMPONENT);
422
423         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
424                 obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1));
425
426         /*
427          * Unlock the namespace before execution.  This allows namespace access
428          * via the external Acpi* interfaces while a method is being executed.
429          * However, any namespace deletion must acquire both the namespace and
430          * interpreter locks to ensure that no thread is using the portion of the
431          * namespace that is being deleted.
432          */
433         status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
434         if (ACPI_FAILURE (status)) {
435                 return_ACPI_STATUS (status);
436         }
437
438         /*
439          * Execute the method via the interpreter.  The interpreter is locked
440          * here before calling into the AML parser
441          */
442         status = acpi_ex_enter_interpreter ();
443         if (ACPI_FAILURE (status)) {
444                 return_ACPI_STATUS (status);
445         }
446
447         status = acpi_psx_execute (method_node, params, return_obj_desc);
448         acpi_ex_exit_interpreter ();
449
450         return_ACPI_STATUS (status);
451 }
452
453
454 /*******************************************************************************
455  *
456  * FUNCTION:    acpi_ns_get_object_value
457  *
458  * PARAMETERS:  Node                - The object
459  *              return_obj_desc     - Where the objects value is returned
460  *
461  * RETURN:      Status
462  *
463  * DESCRIPTION: Return the current value of the object
464  *
465  * MUTEX:       Assumes namespace is locked, leaves namespace unlocked
466  *
467  ******************************************************************************/
468
469 acpi_status
470 acpi_ns_get_object_value (
471         struct acpi_namespace_node      *node,
472         union acpi_operand_object       **return_obj_desc)
473 {
474         acpi_status                     status = AE_OK;
475         struct acpi_namespace_node      *resolved_node = node;
476
477
478         ACPI_FUNCTION_TRACE ("ns_get_object_value");
479
480
481         /*
482          * Objects require additional resolution steps (e.g., the
483          * Node may be a field that must be read, etc.) -- we can't just grab
484          * the object out of the node.
485          */
486
487         /*
488          * Use resolve_node_to_value() to get the associated value. This call
489          * always deletes obj_desc (allocated above).
490          *
491          * NOTE: we can get away with passing in NULL for a walk state
492          * because obj_desc is guaranteed to not be a reference to either
493          * a method local or a method argument (because this interface can only be
494          * called from the acpi_evaluate external interface, never called from
495          * a running control method.)
496          *
497          * Even though we do not directly invoke the interpreter
498          * for this, we must enter it because we could access an opregion.
499          * The opregion access code assumes that the interpreter
500          * is locked.
501          *
502          * We must release the namespace lock before entering the
503          * intepreter.
504          */
505         status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
506         if (ACPI_FAILURE (status)) {
507                 return_ACPI_STATUS (status);
508         }
509
510         status = acpi_ex_enter_interpreter ();
511         if (ACPI_SUCCESS (status)) {
512                 status = acpi_ex_resolve_node_to_value (&resolved_node, NULL);
513                 /*
514                  * If acpi_ex_resolve_node_to_value() succeeded, the return value was
515                  * placed in resolved_node.
516                  */
517                 acpi_ex_exit_interpreter ();
518
519                 if (ACPI_SUCCESS (status)) {
520                         status = AE_CTRL_RETURN_VALUE;
521                         *return_obj_desc = ACPI_CAST_PTR (union acpi_operand_object, resolved_node);
522                         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
523                                 *return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc)));
524                 }
525         }
526
527         /* Namespace is unlocked */
528
529         return_ACPI_STATUS (status);
530 }
531