2005-04-17 02:20:36 +04:00
/*******************************************************************************
*
2006-05-27 00:36:00 +04:00
* Module Name : nseval - Object evaluation , includes control method execution
2005-04-17 02:20:36 +04:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2008-04-24 07:00:13 +04:00
* Copyright ( C ) 2000 - 2008 , Intel Corp .
2005-04-17 02:20:36 +04:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions , and the following disclaimer ,
* without modification .
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the " NO WARRANTY " disclaimer below
* ( " Disclaimer " ) and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution .
* 3. Neither the names of the above - listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* Alternatively , this software may be distributed under the terms of the
* GNU General Public License ( " GPL " ) version 2 as published by the Free
* Software Foundation .
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT ,
* STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES .
*/
# include <acpi/acpi.h>
2008-12-30 22:01:23 +03:00
# include <acpi/accommon.h>
2005-04-17 02:20:36 +04:00
# include <acpi/acparser.h>
# include <acpi/acinterp.h>
# include <acpi/acnamesp.h>
# define _COMPONENT ACPI_NAMESPACE
2005-08-05 08:44:28 +04:00
ACPI_MODULE_NAME ( " nseval " )
2005-04-17 02:20:36 +04:00
/*******************************************************************************
*
2006-05-27 00:36:00 +04:00
* FUNCTION : acpi_ns_evaluate
2005-04-17 02:20:36 +04:00
*
2006-05-27 00:36:00 +04:00
* PARAMETERS : Info - Evaluation info block , contains :
* prefix_node - Prefix or Method / Object Node to execute
* Pathname - Name of method to execute , If NULL , the
* Node is the object to execute
2005-04-19 06:49:35 +04:00
* Parameters - List of parameters to pass to the method ,
* terminated by NULL . Params itself may be
2005-04-17 02:20:36 +04:00
* NULL if no parameters are being passed .
2005-04-19 06:49:35 +04:00
* return_object - Where to put method ' s return value ( if
* any ) . If NULL , no value is returned .
* parameter_type - Type of Parameter list
* return_object - Where to put method ' s return value ( if
* any ) . If NULL , no value is returned .
2006-05-27 00:36:00 +04:00
* Flags - ACPI_IGNORE_RETURN_VALUE to delete return
2005-04-17 02:20:36 +04:00
*
* RETURN : Status
*
2006-05-27 00:36:00 +04:00
* DESCRIPTION : Execute a control method or return the current value of an
* ACPI namespace object .
2005-04-17 02:20:36 +04:00
*
2006-05-27 00:36:00 +04:00
* MUTEX : Locks interpreter
2005-04-17 02:20:36 +04:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-05-10 07:34:35 +04:00
acpi_status acpi_ns_evaluate ( struct acpi_evaluate_info * info )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status ;
2008-09-28 11:26:17 +04:00
struct acpi_namespace_node * node ;
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
ACPI_FUNCTION_TRACE ( ns_evaluate ) ;
2005-04-17 02:20:36 +04:00
if ( ! info ) {
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( AE_BAD_PARAMETER ) ;
2005-04-17 02:20:36 +04:00
}
/* Initialize the return value to an invalid object */
info - > return_object = NULL ;
2008-11-13 06:19:24 +03:00
info - > param_count = 0 ;
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
/*
* Get the actual namespace node for the target object . Handles these cases :
*
* 1 ) Null node , Pathname ( absolute path )
* 2 ) Node , Pathname ( path relative to Node )
* 3 ) Node , Null Pathname
*/
status = acpi_ns_get_node ( info - > prefix_node , info - > pathname ,
ACPI_NS_NO_UPSEARCH , & info - > resolved_node ) ;
2005-08-05 08:44:28 +04:00
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
/*
* For a method alias , we must grab the actual method node so that proper
* scoping context will be established before execution .
*/
2006-05-27 00:36:00 +04:00
if ( acpi_ns_get_type ( info - > resolved_node ) = =
ACPI_TYPE_LOCAL_METHOD_ALIAS ) {
info - > resolved_node =
2005-08-05 08:44:28 +04:00
ACPI_CAST_PTR ( struct acpi_namespace_node ,
2006-05-27 00:36:00 +04:00
info - > resolved_node - > object ) ;
2005-04-17 02:20:36 +04:00
}
2006-05-27 00:36:00 +04:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_NAMES , " %s [%p] Value %p \n " , info - > pathname ,
info - > resolved_node ,
acpi_ns_get_attached_object ( info - > resolved_node ) ) ) ;
2008-09-28 11:26:17 +04:00
node = info - > resolved_node ;
2005-04-17 02:20:36 +04:00
/*
* Two major cases here :
*
2006-05-27 00:36:00 +04:00
* 1 ) The object is a control method - - execute it
* 2 ) The object is not a method - - just return it ' s current value
2005-04-17 02:20:36 +04:00
*/
2006-05-27 00:36:00 +04:00
if ( acpi_ns_get_type ( info - > resolved_node ) = = ACPI_TYPE_METHOD ) {
2005-04-17 02:20:36 +04:00
/*
2006-05-27 00:36:00 +04:00
* 1 ) Object is a control method - execute it
2005-04-17 02:20:36 +04:00
*/
2006-05-27 00:36:00 +04:00
/* Verify that there is a method object associated with this node */
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
info - > obj_desc =
acpi_ns_get_attached_object ( info - > resolved_node ) ;
if ( ! info - > obj_desc ) {
ACPI_ERROR ( ( AE_INFO ,
" Control method has no attached sub-object " ) ) ;
return_ACPI_STATUS ( AE_NULL_OBJECT ) ;
}
2005-04-17 02:20:36 +04:00
2008-11-13 06:19:24 +03:00
/* Count the number of arguments being passed to the method */
2008-06-10 08:25:42 +04:00
if ( info - > parameters ) {
2008-11-13 06:19:24 +03:00
while ( info - > parameters [ info - > param_count ] ) {
if ( info - > param_count > ACPI_METHOD_MAX_ARG ) {
return_ACPI_STATUS ( AE_LIMIT ) ;
}
2008-06-10 08:25:42 +04:00
info - > param_count + + ;
2008-11-13 06:19:24 +03:00
}
2008-06-10 08:25:42 +04:00
}
2006-05-27 00:36:00 +04:00
ACPI_DUMP_PATHNAME ( info - > resolved_node , " Execute Method: " ,
ACPI_LV_INFO , _COMPONENT ) ;
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_EXEC ,
" Method at AML address %p Length %X \n " ,
info - > obj_desc - > method . aml_start + 1 ,
info - > obj_desc - > method . aml_length - 1 ) ) ;
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
/*
* Any namespace deletion must acquire both the namespace and
* interpreter locks to ensure that no thread is using the portion of
* the namespace that is being deleted .
*
* Execute the method via the interpreter . The interpreter is locked
* here before calling into the AML parser
*/
2007-05-10 06:56:38 +04:00
acpi_ex_enter_interpreter ( ) ;
2006-05-27 00:36:00 +04:00
status = acpi_ps_execute_method ( info ) ;
acpi_ex_exit_interpreter ( ) ;
} else {
/*
* 2 ) Object is not a method , return its current value
2008-09-27 06:29:31 +04:00
*
* Disallow certain object types . For these , " evaluation " is undefined .
2006-05-27 00:36:00 +04:00
*/
2008-09-27 06:29:31 +04:00
switch ( info - > resolved_node - > type ) {
case ACPI_TYPE_DEVICE :
case ACPI_TYPE_EVENT :
case ACPI_TYPE_MUTEX :
case ACPI_TYPE_REGION :
case ACPI_TYPE_THERMAL :
case ACPI_TYPE_LOCAL_SCOPE :
ACPI_ERROR ( ( AE_INFO ,
" [%4.4s] Evaluation of object type [%s] is not supported " ,
info - > resolved_node - > name . ascii ,
acpi_ut_get_type_name ( info - > resolved_node - >
type ) ) ) ;
return_ACPI_STATUS ( AE_TYPE ) ;
default :
break ;
}
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
/*
* Objects require additional resolution steps ( e . g . , the Node may be
* a field that must be read , etc . ) - - we can ' t just grab the object
* out of the node .
*
* Use resolve_node_to_value ( ) to get the associated value .
*
* NOTE : we can get away with passing in NULL for a walk state because
* resolved_node is guaranteed to not be a reference to either a method
* local or a method argument ( because this interface is never called
* from a running method . )
*
* Even though we do not directly invoke the interpreter for object
* resolution , we must lock it because we could access an opregion .
* The opregion access code assumes that the interpreter is locked .
*/
2007-05-10 06:56:38 +04:00
acpi_ex_enter_interpreter ( ) ;
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
/* Function has a strange interface */
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
status =
acpi_ex_resolve_node_to_value ( & info - > resolved_node , NULL ) ;
acpi_ex_exit_interpreter ( ) ;
2005-04-17 02:20:36 +04:00
/*
* If acpi_ex_resolve_node_to_value ( ) succeeded , the return value was placed
* in resolved_node .
*/
2005-08-05 08:44:28 +04:00
if ( ACPI_SUCCESS ( status ) ) {
2005-04-17 02:20:36 +04:00
status = AE_CTRL_RETURN_VALUE ;
2006-05-27 00:36:00 +04:00
info - > return_object =
ACPI_CAST_PTR ( union acpi_operand_object ,
info - > resolved_node ) ;
2005-08-05 08:44:28 +04:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_NAMES ,
" Returning object %p [%s] \n " ,
info - > return_object ,
acpi_ut_get_object_type_name ( info - >
return_object ) ) ) ;
2005-04-17 02:20:36 +04:00
}
}
2008-11-13 06:19:24 +03:00
/*
* Check input argument count against the ASL - defined count for a method .
* Also check predefined names : argument count and return value against
* the ACPI specification . Some incorrect return value types are repaired .
*/
( void ) acpi_ns_check_predefined_names ( node , info - > param_count ,
status , & info - > return_object ) ;
2008-09-28 11:26:17 +04:00
/* Check if there is a return value that must be dealt with */
2006-05-27 00:36:00 +04:00
if ( status = = AE_CTRL_RETURN_VALUE ) {
/* If caller does not want the return value, delete it */
2005-04-17 02:20:36 +04:00
2006-05-27 00:36:00 +04:00
if ( info - > flags & ACPI_IGNORE_RETURN_VALUE ) {
acpi_ut_remove_reference ( info - > return_object ) ;
info - > return_object = NULL ;
}
/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
status = AE_OK ;
}
ACPI_DEBUG_PRINT ( ( ACPI_DB_NAMES ,
" *** Completed evaluation of object %s *** \n " ,
info - > pathname ) ) ;
/*
* Namespace was unlocked by the handling acpi_ns * function , so we
* just return
*/
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}