aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser/psparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/parser/psparse.c')
-rw-r--r--drivers/acpi/parser/psparse.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index 76d4d640d83c..7cfa7eb0dfc7 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -503,22 +503,23 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
503 } else if (status == AE_CTRL_TERMINATE) { 503 } else if (status == AE_CTRL_TERMINATE) {
504 status = AE_OK; 504 status = AE_OK;
505 } else if ((status != AE_OK) && (walk_state->method_desc)) { 505 } else if ((status != AE_OK) && (walk_state->method_desc)) {
506 ACPI_REPORT_METHOD_ERROR("Method execution failed", 506 /* Either the method parse or actual execution failed */
507 walk_state->method_node, NULL,
508 status);
509 507
510 /* Ensure proper cleanup */ 508 ACPI_REPORT_METHOD_ERROR
511 509 ("Method parse/execution failed",
512 walk_state->parse_flags |= ACPI_PARSE_EXECUTE; 510 walk_state->method_node, NULL, status);
513 511
514 /* Check for possible multi-thread reentrancy problem */ 512 /* Check for possible multi-thread reentrancy problem */
515 513
516 if ((status == AE_ALREADY_EXISTS) && 514 if ((status == AE_ALREADY_EXISTS) &&
517 (!walk_state->method_desc->method.semaphore)) { 515 (!walk_state->method_desc->method.semaphore)) {
518 /* 516 /*
519 * This method is marked not_serialized, but it tried to create 517 * Method tried to create an object twice. The probable cause is
518 * that the method cannot handle reentrancy.
519 *
520 * The method is marked not_serialized, but it tried to create
520 * a named object, causing the second thread entrance to fail. 521 * a named object, causing the second thread entrance to fail.
521 * We will workaround this by marking the method permanently 522 * Workaround this problem by marking the method permanently
522 * as Serialized. 523 * as Serialized.
523 */ 524 */
524 walk_state->method_desc->method.method_flags |= 525 walk_state->method_desc->method.method_flags |=
@@ -536,15 +537,22 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
536 acpi_ds_scope_stack_clear(walk_state); 537 acpi_ds_scope_stack_clear(walk_state);
537 538
538 /* 539 /*
539 * If we just returned from the execution of a control method, 540 * If we just returned from the execution of a control method or if we
540 * there's lots of cleanup to do 541 * encountered an error during the method parse phase, there's lots of
542 * cleanup to do
541 */ 543 */
542 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == 544 if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
543 ACPI_PARSE_EXECUTE) { 545 ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) {
544 if (walk_state->method_desc) { 546 if (walk_state->method_desc) {
545 /* Decrement the thread count on the method parse tree */ 547 /* Decrement the thread count on the method parse tree */
546 548
547 walk_state->method_desc->method.thread_count--; 549 if (walk_state->method_desc->method.
550 thread_count) {
551 walk_state->method_desc->method.
552 thread_count--;
553 } else {
554 ACPI_REPORT_ERROR(("Invalid zero thread count in method\n"));
555 }
548 } 556 }
549 557
550 acpi_ds_terminate_control_method(walk_state); 558 acpi_ds_terminate_control_method(walk_state);
@@ -553,7 +561,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
553 /* Delete this walk state and all linked control states */ 561 /* Delete this walk state and all linked control states */
554 562
555 acpi_ps_cleanup_scope(&walk_state->parser_state); 563 acpi_ps_cleanup_scope(&walk_state->parser_state);
556
557 previous_walk_state = walk_state; 564 previous_walk_state = walk_state;
558 565
559 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 566 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,