mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Kernel/Storage: Don't try to enumerate PCI adapters if PCI is disabled
If there's no PCI bus, then it's safe to assume that we run on a x86 machine that has an ISA IDE controller in the system. In such case, we just instantiate a ISAIDEController object that assumes fixed locations of IDE IO ports.
This commit is contained in:
parent
fafa339264
commit
30eeba1981
Notes:
sideshowbarker
2024-07-17 18:08:55 +09:00
Author: https://github.com/supercomputer7 Commit: https://github.com/SerenityOS/serenity/commit/30eeba1981 Pull-request: https://github.com/SerenityOS/serenity/pull/12046
11 changed files with 283 additions and 142 deletions
|
@ -96,6 +96,8 @@ set(KERNEL_SOURCES
|
|||
Storage/ATA/ATADiskDevice.cpp
|
||||
Storage/ATA/ATAPIDiscDevice.cpp
|
||||
Storage/ATA/BMIDEChannel.cpp
|
||||
Storage/ATA/ISAIDEController.cpp
|
||||
Storage/ATA/PCIIDEController.cpp
|
||||
Storage/ATA/IDEController.cpp
|
||||
Storage/ATA/IDEChannel.cpp
|
||||
Storage/Partition/DiskPartition.cpp
|
||||
|
|
|
@ -39,7 +39,6 @@ UNMAP_AFTER_INIT void BMIDEChannel::initialize()
|
|||
{
|
||||
VERIFY(m_io_group.bus_master_base().has_value());
|
||||
// Let's try to set up DMA transfers.
|
||||
PCI::enable_bus_mastering(m_parent_controller->pci_address());
|
||||
{
|
||||
auto region_or_error = MM.allocate_dma_buffer_page("IDE PRDT", Memory::Region::Access::ReadWrite, m_prdt_page);
|
||||
if (region_or_error.is_error())
|
||||
|
|
|
@ -51,7 +51,6 @@ UNMAP_AFTER_INIT void IDEChannel::initialize()
|
|||
dbgln_if(PATA_DEBUG, "IDEChannel: {} bus master base: {}", channel_type_string(), m_io_group.bus_master_base().value());
|
||||
else
|
||||
dbgln_if(PATA_DEBUG, "IDEChannel: {} bus master base disabled", channel_type_string());
|
||||
m_parent_controller->enable_pin_based_interrupts();
|
||||
|
||||
// reset the channel
|
||||
u8 device_control = m_io_group.control_base().in<u8>();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
|
||||
* Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -16,9 +16,9 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<IDEController> IDEController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<IDEController> IDEController::initialize()
|
||||
{
|
||||
return adopt_ref(*new IDEController(device_identifier, force_pio));
|
||||
return adopt_ref(*new IDEController());
|
||||
}
|
||||
|
||||
bool IDEController::reset()
|
||||
|
@ -61,121 +61,14 @@ void IDEController::complete_current_request(AsyncDeviceRequest::RequestResult)
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT IDEController::IDEController(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
|
||||
: ATAController()
|
||||
, PCI::Device(device_identifier.address())
|
||||
, m_prog_if(device_identifier.prog_if())
|
||||
, m_interrupt_line(device_identifier.interrupt_line())
|
||||
UNMAP_AFTER_INIT IDEController::IDEController()
|
||||
{
|
||||
PCI::enable_io_space(device_identifier.address());
|
||||
PCI::enable_memory_space(device_identifier.address());
|
||||
initialize(force_pio);
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT IDEController::~IDEController()
|
||||
{
|
||||
}
|
||||
|
||||
bool IDEController::is_pci_native_mode_enabled() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x05) != 0;
|
||||
}
|
||||
|
||||
bool IDEController::is_pci_native_mode_enabled_on_primary_channel() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x1) == 0x1;
|
||||
}
|
||||
|
||||
bool IDEController::is_pci_native_mode_enabled_on_secondary_channel() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x4) == 0x4;
|
||||
}
|
||||
|
||||
bool IDEController::is_bus_master_capable() const
|
||||
{
|
||||
return m_prog_if.value() & (1 << 7);
|
||||
}
|
||||
|
||||
static const char* detect_controller_type(u8 programming_value)
|
||||
{
|
||||
switch (programming_value) {
|
||||
case 0x00:
|
||||
return "ISA Compatibility mode-only controller";
|
||||
case 0x05:
|
||||
return "PCI native mode-only controller";
|
||||
case 0x0A:
|
||||
return "ISA Compatibility mode controller, supports both channels switched to PCI native mode";
|
||||
case 0x0F:
|
||||
return "PCI native mode controller, supports both channels switched to ISA compatibility mode";
|
||||
case 0x80:
|
||||
return "ISA Compatibility mode-only controller, supports bus mastering";
|
||||
case 0x85:
|
||||
return "PCI native mode-only controller, supports bus mastering";
|
||||
case 0x8A:
|
||||
return "ISA Compatibility mode controller, supports both channels switched to PCI native mode, supports bus mastering";
|
||||
case 0x8F:
|
||||
return "PCI native mode controller, supports both channels switched to ISA compatibility mode, supports bus mastering";
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void IDEController::initialize(bool force_pio)
|
||||
{
|
||||
auto bus_master_base = IOAddress(PCI::get_BAR4(pci_address()) & (~1));
|
||||
dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base);
|
||||
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 @ {}: primary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2).in<u8>() >> 5) & 0b11));
|
||||
dbgln("IDE controller @ {}: secondary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2 + 8).in<u8>() >> 5) & 0b11));
|
||||
|
||||
if (!is_bus_master_capable())
|
||||
force_pio = true;
|
||||
|
||||
auto bar0 = PCI::get_BAR0(pci_address());
|
||||
auto primary_base_io = (bar0 == 0x1 || bar0 == 0) ? IOAddress(0x1F0) : IOAddress(bar0 & (~1));
|
||||
auto bar1 = PCI::get_BAR1(pci_address());
|
||||
auto primary_control_io = (bar1 == 0x1 || bar1 == 0) ? IOAddress(0x3F6) : IOAddress(bar1 & (~1));
|
||||
auto bar2 = PCI::get_BAR2(pci_address());
|
||||
auto secondary_base_io = (bar2 == 0x1 || bar2 == 0) ? IOAddress(0x170) : IOAddress(bar2 & (~1));
|
||||
auto bar3 = PCI::get_BAR3(pci_address());
|
||||
auto secondary_control_io = (bar3 == 0x1 || bar3 == 0) ? IOAddress(0x376) : IOAddress(bar3 & (~1));
|
||||
|
||||
auto irq_line = m_interrupt_line.value();
|
||||
if (is_pci_native_mode_enabled()) {
|
||||
VERIFY(irq_line != 0);
|
||||
}
|
||||
|
||||
if (is_pci_native_mode_enabled_on_primary_channel()) {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, irq_line, { primary_base_io, primary_control_io }, IDEChannel::ChannelType::Primary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, irq_line, { primary_base_io, primary_control_io, bus_master_base }, IDEChannel::ChannelType::Primary));
|
||||
} else {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, { primary_base_io, primary_control_io }, IDEChannel::ChannelType::Primary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, { primary_base_io, primary_control_io, bus_master_base }, IDEChannel::ChannelType::Primary));
|
||||
}
|
||||
|
||||
m_channels[0].enable_irq();
|
||||
|
||||
if (is_pci_native_mode_enabled_on_secondary_channel()) {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, irq_line, { secondary_base_io, secondary_control_io }, IDEChannel::ChannelType::Secondary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, irq_line, { secondary_base_io, secondary_control_io, bus_master_base.offset(8) }, IDEChannel::ChannelType::Secondary));
|
||||
} else {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, { secondary_base_io, secondary_control_io }, IDEChannel::ChannelType::Secondary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, { secondary_base_io, secondary_control_io, bus_master_base.offset(8) }, IDEChannel::ChannelType::Secondary));
|
||||
}
|
||||
|
||||
m_channels[1].enable_irq();
|
||||
}
|
||||
|
||||
RefPtr<StorageDevice> IDEController::device_by_channel_and_position(u32 index) const
|
||||
{
|
||||
switch (index) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
|
||||
* Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -17,34 +17,22 @@ namespace Kernel {
|
|||
|
||||
class AsyncBlockDeviceRequest;
|
||||
|
||||
class IDEController final : public ATAController
|
||||
, public PCI::Device {
|
||||
class IDEController : public ATAController {
|
||||
public:
|
||||
static NonnullRefPtr<IDEController> initialize(PCI::DeviceIdentifier const&, bool force_pio);
|
||||
static NonnullRefPtr<IDEController> initialize();
|
||||
virtual ~IDEController() override;
|
||||
|
||||
virtual RefPtr<StorageDevice> device(u32 index) const override;
|
||||
virtual bool reset() override;
|
||||
virtual bool shutdown() override;
|
||||
virtual size_t devices_count() const override;
|
||||
virtual void start_request(const ATADevice&, AsyncBlockDeviceRequest&) override;
|
||||
virtual void complete_current_request(AsyncDeviceRequest::RequestResult) override;
|
||||
virtual RefPtr<StorageDevice> device(u32 index) const override final;
|
||||
virtual bool reset() override final;
|
||||
virtual bool shutdown() override final;
|
||||
virtual size_t devices_count() const override final;
|
||||
virtual void start_request(const ATADevice&, AsyncBlockDeviceRequest&) override final;
|
||||
virtual void complete_current_request(AsyncDeviceRequest::RequestResult) override final;
|
||||
|
||||
bool is_bus_master_capable() const;
|
||||
bool is_pci_native_mode_enabled() const;
|
||||
|
||||
private:
|
||||
bool is_pci_native_mode_enabled_on_primary_channel() const;
|
||||
bool is_pci_native_mode_enabled_on_secondary_channel() const;
|
||||
IDEController(PCI::DeviceIdentifier const&, bool force_pio);
|
||||
protected:
|
||||
IDEController();
|
||||
|
||||
RefPtr<StorageDevice> device_by_channel_and_position(u32 index) const;
|
||||
void initialize(bool force_pio);
|
||||
void detect_disks();
|
||||
|
||||
NonnullRefPtrVector<IDEChannel> m_channels;
|
||||
// FIXME: Find a better way to get the ProgrammingInterface
|
||||
PCI::ProgrammingInterface m_prog_if;
|
||||
PCI::InterruptLine m_interrupt_line;
|
||||
};
|
||||
}
|
||||
|
|
44
Kernel/Storage/ATA/ISAIDEController.cpp
Normal file
44
Kernel/Storage/ATA/ISAIDEController.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Bus/PCI/API.h>
|
||||
#include <Kernel/FileSystem/ProcFS.h>
|
||||
#include <Kernel/Sections.h>
|
||||
#include <Kernel/Storage/ATA/ATADiskDevice.h>
|
||||
#include <Kernel/Storage/ATA/BMIDEChannel.h>
|
||||
#include <Kernel/Storage/ATA/ISAIDEController.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<ISAIDEController> ISAIDEController::initialize()
|
||||
{
|
||||
return adopt_ref(*new ISAIDEController());
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT ISAIDEController::ISAIDEController()
|
||||
{
|
||||
initialize_channels();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void ISAIDEController::initialize_channels()
|
||||
{
|
||||
auto primary_base_io = IOAddress(0x1F0);
|
||||
auto primary_control_io = IOAddress(0x3F6);
|
||||
auto secondary_base_io = IOAddress(0x170);
|
||||
auto secondary_control_io = IOAddress(0x376);
|
||||
|
||||
m_channels.append(IDEChannel::create(*this, { primary_base_io, primary_control_io }, IDEChannel::ChannelType::Primary));
|
||||
m_channels[0].enable_irq();
|
||||
|
||||
m_channels.append(IDEChannel::create(*this, { secondary_base_io, secondary_control_io }, IDEChannel::ChannelType::Secondary));
|
||||
m_channels[1].enable_irq();
|
||||
dbgln("ISA IDE controller detected and initialized");
|
||||
}
|
||||
|
||||
}
|
30
Kernel/Storage/ATA/ISAIDEController.h
Normal file
30
Kernel/Storage/ATA/ISAIDEController.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Storage/ATA/IDEChannel.h>
|
||||
#include <Kernel/Storage/ATA/IDEController.h>
|
||||
#include <Kernel/Storage/StorageDevice.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class AsyncBlockDeviceRequest;
|
||||
|
||||
class ISAIDEController final : public IDEController {
|
||||
public:
|
||||
static NonnullRefPtr<ISAIDEController> initialize();
|
||||
|
||||
private:
|
||||
ISAIDEController();
|
||||
|
||||
RefPtr<StorageDevice> device_by_channel_and_position(u32 index) const;
|
||||
void initialize_channels();
|
||||
};
|
||||
}
|
136
Kernel/Storage/ATA/PCIIDEController.cpp
Normal file
136
Kernel/Storage/ATA/PCIIDEController.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Bus/PCI/API.h>
|
||||
#include <Kernel/FileSystem/ProcFS.h>
|
||||
#include <Kernel/Sections.h>
|
||||
#include <Kernel/Storage/ATA/ATADiskDevice.h>
|
||||
#include <Kernel/Storage/ATA/BMIDEChannel.h>
|
||||
#include <Kernel/Storage/ATA/PCIIDEController.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<PCIIDEController> PCIIDEController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
|
||||
{
|
||||
return adopt_ref(*new PCIIDEController(device_identifier, force_pio));
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT PCIIDEController::PCIIDEController(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
|
||||
: 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 PCIIDEController::is_pci_native_mode_enabled() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x05) != 0;
|
||||
}
|
||||
|
||||
bool PCIIDEController::is_pci_native_mode_enabled_on_primary_channel() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x1) == 0x1;
|
||||
}
|
||||
|
||||
bool PCIIDEController::is_pci_native_mode_enabled_on_secondary_channel() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x4) == 0x4;
|
||||
}
|
||||
|
||||
bool PCIIDEController::is_bus_master_capable() const
|
||||
{
|
||||
return m_prog_if.value() & (1 << 7);
|
||||
}
|
||||
|
||||
static const char* detect_controller_type(u8 programming_value)
|
||||
{
|
||||
switch (programming_value) {
|
||||
case 0x00:
|
||||
return "ISA Compatibility mode-only controller";
|
||||
case 0x05:
|
||||
return "PCI native mode-only controller";
|
||||
case 0x0A:
|
||||
return "ISA Compatibility mode controller, supports both channels switched to PCI native mode";
|
||||
case 0x0F:
|
||||
return "PCI native mode controller, supports both channels switched to ISA compatibility mode";
|
||||
case 0x80:
|
||||
return "ISA Compatibility mode-only controller, supports bus mastering";
|
||||
case 0x85:
|
||||
return "PCI native mode-only controller, supports bus mastering";
|
||||
case 0x8A:
|
||||
return "ISA Compatibility mode controller, supports both channels switched to PCI native mode, supports bus mastering";
|
||||
case 0x8F:
|
||||
return "PCI native mode controller, supports both channels switched to ISA compatibility mode, supports bus mastering";
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void PCIIDEController::initialize(bool force_pio)
|
||||
{
|
||||
auto bus_master_base = IOAddress(PCI::get_BAR4(pci_address()) & (~1));
|
||||
dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base);
|
||||
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 @ {}: primary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2).in<u8>() >> 5) & 0b11));
|
||||
dbgln("IDE controller @ {}: secondary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2 + 8).in<u8>() >> 5) & 0b11));
|
||||
|
||||
if (!is_bus_master_capable())
|
||||
force_pio = true;
|
||||
|
||||
auto bar0 = PCI::get_BAR0(pci_address());
|
||||
auto primary_base_io = (bar0 == 0x1 || bar0 == 0) ? IOAddress(0x1F0) : IOAddress(bar0 & (~1));
|
||||
auto bar1 = PCI::get_BAR1(pci_address());
|
||||
auto primary_control_io = (bar1 == 0x1 || bar1 == 0) ? IOAddress(0x3F6) : IOAddress(bar1 & (~1));
|
||||
auto bar2 = PCI::get_BAR2(pci_address());
|
||||
auto secondary_base_io = (bar2 == 0x1 || bar2 == 0) ? IOAddress(0x170) : IOAddress(bar2 & (~1));
|
||||
auto bar3 = PCI::get_BAR3(pci_address());
|
||||
auto secondary_control_io = (bar3 == 0x1 || bar3 == 0) ? IOAddress(0x376) : IOAddress(bar3 & (~1));
|
||||
|
||||
auto irq_line = m_interrupt_line.value();
|
||||
if (is_pci_native_mode_enabled()) {
|
||||
VERIFY(irq_line != 0);
|
||||
}
|
||||
|
||||
if (is_pci_native_mode_enabled_on_primary_channel()) {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, irq_line, { primary_base_io, primary_control_io }, IDEChannel::ChannelType::Primary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, irq_line, { primary_base_io, primary_control_io, bus_master_base }, IDEChannel::ChannelType::Primary));
|
||||
} else {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, { primary_base_io, primary_control_io }, IDEChannel::ChannelType::Primary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, { primary_base_io, primary_control_io, bus_master_base }, IDEChannel::ChannelType::Primary));
|
||||
}
|
||||
|
||||
m_channels[0].enable_irq();
|
||||
|
||||
if (is_pci_native_mode_enabled_on_secondary_channel()) {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, irq_line, { secondary_base_io, secondary_control_io }, IDEChannel::ChannelType::Secondary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, irq_line, { secondary_base_io, secondary_control_io, bus_master_base.offset(8) }, IDEChannel::ChannelType::Secondary));
|
||||
} else {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, { secondary_base_io, secondary_control_io }, IDEChannel::ChannelType::Secondary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, { secondary_base_io, secondary_control_io, bus_master_base.offset(8) }, IDEChannel::ChannelType::Secondary));
|
||||
}
|
||||
|
||||
m_channels[1].enable_irq();
|
||||
}
|
||||
|
||||
}
|
41
Kernel/Storage/ATA/PCIIDEController.h
Normal file
41
Kernel/Storage/ATA/PCIIDEController.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Storage/ATA/IDEChannel.h>
|
||||
#include <Kernel/Storage/ATA/IDEController.h>
|
||||
#include <Kernel/Storage/StorageDevice.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class AsyncBlockDeviceRequest;
|
||||
|
||||
class PCIIDEController final : public IDEController
|
||||
, public PCI::Device {
|
||||
public:
|
||||
static NonnullRefPtr<PCIIDEController> initialize(PCI::DeviceIdentifier const&, bool force_pio);
|
||||
|
||||
bool is_bus_master_capable() const;
|
||||
bool is_pci_native_mode_enabled() const;
|
||||
|
||||
private:
|
||||
bool is_pci_native_mode_enabled_on_primary_channel() const;
|
||||
bool is_pci_native_mode_enabled_on_secondary_channel() const;
|
||||
PCIIDEController(PCI::DeviceIdentifier const&, bool force_pio);
|
||||
|
||||
RefPtr<StorageDevice> device_by_channel_and_position(u32 index) const;
|
||||
void initialize(bool force_pio);
|
||||
void detect_disks();
|
||||
|
||||
// FIXME: Find a better way to get the ProgrammingInterface
|
||||
PCI::ProgrammingInterface m_prog_if;
|
||||
PCI::InterruptLine m_interrupt_line;
|
||||
};
|
||||
}
|
|
@ -16,7 +16,8 @@
|
|||
#include <Kernel/FileSystem/Ext2FileSystem.h>
|
||||
#include <Kernel/Panic.h>
|
||||
#include <Kernel/Storage/ATA/AHCIController.h>
|
||||
#include <Kernel/Storage/ATA/IDEController.h>
|
||||
#include <Kernel/Storage/ATA/ISAIDEController.h>
|
||||
#include <Kernel/Storage/ATA/PCIIDEController.h>
|
||||
#include <Kernel/Storage/NVMe/NVMeController.h>
|
||||
#include <Kernel/Storage/Partition/EBRPartitionTable.h>
|
||||
#include <Kernel/Storage/Partition/GUIDPartitionTable.h>
|
||||
|
@ -45,7 +46,7 @@ bool StorageManagement::boot_argument_contains_partition_uuid()
|
|||
return m_boot_argument.starts_with(partition_uuid_prefix);
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void StorageManagement::enumerate_controllers(bool force_pio, bool nvme_poll)
|
||||
UNMAP_AFTER_INIT void StorageManagement::enumerate_pci_controllers(bool force_pio, bool nvme_poll)
|
||||
{
|
||||
VERIFY(m_controllers.is_empty());
|
||||
|
||||
|
@ -77,7 +78,7 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_controllers(bool force_pio, b
|
|||
|
||||
auto subclass_code = static_cast<SubclassID>(device_identifier.subclass_code().value());
|
||||
if (subclass_code == SubclassID::IDEController && kernel_command_line().is_ide_enabled()) {
|
||||
m_controllers.append(IDEController::initialize(device_identifier, force_pio));
|
||||
m_controllers.append(PCIIDEController::initialize(device_identifier, force_pio));
|
||||
}
|
||||
|
||||
if (subclass_code == SubclassID::SATAController
|
||||
|
@ -94,7 +95,6 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_controllers(bool force_pio, b
|
|||
}
|
||||
});
|
||||
}
|
||||
m_controllers.append(RamdiskController::initialize());
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void StorageManagement::enumerate_storage_devices()
|
||||
|
@ -273,7 +273,16 @@ UNMAP_AFTER_INIT void StorageManagement::initialize(StringView root_device, bool
|
|||
{
|
||||
VERIFY(s_device_minor_number == 0);
|
||||
m_boot_argument = root_device;
|
||||
enumerate_controllers(force_pio, poll);
|
||||
if (PCI::Access::is_disabled()) {
|
||||
// Note: If PCI is disabled, we assume that at least we have an ISA IDE controller
|
||||
// to probe and use
|
||||
m_controllers.append(ISAIDEController::initialize());
|
||||
} else {
|
||||
enumerate_pci_controllers(force_pio, poll);
|
||||
}
|
||||
// Note: Whether PCI bus is present on the system or not, always try to attach
|
||||
// a given ramdisk.
|
||||
m_controllers.append(RamdiskController::initialize());
|
||||
enumerate_storage_devices();
|
||||
enumerate_disk_partitions();
|
||||
if (!boot_argument_contains_partition_uuid()) {
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
private:
|
||||
bool boot_argument_contains_partition_uuid();
|
||||
|
||||
void enumerate_controllers(bool force_pio, bool nvme_poll);
|
||||
void enumerate_pci_controllers(bool force_pio, bool nvme_poll);
|
||||
void enumerate_storage_devices();
|
||||
void enumerate_disk_partitions();
|
||||
|
||||
|
|
Loading…
Reference in a new issue