evmisc.c
来自「linux 内核源代码」· C语言 代码 · 共 630 行 · 第 1/2 页
C
630 行
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);}/******************************************************************************* * * FUNCTION: acpi_ev_init_global_lock_handler * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Install a handler for the global lock release event * ******************************************************************************/acpi_status acpi_ev_init_global_lock_handler(void){ acpi_status status; ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, (struct acpi_table_header **)&facs); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } acpi_gbl_global_lock_present = TRUE; status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, acpi_ev_global_lock_handler, NULL); /* * If the global lock does not exist on this platform, the attempt * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick) * Map to AE_OK, but mark global lock as not present. * Any attempt to actually use the global lock will be flagged * with an error. */ if (status == AE_NO_HARDWARE_RESPONSE) { ACPI_ERROR((AE_INFO, "No response from Global Lock hardware, disabling lock")); acpi_gbl_global_lock_present = FALSE; status = AE_OK; } return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION: acpi_ev_remove_global_lock_handler * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Remove the handler for the Global Lock * ******************************************************************************/static acpi_status acpi_ev_remove_global_lock_handler(void){ acpi_status status; ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); acpi_gbl_global_lock_present = FALSE; status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, acpi_ev_global_lock_handler); return_ACPI_STATUS(status);}/****************************************************************************** * * FUNCTION: acpi_ev_acquire_global_lock * * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. * * RETURN: Status * * DESCRIPTION: Attempt to gain ownership of the Global Lock. * * MUTEX: Interpreter must be locked * * Note: The original implementation allowed multiple threads to "acquire" the * Global Lock, and the OS would hold the lock until the last thread had * released it. However, this could potentially starve the BIOS out of the * lock, especially in the case where there is a tight handshake between the * Embedded Controller driver and the BIOS. Therefore, this implementation * allows only one thread to acquire the HW Global Lock at a time, and makes * the global lock appear as a standard mutex on the OS side. * *****************************************************************************/static acpi_thread_id acpi_ev_global_lock_thread_id;static int acpi_ev_global_lock_acquired;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);}/******************************************************************************* * * FUNCTION: acpi_ev_release_global_lock * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Releases ownership of the Global Lock. * ******************************************************************************/acpi_status acpi_ev_release_global_lock(void){ u8 pending = FALSE; acpi_status status = AE_OK; ACPI_FUNCTION_TRACE(ev_release_global_lock); /* Lock must be already acquired */ if (!acpi_gbl_global_lock_acquired) { ACPI_WARNING((AE_INFO, "Cannot release the ACPI Global Lock, it has not been acquired")); return_ACPI_STATUS(AE_NOT_ACQUIRED); } acpi_ev_global_lock_acquired--; if (acpi_ev_global_lock_acquired > 0) { return AE_OK; } if (acpi_gbl_global_lock_present) { /* Allow any thread to release the lock */ ACPI_RELEASE_GLOBAL_LOCK(facs, pending); /* * If the pending bit was set, we must write GBL_RLS to the control * register */ if (pending) { status = acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, 1); } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Released hardware Global Lock\n")); } acpi_gbl_global_lock_acquired = FALSE; /* Release the local GL mutex */ acpi_ev_global_lock_thread_id = NULL; acpi_ev_global_lock_acquired = 0; acpi_os_release_mutex(acpi_gbl_global_lock_mutex); return_ACPI_STATUS(status);}/****************************************************************************** * * FUNCTION: acpi_ev_terminate * * PARAMETERS: none * * RETURN: none * * DESCRIPTION: Disable events and free memory allocated for table storage. * ******************************************************************************/void acpi_ev_terminate(void){ acpi_native_uint i; acpi_status status; ACPI_FUNCTION_TRACE(ev_terminate); if (acpi_gbl_events_initialized) { /* * Disable all event-related functionality. * In all cases, on error, print a message but obviously we don't abort. */ /* Disable all fixed events */ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { status = acpi_disable_event((u32) i, 0); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not disable fixed event %d", (u32) i)); } } /* Disable all GPEs in all GPE blocks */ status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block); /* Remove SCI handler */ status = acpi_ev_remove_sci_handler(); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); } status = acpi_ev_remove_global_lock_handler(); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not remove Global Lock handler")); } } /* Deallocate all handler objects installed within GPE info structs */ status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers); /* Return to original mode if necessary */ if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) { status = acpi_disable(); if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, "AcpiDisable failed")); } } return_VOID;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?