X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=drivers%2Fata%2Fsata_sil24.c;h=233e886933959c63f3a5d8d1ea04df0f0a2dfb6b;hb=544002ef832730b18327000c898a140bfc93efd4;hp=46fbbe7f121c2da1ca115a383800ee9f3525da5c;hpb=644b55ce889edd37d6406df26e2d96d7a7390749;p=sfrench%2Fcifs-2.6.git diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 46fbbe7f121c..233e88693395 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -30,7 +30,7 @@ #include #define DRV_NAME "sata_sil24" -#define DRV_VERSION "0.9" +#define DRV_VERSION "1.0" /* * Port request block (PRB) 32 bytes @@ -888,6 +888,16 @@ static inline void sil24_host_intr(struct ata_port *ap) u32 slot_stat, qc_active; int rc; + /* If PCIX_IRQ_WOC, there's an inherent race window between + * clearing IRQ pending status and reading PORT_SLOT_STAT + * which may cause spurious interrupts afterwards. This is + * unavoidable and much better than losing interrupts which + * happens if IRQ pending is cleared after reading + * PORT_SLOT_STAT. + */ + if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) + writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT); + slot_stat = readl(port + PORT_SLOT_STAT); if (unlikely(slot_stat & HOST_SSTAT_ATTN)) { @@ -895,9 +905,6 @@ static inline void sil24_host_intr(struct ata_port *ap) return; } - if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) - writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT); - qc_active = slot_stat & ~HOST_SSTAT_ATTN; rc = ata_qc_complete_multiple(ap, qc_active, sil24_finish_qc); if (rc > 0) @@ -910,7 +917,8 @@ static inline void sil24_host_intr(struct ata_port *ap) return; } - if (ata_ratelimit()) + /* spurious interrupts are expected if PCIX_IRQ_WOC */ + if (!(ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) && ata_ratelimit()) ata_port_printk(ap, KERN_INFO, "spurious interrupt " "(slot_stat 0x%x active_tag %d sactive 0x%x)\n", slot_stat, ap->active_tag, ap->sactive);