aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-02-26 23:24:19 -0500
committerJeff Garzik <jeff@garzik.org>2007-03-01 20:19:45 -0500
commitafb2d552bc4c241c009f5947311a95de426a75d9 (patch)
treec6dc4115ca8bb7e64431af86d553328f13d289fc /drivers/ata/ahci.c
parente34bb370dec4919b7e8b769d51ad2bc2535b6982 (diff)
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.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 45785ec702a1..1539734bbbad 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -200,6 +200,7 @@ struct ahci_port_priv {
200 /* for NCQ spurious interrupt analysis */ 200 /* for NCQ spurious interrupt analysis */
201 unsigned int ncq_saw_d2h:1; 201 unsigned int ncq_saw_d2h:1;
202 unsigned int ncq_saw_dmas:1; 202 unsigned int ncq_saw_dmas:1;
203 unsigned int ncq_saw_sdb:1;
203}; 204};
204 205
205static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); 206static 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)
1157 } 1158 }
1158 1159
1159 if (status & PORT_IRQ_SDB_FIS) { 1160 if (status & PORT_IRQ_SDB_FIS) {
1160 /* SDB FIS containing spurious completions might be
1161 * dangerous, whine and fail commands with HSM
1162 * violation. EH will turn off NCQ after several such
1163 * failures.
1164 */
1165 const __le32 *f = pp->rx_fis + RX_FIS_SDB; 1161 const __le32 *f = pp->rx_fis + RX_FIS_SDB;
1166 1162
1167 ata_ehi_push_desc(ehi, "spurious completion during NCQ " 1163 if (le32_to_cpu(f[1])) {
1168 "issue=0x%x SAct=0x%x FIS=%08x:%08x", 1164 /* SDB FIS containing spurious completions
1169 readl(port_mmio + PORT_CMD_ISSUE), 1165 * might be dangerous, whine and fail commands
1170 readl(port_mmio + PORT_SCR_ACT), 1166 * with HSM violation. EH will turn off NCQ
1171 le32_to_cpu(f[0]), le32_to_cpu(f[1])); 1167 * after several such failures.
1172 1168 */
1173 ehi->err_mask |= AC_ERR_HSM; 1169 ata_ehi_push_desc(ehi,
1174 ehi->action |= ATA_EH_SOFTRESET; 1170 "spurious completions during NCQ "
1175 ata_port_freeze(ap); 1171 "issue=0x%x SAct=0x%x FIS=%08x:%08x",
1176 1172 readl(port_mmio + PORT_CMD_ISSUE),
1173 readl(port_mmio + PORT_SCR_ACT),
1174 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1175 ehi->err_mask |= AC_ERR_HSM;
1176 ehi->action |= ATA_EH_SOFTRESET;
1177 ata_port_freeze(ap);
1178 } else {
1179 if (!pp->ncq_saw_sdb)
1180 ata_port_printk(ap, KERN_INFO,
1181 "spurious SDB FIS %08x:%08x during NCQ, "
1182 "this message won't be printed again\n",
1183 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1184 pp->ncq_saw_sdb = 1;
1185 }
1177 known_irq = 1; 1186 known_irq = 1;
1178 } 1187 }
1179 1188