1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 23:47:45 +00:00

Kernel/Storage: Move Identify page allocation to the AHCIPort class

Instead of doing this in a parent class like the AHCIController, let's
do that directly in the AHCIPort class as that class is the only user of
these sort of physical pages. While it seems like we waste an entire 4KB
of physical RAM for each allocation, this could serve us later on if we
want to fetch other types of logs from the ATA device.
This commit is contained in:
Liav A 2022-04-02 01:47:44 +03:00 committed by Idan Horowitz
parent bf82c4b81b
commit 4d36989954
4 changed files with 14 additions and 21 deletions

View file

@ -22,7 +22,8 @@ namespace Kernel {
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<AHCIPort>> AHCIPort::create(AHCIController const& controller, AHCI::HBADefinedCapabilities hba_capabilities, volatile AHCI::PortRegisters& registers, u32 port_index)
{
auto port = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AHCIPort(controller, hba_capabilities, registers, port_index)));
auto identify_buffer_page = MUST(MM.allocate_supervisor_physical_page());
auto port = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AHCIPort(controller, move(identify_buffer_page), hba_capabilities, registers, port_index)));
TRY(port->allocate_resources_and_initialize_ports());
return port;
}
@ -53,9 +54,10 @@ ErrorOr<void> AHCIPort::allocate_resources_and_initialize_ports()
return {};
}
UNMAP_AFTER_INIT AHCIPort::AHCIPort(AHCIController const& controller, AHCI::HBADefinedCapabilities hba_capabilities, volatile AHCI::PortRegisters& registers, u32 port_index)
UNMAP_AFTER_INIT AHCIPort::AHCIPort(AHCIController const& controller, NonnullRefPtr<Memory::PhysicalPage> identify_buffer_page, AHCI::HBADefinedCapabilities hba_capabilities, volatile AHCI::PortRegisters& registers, u32 port_index)
: m_port_index(port_index)
, m_hba_capabilities(hba_capabilities)
, m_identify_buffer_page(move(identify_buffer_page))
, m_port_registers(registers)
, m_parent_controller(controller)
, m_interrupt_status((u32 volatile&)m_port_registers.is)
@ -326,12 +328,9 @@ bool AHCIPort::initialize()
size_t logical_sector_size = 512;
size_t physical_sector_size = 512;
u64 max_addressable_sector = 0;
RefPtr<AHCIController> controller = m_parent_controller.strong_ref();
if (!controller)
return false;
if (identify_device()) {
auto identify_block = Memory::map_typed<ATAIdentifyBlock>(controller->get_identify_metadata_physical_region({}, m_port_index)).release_value_but_fixme_should_propagate_errors();
auto identify_block = Memory::map_typed<ATAIdentifyBlock>(m_identify_buffer_page->paddr()).release_value_but_fixme_should_propagate_errors();
// Check if word 106 is valid before using it!
if ((identify_block->physical_sector_size_to_logical_sector_size >> 14) == 1) {
if (identify_block->physical_sector_size_to_logical_sector_size & (1 << 12)) {
@ -356,6 +355,11 @@ bool AHCIPort::initialize()
// FIXME: We don't support ATAPI devices yet, so for now we don't "create" them
if (!is_atapi_attached()) {
RefPtr<AHCIController> controller = m_parent_controller.strong_ref();
if (!controller) {
dmesgln("AHCI Port {}: Device found, but parent controller is not available, abort.", representative_port_index());
return false;
}
m_connected_device = ATADiskDevice::create(*controller, { m_port_index, 0 }, 0, logical_sector_size, max_addressable_sector);
} else {
dbgln("AHCI Port {}: Ignoring ATAPI devices for now as we don't currently support them.", representative_port_index());
@ -678,7 +682,7 @@ bool AHCIPort::identify_device()
auto& command_table = *(volatile AHCI::CommandTable*)command_table_region->vaddr().as_ptr();
memset(const_cast<u8*>(command_table.command_fis), 0, 64);
command_table.descriptors[0].base_high = 0;
command_table.descriptors[0].base_low = controller->get_identify_metadata_physical_region({}, m_port_index).get();
command_table.descriptors[0].base_low = m_identify_buffer_page->paddr().get();
command_table.descriptors[0].byte_count = 512 - 1;
auto& fis = *(volatile FIS::HostToDevice::Register*)command_table.command_fis;
fis.header.fis_type = (u8)FIS::Type::RegisterHostToDevice;