Kernel: Fix wrong I/O ports for the ATA alternate status registers

The alternate status register is not part of the same set of registers
as all the other stuff.

Also rename wait_400ns() to io_delay() since we had no guarantee that
it was waiting for 400ns..
This commit is contained in:
Andreas Kling 2019-09-04 11:10:07 +02:00
parent 8cbb38a237
commit e5500e2a22
Notes: sideshowbarker 2024-07-19 12:18:58 +09:00
2 changed files with 15 additions and 17 deletions

View File

@ -71,13 +71,9 @@
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_COMMAND 0x07
#define ATA_REG_STATUS 0x07
#define ATA_REG_SECCOUNT1 0x08
#define ATA_REG_LBA3 0x09
#define ATA_REG_LBA4 0x0A
#define ATA_REG_LBA5 0x0B
#define ATA_REG_CONTROL 0x0C
#define ATA_REG_ALTSTATUS 0x0C
#define ATA_REG_DEVADDRESS 0x0D
#define ATA_CTL_CONTROL 0x00
#define ATA_CTL_ALTSTATUS 0x00
#define ATA_CTL_DEVADDRESS 0x01
static Lock& s_lock()
{
@ -97,6 +93,7 @@ PATAChannel::PATAChannel(ChannelType type)
: IRQHandler((type == ChannelType::Primary ? PATA_PRIMARY_IRQ : PATA_SECONDARY_IRQ))
, m_channel_number((type == ChannelType::Primary ? 0 : 1))
, m_io_base((type == ChannelType::Primary ? 0x1F0 : 0x170))
, m_control_base((type == ChannelType::Primary ? 0x3f6 : 0x376))
{
m_dma_enabled.resource() = true;
ProcFS::add_sys_bool("ide_dma", m_dma_enabled);
@ -175,10 +172,10 @@ void PATAChannel::handle_irq()
m_interrupted = true;
}
static void wait_400ns(u16 io_base)
static void io_delay()
{
for (int i = 0; i < 4; ++i)
IO::in8(io_base + ATA_REG_ALTSTATUS);
IO::in8(0x3f6);
}
void PATAChannel::detect_disks()
@ -285,9 +282,9 @@ bool PATAChannel::ata_read_sectors_with_dma(u32 lba, u16 count, u8* outbuf, bool
if (slave_request)
devsel |= 0x10;
IO::out8(m_io_base + ATA_REG_CONTROL, 0);
IO::out8(m_control_base + ATA_CTL_CONTROL, 0);
IO::out8(m_io_base + ATA_REG_HDDEVSEL, devsel | (static_cast<u8>(slave_request) << 4));
wait_400ns(m_io_base);
io_delay();
IO::out8(m_io_base + ATA_REG_FEATURES, 0);
@ -308,7 +305,7 @@ bool PATAChannel::ata_read_sectors_with_dma(u32 lba, u16 count, u8* outbuf, bool
}
IO::out8(m_io_base + ATA_REG_COMMAND, ATA_CMD_READ_DMA_EXT);
wait_400ns(m_io_base);
io_delay();
// Start bus master
IO::out8(m_bus_master_base, 0x9);
@ -363,9 +360,9 @@ bool PATAChannel::ata_write_sectors_with_dma(u32 lba, u16 count, const u8* inbuf
if (slave_request)
devsel |= 0x10;
IO::out8(m_io_base + ATA_REG_CONTROL, 0);
IO::out8(m_control_base + ATA_CTL_CONTROL, 0);
IO::out8(m_io_base + ATA_REG_HDDEVSEL, devsel | (static_cast<u8>(slave_request) << 4));
wait_400ns(m_io_base);
io_delay();
IO::out8(m_io_base + ATA_REG_FEATURES, 0);
@ -386,7 +383,7 @@ bool PATAChannel::ata_write_sectors_with_dma(u32 lba, u16 count, const u8* inbuf
}
IO::out8(m_io_base + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA_EXT);
wait_400ns(m_io_base);
io_delay();
// Start bus master
IO::out8(m_bus_master_base, 0x1);
@ -446,7 +443,7 @@ bool PATAChannel::ata_read_sectors(u32 start_sector, u16 count, u8* outbuf, bool
return false;
for (int i = 0; i < count; i++) {
wait_400ns(m_io_base);
io_delay();
while (IO::in8(m_io_base + ATA_REG_STATUS) & ATA_SR_BSY)
;
@ -500,7 +497,7 @@ bool PATAChannel::ata_write_sectors(u32 start_sector, u16 count, const u8* inbuf
IO::out8(m_io_base + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
for (int i = 0; i < count; i++) {
wait_400ns(m_io_base);
io_delay();
while (IO::in8(m_io_base + ATA_REG_STATUS) & ATA_SR_BSY)
;

View File

@ -58,6 +58,7 @@ private:
// 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 };
volatile bool m_interrupted { false };