ata: ahci: preserve preset port masks

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: 70c1595c18 ("ata: ahci: Allow ignoring the external/hotplug capability of ports")
Suggested-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: zhoumin <teczm@foxmail.com>
Link: https://lore.kernel.org/r/tencent_26064A115A53E4C6D00433C89E1894E2D808@qq.com
Signed-off-by: Niklas Cassel <cassel@kernel.org>
This commit is contained in:
zhoumin 2026-10-15 17:41:02 +08:00 committed by Niklas Cassel
parent 4153718a21
commit 014c29a8e3

View File

@ -1625,34 +1625,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;
}
@ -1687,13 +1680,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,
@ -1719,10 +1710,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);
}