diff options
author | Mark Lord <liml@rtr.ca> | 2008-05-14 09:19:30 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-05-19 17:27:57 -0400 |
commit | e40060772d85f3534d3d517197696e24bb01f45b (patch) | |
tree | 962f7918afbb38a298c55a0c1307253e579e1c8a /drivers/ata/sata_mv.c | |
parent | 9dcffd99d0b1c0c1b8b2c0f85d240e791eca1055 (diff) |
sata_mv: fis irq register fixes
Fix handling of the FIS_IRQ_CAUSE register in sata_mv.
This register exists *only* on GenIIe devices, so don't bother
writing to it on older chips. Also, it has to be read/cleared
in mv_err_intr() before clearing the main ERR_IRQ_CAUSE register.
This keeps sata_mv from getting stuck forever on certain error types.
Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index bbacdd90f554..2a23d7ae4769 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -886,7 +886,8 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, | |||
886 | mv_edma_cfg(ap, want_ncq); | 886 | mv_edma_cfg(ap, want_ncq); |
887 | 887 | ||
888 | /* clear FIS IRQ Cause */ | 888 | /* clear FIS IRQ Cause */ |
889 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | 889 | if (IS_GEN_IIE(hpriv)) |
890 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
890 | 891 | ||
891 | mv_set_edma_ptrs(port_mmio, hpriv, pp); | 892 | mv_set_edma_ptrs(port_mmio, hpriv, pp); |
892 | 893 | ||
@@ -1812,6 +1813,7 @@ static void mv_err_intr(struct ata_port *ap) | |||
1812 | { | 1813 | { |
1813 | void __iomem *port_mmio = mv_ap_base(ap); | 1814 | void __iomem *port_mmio = mv_ap_base(ap); |
1814 | u32 edma_err_cause, eh_freeze_mask, serr = 0; | 1815 | u32 edma_err_cause, eh_freeze_mask, serr = 0; |
1816 | u32 fis_cause = 0; | ||
1815 | struct mv_port_priv *pp = ap->private_data; | 1817 | struct mv_port_priv *pp = ap->private_data; |
1816 | struct mv_host_priv *hpriv = ap->host->private_data; | 1818 | struct mv_host_priv *hpriv = ap->host->private_data; |
1817 | unsigned int action = 0, err_mask = 0; | 1819 | unsigned int action = 0, err_mask = 0; |
@@ -1821,16 +1823,19 @@ static void mv_err_intr(struct ata_port *ap) | |||
1821 | 1823 | ||
1822 | /* | 1824 | /* |
1823 | * Read and clear the SError and err_cause bits. | 1825 | * Read and clear the SError and err_cause bits. |
1826 | * For GenIIe, if EDMA_ERR_TRANS_IRQ_7 is set, we also must read/clear | ||
1827 | * the FIS_IRQ_CAUSE register before clearing edma_err_cause. | ||
1824 | */ | 1828 | */ |
1825 | sata_scr_read(&ap->link, SCR_ERROR, &serr); | 1829 | sata_scr_read(&ap->link, SCR_ERROR, &serr); |
1826 | sata_scr_write_flush(&ap->link, SCR_ERROR, serr); | 1830 | sata_scr_write_flush(&ap->link, SCR_ERROR, serr); |
1827 | 1831 | ||
1828 | edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 1832 | edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
1833 | if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) { | ||
1834 | fis_cause = readl(port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
1835 | writelfl(~fis_cause, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
1836 | } | ||
1829 | writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 1837 | writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
1830 | 1838 | ||
1831 | ata_port_printk(ap, KERN_INFO, "%s: err_cause=%08x pp_flags=0x%x\n", | ||
1832 | __func__, edma_err_cause, pp->pp_flags); | ||
1833 | |||
1834 | if (edma_err_cause & EDMA_ERR_DEV) { | 1839 | if (edma_err_cause & EDMA_ERR_DEV) { |
1835 | /* | 1840 | /* |
1836 | * Device errors during FIS-based switching operation | 1841 | * Device errors during FIS-based switching operation |
@@ -1844,6 +1849,9 @@ static void mv_err_intr(struct ata_port *ap) | |||
1844 | ata_ehi_clear_desc(ehi); | 1849 | ata_ehi_clear_desc(ehi); |
1845 | ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", | 1850 | ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", |
1846 | edma_err_cause, pp->pp_flags); | 1851 | edma_err_cause, pp->pp_flags); |
1852 | |||
1853 | if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) | ||
1854 | ata_ehi_push_desc(ehi, "fis_cause=%08x", fis_cause); | ||
1847 | /* | 1855 | /* |
1848 | * All generations share these EDMA error cause bits: | 1856 | * All generations share these EDMA error cause bits: |
1849 | */ | 1857 | */ |