From 014c29a8e3bdcaad8c6fdfcf1af2fdbbab3fc323 Mon Sep 17 00:00:00 2001 From: zhoumin Date: Thu, 15 Oct 2026 17:41:02 +0800 Subject: [PATCH] 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: 70c1595c181c ("ata: ahci: Allow ignoring the external/hotplug capability of ports") Suggested-by: Niklas Cassel Signed-off-by: zhoumin Link: https://lore.kernel.org/r/tencent_26064A115A53E4C6D00433C89E1894E2D808@qq.com Signed-off-by: Niklas Cassel --- 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 4466191dd7f6..3c38ee3314ee 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1625,34 +1625,27 @@ MODULE_PARM_DESC(mask_port_ext, "where 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); }