mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:32:46 +00:00 
			
		
		
		
	Kernel: Propagate properly errors from PCI IDE Controller initialization
This commit is contained in:
		
							parent
							
								
									735aa01b58
								
							
						
					
					
						commit
						cf3b75e2e6
					
				
					 3 changed files with 44 additions and 42 deletions
				
			
		|  | @ -15,21 +15,26 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| UNMAP_AFTER_INIT NonnullLockRefPtr<PCIIDELegacyModeController> PCIIDELegacyModeController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio) | UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<PCIIDELegacyModeController>> 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()) |     : PCI::Device(device_identifier.address()) | ||||||
|     , m_prog_if(device_identifier.prog_if()) |     , m_prog_if(device_identifier.prog_if()) | ||||||
|     , m_interrupt_line(device_identifier.interrupt_line()) |     , 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 | bool PCIIDELegacyModeController::is_pci_native_mode_enabled() const | ||||||
|  | @ -77,7 +82,7 @@ static char const* detect_controller_type(u8 programming_value) | ||||||
|     VERIFY_NOT_REACHED(); |     VERIFY_NOT_REACHED(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) | UNMAP_AFTER_INIT ErrorOr<void> 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 @ {}: interrupt line was set to {}", pci_address(), m_interrupt_line.value()); | ||||||
|     dbgln("IDE controller @ {}: {}", pci_address(), detect_controller_type(m_prog_if.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); |         dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto initialize_and_enumerate = [&force_pio](IDEChannel& channel) -> void { |     auto initialize_and_enumerate = [&force_pio](IDEChannel& channel) -> ErrorOr<void> { | ||||||
|         { |         TRY(channel.allocate_resources_for_pci_ide_controller({}, force_pio)); | ||||||
|             auto result = channel.allocate_resources_for_pci_ide_controller({}, force_pio); |         TRY(channel.detect_connected_devices()); | ||||||
|             // FIXME: Propagate errors properly
 |         return {}; | ||||||
|             VERIFY(!result.is_error()); |  | ||||||
|         } |  | ||||||
|         { |  | ||||||
|             auto result = channel.detect_connected_devices(); |  | ||||||
|             // FIXME: Propagate errors properly
 |  | ||||||
|             VERIFY(!result.is_error()); |  | ||||||
|         } |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     if (!is_bus_master_capable()) |     if (!is_bus_master_capable()) | ||||||
|  | @ -105,14 +103,14 @@ UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) | ||||||
|     OwnPtr<IOWindow> primary_base_io_window; |     OwnPtr<IOWindow> primary_base_io_window; | ||||||
|     OwnPtr<IOWindow> primary_control_io_window; |     OwnPtr<IOWindow> primary_control_io_window; | ||||||
|     if (!is_pci_native_mode_enabled_on_primary_channel()) { |     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_base_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x1F0), 8)); | ||||||
|         primary_control_io_window = IOWindow::create_for_io_space(IOAddress(0x3F6), 4).release_value_but_fixme_should_propagate_errors(); |         primary_control_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x3F6), 4)); | ||||||
|     } else { |     } 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 primary_base_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR0)); | ||||||
|         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 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
 |         // Note: the PCI IDE specification says we should access the IO address with an offset of 2
 | ||||||
|         // on native PCI IDE controllers.
 |         // 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); |     VERIFY(primary_base_io_window); | ||||||
|  | @ -122,20 +120,20 @@ UNMAP_AFTER_INIT void PCIIDELegacyModeController::initialize(bool force_pio) | ||||||
|     OwnPtr<IOWindow> secondary_control_io_window; |     OwnPtr<IOWindow> secondary_control_io_window; | ||||||
| 
 | 
 | ||||||
|     if (!is_pci_native_mode_enabled_on_primary_channel()) { |     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_base_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x170), 8)); | ||||||
|         secondary_control_io_window = IOWindow::create_for_io_space(IOAddress(0x376), 4).release_value_but_fixme_should_propagate_errors(); |         secondary_control_io_window = TRY(IOWindow::create_for_io_space(IOAddress(0x376), 4)); | ||||||
|     } else { |     } else { | ||||||
|         secondary_base_io_window = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR2).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 = IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR3).release_value_but_fixme_should_propagate_errors(); |         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
 |         // Note: the PCI IDE specification says we should access the IO address with an offset of 2
 | ||||||
|         // on native PCI IDE controllers.
 |         // 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_base_io_window); | ||||||
|     VERIFY(secondary_control_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 primary_bus_master_io = TRY(IOWindow::create_for_pci_device_bar(pci_address(), PCI::HeaderType0BaseRegister::BAR4, 16)); | ||||||
|     auto secondary_bus_master_io = primary_bus_master_io->create_from_io_window_with_offset(8).release_value_but_fixme_should_propagate_errors(); |     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
 |     // 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.
 |     // 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) }; |     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()) { |     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 { |     } 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(); |     m_channels[0].enable_irq(); | ||||||
| 
 | 
 | ||||||
|     if (is_pci_native_mode_enabled_on_secondary_channel()) { |     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 { |     } 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(); |     m_channels[1].enable_irq(); | ||||||
|  |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ class AsyncBlockDeviceRequest; | ||||||
| class PCIIDELegacyModeController final : public IDEController | class PCIIDELegacyModeController final : public IDEController | ||||||
|     , public PCI::Device { |     , public PCI::Device { | ||||||
| public: | public: | ||||||
|     static NonnullLockRefPtr<PCIIDELegacyModeController> initialize(PCI::DeviceIdentifier const&, bool force_pio); |     static ErrorOr<NonnullLockRefPtr<PCIIDELegacyModeController>> initialize(PCI::DeviceIdentifier const&, bool force_pio); | ||||||
| 
 | 
 | ||||||
|     bool is_bus_master_capable() const; |     bool is_bus_master_capable() const; | ||||||
|     bool is_pci_native_mode_enabled() const; |     bool is_pci_native_mode_enabled() const; | ||||||
|  | @ -27,10 +27,10 @@ public: | ||||||
| private: | private: | ||||||
|     bool is_pci_native_mode_enabled_on_primary_channel() const; |     bool is_pci_native_mode_enabled_on_primary_channel() const; | ||||||
|     bool is_pci_native_mode_enabled_on_secondary_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<StorageDevice> device_by_channel_and_position(u32 index) const; |     LockRefPtr<StorageDevice> device_by_channel_and_position(u32 index) const; | ||||||
|     void initialize(bool force_pio); |     ErrorOr<void> initialize_and_enumerate_channels(bool force_pio); | ||||||
| 
 | 
 | ||||||
|     // FIXME: Find a better way to get the ProgrammingInterface
 |     // FIXME: Find a better way to get the ProgrammingInterface
 | ||||||
|     PCI::ProgrammingInterface m_prog_if; |     PCI::ProgrammingInterface m_prog_if; | ||||||
|  |  | ||||||
|  | @ -105,7 +105,10 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_pci_controllers(bool force_pi | ||||||
|             auto subclass_code = static_cast<SubclassID>(device_identifier.subclass_code().value()); |             auto subclass_code = static_cast<SubclassID>(device_identifier.subclass_code().value()); | ||||||
| #if ARCH(X86_64) | #if ARCH(X86_64) | ||||||
|             if (subclass_code == SubclassID::IDEController && kernel_command_line().is_ide_enabled()) { |             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) | #elif ARCH(AARCH64) | ||||||
|             (void)force_pio; |             (void)force_pio; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Liav A
						Liav A