示例#1
0
acpi_status
acpi_ex_system_acquire_mutex (
	union acpi_operand_object       *time_desc,
	union acpi_operand_object       *obj_desc)
{
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc);


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

	/*
	 * Support for the _GL_ Mutex object -- go get the global lock
	 */
	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
		status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
		return_ACPI_STATUS (status);
	}

	status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
			  (u16) time_desc->integer.value);
	return_ACPI_STATUS (status);
}
acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
	acpi_cpu_flags flags;
	acpi_status status;
	u8 acquired = FALSE;

	ACPI_FUNCTION_TRACE(ev_acquire_global_lock);

	status =
	    acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex.
				      os_mutex, timeout);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	acpi_gbl_global_lock_handle++;
	if (acpi_gbl_global_lock_handle == 0) {
		acpi_gbl_global_lock_handle = 1;
	}

	if (!acpi_gbl_global_lock_present) {
		acpi_gbl_global_lock_acquired = TRUE;
		return_ACPI_STATUS(AE_OK);
	}

	flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);

	do {

		

		ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
		if (acquired) {
			acpi_gbl_global_lock_acquired = TRUE;
			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
					  "Acquired hardware Global Lock\n"));
			break;
		}

		acpi_gbl_global_lock_pending = TRUE;
		acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);

		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "Waiting for hardware Global Lock\n"));

		status =
		    acpi_ex_system_wait_semaphore
		    (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);

		flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);

	} while (ACPI_SUCCESS(status));

	acpi_gbl_global_lock_pending = FALSE;
	acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);

	return_ACPI_STATUS(status);
}
示例#3
0
文件: evmisc.c 项目: kzlin129/tt-gpl
acpi_status
acpi_ev_acquire_global_lock (
	u16                             timeout)
{
	acpi_status                     status = AE_OK;
	u8                              acquired = FALSE;


	ACPI_FUNCTION_TRACE ("ev_acquire_global_lock");


#ifndef ACPI_APPLICATION
	/* Make sure that we actually have a global lock */

	if (!acpi_gbl_global_lock_present) {
		return_ACPI_STATUS (AE_NO_GLOBAL_LOCK);
	}
#endif

	/* One more thread wants the global lock */

	acpi_gbl_global_lock_thread_count++;

	/*
	 * If we (OS side vs. BIOS side) have the hardware lock already,
	 * we are done
	 */
	if (acpi_gbl_global_lock_acquired) {
		return_ACPI_STATUS (AE_OK);
	}

	/* We must acquire the actual hardware lock */

	ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired);
	if (acquired) {
	   /* We got the lock */

		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired the HW Global Lock\n"));

		acpi_gbl_global_lock_acquired = TRUE;
		return_ACPI_STATUS (AE_OK);
	}

	/*
	 * Did not get the lock.  The pending bit was set above, and we must now
	 * wait until we get the global lock released interrupt.
	 */
	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n"));

	/*
	 * Acquire the global lock semaphore first.
	 * Since this wait will block, we must release the interpreter
	 */
	status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore,
			  timeout);
	return_ACPI_STATUS (status);
}
示例#4
0
acpi_status
acpi_ds_begin_method_execution (
	struct acpi_namespace_node      *method_node,
	union acpi_operand_object       *obj_desc,
	struct acpi_namespace_node      *calling_method_node)
{
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node);


	if (!method_node) {
		return_ACPI_STATUS (AE_NULL_ENTRY);
	}

	/*
	 * If there is a concurrency limit on this method, we need to
	 * obtain a unit from the method semaphore.
	 */
	if (obj_desc->method.semaphore) {
		/*
		 * Allow recursive method calls, up to the reentrancy/concurrency
		 * limit imposed by the SERIALIZED rule and the sync_level method
		 * parameter.
		 *
		 * The point of this code is to avoid permanently blocking a
		 * thread that is making recursive method calls.
		 */
		if (method_node == calling_method_node) {
			if (obj_desc->method.thread_count >= obj_desc->method.concurrency) {
				return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
			}
		}

		/*
		 * Get a unit from the method semaphore. This releases the
		 * interpreter if we block
		 */
		status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore,
				 ACPI_WAIT_FOREVER);
	}

	/*
	 * Increment the method parse tree thread count since it has been
	 * reentered one more time (even if it is the same thread)
	 */
	obj_desc->method.thread_count++;
	return_ACPI_STATUS (status);
}
示例#5
0
文件: exsystem.c 项目: Anjali05/linux
acpi_status
acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
			  union acpi_operand_object *obj_desc)
{
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE(ex_system_wait_event);

	if (obj_desc) {
		status =
		    acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
						  (u16) time_desc->integer.
						  value);
	}

	return_ACPI_STATUS(status);
}
acpi_status
acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
			       union acpi_operand_object *obj_desc,
			       struct acpi_namespace_node *calling_method_node)
{
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE_PTR("ds_begin_method_execution", method_node);

	if (!method_node) {
		return_ACPI_STATUS(AE_NULL_ENTRY);
	}

	/* Prevent wraparound of thread count */

