]> git.ipfire.org Git - thirdparty/linux.git/commit
ata: ahci: Do not read the per port area for unimplemented ports
authorNiklas Cassel <cassel@kernel.org>
Mon, 12 Jan 2026 12:20:46 +0000 (13:20 +0100)
committerDamien Le Moal <dlemoal@kernel.org>
Tue, 13 Jan 2026 13:00:02 +0000 (22:00 +0900)
commitea4d4ea6d10a561043922d285f1765c7e4bfd32a
tree44e76e0755ea6baf1e03fda82b6c68bf04053746
parent0f61b1860cc3f52aef9036d7235ed1f017632193
ata: ahci: Do not read the per port area for unimplemented ports

An AHCI HBA specifies the number of ports it supports using CAP.NP.
The HBA is free to only make a subset of the number of ports available
using the PI (Ports Implemented) register.

libata currently creates dummy ports for HBA ports that are provided by
the HBA, but which are marked as "unavailable" using the PI register.

Each port will have a per port area of registers in the HBA, regardless
if the port is marked as "unavailable" or not.

ahci_mark_external_port() currently reads this per port area of registers
using readl() to see if the port is marked as external/hotplug-capable.

However, AHCI 1.3.1, section "3.1.4 Offset 0Ch: PI – Ports Implemented"
states: "Software must not read or write to registers within unavailable
ports."

Thus, make sure that we only call ahci_mark_external_port() and
ahci_update_initial_lpm_policy() for ports that are implemented.

From a libata perspective, this should not change anything related to LPM,
as dummy ports do not provide any ap->ops (they do not have a .set_lpm()
callback), so even if EH were to call .set_lpm() on a dummy port, it was
already a no-op.

Fixes: f7131935238d ("ata: ahci: move marking of external port earlier")
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Tested-by: Wolf <wolf@yoxt.cc>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
drivers/ata/ahci.c