diff --git a/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp b/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp index 35f6c5b8ed..f5260ea1dc 100644 --- a/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp +++ b/Kernel/Arch/x86_64/PCI/IDELegacyModeController.cpp @@ -15,21 +15,26 @@ namespace Kernel { -UNMAP_AFTER_INIT NonnullLockRefPtr PCIIDELegacyModeController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio) +UNMAP_AFTER_INIT ErrorOr> PCIIDELegacyModeController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio) { - return adopt_lock_ref(*new PCIIDELegacyModeController(device_identifier, force_pio)); + auto controller = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) PCIIDELegacyModeController(device_identifier))); + PCI::enable_io_space(device_identifier.address()); + PCI::enable_memory_space(device_identifier.address()); + PCI::enable_bus_mastering(device_identifier.address()); + ArmedScopeGuard disable_interrupts_on_failure([&] { + controller->disable_pin_based_interrupts(); + }); + controller->enable_pin_based_interrupts(); + TRY(controller->initialize_and_enumerate_channels(force_pio)); + disable_interrupts_on_failure.disarm(); + return controller; } -UNMAP_AFTER_INIT PCIIDELegacyModeController::PCIIDELegacyModeController(PCI::DeviceIdentifier const& device_identifier, bool force_pio) +UNMAP_AFTER_INIT PCIIDELegacyModeController::PCIIDELegacyModeController(PCI::DeviceIdentifier const& device_identifier) : PCI::Device(device_identifier.address()) , m_prog_if(device_identifier.prog_if()) , m_interrupt_line(device_identifier.interrupt_line()) { - PCI::enable_io_space(device_identifier.address()); - PCI::enable_memory_space(device_identifier.address()); - PCI::enable_bus_mastering(device_identifier.address()); - enable_pin_based_interrupts(); - initialize(force_pio); } bool PCIIDELegacyModeController::is_pci_native_mode_enabled() const @@ -77,7 +82,7 @@ static char const* detect_controller_type(u8 programming_value) VERIFY_NOT_REACHED(); } -UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) +UNMAP_AFTER_INIT ErrorOr PCIIDELegacyModeController::initialize_and_enumerate_channels(bool force_pio) { dbgln("IDE controller @ {}: interrupt line was set to {}", pci_address(), m_interrupt_line.value()); dbgln("IDE controller @ {}: {}", pci_address(), detect_controller_type(m_prog_if.value())); @@ -86,17 +91,10 @@ UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base); } - auto initialize_and_enumerate = [&force_pio](IDEChannel& channel) -> void { - { - auto result = channel.allocate_resources_for_pci_ide_controller({}, force_pio); - // FIXME: Propagate errors properly - VERIFY(!result.is_error()); - } - { - auto result = channel.detect_connected_devices(); - // FIXME: Propagate errors properly - VERIFY(!result.is_error()); - } + auto initialize_and_enumerate = [&force_pio](IDEChannel& channel) -> ErrorOr { + TRY(channel.allocate_resources_for_pci_ide_controller({}, force_pio)); + TRY(channel.detect_connected_devices()); + return {}; }; if (!is_bus_master_capable()) @@ -105,14 +103,14 @@ UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) OwnPtr primary_base_io_window; OwnPtr primary_control_io_window; if (!is_pci_native_mode_enabled_on_primary_channel()) { - primary_base_io_window = IOWindow::create_for_io_space(IOAddress(0x1F0), 8).release_value_but_fixme_should_propagate_errors(); - primary_control_io_window = IOWindow::create_for_io_space(IOAddress(0x3F6), 4).release_value_but_fixme_should_propagate_errors(); + primary_base_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x1F0), 8)); + primary_control_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x3F6), 4)); } else { - auto primary_base_io_window = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR0).release_value_but_fixme_should_propagate_errors(); - auto pci_primary_control_io_window = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR1).release_value_but_fixme_should_propagate_errors(); + auto primary_base_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR0)); + auto pci_primary_control_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR1)); // Note: the PCI IDE specification says we should access the IO address with an offset of 2 // on native PCI IDE controllers. - primary_control_io_window = pci_primary_control_io_window->create_from_io_window_with_offset(2, 4).release_value_but_fixme_should_propagate_errors(); + primary_control_io_window = TRY(pci_primary_control_io_window->create_from_io_window_with_offset(2, 4)); } VERIFY(primary_base_io_window); @@ -122,20 +120,20 @@ UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) OwnPtr secondary_control_io_window; if (!is_pci_native_mode_enabled_on_primary_channel()) { - secondary_base_io_window = IOWindow::create_for_io_space(IOAddress(0x170), 8).release_value_but_fixme_should_propagate_errors(); - secondary_control_io_window = IOWindow::create_for_io_space(IOAddress(0x376), 4).release_value_but_fixme_should_propagate_errors(); + secondary_base_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x170), 8)); + secondary_control_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x376), 4)); } else { - secondary_base_io_window = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR2).release_value_but_fixme_should_propagate_errors(); - auto pci_secondary_control_io_window = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR3).release_value_but_fixme_should_propagate_errors(); + secondary_base_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR2)); + auto pci_secondary_control_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR3)); // Note: the PCI IDE specification says we should access the IO address with an offset of 2 // on native PCI IDE controllers. - secondary_control_io_window = pci_secondary_control_io_window->create_from_io_window_with_offset(2, 4).release_value_but_fixme_should_propagate_errors(); + secondary_control_io_window = TRY(pci_secondary_control_io_window->create_from_io_window_with_offset(2, 4)); } VERIFY(secondary_base_io_window); VERIFY(secondary_control_io_window); - auto primary_bus_master_io = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR4, 16).release_value_but_fixme_should_propagate_errors(); - auto secondary_bus_master_io = primary_bus_master_io->create_from_io_window_with_offset(8).release_value_but_fixme_should_propagate_errors(); + auto primary_bus_master_io = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR4, 16)); + auto secondary_bus_master_io = TRY(primary_bus_master_io->create_from_io_window_with_offset(8)); // FIXME: On IOAPIC based system, this value might be completely wrong // On QEMU for example, it should be "u8 irq_line = 22;" to actually work. @@ -149,20 +147,21 @@ UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) auto secondary_channel_io_window_group = IDEChannel::IOWindowGroup { secondary_base_io_window.release_nonnull(), secondary_control_io_window.release_nonnull(), move(secondary_bus_master_io) }; if (is_pci_native_mode_enabled_on_primary_channel()) { - m_channels.append(IDEChannel::create(*this, irq_line, move(primary_channel_io_window_group), IDEChannel::ChannelType::Primary)); + TRY(m_channels.try_append(IDEChannel::create(*this, irq_line, move(primary_channel_io_window_group), IDEChannel::ChannelType::Primary))); } else { - m_channels.append(IDEChannel::create(*this, move(primary_channel_io_window_group), IDEChannel::ChannelType::Primary)); + TRY(m_channels.try_append(IDEChannel::create(*this, move(primary_channel_io_window_group), IDEChannel::ChannelType::Primary))); } - initialize_and_enumerate(m_channels[0]); + TRY(initialize_and_enumerate(m_channels[0])); m_channels[0].enable_irq(); if (is_pci_native_mode_enabled_on_secondary_channel()) { - m_channels.append(IDEChannel::create(*this, irq_line, move(secondary_channel_io_window_group), IDEChannel::ChannelType::Secondary)); + TRY(m_channels.try_append(IDEChannel::create(*this, irq_line, move(secondary_channel_io_window_group), IDEChannel::ChannelType::Secondary))); } else { - m_channels.append(IDEChannel::create(*this, move(secondary_channel_io_window_group), IDEChannel::ChannelType::Secondary)); + TRY(m_channels.try_append(IDEChannel::create(*this, move(secondary_channel_io_window_group), IDEChannel::ChannelType::Secondary))); } - initialize_and_enumerate(m_channels[1]); + TRY(initialize_and_enumerate(m_channels[1])); m_channels[1].enable_irq(); + return {}; } } diff --git a/Kernel/Arch/x86_64/PCI/IDELegacyModeController.h b/Kernel/Arch/x86_64/PCI/IDELegacyModeController.h index 380f11dc6c..11aff3d33b 100644 --- a/Kernel/Arch/x86_64/PCI/IDELegacyModeController.h +++ b/Kernel/Arch/x86_64/PCI/IDELegacyModeController.h @@ -19,7 +19,7 @@ class AsyncBlockDeviceRequest; class PCIIDELegacyModeController final : public IDEController , public PCI::Device { public: - static NonnullLockRefPtr initialize(PCI::DeviceIdentifier const&, bool force_pio); + static ErrorOr> initialize(PCI::DeviceIdentifier const&, bool force_pio); bool is_bus_master_capable() const; bool is_pci_native_mode_enabled() const; @@ -27,10 +27,10 @@ public: private: bool is_pci_native_mode_enabled_on_primary_channel() const; bool is_pci_native_mode_enabled_on_secondary_channel() const; - PCIIDELegacyModeController(PCI::DeviceIdentifier const&, bool force_pio); + explicit PCIIDELegacyModeController(PCI::DeviceIdentifier const&); LockRefPtr device_by_channel_and_position(u32 index) const; - void initialize(bool force_pio); + ErrorOr initialize_and_enumerate_channels(bool force_pio); // FIXME: Find a better way to get the ProgrammingInterface PCI::ProgrammingInterface m_prog_if; diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp index 514a40a9c2..8bbfe92a8f 100644 --- a/Kernel/Storage/StorageManagement.cpp +++ b/Kernel/Storage/StorageManagement.cpp @@ -105,7 +105,10 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_pci_controllers(bool force_pi auto subclass_code = static_cast(device_identifier.subclass_code().value()); #if ARCH(X86_64) if (subclass_code == SubclassID::IDEController && kernel_command_line().is_ide_enabled()) { - m_controllers.append(PCIIDELegacyModeController::initialize(device_identifier, force_pio)); + if (auto ide_controller_or_error = PCIIDELegacyModeController::initialize(device_identifier, force_pio); !ide_controller_or_error.is_error()) + m_controllers.append(ide_controller_or_error.release_value()); + else + dmesgln("Unable to initialize IDE controller: {}", ide_controller_or_error.error()); } #elif ARCH(AARCH64) (void)force_pio;