/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ // // 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 #include #include #include #include #include #include #include #include #include #include #include #include namespace Kernel { class AsyncBlockDeviceRequest; class IDEController; #if ARCH(X86_64) class PCIIDELegacyModeController; class ISAIDEController; #endif class IDEChannel : public ATAPort , public IRQHandler { friend class IDEController; public: enum class ChannelType : u8 { Primary, Secondary }; enum class DeviceType : u8 { Master, Slave, }; struct IOWindowGroup { IOWindowGroup(NonnullOwnPtr io_window, NonnullOwnPtr control_window, NonnullOwnPtr m_bus_master_window) : m_io_window(move(io_window)) , m_control_window(move(control_window)) , m_bus_master_window(move(m_bus_master_window)) { } IOWindowGroup(NonnullOwnPtr io_window, NonnullOwnPtr control_window) : m_io_window(move(io_window)) , m_control_window(move(control_window)) { } // Disable default implementations that would use surprising integer promotion. bool operator==(IOWindowGroup const&) const = delete; bool operator<=(IOWindowGroup const&) const = delete; bool operator>=(IOWindowGroup const&) const = delete; bool operator<(IOWindowGroup const&) const = delete; bool operator>(IOWindowGroup const&) const = delete; IOWindow& io_window() const { return *m_io_window; } IOWindow& control_window() const { return *m_control_window; } IOWindow* bus_master_window() const { return m_bus_master_window.ptr(); } private: mutable NonnullOwnPtr m_io_window; mutable NonnullOwnPtr m_control_window; mutable OwnPtr m_bus_master_window; }; public: static ErrorOr> create(IDEController const&, IOWindowGroup, ChannelType type); static ErrorOr> create(IDEController const&, u8 irq, IOWindowGroup, ChannelType type); virtual ~IDEChannel() override; virtual StringView purpose() const override { return "PATA Channel"sv; } #if ARCH(X86_64) ErrorOr allocate_resources_for_pci_ide_controller(Badge, bool force_pio); ErrorOr allocate_resources_for_isa_ide_controller(Badge); #endif private: static constexpr size_t m_logical_sector_size = 512; ErrorOr allocate_resources(bool force_pio); StringView channel_type_string() const; virtual ErrorOr disable() override { TODO(); } virtual ErrorOr power_on() override { TODO(); } virtual ErrorOr port_phy_reset() override; bool select_device_and_wait_until_not_busy(DeviceType, size_t milliseconds_timeout); virtual bool pio_capable() const override { return true; } virtual bool dma_capable() const override { return m_dma_enabled; } virtual size_t max_possible_devices_connected() const override { return 2; } virtual ErrorOr stop_busmastering() override; virtual ErrorOr start_busmastering(TransactionDirection) override; virtual ErrorOr force_busmastering_status_clean() override; virtual ErrorOr busmastering_status() override; virtual ErrorOr prepare_transaction_with_busmastering(TransactionDirection, PhysicalAddress prdt_buffer) override; virtual ErrorOr initiate_transaction(TransactionDirection) override; virtual ErrorOr task_file_status() override; virtual ErrorOr task_file_error() override; virtual ErrorOr wait_if_busy_until_timeout(size_t timeout_in_milliseconds) override; virtual ErrorOr device_select(size_t device_index) override; virtual ErrorOr detect_presence_on_selected_device() override; virtual ErrorOr enable_interrupts() override; virtual ErrorOr disable_interrupts() override; virtual ErrorOr force_clear_interrupts() override; virtual ErrorOr load_taskfile_into_registers(TaskFile const&, LBAMode lba_mode, size_t completion_timeout_in_milliseconds) override; virtual ErrorOr read_pio_data_to_buffer(UserOrKernelBuffer&, size_t block_offset, size_t words_count) override; virtual ErrorOr write_pio_data_from_buffer(UserOrKernelBuffer const&, size_t block_offset, size_t words_count) override; IDEChannel(IDEController const&, IOWindowGroup, ChannelType type, NonnullOwnPtr ata_identify_data_buffer); IDEChannel(IDEController const&, u8 irq, IOWindowGroup, ChannelType type, NonnullOwnPtr ata_identify_data_buffer); //^ IRQHandler virtual bool handle_irq(RegisterState const&) override; // Data members ChannelType m_channel_type { ChannelType::Primary }; bool m_dma_enabled { false }; bool m_interrupts_enabled { true }; IOWindowGroup m_io_window_group; }; }