Skip to content

Commit 2bd3731

Browse files
committed
Merge tag 'ata-6.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux
Pull ata fixes from Damien Le Moal: - Fix the type of return values to be signed in the ahci_xgen driver (Qianfeng) - Add the mask_port_ext module parameter to the ahci driver. This is to allow a user to ignore ports that are advertized as external (hotplug capable) in favor of lower link power management policies instead of the default max_performance for these ports. This is useful to allow e.g. laptops to go into low power states when hooked up to docking station with sata slots, connected with an external port for hotplug (me) * tag 'ata-6.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux: ata: ahci_xgene: Use int type for 'rc' to store error codes ata: ahci: Allow ignoring the external/hotplug capability of ports
2 parents 18ee2b9 + 82b8166 commit 2bd3731

File tree

3 files changed

+43
-22
lines changed

3 files changed

+43
-22
lines changed

drivers/ata/ahci.c

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -689,40 +689,50 @@ MODULE_PARM_DESC(mask_port_map,
689689
"where <pci_dev> is the PCI ID of an AHCI controller in the "
690690
"form \"domain:bus:dev.func\"");
691691

692-
static void ahci_apply_port_map_mask(struct device *dev,
693-
struct ahci_host_priv *hpriv, char *mask_s)
692+
static char *ahci_mask_port_ext;
693+
module_param_named(mask_port_ext, ahci_mask_port_ext, charp, 0444);
694+
MODULE_PARM_DESC(mask_port_ext,
695+
"32-bits mask to ignore the external/hotplug capability of ports. "
696+
"Valid values are: "
697+
"\"<mask>\" to apply the same mask to all AHCI controller "
698+
"devices, and \"<pci_dev>=<mask>,<pci_dev>=<mask>,...\" to "
699+
"specify different masks for the controllers specified, "
700+
"where <pci_dev> is the PCI ID of an AHCI controller in the "
701+
"form \"domain:bus:dev.func\"");
702+
703+
static u32 ahci_port_mask(struct device *dev, char *mask_s)
694704
{
695705
unsigned int mask;
696706

697707
if (kstrtouint(mask_s, 0, &mask)) {
698708
dev_err(dev, "Invalid port map mask\n");
699-
return;
709+
return 0;
700710
}
701711

702-
hpriv->mask_port_map = mask;
712+
return mask;
703713
}
704714

705-
static void ahci_get_port_map_mask(struct device *dev,
706-
struct ahci_host_priv *hpriv)
715+
static u32 ahci_get_port_mask(struct device *dev, char *mask_p)
707716
{
708717
char *param, *end, *str, *mask_s;
709718
char *name;
719+
u32 mask = 0;
710720

711-
if (!strlen(ahci_mask_port_map))
712-
return;
721+
if (!mask_p || !strlen(mask_p))
722+
return 0;
713723

714-
str = kstrdup(ahci_mask_port_map, GFP_KERNEL);
724+
str = kstrdup(mask_p, GFP_KERNEL);
715725
if (!str)
716-
return;
726+
return 0;
717727

718728
/* Handle single mask case */
719729
if (!strchr(str, '=')) {
720-
ahci_apply_port_map_mask(dev, hpriv, str);
730+
mask = ahci_port_mask(dev, str);
721731
goto free;
722732
}
723733

724734
/*
725-
* Mask list case: parse the parameter to apply the mask only if
735+
* Mask list case: parse the parameter to get the mask only if
726736
* the device name matches.
727737
*/
728738
param = str;
@@ -752,11 +762,13 @@ static void ahci_get_port_map_mask(struct device *dev,
752762
param++;
753763
}
754764

755-
ahci_apply_port_map_mask(dev, hpriv, mask_s);
765+
mask = ahci_port_mask(dev, mask_s);
756766
}
757767

758768
free:
759769
kfree(str);
770+
771+
return mask;
760772
}
761773

762774
static void ahci_pci_save_initial_config(struct pci_dev *pdev,
@@ -782,8 +794,10 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
782794
}
783795

784796
/* Handle port map masks passed as module parameter. */
785-
if (ahci_mask_port_map)
786-
ahci_get_port_map_mask(&pdev->dev, hpriv);
797+
hpriv->mask_port_map =
798+
ahci_get_port_mask(&pdev->dev, ahci_mask_port_map);
799+
hpriv->mask_port_ext =
800+
ahci_get_port_mask(&pdev->dev, ahci_mask_port_ext);
787801

788802
ahci_save_initial_config(&pdev->dev, hpriv);
789803
}
@@ -1757,11 +1771,20 @@ static void ahci_mark_external_port(struct ata_port *ap)
17571771
void __iomem *port_mmio = ahci_port_base(ap);
17581772
u32 tmp;
17591773

1760-
/* mark external ports (hotplug-capable, eSATA) */
1774+
/*
1775+
* Mark external ports (hotplug-capable, eSATA), unless we were asked to
1776+
* ignore this feature.
1777+
*/
17611778
tmp = readl(port_mmio + PORT_CMD);
17621779
if (((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)) ||
1763-
(tmp & PORT_CMD_HPCP))
1780+
(tmp & PORT_CMD_HPCP)) {
1781+
if (hpriv->mask_port_ext & (1U << ap->port_no)) {
1782+
ata_port_info(ap,
1783+
"Ignoring external/hotplug capability\n");
1784+
return;
1785+
}
17641786
ap->pflags |= ATA_PFLAG_EXTERNAL;
1787+
}
17651788
}
17661789

17671790
static void ahci_update_initial_lpm_policy(struct ata_port *ap)

drivers/ata/ahci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ struct ahci_host_priv {
330330
/* Input fields */
331331
unsigned int flags; /* AHCI_HFLAG_* */
332332
u32 mask_port_map; /* Mask of valid ports */
333+
u32 mask_port_ext; /* Mask of ports ext capability */
333334

334335
void __iomem * mmio; /* bus-independent mem map */
335336
u32 cap; /* cap to use */

drivers/ata/ahci_xgene.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ static int xgene_ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
450450
{
451451
int pmp = sata_srst_pmp(link);
452452
struct ata_port *ap = link->ap;
453-
u32 rc;
454453
void __iomem *port_mmio = ahci_port_base(ap);
455454
u32 port_fbs;
456455

@@ -463,9 +462,7 @@ static int xgene_ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
463462
port_fbs |= pmp << PORT_FBS_DEV_OFFSET;
464463
writel(port_fbs, port_mmio + PORT_FBS);
465464

466-
rc = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
467-
468-
return rc;
465+
return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
469466
}
470467

471468
/**
@@ -500,7 +497,7 @@ static int xgene_ahci_softreset(struct ata_link *link, unsigned int *class,
500497
u32 port_fbs;
501498
u32 port_fbs_save;
502499
u32 retry = 1;
503-
u32 rc;
500+
int rc;
504501

505502
port_fbs_save = readl(port_mmio + PORT_FBS);
506503

0 commit comments

Comments
 (0)