Skip to content

Commit ea4d4ea

Browse files
floatiousdamien-lemoal
authored andcommitted
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: f713193 ("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>
1 parent 0f61b18 commit ea4d4ea

1 file changed

Lines changed: 5 additions & 5 deletions

File tree

drivers/ata/ahci.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,13 +2094,13 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
20942094
if (ap->flags & ATA_FLAG_EM)
20952095
ap->em_message_type = hpriv->em_msg_type;
20962096

2097-
ahci_mark_external_port(ap);
2098-
2099-
ahci_update_initial_lpm_policy(ap);
2100-
21012097
/* disabled/not-implemented port */
2102-
if (!(hpriv->port_map & (1 << i)))
2098+
if (!(hpriv->port_map & (1 << i))) {
21032099
ap->ops = &ata_dummy_port_ops;
2100+
} else {
2101+
ahci_mark_external_port(ap);
2102+
ahci_update_initial_lpm_policy(ap);
2103+
}
21042104
}
21052105

21062106
/* apply workaround for ASUS P5W DH Deluxe mainboard */

0 commit comments

Comments
 (0)