diff options
| author | Tejun Heo <htejun@gmail.com> | 2007-02-26 23:24:19 -0500 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2007-03-01 20:19:45 -0500 |
| commit | afb2d552bc4c241c009f5947311a95de426a75d9 (patch) | |
| tree | c6dc4115ca8bb7e64431af86d553328f13d289fc | |
| parent | e34bb370dec4919b7e8b769d51ad2bc2535b6982 (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>
| -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 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 | ||
| 205 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); | 206 | 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) | |||
| 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 | ||
