2018-03-14 16:13:07 -07:00
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2013-05-30 10:00:01 +08:00
/******************************************************************************
*
* Module Name : nsarguments - Validation of args for ACPI predefined methods
*
2018-01-04 10:06:38 -08:00
* Copyright ( C ) 2000 - 2018 , Intel Corp .
2013-05-30 10:00:01 +08:00
*
2018-03-14 16:13:07 -07:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-05-30 10:00:01 +08:00
# include <acpi/acpi.h>
# include "accommon.h"
# include "acnamesp.h"
# include "acpredef.h"
# define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ( " nsarguments " )
/*******************************************************************************
*
* FUNCTION : acpi_ns_check_argument_types
*
* PARAMETERS : info - Method execution information block
*
* RETURN : None
*
* DESCRIPTION : Check the incoming argument count and all argument types
* against the argument type list for a predefined name .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void acpi_ns_check_argument_types ( struct acpi_evaluate_info * info )
{
u16 arg_type_list ;
u8 arg_count ;
u8 arg_type ;
u8 user_arg_type ;
u32 i ;
2017-08-03 14:27:22 +08:00
/*
* If not a predefined name , cannot typecheck args , because
* we have no idea what argument types are expected .
* Also , ignore typecheck if warnings / errors if this method
* has already been evaluated at least once - - in order
* to suppress repetitive messages .
*/
if ( ! info - > predefined | | ( info - > node - > flags & ANOBJ_EVALUATED ) ) {
2013-05-30 10:00:01 +08:00
return ;
}
arg_type_list = info - > predefined - > info . argument_list ;
arg_count = METHOD_GET_ARG_COUNT ( arg_type_list ) ;
/* Typecheck all arguments */
for ( i = 0 ; ( ( i < arg_count ) & & ( i < info - > param_count ) ) ; i + + ) {
arg_type = METHOD_GET_NEXT_TYPE ( arg_type_list ) ;
user_arg_type = info - > parameters [ i ] - > common . type ;
if ( user_arg_type ! = arg_type ) {
ACPI_WARN_PREDEFINED ( ( AE_INFO , info - > full_pathname ,
ACPI_WARN_ALWAYS ,
" Argument #%u type mismatch - "
" Found [%s], ACPI requires [%s] " ,
( i + 1 ) ,
acpi_ut_get_type_name
( user_arg_type ) ,
acpi_ut_get_type_name ( arg_type ) ) ) ;
2017-08-03 14:27:22 +08:00
/* Prevent any additional typechecking for this method */
info - > node - > flags | = ANOBJ_EVALUATED ;
2013-05-30 10:00:01 +08:00
}
}
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_check_acpi_compliance
*
* PARAMETERS : pathname - Full pathname to the node ( for error msgs )
* node - Namespace node for the method / object
* predefined - Pointer to entry in predefined name table
*
* RETURN : None
*
* DESCRIPTION : Check that the declared parameter count ( in ASL / AML ) for a
* predefined name is what is expected ( matches what is defined in
* the ACPI specification for this predefined name . )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
acpi_ns_check_acpi_compliance ( char * pathname ,
struct acpi_namespace_node * node ,
const union acpi_predefined_info * predefined )
{
u32 aml_param_count ;
u32 required_param_count ;
2017-08-03 14:27:22 +08:00
if ( ! predefined | | ( node - > flags & ANOBJ_EVALUATED ) ) {
2013-05-30 10:00:01 +08:00
return ;
}
/* Get the ACPI-required arg count from the predefined info table */
required_param_count =
METHOD_GET_ARG_COUNT ( predefined - > info . argument_list ) ;
/*
* If this object is not a control method , we can check if the ACPI
* spec requires that it be a method .
*/
if ( node - > type ! = ACPI_TYPE_METHOD ) {
if ( required_param_count > 0 ) {
/* Object requires args, must be implemented as a method */
ACPI_BIOS_ERROR_PREDEFINED ( ( AE_INFO , pathname ,
ACPI_WARN_ALWAYS ,
" Object (%s) must be a control method with %u arguments " ,
acpi_ut_get_type_name ( node - >
type ) ,
required_param_count ) ) ;
} else if ( ! required_param_count
& & ! predefined - > info . expected_btypes ) {
/* Object requires no args and no return value, must be a method */
ACPI_BIOS_ERROR_PREDEFINED ( ( AE_INFO , pathname ,
ACPI_WARN_ALWAYS ,
" Object (%s) must be a control method "
" with no arguments and no return value " ,
acpi_ut_get_type_name ( node - >
type ) ) ) ;
}
return ;
}
/*
* This is a control method .
* Check that the ASL / AML - defined parameter count for this method
* matches the ACPI - required parameter count
*
* Some methods are allowed to have a " minimum " number of args ( _SCP )
* because their definition in ACPI has changed over time .
*
* Note : These are BIOS errors in the declaration of the object
*/
aml_param_count = node - > object - > method . param_count ;
if ( aml_param_count < required_param_count ) {
ACPI_BIOS_ERROR_PREDEFINED ( ( AE_INFO , pathname , ACPI_WARN_ALWAYS ,
" Insufficient arguments - "
" ASL declared %u, ACPI requires %u " ,
aml_param_count ,
required_param_count ) ) ;
} else if ( ( aml_param_count > required_param_count )
& & ! ( predefined - > info .
argument_list & ARG_COUNT_IS_MINIMUM ) ) {
ACPI_BIOS_ERROR_PREDEFINED ( ( AE_INFO , pathname , ACPI_WARN_ALWAYS ,
" Excess arguments - "
" ASL declared %u, ACPI requires %u " ,
aml_param_count ,
required_param_count ) ) ;
}
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_check_argument_count
*
* PARAMETERS : pathname - Full pathname to the node ( for error msgs )
* node - Namespace node for the method / object
* user_param_count - Number of args passed in by the caller
* predefined - Pointer to entry in predefined name table
*
* RETURN : None
*
* DESCRIPTION : Check that incoming argument count matches the declared
* parameter count ( in the ASL / AML ) for an object .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
acpi_ns_check_argument_count ( char * pathname ,
struct acpi_namespace_node * node ,
u32 user_param_count ,
const union acpi_predefined_info * predefined )
{
u32 aml_param_count ;
u32 required_param_count ;
2017-08-03 14:27:22 +08:00
if ( node - > flags & ANOBJ_EVALUATED ) {
return ;
}
2013-05-30 10:00:01 +08:00
if ( ! predefined ) {
/*
* Not a predefined name . Check the incoming user argument count
* against the count that is specified in the method / object .
*/
if ( node - > type ! = ACPI_TYPE_METHOD ) {
if ( user_param_count ) {
ACPI_INFO_PREDEFINED ( ( AE_INFO , pathname ,
ACPI_WARN_ALWAYS ,
" %u arguments were passed to a non-method ACPI object (%s) " ,
user_param_count ,
acpi_ut_get_type_name
( node - > type ) ) ) ;
}
return ;
}
/*
* This is a control method . Check the parameter count .
* We can only check the incoming argument count against the
* argument count declared for the method in the ASL / AML .
*
* Emit a message if too few or too many arguments have been passed
* by the caller .
*
* Note : Too many arguments will not cause the method to
* fail . However , the method will fail if there are too few
* arguments and the method attempts to use one of the missing ones .
*/
aml_param_count = node - > object - > method . param_count ;
if ( user_param_count < aml_param_count ) {
ACPI_WARN_PREDEFINED ( ( AE_INFO , pathname ,
ACPI_WARN_ALWAYS ,
" Insufficient arguments - "
" Caller passed %u, method requires %u " ,
user_param_count ,
aml_param_count ) ) ;
} else if ( user_param_count > aml_param_count ) {
ACPI_INFO_PREDEFINED ( ( AE_INFO , pathname ,
ACPI_WARN_ALWAYS ,
" Excess arguments - "
" Caller passed %u, method requires %u " ,
user_param_count ,
aml_param_count ) ) ;
}
return ;
}
/*
* This is a predefined name . Validate the user - supplied parameter
* count against the ACPI specification . We don ' t validate against
* the method itself because what is important here is that the
* caller is in conformance with the spec . ( The arg count for the
* method was checked against the ACPI spec earlier . )
*
* Some methods are allowed to have a " minimum " number of args ( _SCP )
* because their definition in ACPI has changed over time .
*/
required_param_count =
METHOD_GET_ARG_COUNT ( predefined - > info . argument_list ) ;
if ( user_param_count < required_param_count ) {
ACPI_WARN_PREDEFINED ( ( AE_INFO , pathname , ACPI_WARN_ALWAYS ,
" Insufficient arguments - "
" Caller passed %u, ACPI requires %u " ,
user_param_count , required_param_count ) ) ;
} else if ( ( user_param_count > required_param_count ) & &
! ( predefined - > info . argument_list & ARG_COUNT_IS_MINIMUM ) ) {
ACPI_INFO_PREDEFINED ( ( AE_INFO , pathname , ACPI_WARN_ALWAYS ,
" Excess arguments - "
" Caller passed %u, ACPI requires %u " ,
user_param_count , required_param_count ) ) ;
}
}