kernel/ATA: Handle drive IRQs in compatibility mode

This commit is contained in:
apio 2023-05-13 14:24:45 +02:00
parent 739950e8f0
commit ee691bbb0f
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 34 additions and 0 deletions

View File

@ -5,6 +5,11 @@
SharedPtr<ATA::Controller> g_controller;
static void irq_handler(Registers* regs, void* ctx)
{
((ATA::Channel*)ctx)->irq_handler(regs);
}
namespace ATA
{
Result<void> Controller::scan()
@ -85,6 +90,22 @@ namespace ATA
m_current_drive = drive;
}
void Channel::irq_handler(Registers*)
{
// FIXME: Read the Busmaster register to make sure the IRQ is for this channel.
// FIXME: Also read it in case there was a DMA read error.
m_thread->wake_up();
}
void Channel::wait_for_irq()
{
m_thread = Scheduler::current();
kernel_wait_for_event();
}
bool Channel::initialize()
{
int offset = m_channel_index ? 2 : 0;
@ -113,6 +134,14 @@ namespace ATA
else
m_interrupt_line = m_channel_index ? 15 : 14;
bool ok = CPU::register_interrupt(m_interrupt_line, ::irq_handler, this);
if (!ok)
{
kerrorln("ata: Failed to register IRQ handler for ATA channel %d (IRQ %d)", m_channel_index,
m_interrupt_line);
return false;
}
for (u8 drive = 0; drive < 2; drive++)
{
ScopedKMutexLock<100> lock(m_lock);

View File

@ -52,6 +52,9 @@ namespace ATA
void delay_400ns();
void wait_for_irq();
void irq_handler(Registers*);
void select(u8 drive);
bool initialize();
@ -65,6 +68,8 @@ namespace ATA
KMutex<100> m_lock {};
Thread* m_thread;
u16 m_io_base;
u16 m_control_base;