From e53a2bded315218caf11754e09b075501df4d17a Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:04:33 +0800 Subject: [PATCH] --- yaml --- r: 151004 b: refs/heads/master c: 315c728887f198d12eb6ec7ef9d88483018c11cb h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/acpi/acpica/exmutex.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index fa278cd6ce03..5919101d5db9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 10a3b461a258f52b17fb8e35edf3625726eca9a8 +refs/heads/master: 315c728887f198d12eb6ec7ef9d88483018c11cb diff --git a/trunk/drivers/acpi/acpica/exmutex.c b/trunk/drivers/acpi/acpica/exmutex.c index 77a592aa53c0..2f0114202b05 100644 --- a/trunk/drivers/acpi/acpica/exmutex.c +++ b/trunk/drivers/acpi/acpica/exmutex.c @@ -402,10 +402,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, } /* - * The sync level of the mutex must be less than or equal to the current - * sync level + * The sync level of the mutex must be equal to the current sync level. In + * other words, the current level means that at least one mutex at that + * level is currently being held. Attempting to release a mutex of a + * different level can only mean that the mutex ordering rule is being + * violated. This behavior is clarified in ACPI 4.0 specification. */ - if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { + if (obj_desc->mutex.sync_level != + walk_state->thread->current_sync_level) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", acpi_ut_get_node_name(obj_desc->mutex.node), @@ -423,10 +427,13 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, walk_state->thread->acquired_mutex_list->mutex.original_sync_level; status = acpi_ex_release_mutex_object(obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } if (obj_desc->mutex.acquisition_depth == 0) { - /* Restore the original sync_level */ + /* Restore the previous sync_level */ walk_state->thread->current_sync_level = previous_sync_level; }