1 /*******************************************************************************
3 * Module Name: nseval - Object evaluation interfaces -- includes control
4 * method lookup and execution.
7 ******************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #define _COMPONENT ACPI_NAMESPACE
36 MODULE_NAME ("nseval")
39 /*******************************************************************************
41 * FUNCTION: Acpi_ns_evaluate_relative
43 * PARAMETERS: Handle - The relative containing object
44 * *Pathname - Name of method to execute, If NULL, the
45 * handle is the object to execute
46 * **Params - List of parameters to pass to the method,
47 * terminated by NULL. Params itself may be
48 * NULL if no parameters are being passed.
49 * *Return_object - Where to put method's return value (if
50 * any). If NULL, no value is returned.
54 * DESCRIPTION: Find and execute the requested method using the handle as a
57 * MUTEX: Locks Namespace
59 ******************************************************************************/
62 acpi_ns_evaluate_relative (
63 ACPI_NAMESPACE_NODE
*handle
,
64 NATIVE_CHAR
*pathname
,
65 ACPI_OPERAND_OBJECT
**params
,
66 ACPI_OPERAND_OBJECT
**return_object
)
68 ACPI_NAMESPACE_NODE
*prefix_node
;
70 ACPI_NAMESPACE_NODE
*node
= NULL
;
71 NATIVE_CHAR
*internal_path
= NULL
;
72 ACPI_GENERIC_STATE scope_info
;
76 * Must have a valid object handle
79 return (AE_BAD_PARAMETER
);
82 /* Build an internal name string for the method */
84 status
= acpi_ns_internalize_name (pathname
, &internal_path
);
85 if (ACPI_FAILURE (status
)) {
89 /* Get the prefix handle and Node */
91 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
93 prefix_node
= acpi_ns_convert_handle_to_entry (handle
);
95 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
96 status
= AE_BAD_PARAMETER
;
100 /* Lookup the name in the namespace */
102 scope_info
.scope
.node
= prefix_node
;
103 status
= acpi_ns_lookup (&scope_info
, internal_path
, ACPI_TYPE_ANY
,
104 IMODE_EXECUTE
, NS_NO_UPSEARCH
, NULL
,
107 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
109 if (ACPI_FAILURE (status
)) {
114 * Now that we have a handle to the object, we can attempt
118 status
= acpi_ns_evaluate_by_handle (node
, params
, return_object
);
124 acpi_cm_free (internal_path
);
130 /*******************************************************************************
132 * FUNCTION: Acpi_ns_evaluate_by_name
134 * PARAMETERS: Pathname - Fully qualified pathname to the object
135 * *Return_object - Where to put method's return value (if
136 * any). If NULL, no value is returned.
137 * **Params - List of parameters to pass to the method,
138 * terminated by NULL. Params itself may be
139 * NULL if no parameters are being passed.
143 * DESCRIPTION: Find and execute the requested method passing the given
146 * MUTEX: Locks Namespace
148 ******************************************************************************/
151 acpi_ns_evaluate_by_name (
152 NATIVE_CHAR
*pathname
,
153 ACPI_OPERAND_OBJECT
**params
,
154 ACPI_OPERAND_OBJECT
**return_object
)
157 ACPI_NAMESPACE_NODE
*node
= NULL
;
158 NATIVE_CHAR
*internal_path
= NULL
;
161 /* Build an internal name string for the method */
163 status
= acpi_ns_internalize_name (pathname
, &internal_path
);
164 if (ACPI_FAILURE (status
)) {
168 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
170 /* Lookup the name in the namespace */
172 status
= acpi_ns_lookup (NULL
, internal_path
, ACPI_TYPE_ANY
,
173 IMODE_EXECUTE
, NS_NO_UPSEARCH
, NULL
,
176 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
178 if (ACPI_FAILURE (status
)) {
183 * Now that we have a handle to the object, we can attempt
187 status
= acpi_ns_evaluate_by_handle (node
, params
, return_object
);
195 acpi_cm_free (internal_path
);
202 /*******************************************************************************
204 * FUNCTION: Acpi_ns_evaluate_by_handle
206 * PARAMETERS: Handle - Method Node to execute
207 * **Params - List of parameters to pass to the method,
208 * terminated by NULL. Params itself may be
209 * NULL if no parameters are being passed.
210 * *Return_object - Where to put method's return value (if
211 * any). If NULL, no value is returned.
215 * DESCRIPTION: Execute the requested method passing the given parameters
217 * MUTEX: Locks Namespace
219 ******************************************************************************/
222 acpi_ns_evaluate_by_handle (
223 ACPI_NAMESPACE_NODE
*handle
,
224 ACPI_OPERAND_OBJECT
**params
,
225 ACPI_OPERAND_OBJECT
**return_object
)
227 ACPI_NAMESPACE_NODE
*node
;
229 ACPI_OPERAND_OBJECT
*local_return_object
;
232 /* Check if namespace has been initialized */
234 if (!acpi_gbl_root_node
) {
235 return (AE_NO_NAMESPACE
);
238 /* Parameter Validation */
241 return (AE_BAD_PARAMETER
);
245 /* Initialize the return value to an invalid object */
247 *return_object
= NULL
;
250 /* Get the prefix handle and Node */
252 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
254 node
= acpi_ns_convert_handle_to_entry (handle
);
256 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
257 return (AE_BAD_PARAMETER
);
262 * Two major cases here:
263 * 1) The object is an actual control method -- execute it.
264 * 2) The object is not a method -- just return it's current
267 * In both cases, the namespace is unlocked by the
270 if (acpi_ns_get_type (node
) == ACPI_TYPE_METHOD
) {
272 * Case 1) We have an actual control method to execute
274 status
= acpi_ns_execute_control_method (node
, params
,
275 &local_return_object
);
280 * Case 2) Object is NOT a method, just return its
283 status
= acpi_ns_get_object_value (node
, &local_return_object
);
288 * Check if there is a return value on the stack that must
291 if (status
== AE_CTRL_RETURN_VALUE
) {
293 * If the Method returned a value and the caller
294 * provided a place to store a returned value, Copy
295 * the returned value to the object descriptor provided
300 * Valid return object, copy the pointer to
301 * the returned object
303 *return_object
= local_return_object
;
307 /* Map AE_RETURN_VALUE to AE_OK, we are done with it */
309 if (status
== AE_CTRL_RETURN_VALUE
) {
315 * Namespace was unlocked by the handling Acpi_ns* function,
322 /*******************************************************************************
324 * FUNCTION: Acpi_ns_execute_control_method
326 * PARAMETERS: Method_node - The object/method
327 * **Params - List of parameters to pass to the method,
328 * terminated by NULL. Params itself may be
329 * NULL if no parameters are being passed.
330 * **Return_obj_desc - List of result objects to be returned
335 * DESCRIPTION: Execute the requested method passing the given parameters
337 * MUTEX: Assumes namespace is locked
339 ******************************************************************************/
342 acpi_ns_execute_control_method (
343 ACPI_NAMESPACE_NODE
*method_node
,
344 ACPI_OPERAND_OBJECT
**params
,
345 ACPI_OPERAND_OBJECT
**return_obj_desc
)
348 ACPI_OPERAND_OBJECT
*obj_desc
;
351 /* Verify that there is a method associated with this object */
353 obj_desc
= acpi_ns_get_attached_object ((ACPI_HANDLE
) method_node
);
355 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
361 * Unlock the namespace before execution. This allows namespace access
362 * via the external Acpi* interfaces while a method is being executed.
363 * However, any namespace deletion must acquire both the namespace and
364 * interpreter locks to ensure that no thread is using the portion of the
365 * namespace that is being deleted.
367 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
370 * Execute the method via the interpreter
372 status
= acpi_aml_execute_method (method_node
, params
, return_obj_desc
);
378 /*******************************************************************************
380 * FUNCTION: Acpi_ns_get_object_value
382 * PARAMETERS: Node - The object
386 * DESCRIPTION: Return the current value of the object
388 * MUTEX: Assumes namespace is locked
390 ******************************************************************************/
393 acpi_ns_get_object_value (
394 ACPI_NAMESPACE_NODE
*node
,
395 ACPI_OPERAND_OBJECT
**return_obj_desc
)
397 ACPI_STATUS status
= AE_OK
;
398 ACPI_OPERAND_OBJECT
*obj_desc
;
399 ACPI_OPERAND_OBJECT
*val_desc
;
403 * We take the value from certain objects directly
406 if ((node
->type
== ACPI_TYPE_PROCESSOR
) ||
407 (node
->type
== ACPI_TYPE_POWER
)) {
409 * Create a Reference object to contain the object
411 obj_desc
= acpi_cm_create_internal_object (node
->type
);
413 status
= AE_NO_MEMORY
;
414 goto unlock_and_exit
;
418 * Get the attached object
421 val_desc
= acpi_ns_get_attached_object (node
);
423 status
= AE_NULL_OBJECT
;
424 goto unlock_and_exit
;
428 * Just copy from the original to the return object
430 * TBD: [Future] - need a low-level object copy that handles
431 * the reference count automatically. (Don't want to copy it)
434 MEMCPY (obj_desc
, val_desc
, sizeof (ACPI_OPERAND_OBJECT
));
435 obj_desc
->common
.reference_count
= 1;
436 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
441 * Other objects require a reference object wrapper which we
442 * then attempt to resolve.
445 /* Create an Reference object to contain the object */
447 obj_desc
= acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE
);
449 status
= AE_NO_MEMORY
;
450 goto unlock_and_exit
;
453 /* Construct a descriptor pointing to the name */
455 obj_desc
->reference
.opcode
= (u8
) AML_NAME_OP
;
456 obj_desc
->reference
.object
= (void *) node
;
459 * Use Resolve_to_value() to get the associated value. This call
460 * always deletes Obj_desc (allocated above).
462 * NOTE: we can get away with passing in NULL for a walk state
463 * because Obj_desc is guaranteed to not be a reference to either
464 * a method local or a method argument
466 * Even though we do not directly invoke the interpreter
467 * for this, we must enter it because we could access an opregion.
468 * The opregion access code assumes that the interpreter
471 * We must release the namespace lock before entering the
475 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
476 status
= acpi_aml_enter_interpreter ();
477 if (ACPI_SUCCESS (status
)) {
478 status
= acpi_aml_resolve_to_value (&obj_desc
, NULL
);
480 acpi_aml_exit_interpreter ();
485 * If Acpi_aml_resolve_to_value() succeeded, the return value was
486 * placed in Obj_desc.
489 if (ACPI_SUCCESS (status
)) {
490 status
= AE_CTRL_RETURN_VALUE
;
492 *return_obj_desc
= obj_desc
;
495 /* Namespace is unlocked */
502 /* Unlock the namespace */
504 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);