
The new PCI subsystem is initialized during runtime. PCI::Initializer is supposed to be called during early boot, to perform a few tests, and initialize the proper configuration space access mechanism. Kernel boot parameters can be specified by a user to determine what tests will occur, to aid debugging on problematic machines. After that, PCI::Initializer should be dismissed. PCI::IOAccess is a class that is derived from PCI::Access class and implements PCI configuration space access mechanism via x86 IO ports. PCI::MMIOAccess is a class that is derived from PCI::Access and implements PCI configurtaion space access mechanism via memory access. The new PCI subsystem also supports determination of IO/MMIO space needed by a device by checking a given BAR. In addition, Every device or component that use the PCI subsystem has changed to match the last changes.
75 lines
2.1 KiB
C++
75 lines
2.1 KiB
C++
//
|
|
// Parallel ATA (PATA) controller driver
|
|
//
|
|
// This driver describes a logical PATA Channel. Each channel can connect up to 2
|
|
// IDE Hard Disk Drives. The drives themselves can be either the master drive (hd0)
|
|
// or the slave drive (hd1).
|
|
//
|
|
// More information about the ATA spec for PATA can be found here:
|
|
// ftp://ftp.seagate.com/acrobat/reference/111-1c.pdf
|
|
//
|
|
#pragma once
|
|
|
|
#include <AK/OwnPtr.h>
|
|
#include <AK/RefPtr.h>
|
|
#include <Kernel/IRQHandler.h>
|
|
#include <Kernel/Lock.h>
|
|
#include <Kernel/PCI/Access.h>
|
|
#include <Kernel/VM/PhysicalAddress.h>
|
|
#include <Kernel/VM/PhysicalPage.h>
|
|
#include <Kernel/WaitQueue.h>
|
|
|
|
struct PhysicalRegionDescriptor {
|
|
PhysicalAddress offset;
|
|
u16 size { 0 };
|
|
u16 end_of_table { 0 };
|
|
};
|
|
|
|
class PATADiskDevice;
|
|
class PATAChannel final : public IRQHandler {
|
|
friend class PATADiskDevice;
|
|
AK_MAKE_ETERNAL
|
|
public:
|
|
enum class ChannelType : u8 {
|
|
Primary,
|
|
Secondary
|
|
};
|
|
|
|
public:
|
|
static OwnPtr<PATAChannel> create(ChannelType type, bool force_pio);
|
|
PATAChannel(ChannelType type, bool force_pio);
|
|
virtual ~PATAChannel() override;
|
|
|
|
RefPtr<PATADiskDevice> master_device() { return m_master; };
|
|
RefPtr<PATADiskDevice> slave_device() { return m_slave; };
|
|
|
|
private:
|
|
//^ IRQHandler
|
|
virtual void handle_irq() override;
|
|
|
|
void initialize(bool force_pio);
|
|
void detect_disks();
|
|
|
|
void wait_for_irq();
|
|
bool ata_read_sectors_with_dma(u32, u16, u8*, bool);
|
|
bool ata_write_sectors_with_dma(u32, u16, const u8*, bool);
|
|
bool ata_read_sectors(u32, u16, u8*, bool);
|
|
bool ata_write_sectors(u32, u16, const u8*, bool);
|
|
|
|
// Data members
|
|
u8 m_channel_number { 0 }; // Channel number. 0 = master, 1 = slave
|
|
u16 m_io_base { 0x1F0 };
|
|
u16 m_control_base { 0 };
|
|
volatile u8 m_device_error { 0 };
|
|
|
|
WaitQueue m_irq_queue;
|
|
|
|
PCI::Address m_pci_address;
|
|
PhysicalRegionDescriptor m_prdt;
|
|
RefPtr<PhysicalPage> m_dma_buffer_page;
|
|
u16 m_bus_master_base { 0 };
|
|
Lockable<bool> m_dma_enabled;
|
|
|
|
RefPtr<PATADiskDevice> m_master;
|
|
RefPtr<PATADiskDevice> m_slave;
|
|
};
|