aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c74
1 files changed, 3 insertions, 71 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index cb7853b7335d..54f38c21dd95 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1640,7 +1640,7 @@ static void ahci_port_intr(struct ata_port *ap)
1640 struct ahci_host_priv *hpriv = ap->host->private_data; 1640 struct ahci_host_priv *hpriv = ap->host->private_data;
1641 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); 1641 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
1642 u32 status, qc_active; 1642 u32 status, qc_active;
1643 int rc, known_irq = 0; 1643 int rc;
1644 1644
1645 status = readl(port_mmio + PORT_IRQ_STAT); 1645 status = readl(port_mmio + PORT_IRQ_STAT);
1646 writel(status, port_mmio + PORT_IRQ_STAT); 1646 writel(status, port_mmio + PORT_IRQ_STAT);
@@ -1698,80 +1698,12 @@ static void ahci_port_intr(struct ata_port *ap)
1698 1698
1699 rc = ata_qc_complete_multiple(ap, qc_active, NULL); 1699 rc = ata_qc_complete_multiple(ap, qc_active, NULL);
1700 1700
1701 /* If resetting, spurious or invalid completions are expected, 1701 /* while resetting, invalid completions are expected */
1702 * return unconditionally. 1702 if (unlikely(rc < 0 && !resetting)) {
1703 */
1704 if (resetting)
1705 return;
1706
1707 if (rc > 0)
1708 return;
1709 if (rc < 0) {
1710 ehi->err_mask |= AC_ERR_HSM; 1703 ehi->err_mask |= AC_ERR_HSM;
1711 ehi->action |= ATA_EH_SOFTRESET; 1704 ehi->action |= ATA_EH_SOFTRESET;
1712 ata_port_freeze(ap); 1705 ata_port_freeze(ap);
1713 return;
1714 }
1715
1716 /* hmmm... a spurious interrupt */
1717
1718 /* if !NCQ, ignore. No modern ATA device has broken HSM
1719 * implementation for non-NCQ commands.
1720 */
1721 if (!ap->link.sactive)
1722 return;
1723
1724 if (status & PORT_IRQ_D2H_REG_FIS) {
1725 if (!pp->ncq_saw_d2h)
1726 ata_port_printk(ap, KERN_INFO,
1727 "D2H reg with I during NCQ, "
1728 "this message won't be printed again\n");
1729 pp->ncq_saw_d2h = 1;
1730 known_irq = 1;
1731 }
1732
1733 if (status & PORT_IRQ_DMAS_FIS) {
1734 if (!pp->ncq_saw_dmas)
1735 ata_port_printk(ap, KERN_INFO,
1736 "DMAS FIS during NCQ, "
1737 "this message won't be printed again\n");
1738 pp->ncq_saw_dmas = 1;
1739 known_irq = 1;
1740 } 1706 }
1741
1742 if (status & PORT_IRQ_SDB_FIS) {
1743 const __le32 *f = pp->rx_fis + RX_FIS_SDB;
1744
1745 if (le32_to_cpu(f[1])) {
1746 /* SDB FIS containing spurious completions
1747 * might be dangerous, whine and fail commands
1748 * with HSM violation. EH will turn off NCQ
1749 * after several such failures.
1750 */
1751 ata_ehi_push_desc(ehi,
1752 "spurious completions during NCQ "
1753 "issue=0x%x SAct=0x%x FIS=%08x:%08x",
1754 readl(port_mmio + PORT_CMD_ISSUE),
1755 readl(port_mmio + PORT_SCR_ACT),
1756 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1757 ehi->err_mask |= AC_ERR_HSM;
1758 ehi->action |= ATA_EH_SOFTRESET;
1759 ata_port_freeze(ap);
1760 } else {
1761 if (!pp->ncq_saw_sdb)
1762 ata_port_printk(ap, KERN_INFO,
1763 "spurious SDB FIS %08x:%08x during NCQ, "
1764 "this message won't be printed again\n",
1765 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1766 pp->ncq_saw_sdb = 1;
1767 }
1768 known_irq = 1;
1769 }
1770
1771 if (!known_irq)
1772 ata_port_printk(ap, KERN_INFO, "spurious interrupt "
1773 "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
1774 status, ap->link.active_tag, ap->link.sactive);
1775} 1707}
1776 1708
1777static void ahci_irq_clear(struct ata_port *ap) 1709static void ahci_irq_clear(struct ata_port *ap)