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