From 3ea49259dfe6cf2b58b676b49a890cfc49157d05 Mon Sep 17 00:00:00 2001 From: Liav A Date: Sat, 13 Nov 2021 13:07:55 +0200 Subject: [PATCH] Kernel/Storage: Don't use interrupts when resetting SATA AHCI devices Don't use interrupts when trying to reset a device that is connected to a port on the AHCI controller, and instead poll for changes in status to break out from the loop. At the worst case scenario we can wait 0.01 seconds for each SATA reset. --- Kernel/Storage/ATA/AHCIPort.cpp | 30 +++++++++++------------------- Kernel/Storage/ATA/AHCIPort.h | 2 +- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/Kernel/Storage/ATA/AHCIPort.cpp b/Kernel/Storage/ATA/AHCIPort.cpp index ee762254b2..7e8ddca756 100644 --- a/Kernel/Storage/ATA/AHCIPort.cpp +++ b/Kernel/Storage/ATA/AHCIPort.cpp @@ -250,7 +250,7 @@ bool AHCIPort::reset() full_memory_barrier(); clear_sata_error_register(); full_memory_barrier(); - if (!initiate_sata_reset(lock)) { + if (!initiate_sata_reset()) { return false; } return initialize(); @@ -780,7 +780,7 @@ void AHCIPort::stop_fis_receiving() const m_port_registers.cmd = m_port_registers.cmd & 0xFFFFFFEF; } -bool AHCIPort::initiate_sata_reset(SpinlockLocker& main_lock) +bool AHCIPort::initiate_sata_reset() { VERIFY(m_lock.is_locked()); VERIFY(m_hard_lock.is_locked()); @@ -802,24 +802,16 @@ bool AHCIPort::initiate_sata_reset(SpinlockLocker& main_lock) set_interface_state(AHCI::DeviceDetectionInitialization::PerformInterfaceInitializationSequence); // The AHCI specification says to wait now a 1 millisecond IO::delay(1000); - // FIXME: Find a better way to opt-out temporarily from Scoped locking! - { - main_lock.unlock(); - VERIFY_INTERRUPTS_ENABLED(); - full_memory_barrier(); - set_interface_state(AHCI::DeviceDetectionInitialization::NoActionRequested); - full_memory_barrier(); - if (m_wait_connect_for_completion) { - retry = 0; - while (retry < 100000) { - if (is_phy_enabled()) - break; + full_memory_barrier(); + set_interface_state(AHCI::DeviceDetectionInitialization::NoActionRequested); + full_memory_barrier(); + retry = 0; + while (retry < 1000) { + if (is_phy_enabled()) + break; - IO::delay(10); - retry++; - } - } - main_lock.lock(); + IO::delay(10); + retry++; } dmesgln("AHCI Port {}: {}", representative_port_index(), try_disambiguate_sata_status()); diff --git a/Kernel/Storage/ATA/AHCIPort.h b/Kernel/Storage/ATA/AHCIPort.h index d360703752..669d36f27a 100644 --- a/Kernel/Storage/ATA/AHCIPort.h +++ b/Kernel/Storage/ATA/AHCIPort.h @@ -64,7 +64,7 @@ private: const char* try_disambiguate_sata_status(); void try_disambiguate_sata_error(); - bool initiate_sata_reset(SpinlockLocker&); + bool initiate_sata_reset(); void rebase(); void recover_from_fatal_error(); bool shutdown();