hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/ata/libahci.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * libahci.c - Common AHCI SATA low-level routines
34 *
....@@ -7,29 +8,12 @@
78 *
89 * Copyright 2004-2005 Red Hat, Inc.
910 *
10
- *
11
- * This program is free software; you can redistribute it and/or modify
12
- * it under the terms of the GNU General Public License as published by
13
- * the Free Software Foundation; either version 2, or (at your option)
14
- * any later version.
15
- *
16
- * This program is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; see the file COPYING. If not, write to
23
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24
- *
25
- *
2611 * libata documentation is available via 'make {ps|pdf}docs',
2712 * as Documentation/driver-api/libata.rst
2813 *
2914 * AHCI hardware documentation:
3015 * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
3116 * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
32
- *
3317 */
3418
3519 #include <linux/kernel.h>
....@@ -507,6 +491,11 @@
507491 if (!(cap & HOST_CAP_ALPM) && (hpriv->flags & AHCI_HFLAG_YES_ALPM)) {
508492 dev_info(dev, "controller can do ALPM, turning on CAP_ALPM\n");
509493 cap |= HOST_CAP_ALPM;
494
+ }
495
+
496
+ if ((cap & HOST_CAP_SXS) && (hpriv->flags & AHCI_HFLAG_NO_SXS)) {
497
+ dev_info(dev, "controller does not support SXS, disabling CAP_SXS\n");
498
+ cap &= ~HOST_CAP_SXS;
510499 }
511500
512501 if (hpriv->force_port_map && port_map != hpriv->force_port_map) {
....@@ -1210,6 +1199,26 @@
12101199 return sprintf(buf, "%d\n", emp->blink_policy);
12111200 }
12121201
1202
+static void ahci_port_clear_pending_irq(struct ata_port *ap)
1203
+{
1204
+ struct ahci_host_priv *hpriv = ap->host->private_data;
1205
+ void __iomem *port_mmio = ahci_port_base(ap);
1206
+ u32 tmp;
1207
+
1208
+ /* clear SError */
1209
+ tmp = readl(port_mmio + PORT_SCR_ERR);
1210
+ dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp);
1211
+ writel(tmp, port_mmio + PORT_SCR_ERR);
1212
+
1213
+ /* clear port IRQ */
1214
+ tmp = readl(port_mmio + PORT_IRQ_STAT);
1215
+ dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp);
1216
+ if (tmp)
1217
+ writel(tmp, port_mmio + PORT_IRQ_STAT);
1218
+
1219
+ writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT);
1220
+}
1221
+
12131222 static void ahci_port_init(struct device *dev, struct ata_port *ap,
12141223 int port_no, void __iomem *mmio,
12151224 void __iomem *port_mmio)
....@@ -1224,18 +1233,7 @@
12241233 if (rc)
12251234 dev_warn(dev, "%s (%d)\n", emsg, rc);
12261235
1227
- /* clear SError */
1228
- tmp = readl(port_mmio + PORT_SCR_ERR);
1229
- VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
1230
- writel(tmp, port_mmio + PORT_SCR_ERR);
1231
-
1232
- /* clear port IRQ */
1233
- tmp = readl(port_mmio + PORT_IRQ_STAT);
1234
- VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
1235
- if (tmp)
1236
- writel(tmp, port_mmio + PORT_IRQ_STAT);
1237
-
1238
- writel(1 << port_no, mmio + HOST_IRQ_STAT);
1236
+ ahci_port_clear_pending_irq(ap);
12391237
12401238 /* mark esata ports */
12411239 tmp = readl(port_mmio + PORT_CMD);
....@@ -1262,10 +1260,10 @@
12621260 }
12631261
12641262 tmp = readl(mmio + HOST_CTL);
1265
- VPRINTK("HOST_CTL 0x%x\n", tmp);
1263
+ dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp);
12661264 writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
12671265 tmp = readl(mmio + HOST_CTL);
1268
- VPRINTK("HOST_CTL 0x%x\n", tmp);
1266
+ dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp);
12691267 }
12701268 EXPORT_SYMBOL_GPL(ahci_init_controller);
12711269
....@@ -1465,7 +1463,7 @@
14651463 *class = ahci_dev_classify(ap);
14661464
14671465 /* re-enable FBS if disabled before */
1468
- if (fbs_disabled)
1466
+ if (fbs_disabled || (!ata_is_host_link(link) && pp->fbs_supported))
14691467 ahci_enable_fbs(ap);
14701468
14711469 DPRINTK("EXIT, class=%u\n", *class);
....@@ -1564,6 +1562,8 @@
15641562 ata_tf_init(link->device, &tf);
15651563 tf.command = ATA_BUSY;
15661564 ata_tf_to_fis(&tf, 0, 0, d2h_fis);
1565
+
1566
+ ahci_port_clear_pending_irq(ap);
15671567
15681568 rc = sata_link_hardreset(link, timing, deadline, online,
15691569 ahci_check_ready);
....@@ -1916,16 +1916,12 @@
19161916 void __iomem *port_mmio = ahci_port_base(ap);
19171917 u32 status;
19181918
1919
- VPRINTK("ENTER\n");
1920
-
19211919 status = readl(port_mmio + PORT_IRQ_STAT);
19221920 writel(status, port_mmio + PORT_IRQ_STAT);
19231921
19241922 spin_lock(ap->lock);
19251923 ahci_handle_port_interrupt(ap, port_mmio, status);
19261924 spin_unlock(ap->lock);
1927
-
1928
- VPRINTK("EXIT\n");
19291925
19301926 return IRQ_HANDLED;
19311927 }
....@@ -1943,9 +1939,7 @@
19431939 ap = host->ports[i];
19441940 if (ap) {
19451941 ahci_port_intr(ap);
1946
- VPRINTK("port %u\n", i);
19471942 } else {
1948
- VPRINTK("port %u (no irq)\n", i);
19491943 if (ata_ratelimit())
19501944 dev_warn(host->dev,
19511945 "interrupt on disabled port %u\n", i);
....@@ -1965,8 +1959,6 @@
19651959 unsigned int rc = 0;
19661960 void __iomem *mmio;
19671961 u32 irq_stat, irq_masked;
1968
-
1969
- VPRINTK("ENTER\n");
19701962
19711963 hpriv = host->private_data;
19721964 mmio = hpriv->mmio;
....@@ -1994,8 +1986,6 @@
19941986 writel(irq_stat, mmio + HOST_IRQ_STAT);
19951987
19961988 spin_unlock(&host->lock);
1997
-
1998
- VPRINTK("EXIT\n");
19991989
20001990 return IRQ_RETVAL(rc);
20011991 }
....@@ -2382,7 +2372,6 @@
23822372 mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL);
23832373 if (!mem)
23842374 return -ENOMEM;
2385
- memset(mem, 0, dma_sz);
23862375
23872376 /*
23882377 * First item in chunk of DMA memory: 32-slot command table,
....@@ -2600,7 +2589,8 @@
26002589 int rc;
26012590
26022591 if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) {
2603
- if (hpriv->irq_handler)
2592
+ if (hpriv->irq_handler &&
2593
+ hpriv->irq_handler != ahci_single_level_irq_intr)
26042594 dev_warn(host->dev,
26052595 "both AHCI_HFLAG_MULTI_MSI flag set and custom irq handler implemented\n");
26062596 if (!hpriv->get_irq_vector) {