From 5541dfd9f80bebaeb946dd3d87df7b1db405d90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Offenh=C3=A4user?= Date: Tue, 14 Mar 2023 14:13:50 +0100 Subject: [PATCH] Kernel: Allow AHCIController::initialize() to fail If we fail to initialize an AHCI controller, we now skip adding it to the list of storage controllers in StorageManagement. --- Kernel/Storage/ATA/AHCI/Controller.cpp | 11 +++++++---- Kernel/Storage/ATA/AHCI/Controller.h | 4 ++-- Kernel/Storage/StorageManagement.cpp | 5 ++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Kernel/Storage/ATA/AHCI/Controller.cpp b/Kernel/Storage/ATA/AHCI/Controller.cpp index 525c84bc0c..ca55dd3340 100644 --- a/Kernel/Storage/ATA/AHCI/Controller.cpp +++ b/Kernel/Storage/ATA/AHCI/Controller.cpp @@ -18,10 +18,10 @@ namespace Kernel { -UNMAP_AFTER_INIT NonnullRefPtr AHCIController::initialize(PCI::DeviceIdentifier const& pci_device_identifier) +UNMAP_AFTER_INIT ErrorOr> AHCIController::initialize(PCI::DeviceIdentifier const& pci_device_identifier) { auto controller = adopt_ref_if_nonnull(new (nothrow) AHCIController(pci_device_identifier)).release_nonnull(); - controller->initialize_hba(pci_device_identifier); + TRY(controller->initialize_hba(pci_device_identifier)); return controller; } @@ -161,7 +161,7 @@ UNMAP_AFTER_INIT NonnullOwnPtr AHCIController::default_hba_regio AHCIController::~AHCIController() = default; -UNMAP_AFTER_INIT void AHCIController::initialize_hba(PCI::DeviceIdentifier const& pci_device_identifier) +UNMAP_AFTER_INIT ErrorOr AHCIController::initialize_hba(PCI::DeviceIdentifier const& pci_device_identifier) { u32 version = hba().control_regs.version; @@ -172,9 +172,12 @@ UNMAP_AFTER_INIT void AHCIController::initialize_hba(PCI::DeviceIdentifier const auto implemented_ports = AHCI::MaskedBitField((u32 volatile&)(hba().control_regs.pi)); m_irq_handler = AHCIInterruptHandler::create(*this, pci_device_identifier.interrupt_line().value(), implemented_ports).release_value_but_fixme_should_propagate_errors(); - reset(); + TRY(reset()); + dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Version = {:#08x}", device_identifier().address(), version); dbgln("{}: AHCI command list entries count - {}", device_identifier().address(), m_hba_capabilities.max_command_list_entries_count); + + return {}; } void AHCIController::handle_interrupt_for_port(Badge, u32 port_index) const diff --git a/Kernel/Storage/ATA/AHCI/Controller.h b/Kernel/Storage/ATA/AHCI/Controller.h index 0be7064369..0dd5caba3f 100644 --- a/Kernel/Storage/ATA/AHCI/Controller.h +++ b/Kernel/Storage/ATA/AHCI/Controller.h @@ -24,7 +24,7 @@ class AHCIController final : public ATAController friend class AHCIInterruptHandler; public: - static NonnullRefPtr initialize(PCI::DeviceIdentifier const& pci_device_identifier); + static ErrorOr> initialize(PCI::DeviceIdentifier const& pci_device_identifier); virtual ~AHCIController() override; virtual StringView device_name() const override { return "AHCI"sv; } @@ -43,7 +43,7 @@ private: void enable_global_interrupts() const; explicit AHCIController(PCI::DeviceIdentifier const&); - void initialize_hba(PCI::DeviceIdentifier const&); + ErrorOr initialize_hba(PCI::DeviceIdentifier const&); AHCI::HBADefinedCapabilities capabilities() const; LockRefPtr device_by_port(u32 index) const; diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp index 76dd7fd826..cd529ed0e1 100644 --- a/Kernel/Storage/StorageManagement.cpp +++ b/Kernel/Storage/StorageManagement.cpp @@ -111,7 +111,10 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_pci_controllers(bool force_pi if (subclass_code == SubclassID::SATAController && device_identifier.prog_if().value() == to_underlying(PCI::MassStorage::SATAProgIF::AHCI)) { - m_controllers.append(AHCIController::initialize(device_identifier)); + if (auto ahci_controller_or_error = AHCIController::initialize(device_identifier); !ahci_controller_or_error.is_error()) + m_controllers.append(ahci_controller_or_error.value()); + else + dmesgln("Unable to initialize AHCI controller: {}", ahci_controller_or_error.error()); } if (subclass_code == SubclassID::NVMeController) { auto controller = NVMeController::try_initialize(device_identifier, nvme_poll);