diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 74 |
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 | ||
1777 | static void ahci_irq_clear(struct ata_port *ap) | 1709 | static void ahci_irq_clear(struct ata_port *ap) |