Ejemplo n.º 1
0
static u32 acpi_ev_global_lock_handler(void *context)
{
	acpi_status status;
	acpi_cpu_flags flags;

	flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);

	/*
	 * If a request for the global lock is not actually pending,
	 * we are done. This handles "spurious" global lock interrupts
	 * which are possible (and have been seen) with bad BIOSs.
	 */
	if (!acpi_gbl_global_lock_pending) {
		goto cleanup_and_exit;
	}

	/*
	 * Send a unit to the global lock semaphore. The actual acquisition
	 * of the global lock will be performed by the waiting thread.
	 */
	status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
	if (ACPI_FAILURE(status)) {
		ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
	}

	acpi_gbl_global_lock_pending = FALSE;

      cleanup_and_exit:

	acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
	return (ACPI_INTERRUPT_HANDLED);
}
Ejemplo n.º 2
0
static u32 acpi_ev_global_lock_handler(void *context)
{
	u8 acquired = FALSE;

	/*
	 * Attempt to get the lock.
	 *
	 * If we don't get it now, it will be marked pending and we will
	 * take another interrupt when it becomes free.
	 */
	ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
	if (acquired) {

		/* Got the lock, now wake all threads waiting for it */

		acpi_gbl_global_lock_acquired = TRUE;
		/* Send a unit to the semaphore */

		if (ACPI_FAILURE
		    (acpi_os_signal_semaphore
		     (acpi_gbl_global_lock_semaphore, 1))) {
			ACPI_ERROR((AE_INFO,
				    "Could not signal Global Lock semaphore"));
		}
	}

	return (ACPI_INTERRUPT_HANDLED);
}
Ejemplo n.º 3
0
acpi_status
acpi_ex_system_release_mutex (
	union acpi_operand_object       *obj_desc)
{
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("ex_system_release_mutex");


