Commit 4119532c authored by Bob Moore's avatar Bob Moore Committed by Len Brown

ACPI: ACPICA 20060526

Restructured, flattened, and simplified the internal
interfaces for namespace object evaluation - resulting
in smaller code, less CPU stack use, and fewer
interfaces. (With assistance from Mikhail Kouzmich)

Fixed a problem with the CopyObject operator where the
first parameter was not typed correctly for the parser,
interpreter, compiler, and disassembler. Caused various
errors and unexpected behavior.

Fixed a problem where a ShiftLeft or ShiftRight of
more than 64 bits produced incorrect results with some
C compilers. Since the behavior of C compilers when
the shift value is larger than the datatype width is
apparently not well defined, the interpreter now detects
this condition and simply returns zero as expected in all
such cases. (BZ 395)

Fixed problem reports (Valery Podrezov) integrated: -
Update String-to-Integer conversion to match ACPI 3.0A spec
http://bugzilla.kernel.org/show_bug.cgi?id=5329
Allow interpreter to handle nested method declarations
http://bugzilla.kernel.org/show_bug.cgi?id=5361

Fixed problem reports (Fiodor Suietov) integrated: -
acpi_terminate() doesn't free debug memory allocation
list objects (BZ 355) - After Core Subsystem
shutdown, acpi_subsystem_status() returns AE_OK (BZ 356) -
acpi_os_unmap_memory() for RSDP can be invoked inconsistently
(BZ 357) - Resource Manager should return AE_TYPE for
non-device objects (BZ 358) - Incomplete cleanup branch
in AcpiNsEvaluateRelative (BZ 359) - Use acpi_os_free()
instead of ACPI_FREE in acpi_rs_set_srs_method_data (BZ 360)
- Incomplete cleanup branch in acpi_ps_parse_aml (BZ 361) -
Incomplete cleanup branch in acpi_ds_delete_walk_state (BZ 362)
- acpi_get_table_header returns AE_NO_ACPI_TABLES until DSDT
is loaded (BZ 365) - Status of the Global Initialization
Handler call not used (BZ 366) - Incorrect object parameter
to Global Initialization Handler (BZ 367)
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent b8d35192
......@@ -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;
}
......
......@@ -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
......
......@@ -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 */
......
......@@ -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]",
......
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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 */
......
......@@ -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) */
......
......@@ -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;
}
......
......@@ -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);
}
......@@ -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);
}
......
......@@ -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);
......
This diff is collapsed.
......@@ -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);
}
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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)) {
......
......@@ -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);
}
......
......@@ -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,
......
......@@ -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);
}
This diff is collapsed.
......@@ -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);
}
......@@ -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 */
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
}
/*******************************************************************************
......
......@@ -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;
}
......@@ -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);
......
......@@ -63,7 +63,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20060512
#define ACPI_CA_VERSION 0x20060526
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
......
......@@ -304,7 +304,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
acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
......
......@@ -173,13 +173,7 @@ acpi_ns_dump_objects(acpi_object_type type,
/*
* nseval - Namespace evaluation functions
*/
acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info);
acpi_status
acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info);
acpi_status
acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info);
acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info);
/*
* nsnames - Name and Scope manipulation
......@@ -202,9 +196,9 @@ u8
acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for);
acpi_status
acpi_ns_get_node_by_path(char *external_pathname,
struct acpi_namespace_node *in_prefix_node,
u32 flags, struct acpi_namespace_node **out_node);
acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
char *external_pathname,
u32 flags, struct acpi_namespace_node **out_node);
acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node);
......@@ -247,10 +241,10 @@ acpi_ns_search_and_enter(u32 entry_name,
u32 flags, struct acpi_namespace_node **ret_node);
acpi_status
acpi_ns_search_node(u32 entry_name,
struct acpi_namespace_node *node,
acpi_object_type type,
struct acpi_namespace_node **ret_node);
acpi_ns_search_one_scope(u32 entry_name,
struct acpi_namespace_node *node,
acpi_object_type type,
struct acpi_namespace_node **ret_node);
void
acpi_ns_install_node(struct acpi_walk_state *walk_state,
......
......@@ -94,7 +94,7 @@
#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME)
#define ARGP_CONTINUE_OP ARG_NONE
#define ARGP_COPY_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SIMPLENAME)
#define ARGP_COPY_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SIMPLENAME)
#define ARGP_CREATE_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
#define ARGP_CREATE_BYTE_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
#define ARGP_CREATE_DWORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
......
......@@ -71,7 +71,7 @@
/*
* psxface - Parser external interfaces
*/
acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info);
acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info);
/*
* psargs - Parse AML opcode arguments
......
......@@ -58,8 +58,7 @@ typedef enum {
OSL_GPE_HANDLER,
OSL_DEBUGGER_THREAD,
OSL_EC_POLL_HANDLER,
OSL_EC_BURST_HANDLER,
OSL_EC_BURST_HANDLER
} acpi_execute_type;
#define ACPI_NO_UNIT_LIMIT ((u32) -1)
......@@ -217,7 +216,6 @@ acpi_os_derive_pci_id(acpi_handle rhandle,
/*
* Miscellaneous
*/
acpi_status acpi_os_validate_interface(char *interface);
acpi_status
......@@ -265,11 +263,4 @@ char *acpi_os_get_next_filename(void *dir_handle);
void acpi_os_close_directory(void *dir_handle);
/*
* Debug
*/
void
acpi_os_dbg_assert(void *failed_assertion,
void *file_name, u32 line_number, char *message);
#endif /* __ACPIOSXF_H__ */
......@@ -164,23 +164,26 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/*
* rsutils
*/
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);
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);
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
#endif /* ACPI_FUTURE_USAGE */
acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
struct acpi_buffer *ret_buffer);
acpi_status
acpi_rs_get_method_data(acpi_handle handle,
char *path, struct acpi_buffer *ret_buffer);
acpi_status
acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
struct acpi_buffer *ret_buffer);
/*
* rscalc
......
......@@ -53,17 +53,25 @@
****************************************************************************/
/*
* Walk state - current state of a parse tree walk. Used for both a leisurely stroll through
* the tree (for whatever reason), and for control method execution.
* Walk state - current state of a parse tree walk. Used for both a leisurely
* stroll through the tree (for whatever reason), and for control method
* execution.
*/
#define ACPI_NEXT_OP_DOWNWARD 1
#define ACPI_NEXT_OP_UPWARD 2
/*
* Groups of definitions for walk_type used for different implementations of
* walkers (never simultaneously) - flags for interpreter:
*/
#define ACPI_WALK_NON_METHOD 0
#define ACPI_WALK_METHOD 1
#define ACPI_WALK_METHOD_RESTART 2
#define ACPI_WALK_CONST_REQUIRED 3
#define ACPI_WALK_CONST_OPTIONAL 4
#define ACPI_WALK_METHOD 0x01
#define ACPI_WALK_METHOD_RESTART 0x02
/* Flags for i_aSL compiler only */
#define ACPI_WALK_CONST_REQUIRED 0x10
#define ACPI_WALK_CONST_OPTIONAL 0x20
struct acpi_walk_state {
struct acpi_walk_state *next; /* Next walk_state in list */
......@@ -134,32 +142,6 @@ struct acpi_init_walk_info {
struct acpi_table_desc *table_desc;
};
/* Info used by acpi_ns_initialize_devices */
struct acpi_device_walk_info {
u16 device_count;
u16 num_STA;
u16 num_INI;
struct acpi_table_desc *table_desc;
};
/* TBD: [Restructure] Merge with struct above */
struct acpi_walk_info {
u32 debug_level;
u32 count;
acpi_owner_id owner_id;
u8 display_type;
};
/* Display Types */
#define ACPI_DISPLAY_SUMMARY (u8) 0
#define ACPI_DISPLAY_OBJECTS (u8) 1
#define ACPI_DISPLAY_MASK (u8) 1
#define ACPI_DISPLAY_SHORT (u8) 2
struct acpi_get_devices_info {
acpi_walk_callback user_function;
void *context;
......@@ -192,16 +174,21 @@ union acpi_aml_operands {
} mid;
};
/* Internal method parameter list */
struct acpi_parameter_info {
struct acpi_namespace_node *node;
/*
* Structure used to pass object evaluation parameters.
* Purpose is to reduce CPU stack use.
*/
struct acpi_evaluate_info {
struct acpi_namespace_node *prefix_node;
char *pathname;
union acpi_operand_object *obj_desc;
union acpi_operand_object **parameters;
struct acpi_namespace_node *resolved_node;
union acpi_operand_object *return_object;
u8 pass_number;
u8 parameter_type;
u8 return_object_type;
u8 flags;
};
/* Types for parameter_type above */
......@@ -209,4 +196,35 @@ struct acpi_parameter_info {
#define ACPI_PARAM_ARGS 0
#define ACPI_PARAM_GPE 1
/* Values for Flags above */
#define ACPI_IGNORE_RETURN_VALUE 1
/* Info used by acpi_ns_initialize_devices */
struct acpi_device_walk_info {
u16 device_count;
u16 num_STA;
u16 num_INI;
struct acpi_table_desc *table_desc;
struct acpi_evaluate_info *evaluate_info;
};
/* TBD: [Restructure] Merge with struct above */
struct acpi_walk_info {
u32 debug_level;
u32 count;
acpi_owner_id owner_id;
u8 display_type;
};
/* Display Types */
#define ACPI_DISPLAY_SUMMARY (u8) 0
#define ACPI_DISPLAY_OBJECTS (u8) 1
#define ACPI_DISPLAY_MASK (u8) 1
#define ACPI_DISPLAY_SHORT (u8) 2
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment