Index: 2.6.13-acpica/drivers/acpi/dispatcher/dsmethod.c =================================================================== --- 2.6.13-acpica.orig/drivers/acpi/dispatcher/dsmethod.c 2005-09-02 17:49:00.000000000 -0400 +++ 2.6.13-acpica/drivers/acpi/dispatcher/dsmethod.c 2005-09-02 17:51:43.000000000 -0400 @@ -243,15 +243,6 @@ acpi_ds_begin_method_execution ( status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore, ACPI_WAIT_FOREVER); } - /* - * allocate owner id for this method - */ - if (!obj_desc->method.thread_count) { - status = acpi_ut_allocate_owner_id (&obj_desc->method.owner_id); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - } /* * Increment the method parse tree thread count since it has been @@ -308,6 +299,11 @@ acpi_ds_call_control_method ( return_ACPI_STATUS (AE_NULL_OBJECT); } + status = acpi_ut_allocate_owner_id (&obj_desc->method.owner_id); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* Init for new method, wait on concurrency semaphore */ status = acpi_ds_begin_method_execution (method_node, obj_desc, @@ -391,17 +387,23 @@ acpi_ds_call_control_method ( if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { status = obj_desc->method.implementation (next_walk_state); + return_ACPI_STATUS (status); } - goto end; + + return_ACPI_STATUS (AE_OK); + + + /* On error, we must delete the new walk state */ + cleanup: - /* Decrement the thread count on the method parse tree */ + acpi_ut_release_owner_id (&obj_desc->method.owner_id); if (next_walk_state && (next_walk_state->method_desc)) { - next_walk_state->method_desc->method.thread_count--; + /* Decrement the thread count on the method parse tree */ + + next_walk_state->method_desc->method.thread_count--; } - /* On error, we must delete the new walk state */ - acpi_ds_terminate_control_method (next_walk_state); + (void) acpi_ds_terminate_control_method (next_walk_state); acpi_ds_delete_walk_state (next_walk_state); -end: return_ACPI_STATUS (status); } @@ -489,7 +491,7 @@ acpi_ds_restart_control_method ( * * PARAMETERS: walk_state - State of the method * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Terminate a control method. Delete everything that the method * created, delete all locals and arguments, and delete the parse @@ -497,7 +499,7 @@ acpi_ds_restart_control_method ( * ******************************************************************************/ -void +acpi_status acpi_ds_terminate_control_method ( struct acpi_walk_state *walk_state) { @@ -510,14 +512,14 @@ acpi_ds_terminate_control_method ( if (!walk_state) { - return_VOID; + return (AE_BAD_PARAMETER); } /* The current method object was saved in the walk state */ obj_desc = walk_state->method_desc; if (!obj_desc) { - return_VOID; + return_ACPI_STATUS (AE_OK); } /* Delete all arguments and locals */ @@ -531,7 +533,7 @@ acpi_ds_terminate_control_method ( */ status = acpi_ut_acquire_mutex (ACPI_MTX_PARSER); if (ACPI_FAILURE (status)) { - return_VOID; + return_ACPI_STATUS (status); } /* Signal completion of the execution of this method if necessary */ @@ -584,7 +586,7 @@ acpi_ds_terminate_control_method ( */ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - goto cleanup; + return_ACPI_STATUS (status); } if (method_node->child) { @@ -600,11 +602,12 @@ acpi_ds_terminate_control_method ( acpi_ut_release_owner_id (&walk_state->method_desc->method.owner_id); if (ACPI_FAILURE (status)) { - goto cleanup; + return_ACPI_STATUS (status); } } -cleanup: - acpi_ut_release_mutex (ACPI_MTX_PARSER); + + status = acpi_ut_release_mutex (ACPI_MTX_PARSER); + return_ACPI_STATUS (status); } Index: 2.6.13-acpica/drivers/acpi/parser/psparse.c =================================================================== --- 2.6.13-acpica.orig/drivers/acpi/parser/psparse.c 2005-09-02 17:49:00.000000000 -0400 +++ 2.6.13-acpica/drivers/acpi/parser/psparse.c 2005-09-02 17:51:43.000000000 -0400 @@ -437,6 +437,7 @@ acpi_ps_parse_aml ( struct acpi_walk_state *walk_state) { acpi_status status; + acpi_status terminate_status; struct acpi_thread_state *thread; struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; struct acpi_walk_state *previous_walk_state; @@ -506,10 +507,7 @@ acpi_ps_parse_aml ( else if ((status != AE_OK) && (walk_state->method_desc)) { ACPI_REPORT_METHOD_ERROR ("Method execution failed", walk_state->method_node, NULL, status); - - /* Make sure that failed method will be cleaned as if it was executed */ - walk_state->parse_flags |= ACPI_PARSE_EXECUTE; - + /* Check for possible multi-thread reentrancy problem */ if ((status == AE_ALREADY_EXISTS) && @@ -525,6 +523,14 @@ acpi_ps_parse_aml ( } } + if (walk_state->method_desc) { + /* Decrement the thread count on the method parse tree */ + + if (walk_state->method_desc->method.thread_count) { + walk_state->method_desc->method.thread_count--; + } + } + /* We are done with this walk, move on to the parent if any */ walk_state = acpi_ds_pop_walk_state (thread); @@ -538,11 +544,13 @@ acpi_ps_parse_aml ( * there's lots of cleanup to do */ if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { - /* Decrement the thread count on the method parse tree */ - if (walk_state->method_desc) { - walk_state->method_desc->method.thread_count--; + terminate_status = acpi_ds_terminate_control_method (walk_state); + if (ACPI_FAILURE (terminate_status)) { + ACPI_REPORT_ERROR (( + "Could not terminate control method properly\n")); + + /* Ignore error and continue */ } - acpi_ds_terminate_control_method (walk_state); } /* Delete this walk state and all linked control states */ Index: 2.6.13-acpica/drivers/acpi/parser/psxface.c =================================================================== --- 2.6.13-acpica.orig/drivers/acpi/parser/psxface.c 2005-09-02 17:49:00.000000000 -0400 +++ 2.6.13-acpica/drivers/acpi/parser/psxface.c 2005-09-02 17:51:43.000000000 -0400 @@ -110,6 +110,16 @@ acpi_ps_execute_method ( } /* + * 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 (&info->obj_desc->method.owner_id); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* * The caller "owns" the parameters, so give each one an extra * reference */ @@ -141,6 +151,10 @@ acpi_ps_execute_method ( cleanup: + if (info->obj_desc->method.owner_id) { + acpi_ut_release_owner_id (&info->obj_desc->method.owner_id); + } + /* Take away the extra reference that we gave the parameters above */ acpi_ps_update_parameter_list (info, REF_DECREMENT); Index: 2.6.13-acpica/drivers/acpi/utilities/utmisc.c =================================================================== --- 2.6.13-acpica.orig/drivers/acpi/utilities/utmisc.c 2005-09-02 17:51:11.000000000 -0400 +++ 2.6.13-acpica/drivers/acpi/utilities/utmisc.c 2005-09-02 17:51:43.000000000 -0400 @@ -74,8 +74,7 @@ acpi_ut_allocate_owner_id ( ACPI_FUNCTION_TRACE ("ut_allocate_owner_id"); - WARN_ON(*owner_id); - + /* Mutex for the global ID mask */ status = acpi_ut_acquire_mutex (ACPI_MTX_CACHES); Index: 2.6.13-acpica/include/acpi/acdispat.h =================================================================== --- 2.6.13-acpica.orig/include/acpi/acdispat.h 2005-09-02 17:49:00.000000000 -0400 +++ 2.6.13-acpica/include/acpi/acdispat.h 2005-09-02 17:51:43.000000000 -0400 @@ -249,7 +249,7 @@ acpi_ds_restart_control_method ( struct acpi_walk_state *walk_state, union acpi_operand_object *return_desc); -void +acpi_status acpi_ds_terminate_control_method ( struct acpi_walk_state *walk_state);