.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * libahci.c - Common AHCI SATA low-level routines |
---|
3 | 4 | * |
---|
.. | .. |
---|
7 | 8 | * |
---|
8 | 9 | * Copyright 2004-2005 Red Hat, Inc. |
---|
9 | 10 | * |
---|
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 | | - * |
---|
26 | 11 | * libata documentation is available via 'make {ps|pdf}docs', |
---|
27 | 12 | * as Documentation/driver-api/libata.rst |
---|
28 | 13 | * |
---|
29 | 14 | * AHCI hardware documentation: |
---|
30 | 15 | * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf |
---|
31 | 16 | * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf |
---|
32 | | - * |
---|
33 | 17 | */ |
---|
34 | 18 | |
---|
35 | 19 | #include <linux/kernel.h> |
---|
.. | .. |
---|
507 | 491 | if (!(cap & HOST_CAP_ALPM) && (hpriv->flags & AHCI_HFLAG_YES_ALPM)) { |
---|
508 | 492 | dev_info(dev, "controller can do ALPM, turning on CAP_ALPM\n"); |
---|
509 | 493 | 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; |
---|
510 | 499 | } |
---|
511 | 500 | |
---|
512 | 501 | if (hpriv->force_port_map && port_map != hpriv->force_port_map) { |
---|
.. | .. |
---|
1210 | 1199 | return sprintf(buf, "%d\n", emp->blink_policy); |
---|
1211 | 1200 | } |
---|
1212 | 1201 | |
---|
| 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 | + |
---|
1213 | 1222 | static void ahci_port_init(struct device *dev, struct ata_port *ap, |
---|
1214 | 1223 | int port_no, void __iomem *mmio, |
---|
1215 | 1224 | void __iomem *port_mmio) |
---|
.. | .. |
---|
1224 | 1233 | if (rc) |
---|
1225 | 1234 | dev_warn(dev, "%s (%d)\n", emsg, rc); |
---|
1226 | 1235 | |
---|
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); |
---|
1239 | 1237 | |
---|
1240 | 1238 | /* mark esata ports */ |
---|
1241 | 1239 | tmp = readl(port_mmio + PORT_CMD); |
---|
.. | .. |
---|
1262 | 1260 | } |
---|
1263 | 1261 | |
---|
1264 | 1262 | tmp = readl(mmio + HOST_CTL); |
---|
1265 | | - VPRINTK("HOST_CTL 0x%x\n", tmp); |
---|
| 1263 | + dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp); |
---|
1266 | 1264 | writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); |
---|
1267 | 1265 | tmp = readl(mmio + HOST_CTL); |
---|
1268 | | - VPRINTK("HOST_CTL 0x%x\n", tmp); |
---|
| 1266 | + dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp); |
---|
1269 | 1267 | } |
---|
1270 | 1268 | EXPORT_SYMBOL_GPL(ahci_init_controller); |
---|
1271 | 1269 | |
---|
.. | .. |
---|
1465 | 1463 | *class = ahci_dev_classify(ap); |
---|
1466 | 1464 | |
---|
1467 | 1465 | /* re-enable FBS if disabled before */ |
---|
1468 | | - if (fbs_disabled) |
---|
| 1466 | + if (fbs_disabled || (!ata_is_host_link(link) && pp->fbs_supported)) |
---|
1469 | 1467 | ahci_enable_fbs(ap); |
---|
1470 | 1468 | |
---|
1471 | 1469 | DPRINTK("EXIT, class=%u\n", *class); |
---|
.. | .. |
---|
1564 | 1562 | ata_tf_init(link->device, &tf); |
---|
1565 | 1563 | tf.command = ATA_BUSY; |
---|
1566 | 1564 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
---|
| 1565 | + |
---|
| 1566 | + ahci_port_clear_pending_irq(ap); |
---|
1567 | 1567 | |
---|
1568 | 1568 | rc = sata_link_hardreset(link, timing, deadline, online, |
---|
1569 | 1569 | ahci_check_ready); |
---|
.. | .. |
---|
1916 | 1916 | void __iomem *port_mmio = ahci_port_base(ap); |
---|
1917 | 1917 | u32 status; |
---|
1918 | 1918 | |
---|
1919 | | - VPRINTK("ENTER\n"); |
---|
1920 | | - |
---|
1921 | 1919 | status = readl(port_mmio + PORT_IRQ_STAT); |
---|
1922 | 1920 | writel(status, port_mmio + PORT_IRQ_STAT); |
---|
1923 | 1921 | |
---|
1924 | 1922 | spin_lock(ap->lock); |
---|
1925 | 1923 | ahci_handle_port_interrupt(ap, port_mmio, status); |
---|
1926 | 1924 | spin_unlock(ap->lock); |
---|
1927 | | - |
---|
1928 | | - VPRINTK("EXIT\n"); |
---|
1929 | 1925 | |
---|
1930 | 1926 | return IRQ_HANDLED; |
---|
1931 | 1927 | } |
---|
.. | .. |
---|
1943 | 1939 | ap = host->ports[i]; |
---|
1944 | 1940 | if (ap) { |
---|
1945 | 1941 | ahci_port_intr(ap); |
---|
1946 | | - VPRINTK("port %u\n", i); |
---|
1947 | 1942 | } else { |
---|
1948 | | - VPRINTK("port %u (no irq)\n", i); |
---|
1949 | 1943 | if (ata_ratelimit()) |
---|
1950 | 1944 | dev_warn(host->dev, |
---|
1951 | 1945 | "interrupt on disabled port %u\n", i); |
---|
.. | .. |
---|
1965 | 1959 | unsigned int rc = 0; |
---|
1966 | 1960 | void __iomem *mmio; |
---|
1967 | 1961 | u32 irq_stat, irq_masked; |
---|
1968 | | - |
---|
1969 | | - VPRINTK("ENTER\n"); |
---|
1970 | 1962 | |
---|
1971 | 1963 | hpriv = host->private_data; |
---|
1972 | 1964 | mmio = hpriv->mmio; |
---|
.. | .. |
---|
1994 | 1986 | writel(irq_stat, mmio + HOST_IRQ_STAT); |
---|
1995 | 1987 | |
---|
1996 | 1988 | spin_unlock(&host->lock); |
---|
1997 | | - |
---|
1998 | | - VPRINTK("EXIT\n"); |
---|
1999 | 1989 | |
---|
2000 | 1990 | return IRQ_RETVAL(rc); |
---|
2001 | 1991 | } |
---|
.. | .. |
---|
2382 | 2372 | mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL); |
---|
2383 | 2373 | if (!mem) |
---|
2384 | 2374 | return -ENOMEM; |
---|
2385 | | - memset(mem, 0, dma_sz); |
---|
2386 | 2375 | |
---|
2387 | 2376 | /* |
---|
2388 | 2377 | * First item in chunk of DMA memory: 32-slot command table, |
---|
.. | .. |
---|
2600 | 2589 | int rc; |
---|
2601 | 2590 | |
---|
2602 | 2591 | 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) |
---|
2604 | 2594 | dev_warn(host->dev, |
---|
2605 | 2595 | "both AHCI_HFLAG_MULTI_MSI flag set and custom irq handler implemented\n"); |
---|
2606 | 2596 | if (!hpriv->get_irq_vector) { |
---|