[PATCH v2] ata: ahci: preserve preset port masks
From: zhoumin
Date: Thu Oct 15 2026 - 05:44:48 EST
ahci_get_port_mask() returns zero for absent or unmatched parameters,
overwriting the mask set by the Marvell PATA quirk.
Update the mask in place only when parsing a global value or a matching
device entry. Leave the mask unchanged on parsing errors.
Fixes: 70c1595c181c ("ata: ahci: Allow ignoring the external/hotplug capability of ports")
Suggested-by: Niklas Cassel <cassel@xxxxxxxxxx>
Signed-off-by: zhoumin <teczm@xxxxxxxxxxx>
---
Changes in v2:
- Leave the mask unchanged on parsing errors, as suggested by Niklas.
drivers/ata/ahci.c | 31 +++++++++++--------------------
1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 9b8c0935001c..fdce365969b4 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1642,34 +1642,27 @@ MODULE_PARM_DESC(mask_port_ext,
"where <pci_dev> is the PCI ID of an AHCI controller in the "
"form \"domain:bus:dev.func\"");
-static u32 ahci_port_mask(struct device *dev, char *mask_s)
+static void ahci_port_mask(struct device *dev, char *mask_s, u32 *mask)
{
- unsigned int mask;
-
- if (kstrtouint(mask_s, 0, &mask)) {
+ if (kstrtou32(mask_s, 0, mask))
dev_err(dev, "Invalid port map mask\n");
- return 0;
- }
-
- return mask;
}
-static u32 ahci_get_port_mask(struct device *dev, char *mask_p)
+static void ahci_get_port_mask(struct device *dev, char *mask_p, u32 *mask)
{
char *param, *end, *str, *mask_s;
char *name;
- u32 mask = 0;
if (!mask_p || !strlen(mask_p))
- return 0;
+ return;
str = kstrdup(mask_p, GFP_KERNEL);
if (!str)
- return 0;
+ return;
/* Handle single mask case */
if (!strchr(str, '=')) {
- mask = ahci_port_mask(dev, str);
+ ahci_port_mask(dev, str, mask);
goto free;
}
@@ -1704,13 +1697,11 @@ static u32 ahci_get_port_mask(struct device *dev, char *mask_p)
param++;
}
- mask = ahci_port_mask(dev, mask_s);
+ ahci_port_mask(dev, mask_s, mask);
}
free:
kfree(str);
-
- return mask;
}
static void ahci_pci_save_initial_config(struct pci_dev *pdev,
@@ -1736,10 +1727,10 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
}
/* Handle port map masks passed as module parameter. */
- hpriv->mask_port_map =
- ahci_get_port_mask(&pdev->dev, ahci_mask_port_map);
- hpriv->mask_port_ext =
- ahci_get_port_mask(&pdev->dev, ahci_mask_port_ext);
+ ahci_get_port_mask(&pdev->dev, ahci_mask_port_map,
+ &hpriv->mask_port_map);
+ ahci_get_port_mask(&pdev->dev, ahci_mask_port_ext,
+ &hpriv->mask_port_ext);
ahci_save_initial_config(&pdev->dev, hpriv);
}
--
2.53.0