diff options
Diffstat (limited to 'drivers/acpi/parser/psparse.c')
-rw-r--r-- | drivers/acpi/parser/psparse.c | 35 |
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, |