summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander <electrodeyt@gmail.com>2021-06-25 15:49:33 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-25 16:27:01 +0200
commit2b4cab284c1231822a361a3141805a0951c743d3 (patch)
treeb713ba8445c576202b08c0743f1f826ef3c9c23a
parente9b7d58d105d780bed65ffefb5e69a62e2ff4ab9 (diff)
downloadserenity-2b4cab284c1231822a361a3141805a0951c743d3.zip
Kernel/AHCI: Dont assume ports start at 0
This fixes a bug that occurs when the controller's ports are not (internally) numbered sequentially. This is done by checking the bits set in PI. This bug was found on bare-metal, on a laptop with 1 Port that was reported as port 4.
-rw-r--r--Kernel/Storage/AHCIController.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/Kernel/Storage/AHCIController.cpp b/Kernel/Storage/AHCIController.cpp
index 4a2044f556..ab86447ae3 100644
--- a/Kernel/Storage/AHCIController.cpp
+++ b/Kernel/Storage/AHCIController.cpp
@@ -181,12 +181,18 @@ RefPtr<StorageDevice> AHCIController::device_by_port(u32 port_index) const
RefPtr<StorageDevice> AHCIController::device(u32 index) const
{
NonnullRefPtrVector<StorageDevice> connected_devices;
- for (size_t index = 0; index < capabilities().ports_count; index++) {
- auto checked_device = device_by_port(index);
+ u32 pi = hba().control_regs.pi;
+ u32 bit = __builtin_ffsl(pi);
+ while (bit) {
+ dbgln_if(AHCI_DEBUG, "Checking implemented port {}, pi {:b}", bit - 1, pi);
+ pi &= ~(1u << (bit - 1));
+ auto checked_device = device_by_port(bit - 1);
+ bit = __builtin_ffsl(pi);
if (checked_device.is_null())
continue;
connected_devices.append(checked_device.release_nonnull());
}
+ dbgln_if(AHCI_DEBUG, "Connected device count: {}, Index: {}", connected_devices.size(), index);
if (index >= connected_devices.size())
return nullptr;
return connected_devices[index];