Kernel: Fix PATA reads without DMA

Apparently we need to poll the drive for its status after each sector we
read if we're not doing DMA. Previously we only did it at the start,
which resulted in every sector after the first in a batch having 12 bytes
of garbage on the end. This manifested as silent read corruption.
This commit is contained in:
Conrad Pankoff 2019-08-11 14:55:53 +10:00 committed by Andreas Kling
parent d1a7316799
commit f6dd76b915
Notes: sideshowbarker 2024-07-19 12:45:48 +09:00

View file

@ -443,13 +443,21 @@ bool PATAChannel::ata_read_sectors(u32 start_sector, u16 count, u8* outbuf, bool
if (m_device_error)
return false;
u8 status = IO::in8(m_io_base + ATA_REG_STATUS);
ASSERT(status & ATA_SR_DRQ);
for (int i = 0; i < count; i++) {
wait_400ns(m_io_base);
while (IO::in8(m_io_base + ATA_REG_STATUS) & ATA_SR_BSY)
;
u8 status = IO::in8(m_io_base + ATA_REG_STATUS);
ASSERT(status & ATA_SR_DRQ);
#ifdef PATA_DEBUG
kprintf("Retrieving %u bytes (status=%b), outbuf=%p...\n", count * 512, status, outbuf);
kprintf("PATAChannel: Retrieving 512 bytes (part %d) (status=%b), outbuf=%p...\n", i, status, outbuf + (512 * i));
#endif
IO::repeated_in16(m_io_base + ATA_REG_DATA, outbuf, count * 256);
IO::repeated_in16(m_io_base + ATA_REG_DATA, outbuf + (512 * i), 256);
}
return true;
}