Commit 29a241cc authored by Bob Moore's avatar Bob Moore Committed by Rafael J. Wysocki

ACPICA: Add argument typechecking for all predefined ACPI names

Fully implements typechecking on all incoming arguments for all
predefined names. This ensures that ACPI-related drivers are
passing the correct number of arguments, each of the correct
object type.
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Acked-by: default avatarLen Brown <len.brown@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent e1405ca5
...@@ -83,6 +83,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o ...@@ -83,6 +83,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
acpi-y += \ acpi-y += \
nsaccess.o \ nsaccess.o \
nsalloc.o \ nsalloc.o \
nsarguments.o \
nsconvert.o \ nsconvert.o \
nsdump.o \ nsdump.o \
nseval.o \ nseval.o \
......
...@@ -362,23 +362,6 @@ union acpi_predefined_info { ...@@ -362,23 +362,6 @@ union acpi_predefined_info {
#pragma pack() #pragma pack()
/* Data block used during object validation */
struct acpi_predefined_data {
char *pathname;
const union acpi_predefined_info *predefined;
union acpi_operand_object *parent_package;
struct acpi_namespace_node *node;
u32 flags;
u32 return_btype;
u8 node_flags;
};
/* Defines for Flags field above */
#define ACPI_OBJECT_REPAIRED 1
#define ACPI_OBJECT_WRAPPED 2
/* Return object auto-repair info */ /* Return object auto-repair info */
typedef acpi_status(*acpi_object_converter) (union acpi_operand_object typedef acpi_status(*acpi_object_converter) (union acpi_operand_object
......
...@@ -223,22 +223,33 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); ...@@ -223,22 +223,33 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info);
void acpi_ns_exec_module_code_list(void); void acpi_ns_exec_module_code_list(void);
/* /*
* nspredef - Support for predefined/reserved names * nsarguments - Argument count/type checking for predefined/reserved names
*/ */
acpi_status void
acpi_ns_check_predefined_names(struct acpi_namespace_node *node, acpi_ns_check_argument_count(char *pathname,
u32 user_param_count, struct acpi_namespace_node *node,
acpi_status return_status, u32 user_param_count,
union acpi_operand_object **return_object); const union acpi_predefined_info *info);
void void
acpi_ns_check_parameter_count(char *pathname, acpi_ns_check_acpi_compliance(char *pathname,
struct acpi_namespace_node *node, struct acpi_namespace_node *node,
u32 user_param_count, const union acpi_predefined_info *predefined);
const union acpi_predefined_info *info);
void acpi_ns_check_argument_types(struct acpi_evaluate_info *info);
/*
* nspredef - Return value checking for predefined/reserved names
*/
acpi_status
acpi_ns_check_return_value(struct acpi_namespace_node *node,
struct acpi_evaluate_info *info,
u32 user_param_count,
acpi_status return_status,
union acpi_operand_object **return_object);
acpi_status acpi_status
acpi_ns_check_object_type(struct acpi_predefined_data *data, acpi_ns_check_object_type(struct acpi_evaluate_info *info,
union acpi_operand_object **return_object_ptr, union acpi_operand_object **return_object_ptr,
u32 expected_btypes, u32 package_index); u32 expected_btypes, u32 package_index);
...@@ -246,7 +257,7 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, ...@@ -246,7 +257,7 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
* nsprepkg - Validation of predefined name packages * nsprepkg - Validation of predefined name packages
*/ */
acpi_status acpi_status
acpi_ns_check_package(struct acpi_predefined_data *data, acpi_ns_check_package(struct acpi_evaluate_info *info,
union acpi_operand_object **return_object_ptr); union acpi_operand_object **return_object_ptr);
/* /*
...@@ -308,24 +319,24 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node, ...@@ -308,24 +319,24 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node,
* predefined methods/objects * predefined methods/objects
*/ */
acpi_status acpi_status
acpi_ns_simple_repair(struct acpi_predefined_data *data, acpi_ns_simple_repair(struct acpi_evaluate_info *info,
u32 expected_btypes, u32 expected_btypes,
u32 package_index, u32 package_index,
union acpi_operand_object **return_object_ptr); union acpi_operand_object **return_object_ptr);
acpi_status acpi_status
acpi_ns_wrap_with_package(struct acpi_predefined_data *data, acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
union acpi_operand_object *original_object, union acpi_operand_object *original_object,
union acpi_operand_object **obj_desc_ptr); union acpi_operand_object **obj_desc_ptr);
acpi_status acpi_status
acpi_ns_repair_null_element(struct acpi_predefined_data *data, acpi_ns_repair_null_element(struct acpi_evaluate_info *info,
u32 expected_btypes, u32 expected_btypes,
u32 package_index, u32 package_index,
union acpi_operand_object **return_object_ptr); union acpi_operand_object **return_object_ptr);
void void
acpi_ns_remove_null_elements(struct acpi_predefined_data *data, acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
u8 package_type, u8 package_type,
union acpi_operand_object *obj_desc); union acpi_operand_object *obj_desc);
...@@ -334,7 +345,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, ...@@ -334,7 +345,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
* predefined methods/objects * predefined methods/objects
*/ */
acpi_status acpi_status
acpi_ns_complex_repairs(struct acpi_predefined_data *data, acpi_ns_complex_repairs(struct acpi_evaluate_info *info,
struct acpi_namespace_node *node, struct acpi_namespace_node *node,
acpi_status validate_status, acpi_status validate_status,
union acpi_operand_object **return_object_ptr); union acpi_operand_object **return_object_ptr);
......
...@@ -128,8 +128,8 @@ enum acpi_return_package_types { ...@@ -128,8 +128,8 @@ enum acpi_return_package_types {
#define ARG_COUNT_IS_MINIMUM 0x8000 #define ARG_COUNT_IS_MINIMUM 0x8000
#define METHOD_MAX_ARG_TYPE ACPI_TYPE_PACKAGE #define METHOD_MAX_ARG_TYPE ACPI_TYPE_PACKAGE
#define METHOD_GET_COUNT(arg_list) (arg_list & METHOD_ARG_MASK) #define METHOD_GET_ARG_COUNT(arg_list) ((arg_list) & METHOD_ARG_MASK)
#define METHOD_GET_NEXT_ARG(arg_list) (arg_list >> METHOD_ARG_BIT_WIDTH) #define METHOD_GET_NEXT_TYPE(arg_list) (((arg_list) >>= METHOD_ARG_BIT_WIDTH) & METHOD_ARG_MASK)
/* Macros used to build the predefined info table */ /* Macros used to build the predefined info table */
......
...@@ -178,25 +178,41 @@ union acpi_aml_operands { ...@@ -178,25 +178,41 @@ union acpi_aml_operands {
}; };
/* /*
* Structure used to pass object evaluation parameters. * Structure used to pass object evaluation information and parameters.
* Purpose is to reduce CPU stack use. * Purpose is to reduce CPU stack use.
*/ */
struct acpi_evaluate_info { struct acpi_evaluate_info {
struct acpi_namespace_node *prefix_node; /* The first 3 elements are passed by the caller to acpi_ns_evaluate */
char *pathname;
union acpi_operand_object *obj_desc; struct acpi_namespace_node *prefix_node; /* Input: starting node */
union acpi_operand_object **parameters; char *relative_pathname; /* Input: path relative to prefix_node */
struct acpi_namespace_node *resolved_node; union acpi_operand_object **parameters; /* Input: argument list */
union acpi_operand_object *return_object;
u8 param_count; struct acpi_namespace_node *node; /* Resolved node (prefix_node:relative_pathname) */
u8 pass_number; union acpi_operand_object *obj_desc; /* Object attached to the resolved node */
u8 return_object_type; char *full_pathname; /* Full pathname of the resolved node */
u8 flags;
const union acpi_predefined_info *predefined; /* Used if Node is a predefined name */
union acpi_operand_object *return_object; /* Object returned from the evaluation */
union acpi_operand_object *parent_package; /* Used if return object is a Package */
u32 return_flags; /* Used for return value analysis */
u32 return_btype; /* Bitmapped type of the returned object */
u16 param_count; /* Count of the input argument list */
u8 pass_number; /* Parser pass number */
u8 return_object_type; /* Object type of the returned object */
u8 node_flags; /* Same as Node->Flags */
u8 flags; /* General flags */
}; };
/* Values for Flags above */ /* Values for Flags above */
#define ACPI_IGNORE_RETURN_VALUE 1 #define ACPI_IGNORE_RETURN_VALUE 1
/* Defines for return_flags field above */
#define ACPI_OBJECT_REPAIRED 1
#define ACPI_OBJECT_WRAPPED 2
/* Info used by acpi_ns_initialize_devices */ /* Info used by acpi_ns_initialize_devices */
......
...@@ -579,7 +579,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) ...@@ -579,7 +579,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
(local_gpe_event_info->dispatch. (local_gpe_event_info->dispatch.
method_node))); method_node)));
} }
break; break;
default: default:
......
...@@ -532,7 +532,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) ...@@ -532,7 +532,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
} }
info->prefix_node = region_obj2->extra.method_REG; info->prefix_node = region_obj2->extra.method_REG;
info->pathname = NULL; info->relative_pathname = NULL;
info->parameters = args; info->parameters = args;
info->flags = ACPI_IGNORE_RETURN_VALUE; info->flags = ACPI_IGNORE_RETURN_VALUE;
......
...@@ -495,7 +495,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) ...@@ -495,7 +495,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
* Evaluate the \_Sx namespace object containing the register values * Evaluate the \_Sx namespace object containing the register values
* for this state * for this state
*/ */
info->pathname = info->relative_pathname =
ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
status = acpi_ns_evaluate(info); status = acpi_ns_evaluate(info);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -506,7 +506,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) ...@@ -506,7 +506,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
if (!info->return_object) { if (!info->return_object) {
ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
info->pathname)); info->relative_pathname));
status = AE_AML_NO_RETURN_VALUE; status = AE_AML_NO_RETURN_VALUE;
goto cleanup; goto cleanup;
} }
...@@ -565,7 +565,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) ...@@ -565,7 +565,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"While evaluating Sleep State [%s]", "While evaluating Sleep State [%s]",
info->pathname)); info->relative_pathname));
} }
ACPI_FREE(info); ACPI_FREE(info);
......
This diff is collapsed.
This diff is collapsed.
...@@ -176,7 +176,7 @@ acpi_status acpi_ns_initialize_devices(void) ...@@ -176,7 +176,7 @@ acpi_status acpi_ns_initialize_devices(void)
* part of the ACPI specification. * part of the ACPI specification.
*/ */
info.evaluate_info->prefix_node = acpi_gbl_root_node; info.evaluate_info->prefix_node = acpi_gbl_root_node;
info.evaluate_info->pathname = METHOD_NAME__INI; info.evaluate_info->relative_pathname = METHOD_NAME__INI;
info.evaluate_info->parameters = NULL; info.evaluate_info->parameters = NULL;
info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE; info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
...@@ -560,7 +560,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle, ...@@ -560,7 +560,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info)); ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
info->prefix_node = device_node; info->prefix_node = device_node;
info->pathname = METHOD_NAME__INI; info->relative_pathname = METHOD_NAME__INI;
info->parameters = NULL; info->parameters = NULL;
info->flags = ACPI_IGNORE_RETURN_VALUE; info->flags = ACPI_IGNORE_RETURN_VALUE;
...@@ -574,8 +574,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle, ...@@ -574,8 +574,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
/* Ignore error and move on to next device */ /* Ignore error and move on to next device */
char *scope_name = char *scope_name = acpi_ns_get_external_pathname(info->node);
acpi_ns_get_external_pathname(info->resolved_node);
ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution",
scope_name)); scope_name));
......
This diff is collapsed.
This diff is collapsed.
...@@ -130,7 +130,7 @@ static const struct acpi_simple_repair_info acpi_object_repair_info[] = { ...@@ -130,7 +130,7 @@ static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
* *
* FUNCTION: acpi_ns_simple_repair * FUNCTION: acpi_ns_simple_repair
* *
* PARAMETERS: data - Pointer to validation data structure * PARAMETERS: info - Method execution information block
* expected_btypes - Object types expected * expected_btypes - Object types expected
* package_index - Index of object within parent package (if * package_index - Index of object within parent package (if
* applicable - ACPI_NOT_PACKAGE_ELEMENT * applicable - ACPI_NOT_PACKAGE_ELEMENT
...@@ -146,7 +146,7 @@ static const struct acpi_simple_repair_info acpi_object_repair_info[] = { ...@@ -146,7 +146,7 @@ static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ns_simple_repair(struct acpi_predefined_data *data, acpi_ns_simple_repair(struct acpi_evaluate_info *info,
u32 expected_btypes, u32 expected_btypes,
u32 package_index, u32 package_index,
union acpi_operand_object **return_object_ptr) union acpi_operand_object **return_object_ptr)
...@@ -162,12 +162,12 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data, ...@@ -162,12 +162,12 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
* Special repairs for certain names that are in the repair table. * Special repairs for certain names that are in the repair table.
* Check if this name is in the list of repairable names. * Check if this name is in the list of repairable names.
*/ */
predefined = acpi_ns_match_simple_repair(data->node, predefined = acpi_ns_match_simple_repair(info->node,
data->return_btype, info->return_btype,
package_index); package_index);
if (predefined) { if (predefined) {
if (!return_object) { if (!return_object) {
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
ACPI_WARN_ALWAYS, ACPI_WARN_ALWAYS,
"Missing expected return value")); "Missing expected return value"));
} }
...@@ -191,7 +191,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data, ...@@ -191,7 +191,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
* Do not perform simple object repair unless the return type is not * Do not perform simple object repair unless the return type is not
* expected. * expected.
*/ */
if (data->return_btype & expected_btypes) { if (info->return_btype & expected_btypes) {
return (AE_OK); return (AE_OK);
} }
...@@ -211,7 +211,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data, ...@@ -211,7 +211,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
*/ */
if (!return_object) { if (!return_object) {
if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
ACPI_WARN_ALWAYS, ACPI_WARN_ALWAYS,
"Missing expected return value")); "Missing expected return value"));
...@@ -247,14 +247,14 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data, ...@@ -247,14 +247,14 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
* for correct contents (expected object type or types). * for correct contents (expected object type or types).
*/ */
status = status =
acpi_ns_wrap_with_package(data, return_object, &new_object); acpi_ns_wrap_with_package(info, return_object, &new_object);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
/* /*
* The original object just had its reference count * The original object just had its reference count
* incremented for being inserted into the new package. * incremented for being inserted into the new package.
*/ */
*return_object_ptr = new_object; /* New Package object */ *return_object_ptr = new_object; /* New Package object */
data->flags |= ACPI_OBJECT_REPAIRED; info->return_flags |= ACPI_OBJECT_REPAIRED;
return (AE_OK); return (AE_OK);
} }
} }
...@@ -277,7 +277,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data, ...@@ -277,7 +277,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
* package object as part of the repair, we don't need to * package object as part of the repair, we don't need to
* change the reference count. * change the reference count.
*/ */
if (!(data->flags & ACPI_OBJECT_WRAPPED)) { if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) {
new_object->common.reference_count = new_object->common.reference_count =
return_object->common.reference_count; return_object->common.reference_count;
...@@ -288,14 +288,14 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data, ...@@ -288,14 +288,14 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
"%s: Converted %s to expected %s at Package index %u\n", "%s: Converted %s to expected %s at Package index %u\n",
data->pathname, info->full_pathname,
acpi_ut_get_object_type_name(return_object), acpi_ut_get_object_type_name(return_object),
acpi_ut_get_object_type_name(new_object), acpi_ut_get_object_type_name(new_object),
package_index)); package_index));
} else { } else {
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
"%s: Converted %s to expected %s\n", "%s: Converted %s to expected %s\n",
data->pathname, info->full_pathname,
acpi_ut_get_object_type_name(return_object), acpi_ut_get_object_type_name(return_object),
acpi_ut_get_object_type_name(new_object))); acpi_ut_get_object_type_name(new_object)));
} }
...@@ -304,7 +304,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data, ...@@ -304,7 +304,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
acpi_ut_remove_reference(return_object); acpi_ut_remove_reference(return_object);
*return_object_ptr = new_object; *return_object_ptr = new_object;
data->flags |= ACPI_OBJECT_REPAIRED; info->return_flags |= ACPI_OBJECT_REPAIRED;
return (AE_OK); return (AE_OK);
} }
...@@ -359,7 +359,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct ...@@ -359,7 +359,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
* *
* FUNCTION: acpi_ns_repair_null_element * FUNCTION: acpi_ns_repair_null_element
* *
* PARAMETERS: data - Pointer to validation data structure * PARAMETERS: info - Method execution information block
* expected_btypes - Object types expected * expected_btypes - Object types expected
* package_index - Index of object within parent package (if * package_index - Index of object within parent package (if
* applicable - ACPI_NOT_PACKAGE_ELEMENT * applicable - ACPI_NOT_PACKAGE_ELEMENT
...@@ -374,7 +374,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct ...@@ -374,7 +374,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ns_repair_null_element(struct acpi_predefined_data *data, acpi_ns_repair_null_element(struct acpi_evaluate_info * info,
u32 expected_btypes, u32 expected_btypes,
u32 package_index, u32 package_index,
union acpi_operand_object **return_object_ptr) union acpi_operand_object **return_object_ptr)
...@@ -424,16 +424,16 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data, ...@@ -424,16 +424,16 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data,
/* Set the reference count according to the parent Package object */ /* Set the reference count according to the parent Package object */
new_object->common.reference_count = new_object->common.reference_count =
data->parent_package->common.reference_count; info->parent_package->common.reference_count;
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
"%s: Converted NULL package element to expected %s at index %u\n", "%s: Converted NULL package element to expected %s at index %u\n",
data->pathname, info->full_pathname,
acpi_ut_get_object_type_name(new_object), acpi_ut_get_object_type_name(new_object),
package_index)); package_index));
*return_object_ptr = new_object; *return_object_ptr = new_object;
data->flags |= ACPI_OBJECT_REPAIRED; info->return_flags |= ACPI_OBJECT_REPAIRED;
return (AE_OK); return (AE_OK);
} }
...@@ -441,7 +441,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data, ...@@ -441,7 +441,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data,
* *
* FUNCTION: acpi_ns_remove_null_elements * FUNCTION: acpi_ns_remove_null_elements
* *
* PARAMETERS: data - Pointer to validation data structure * PARAMETERS: info - Method execution information block
* package_type - An acpi_return_package_types value * package_type - An acpi_return_package_types value
* obj_desc - A Package object * obj_desc - A Package object
* *
...@@ -454,7 +454,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data, ...@@ -454,7 +454,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data,
*****************************************************************************/ *****************************************************************************/
void void
acpi_ns_remove_null_elements(struct acpi_predefined_data *data, acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
u8 package_type, u8 package_type,
union acpi_operand_object *obj_desc) union acpi_operand_object *obj_desc)
{ {
...@@ -511,7 +511,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, ...@@ -511,7 +511,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
if (new_count < count) { if (new_count < count) {
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
"%s: Found and removed %u NULL elements\n", "%s: Found and removed %u NULL elements\n",
data->pathname, (count - new_count))); info->full_pathname, (count - new_count)));
/* NULL terminate list and update the package count */ /* NULL terminate list and update the package count */
...@@ -524,7 +524,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, ...@@ -524,7 +524,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
* *
* FUNCTION: acpi_ns_wrap_with_package * FUNCTION: acpi_ns_wrap_with_package
* *
* PARAMETERS: data - Pointer to validation data structure * PARAMETERS: info - Method execution information block
* original_object - Pointer to the object to repair. * original_object - Pointer to the object to repair.
* obj_desc_ptr - The new package object is returned here * obj_desc_ptr - The new package object is returned here
* *
...@@ -545,7 +545,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, ...@@ -545,7 +545,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ns_wrap_with_package(struct acpi_predefined_data *data, acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
union acpi_operand_object *original_object, union acpi_operand_object *original_object,
union acpi_operand_object **obj_desc_ptr) union acpi_operand_object **obj_desc_ptr)
{ {
...@@ -566,12 +566,12 @@ acpi_ns_wrap_with_package(struct acpi_predefined_data *data, ...@@ -566,12 +566,12 @@ acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
"%s: Wrapped %s with expected Package object\n", "%s: Wrapped %s with expected Package object\n",
data->pathname, info->full_pathname,
acpi_ut_get_object_type_name(original_object))); acpi_ut_get_object_type_name(original_object)));
/* Return the new object in the object pointer */ /* Return the new object in the object pointer */
*obj_desc_ptr = pkg_obj_desc; *obj_desc_ptr = pkg_obj_desc;
data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
return (AE_OK); return (AE_OK);
} }
This diff is collapsed.
...@@ -187,8 +187,6 @@ acpi_evaluate_object(acpi_handle handle, ...@@ -187,8 +187,6 @@ acpi_evaluate_object(acpi_handle handle,
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
info->pathname = pathname;
/* Convert and validate the device handle */ /* Convert and validate the device handle */
info->prefix_node = acpi_ns_validate_handle(handle); info->prefix_node = acpi_ns_validate_handle(handle);
...@@ -198,17 +196,64 @@ acpi_evaluate_object(acpi_handle handle, ...@@ -198,17 +196,64 @@ acpi_evaluate_object(acpi_handle handle,
} }
/* /*
* If there are parameters to be passed to a control method, the external * Get the actual namespace node for the target object.
* objects must all be converted to internal objects * Handles these cases:
*
* 1) Null node, valid pathname from root (absolute path)
* 2) Node and valid pathname (path relative to Node)
* 3) Node, Null pathname
*/
if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
/* The path is fully qualified, just evaluate by name */
info->prefix_node = NULL;
} else if (!handle) {
/*
* A handle is optional iff a fully qualified pathname is specified.
* Since we've already handled fully qualified names above, this is
* an error.
*/
if (!pathname) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Both Handle and Pathname are NULL"));
} else {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Null Handle with relative pathname [%s]",
pathname));
}
status = AE_BAD_PARAMETER;
goto cleanup;
}
info->relative_pathname = pathname;
/*
* Convert all external objects passed as arguments to the
* internal version(s).
*/ */
if (external_params && external_params->count) { if (external_params && external_params->count) {
info->param_count = (u16)external_params->count;
/* Warn on impossible argument count */
if (info->param_count > ACPI_METHOD_NUM_ARGS) {
ACPI_WARN_PREDEFINED((AE_INFO, pathname,
ACPI_WARN_ALWAYS,
"Excess arguments (%u) - using only %u",
info->param_count,
ACPI_METHOD_NUM_ARGS));
info->param_count = ACPI_METHOD_NUM_ARGS;
}
/* /*
* Allocate a new parameter block for the internal objects * Allocate a new parameter block for the internal objects
* Add 1 to count to allow for null terminated internal list * Add 1 to count to allow for null terminated internal list
*/ */
info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) info->
external_params-> param_count +
count +
1) * sizeof(void *)); 1) * sizeof(void *));
if (!info->parameters) { if (!info->parameters) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
...@@ -217,7 +262,7 @@ acpi_evaluate_object(acpi_handle handle, ...@@ -217,7 +262,7 @@ acpi_evaluate_object(acpi_handle handle,
/* Convert each external object in the list to an internal object */ /* Convert each external object in the list to an internal object */
for (i = 0; i < external_params->count; i++) { for (i = 0; i < info->param_count; i++) {
status = status =
acpi_ut_copy_eobject_to_iobject(&external_params-> acpi_ut_copy_eobject_to_iobject(&external_params->
pointer[i], pointer[i],
...@@ -227,43 +272,96 @@ acpi_evaluate_object(acpi_handle handle, ...@@ -227,43 +272,96 @@ acpi_evaluate_object(acpi_handle handle,
goto cleanup; goto cleanup;
} }
} }
info->parameters[external_params->count] = NULL;
info->parameters[info->param_count] = NULL;
} }
#if 0
/* /*
* Three major cases: * Begin incoming argument count analysis. Check for too few args
* 1) Fully qualified pathname * and too many args.
* 2) No handle, not fully qualified pathname (error)
* 3) Valid handle
*/ */
if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
/* The path is fully qualified, just evaluate by name */ switch (acpi_ns_get_type(info->node)) {
case ACPI_TYPE_METHOD:
/* Check incoming argument count against the method definition */
if (info->obj_desc->method.param_count > info->param_count) {
ACPI_ERROR((AE_INFO,
"Insufficient arguments (%u) - %u are required",
info->param_count,
info->obj_desc->method.param_count));
status = AE_MISSING_ARGUMENTS;
goto cleanup;
}
else if (info->obj_desc->method.param_count < info->param_count) {
ACPI_WARNING((AE_INFO,
"Excess arguments (%u) - only %u are required",
info->param_count,
info->obj_desc->method.param_count));
/* Just pass the required number of arguments */
info->param_count = info->obj_desc->method.param_count;
}
info->prefix_node = NULL;
status = acpi_ns_evaluate(info);
} else if (!handle) {
/* /*
* A handle is optional iff a fully qualified pathname is specified. * Any incoming external objects to be passed as arguments to the
* Since we've already handled fully qualified names above, this is * method must be converted to internal objects
* an error
*/ */
if (!pathname) { if (info->param_count) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, /*
"Both Handle and Pathname are NULL")); * Allocate a new parameter block for the internal objects
} else { * Add 1 to count to allow for null terminated internal list
ACPI_DEBUG_PRINT((ACPI_DB_INFO, */
"Null Handle with relative pathname [%s]", info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
pathname)); info->
param_count +
1) *
sizeof(void *));
if (!info->parameters) {
status = AE_NO_MEMORY;
goto cleanup;
}
/* Convert each external object in the list to an internal object */
for (i = 0; i < info->param_count; i++) {
status =
acpi_ut_copy_eobject_to_iobject
(&external_params->pointer[i],
&info->parameters[i]);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
}
info->parameters[info->param_count] = NULL;
} }
break;
status = AE_BAD_PARAMETER; default:
} else {
/* We have a namespace a node and a possible relative path */
status = acpi_ns_evaluate(info); /* Warn if arguments passed to an object that is not a method */
if (info->param_count) {
ACPI_WARNING((AE_INFO,
"%u arguments were passed to a non-method ACPI object",
info->param_count));
}
break;
} }
#endif
/* Now we can evaluate the object */
status = acpi_ns_evaluate(info);
/* /*
* If we are expecting a return value, and all went well above, * If we are expecting a return value, and all went well above,
* copy the return value to an external object. * copy the return value to an external object.
......
...@@ -125,7 +125,7 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info) ...@@ -125,7 +125,7 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info)
} }
if ((!acpi_gbl_trace_method_name) || if ((!acpi_gbl_trace_method_name) ||
(acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { (acpi_gbl_trace_method_name != info->node->name.integer)) {
goto exit; goto exit;
} }
...@@ -170,7 +170,7 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) ...@@ -170,7 +170,7 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info)
} }
if ((!acpi_gbl_trace_method_name) || if ((!acpi_gbl_trace_method_name) ||
(acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { (acpi_gbl_trace_method_name != info->node->name.integer)) {
goto exit; goto exit;
} }
...@@ -226,15 +226,14 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) ...@@ -226,15 +226,14 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
/* Validate the Info and method Node */ /* Validate the Info and method Node */
if (!info || !info->resolved_node) { if (!info || !info->node) {
return_ACPI_STATUS(AE_NULL_ENTRY); return_ACPI_STATUS(AE_NULL_ENTRY);
} }
/* Init for new method, wait on concurrency semaphore */ /* Init for new method, wait on concurrency semaphore */
status = status =
acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc, acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -253,8 +252,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) ...@@ -253,8 +252,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
*/ */
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
"**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n", "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
info->resolved_node->name.ascii, info->resolved_node, info->node->name.ascii, info->node, info->obj_desc));
info->obj_desc));
/* Create and init a Root Node */ /* Create and init a Root Node */
...@@ -275,7 +273,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) ...@@ -275,7 +273,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
goto cleanup; goto cleanup;
} }
status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, status = acpi_ds_init_aml_walk(walk_state, op, info->node,
info->obj_desc->method.aml_start, info->obj_desc->method.aml_start,
info->obj_desc->method.aml_length, info, info->obj_desc->method.aml_length, info,
info->pass_number); info->pass_number);
......
...@@ -736,7 +736,7 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, ...@@ -736,7 +736,7 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
} }
info->prefix_node = node; info->prefix_node = node;
info->pathname = METHOD_NAME__SRS; info->relative_pathname = METHOD_NAME__SRS;
info->parameters = args; info->parameters = args;
info->flags = ACPI_IGNORE_RETURN_VALUE; info->flags = ACPI_IGNORE_RETURN_VALUE;
......
...@@ -87,7 +87,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node, ...@@ -87,7 +87,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node,
} }
info->prefix_node = prefix_node; info->prefix_node = prefix_node;
info->pathname = path; info->relative_pathname = path;
/* Evaluate the object/method */ /* Evaluate the object/method */
......
...@@ -147,6 +147,11 @@ void acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes) ...@@ -147,6 +147,11 @@ void acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes)
u32 i; u32 i;
u32 j; u32 j;
if (!expected_btypes) {
ACPI_STRCPY(buffer, "NONE");
return;
}
j = 1; j = 1;
buffer[0] = 0; buffer[0] = 0;
this_rtype = ACPI_RTYPE_INTEGER; this_rtype = ACPI_RTYPE_INTEGER;
...@@ -328,9 +333,7 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types) ...@@ -328,9 +333,7 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types)
/* First field in the types list is the count of args to follow */ /* First field in the types list is the count of args to follow */
arg_count = (argument_types & METHOD_ARG_MASK); arg_count = METHOD_GET_ARG_COUNT(argument_types);
argument_types >>= METHOD_ARG_BIT_WIDTH;
if (arg_count > METHOD_PREDEF_ARGS_MAX) { if (arg_count > METHOD_PREDEF_ARGS_MAX) {
printf("**** Invalid argument count (%u) " printf("**** Invalid argument count (%u) "
"in predefined info structure\n", arg_count); "in predefined info structure\n", arg_count);
...@@ -340,7 +343,8 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types) ...@@ -340,7 +343,8 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types)
/* Get each argument from the list, convert to ascii, store to buffer */ /* Get each argument from the list, convert to ascii, store to buffer */
for (i = 0; i < arg_count; i++) { for (i = 0; i < arg_count; i++) {
this_argument_type = (argument_types & METHOD_ARG_MASK); this_argument_type = METHOD_GET_NEXT_TYPE(argument_types);
if (!this_argument_type if (!this_argument_type
|| (this_argument_type > METHOD_MAX_ARG_TYPE)) { || (this_argument_type > METHOD_MAX_ARG_TYPE)) {
printf("**** Invalid argument type (%u) " printf("**** Invalid argument type (%u) "
...@@ -351,10 +355,6 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types) ...@@ -351,10 +355,6 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types)
strcat(buffer, strcat(buffer,
ut_external_type_names[this_argument_type] + sub_index); ut_external_type_names[this_argument_type] + sub_index);
/* Shift to next argument type field */
argument_types >>= METHOD_ARG_BIT_WIDTH;
sub_index = 0; sub_index = 0;
} }
......
...@@ -219,8 +219,8 @@ ...@@ -219,8 +219,8 @@
* *
*****************************************************************************/ *****************************************************************************/
#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */ #define ACPI_DEBUGGER_MAX_ARGS ACPI_METHOD_NUM_ARGS + 4 /* Max command line arguments */
#define ACPI_DB_LINE_BUFFER_SIZE 512 #define ACPI_DB_LINE_BUFFER_SIZE 512
#define ACPI_DEBUGGER_COMMAND_PROMPT '-' #define ACPI_DEBUGGER_COMMAND_PROMPT '-'
#define ACPI_DEBUGGER_EXECUTE_PROMPT '%' #define ACPI_DEBUGGER_EXECUTE_PROMPT '%'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment