aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
authorMark Brown <broonie@kernel.org>2026-05-29 22:42:49 +0100
committerMark Brown <broonie@kernel.org>2026-05-29 22:42:49 +0100
commit673ae5a6c0d932f536f249b89227e38fb1b22a30 (patch)
treeea1fcc12a07396d60a765c5d51f7b96eac8b47fc /drivers
parent692f367d6033168e32c5ea2139683794e8ffa8ad (diff)
parentd114b8432030113f466cfe6a27244f6f68cd0f26 (diff)
downloadlinux-next-history-673ae5a6c0d932f536f249b89227e38fb1b22a30.tar.gz
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/libata/linux
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c22
-rw-r--r--drivers/ata/libahci.c10
-rw-r--r--drivers/ata/libata-core.c19
-rw-r--r--drivers/ata/libata-eh.c2
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/pata_arasan_cf.c24
6 files changed, 50 insertions, 29 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 1d73a53370cf3..b4e5d347151a9 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1888,6 +1888,24 @@ static ssize_t remapped_nvme_show(struct device *dev,
static DEVICE_ATTR_RO(remapped_nvme);
+static int ahci_validate_bar_size(struct pci_dev *pdev, int bar,
+ struct ahci_host_priv *hpriv)
+{
+ u32 cap = readl(hpriv->mmio + HOST_CAP);
+ unsigned int max_ports = ahci_nr_ports(cap);
+ u32 last_port_end = 0x100 + (max_ports * 0x80);
+ resource_size_t bar_size = pci_resource_len(pdev, bar);
+
+ if (last_port_end > bar_size) {
+ dev_warn(&pdev->dev,
+ "BAR%d too small for %u ports (last port ends at %#x, BAR %pa)\n",
+ bar, max_ports, last_port_end, &bar_size);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned int board_id = ent->driver_data;
@@ -1988,6 +2006,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!hpriv->mmio)
return -ENOMEM;
+ rc = ahci_validate_bar_size(pdev, ahci_pci_bar, hpriv);
+ if (rc)
+ return rc;
+
/* detect remapped nvme devices */
ahci_remap_check(pdev, ahci_pci_bar, hpriv);
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index c79abdfcd7a9b..e0af4b5716b3f 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -552,11 +552,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
/* cross check port_map and cap.n_ports */
if (port_map) {
- int map_ports = 0;
-
- for (i = 0; i < AHCI_MAX_PORTS; i++)
- if (port_map & (1 << i))
- map_ports++;
+ int map_ports = hweight_long(port_map);
/* If PI has more ports than n_ports, whine, clear
* port_map and let it be generated from n_ports.
@@ -1527,6 +1523,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
ata_link_err(link, "softreset failed (%s)\n", reason);
return rc;
}
+EXPORT_SYMBOL_GPL(ahci_do_softreset);
int ahci_check_ready(struct ata_link *link)
{
@@ -1544,7 +1541,6 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class,
return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
}
-EXPORT_SYMBOL_GPL(ahci_do_softreset);
static int ahci_bad_pmp_check_ready(struct ata_link *link)
{
@@ -2636,7 +2632,7 @@ void ahci_print_info(struct ata_host *host, const char *scc_s)
,
hweight32(impl),
- (cap & 0x1f) + 1,
+ ahci_nr_ports(cap),
impl);
dev_info(host->dev,
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3d0027ec33c2a..3e19a00a92393 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1540,6 +1540,7 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
{
struct ata_link *link = dev->link;
struct ata_port *ap = link->ap;
+ const bool owns_eh_mutex = ap->host->eh_owner == current;
u8 command = tf->command;
struct ata_queued_cmd *qc;
struct scatterlist sgl;
@@ -1617,11 +1618,25 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
}
}
- ata_eh_release(ap);
+ if (owns_eh_mutex) {
+ /*
+ * To prevent that the compiler complains about the
+ * ata_eh_release() call below.
+ */
+ __acquire(&ap->host->eh_mutex);
+ ata_eh_release(ap);
+ }
rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
- ata_eh_acquire(ap);
+ if (owns_eh_mutex) {
+ ata_eh_acquire(ap);
+ /*
+ * To prevent that the compiler complains about the above
+ * ata_eh_acquire() call.
+ */
+ __release(&ap->host->eh_mutex);
+ }
ata_sff_flush_pio_task(ap);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index d623eb32ed8b7..715bc525b38ff 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -819,7 +819,7 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
ap->pflags &= ~ATA_PFLAG_LOADING;
else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) &&
!(ap->flags & ATA_FLAG_SAS_HOST))
- schedule_delayed_work(&ap->hotplug_task, 0);
+ queue_delayed_work(system_dfl_long_wq, &ap->hotplug_task, 0);
if (ap->pflags & ATA_PFLAG_RECOVERED)
ata_port_info(ap, "EH complete\n");
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index d43207c6e4679..1f4a4329fc11f 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -4768,7 +4768,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
"WARNING: synchronous SCSI scan failed without making any progress, switching to async\n");
}
- queue_delayed_work(system_long_wq, &ap->hotplug_task,
+ queue_delayed_work(system_dfl_long_wq, &ap->hotplug_task,
round_jiffies_relative(HZ));
}
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index b1e281b64f57c..a77fefd320c26 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -803,16 +803,6 @@ static int arasan_cf_probe(struct platform_device *pdev)
irq_handler_t irq_handler = NULL;
int ret;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -EINVAL;
-
- if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
- DRIVER_NAME)) {
- dev_warn(&pdev->dev, "Failed to get memory region resource\n");
- return -ENOENT;
- }
-
acdev = devm_kzalloc(&pdev->dev, sizeof(*acdev), GFP_KERNEL);
if (!acdev)
return -ENOMEM;
@@ -827,22 +817,20 @@ static int arasan_cf_probe(struct platform_device *pdev)
* support only PIO
*/
ret = platform_get_irq(pdev, 0);
+ if (ret == -EPROBE_DEFER)
+ return ret;
if (ret > 0) {
acdev->irq = ret;
irq_handler = arasan_cf_interrupt;
- } else if (ret == -EPROBE_DEFER) {
- return ret;
} else {
quirk |= CF_BROKEN_MWDMA | CF_BROKEN_UDMA;
}
+ acdev->vbase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(acdev->vbase))
+ return PTR_ERR(acdev->vbase);
+
acdev->pbase = res->start;
- acdev->vbase = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!acdev->vbase) {
- dev_warn(&pdev->dev, "ioremap fail\n");
- return -ENOMEM;
- }
acdev->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(acdev->clk)) {