	if (!obj_desc) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/*
	 * Support for the _GL_ Mutex object -- release the global lock
	 */
	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
		status = acpi_ev_release_global_lock ();
		return_ACPI_STATUS (status);
	}

	status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
	return_ACPI_STATUS (status);
}
Ejemplo n.º 4
0
static u32 acpi_ev_global_lock_handler(void *context)
{
	acpi_status status;
	acpi_cpu_flags flags;

	flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);

	if (!acpi_ev_global_lock_pending) {
		goto out;
	}

	/* Send a unit to the semaphore */

	status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
	if (ACPI_FAILURE(status)) {
		ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
	}

	acpi_ev_global_lock_pending = FALSE;

 out:
	acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);

	return (ACPI_INTERRUPT_HANDLED);
}
Ejemplo n.º 5
0
void
acpi_db_method_thread (
	void                    *context)
{
	acpi_status             status;
	db_method_info          *info = context;
	u32                     i;
	acpi_buffer             return_obj;


	for (i = 0; i < info->num_loops; i++) {
		status = acpi_db_execute_method (info, &return_obj);
		if (ACPI_SUCCESS (status)) {
			if (return_obj.length) {
				acpi_os_printf ("Execution of %s returned object %p Buflen %X\n",
					info->pathname, return_obj.pointer, return_obj.length);
				acpi_db_dump_object (return_obj.pointer, 1);
			}
		}
	}

	/* Signal our completion */

	acpi_os_signal_semaphore (info->thread_gate, 1);
}
Ejemplo n.º 6
0
acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
{
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE(ex_system_signal_event);

	if (obj_desc) {
		status =
		    acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
	}

	return_ACPI_STATUS(status);
}
Ejemplo n.º 7
0
static void ACPI_SYSTEM_XFACE
acpi_ev_global_lock_thread (
	void                            *context)
{
	acpi_status                     status;


	/* Signal threads that are waiting for the lock */

	if (acpi_gbl_global_lock_thread_count) {
		/* Send sufficient units to the semaphore */

		status = acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore,
				 acpi_gbl_global_lock_thread_count);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("Could not signal Global Lock semaphore\n"));
		}
	}
}
Ejemplo n.º 8
0
ACPI_STATUS
acpi_cm_release_mutex (
	ACPI_MUTEX_HANDLE       mutex_id)
{
	ACPI_STATUS             status;


	if (mutex_id > MAX_MTX) {
		return (AE_BAD_PARAMETER);
	}


	acpi_gbl_acpi_mutex_info[mutex_id].locked = FALSE; /* Mark before unlocking */

	status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);


	return (status);
}
Ejemplo n.º 9
0
void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state)
{
	union acpi_operand_object *obj_desc;
	struct acpi_namespace_node *method_node;
	acpi_status status;

	ACPI_FUNCTION_TRACE_PTR("ds_terminate_control_method", walk_state);

	if (!walk_state) {
		return_VOID;
	}

	/* The current method object was saved in the walk state */

	obj_desc = walk_state->method_desc;
	if (!obj_desc) {
		return_VOID;
	}

	/* Delete all arguments and locals */

	acpi_ds_method_data_delete_all(walk_state);

	/*
	 * Lock the parser while we terminate this method.
	 * If this is the last thread executing the method,
	 * we have additional cleanup to perform
	 */
	status = acpi_ut_acquire_mutex(ACPI_MTX_PARSER);
	if (ACPI_FAILURE(status)) {
		return_VOID;
	}

	/* Signal completion of the execution of this method if necessary */

	if (walk_state->method_desc->method.semaphore) {
		status =
		    acpi_os_signal_semaphore(walk_state->method_desc->method.
					     semaphore, 1);
		if (ACPI_FAILURE(status)) {
			ACPI_REPORT_ERROR(("Could not signal method semaphore\n"));

			/* Ignore error and continue cleanup */
		}
	}

	if (walk_state->method_desc->method.thread_count) {
		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
				  "*** Not deleting method namespace, there are still %d threads\n",
				  walk_state->method_desc->method.
				  thread_count));
	} else {		/* This is the last executing thread */

		/*
		 * Support to dynamically change a method from not_serialized to
		 * Serialized if it appears that the method is written foolishly and
		 * does not support multiple thread execution.  The best example of this
		 * is if such a method creates namespace objects and blocks.  A second
		 * thread will fail with an AE_ALREADY_EXISTS exception
		 *
		 * This code is here because we must wait until the last thread exits
		 * before creating the synchronization semaphore.
		 */
		if ((walk_state->method_desc->method.concurrency == 1) &&
		    (!walk_state->method_desc->method.semaphore)) {
			status = acpi_os_create_semaphore(1, 1,
							  &walk_state->
							  method_desc->method.
							  semaphore);
		}

		/*
		 * There are no more threads executing this method.  Perform
		 * additional cleanup.
		 *
		 * The method Node is stored in the walk state
		 */
		method_node = walk_state->method_node;

		/*
		 * Delete any namespace entries created immediately underneath
		 * the method
		 */
		status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
		if (ACPI_FAILURE(status)) {
			goto exit;
		}

		if (method_node->child) {
			acpi_ns_delete_namespace_subtree(method_node);
		}

		/*
		 * Delete any namespace entries created anywhere else within
		 * the namespace
		 */
		acpi_ns_delete_namespace_by_owner(walk_state->method_desc->
						  method.owner_id);
		status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
		acpi_ut_release_owner_id(&walk_state->method_desc->method.
					 owner_id);
	}

      exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_PARSER);
	return_VOID;
}
Ejemplo n.º 10
0
void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags)
{
	acpi_os_signal_semaphore(handle, 1);
}
Ejemplo n.º 11
0
acpi_status
acpi_ut_release_mutex (
	acpi_mutex_handle               mutex_id)
{
	acpi_status                     status;
	u32                             i;
	u32                             this_thread_id;


	ACPI_FUNCTION_NAME ("ut_release_mutex");


	this_thread_id = acpi_os_get_thread_id ();
	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
		"Thread %X releasing Mutex [%s]\n", this_thread_id,
		acpi_ut_get_mutex_name (mutex_id)));

	if (mutex_id > MAX_MUTEX) {
		return (AE_BAD_PARAMETER);
	}

	/*
	 * Mutex must be acquired in order to release it!
	 */
	if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Mutex [%s] is not acquired, cannot release\n",
			acpi_ut_get_mutex_name (mutex_id)));

		return (AE_NOT_ACQUIRED);
	}

	/*
	 * Deadlock prevention.  Check if this thread owns any mutexes of value
	 * greater than this one.  If so, the thread has violated the mutex
	 * ordering rule.  This indicates a coding error somewhere in
	 * the ACPI subsystem code.
	 */
	for (i = mutex_id; i < MAX_MUTEX; i++) {
		if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
			if (i == mutex_id) {
				continue;
			}

			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Invalid release order: owns [%s], releasing [%s]\n",
				acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));

			return (AE_RELEASE_DEADLOCK);
		}
	}

	/* Mark unlocked FIRST */

	acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;

	status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);

	if (ACPI_FAILURE (status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Thread %X could not release Mutex [%s] %s\n",
			this_thread_id, acpi_ut_get_mutex_name (mutex_id),
			acpi_format_exception (status)));
	}
	else {
		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
			this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
	}

	return (status);
}
Ejemplo n.º 12
0
ACPI_STATUS
acpi_ds_terminate_control_method (
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_STATUS             status;
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_NAMESPACE_NODE     *method_node;


	/* The method object should be stored in the walk state */

	obj_desc = walk_state->method_desc;
	if (!obj_desc) {
		return (AE_OK);
	}

	/* Delete all arguments and locals */

	acpi_ds_method_data_delete_all (walk_state);

	/*
	 * Lock the parser while we terminate this method.
	 * If this is the last thread executing the method,
	 * we have additional cleanup to perform
	 */

	acpi_cm_acquire_mutex (ACPI_MTX_PARSER);


	/* Signal completion of the execution of this method if necessary */

	if (walk_state->method_desc->method.semaphore) {
		status = acpi_os_signal_semaphore (
				 walk_state->method_desc->method.semaphore, 1);
	}

	/* Decrement the thread count on the method parse tree */

	walk_state->method_desc->method.thread_count--;
	if (!walk_state->method_desc->method.thread_count) {
		/*
		 * There are no more threads executing this method.  Perform
		 * additional cleanup.
		 *
		 * The method Node is stored in the walk state
		 */
		method_node = walk_state->method_node;
		/*
		 * Delete any namespace entries created immediately underneath
		 * the method
		 */
		acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
		if (method_node->child) {
			acpi_ns_delete_namespace_subtree (method_node);
		}

		/*
		 * Delete any namespace entries created anywhere else within
		 * the namespace
		 */
		acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
	}

	acpi_cm_release_mutex (ACPI_MTX_PARSER);
	return (AE_OK);
}