void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) { union acpi_operand_object *next = thread->acquired_mutex_list; union acpi_operand_object *this; acpi_status status; ACPI_FUNCTION_ENTRY(); /* Traverse the list of owned mutexes, releasing each one */ while (next) { this = next; next = this->mutex.next; this->mutex.acquisition_depth = 1; this->mutex.prev = NULL; this->mutex.next = NULL; /* Release the mutex */ status = acpi_ex_system_release_mutex(this); if (ACPI_FAILURE(status)) { continue; } /* Mark mutex unowned */ this->mutex.owner_thread = NULL; /* Update Thread sync_level (Last mutex is the important one) */ thread->current_sync_level = this->mutex.original_sync_level; } }
acpi_status acpi_ex_release_all_mutexes ( acpi_operand_object *list_head) { acpi_operand_object *next = list_head->mutex.next; acpi_operand_object *this; FUNCTION_ENTRY (); /* * Traverse the list of owned mutexes, releasing each one. */ while (next) { this = next; next = this->mutex.next; /* Mark mutex un-owned */ this->mutex.owner = NULL; this->mutex.prev = NULL; this->mutex.next = NULL; this->mutex.acquisition_depth = 0; /* Release the mutex */ acpi_ex_system_release_mutex (this); } return (AE_OK); }
acpi_status acpi_ex_release_mutex(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { acpi_status status; ACPI_FUNCTION_TRACE(ex_release_mutex); if (!obj_desc) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* The mutex must have been previously acquired in order to release it */ if (!obj_desc->mutex.owner_thread) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], not acquired", acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); } /* Sanity check -- we must have a valid thread ID */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], null thread info", acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_INTERNAL); } /* * The Mutex is owned, but this thread must be the owner. * Special case for Global Lock, any thread can release */ if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { ACPI_ERROR((AE_INFO, "Thread %X cannot release Mutex [%4.4s] acquired by thread %X", (u32)(long) walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), (u32)(long) obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS(AE_AML_NOT_OWNER); } /* * The sync level of the mutex must be less than or * equal to the current sync level */ if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], incorrect SyncLevel", acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_MUTEX_ORDER); } /* Match multiple Acquires with multiple Releases */ obj_desc->mutex.acquisition_depth--; if (obj_desc->mutex.acquisition_depth != 0) { /* Just decrement the depth and return */ return_ACPI_STATUS(AE_OK); } /* Unlink the mutex from the owner's list */ acpi_ex_unlink_mutex(obj_desc); /* Release the mutex */ status = acpi_ex_system_release_mutex(obj_desc); /* Update the mutex and walk state, restore sync_level before acquire */ obj_desc->mutex.owner_thread = NULL; walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level; return_ACPI_STATUS(status); }
acpi_status acpi_ex_release_mutex ( acpi_operand_object *obj_desc, acpi_walk_state *walk_state) { acpi_status status; FUNCTION_TRACE ("Ex_release_mutex"); if (!obj_desc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* The mutex must have been previously acquired in order to release it */ if (!obj_desc->mutex.owner) { return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED); } /* The Mutex is owned, but this thread must be the owner */ if (obj_desc->mutex.owner != walk_state) { return_ACPI_STATUS (AE_AML_NOT_OWNER); } /* * The sync level of the mutex must be less than or * equal to the current sync level */ if (obj_desc->mutex.sync_level > walk_state->current_sync_level) { return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } /* * Match multiple Acquires with multiple Releases */ obj_desc->mutex.acquisition_depth--; if (obj_desc->mutex.acquisition_depth != 0) { /* Just decrement the depth and return */ return_ACPI_STATUS (AE_OK); } /* Release the mutex */ status = acpi_ex_system_release_mutex (obj_desc); /* Update the mutex and walk state */ obj_desc->mutex.owner = NULL; walk_state->current_sync_level = obj_desc->mutex.sync_level; /* Unlink the mutex from the owner's list */ acpi_ex_unlink_mutex (obj_desc); return_ACPI_STATUS (status); }