mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 08:25:07 +00:00

We do that to increase clarity of the major and secondary components in the subsystem. To ensure it's even more understandable, we rename the files to better represent the class within them and to remove redundancy in the name. Also, some includes are removed from the general components of the ATA components' classes.
55 lines
1.9 KiB
C++
55 lines
1.9 KiB
C++
/*
|
|
* Copyright (c) 2021-2022, Liav A. <liavalb@hotmail.co.il>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/Storage/ATA/AHCI/InterruptHandler.h>
|
|
|
|
namespace Kernel {
|
|
|
|
UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<AHCIInterruptHandler>> AHCIInterruptHandler::create(AHCIController& controller, u8 irq, AHCI::MaskedBitField taken_ports)
|
|
{
|
|
auto port_handler = TRY(adopt_nonnull_own_or_enomem(new (nothrow) AHCIInterruptHandler(controller, irq, taken_ports)));
|
|
port_handler->allocate_resources_and_initialize_ports();
|
|
return port_handler;
|
|
}
|
|
|
|
void AHCIInterruptHandler::allocate_resources_and_initialize_ports()
|
|
{
|
|
// Clear pending interrupts, if there are any!
|
|
m_pending_ports_interrupts.set_all();
|
|
enable_irq();
|
|
}
|
|
|
|
UNMAP_AFTER_INIT AHCIInterruptHandler::AHCIInterruptHandler(AHCIController& controller, u8 irq, AHCI::MaskedBitField taken_ports)
|
|
: IRQHandler(irq)
|
|
, m_parent_controller(controller)
|
|
, m_taken_ports(taken_ports)
|
|
, m_pending_ports_interrupts(create_pending_ports_interrupts_bitfield())
|
|
{
|
|
dbgln_if(AHCI_DEBUG, "AHCI Port Handler: IRQ {}", irq);
|
|
}
|
|
|
|
AHCI::MaskedBitField AHCIInterruptHandler::create_pending_ports_interrupts_bitfield() const
|
|
{
|
|
return AHCI::MaskedBitField((u32 volatile&)m_parent_controller->hba().control_regs.is, m_taken_ports.bit_mask());
|
|
}
|
|
|
|
AHCIInterruptHandler::~AHCIInterruptHandler() = default;
|
|
|
|
bool AHCIInterruptHandler::handle_irq(RegisterState const&)
|
|
{
|
|
dbgln_if(AHCI_DEBUG, "AHCI Port Handler: IRQ received");
|
|
if (m_pending_ports_interrupts.is_zeroed())
|
|
return false;
|
|
for (auto port_index : m_pending_ports_interrupts.to_vector()) {
|
|
dbgln_if(AHCI_DEBUG, "AHCI Port Handler: Handling IRQ for port {}", port_index);
|
|
m_parent_controller->handle_interrupt_for_port({}, port_index);
|
|
// We do this to clear the pending interrupt after we handled it.
|
|
m_pending_ports_interrupts.set_at(port_index);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
}
|