IDEChannel.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. //
  7. // Parallel ATA (PATA) controller driver
  8. //
  9. // This driver describes a logical PATA Channel. Each channel can connect up to 2
  10. // IDE Hard Disk Drives. The drives themselves can be either the master drive (hd0)
  11. // or the slave drive (hd1).
  12. //
  13. // More information about the ATA spec for PATA can be found here:
  14. // ftp://ftp.seagate.com/acrobat/reference/111-1c.pdf
  15. //
  16. #pragma once
  17. #include <AK/RefPtr.h>
  18. #include <Kernel/Devices/Device.h>
  19. #include <Kernel/IO.h>
  20. #include <Kernel/Interrupts/IRQHandler.h>
  21. #include <Kernel/Locking/Mutex.h>
  22. #include <Kernel/Memory/PhysicalPage.h>
  23. #include <Kernel/PhysicalAddress.h>
  24. #include <Kernel/Random.h>
  25. #include <Kernel/Storage/StorageDevice.h>
  26. #include <Kernel/WaitQueue.h>
  27. namespace Kernel {
  28. class AsyncBlockDeviceRequest;
  29. class IDEController;
  30. class IDEChannel : public RefCounted<IDEChannel>
  31. , public IRQHandler {
  32. friend class IDEController;
  33. friend class PATADiskDevice;
  34. AK_MAKE_ETERNAL
  35. public:
  36. enum class ChannelType : u8 {
  37. Primary,
  38. Secondary
  39. };
  40. struct IOAddressGroup {
  41. IOAddressGroup(IOAddress io_base, IOAddress control_base, IOAddress bus_master_base)
  42. : m_io_base(io_base)
  43. , m_control_base(control_base)
  44. , m_bus_master_base(bus_master_base)
  45. {
  46. }
  47. IOAddressGroup(IOAddress io_base, IOAddress control_base)
  48. : m_io_base(io_base)
  49. , m_control_base(control_base)
  50. , m_bus_master_base()
  51. {
  52. }
  53. IOAddressGroup(const IOAddressGroup& other, IOAddress bus_master_base)
  54. : m_io_base(other.io_base())
  55. , m_control_base(other.control_base())
  56. , m_bus_master_base(bus_master_base)
  57. {
  58. }
  59. // Disable default implementations that would use surprising integer promotion.
  60. bool operator==(const IOAddressGroup&) const = delete;
  61. bool operator<=(const IOAddressGroup&) const = delete;
  62. bool operator>=(const IOAddressGroup&) const = delete;
  63. bool operator<(const IOAddressGroup&) const = delete;
  64. bool operator>(const IOAddressGroup&) const = delete;
  65. IOAddress io_base() const { return m_io_base; };
  66. IOAddress control_base() const { return m_control_base; }
  67. Optional<IOAddress> bus_master_base() const { return m_bus_master_base; }
  68. const IOAddressGroup& operator=(const IOAddressGroup& group)
  69. {
  70. m_io_base = group.io_base();
  71. m_control_base = group.control_base();
  72. m_bus_master_base = group.bus_master_base();
  73. return *this;
  74. }
  75. private:
  76. IOAddress m_io_base;
  77. IOAddress m_control_base;
  78. Optional<IOAddress> m_bus_master_base;
  79. };
  80. public:
  81. static NonnullRefPtr<IDEChannel> create(const IDEController&, IOAddressGroup, ChannelType type);
  82. static NonnullRefPtr<IDEChannel> create(const IDEController&, u8 irq, IOAddressGroup, ChannelType type);
  83. virtual ~IDEChannel() override;
  84. RefPtr<StorageDevice> master_device() const;
  85. RefPtr<StorageDevice> slave_device() const;
  86. virtual StringView purpose() const override { return "PATA Channel"; }
  87. virtual bool is_dma_enabled() const { return false; }
  88. private:
  89. void complete_current_request(AsyncDeviceRequest::RequestResult);
  90. void initialize();
  91. protected:
  92. enum class LBAMode : u8 {
  93. None, // CHS
  94. TwentyEightBit,
  95. FortyEightBit,
  96. };
  97. enum class Direction : u8 {
  98. Read,
  99. Write,
  100. };
  101. IDEChannel(const IDEController&, IOAddressGroup, ChannelType type);
  102. IDEChannel(const IDEController&, u8 irq, IOAddressGroup, ChannelType type);
  103. //^ IRQHandler
  104. virtual bool handle_irq(const RegisterState&) override;
  105. virtual void send_ata_io_command(LBAMode lba_mode, Direction direction) const;
  106. virtual void ata_read_sectors(bool, u16);
  107. virtual void ata_write_sectors(bool, u16);
  108. void detect_disks();
  109. String channel_type_string() const;
  110. void try_disambiguate_error();
  111. bool wait_until_not_busy(bool slave, size_t milliseconds_timeout);
  112. bool wait_until_not_busy(size_t milliseconds_timeout);
  113. void start_request(AsyncBlockDeviceRequest&, bool, u16);
  114. void clear_pending_interrupts() const;
  115. void ata_access(Direction, bool, u64, u8, u16);
  116. bool ata_do_read_sector();
  117. void ata_do_write_sector();
  118. // Data members
  119. ChannelType m_channel_type { ChannelType::Primary };
  120. volatile u8 m_device_error { 0 };
  121. EntropySource m_entropy_source;
  122. RefPtr<StorageDevice> m_master;
  123. RefPtr<StorageDevice> m_slave;
  124. RefPtr<AsyncBlockDeviceRequest> m_current_request;
  125. u64 m_current_request_block_index { 0 };
  126. bool m_current_request_flushing_cache { false };
  127. Spinlock<u8> m_request_lock;
  128. Mutex m_lock { "IDEChannel" };
  129. IOAddressGroup m_io_group;
  130. NonnullRefPtr<IDEController> m_parent_controller;
  131. };
  132. }