summaryrefslogtreecommitdiff
path: root/Kernel/Storage/ATA
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-09-02 11:23:32 +0300
committerLinus Groh <mail@linusgroh.de>2022-09-20 18:43:05 +0100
commit84fbab6803bcb6ed02335a9b9bf83545a18cf4a4 (patch)
treeac231cce6bf7a3e952efc1dea35dbb73c2ae85db /Kernel/Storage/ATA
parentcac72259d00fecb9b638adab2c32fc2c5943e1da (diff)
downloadserenity-84fbab6803bcb6ed02335a9b9bf83545a18cf4a4.zip
Kernel: Move IO delay code to x86 architecture subdirectory
Many code patterns and hardware procedures rely on reliable delay in the microseconds granularity, and since they are using such delays which are valid cases, but should not rely on x86 specific code, we allow to determine in compile time the proper platform-specific code to use to invoke such delays.
Diffstat (limited to 'Kernel/Storage/ATA')
-rw-r--r--Kernel/Storage/ATA/AHCI/Controller.cpp3
-rw-r--r--Kernel/Storage/ATA/AHCI/Port.cpp9
-rw-r--r--Kernel/Storage/ATA/ATAPort.cpp4
-rw-r--r--Kernel/Storage/ATA/GenericIDE/Channel.cpp21
4 files changed, 20 insertions, 17 deletions
diff --git a/Kernel/Storage/ATA/AHCI/Controller.cpp b/Kernel/Storage/ATA/AHCI/Controller.cpp
index 6b375ecdeb..d05f1c8e91 100644
--- a/Kernel/Storage/ATA/AHCI/Controller.cpp
+++ b/Kernel/Storage/ATA/AHCI/Controller.cpp
@@ -8,6 +8,7 @@
#include <AK/BuiltinWrappers.h>
#include <AK/OwnPtr.h>
#include <AK/Types.h>
+#include <Kernel/Arch/Delay.h>
#include <Kernel/Bus/PCI/API.h>
#include <Kernel/CommandLine.h>
#include <Kernel/Library/LockRefPtr.h>
@@ -42,7 +43,7 @@ bool AHCIController::reset()
return false;
if (!(hba().control_regs.ghc & 1))
break;
- IO::delay(1000);
+ microseconds_delay(1000);
retry++;
}
// Note: Turn on AHCI HBA and Global HBA Interrupts.
diff --git a/Kernel/Storage/ATA/AHCI/Port.cpp b/Kernel/Storage/ATA/AHCI/Port.cpp
index aff473adc8..776d1d125e 100644
--- a/Kernel/Storage/ATA/AHCI/Port.cpp
+++ b/Kernel/Storage/ATA/AHCI/Port.cpp
@@ -8,6 +8,7 @@
// please look at Documentation/Kernel/AHCILocking.md
#include <AK/Atomic.h>
+#include <Kernel/Arch/Delay.h>
#include <Kernel/Locking/Spinlock.h>
#include <Kernel/Memory/MemoryManager.h>
#include <Kernel/Memory/ScatterGatherList.h>
@@ -552,7 +553,7 @@ bool AHCIPort::spin_until_ready() const
size_t spin = 0;
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Spinning until ready.", representative_port_index());
while ((m_port_registers.tfd & (ATA_SR_BSY | ATA_SR_DRQ)) && spin <= 100) {
- IO::delay(1000);
+ microseconds_delay(1000);
spin++;
}
if (spin == 100) {
@@ -719,7 +720,7 @@ bool AHCIPort::identify_device()
success = true;
break;
}
- IO::delay(1000); // delay with 1 milliseconds
+ microseconds_delay(1000); // delay with 1 milliseconds
time_elapsed++;
}
@@ -739,7 +740,7 @@ void AHCIPort::wait_until_condition_met_or_timeout(size_t delay_in_microseconds,
while (retry < retries) {
if (condition_being_met())
break;
- IO::delay(delay_in_microseconds);
+ microseconds_delay(delay_in_microseconds);
retry++;
}
}
@@ -852,7 +853,7 @@ bool AHCIPort::initiate_sata_reset()
full_memory_barrier();
set_interface_state(AHCI::DeviceDetectionInitialization::PerformInterfaceInitializationSequence);
// The AHCI specification says to wait now a 1 millisecond
- IO::delay(1000);
+ microseconds_delay(1000);
full_memory_barrier();
set_interface_state(AHCI::DeviceDetectionInitialization::NoActionRequested);
full_memory_barrier();
diff --git a/Kernel/Storage/ATA/ATAPort.cpp b/Kernel/Storage/ATA/ATAPort.cpp
index 7f89a9d64c..99e0838f21 100644
--- a/Kernel/Storage/ATA/ATAPort.cpp
+++ b/Kernel/Storage/ATA/ATAPort.cpp
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
-#include <Kernel/Arch/x86/IO.h>
+#include <Kernel/Arch/Delay.h>
#include <Kernel/Storage/ATA/ATADiskDevice.h>
#include <Kernel/Storage/ATA/ATAPort.h>
#include <Kernel/Storage/ATA/Definitions.h>
@@ -499,7 +499,7 @@ ErrorOr<void> ATAPort::execute_polled_command(TransactionDirection direction, LB
break;
}
- IO::delay(1000);
+ microseconds_delay(1000);
milliseconds_elapsed++;
}
if (milliseconds_elapsed > completion_timeout_in_milliseconds) {
diff --git a/Kernel/Storage/ATA/GenericIDE/Channel.cpp b/Kernel/Storage/ATA/GenericIDE/Channel.cpp
index c89ef74d6f..feda770ba2 100644
--- a/Kernel/Storage/ATA/GenericIDE/Channel.cpp
+++ b/Kernel/Storage/ATA/GenericIDE/Channel.cpp
@@ -7,6 +7,7 @@
#include <AK/ByteBuffer.h>
#include <AK/Singleton.h>
#include <AK/StringView.h>
+#include <Kernel/Arch/Delay.h>
#include <Kernel/Arch/x86/IO.h>
#include <Kernel/Bus/PCI/API.h>
#include <Kernel/Memory/MemoryManager.h>
@@ -44,13 +45,13 @@ StringView IDEChannel::channel_type_string() const
bool IDEChannel::select_device_and_wait_until_not_busy(DeviceType device_type, size_t milliseconds_timeout)
{
- IO::delay(20);
+ microseconds_delay(20);
u8 slave = device_type == DeviceType::Slave;
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(0xA0 | (slave << 4)); // First, we need to select the drive itself
- IO::delay(20);
+ microseconds_delay(20);
size_t time_elapsed = 0;
while (m_io_group.control_base().in<u8>() & ATA_SR_BSY && time_elapsed <= milliseconds_timeout) {
- IO::delay(1000);
+ microseconds_delay(1000);
time_elapsed++;
}
return time_elapsed <= milliseconds_timeout;
@@ -63,10 +64,10 @@ ErrorOr<void> IDEChannel::port_phy_reset()
// reset the channel
u8 device_control = m_io_group.control_base().in<u8>();
// Wait 30 milliseconds
- IO::delay(30000);
+ microseconds_delay(30000);
m_io_group.control_base().out<u8>(device_control | (1 << 2));
// Wait 30 milliseconds
- IO::delay(30000);
+ microseconds_delay(30000);
m_io_group.control_base().out<u8>(device_control);
// Wait up to 30 seconds before failing
if (!select_device_and_wait_until_not_busy(DeviceType::Master, 30000)) {
@@ -220,7 +221,7 @@ ErrorOr<void> IDEChannel::wait_if_busy_until_timeout(size_t timeout_in_milliseco
{
size_t time_elapsed = 0;
while (m_io_group.control_base().in<u8>() & ATA_SR_BSY && time_elapsed <= timeout_in_milliseconds) {
- IO::delay(1000);
+ microseconds_delay(1000);
time_elapsed++;
}
if (time_elapsed <= timeout_in_milliseconds)
@@ -249,7 +250,7 @@ ErrorOr<void> IDEChannel::load_taskfile_into_registers(ATAPort::TaskFile const&
// Note: Preserve the selected drive, always use LBA addressing
auto driver_register = ((m_io_group.io_base().offset(ATA_REG_HDDEVSEL).in<u8>() & (1 << 4)) | (head | (1 << 5) | (1 << 6)));
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(driver_register);
- IO::delay(50);
+ microseconds_delay(50);
if (lba_mode == LBAMode::FortyEightBit) {
m_io_group.io_base().offset(ATA_REG_SECCOUNT1).out<u8>((task_file.count >> 8) & 0xFF);
@@ -272,7 +273,7 @@ ErrorOr<void> IDEChannel::load_taskfile_into_registers(ATAPort::TaskFile const&
auto status = m_io_group.control_base().in<u8>();
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY))
break;
- IO::delay(1000);
+ microseconds_delay(1000);
time_elapsed++;
}
m_io_group.io_base().offset(ATA_REG_COMMAND).out<u8>(task_file.command);
@@ -284,9 +285,9 @@ ErrorOr<void> IDEChannel::device_select(size_t device_index)
VERIFY(m_lock.is_locked());
if (device_index > 1)
return Error::from_errno(EINVAL);
- IO::delay(20);
+ microseconds_delay(20);
m_io_group.io_base().offset(ATA_REG_HDDEVSEL).out<u8>(0xA0 | ((device_index) << 4));
- IO::delay(20);
+ microseconds_delay(20);
return {};
}