diff options
author | Robert Moore <robert.moore@intel.com> | 2005-07-29 15:15:00 -0700 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-07-30 00:51:39 -0400 |
commit | 0c9938cc75057c0fca1af55a55dcfc2842436695 (patch) | |
tree | d18e809bf9e3811f20c609b6515d4d1b8520cfbc /drivers/acpi/parser/psxface.c | |
parent | dd8f39bbf5154cdbfd698fc70c66faba33eafa44 (diff) |
[ACPI] ACPICA 20050729 from Bob Moore
Implemented support to ignore an attempt to install/load
a particular ACPI table more than once. Apparently there
exists BIOS code that repeatedly attempts to load the same
SSDT upon certain events. Thanks to Venkatesh Pallipadi.
Restructured the main interface to the AML parser in
order to correctly handle all exceptional conditions. This
will prevent leakage of the OwnerId resource and should
eliminate the AE_OWNER_ID_LIMIT exceptions seen on some
machines. Thanks to Alexey Starikovskiy.
Support for "module level code" has been disabled in this
version due to a number of issues that have appeared
on various machines. The support can be enabled by
defining ACPI_ENABLE_MODULE_LEVEL_CODE during subsystem
compilation. When the issues are fully resolved, the code
will be enabled by default again.
Modified the internal functions for debug print support
to define the FunctionName parameter as a (const char *)
for compatibility with compiler built-in macros such as
__FUNCTION__, etc.
Linted the entire ACPICA source tree for both 32-bit
and 64-bit.
Signed-off-by: Robert Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/parser/psxface.c')
-rw-r--r-- | drivers/acpi/parser/psxface.c | 242 |
1 files changed, 137 insertions, 105 deletions
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 5279b51e778..d1541fabaf0 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -46,19 +46,30 @@ #include <acpi/acparser.h> #include <acpi/acdispat.h> #include <acpi/acinterp.h> -#include <acpi/acnamesp.h> #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("psxface") +/* Local Prototypes */ + +static acpi_status +acpi_ps_execute_pass ( + struct acpi_parameter_info *info); + +static void +acpi_ps_update_parameter_list ( + struct acpi_parameter_info *info, + u16 action); + /******************************************************************************* * - * FUNCTION: acpi_psx_execute + * FUNCTION: acpi_ps_execute_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. @@ -67,6 +78,7 @@ * parameter_type - Type of Parameter list * return_object - Where to put method's return value (if * any). If NULL, no value is returned. + * pass_number - Parse or execute pass * * RETURN: Status * @@ -75,174 +87,194 @@ ******************************************************************************/ acpi_status -acpi_psx_execute ( +acpi_ps_execute_method ( struct acpi_parameter_info *info) { acpi_status status; - union acpi_operand_object *obj_desc; - u32 i; - union acpi_parse_object *op; - struct acpi_walk_state *walk_state; - ACPI_FUNCTION_TRACE ("psx_execute"); + ACPI_FUNCTION_TRACE ("ps_execute_method"); - /* Validate the Node and get the attached object */ + /* Validate the Info and method Node */ if (!info || !info->node) { return_ACPI_STATUS (AE_NULL_ENTRY); } - obj_desc = acpi_ns_get_attached_object (info->node); - if (!obj_desc) { - return_ACPI_STATUS (AE_NULL_OBJECT); - } - /* Init for new method, wait on concurrency semaphore */ - status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL); + status = acpi_ds_begin_method_execution (info->node, info->obj_desc, NULL); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - if ((info->parameter_type == ACPI_PARAM_ARGS) && - (info->parameters)) { - /* - * The caller "owns" the parameters, so give each one an extra - * reference - */ - for (i = 0; info->parameters[i]; i++) { - acpi_ut_add_reference (info->parameters[i]); - } - } - - /* - * 1) Perform the first pass parse of the method to enter any - * named objects that it creates into the namespace - */ - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "**** Begin Method Parse **** Entry=%p obj=%p\n", - info->node, obj_desc)); - - /* Create and init a Root Node */ - - op = acpi_ps_create_scope_op (); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup1; - } - /* * Get a new owner_id for objects created by this method. Namespace * objects (such as Operation Regions) can be created during the * first pass parse. */ - status = acpi_ut_allocate_owner_id (&obj_desc->method.owner_id); + status = acpi_ut_allocate_owner_id (&info->obj_desc->method.owner_id); if (ACPI_FAILURE (status)) { - goto cleanup2; - } - - /* Create and initialize a new walk state */ - - walk_state = acpi_ds_create_walk_state (obj_desc->method.owner_id, - NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup2; + return_ACPI_STATUS (status); } - status = acpi_ds_init_aml_walk (walk_state, op, info->node, - obj_desc->method.aml_start, - obj_desc->method.aml_length, NULL, 1); - if (ACPI_FAILURE (status)) { - goto cleanup3; - } + /* + * The caller "owns" the parameters, so give each one an extra + * reference + */ + acpi_ps_update_parameter_list (info, REF_INCREMENT); - /* Parse the AML */ + /* + * 1) Perform the first pass parse of the method to enter any + * named objects that it creates into the namespace + */ + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "**** Begin Method Parse **** Entry=%p obj=%p\n", + info->node, info->obj_desc)); - status = acpi_ps_parse_aml (walk_state); - acpi_ps_delete_parse_tree (op); + info->pass_number = 1; + status = acpi_ps_execute_pass (info); if (ACPI_FAILURE (status)) { - goto cleanup1; /* Walk state is already deleted */ + goto cleanup; } /* - * 2) Execute the method. Performs second pass parse simultaneously + * 2) Execute the method. Performs second pass parse simultaneously */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Execution **** Entry=%p obj=%p\n", - info->node, obj_desc)); + info->node, info->obj_desc)); - /* Create and init a Root Node */ + info->pass_number = 3; + status = acpi_ps_execute_pass (info); - op = acpi_ps_create_scope_op (); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup1; + +cleanup: + if (info->obj_desc->method.owner_id) { + acpi_ut_release_owner_id (&info->obj_desc->method.owner_id); } - /* Init new op with the method name and pointer back to the NS node */ + /* Take away the extra reference that we gave the parameters above */ - acpi_ps_set_name (op, info->node->name.integer); - op->common.node = info->node; + acpi_ps_update_parameter_list (info, REF_DECREMENT); - /* Create and initialize a new walk state */ + /* Exit now if error above */ - walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup2; + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - status = acpi_ds_init_aml_walk (walk_state, op, info->node, - obj_desc->method.aml_start, - obj_desc->method.aml_length, info, 3); - if (ACPI_FAILURE (status)) { - goto cleanup3; + /* + * If the method has returned an object, signal this to the caller with + * a control exception code + */ + if (info->return_object) { + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", + info->return_object)); + ACPI_DUMP_STACK_ENTRY (info->return_object); + + status = AE_CTRL_RETURN_VALUE; } - /* The walk of the parse tree is where we actually execute the method */ + return_ACPI_STATUS (status); +} - status = acpi_ps_parse_aml (walk_state); - goto cleanup2; /* Walk state already deleted */ +/******************************************************************************* + * + * FUNCTION: acpi_ps_update_parameter_list + * + * PARAMETERS: Info - See struct acpi_parameter_info + * (Used: parameter_type and Parameters) + * Action - Add or Remove reference + * + * RETURN: Status + * + * DESCRIPTION: Update reference count on all method parameter objects + * + ******************************************************************************/ -cleanup3: - acpi_ds_delete_walk_state (walk_state); +static void +acpi_ps_update_parameter_list ( + struct acpi_parameter_info *info, + u16 action) +{ + acpi_native_uint i; -cleanup2: - acpi_ps_delete_parse_tree (op); -cleanup1: if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) { - /* Take away the extra reference that we gave the parameters above */ + /* Update reference count for each parameter */ for (i = 0; info->parameters[i]; i++) { /* Ignore errors, just do them all */ - (void) acpi_ut_update_object_reference ( - info->parameters[i], REF_DECREMENT); + (void) acpi_ut_update_object_reference (info->parameters[i], action); } } +} - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + +/******************************************************************************* + * + * FUNCTION: acpi_ps_execute_pass + * + * PARAMETERS: Info - See struct acpi_parameter_info + * (Used: pass_number, Node, and obj_desc) + * + * RETURN: Status + * + * DESCRIPTION: Single AML pass: Parse or Execute a control method + * + ******************************************************************************/ + +static acpi_status +acpi_ps_execute_pass ( + struct acpi_parameter_info *info) +{ + acpi_status status; + union acpi_parse_object *op; + struct acpi_walk_state *walk_state; + + + ACPI_FUNCTION_TRACE ("ps_execute_pass"); + + + /* Create and init a Root Node */ + + op = acpi_ps_create_scope_op (); + if (!op) { + return_ACPI_STATUS (AE_NO_MEMORY); } - /* - * If the method has returned an object, signal this to the caller with - * a control exception code - */ - if (info->return_object) { - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", - info->return_object)); - ACPI_DUMP_STACK_ENTRY (info->return_object); + /* Create and initialize a new walk state */ - status = AE_CTRL_RETURN_VALUE; + walk_state = acpi_ds_create_walk_state ( + info->obj_desc->method.owner_id, NULL, NULL, NULL); + if (!walk_state) { + status = AE_NO_MEMORY; + goto cleanup; + } + + status = acpi_ds_init_aml_walk (walk_state, op, info->node, + info->obj_desc->method.aml_start, + info->obj_desc->method.aml_length, + info->pass_number == 1 ? NULL : info, + info->pass_number); + if (ACPI_FAILURE (status)) { + acpi_ds_delete_walk_state (walk_state); + goto cleanup; } + /* Parse the AML */ + + status = acpi_ps_parse_aml (walk_state); + + /* Walk state was deleted by parse_aml */ + +cleanup: + acpi_ps_delete_parse_tree (op); return_ACPI_STATUS (status); } |