From da109eeab815261470bc1f2cc877dd1d0021b241 Mon Sep 17 00:00:00 2001 From: Liav A Date: Mon, 5 Apr 2021 21:24:05 +0300 Subject: [PATCH] Kernel/Storage: Wait a few microseconds after selecting the IDE drive We need to do it to let real hardware to put the correct voltages on the wire. Apparently my ICH7 machine refused to boot, and was reading lots of garbage from an unconnected IDE channel. It was fixed after I added a delay of 20 microseconds. It probably can be reduced, I just took a safe value and it seems to work correctly without any problems :) --- Kernel/Storage/IDEChannel.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Kernel/Storage/IDEChannel.cpp b/Kernel/Storage/IDEChannel.cpp index f8b7418130..14debe1dc7 100644 --- a/Kernel/Storage/IDEChannel.cpp +++ b/Kernel/Storage/IDEChannel.cpp @@ -288,8 +288,14 @@ UNMAP_AFTER_INIT void IDEChannel::detect_disks() // There are only two possible disks connected to a channel for (auto i = 0; i < 2; i++) { + // We need to select the drive and then we wait 20 microseconds... and it doesn't hurt anything so let's just do it. m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out(0xA0 | (i << 4)); // First, we need to select the drive itself + IO::delay(20); + m_io_group.io_base().offset(ATA_REG_SECCOUNT0).out(0); + m_io_group.io_base().offset(ATA_REG_LBA0).out(0); + m_io_group.io_base().offset(ATA_REG_LBA1).out(0); + m_io_group.io_base().offset(ATA_REG_LBA2).out(0); m_io_group.io_base().offset(ATA_REG_COMMAND).out(ATA_CMD_IDENTIFY); // Send the ATA_IDENTIFY command // Wait for the BSY flag to be reset @@ -389,7 +395,9 @@ void IDEChannel::ata_access(Direction direction, bool slave_request, u64 lba, u8 wait_until_not_busy(); + // We need to select the drive and then we wait 20 microseconds... and it doesn't hurt anything so let's just do it. m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out(0xE0 | (static_cast(slave_request) << 4) | head); + IO::delay(20); if (lba_mode == LBAMode::FortyEightBit) { m_io_group.io_base().offset(ATA_REG_SECCOUNT1).out(0);