aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c20
-rw-r--r--drivers/acpi/dispatcher/dswexec.c2
-rw-r--r--drivers/acpi/dispatcher/dswstate.c5
-rw-r--r--drivers/acpi/events/evgpe.c39
-rw-r--r--drivers/acpi/events/evmisc.c18
-rw-r--r--drivers/acpi/events/evregion.c65
-rw-r--r--drivers/acpi/events/evrgnini.c5
-rw-r--r--drivers/acpi/executer/exconfig.c10
-rw-r--r--drivers/acpi/executer/exfldio.c24
-rw-r--r--drivers/acpi/executer/exmisc.c14
-rw-r--r--drivers/acpi/executer/exoparg1.c18
-rw-r--r--drivers/acpi/executer/exregion.c15
-rw-r--r--drivers/acpi/hardware/hwregs.c51
-rw-r--r--drivers/acpi/namespace/nsaccess.c6
-rw-r--r--drivers/acpi/namespace/nseval.c485
-rw-r--r--drivers/acpi/namespace/nsinit.c57
-rw-r--r--drivers/acpi/namespace/nssearch.c82
-rw-r--r--drivers/acpi/namespace/nsutils.c63
-rw-r--r--drivers/acpi/namespace/nsxfeval.c119
-rw-r--r--drivers/acpi/namespace/nsxfname.c5
-rw-r--r--drivers/acpi/parser/psparse.c1
-rw-r--r--drivers/acpi/parser/psxface.c37
-rw-r--r--drivers/acpi/resources/rsutils.c95
-rw-r--r--drivers/acpi/resources/rsxface.c368
-rw-r--r--drivers/acpi/tables/tbget.c40
-rw-r--r--drivers/acpi/tables/tbrsdt.c11
-rw-r--r--drivers/acpi/utilities/utalloc.c51
-rw-r--r--drivers/acpi/utilities/utdelete.c24
-rw-r--r--drivers/acpi/utilities/uteval.c45
-rw-r--r--drivers/acpi/utilities/utinit.c8
-rw-r--r--drivers/acpi/utilities/utmisc.c109
31 files changed, 905 insertions, 987 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index e348db0e541e..21f059986273 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -231,7 +231,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
struct acpi_namespace_node *method_node;
struct acpi_walk_state *next_walk_state = NULL;
union acpi_operand_object *obj_desc;
- struct acpi_parameter_info info;
+ struct acpi_evaluate_info *info;
u32 i;
ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state);
@@ -319,12 +319,24 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
*/
this_walk_state->operands[this_walk_state->num_operands] = NULL;
- info.parameters = &this_walk_state->operands[0];
- info.parameter_type = ACPI_PARAM_ARGS;
+ /*
+ * Allocate and initialize the evaluation information block
+ * TBD: this is somewhat inefficient, should change interface to
+ * ds_init_aml_walk. For now, keeps this struct off the CPU stack
+ */
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+ info->parameters = &this_walk_state->operands[0];
+ info->parameter_type = ACPI_PARAM_ARGS;
status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
obj_desc->method.aml_start,
- obj_desc->method.aml_length, &info, 3);
+ obj_desc->method.aml_length, info, 3);
+
+ ACPI_FREE(info);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 8afb20384e96..3acbd9145d72 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -295,7 +295,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
case AML_CLASS_NAMED_OBJECT:
- if (walk_state->walk_type == ACPI_WALK_METHOD) {
+ if (walk_state->walk_type & ACPI_WALK_METHOD) {
/*
* Found a named object declaration during method execution;
* we must enter this object into the namespace. The created
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 82c1e219bf15..7817e5522679 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -703,7 +703,7 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
struct acpi_namespace_node *method_node,
u8 * aml_start,
u32 aml_length,
- struct acpi_parameter_info *info, u8 pass_number)
+ struct acpi_evaluate_info *info, u8 pass_number)
{
acpi_status status;
struct acpi_parse_state *parser_state = &walk_state->parser_state;
@@ -825,9 +825,12 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
return;
}
+ /* There should not be any open scopes */
+
if (walk_state->parser_state.scope) {
ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
walk_state));
+ acpi_ps_cleanup_scope(&walk_state->parser_state);
}
/* Always must free any linked control states */
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index aa179dc78011..23fe53ba7375 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -488,9 +488,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
*
* RETURN: None
*
- * DESCRIPTION: Perform the actual execution of a GPE control method. This
- * function is called from an invocation of acpi_os_exece
- * (and therefore does NOT execute at interrupt level) so that
+ * DESCRIPTION: Perform the actual execution of a GPE control method. This
+ * function is called from an invocation of acpi_os_execute and
+ * therefore does NOT execute at interrupt level - so that
* the control method itself is not executed in the context of
* an interrupt handler.
*
@@ -502,7 +502,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
u32 gpe_number = 0;
acpi_status status;
struct acpi_gpe_event_info local_gpe_event_info;
- struct acpi_parameter_info info;
+ struct acpi_evaluate_info *info;
ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
@@ -540,16 +540,29 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
*/
if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_METHOD) {
- /*
- * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
- * control method that corresponds to this GPE
- */
- info.node = local_gpe_event_info.dispatch.method_node;
- info.parameters =
- ACPI_CAST_PTR(union acpi_operand_object *, gpe_event_info);
- info.parameter_type = ACPI_PARAM_GPE;
- status = acpi_ns_evaluate_by_handle(&info);
+ /* Allocate the evaluation information block */
+
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ status = AE_NO_MEMORY;
+ } else {
+ /*
+ * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
+ * control method that corresponds to this GPE
+ */
+ info->prefix_node =
+ local_gpe_event_info.dispatch.method_node;
+ info->parameters =
+ ACPI_CAST_PTR(union acpi_operand_object *,
+ gpe_event_info);
+ info->parameter_type = ACPI_PARAM_GPE;
+ info->flags = ACPI_IGNORE_RETURN_VALUE;
+
+ status = acpi_ns_evaluate(info);
+ ACPI_FREE(info);
+ }
+
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"While evaluating method [%4.4s] for GPE[%2X]",
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 24e0b8d36f31..6eef4efddcf6 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -49,12 +49,13 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evmisc")
+/* Names for Notify() values, used for debug output */
#ifdef ACPI_DEBUG_OUTPUT
static const char *acpi_notify_value_names[] = {
"Bus Check",
"Device Check",
"Device Wake",
- "Eject request",
+ "Eject Request",
"Device Check Light",
"Frequency Mismatch",
"Bus Mode Mismatch",
@@ -191,8 +192,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
notify_info->notify.value = (u16) notify_value;
notify_info->notify.handler_obj = handler_obj;
- status = acpi_os_execute(OSL_NOTIFY_HANDLER,
- acpi_ev_notify_dispatch, notify_info);
+ status =
+ acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
+ notify_info);
if (ACPI_FAILURE(status)) {
acpi_ut_delete_generic_state(notify_info);
}
@@ -345,8 +347,9 @@ static u32 acpi_ev_global_lock_handler(void *context)
/* Run the Global Lock thread which will signal all waiting threads */
- status = acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
- acpi_ev_global_lock_thread, context);
+ status =
+ acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
+ acpi_ev_global_lock_thread, context);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not queue Global Lock thread"));
@@ -462,8 +465,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
* Acquire the global lock semaphore first.
* Since this wait will block, we must release the interpreter
*/
- status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
- timeout);
+ status =
+ acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
+ timeout);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index edf9d2e1dff9..094a17e4c86d 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -193,8 +193,8 @@ acpi_status acpi_ev_initialize_op_regions(void)
acpi_status
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
{
- struct acpi_parameter_info info;
- union acpi_operand_object *params[3];
+ struct acpi_evaluate_info *info;
+ union acpi_operand_object *args[3];
union acpi_operand_object *region_obj2;
acpi_status status;
@@ -209,47 +209,60 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
return_ACPI_STATUS(AE_OK);
}
+ /* Allocate and initialize the evaluation information block */
+
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+ info->prefix_node = region_obj2->extra.method_REG;
+ info->pathname = NULL;
+ info->parameters = args;
+ info->parameter_type = ACPI_PARAM_ARGS;
+ info->flags = ACPI_IGNORE_RETURN_VALUE;
+
/*
* The _REG method has two arguments:
*
- * Arg0, Integer: Operation region space ID
- * Same value as region_obj->Region.space_id
- * Arg1, Integer: connection status
- * 1 for connecting the handler,
- * 0 for disconnecting the handler
- * Passed as a parameter
+ * Arg0 - Integer:
+ * Operation region space ID Same value as region_obj->Region.space_id
+ *
+ * Arg1 - Integer:
+ * connection status 1 for connecting the handler, 0 for disconnecting
+ * the handler (Passed as a parameter)
*/
- params[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
- if (!params[0]) {
- return_ACPI_STATUS(AE_NO_MEMORY);
+ args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+ if (!args[0]) {
+ status = AE_NO_MEMORY;
+ goto cleanup1;
}
- params[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
- if (!params[1]) {
+ args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+ if (!args[1]) {
status = AE_NO_MEMORY;
- goto cleanup;
+ goto cleanup2;
}
/* Setup the parameter objects */
- params[0]->integer.value = region_obj->region.space_id;
- params[1]->integer.value = function;
- params[2] = NULL;
-
- info.node = region_obj2->extra.method_REG;
- info.parameters = params;
- info.parameter_type = ACPI_PARAM_ARGS;
+ args[0]->integer.value = region_obj->region.space_id;
+ args[1]->integer.value = function;
+ args[2] = NULL;
/* Execute the method, no return value */
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
- (ACPI_TYPE_METHOD, info.node, NULL));
- status = acpi_ns_evaluate_by_handle(&info);
+ (ACPI_TYPE_METHOD, info->prefix_node, NULL));
+
+ status = acpi_ns_evaluate(info);
+ acpi_ut_remove_reference(args[1]);
- acpi_ut_remove_reference(params[1]);
+ cleanup2:
+ acpi_ut_remove_reference(args[0]);
- cleanup:
- acpi_ut_remove_reference(params[0]);
+ cleanup1:
+ ACPI_FREE(info);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 1cecd577b899..5b3c7a85eb9a 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -475,8 +475,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
/* Find any "_REG" method associated with this region definition */
- status = acpi_ns_search_node(*reg_name_ptr, node,
- ACPI_TYPE_METHOD, &method_node);
+ status =
+ acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
+ &method_node);
if (ACPI_SUCCESS(status)) {
/*
* The _REG method is optional and there can be only one per region
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 9ae3cb55979b..823352435e08 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -214,9 +214,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
* location within the namespace where the table will be loaded.
*/
status =
- acpi_ns_get_node_by_path(operand[3]->string.pointer,
- start_node, ACPI_NS_SEARCH_PARENT,
- &parent_node);
+ acpi_ns_get_node(start_node, operand[3]->string.pointer,
+ ACPI_NS_SEARCH_PARENT, &parent_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -237,9 +236,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
/* Find the node referenced by the parameter_path_string */
status =
- acpi_ns_get_node_by_path(operand[4]->string.pointer,
- start_node, ACPI_NS_SEARCH_PARENT,
- &parameter_node);
+ acpi_ns_get_node(start_node, operand[4]->string.pointer,
+ ACPI_NS_SEARCH_PARENT, &parameter_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index ca9925c0d011..3b7c4352ec57 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -145,10 +145,10 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
* length of one field datum (access width) must fit within the region.
* (Region length is specified in bytes)
*/
- if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset +
- field_datum_byte_offset +
- obj_desc->common_field.
- access_byte_width)) {
+ if (rgn_desc->region.length <
+ (obj_desc->common_field.base_byte_offset +
+ field_datum_byte_offset +
+ obj_desc->common_field.access_byte_width)) {
if (acpi_gbl_enable_interpreter_slack) {
/*
* Slack mode only: We will go ahead and allow access to this
@@ -811,13 +811,15 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
mask =
ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
- datum_count =
- ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
- obj_desc->common_field.access_bit_width);
- field_datum_count =
- ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
- obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.access_bit_width);
+
+ datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
+ obj_desc->common_field.access_bit_width);
+
+ field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
+ obj_desc->common_field.
+ start_field_bit_offset,
+ obj_desc->common_field.
+ access_bit_width);
/* Get initial Datum from the input buffer */
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index 794d9b8de956..bd98aab017cf 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -445,10 +445,24 @@ acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1)
case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
+ /*
+ * We need to check if the shiftcount is larger than the integer bit
+ * width since the behavior of this is not well-defined in the C language.
+ */
+ if (integer1 >= acpi_gbl_integer_bit_width) {
+ return (0);
+ }
return (integer0 << integer1);
case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
+ /*
+ * We need to check if the shiftcount is larger than the integer bit
+ * width since the behavior of this is not well-defined in the C language.
+ */
+ if (integer1 >= acpi_gbl_integer_bit_width) {
+ return (0);
+ }
return (integer0 >> integer1);
case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 05b89c5878eb..8284c52875be 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -874,16 +874,14 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
* Field, so we need to resolve the node to a value.
*/
status =
- acpi_ns_get_node_by_path(operand[0]->string.
- pointer,
- walk_state->
- scope_info->scope.
- node,
- ACPI_NS_SEARCH_PARENT,
- ACPI_CAST_INDIRECT_PTR
- (struct
- acpi_namespace_node,
- &return_desc));
+ acpi_ns_get_node(walk_state->scope_info->
+ scope.node,
+ operand[0]->string.pointer,
+ ACPI_NS_SEARCH_PARENT,
+ ACPI_CAST_INDIRECT_PTR
+ (struct
+ acpi_namespace_node,
+ &return_desc));
if (ACPI_FAILURE(status)) {
goto cleanup;
}
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 4fba452a5590..3cc97ba48b36 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -477,23 +477,16 @@ acpi_ex_data_table_space_handler(u32 function,
acpi_integer * value,
void *handler_context, void *region_context)
{
- acpi_status status = AE_OK;
- u32 byte_width = ACPI_DIV_8(bit_width);
- u32 i;
- char *logical_addr_ptr;
-
ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
- logical_addr_ptr = ACPI_PHYSADDR_TO_PTR(address);
-
/* Perform the memory read or write */
switch (function) {
case ACPI_READ:
- for (i = 0; i < byte_width; i++) {
- ((char *)value)[i] = logical_addr_ptr[i];
- }
+ ACPI_MEMCPY(ACPI_CAST_PTR(char, value),
+ ACPI_PHYSADDR_TO_PTR(address),
+ ACPI_DIV_8(bit_width));
break;
case ACPI_WRITE:
@@ -502,5 +495,5 @@ acpi_ex_data_table_space_handler(u32 function,
return_ACPI_STATUS(AE_SUPPORT);
}
- return_ACPI_STATUS(status);
+ return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index ec9f5a11a8b3..5a3aa8dd8cb7 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -127,8 +127,7 @@ acpi_status
acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
{
acpi_status status = AE_OK;
- struct acpi_parameter_info info;
- char *sleep_state_name;
+ struct acpi_evaluate_info *info;
ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
@@ -138,34 +137,39 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /* Evaluate the namespace object containing the values for this state */
+ /* Allocate the evaluation information block */
+
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
- info.parameters = NULL;
- info.return_object = NULL;
- sleep_state_name =
+ info->pathname =
ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
- status = acpi_ns_evaluate_by_name(sleep_state_name, &info);
+ /* Evaluate the namespace object containing the values for this state */
+
+ status = acpi_ns_evaluate(info);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"%s while evaluating SleepState [%s]\n",
acpi_format_exception(status),
- sleep_state_name));
+ info->pathname));
- return_ACPI_STATUS(status);
+ goto cleanup;
}
/* Must have a return object */
- if (!info.return_object) {
+ if (!info->return_object) {
ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
- sleep_state_name));
+ info->pathname));
status = AE_NOT_EXIST;
}
/* It must be of type Package */
- else if (ACPI_GET_OBJECT_TYPE(info.return_object) != ACPI_TYPE_PACKAGE) {
+ else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO,
"Sleep State return object is not a Package"));
status = AE_AML_OPERAND_TYPE;
@@ -178,7 +182,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
* by BIOS vendors seems to be to have 2 or more elements, at least
* one per sleep type (A/B).
*/
- else if (info.return_object->package.count < 2) {
+ else if (info->return_object->package.count < 2) {
ACPI_ERROR((AE_INFO,
"Sleep State return package does not have at least two elements"));
status = AE_AML_NO_OPERAND;
@@ -186,35 +190,38 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[0])
+ else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
!= ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[1])
+ (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
!= ACPI_TYPE_INTEGER)) {
ACPI_ERROR((AE_INFO,
"Sleep State return package elements are not both Integers (%s, %s)",
- acpi_ut_get_object_type_name(info.return_object->
+ acpi_ut_get_object_type_name(info->return_object->
package.elements[0]),
- acpi_ut_get_object_type_name(info.return_object->
+ acpi_ut_get_object_type_name(info->return_object->
package.elements[1])));
status = AE_AML_OPERAND_TYPE;
} else {
/* Valid _Sx_ package size, type, and value */
*sleep_type_a = (u8)
- (info.return_object->package.elements[0])->integer.value;
+ (info->return_object->package.elements[0])->integer.value;
*sleep_type_b = (u8)
- (info.return_object->package.elements[1])->integer.value;
+ (info->return_object->package.elements[1])->integer.value;
}
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"While evaluating SleepState [%s], bad Sleep object %p type %s",
- sleep_state_name, info.return_object,
- acpi_ut_get_object_type_name(info.
+ info->pathname, info->return_object,
+ acpi_ut_get_object_type_name(info->
return_object)));
}
- acpi_ut_remove_reference(info.return_object);
+ acpi_ut_remove_reference(info->return_object);
+
+ cleanup:
+ ACPI_FREE(info);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index ba8ad569188f..48fadade52e2 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -259,10 +259,8 @@ acpi_status acpi_ns_root_initialize(void)
/* Save a handle to "_GPE", it is always present */
if (ACPI_SUCCESS(status)) {
- status =
- acpi_ns_get_node_by_path("\\_GPE", NULL,
- ACPI_NS_NO_UPSEARCH,
- &acpi_gbl_fadt_gpe_device);
+ status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
+ &acpi_gbl_fadt_gpe_device);
}
return_ACPI_STATUS(status);
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 4b054062b46a..4b0a4a8c9843 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -1,7 +1,6 @@
/*******************************************************************************
*
- * Module Name: nseval - Object evaluation interfaces -- includes control
- * method lookup and execution.
+ * Module Name: nseval - Object evaluation, includes control method execution
*
******************************************************************************/
@@ -50,196 +49,14 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nseval")
-/* Local prototypes */
-static acpi_status
-acpi_ns_execute_control_method(struct acpi_parameter_info *info);
-
-static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info);
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ns_evaluate_relative
- *
- * PARAMETERS: Pathname - Name of method to execute, If NULL, the
- * handle is the object to execute
- * Info - Method info block, contains:
- * return_object - Where to put method's return value (if
- * any). If NULL, no value is returned.
- * Params - List of parameters to pass to the method,
- * terminated by NULL. Params itself may be
- * NULL if no parameters are being passed.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Evaluate the object or find and execute the requested method
- *
- * MUTEX: Locks Namespace
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info)
-{
- acpi_status status;
- struct acpi_namespace_node *node = NULL;
- union acpi_generic_state *scope_info;
- char *internal_path = NULL;
-
- ACPI_FUNCTION_TRACE(ns_evaluate_relative);
-
- /*
- * Must have a valid object handle
- */
- if (!info || !info->node) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
-
- /* Build an internal name string for the method */
-
- status = acpi_ns_internalize_name(pathname, &internal_path);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- scope_info = acpi_ut_create_generic_state();
- if (!scope_info) {
- goto cleanup1;
- }
-
- /* Get the prefix handle and Node */
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- goto cleanup;
- }
-
- info->node = acpi_ns_map_handle_to_node(info->node);
- if (!info->node) {
- (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- status = AE_BAD_PARAMETER;
- goto cleanup;
- }
-
- /* Lookup the name in the namespace */
-
- scope_info->scope.node = info->node;
- status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY,
- ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
- &node);
-
- (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-
- if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
- pathname, acpi_format_exception(status)));
- goto cleanup;
- }
-
- /*
- * Now that we have a handle to the object, we can attempt to evaluate it.
- */
- ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
- pathname, node, acpi_ns_get_attached_object(node)));
-
- info->node = node;
- status = acpi_ns_evaluate_by_handle(info);
-
- ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
- "*** Completed eval of object %s ***\n", pathname));
-
- cleanup:
- acpi_ut_delete_generic_state(scope_info);
-
- cleanup1:
- ACPI_FREE(internal_path);
- return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ns_evaluate_by_name
- *
- * PARAMETERS: Pathname - Fully qualified pathname to the object
- * Info - Method info block, contains:
- * return_object - Where to put method's return value (if
- * any). If NULL, no value is returned.
- * Params - List of parameters to pass to the method,
- * terminated by NULL. Params itself may be
- * NULL if no parameters are being passed.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Evaluate the object or rind and execute the requested method
- * passing the given parameters
- *
- * MUTEX: Locks Namespace
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info)
-{
- acpi_status status;
- char *internal_path = NULL;
-
- ACPI_FUNCTION_TRACE(ns_evaluate_by_name);
-
- /* Build an internal name string for the method */
-
- status = acpi_ns_internalize_name(pathname, &internal_path);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- goto cleanup;
- }
-
- /* Lookup the name in the namespace */
-
- status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
- ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
- &info->node);
-
- (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-
- if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
- "Object at [%s] was not found, status=%.4X\n",
- pathname, status));
- goto cleanup;
- }
-
- /*
- * Now that we have a handle to the object, we can attempt to evaluate it.
- */
- ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
- pathname, info->node,
- acpi_ns_get_attached_object(info->node)));
-
- status = acpi_ns_evaluate_by_handle(info);
-
- ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
- "*** Completed eval of object %s ***\n", pathname));
-
- cleanup:
-
- /* Cleanup */
-
- if (internal_path) {
- ACPI_FREE(internal_path);
- }
-
- return_ACPI_STATUS(status);
-}
-
/*******************************************************************************
*
- * FUNCTION: acpi_ns_evaluate_by_handle
+ * FUNCTION: acpi_ns_evaluate
*
- * PARAMETERS: Info - Method info block, contains:
- * Node - Method/Object Node to execute
+ * 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
* Parameters - List of parameters to pass to the method,
* terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
@@ -248,29 +65,21 @@ acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info)
* parameter_type - Type of Parameter list
* return_object - Where to put method's return value (if
* any). If NULL, no value is returned.
+ * Flags - ACPI_IGNORE_RETURN_VALUE to delete return
*
* RETURN: Status
*
- * DESCRIPTION: Evaluate object or execute the requested method passing the
- * given parameters
+ * DESCRIPTION: Execute a control method or return the current value of an
+ * ACPI namespace object.
*
- * MUTEX: Locks Namespace
+ * MUTEX: Locks interpreter
*
******************************************************************************/
-
-acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info)
+acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
{
acpi_status status;
- ACPI_FUNCTION_TRACE(ns_evaluate_by_handle);
-
- /* Check if namespace has been initialized */
-
- if (!acpi_gbl_root_node) {
- return_ACPI_STATUS(AE_NO_NAMESPACE);
- }
-
- /* Parameter Validation */
+ ACPI_FUNCTION_TRACE(ns_evaluate);
if (!info) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -280,203 +89,120 @@ acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info)
info->return_object = NULL;
- /* Get the prefix handle and Node */
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ /*
+ * 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);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- info->node = acpi_ns_map_handle_to_node(info->node);
- if (!info->node) {
- (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
-
/*
* For a method alias, we must grab the actual method node so that proper
* scoping context will be established before execution.
*/
- if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
- info->node =
+ if (acpi_ns_get_type(info->resolved_node) ==
+ ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+ info->resolved_node =
ACPI_CAST_PTR(struct acpi_namespace_node,
- info->node->object);
+ info->resolved_node->object);
}
+ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname,
+ info->resolved_node,
+ acpi_ns_get_attached_object(info->resolved_node)));
+
/*
* Two major cases here:
- * 1) The object is an actual control method -- execute it.
- * 2) The object is not a method -- just return it's current value
*
- * In both cases, the namespace is unlocked by the acpi_ns* procedure
+ * 1) The object is a control method -- execute it
+ * 2) The object is not a method -- just return it's current value
*/
- if (acpi_ns_get_type(info->node) == ACPI_TYPE_METHOD) {
+ if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) {
/*
- * Case 1) We have an actual control method to execute
+ * 1) Object is a control method - execute it
*/
- status = acpi_ns_execute_control_method(info);
- } else {
- /*
- * Case 2) Object is NOT a method, just return its current value
- */
- status = acpi_ns_get_object_value(info);
- }
-
- /*
- * Check if there is a return value on the stack that must be dealt with
- */
- if (status == AE_CTRL_RETURN_VALUE) {
-
- /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
-
- status = AE_OK;
- }
-
- /*
- * Namespace was unlocked by the handling acpi_ns* function, so we
- * just return
- */
- return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ns_execute_control_method
- *
- * PARAMETERS: Info - Method info block, contains:
- * Node - Method Node to execute
- * obj_desc - Method object
- * Parameters - List of parameters to pass to the method,
- * terminated by NULL. Params itself may be
- * NULL if no parameters are being passed.
- * 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.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Execute the requested method passing the given parameters
- *
- * MUTEX: Assumes namespace is locked
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ns_execute_control_method(struct acpi_parameter_info *info)
-{
- acpi_status status;
-
- ACPI_FUNCTION_TRACE(ns_execute_control_method);
-
- /* Verify that there is a method associated with this object */
-
- info->obj_desc = acpi_ns_get_attached_object(info->node);
- if (!info->obj_desc) {
- ACPI_ERROR((AE_INFO, "No attached method object"));
- (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS(AE_NULL_OBJECT);
- }
-
- ACPI_DUMP_PATHNAME(info->node, "Execute Method:",
- ACPI_LV_INFO, _COMPONENT);
-
- 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));
-
- /*
- * Unlock the namespace before execution. This allows namespace access
- * via the external Acpi* interfaces while a method is being executed.
- * However, 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.
- */
- status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ /* Verify that there is a method object associated with this node */
- /*
- * Execute the method via the interpreter. The interpreter is locked
- * here before calling into the AML parser
- */
- status = acpi_ex_enter_interpreter();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ 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);
+ }
- status = acpi_ps_execute_method(info);
- acpi_ex_exit_interpreter();
+ ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
+ ACPI_LV_INFO, _COMPONENT);
- return_ACPI_STATUS(status);
-}
+ 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));
-/*******************************************************************************
- *
- * FUNCTION: acpi_ns_get_object_value
- *
- * PARAMETERS: Info - Method info block, contains:
- * Node - Object's NS node
- * return_object - Where to put object value (if
- * any). If NULL, no value is returned.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Return the current value of the object
- *
- * MUTEX: Assumes namespace is locked, leaves namespace unlocked
- *
- ******************************************************************************/
+ /*
+ * 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
+ */
+ status = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
-static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info)
-{
- acpi_status status = AE_OK;
- struct acpi_namespace_node *resolved_node = info->node;
+ status = acpi_ps_execute_method(info);
+ acpi_ex_exit_interpreter();
+ } else {
+ /*
+ * 2) Object is not a method, return its current value
+ */
- ACPI_FUNCTION_TRACE(ns_get_object_value);
+ /*
+ * 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.
+ */
+ status = acpi_ex_enter_interpreter();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
- /*
- * 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.
- */
+ /* Function has a strange interface */
- /*
- * Use resolve_node_to_value() to get the associated value. This call always
- * deletes obj_desc (allocated above).
- *
- * NOTE: we can get away with passing in NULL for a walk state because
- * obj_desc is guaranteed to not be a reference to either a method local or
- * a method argument (because this interface can only be called from the
- * acpi_evaluate external interface, never called from a running method.)
- *
- * Even though we do not directly invoke the interpreter for this, we must
- * enter it because we could access an opregion. The opregion access code
- * assumes that the interpreter is locked.
- *
- * We must release the namespace lock before entering the intepreter.
- */
- status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ status =
+ acpi_ex_resolve_node_to_value(&info->resolved_node, NULL);
+ acpi_ex_exit_interpreter();
- status = acpi_ex_enter_interpreter();
- if (ACPI_SUCCESS(status)) {
- status = acpi_ex_resolve_node_to_value(&resolved_node, NULL);
/*
* If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
* in resolved_node.
*/
- acpi_ex_exit_interpreter();
-
if (ACPI_SUCCESS(status)) {
status = AE_CTRL_RETURN_VALUE;
- info->return_object = ACPI_CAST_PTR
- (union acpi_operand_object, resolved_node);
+ info->return_object =
+ ACPI_CAST_PTR(union acpi_operand_object,
+ info->resolved_node);
+
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
"Returning object %p [%s]\n",
info->return_object,
@@ -485,7 +211,30 @@ static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info)
}
}
- /* Namespace is unlocked */
+ /*
+ * Check if there is a return value that must be dealt with
+ */
+ if (status == AE_CTRL_RETURN_VALUE) {
+
+ /* If caller does not want the return value, delete it */
+ 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
+ */
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index bf1d8dbc0b86..1c9ca6e05314 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -154,7 +154,16 @@ acpi_status acpi_ns_initialize_devices(void)
ACPI_UINT32_MAX, FALSE,
acpi_ns_find_ini_methods, &info, NULL);
if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
+ goto error_exit;
+ }
+
+ /* Allocate the evaluation information block */
+
+ info.evaluate_info =
+ ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info.evaluate_info) {
+ status = AE_NO_MEMORY;
+ goto error_exit;
}
/* Walk namespace to execute all _INIs on present devices */
@@ -162,8 +171,10 @@ acpi_status acpi_ns_initialize_devices(void)
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, FALSE,
acpi_ns_init_one_device, &info, NULL);
+
+ ACPI_FREE(info.evaluate_info);
if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
+ goto error_exit;
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
@@ -171,6 +182,10 @@ acpi_status acpi_ns_initialize_devices(void)
info.num_INI, info.num_STA, info.device_count));
return_ACPI_STATUS(status);
+
+ error_exit:
+ ACPI_EXCEPTION((AE_INFO, status, "During device initialization"));
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -398,9 +413,9 @@ static acpi_status
acpi_ns_init_one_device(acpi_handle obj_handle,
u32 nesting_level, void *context, void **return_value)
{
- struct acpi_device_walk_info *info =
+ struct acpi_device_walk_info *walk_info =
ACPI_CAST_PTR(struct acpi_device_walk_info, context);
- struct acpi_parameter_info pinfo;
+ struct acpi_evaluate_info *info = walk_info->evaluate_info;
u32 flags;
acpi_status status;
struct acpi_namespace_node *device_node;
@@ -460,7 +475,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
* other words, the device is present, ..., and functioning)"
*/
if (flags != ACPI_UINT32_MAX) {
- info->num_STA++;
+ walk_info->num_STA++;
}
/*
@@ -516,20 +531,16 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
(ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI));
- pinfo.node = device_node;
- pinfo.parameters = NULL;
- pinfo.parameter_type = ACPI_PARAM_ARGS;
+ info->prefix_node = device_node;
+ info->pathname = METHOD_NAME__INI;
+ info->parameters = NULL;
+ info->parameter_type = ACPI_PARAM_ARGS;
+ info->flags = ACPI_IGNORE_RETURN_VALUE;
- status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo);
+ status = acpi_ns_evaluate(info);
if (ACPI_SUCCESS(status)) {
+ walk_info->num_INI++;
- /* Delete any return object (especially if implicit_return is enabled) */
-
- if (pinfo.return_object) {
- acpi_ut_remove_reference(pinfo.return_object);
- }
-
- info->num_INI++;
if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
(!(acpi_dbg_level & ACPI_LV_INFO))) {
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
@@ -540,20 +551,24 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
/* Ignore error and move on to next device */
- char *scope_name = acpi_ns_get_external_pathname(pinfo.node);
+ char *scope_name =
+ acpi_ns_get_external_pathname(info->resolved_node);
ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution",
scope_name));
ACPI_FREE(scope_name);
+ status = AE_OK;
}
#endif
- /* If an external initialization handler is present, call it */
-
+ /*
+ * The _INI method has been run if present; call the Global Initialization
+ * Handler for this device.
+ */
if (acpi_gbl_init_handler) {
status =
- acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI);
+ acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI);
}
- return_ACPI_STATUS(AE_OK);
+ return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index d2473476afa5..500e2bbcfaf7 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -56,16 +56,16 @@ acpi_ns_search_parent_tree(u32 target_name,
/*******************************************************************************
*
- * FUNCTION: acpi_ns_search_node
+ * FUNCTION: acpi_ns_search_one_scope
*
* PARAMETERS: target_name - Ascii ACPI name to search for
- * Node - Starting node where search will begin
+ * parent_node - Starting node where search will begin
* Type - Object type to match
* return_node - Where the matched Named obj is returned
*
* RETURN: Status
*
- * DESCRIPTION: Search a single level of the namespace. Performs a
+ * DESCRIPTION: Search a single level of the namespace. Performs a
* simple search of the specified level, and does not add
* entries or search parents.
*
@@ -75,32 +75,37 @@ acpi_ns_search_parent_tree(u32 target_name,
*
* All namespace searching is linear in this implementation, but
* could be easily modified to support any improved search
- * algorithm. However, the linear search was chosen for simplicity
+ * algorithm. However, the linear search was chosen for simplicity
* and because the trees are small and the other interpreter
* execution overhead is relatively high.
*
+ * Note: CPU execution analysis has shown that the AML interpreter spends
+ * a very small percentage of its time searching the namespace. Therefore,
+ * the linear search seems to be sufficient, as there would seem to be
+ * little value in improving the search.
+ *
******************************************************************************/
acpi_status
-acpi_ns_search_node(u32 target_name,
- struct acpi_namespace_node *node,
- acpi_object_type type,
- struct acpi_namespace_node **return_node)
+acpi_ns_search_one_scope(u32 target_name,
+ struct acpi_namespace_node *parent_node,
+ acpi_object_type type,
+ struct acpi_namespace_node **return_node)
{
- struct acpi_namespace_node *next_node;
+ struct acpi_namespace_node *node;
- ACPI_FUNCTION_TRACE(ns_search_node);
+ ACPI_FUNCTION_TRACE(ns_search_one_scope);
#ifdef ACPI_DEBUG_OUTPUT
if (ACPI_LV_NAMES & acpi_dbg_level) {
char *scope_name;
- scope_name = acpi_ns_get_external_pathname(node);
+ scope_name = acpi_ns_get_external_pathname(parent_node);
if (scope_name) {
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
"Searching %s (%p) For [%4.4s] (%s)\n",
- scope_name, node, ACPI_CAST_PTR(char,
- &target_name),
+ scope_name, parent_node,
+ ACPI_CAST_PTR(char, &target_name),
acpi_ut_get_type_name(type)));
ACPI_FREE(scope_name);
@@ -112,20 +117,20 @@ acpi_ns_search_node(u32 target_name,
* Search for name at this namespace level, which is to say that we
* must search for the name among the children of this object
*/
- next_node = node->child;
- while (next_node) {
+ node = parent_node->child;
+ while (node) {
/* Check for match against the name */
- if (next_node->name.integer == target_name) {
+ if (node->name.integer == target_name) {
/* Resolve a control method alias if any */
- if (acpi_ns_get_type(next_node) ==
+ if (acpi_ns_get_type(node) ==
ACPI_TYPE_LOCAL_METHOD_ALIAS) {
- next_node =
+ node =
ACPI_CAST_PTR(struct acpi_namespace_node,
- next_node->object);
+ node->object);
}
/* Found matching entry */
@@ -133,12 +138,12 @@ acpi_ns_search_node(u32 target_name,
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
"Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
ACPI_CAST_PTR(char, &target_name),
- acpi_ut_get_type_name(next_node->
- type),
- next_node,
- acpi_ut_get_node_name(node), node));
+ acpi_ut_get_type_name(node->type),
+ node,
+ acpi_ut_get_node_name(parent_node),
+ parent_node));
- *return_node = next_node;
+ *return_node = node;
return_ACPI_STATUS(AE_OK);
}
@@ -146,7 +151,7 @@ acpi_ns_search_node(u32 target_name,
* The last entry in the list points back to the parent,
* so a flag is used to indicate the end-of-list
*/
- if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+ if (node->flags & ANOBJ_END_OF_PEER_LIST) {
/* Searched entire list, we are done */
@@ -155,7 +160,7 @@ acpi_ns_search_node(u32 target_name,
/* Didn't match name, move on to the next peer object */
- next_node = next_node->peer;
+ node = node->peer;
}
/* Searched entire namespace level, not found */
@@ -164,7 +169,8 @@ acpi_ns_search_node(u32 target_name,
"Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
ACPI_CAST_PTR(char, &target_name),
acpi_ut_get_type_name(type),
- acpi_ut_get_node_name(node), node, node->child));
+ acpi_ut_get_node_name(parent_node), parent_node,
+ parent_node->child));
return_ACPI_STATUS(AE_NOT_FOUND);
}
@@ -181,14 +187,14 @@ acpi_ns_search_node(u32 target_name,
* RETURN: Status
*
* DESCRIPTION: Called when a name has not been found in the current namespace
- * level. Before adding it or giving up, ACPI scope rules require
+ * level. Before adding it or giving up, ACPI scope rules require
* searching enclosing scopes in cases identified by acpi_ns_local().
*
* "A name is located by finding the matching name in the current
* name space, and then in the parent name space. If the parent
* name space does not contain the name, the search continues
* recursively until either the name is found or the name space
- * does not have a parent (the root of the name space). This
+ * does not have a parent (the root of the name space). This
* indicates that the name is not found" (From ACPI Specification,
* section 5.3)
*
@@ -237,11 +243,12 @@ acpi_ns_search_parent_tree(u32 target_name,
*/
while (parent_node) {
/*
- * Search parent scope. Use TYPE_ANY because we don't care about the
+ * Search parent scope. Use TYPE_ANY because we don't care about the
* object type at this point, we only care about the existence of
- * the actual name we are searching for. Typechecking comes later.
+ * the actual name we are searching for. Typechecking comes later.
*/
- status = acpi_ns_search_node(target_name, parent_node,
+ status =
+ acpi_ns_search_one_scope(target_name, parent_node,
ACPI_TYPE_ANY, return_node);
if (ACPI_SUCCESS(status)) {
return_ACPI_STATUS(status);
@@ -273,7 +280,7 @@ acpi_ns_search_parent_tree(u32 target_name,
* RETURN: Status
*
* DESCRIPTION: Search for a name segment in a single namespace level,
- * optionally adding it if it is not found. If the passed
+ * optionally adding it if it is not found. If the passed
* Type is not Any and the type previously stored in the
* entry was Any (i.e. unknown), update the stored type.
*
@@ -332,7 +339,7 @@ acpi_ns_search_and_enter(u32 target_name,
/* Try to find the name in the namespace level specified by the caller */
*return_node = ACPI_ENTRY_NOT_FOUND;
- status = acpi_ns_search_node(target_name, node, type, return_node);
+ status = acpi_ns_search_one_scope(target_name, node, type, return_node);
if (status != AE_NOT_FOUND) {
/*
* If we found it AND the request specifies that a find is an error,
@@ -348,10 +355,10 @@ acpi_ns_search_and_enter(u32 target_name,
}
/*
- * The name was not found. If we are NOT performing the first pass
+ * The name was not found. If we are NOT performing the first pass
* (name entry) of loading the namespace, search the parent tree (all the
* way to the root if necessary.) We don't want to perform the parent
- * search when the namespace is actually being loaded. We want to perform
+ * search when the namespace is actually being loaded. We want to perform
* the search when namespace references are being resolved (load pass 2)
* and during the execution phase.
*/
@@ -386,6 +393,9 @@ acpi_ns_search_and_enter(u32 target_name,
return_ACPI_STATUS(AE_NO_MEMORY);
}
#ifdef ACPI_ASL_COMPILER
+ /*
+ * Node is an object defined by an External() statement
+ */
if (flags & ACPI_NS_EXTERNAL) {
new_node->flags |= ANOBJ_IS_EXTERNAL;
}
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index d1d55032b455..aa4e799d9a8c 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -142,8 +142,9 @@ acpi_ns_report_method_error(char *module_name,
acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
if (path) {
- status = acpi_ns_get_node_by_path(path, prefix_node,
- ACPI_NS_NO_UPSEARCH, &node);
+ status =
+ acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
+ &node);
if (ACPI_FAILURE(status)) {
acpi_os_printf("[Could not get node by pathname]");
}
@@ -685,13 +686,9 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
ACPI_FUNCTION_ENTRY();
/*
- * Simple implementation.
+ * Simple implementation
*/
- if (!handle) {
- return (NULL);
- }
-
- if (handle == ACPI_ROOT_OBJECT) {
+ if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
return (acpi_gbl_root_node);
}
@@ -701,7 +698,7 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
return (NULL);
}
- return ((struct acpi_namespace_node *)handle);
+ return (ACPI_CAST_PTR(struct acpi_namespace_node, handle));
}
/*******************************************************************************
@@ -811,12 +808,12 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
/*******************************************************************************
*
- * FUNCTION: acpi_ns_get_node_by_path
+ * FUNCTION: acpi_ns_get_node
*
* PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
* \ (backslash) and ^ (carat) prefixes, and the
* . (period) to separate segments are supported.
- * start_node - Root of subtree to be searched, or NS_ALL for the
+ * prefix_node - Root of subtree to be searched, or NS_ALL for the
* root of the name space. If Name is fully
* qualified (first s8 is '\'), the passed value
* of Scope will not be accessed.
@@ -832,24 +829,29 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
******************************************************************************/
acpi_status
-acpi_ns_get_node_by_path(char *pathname,
- struct acpi_namespace_node *start_node,
- u32 flags, struct acpi_namespace_node **return_node)
+acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
+ char *pathname,
+ u32 flags, struct acpi_namespace_node **return_node)
{
union acpi_generic_state scope_info;
acpi_status status;
- char *internal_path = NULL;
+ char *internal_path;
- ACPI_FUNCTION_TRACE_PTR(ns_get_node_by_path, pathname);
+ ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname);
- if (pathname) {
+ if (!pathname) {
+ *return_node = prefix_node;
+ if (!prefix_node) {
+ *return_node = acpi_gbl_root_node;
+ }
+ return_ACPI_STATUS(AE_OK);
+ }
- /* Convert path to internal representation */
+ /* Convert path to internal representation */
- status = acpi_ns_internalize_name(pathname, &internal_path);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ status = acpi_ns_internalize_name(pathname, &internal_path);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
/* Must lock namespace during lookup */
@@ -861,26 +863,23 @@ acpi_ns_get_node_by_path(char *pathname,
/* Setup lookup scope (search starting point) */
- scope_info.scope.node = start_node;
+ scope_info.scope.node = prefix_node;
/* Lookup the name in the namespace */
- status = acpi_ns_lookup(&scope_info, internal_path,
- ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- (flags | ACPI_NS_DONT_OPEN_SCOPE),
- NULL, return_node);
+ status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE,
+ (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
+ return_node);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
- internal_path,
- acpi_format_exception(status)));
+ pathname, acpi_format_exception(status)));
}
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
cleanup:
- if (internal_path) {
- ACPI_FREE(internal_path);
- }
+ ACPI_FREE(internal_path);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 998b29611b19..6d9bd45af30a 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -171,51 +171,61 @@ acpi_evaluate_object(acpi_handle handle,
{
acpi_status status;
acpi_status status2;
- struct acpi_parameter_info info;
+ struct acpi_evaluate_info *info;
acpi_size buffer_space_needed;
u32 i;
ACPI_FUNCTION_TRACE(acpi_evaluate_object);
- info.node = handle;
- info.parameters = NULL;
- info.return_object = NULL;
- info.parameter_type = ACPI_PARAM_ARGS;
+ /* Allocate and initialize the evaluation information block */
+
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+ info->pathname = pathname;
+ info->parameter_type = ACPI_PARAM_ARGS;
+
+ /* Convert and validate the device handle */
+
+ info->prefix_node = acpi_ns_map_handle_to_node(handle);
+ if (!info->prefix_node) {
+ status = AE_BAD_PARAMETER;
+ goto cleanup;
+ }
/*
- * If there are parameters to be passed to the object
- * (which must be a control method), the external objects
- * must be converted to internal objects
+ * If there are parameters to be passed to a control method, the external
+ * objects must all be converted to internal objects
*/
if (external_params && external_params->count) {
/*
* Allocate a new parameter block for the internal objects
* Add 1 to count to allow for null terminated internal list
*/
- info.parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
- external_params->count +
- 1) * sizeof(void *));
- if (!info.parameters) {
- return_ACPI_STATUS(AE_NO_MEMORY);
+ info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
+ external_params->
+ count +
+ 1) * sizeof(void *));
+ if (!info->parameters) {
+ status = AE_NO_MEMORY;
+ goto cleanup;
}
- /*
- * 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++) {
status =
acpi_ut_copy_eobject_to_iobject(&external_params->
pointer[i],
- &info.
+ &info->
parameters[i]);
if (ACPI_FAILURE(status)) {
- acpi_ut_delete_internal_object_list(info.
- parameters);
- return_ACPI_STATUS(status);
+ goto cleanup;
}
}
- info.parameters[external_params->count] = NULL;
+ info->parameters[external_params->count] = NULL;
}
/*
@@ -228,12 +238,13 @@ acpi_evaluate_object(acpi_handle handle,
/* The path is fully qualified, just evaluate by name */
- status = acpi_ns_evaluate_by_name(pathname, &info);
+ info->prefix_node = NULL;
+ status = acpi_ns_evaluate(info);
} 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
+ * 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,
@@ -246,22 +257,9 @@ acpi_evaluate_object(acpi_handle handle,
status = AE_BAD_PARAMETER;
} else {
- /*
- * We get here if we have a handle -- and if we have a
- * pathname it is relative. The handle will be validated
- * in the lower procedures
- */
- if (!pathname) {
- /*
- * The null pathname case means the handle is for
- * the actual object to be evaluated
- */
- status = acpi_ns_evaluate_by_handle(&info);
- } else {
- /* Both a Handle and a relative Pathname */
+ /* We have a namespace a node and a possible relative path */
- status = acpi_ns_evaluate_relative(pathname, &info);
- }
+ status = acpi_ns_evaluate(info);
}
/*
@@ -269,10 +267,10 @@ acpi_evaluate_object(acpi_handle handle,
* copy the return value to an external object.
*/
if (return_buffer) {
- if (!info.return_object) {
+ if (!info->return_object) {
return_buffer->length = 0;
} else {
- if (ACPI_GET_DESCRIPTOR_TYPE(info.return_object) ==
+ if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
ACPI_DESC_TYPE_NAMED) {
/*
* If we received a NS Node as a return object, this means that
@@ -283,17 +281,16 @@ acpi_evaluate_object(acpi_handle handle,
* support for various types at a later date if necessary.
*/
status = AE_TYPE;
- info.return_object = NULL; /* No need to delete a NS Node */
+ info->return_object = NULL; /* No need to delete a NS Node */
return_buffer->length = 0;
}
if (ACPI_SUCCESS(status)) {
- /*
- * Find out how large a buffer is needed
- * to contain the returned object
- */
+
+ /* Get the size of the returned object */
+
status =
- acpi_ut_get_object_size(info.return_object,
+ acpi_ut_get_object_size(info->return_object,
&buffer_space_needed);
if (ACPI_SUCCESS(status)) {
@@ -319,7 +316,7 @@ acpi_evaluate_object(acpi_handle handle,
status =
acpi_ut_copy_iobject_to_eobject
- (info.return_object,
+ (info->return_object,
return_buffer);
}
}
@@ -327,31 +324,33 @@ acpi_evaluate_object(acpi_handle handle,
}
}
- if (info.return_object) {
+ if (info->return_object) {
/*
- * Delete the internal return object. NOTE: Interpreter
- * must be locked to avoid race condition.
+ * Delete the internal return object. NOTE: Interpreter must be
+ * locked to avoid race condition.
*/
status2 = acpi_ex_enter_interpreter();
if (ACPI_SUCCESS(status2)) {
- /*
- * Delete the internal return object. (Or at least
- * decrement the reference count by one)
- */
- acpi_ut_remove_reference(info.return_object);
+
+ /* Remove one reference on the return object (should delete it) */
+
+ acpi_ut_remove_reference(info->return_object);
acpi_ex_exit_interpreter();
}
}
+ cleanup:
+
/* Free the input parameter list (if we created one) */
- if (info.parameters) {
+ if (info->parameters) {
/* Free the allocated parameter block */
- acpi_ut_delete_internal_object_list(info.parameters);
+ acpi_ut_delete_internal_object_list(info->parameters);
}
+ ACPI_FREE(info);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index 1303e2b062bb..978213a6c19f 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -112,9 +112,8 @@ acpi_get_handle(acpi_handle parent,
/*
* Find the Node and convert to a handle
*/
- status =
- acpi_ns_get_node_by_path(pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
- &node);
+ status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH,
+ &node);
*ret_handle = NULL;
if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index 796f6b719929..7ee2f2e77525 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -464,6 +464,7 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
thread = acpi_ut_create_thread_state();
if (!thread) {
+ acpi_ds_delete_walk_state(walk_state);
return_ACPI_STATUS(AE_NO_MEMORY);
}
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 6b1411f1087d..5d996c1140af 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -50,14 +50,14 @@
ACPI_MODULE_NAME("psxface")
/* Local Prototypes */
-static void acpi_ps_start_trace(struct acpi_parameter_info *info);
+static void acpi_ps_start_trace(struct acpi_evaluate_info *info);
-static void acpi_ps_stop_trace(struct acpi_parameter_info *info);
+static void acpi_ps_stop_trace(struct acpi_evaluate_info *info);
-static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info);
+static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info);
static void
-acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action);
+acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
/*******************************************************************************
*
@@ -113,7 +113,7 @@ acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags)
*
******************************************************************************/
-static void acpi_ps_start_trace(struct acpi_parameter_info *info)
+static void acpi_ps_start_trace(struct acpi_evaluate_info *info)
{
acpi_status status;
@@ -125,7 +125,7 @@ static void acpi_ps_start_trace(struct acpi_parameter_info *info)
}
if ((!acpi_gbl_trace_method_name) ||
- (acpi_gbl_trace_method_name != info->node->name.integer)) {
+ (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
goto exit;
}
@@ -158,7 +158,7 @@ static void acpi_ps_start_trace(struct acpi_parameter_info *info)
*
******************************************************************************/
-static void acpi_ps_stop_trace(struct acpi_parameter_info *info)
+static void acpi_ps_stop_trace(struct acpi_evaluate_info *info)
{
acpi_status status;
@@ -170,7 +170,7 @@ static void acpi_ps_stop_trace(struct acpi_parameter_info *info)
}
if ((!acpi_gbl_trace_method_name) ||
- (acpi_gbl_trace_method_name != info->node->name.integer)) {
+ (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
goto exit;
}
@@ -212,7 +212,7 @@ static void acpi_ps_stop_trace(struct acpi_parameter_info *info)
*
******************************************************************************/
-acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
+acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
{
acpi_status status;
@@ -220,14 +220,15 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
/* Validate the Info and method Node */
- if (!info || !info->node) {
+ if (!info || !info->resolved_node) {
return_ACPI_STATUS(AE_NULL_ENTRY);
}
/* Init for new method, wait on concurrency semaphore */
status =
- acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
+ acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc,
+ NULL);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -248,7 +249,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
"**** Begin Method Parse **** Entry=%p obj=%p\n",
- info->node, info->obj_desc));
+ info->resolved_node, info->obj_desc));
info->pass_number = 1;
status = acpi_ps_execute_pass(info);
@@ -261,7 +262,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
"**** Begin Method Execution **** Entry=%p obj=%p\n",
- info->node, info->obj_desc));
+ info->resolved_node, info->obj_desc));
info->pass_number = 3;
status = acpi_ps_execute_pass(info);
@@ -300,7 +301,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
*
* FUNCTION: acpi_ps_update_parameter_list
*
- * PARAMETERS: Info - See struct acpi_parameter_info
+ * PARAMETERS: Info - See struct acpi_evaluate_info
* (Used: parameter_type and Parameters)
* Action - Add or Remove reference
*
@@ -311,7 +312,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
******************************************************************************/
static void
-acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action)
+acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
{
acpi_native_uint i;
@@ -334,7 +335,7 @@ acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action)
*
* FUNCTION: acpi_ps_execute_pass
*
- * PARAMETERS: Info - See struct acpi_parameter_info
+ * PARAMETERS: Info - See struct acpi_evaluate_info
* (Used: pass_number, Node, and obj_desc)
*
* RETURN: Status
@@ -343,7 +344,7 @@ acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action)
*
******************************************************************************/
-static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info)
+static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info)
{
acpi_status status;
union acpi_parse_object *op;
@@ -368,7 +369,7 @@ static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info)
goto cleanup;
}
- status = acpi_ds_init_aml_walk(walk_state, op, info->node,
+ status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
info->obj_desc->method.aml_start,
info->obj_desc->method.aml_length,
info->pass_number == 1 ? NULL : info,
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index 0e493f2fec4d..a9cbee8e8b44 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -442,7 +442,7 @@ acpi_rs_set_resource_source(union aml_resource * aml,
*
* FUNCTION: acpi_rs_get_prt_method_data
*
- * PARAMETERS: Handle - Handle to the containing object
+ * PARAMETERS: Node - Device node
* ret_buffer - Pointer to a buffer structure for the
* results
*
@@ -457,7 +457,8 @@ acpi_rs_set_resource_source(union aml_resource * aml,
******************************************************************************/
acpi_status
-acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer)
+acpi_rs_get_prt_method_data(struct acpi_namespace_node * node,
+ struct acpi_buffer * ret_buffer)
{
union acpi_operand_object *obj_desc;
acpi_status status;
@@ -468,7 +469,7 @@ acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer)
/* Execute the method, no parameters */
- status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRT,
+ status = acpi_ut_evaluate_object(node, METHOD_NAME__PRT,
ACPI_BTYPE_PACKAGE, &obj_desc);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -490,7 +491,7 @@ acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer)
*
* FUNCTION: acpi_rs_get_crs_method_data
*
- * PARAMETERS: Handle - Handle to the containing object
+ * PARAMETERS: Node - Device node
* ret_buffer - Pointer to a buffer structure for the
* results
*
@@ -505,7 +506,8 @@ acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer)
******************************************************************************/
acpi_status
-acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
+acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
+ struct acpi_buffer *ret_buffer)
{
union acpi_operand_object *obj_desc;
acpi_status status;
@@ -516,7 +518,7 @@ acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
/* Execute the method, no parameters */
- status = acpi_ut_evaluate_object(handle, METHOD_NAME__CRS,
+ status = acpi_ut_evaluate_object(node, METHOD_NAME__CRS,
ACPI_BTYPE_BUFFER, &obj_desc);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -539,7 +541,7 @@ acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
*
* FUNCTION: acpi_rs_get_prs_method_data
*
- * PARAMETERS: Handle - Handle to the containing object
+ * PARAMETERS: Node - Device node
* ret_buffer - Pointer to a buffer structure for the
* results
*
@@ -555,7 +557,8 @@ acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
+acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
+ struct acpi_buffer *ret_buffer)
{
union acpi_operand_object *obj_desc;
acpi_status status;
@@ -566,7 +569,7 @@ acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
/* Execute the method, no parameters */
- status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRS,
+ status = acpi_ut_evaluate_object(node, METHOD_NAME__PRS,
ACPI_BTYPE_BUFFER, &obj_desc);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -641,7 +644,7 @@ acpi_rs_get_method_data(acpi_handle handle,
*
* FUNCTION: acpi_rs_set_srs_method_data
*
- * PARAMETERS: Handle - Handle to the containing object
+ * PARAMETERS: Node - Device node
* in_buffer - Pointer to a buffer structure of the
* parameter
*
@@ -653,23 +656,37 @@ acpi_rs_get_method_data(acpi_handle handle,
* If the function fails an appropriate status will be returned
* and the contents of the callers buffer is undefined.
*
+ * Note: Parameters guaranteed valid by caller
+ *
******************************************************************************/
acpi_status
-acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer)
+acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
+ struct acpi_buffer *in_buffer)
{
- struct acpi_parameter_info info;
- union acpi_operand_object *params[2];
+ struct acpi_evaluate_info *info;
+ union acpi_operand_object *args[2];
acpi_status status;
struct acpi_buffer buffer;
ACPI_FUNCTION_TRACE(rs_set_srs_method_data);
- /* Parameters guaranteed valid by caller */
+ /* Allocate and initialize the evaluation information block */
+
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+ info->prefix_node = node;
+ info->pathname = METHOD_NAME__SRS;
+ info->parameters = args;
+ info->parameter_type = ACPI_PARAM_ARGS;
+ info->flags = ACPI_IGNORE_RETURN_VALUE;
/*
* The in_buffer parameter will point to a linked list of
- * resource parameters. It needs to be formatted into a
+ * resource parameters. It needs to be formatted into a
* byte stream to be sent in as an input parameter to _SRS
*
* Convert the linked list into a byte stream
@@ -677,42 +694,36 @@ acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer)
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto cleanup;
}
- /* Init the param object */
+ /* Create and initialize the method parameter object */
- params[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
- if (!params[0]) {
- acpi_os_free(buffer.pointer);
- return_ACPI_STATUS(AE_NO_MEMORY);
+ args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
+ if (!args[0]) {
+ /*
+ * Must free the buffer allocated above (otherwise it is freed
+ * later)
+ */
+ ACPI_FREE(buffer.pointer);
+ status = AE_NO_MEMORY;
+ goto cleanup;
}
- /* Set up the parameter object */
-
- params[0]->buffer.length = (u32) buffer.length;
- params[0]->buffer.pointer = buffer.pointer;
- params[0]->common.flags = AOPOBJ_DATA_VALID;
- params[1] = NULL;
+ args[0]->buffer.length = (u32) buffer.length;
+ args[0]->buffer.pointer = buffer.pointer;
+ args[0]->common.flags = AOPOBJ_DATA_VALID;
+ args[1] = NULL;
- info.node = handle;
- info.parameters = params;
- info.parameter_type = ACPI_PARAM_ARGS;
+ /* Execute the method, no return value is expected */
- /* Execute the method, no return value */
+ status = acpi_ns_evaluate(info);
- status = acpi_ns_evaluate_relative(METHOD_NAME__SRS, &info);
- if (ACPI_SUCCESS(status)) {
-
- /* Delete any return object (especially if implicit_return is enabled) */
-
- if (info.return_object) {
- acpi_ut_remove_reference(info.return_object);
- }
- }
+ /* Clean up and return the status from acpi_ns_evaluate */
- /* Clean up and return the status from acpi_ns_evaluate_relative */
+ acpi_ut_remove_reference(args[0]);
- acpi_ut_remove_reference(params[0]);
+ cleanup:
+ ACPI_FREE(info);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index 8c1628c12cc8..1999e2ab7daa 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -43,6 +43,7 @@
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
+#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_RESOURCES
ACPI_MODULE_NAME("rsxface")
@@ -66,19 +67,80 @@ ACPI_MODULE_NAME("rsxface")
static acpi_status
acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
+static acpi_status
+acpi_rs_validate_parameters(acpi_handle device_handle,
+ struct acpi_buffer *buffer,
+ struct acpi_namespace_node **return_node);
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_validate_parameters
+ *
+ * PARAMETERS: device_handle - Handle to a device
+ * Buffer - Pointer to a data buffer
+ * return_node - Pointer to where the device node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Common parameter validation for resource interfaces
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_rs_validate_parameters(acpi_handle device_handle,
+ struct acpi_buffer *buffer,
+ struct acpi_namespace_node **return_node)
+{
+ acpi_status status;
+ struct acpi_namespace_node *node;
+
+ ACPI_FUNCTION_TRACE(rs_validate_parameters);
+
+ /*
+ * Must have a valid handle to an ACPI device
+ */
+ if (!device_handle) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ node = acpi_ns_map_handle_to_node(device_handle);
+ if (!node) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ if (node->type != ACPI_TYPE_DEVICE) {
+ return_ACPI_STATUS(AE_TYPE);
+ }
+
+ /*
+ * Validate the user buffer object
+ *
+ * if there is a non-zero buffer length we also need a valid pointer in
+ * the buffer. If it's a zero buffer length, we'll be returning the
+ * needed buffer size (later), so keep going.
+ */
+ status = acpi_ut_validate_buffer(buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ *return_node = node;
+ return_ACPI_STATUS(AE_OK);
+}
+
/*******************************************************************************
*
* FUNCTION: acpi_get_irq_routing_table
*
- * PARAMETERS: device_handle - a handle to the Bus device we are querying
- * ret_buffer - a pointer to a buffer to receive the
+ * PARAMETERS: device_handle - Handle to the Bus device we are querying
+ * ret_buffer - Pointer to a buffer to receive the
* current resources for the device
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get the IRQ routing table for a
- * specific bus. The caller must first acquire a handle for the
- * desired bus. The routine table is placed in the buffer pointed
+ * specific bus. The caller must first acquire a handle for the
+ * desired bus. The routine table is placed in the buffer pointed
* to by the ret_buffer variable parameter.
*
* If the function fails an appropriate status will be returned
@@ -94,25 +156,18 @@ acpi_get_irq_routing_table(acpi_handle device_handle,
struct acpi_buffer *ret_buffer)
{
acpi_status status;
+ struct acpi_namespace_node *node;
ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
- /*
- * Must have a valid handle and buffer, So we have to have a handle
- * and a return buffer structure, and if there is a non-zero buffer length
- * we also need a valid pointer in the buffer. If it's a zero buffer length,
- * we'll be returning the needed buffer size, so keep going.
- */
- if (!device_handle) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
+ /* Validate parameters then dispatch to internal routine */
- status = acpi_ut_validate_buffer(ret_buffer);
+ status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_rs_get_prt_method_data(device_handle, ret_buffer);
+ status = acpi_rs_get_prt_method_data(node, ret_buffer);
return_ACPI_STATUS(status);
}
@@ -122,16 +177,16 @@ ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
*
* FUNCTION: acpi_get_current_resources
*
- * PARAMETERS: device_handle - a handle to the device object for the
+ * PARAMETERS: device_handle - Handle to the device object for the
* device we are querying
- * ret_buffer - a pointer to a buffer to receive the
+ * ret_buffer - Pointer to a buffer to receive the
* current resources for the device
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get the current resources for a
- * specific device. The caller must first acquire a handle for
- * the desired device. The resource data is placed in the buffer
+ * specific device. The caller must first acquire a handle for
+ * the desired device. The resource data is placed in the buffer
* pointed to by the ret_buffer variable parameter.
*
* If the function fails an appropriate status will be returned
@@ -146,25 +201,18 @@ acpi_get_current_resources(acpi_handle device_handle,
struct acpi_buffer *ret_buffer)
{
acpi_status status;
+ struct acpi_namespace_node *node;
ACPI_FUNCTION_TRACE(acpi_get_current_resources);
- /*
- * Must have a valid handle and buffer, So we have to have a handle
- * and a return buffer structure, and if there is a non-zero buffer length
- * we also need a valid pointer in the buffer. If it's a zero buffer length,
- * we'll be returning the needed buffer size, so keep going.
- */
- if (!device_handle) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
+ /* Validate parameters then dispatch to internal routine */
- status = acpi_ut_validate_buffer(ret_buffer);
+ status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_rs_get_crs_method_data(device_handle, ret_buffer);
+ status = acpi_rs_get_crs_method_data(node, ret_buffer);
return_ACPI_STATUS(status);
}
@@ -175,16 +223,16 @@ ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
*
* FUNCTION: acpi_get_possible_resources
*
- * PARAMETERS: device_handle - a handle to the device object for the
+ * PARAMETERS: device_handle - Handle to the device object for the
* device we are querying
- * ret_buffer - a pointer to a buffer to receive the
+ * ret_buffer - Pointer to a buffer to receive the
* resources for the device
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get a list of the possible resources
- * for a specific device. The caller must first acquire a handle
- * for the desired device. The resource data is placed in the
+ * for a specific device. The caller must first acquire a handle
+ * for the desired device. The resource data is placed in the
* buffer pointed to by the ret_buffer variable.
*
* If the function fails an appropriate status will be returned
@@ -196,25 +244,18 @@ acpi_get_possible_resources(acpi_handle device_handle,
struct acpi_buffer *ret_buffer)
{
acpi_status status;
+ struct acpi_namespace_node *node;
ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
- /*
- * Must have a valid handle and buffer, So we have to have a handle
- * and a return buffer structure, and if there is a non-zero buffer length
- * we also need a valid pointer in the buffer. If it's a zero buffer length,
- * we'll be returning the needed buffer size, so keep going.
- */
- if (!device_handle) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
+ /* Validate parameters then dispatch to internal routine */
- status = acpi_ut_validate_buffer(ret_buffer);
+ status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_rs_get_prs_method_data(device_handle, ret_buffer);
+ status = acpi_rs_get_prs_method_data(node, ret_buffer);
return_ACPI_STATUS(status);
}
@@ -223,113 +264,18 @@ ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
/*******************************************************************************
*
- * FUNCTION: acpi_walk_resources
- *
- * PARAMETERS: device_handle - Handle to the device object for the
- * device we are querying
- * Name - Method name of the resources we want
- * (METHOD_NAME__CRS or METHOD_NAME__PRS)
- * user_function - Called for each resource
- * Context - Passed to user_function
- *
- * RETURN: Status
- *
- * DESCRIPTION: Retrieves the current or possible resource list for the
- * specified device. The user_function is called once for
- * each resource in the list.
- *
- ******************************************************************************/
-acpi_status
-acpi_walk_resources(acpi_handle device_handle,
- char *name,
- acpi_walk_resource_callback user_function, void *context)
-{
- acpi_status status;
- struct acpi_buffer buffer;
- struct acpi_resource *resource;
- struct acpi_resource *resource_end;
-
- ACPI_FUNCTION_TRACE(acpi_walk_resources);
-
- /* Parameter validation */
-
- if (!device_handle || !user_function || !name ||
- (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
- !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
-
- /* Get the _CRS or _PRS resource list */
-
- buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_rs_get_method_data(device_handle, name, &buffer);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- /* Buffer now contains the resource list */
-
- resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
- resource_end =
- ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
-
- /* Walk the resource list until the end_tag is found (or buffer end) */
-
- while (resource < resource_end) {
-
- /* Sanity check the resource */
-
- if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
- status = AE_AML_INVALID_RESOURCE_TYPE;
- break;
- }
-
- /* Invoke the user function, abort on any error returned */
-
- status = user_function(resource, context);
- if (ACPI_FAILURE(status)) {
- if (status == AE_CTRL_TERMINATE) {
-
- /* This is an OK termination by the user function */
-
- status = AE_OK;
- }
- break;
- }
-
- /* end_tag indicates end-of-list */
-
- if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
- break;
- }
-
- /* Get the next resource descriptor */
-
- resource =
- ACPI_ADD_PTR(struct acpi_resource, resource,
- resource->length);
- }
-
- ACPI_FREE(buffer.pointer);
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_walk_resources)
-
-/*******************************************************************************
- *
* FUNCTION: acpi_set_current_resources
*
- * PARAMETERS: device_handle - a handle to the device object for the
- * device we are changing the resources of
- * in_buffer - a pointer to a buffer containing the
+ * PARAMETERS: device_handle - Handle to the device object for the
+ * device we are setting resources
+ * in_buffer - Pointer to a buffer containing the
* resources to be set for the device
*
* RETURN: Status
*
* DESCRIPTION: This function is called to set the current resources for a
- * specific device. The caller must first acquire a handle for
- * the desired device. The resource data is passed to the routine
+ * specific device. The caller must first acquire a handle for
+ * the desired device. The resource data is passed to the routine
* the buffer pointed to by the in_buffer variable.
*
******************************************************************************/
@@ -338,17 +284,24 @@ acpi_set_current_resources(acpi_handle device_handle,
struct acpi_buffer *in_buffer)
{
acpi_status status;
+ struct acpi_namespace_node *node;
ACPI_FUNCTION_TRACE(acpi_set_current_resources);
- /* Must have a valid handle and buffer */
+ /* Validate the buffer, don't allow zero length */
- if ((!device_handle) ||
- (!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
+ if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status = acpi_rs_set_srs_method_data(device_handle, in_buffer);
+ /* Validate parameters then dispatch to internal routine */
+
+ status = acpi_rs_validate_parameters(device_handle, in_buffer, &node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ status = acpi_rs_set_srs_method_data(node, in_buffer);
return_ACPI_STATUS(status);
}
@@ -358,15 +311,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_current_resources)
*
* FUNCTION: acpi_resource_to_address64
*
- * PARAMETERS: Resource - Pointer to a resource
- * Out - Pointer to the users's return
- * buffer (a struct
- * struct acpi_resource_address64)
+ * PARAMETERS: Resource - Pointer to a resource
+ * Out - Pointer to the users's return buffer
+ * (a struct acpi_resource_address64)
*
* RETURN: Status
*
* DESCRIPTION: If the resource is an address16, address32, or address64,
- * copy it to the address64 return buffer. This saves the
+ * copy it to the address64 return buffer. This saves the
* caller from having to duplicate code for different-sized
* addresses.
*
@@ -418,12 +370,12 @@ ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
*
* FUNCTION: acpi_get_vendor_resource
*
- * PARAMETERS: device_handle - Handle for the parent device object
- * Name - Method name for the parent resource
- * (METHOD_NAME__CRS or METHOD_NAME__PRS)
- * Uuid - Pointer to the UUID to be matched.
- * includes both subtype and 16-byte UUID
- * ret_buffer - Where the vendor resource is returned
+ * PARAMETERS: device_handle - Handle for the parent device object
+ * Name - Method name for the parent resource
+ * (METHOD_NAME__CRS or METHOD_NAME__PRS)
+ * Uuid - Pointer to the UUID to be matched.
+ * includes both subtype and 16-byte UUID
+ * ret_buffer - Where the vendor resource is returned
*
* RETURN: Status
*
@@ -525,3 +477,99 @@ acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
}
ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_walk_resources
+ *
+ * PARAMETERS: device_handle - Handle to the device object for the
+ * device we are querying
+ * Name - Method name of the resources we want
+ * (METHOD_NAME__CRS or METHOD_NAME__PRS)
+ * user_function - Called for each resource
+ * Context - Passed to user_function
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieves the current or possible resource list for the
+ * specified device. The user_function is called once for
+ * each resource in the list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_walk_resources(acpi_handle device_handle,
+ char *name,
+ acpi_walk_resource_callback user_function, void *context)
+{
+ acpi_status status;
+ struct acpi_buffer buffer;
+ struct acpi_resource *resource;
+ struct acpi_resource *resource_end;
+
+ ACPI_FUNCTION_TRACE(acpi_walk_resources);
+
+ /* Parameter validation */
+
+ if (!device_handle || !user_function || !name ||
+ (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
+ !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ /* Get the _CRS or _PRS resource list */
+
+ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ status = acpi_rs_get_method_data(device_handle, name, &buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /* Buffer now contains the resource list */
+
+ resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
+ resource_end =
+ ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
+
+ /* Walk the resource list until the end_tag is found (or buffer end) */
+
+ while (resource < resource_end) {
+
+ /* Sanity check the resource */
+
+ if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
+ status = AE_AML_INVALID_RESOURCE_TYPE;
+ break;
+ }
+
+ /* Invoke the user function, abort on any error returned */
+
+ status = user_function(resource, context);
+ if (ACPI_FAILURE(status)) {
+ if (status == AE_CTRL_TERMINATE) {
+
+ /* This is an OK termination by the user function */
+
+ status = AE_OK;
+ }
+ break;
+ }
+
+ /* end_tag indicates end-of-list */
+
+ if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
+ break;
+ }
+
+ /* Get the next resource descriptor */
+
+ resource =
+ ACPI_ADD_PTR(struct acpi_resource, resource,
+ resource->length);
+ }
+
+ ACPI_FREE(buffer.pointer);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_walk_resources)
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 3a4f46ca3884..99eacceff563 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -417,7 +417,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
*
* PARAMETERS: table_type - one of the defined table types
* Instance - Which table of this type
- * table_ptr_loc - pointer to location to place the pointer for
+ * return_table - pointer to location to place the pointer for
* return
*
* RETURN: Status
@@ -428,58 +428,34 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
acpi_status
acpi_tb_get_table_ptr(acpi_table_type table_type,
- u32 instance, struct acpi_table_header **table_ptr_loc)
+ u32 instance, struct acpi_table_header **return_table)
{
struct acpi_table_desc *table_desc;
u32 i;
ACPI_FUNCTION_TRACE(tb_get_table_ptr);
- if (!acpi_gbl_DSDT) {
- return_ACPI_STATUS(AE_NO_ACPI_TABLES);
- }
-
if (table_type > ACPI_TABLE_ID_MAX) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /*
- * For all table types (Single/Multiple), the first
- * instance is always in the list head.
- */
- if (instance == 1) {
-
- /* Get the first */
-
- *table_ptr_loc = NULL;
- if (acpi_gbl_table_lists[table_type].next) {
- *table_ptr_loc =
- acpi_gbl_table_lists[table_type].next->pointer;
- }
- return_ACPI_STATUS(AE_OK);
- }
-
- /* Check for instance out of range */
+ /* Check for instance out of range of the current table count */
if (instance > acpi_gbl_table_lists[table_type].count) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
- /* Walk the list to get the desired table
- * Since the if (Instance == 1) check above checked for the
- * first table, setting table_desc equal to the .Next member
- * is actually pointing to the second table. Therefore, we
- * need to walk from the 2nd table until we reach the Instance
- * that the user is looking for and return its table pointer.
+ /*
+ * Walk the list to get the desired table
+ * Note: Instance is one-based
*/
table_desc = acpi_gbl_table_lists[table_type].next;
- for (i = 2; i < instance; i++) {
+ for (i = 1; i < instance; i++) {
table_desc = table_desc->next;
}
/* We are now pointing to the requested table's descriptor */
- *table_ptr_loc = table_desc->pointer;
-
+ *return_table = table_desc->pointer;
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index 494965229fa2..abcb08c2592a 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -78,7 +78,7 @@ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address)
*/
status = acpi_os_map_memory(address->pointer.physical,
sizeof(struct rsdp_descriptor),
- (void *)&rsdp);
+ ACPI_CAST_PTR(void, &rsdp));
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -95,11 +95,16 @@ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address)
goto cleanup;
}
- /* The RSDP supplied is OK */
+ /* RSDP is ok. Init the table info */
table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp);
table_info.length = sizeof(struct rsdp_descriptor);
- table_info.allocation = ACPI_MEM_MAPPED;
+
+ if (address->pointer_type == ACPI_PHYSICAL_POINTER) {
+ table_info.allocation = ACPI_MEM_MAPPED;
+ } else {
+ table_info.allocation = ACPI_MEM_NOT_ALLOCATED;
+ }
/* Save the table pointers and allocation info */
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 65a7c2ed9aa1..7940fc1bd69e 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -61,24 +61,6 @@ acpi_status acpi_ut_create_caches(void)
{
acpi_status status;
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-
- /* Memory allocation lists */
-
- status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
- if (ACPI_FAILURE(status)) {
- return (status);
- }
-
- status =
- acpi_ut_create_list("Acpi-Namespace",
- sizeof(struct acpi_namespace_node),
- &acpi_gbl_ns_node_list);
- if (ACPI_FAILURE(status)) {
- return (status);
- }
-#endif
-
/* Object Caches, for frequently used objects */
status =
@@ -125,6 +107,24 @@ acpi_status acpi_ut_create_caches(void)
return (status);
}
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+ /* Memory allocation lists */
+
+ status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ status =
+ acpi_ut_create_list("Acpi-Namespace",
+ sizeof(struct acpi_namespace_node),
+ &acpi_gbl_ns_node_list);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+#endif
+
return (AE_OK);
}
@@ -158,6 +158,21 @@ acpi_status acpi_ut_delete_caches(void)
(void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
acpi_gbl_ps_node_ext_cache = NULL;
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+ /* Debug only - display leftover memory allocation, if any */
+
+ acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
+
+ /* Free memory lists */
+
+ acpi_os_free(acpi_gbl_global_list);
+ acpi_gbl_global_list = NULL;
+
+ acpi_os_free(acpi_gbl_ns_node_list);
+ acpi_gbl_ns_node_list = NULL;
+#endif
+
return (AE_OK);
}
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 0bb4b59b2804..67b9f325c6fa 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -319,11 +319,9 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
new_count = count;
/*
- * Perform the reference count action
- * (increment, decrement, or force delete)
+ * Perform the reference count action (increment, decrement, force delete)
*/
switch (action) {
-
case REF_INCREMENT:
new_count++;
@@ -360,7 +358,6 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
if (new_count == 0) {
acpi_ut_delete_internal_obj(object);
}
-
break;
case REF_FORCE_DELETE:
@@ -385,13 +382,10 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
* (A deleted object will have a huge reference count)
*/
if (count > ACPI_MAX_REFERENCE_COUNT) {
-
ACPI_WARNING((AE_INFO,
- "Large Reference Count (%X) in object %p",
- count, object));
+ "Large Reference Count (%X) in object %p", count,
+ object));
}
-
- return;
}
/*******************************************************************************
@@ -417,7 +411,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
******************************************************************************/
acpi_status
-acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action)
+acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
{
acpi_status status = AE_OK;
union acpi_generic_state *state_list = NULL;
@@ -521,11 +515,11 @@ acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action)
case ACPI_TYPE_REGION:
default:
- break; /* No subobjects */
+ break; /* No subobjects for all other types */
}
/*
- * Now we can update the count in the main object. This can only
+ * Now we can update the count in the main object. This can only
* happen after we update the sub-objects in case this causes the
* main object to be deleted.
*/
@@ -606,8 +600,8 @@ void acpi_ut_remove_reference(union acpi_operand_object *object)
ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object);
/*
- * Allow a NULL pointer to be passed in, just ignore it. This saves
- * each caller from having to check. Also, ignore NS nodes.
+ * Allow a NULL pointer to be passed in, just ignore it. This saves
+ * each caller from having to check. Also, ignore NS nodes.
*
*/
if (!object ||
@@ -627,7 +621,7 @@ void acpi_ut_remove_reference(union acpi_operand_object *object)
/*
* Decrement the reference count, and only actually delete the object
- * if the reference count becomes 0. (Must also decrement the ref count
+ * if the reference count becomes 0. (Must also decrement the ref count
* of all subobjects!)
*/
(void)acpi_ut_update_object_reference(object, REF_DECREMENT);
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 444d3a502c46..d6d7121583c0 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -181,19 +181,26 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
u32 expected_return_btypes,
union acpi_operand_object **return_desc)
{
- struct acpi_parameter_info info;
+ struct acpi_evaluate_info *info;
acpi_status status;
u32 return_btype;
ACPI_FUNCTION_TRACE(ut_evaluate_object);
- info.node = prefix_node;
- info.parameters = NULL;
- info.parameter_type = ACPI_PARAM_ARGS;
+ /* Allocate the evaluation information block */
+
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+ info->prefix_node = prefix_node;
+ info->pathname = path;
+ info->parameter_type = ACPI_PARAM_ARGS;
/* Evaluate the object/method */
- status = acpi_ns_evaluate_relative(path, &info);
+ status = acpi_ns_evaluate(info);
if (ACPI_FAILURE(status)) {
if (status == AE_NOT_FOUND) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -205,25 +212,25 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
prefix_node, path, status);
}
- return_ACPI_STATUS(status);
+ goto cleanup;
}
/* Did we get a return object? */
- if (!info.return_object) {
+ if (!info->return_object) {
if (expected_return_btypes) {
ACPI_ERROR_METHOD("No object was returned from",
prefix_node, path, AE_NOT_EXIST);
- return_ACPI_STATUS(AE_NOT_EXIST);
+ status = AE_NOT_EXIST;
}
- return_ACPI_STATUS(AE_OK);
+ goto cleanup;
}
/* Map the return object type to the bitmapped type */
- switch (ACPI_GET_OBJECT_TYPE(info.return_object)) {
+ switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_BTYPE_INTEGER;
break;
@@ -251,8 +258,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
* happen frequently if the "implicit return" feature is enabled.
* Just delete the return object and return AE_OK.
*/
- acpi_ut_remove_reference(info.return_object);
- return_ACPI_STATUS(AE_OK);
+ acpi_ut_remove_reference(info->return_object);
+ goto cleanup;
}
/* Is the return object one of the expected types? */
@@ -264,19 +271,23 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
ACPI_ERROR((AE_INFO,
"Type returned from %s was incorrect: %s, expected Btypes: %X",
path,
- acpi_ut_get_object_type_name(info.return_object),
+ acpi_ut_get_object_type_name(info->return_object),
expected_return_btypes));
/* On error exit, we must delete the return object */
- acpi_ut_remove_reference(info.return_object);
- return_ACPI_STATUS(AE_TYPE);
+ acpi_ut_remove_reference(info->return_object);
+ status = AE_TYPE;
+ goto cleanup;
}
/* Object type is OK, return it */
- *return_desc = info.return_object;
- return_ACPI_STATUS(AE_OK);
+ *return_desc = info->return_object;
+
+ cleanup:
+ ACPI_FREE(info);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index c65747d3c880..ff76055eb7d6 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -228,6 +228,7 @@ void acpi_ut_subsystem_shutdown(void)
/* Subsystem appears active, go ahead and shut it down */
acpi_gbl_shutdown = TRUE;
+ acpi_gbl_startup_flags = 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
/* Close the acpi_event Handling */
@@ -245,12 +246,5 @@ void acpi_ut_subsystem_shutdown(void)
/* Purge the local caches */
(void)acpi_ut_delete_caches();
-
- /* Debug only - display leftover memory allocation, if any */
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
-#endif
-
return_VOID;
}
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 874467117cec..5c75d35ad1cd 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -601,7 +601,8 @@ acpi_name acpi_ut_repair_name(acpi_name name)
* FUNCTION: acpi_ut_strtoul64
*
* PARAMETERS: String - Null terminated string
- * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE
+ * Base - Radix of the string: 16 or ACPI_ANY_BASE;
+ * ACPI_ANY_BASE means 'in behalf of to_integer'
* ret_integer - Where the converted integer is returned
*
* RETURN: Status and Converted value
@@ -617,16 +618,17 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
u32 this_digit = 0;
acpi_integer return_value = 0;
acpi_integer quotient;
+ acpi_integer dividend;
+ u32 to_integer_op = (base == ACPI_ANY_BASE);
+ u32 mode32 = (acpi_gbl_integer_byte_width == 4);
+ u8 valid_digits = 0;
+ u8 sign_of0x = 0;
+ u8 term = 0;
ACPI_FUNCTION_TRACE(ut_stroul64);
- if ((!string) || !(*string)) {
- goto error_exit;
- }
-
switch (base) {
case ACPI_ANY_BASE:
- case 10:
case 16:
break;
@@ -635,39 +637,45 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
+ if (!string) {
+ goto error_exit;
+ }
+
/* Skip over any white space in the buffer */
- while (ACPI_IS_SPACE(*string) || *string == '\t') {
+ while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
string++;
}
- /*
- * If the input parameter Base is zero, then we need to
- * determine if it is decimal or hexadecimal:
- */
- if (base == 0) {
+ if (to_integer_op) {
+ /*
+ * Base equal to ACPI_ANY_BASE means 'to_integer operation case'.
+ * We need to determine if it is decimal or hexadecimal.
+ */
if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
+ sign_of0x = 1;
base = 16;
+
+ /* Skip over the leading '0x' */
string += 2;
} else {
base = 10;
}
}
- /*
- * For hexadecimal base, skip over the leading
- * 0 or 0x, if they are present.
- */
- if ((base == 16) &&
- (*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
- string += 2;
+ /* Any string left? Check that '0x' is not followed by white space. */
+
+ if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
+ if (to_integer_op) {
+ goto error_exit;
+ } else {
+ goto all_done;
+ }
}
- /* Any string left? */
+ dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
- if (!(*string)) {
- goto error_exit;
- }
+ /* At least one character in the string here */
/* Main loop: convert the string to a 64-bit integer */
@@ -677,14 +685,12 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
/* Convert ASCII 0-9 to Decimal value */
this_digit = ((u8) * string) - '0';
- } else {
- if (base == 10) {
+ } else if (base == 10) {
- /* Digit is out of range */
-
- goto error_exit;
- }
+ /* Digit is out of range; possible in to_integer case only */
+ term = 1;
+ } else {
this_digit = (u8) ACPI_TOUPPER(*string);
if (ACPI_IS_XDIGIT((char)this_digit)) {
@@ -692,22 +698,49 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
this_digit = this_digit - 'A' + 10;
} else {
- /*
- * We allow non-hex chars, just stop now, same as end-of-string.
- * See ACPI spec, string-to-integer conversion.
- */
+ term = 1;
+ }
+ }
+
+ if (term) {
+ if (to_integer_op) {
+ goto error_exit;
+ } else {
break;
}
+ } else if ((valid_digits == 0) && (this_digit == 0)
+ && !sign_of0x) {
+
+ /* Skip zeros */
+ string++;
+ continue;
+ }
+
+ valid_digits++;
+
+ if (sign_of0x
+ && ((valid_digits > 16)
+ || ((valid_digits > 8) && mode32))) {
+ /*
+ * This is to_integer operation case.
+ * No any restrictions for string-to-integer conversion,
+ * see ACPI spec.
+ */
+ goto error_exit;
}
/* Divide the digit into the correct position */
(void)
- acpi_ut_short_divide((ACPI_INTEGER_MAX -
- (acpi_integer) this_digit), base,
- &quotient, NULL);
+ acpi_ut_short_divide((dividend - (acpi_integer) this_digit),
+ base, &quotient, NULL);
+
if (return_value > quotient) {
- goto error_exit;
+ if (to_integer_op) {
+ goto error_exit;
+ } else {
+ break;
+ }
}
return_value *= base;
@@ -717,6 +750,8 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
/* All done, normal exit */
+ all_done:
+
*ret_integer = return_value;
return_ACPI_STATUS(AE_OK);