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>

authored by Tejun Heo and committed by Jeff Garzik afb2d552 e34bb370

+24 -15
+24 -15
drivers/ata/ahci.c
··· 200 200 /* for NCQ spurious interrupt analysis */ 201 201 unsigned int ncq_saw_d2h:1; 202 202 unsigned int ncq_saw_dmas:1; 203 + unsigned int ncq_saw_sdb:1; 203 204 }; 204 205 205 206 static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); ··· 1158 1157 } 1159 1158 1160 1159 if (status & PORT_IRQ_SDB_FIS) { 1161 - /* SDB FIS containing spurious completions might be 1162 - * dangerous, whine and fail commands with HSM 1163 - * violation. EH will turn off NCQ after several such 1164 - * failures. 1165 - */ 1166 1160 const __le32 *f = pp->rx_fis + RX_FIS_SDB; 1167 1161 1168 - ata_ehi_push_desc(ehi, "spurious completion during NCQ " 1169 - "issue=0x%x SAct=0x%x FIS=%08x:%08x", 1170 - readl(port_mmio + PORT_CMD_ISSUE), 1171 - readl(port_mmio + PORT_SCR_ACT), 1172 - le32_to_cpu(f[0]), le32_to_cpu(f[1])); 1173 - 1174 - ehi->err_mask |= AC_ERR_HSM; 1175 - ehi->action |= ATA_EH_SOFTRESET; 1176 - ata_port_freeze(ap); 1177 - 1162 + if (le32_to_cpu(f[1])) { 1163 + /* SDB FIS containing spurious completions 1164 + * might be dangerous, whine and fail commands 1165 + * with HSM violation. EH will turn off NCQ 1166 + * after several such failures. 1167 + */ 1168 + ata_ehi_push_desc(ehi, 1169 + "spurious completions during NCQ " 1170 + "issue=0x%x SAct=0x%x FIS=%08x:%08x", 1171 + readl(port_mmio + PORT_CMD_ISSUE), 1172 + readl(port_mmio + PORT_SCR_ACT), 1173 + le32_to_cpu(f[0]), le32_to_cpu(f[1])); 1174 + ehi->err_mask |= AC_ERR_HSM; 1175 + ehi->action |= ATA_EH_SOFTRESET; 1176 + ata_port_freeze(ap); 1177 + } else { 1178 + if (!pp->ncq_saw_sdb) 1179 + ata_port_printk(ap, KERN_INFO, 1180 + "spurious SDB FIS %08x:%08x during NCQ, " 1181 + "this message won't be printed again\n", 1182 + le32_to_cpu(f[0]), le32_to_cpu(f[1])); 1183 + pp->ncq_saw_sdb = 1; 1184 + } 1178 1185 known_irq = 1; 1179 1186 } 1180 1187