Serenity Operating System
at hosted 109 lines 3.8 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27// 28// Parallel ATA (PATA) controller driver 29// 30// This driver describes a logical PATA Channel. Each channel can connect up to 2 31// IDE Hard Disk Drives. The drives themselves can be either the master drive (hd0) 32// or the slave drive (hd1). 33// 34// More information about the ATA spec for PATA can be found here: 35// ftp://ftp.seagate.com/acrobat/reference/111-1c.pdf 36// 37#pragma once 38 39#include <AK/OwnPtr.h> 40#include <AK/RefPtr.h> 41#include <Kernel/Lock.h> 42#include <Kernel/PCI/Access.h> 43#include <Kernel/PCI/Device.h> 44#include <Kernel/VM/PhysicalPage.h> 45#include <Kernel/WaitQueue.h> 46#include <LibBareMetal/IO.h> 47#include <LibBareMetal/Memory/PhysicalAddress.h> 48 49namespace Kernel { 50 51struct PhysicalRegionDescriptor { 52 PhysicalAddress offset; 53 u16 size { 0 }; 54 u16 end_of_table { 0 }; 55}; 56 57class PATADiskDevice; 58class PATAChannel final : public PCI::Device { 59 friend class PATADiskDevice; 60 AK_MAKE_ETERNAL 61public: 62 enum class ChannelType : u8 { 63 Primary, 64 Secondary 65 }; 66 67public: 68 static OwnPtr<PATAChannel> create(ChannelType type, bool force_pio); 69 PATAChannel(PCI::Address address, ChannelType type, bool force_pio); 70 virtual ~PATAChannel() override; 71 72 RefPtr<PATADiskDevice> master_device() { return m_master; }; 73 RefPtr<PATADiskDevice> slave_device() { return m_slave; }; 74 75 virtual const char* purpose() const override { return "PATA Channel"; } 76 77private: 78 //^ IRQHandler 79 virtual void handle_irq(const RegisterState&) override; 80 81 void initialize(bool force_pio); 82 void detect_disks(); 83 84 void wait_for_irq(); 85 bool ata_read_sectors_with_dma(u32, u16, u8*, bool); 86 bool ata_write_sectors_with_dma(u32, u16, const u8*, bool); 87 bool ata_read_sectors(u32, u16, u8*, bool); 88 bool ata_write_sectors(u32, u16, const u8*, bool); 89 90 inline void prepare_for_irq(); 91 92 // Data members 93 u8 m_channel_number { 0 }; // Channel number. 0 = master, 1 = slave 94 IOAddress m_io_base; 95 IOAddress m_control_base; 96 volatile u8 m_device_error { 0 }; 97 98 WaitQueue m_irq_queue; 99 100 PhysicalRegionDescriptor& prdt() { return *reinterpret_cast<PhysicalRegionDescriptor*>(m_prdt_page->paddr().offset(0xc0000000).as_ptr()); } 101 RefPtr<PhysicalPage> m_prdt_page; 102 RefPtr<PhysicalPage> m_dma_buffer_page; 103 IOAddress m_bus_master_base; 104 Lockable<bool> m_dma_enabled; 105 106 RefPtr<PATADiskDevice> m_master; 107 RefPtr<PATADiskDevice> m_slave; 108}; 109}