mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:27:43 +00:00
Kernel/Storage: Simplify AHCIPortHandler class
The way AHCIPortHandler held AHCIPorts and even provided them with physical pages for the ATA identify buffer just felt wrong. To fix this, AHCIPortHandler is not a ref-counted object anymore. This solves the big part of the problem, because AHCIPorts can't hold a reference to this object anymore, only the AHCIController can do that. Then, most of the responsibilities are shifted to the AHCIController, making the AHCIPortHandler a handler of port interrupts only.
This commit is contained in:
parent
4169ac4a7b
commit
cc734c106e
6 changed files with 98 additions and 109 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||
* Copyright (c) 2021-2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -10,6 +10,7 @@
|
|||
#include <AK/RefPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Bus/PCI/API.h>
|
||||
#include <Kernel/CommandLine.h>
|
||||
#include <Kernel/Memory/MemoryManager.h>
|
||||
#include <Kernel/Storage/ATA/AHCIController.h>
|
||||
#include <Kernel/Storage/ATA/AHCIPortHandler.h>
|
||||
|
@ -52,20 +53,16 @@ bool AHCIController::shutdown()
|
|||
size_t AHCIController::devices_count() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (auto& port_handler : m_handlers) {
|
||||
port_handler.enumerate_ports([&](AHCIPort const& port) {
|
||||
if (port.connected_device())
|
||||
count++;
|
||||
});
|
||||
for (auto port : m_ports) {
|
||||
if (port && port->connected_device())
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void AHCIController::start_request(ATADevice const& device, AsyncBlockDeviceRequest& request)
|
||||
{
|
||||
// FIXME: For now we have one port handler, check all of them...
|
||||
VERIFY(m_handlers.size() > 0);
|
||||
auto port = m_handlers[0].port_at_index(device.ata_address().port);
|
||||
auto port = m_ports[device.ata_address().port];
|
||||
VERIFY(port);
|
||||
port->start_request(request);
|
||||
}
|
||||
|
@ -90,10 +87,16 @@ UNMAP_AFTER_INIT AHCIController::AHCIController(PCI::DeviceIdentifier const& pci
|
|||
: ATAController()
|
||||
, PCI::Device(pci_device_identifier.address())
|
||||
, m_hba_region(default_hba_region())
|
||||
, m_capabilities(capabilities())
|
||||
, m_hba_capabilities(capabilities())
|
||||
{
|
||||
}
|
||||
|
||||
PhysicalAddress AHCIController::get_identify_metadata_physical_region(Badge<AHCIPort>, u32 port_index) const
|
||||
{
|
||||
dbgln_if(AHCI_DEBUG, "AHCI Controller @ {}: Get identify metadata physical address of port {} - {}", pci_address(), port_index, (port_index * 512) / PAGE_SIZE);
|
||||
return m_identify_metadata_pages[(port_index * 512) / PAGE_SIZE].paddr().offset((port_index * 512) % PAGE_SIZE);
|
||||
}
|
||||
|
||||
AHCI::HBADefinedCapabilities AHCIController::capabilities() const
|
||||
{
|
||||
u32 capabilities = hba().control_regs.cap;
|
||||
|
@ -145,7 +148,7 @@ UNMAP_AFTER_INIT void AHCIController::initialize_hba(PCI::DeviceIdentifier const
|
|||
return;
|
||||
}
|
||||
dmesgln("{}: AHCI controller reset", pci_address());
|
||||
dbgln("{}: AHCI command list entries count - {}", pci_address(), hba_capabilities().max_command_list_entries_count);
|
||||
dbgln("{}: AHCI command list entries count - {}", pci_address(), m_hba_capabilities.max_command_list_entries_count);
|
||||
|
||||
u32 version = hba().control_regs.version;
|
||||
dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Version = {:#08x}", pci_address(), version);
|
||||
|
@ -155,8 +158,34 @@ UNMAP_AFTER_INIT void AHCIController::initialize_hba(PCI::DeviceIdentifier const
|
|||
PCI::enable_bus_mastering(pci_address());
|
||||
enable_global_interrupts();
|
||||
|
||||
auto port_handler = AHCIPortHandler::create(*this, pci_device_identifier.interrupt_line().value(), AHCI::MaskedBitField((u32 volatile&)(hba().control_regs.pi))).release_value_but_fixme_should_propagate_errors();
|
||||
m_handlers.append(move(port_handler));
|
||||
auto implemented_ports = AHCI::MaskedBitField((u32 volatile&)(hba().control_regs.pi));
|
||||
m_irq_handler = AHCIPortHandler::create(*this, pci_device_identifier.interrupt_line().value(), implemented_ports).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
// FIXME: Use the number of ports to determine how many pages we should allocate.
|
||||
for (size_t index = 0; index < (((size_t)AHCI::Limits::MaxPorts * 512) / PAGE_SIZE); index++) {
|
||||
m_identify_metadata_pages.append(MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
if (kernel_command_line().ahci_reset_mode() == AHCIResetMode::Aggressive) {
|
||||
for (auto index : implemented_ports.to_vector()) {
|
||||
auto port = AHCIPort::create(*this, m_hba_capabilities, static_cast<volatile AHCI::PortRegisters&>(hba().port_regs[index]), index).release_value_but_fixme_should_propagate_errors();
|
||||
m_ports[index] = port;
|
||||
port->reset();
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (auto index : implemented_ports.to_vector()) {
|
||||
auto port = AHCIPort::create(*this, m_hba_capabilities, static_cast<volatile AHCI::PortRegisters&>(hba().port_regs[index]), index).release_value_but_fixme_should_propagate_errors();
|
||||
m_ports[index] = port;
|
||||
port->initialize_without_reset();
|
||||
}
|
||||
}
|
||||
|
||||
void AHCIController::handle_interrupt_for_port(Badge<AHCIPortHandler>, u32 port_index) const
|
||||
{
|
||||
auto port = m_ports[port_index];
|
||||
VERIFY(port);
|
||||
port->handle_interrupt();
|
||||
}
|
||||
|
||||
void AHCIController::disable_global_interrupts() const
|
||||
|
@ -170,16 +199,10 @@ void AHCIController::enable_global_interrupts() const
|
|||
|
||||
RefPtr<StorageDevice> AHCIController::device_by_port(u32 port_index) const
|
||||
{
|
||||
for (auto& port_handler : m_handlers) {
|
||||
if (!port_handler.is_responsible_for_port_index(port_index))
|
||||
continue;
|
||||
|
||||
auto port = port_handler.port_at_index(port_index);
|
||||
if (!port)
|
||||
return nullptr;
|
||||
return port->connected_device();
|
||||
}
|
||||
return nullptr;
|
||||
auto port = m_ports[port_index];
|
||||
if (!port)
|
||||
return {};
|
||||
return port->connected_device();
|
||||
}
|
||||
|
||||
RefPtr<StorageDevice> AHCIController::device(u32 index) const
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue