diff options
-rw-r--r-- | drivers/acpi/dispatcher/dsmethod.c | 52 | ||||
-rw-r--r-- | drivers/acpi/parser/psparse.c | 21 | ||||
-rw-r--r-- | drivers/acpi/parser/psxface.c | 13 | ||||
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 2 | ||||
-rw-r--r-- | include/acpi/acdispat.h | 2 |
5 files changed, 55 insertions, 35 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 8b67a918341e..77fcfc3070db 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -235,16 +235,6 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, | |||
235 | acpi_ex_system_wait_semaphore(obj_desc->method.semaphore, | 235 | acpi_ex_system_wait_semaphore(obj_desc->method.semaphore, |
236 | ACPI_WAIT_FOREVER); | 236 | ACPI_WAIT_FOREVER); |
237 | } | 237 | } |
238 | /* | ||
239 | * allocate owner id for this method | ||
240 | */ | ||
241 | if (!obj_desc->method.thread_count) { | ||
242 | status = acpi_ut_allocate_owner_id (&obj_desc->method.owner_id); | ||
243 | if (ACPI_FAILURE (status)) { | ||
244 | return_ACPI_STATUS (status); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | 238 | ||
249 | /* | 239 | /* |
250 | * Increment the method parse tree thread count since it has been | 240 | * Increment the method parse tree thread count since it has been |
@@ -299,6 +289,11 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
299 | return_ACPI_STATUS(AE_NULL_OBJECT); | 289 | return_ACPI_STATUS(AE_NULL_OBJECT); |
300 | } | 290 | } |
301 | 291 | ||
292 | status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); | ||
293 | if (ACPI_FAILURE(status)) { | ||
294 | return_ACPI_STATUS(status); | ||
295 | } | ||
296 | |||
302 | /* Init for new method, wait on concurrency semaphore */ | 297 | /* Init for new method, wait on concurrency semaphore */ |
303 | 298 | ||
304 | status = acpi_ds_begin_method_execution(method_node, obj_desc, | 299 | status = acpi_ds_begin_method_execution(method_node, obj_desc, |
@@ -385,18 +380,22 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
385 | 380 | ||
386 | if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { | 381 | if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { |
387 | status = obj_desc->method.implementation(next_walk_state); | 382 | status = obj_desc->method.implementation(next_walk_state); |
383 | return_ACPI_STATUS(status); | ||
388 | } | 384 | } |
389 | goto end; | ||
390 | 385 | ||
391 | cleanup: | 386 | return_ACPI_STATUS(AE_OK); |
392 | /* Decrement the thread count on the method parse tree */ | 387 | |
388 | /* On error, we must delete the new walk state */ | ||
389 | |||
390 | cleanup: | ||
391 | acpi_ut_release_owner_id(&obj_desc->method.owner_id); | ||
393 | if (next_walk_state && (next_walk_state->method_desc)) { | 392 | if (next_walk_state && (next_walk_state->method_desc)) { |
393 | /* Decrement the thread count on the method parse tree */ | ||
394 | |||
394 | next_walk_state->method_desc->method.thread_count--; | 395 | next_walk_state->method_desc->method.thread_count--; |
395 | } | 396 | } |
396 | /* On error, we must delete the new walk state */ | 397 | (void)acpi_ds_terminate_control_method(next_walk_state); |
397 | acpi_ds_terminate_control_method (next_walk_state); | 398 | acpi_ds_delete_walk_state(next_walk_state); |
398 | acpi_ds_delete_walk_state (next_walk_state); | ||
399 | end: | ||
400 | return_ACPI_STATUS(status); | 399 | return_ACPI_STATUS(status); |
401 | } | 400 | } |
402 | 401 | ||
@@ -480,7 +479,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, | |||
480 | * | 479 | * |
481 | * PARAMETERS: walk_state - State of the method | 480 | * PARAMETERS: walk_state - State of the method |
482 | * | 481 | * |
483 | * RETURN: None | 482 | * RETURN: Status |
484 | * | 483 | * |
485 | * DESCRIPTION: Terminate a control method. Delete everything that the method | 484 | * DESCRIPTION: Terminate a control method. Delete everything that the method |
486 | * created, delete all locals and arguments, and delete the parse | 485 | * created, delete all locals and arguments, and delete the parse |
@@ -488,7 +487,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, | |||
488 | * | 487 | * |
489 | ******************************************************************************/ | 488 | ******************************************************************************/ |
490 | 489 | ||
491 | void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) | 490 | acpi_status acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) |
492 | { | 491 | { |
493 | union acpi_operand_object *obj_desc; | 492 | union acpi_operand_object *obj_desc; |
494 | struct acpi_namespace_node *method_node; | 493 | struct acpi_namespace_node *method_node; |
@@ -497,14 +496,14 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) | |||
497 | ACPI_FUNCTION_TRACE_PTR("ds_terminate_control_method", walk_state); | 496 | ACPI_FUNCTION_TRACE_PTR("ds_terminate_control_method", walk_state); |
498 | 497 | ||
499 | if (!walk_state) { | 498 | if (!walk_state) { |
500 | return_VOID; | 499 | return (AE_BAD_PARAMETER); |
501 | } | 500 | } |
502 | 501 | ||
503 | /* The current method object was saved in the walk state */ | 502 | /* The current method object was saved in the walk state */ |
504 | 503 | ||
505 | obj_desc = walk_state->method_desc; | 504 | obj_desc = walk_state->method_desc; |
506 | if (!obj_desc) { | 505 | if (!obj_desc) { |
507 | return_VOID; | 506 | return_ACPI_STATUS(AE_OK); |
508 | } | 507 | } |
509 | 508 | ||
510 | /* Delete all arguments and locals */ | 509 | /* Delete all arguments and locals */ |
@@ -518,7 +517,7 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) | |||
518 | */ | 517 | */ |
519 | status = acpi_ut_acquire_mutex(ACPI_MTX_PARSER); | 518 | status = acpi_ut_acquire_mutex(ACPI_MTX_PARSER); |
520 | if (ACPI_FAILURE(status)) { | 519 | if (ACPI_FAILURE(status)) { |
521 | return_VOID; | 520 | return_ACPI_STATUS(status); |
522 | } | 521 | } |
523 | 522 | ||
524 | /* Signal completion of the execution of this method if necessary */ | 523 | /* Signal completion of the execution of this method if necessary */ |
@@ -575,7 +574,7 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) | |||
575 | */ | 574 | */ |
576 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 575 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
577 | if (ACPI_FAILURE(status)) { | 576 | if (ACPI_FAILURE(status)) { |
578 | goto cleanup; | 577 | return_ACPI_STATUS(status); |
579 | } | 578 | } |
580 | 579 | ||
581 | if (method_node->child) { | 580 | if (method_node->child) { |
@@ -593,9 +592,10 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) | |||
593 | owner_id); | 592 | owner_id); |
594 | 593 | ||
595 | if (ACPI_FAILURE(status)) { | 594 | if (ACPI_FAILURE(status)) { |
596 | goto cleanup; | 595 | return_ACPI_STATUS(status); |
597 | } | 596 | } |
598 | } | 597 | } |
599 | cleanup: | 598 | |
600 | acpi_ut_release_mutex (ACPI_MTX_PARSER); | 599 | status = acpi_ut_release_mutex(ACPI_MTX_PARSER); |
600 | return_ACPI_STATUS(status); | ||
601 | } | 601 | } |
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 36771309c62f..3248051d77ee 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -438,6 +438,7 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, | |||
438 | acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | 438 | acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) |
439 | { | 439 | { |
440 | acpi_status status; | 440 | acpi_status status; |
441 | acpi_status terminate_status; | ||
441 | struct acpi_thread_state *thread; | 442 | struct acpi_thread_state *thread; |
442 | struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; | 443 | struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; |
443 | struct acpi_walk_state *previous_walk_state; | 444 | struct acpi_walk_state *previous_walk_state; |
@@ -507,9 +508,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
507 | walk_state->method_node, NULL, | 508 | walk_state->method_node, NULL, |
508 | status); | 509 | status); |
509 | 510 | ||
510 | /* Make sure that failed method will be cleaned as if it was executed */ | ||
511 | walk_state->parse_flags |= ACPI_PARSE_EXECUTE; | ||
512 | |||
513 | /* Check for possible multi-thread reentrancy problem */ | 511 | /* Check for possible multi-thread reentrancy problem */ |
514 | 512 | ||
515 | if ((status == AE_ALREADY_EXISTS) && | 513 | if ((status == AE_ALREADY_EXISTS) && |
@@ -526,6 +524,14 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
526 | } | 524 | } |
527 | } | 525 | } |
528 | 526 | ||
527 | if (walk_state->method_desc) { | ||
528 | /* Decrement the thread count on the method parse tree */ | ||
529 | |||
530 | if (walk_state->method_desc->method.thread_count) { | ||
531 | walk_state->method_desc->method.thread_count--; | ||
532 | } | ||
533 | } | ||
534 | |||
529 | /* We are done with this walk, move on to the parent if any */ | 535 | /* We are done with this walk, move on to the parent if any */ |
530 | 536 | ||
531 | walk_state = acpi_ds_pop_walk_state(thread); | 537 | walk_state = acpi_ds_pop_walk_state(thread); |
@@ -540,10 +546,13 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
540 | */ | 546 | */ |
541 | if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == | 547 | if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == |
542 | ACPI_PARSE_EXECUTE) { | 548 | ACPI_PARSE_EXECUTE) { |
543 | if (walk_state->method_desc) { | 549 | terminate_status = |
544 | walk_state->method_desc->method.thread_count--; | 550 | acpi_ds_terminate_control_method(walk_state); |
551 | if (ACPI_FAILURE(terminate_status)) { | ||
552 | ACPI_REPORT_ERROR(("Could not terminate control method properly\n")); | ||
553 | |||
554 | /* Ignore error and continue */ | ||
545 | } | 555 | } |
546 | acpi_ds_terminate_control_method (walk_state); | ||
547 | } | 556 | } |
548 | 557 | ||
549 | /* Delete this walk state and all linked control states */ | 558 | /* Delete this walk state and all linked control states */ |
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index f6904bdf5739..80c67f2d3dd2 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c | |||
@@ -99,6 +99,16 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * Get a new owner_id for objects created by this method. Namespace | ||
103 | * objects (such as Operation Regions) can be created during the | ||
104 | * first pass parse. | ||
105 | */ | ||
106 | status = acpi_ut_allocate_owner_id(&info->obj_desc->method.owner_id); | ||
107 | if (ACPI_FAILURE(status)) { | ||
108 | return_ACPI_STATUS(status); | ||
109 | } | ||
110 | |||
111 | /* | ||
102 | * The caller "owns" the parameters, so give each one an extra | 112 | * The caller "owns" the parameters, so give each one an extra |
103 | * reference | 113 | * reference |
104 | */ | 114 | */ |
@@ -129,6 +139,9 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
129 | status = acpi_ps_execute_pass(info); | 139 | status = acpi_ps_execute_pass(info); |
130 | 140 | ||
131 | cleanup: | 141 | cleanup: |
142 | if (info->obj_desc->method.owner_id) { | ||
143 | acpi_ut_release_owner_id(&info->obj_desc->method.owner_id); | ||
144 | } | ||
132 | 145 | ||
133 | /* Take away the extra reference that we gave the parameters above */ | 146 | /* Take away the extra reference that we gave the parameters above */ |
134 | 147 | ||
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index c2f5b2adb5d6..f0275025b718 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -67,8 +67,6 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) | |||
67 | 67 | ||
68 | ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); | 68 | ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); |
69 | 69 | ||
70 | WARN_ON(*owner_id); | ||
71 | |||
72 | /* Mutex for the global ID mask */ | 70 | /* Mutex for the global ID mask */ |
73 | 71 | ||
74 | status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); | 72 | status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); |
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h index c436e8be6ba8..59306186f5e2 100644 --- a/include/acpi/acdispat.h +++ b/include/acpi/acdispat.h | |||
@@ -194,7 +194,7 @@ acpi_status | |||
194 | acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, | 194 | acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, |
195 | union acpi_operand_object *return_desc); | 195 | union acpi_operand_object *return_desc); |
196 | 196 | ||
197 | void | 197 | acpi_status |
198 | acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state); | 198 | acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state); |
199 | 199 | ||
200 | acpi_status | 200 | acpi_status |