	if (obj_desc->method.thread_count == ACPI_UINT8_MAX) {
		ACPI_REPORT_ERROR(("Method reached maximum reentrancy limit (255)\n"));
		return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
	}

	/*
	 * If there is a concurrency limit on this method, we need to
	 * obtain a unit from the method semaphore.
	 */
	if (obj_desc->method.semaphore) {
		/*
		 * Allow recursive method calls, up to the reentrancy/concurrency
		 * limit imposed by the SERIALIZED rule and the sync_level method
		 * parameter.
		 *
		 * The point of this code is to avoid permanently blocking a
		 * thread that is making recursive method calls.
		 */
		if (method_node == calling_method_node) {
			if (obj_desc->method.thread_count >=
			    obj_desc->method.concurrency) {
				return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
			}
		}

		/*
		 * Get a unit from the method semaphore. This releases the
		 * interpreter if we block
		 */
		status =
		    acpi_ex_system_wait_semaphore(obj_desc->method.semaphore,
						  ACPI_WAIT_FOREVER);
	}

	/*
	 * Allocate an Owner ID for this method, only if this is the first thread
	 * to begin concurrent execution. We only need one owner_id, even if the
	 * method is invoked recursively.
	 */
	if (!obj_desc->method.owner_id) {
		status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}
	}

	/*
	 * Increment the method parse tree thread count since it has been
	 * reentered one more time (even if it is the same thread)
	 */
	obj_desc->method.thread_count++;
	return_ACPI_STATUS(status);
}
acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
	acpi_cpu_flags flags;
	acpi_status status;
	u8 acquired = FALSE;

	ACPI_FUNCTION_TRACE(ev_acquire_global_lock);

	/*
	 * Only one thread can acquire the GL at a time, the global_lock_mutex
	 * enforces this. This interface releases the interpreter if we must wait.
	 */
	status =
	    acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex.
				      os_mutex, timeout);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Update the global lock handle and check for wraparound. The handle is
	 * only used for the external global lock interfaces, but it is updated
	 * here to properly handle the case where a single thread may acquire the
	 * lock via both the AML and the acpi_acquire_global_lock interfaces. The
	 * handle is therefore updated on the first acquire from a given thread
	 * regardless of where the acquisition request originated.
	 */
	acpi_gbl_global_lock_handle++;
	if (acpi_gbl_global_lock_handle == 0) {
		acpi_gbl_global_lock_handle = 1;
	}

	/*
	 * Make sure that a global lock actually exists. If not, just
	 * treat the lock as a standard mutex.
	 */
	if (!acpi_gbl_global_lock_present) {
		acpi_gbl_global_lock_acquired = TRUE;
		return_ACPI_STATUS(AE_OK);
	}

	flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);

	do {

		/* Attempt to acquire the actual hardware lock */

		ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
		if (acquired) {
			acpi_gbl_global_lock_acquired = TRUE;
			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
					  "Acquired hardware Global Lock\n"));
			break;
		}

		/*
		 * Did not get the lock. The pending bit was set above, and
		 * we must now wait until we receive the global lock
		 * released interrupt.
		 */
		acpi_gbl_global_lock_pending = TRUE;
		acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);

		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "Waiting for hardware Global Lock\n"));

		/*
		 * Wait for handshake with the global lock interrupt handler.
		 * This interface releases the interpreter if we must wait.
		 */
		status =
		    acpi_ex_system_wait_semaphore
		    (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);

		flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);

	} while (ACPI_SUCCESS(status));

	acpi_gbl_global_lock_pending = FALSE;
	acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);

	return_ACPI_STATUS(status);
}
示例#8
0
acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
	acpi_status status = AE_OK;
	u8 acquired = FALSE;

	ACPI_FUNCTION_TRACE(ev_acquire_global_lock);

	/*
	 * Only one thread can acquire the GL at a time, the global_lock_mutex
	 * enforces this. This interface releases the interpreter if we must wait.
	 */
	status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0);
	if (status == AE_TIME) {
		if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
			acpi_ev_global_lock_acquired++;
			return AE_OK;
		}
	}

	if (ACPI_FAILURE(status)) {
		status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
	}
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
	acpi_ev_global_lock_acquired++;

	/*
	 * Make sure that a global lock actually exists. If not, just treat
	 * the lock as a standard mutex.
	 */
	if (!acpi_gbl_global_lock_present) {
		acpi_gbl_global_lock_acquired = TRUE;
		return_ACPI_STATUS(AE_OK);
	}

	/* Attempt to acquire the actual hardware lock */

	ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
	if (acquired) {

		/* We got the lock */

		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "Acquired hardware Global Lock\n"));

		acpi_gbl_global_lock_acquired = TRUE;
		return_ACPI_STATUS(AE_OK);
	}

	/*
	 * Did not get the lock. The pending bit was set above, and we must now
	 * wait until we get the global lock released interrupt.
	 */
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));

	/*
	 * Wait for handshake with the global lock interrupt handler.
	 * This interface releases the interpreter if we must wait.
	 */
	status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
					       ACPI_WAIT_FOREVER);

	return_ACPI_STATUS(status);
}