diff options
Diffstat (limited to 'Kernel/Storage/IDEChannel.cpp')
-rw-r--r-- | Kernel/Storage/IDEChannel.cpp | 87 |
1 files changed, 41 insertions, 46 deletions
diff --git a/Kernel/Storage/IDEChannel.cpp b/Kernel/Storage/IDEChannel.cpp index 6127124b9a..e7dc66846c 100644 --- a/Kernel/Storage/IDEChannel.cpp +++ b/Kernel/Storage/IDEChannel.cpp @@ -292,8 +292,6 @@ void IDEChannel::handle_irq(const RegisterState&) return; } - bool received_all_irqs = m_current_request_uses_dma || m_current_request_block_index + 1 >= m_current_request->block_count(); - if (status & ATA_SR_ERR) { print_ide_status(status); m_device_error = m_io_group.io_base().offset(ATA_REG_ERROR).in<u8>(); @@ -302,45 +300,44 @@ void IDEChannel::handle_irq(const RegisterState&) complete_current_request(AsyncDeviceRequest::Failure); return; } - m_device_error = 0; - if (received_all_irqs) { + if (m_current_request_uses_dma) { complete_current_request(AsyncDeviceRequest::Success); - } else { - ASSERT(!m_current_request_uses_dma); - - // Now schedule reading/writing the buffer as soon as we leave the irq handler. - // This is important so that we can safely access the buffers, which could - // trigger page faults - Processor::deferred_call_queue([this]() { - if (m_current_request->request_type() == AsyncBlockDeviceRequest::Read) { - dbgln("IDEChannel: Read block {}/{}", m_current_request_block_index, m_current_request->block_count()); - if (ata_do_read_sector()) { - if (++m_current_request_block_index >= m_current_request->block_count()) { - complete_current_request(AsyncDeviceRequest::Success); - return; - } - // Wait for the next block - enable_irq(); + return; + } + + // Now schedule reading/writing the buffer as soon as we leave the irq handler. + // This is important so that we can safely access the buffers, which could + // trigger page faults + Processor::deferred_call_queue([this]() { + ScopedSpinLock lock(m_request_lock); + if (m_current_request->request_type() == AsyncBlockDeviceRequest::Read) { + dbgln<PATA_DEBUG>("IDEChannel: Read block {}/{}", m_current_request_block_index, m_current_request->block_count()); + if (ata_do_read_sector()) { + if (++m_current_request_block_index >= m_current_request->block_count()) { + complete_current_request(AsyncDeviceRequest::Success); + return; } - } else { - if (!m_current_request_flushing_cache) { - dbgln("IDEChannel: Wrote block {}/{}", m_current_request_block_index, m_current_request->block_count()); - if (++m_current_request_block_index >= m_current_request->block_count()) { - // We read the last block, flush cache - ASSERT(!m_current_request_flushing_cache); - m_current_request_flushing_cache = true; - m_io_group.io_base().offset(ATA_REG_COMMAND).out<u8>(ATA_CMD_CACHE_FLUSH); - } else { - // Read next block - ata_do_write_sector(); - } + // Wait for the next block + enable_irq(); + } + } else { + if (!m_current_request_flushing_cache) { + dbgln<PATA_DEBUG>("IDEChannel: Wrote block {}/{}", m_current_request_block_index, m_current_request->block_count()); + if (++m_current_request_block_index >= m_current_request->block_count()) { + // We read the last block, flush cache + ASSERT(!m_current_request_flushing_cache); + m_current_request_flushing_cache = true; + m_io_group.io_base().offset(ATA_REG_COMMAND).out<u8>(ATA_CMD_CACHE_FLUSH); } else { - complete_current_request(AsyncDeviceRequest::Success); + // Read next block + ata_do_write_sector(); } + } else { + complete_current_request(AsyncDeviceRequest::Success); } - }); - } + } + }); } static void io_delay() @@ -351,7 +348,7 @@ static void io_delay() void IDEChannel::wait_until_not_busy() { - while (m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>() & ATA_SR_BSY) + while (m_io_group.control_base().in<u8>() & ATA_SR_BSY) ; } @@ -379,10 +376,10 @@ void IDEChannel::detect_disks() m_io_group.io_base().offset(ATA_REG_COMMAND).out<u8>(ATA_CMD_IDENTIFY); // Send the ATA_IDENTIFY command // Wait for the BSY flag to be reset - while (m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>() & ATA_SR_BSY) + while (m_io_group.control_base().in<u8>() & ATA_SR_BSY) ; - if (m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>() == 0x00) { + if (m_io_group.control_base().in<u8>() == 0x00) { dbgln<PATA_DEBUG>("IDEChannel: No {} {} disk detected!", channel_type_string().to_lowercase(), channel_string(i)); continue; } @@ -391,7 +388,7 @@ void IDEChannel::detect_disks() PATADiskDevice::InterfaceType interface_type = PATADiskDevice::InterfaceType::ATA; for (;;) { - u8 status = m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>(); + u8 status = m_io_group.control_base().in<u8>(); if (status & ATA_SR_ERR) { dbgln<PATA_DEBUG>("IDEChannel: {} {} device is not ATA. Will check for ATAPI.", channel_type_string(), channel_string(i)); check_for_atapi = true; @@ -499,7 +496,7 @@ void IDEChannel::ata_access(Direction direction, bool slave_request, u32 lba, u8 } for (;;) { - auto status = m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>(); + auto status = m_io_group.control_base().in<u8>(); if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break; } @@ -515,7 +512,6 @@ void IDEChannel::ata_access(Direction direction, bool slave_request, u32 lba, u8 else m_io_group.io_base().offset(ATA_REG_COMMAND).out<u8>(direction == Direction::Read ? ATA_CMD_READ_PIO_EXT : ATA_CMD_WRITE_PIO_EXT); } - enable_irq(); } @@ -550,6 +546,7 @@ void IDEChannel::ata_read_sectors_with_dma(bool slave_request, u16 capabilities) bool IDEChannel::ata_do_read_sector() { + dbgln<PATA_DEBUG>("IDEChannel::ata_do_read_sector"); auto& request = *m_current_request; auto out_buffer = request.buffer().offset(m_current_request_block_index * 512); ssize_t nwritten = request.write_to_buffer_buffered<512>(out_buffer, 512, [&](u8* buffer, size_t buffer_bytes) { @@ -576,7 +573,6 @@ void IDEChannel::ata_read_sectors(bool slave_request, u16 capabilities) dbgln<PATA_DEBUG>("IDEChannel: Reading {} sector(s) @ LBA {}", request.block_count(), lba); ata_access(Direction::Read, slave_request, lba, request.block_count(), capabilities, false); - ata_do_read_sector(); } void IDEChannel::ata_write_sectors_with_dma(bool slave_request, u16 capabilities) @@ -615,10 +611,10 @@ void IDEChannel::ata_do_write_sector() auto& request = *m_current_request; io_delay(); - while ((m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>() & ATA_SR_BSY) || !(m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>() & ATA_SR_DRQ)) + while ((m_io_group.control_base().in<u8>() & ATA_SR_BSY) || !(m_io_group.control_base().in<u8>() & ATA_SR_DRQ)) ; - u8 status = m_io_group.io_base().offset(ATA_REG_STATUS).in<u8>(); + u8 status = m_io_group.control_base().in<u8>(); ASSERT(status & ATA_SR_DRQ); auto in_buffer = request.buffer().offset(m_current_request_block_index * 512); @@ -642,8 +638,7 @@ void IDEChannel::ata_write_sectors(bool slave_request, u16 capabilities) u32 count = request.block_count(); dbgln<PATA_DEBUG>("IDEChannel: Writing {} sector(s) @ LBA {}", count, start_sector); - ata_access(Direction::Write, slave_request, start_sector, request.block_count(), capabilities, true); + ata_access(Direction::Write, slave_request, start_sector, request.block_count(), capabilities, false); ata_do_write_sector(); } - } |