Browse Source

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.
Liav A 3 năm trước cách đây
mục cha
commit
3ea49259df

+ 12 - 20
Kernel/Storage/ATA/AHCIPort.cpp

@@ -250,7 +250,7 @@ bool AHCIPort::reset()
     full_memory_barrier();
     full_memory_barrier();
     clear_sata_error_register();
     clear_sata_error_register();
     full_memory_barrier();
     full_memory_barrier();
-    if (!initiate_sata_reset(lock)) {
+    if (!initiate_sata_reset()) {
         return false;
         return false;
     }
     }
     return initialize();
     return initialize();
@@ -780,7 +780,7 @@ void AHCIPort::stop_fis_receiving() const
     m_port_registers.cmd = m_port_registers.cmd & 0xFFFFFFEF;
     m_port_registers.cmd = m_port_registers.cmd & 0xFFFFFFEF;
 }
 }
 
 
-bool AHCIPort::initiate_sata_reset(SpinlockLocker<Spinlock>& main_lock)
+bool AHCIPort::initiate_sata_reset()
 {
 {
     VERIFY(m_lock.is_locked());
     VERIFY(m_lock.is_locked());
     VERIFY(m_hard_lock.is_locked());
     VERIFY(m_hard_lock.is_locked());
@@ -802,24 +802,16 @@ bool AHCIPort::initiate_sata_reset(SpinlockLocker<Spinlock>& main_lock)
     set_interface_state(AHCI::DeviceDetectionInitialization::PerformInterfaceInitializationSequence);
     set_interface_state(AHCI::DeviceDetectionInitialization::PerformInterfaceInitializationSequence);
     // The AHCI specification says to wait now a 1 millisecond
     // The AHCI specification says to wait now a 1 millisecond
     IO::delay(1000);
     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;
-
-                IO::delay(10);
-                retry++;
-            }
-        }
-        main_lock.lock();
+    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++;
     }
     }
 
 
     dmesgln("AHCI Port {}: {}", representative_port_index(), try_disambiguate_sata_status());
     dmesgln("AHCI Port {}: {}", representative_port_index(), try_disambiguate_sata_status());

+ 1 - 1
Kernel/Storage/ATA/AHCIPort.h

@@ -64,7 +64,7 @@ private:
     const char* try_disambiguate_sata_status();
     const char* try_disambiguate_sata_status();
     void try_disambiguate_sata_error();
     void try_disambiguate_sata_error();
 
 
-    bool initiate_sata_reset(SpinlockLocker<Spinlock>&);
+    bool initiate_sata_reset();
     void rebase();
     void rebase();
     void recover_from_fatal_error();
     void recover_from_fatal_error();
     bool shutdown();
     bool shutdown();