diff options
author | Tejun Heo <htejun@gmail.com> | 2007-02-27 04:24:19 (GMT) |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-03-02 01:19:45 (GMT) |
commit | afb2d552bc4c241c009f5947311a95de426a75d9 (patch) | |
tree | c6dc4115ca8bb7e64431af86d553328f13d289fc /drivers/ata/ahci.c | |
parent | e34bb370dec4919b7e8b769d51ad2bc2535b6982 (diff) | |
download | linux-fsl-qoriq-afb2d552bc4c241c009f5947311a95de426a75d9.tar.xz |
ahci: improve spurious SDB FIS handling
Spurious SDB FIS during NCQ might not contain spurious completions.
It could be spurious TF update or invalid async notification. Treat
as HSM violation iff a spurious SDB FIS contains spurious completions;
otherwise, just whine once about it.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 45785ec..1539734 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -200,6 +200,7 @@ struct ahci_port_priv { /* for NCQ spurious interrupt analysis */ unsigned int ncq_saw_d2h:1; unsigned int ncq_saw_dmas:1; + unsigned int ncq_saw_sdb:1; }; static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); @@ -1157,23 +1158,31 @@ static void ahci_host_intr(struct ata_port *ap) } if (status & PORT_IRQ_SDB_FIS) { - /* SDB FIS containing spurious completions might be - * dangerous, whine and fail commands with HSM - * violation. EH will turn off NCQ after several such - * failures. - */ const __le32 *f = pp->rx_fis + RX_FIS_SDB; - ata_ehi_push_desc(ehi, "spurious completion during NCQ " - "issue=0x%x SAct=0x%x FIS=%08x:%08x", - readl(port_mmio + PORT_CMD_ISSUE), - readl(port_mmio + PORT_SCR_ACT), - le32_to_cpu(f[0]), le32_to_cpu(f[1])); - - ehi->err_mask |= AC_ERR_HSM; - ehi->action |= ATA_EH_SOFTRESET; - ata_port_freeze(ap); - + if (le32_to_cpu(f[1])) { + /* SDB FIS containing spurious completions + * might be dangerous, whine and fail commands + * with HSM violation. EH will turn off NCQ + * after several such failures. + */ + ata_ehi_push_desc(ehi, + "spurious completions during NCQ " + "issue=0x%x SAct=0x%x FIS=%08x:%08x", + readl(port_mmio + PORT_CMD_ISSUE), + readl(port_mmio + PORT_SCR_ACT), + le32_to_cpu(f[0]), le32_to_cpu(f[1])); + ehi->err_mask |= AC_ERR_HSM; + ehi->action |= ATA_EH_SOFTRESET; + ata_port_freeze(ap); + } else { + if (!pp->ncq_saw_sdb) + ata_port_printk(ap, KERN_INFO, + "spurious SDB FIS %08x:%08x during NCQ, " + "this message won't be printed again\n", + le32_to_cpu(f[0]), le32_to_cpu(f[1])); + pp->ncq_saw_sdb = 1; + } known_irq = 1; } |