summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2021-03-19 03:08:23 +0200
committerAndreas Kling <kling@serenityos.org>2021-03-21 13:41:09 +0100
commit6c03fdc1ef07ca97c64c87d36dcfd8e5042bafa7 (patch)
tree19dec99fd52126929ab43c875aa03ae4a8ff7fca /Kernel
parent0b1fa97b30fe3f8941a92ebded9f7bc12367b508 (diff)
downloadserenity-6c03fdc1ef07ca97c64c87d36dcfd8e5042bafa7.zip
Kernel/AHCI: Don't set the PRDBC when accessing the device
This resulted in fatal error when trying to write to real hard drive I tested, so we only set the counts in the scatter/gather list later.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Storage/AHCIPort.cpp12
1 files changed, 10 insertions, 2 deletions
diff --git a/Kernel/Storage/AHCIPort.cpp b/Kernel/Storage/AHCIPort.cpp
index 70670cba3d..64638e17dd 100644
--- a/Kernel/Storage/AHCIPort.cpp
+++ b/Kernel/Storage/AHCIPort.cpp
@@ -536,7 +536,7 @@ bool AHCIPort::access_device(AsyncBlockDeviceRequest::RequestType direction, u64
auto* command_list_entries = (volatile AHCI::CommandHeader*)m_command_list_region->vaddr().as_ptr();
command_list_entries[unused_command_header.value()].ctba = m_command_table_pages[unused_command_header.value()].paddr().get();
command_list_entries[unused_command_header.value()].ctbau = 0;
- command_list_entries[unused_command_header.value()].prdbc = (block_count * m_connected_device->block_size());
+ command_list_entries[unused_command_header.value()].prdbc = 0;
command_list_entries[unused_command_header.value()].prdtl = m_current_scatter_list->scatters_count();
// Note: we must set the correct Dword count in this register. Real hardware
@@ -555,12 +555,20 @@ bool AHCIPort::access_device(AsyncBlockDeviceRequest::RequestType direction, u64
memset(const_cast<u8*>(command_table.command_fis), 0, 64);
size_t scatter_entry_index = 0;
+ size_t data_transfer_count = (block_count * m_connected_device->block_size());
for (auto scatter_page : m_current_scatter_list->vmobject().physical_pages()) {
+ VERIFY(data_transfer_count != 0);
VERIFY(scatter_page);
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Add a transfer scatter entry @ {}", representative_port_index(), scatter_page->paddr());
command_table.descriptors[scatter_entry_index].base_high = 0;
command_table.descriptors[scatter_entry_index].base_low = scatter_page->paddr().get();
- command_table.descriptors[scatter_entry_index].byte_count = PAGE_SIZE - 1;
+ if (data_transfer_count <= PAGE_SIZE) {
+ command_table.descriptors[scatter_entry_index].byte_count = data_transfer_count - 1;
+ data_transfer_count = 0;
+ } else {
+ command_table.descriptors[scatter_entry_index].byte_count = PAGE_SIZE - 1;
+ data_transfer_count -= PAGE_SIZE;
+ }
scatter_entry_index++;
}
command_table.descriptors[scatter_entry_index].byte_count = (PAGE_SIZE - 1) | (1 << 31);