From: Mark Lord <liml@rtr.ca>
To: IDE/ATA development list <linux-ide@vger.kernel.org>,
Brian Rademacher <rad@radfiles.net>,
Eamonn Hamilton <EAMONN.HAMILTON@saic.com>
Subject: sata_mv: trial fix for lost NCQ interrupts
Date: Tue, 13 Jan 2009 16:17:31 -0500 [thread overview]
Message-ID: <496D04EB.3060803@rtr.ca> (raw)
This patch is for trial/critique use only at the moment.
Once I hear back from a few people who actually use it,
I'll post an updated fix for upstream/backstream inclusion.
I spent this afternoon nitpicking and bitpicking through the interrupt code
in sata_mv.c, and I believe I found a race on the hc_irq_cause register. The
code was "helpfully" attempting to use read-modify-write to clear individual
port bits there, but this is impossible to do in a race-free fashion.
So.. the obvious fix is to just write the bits being cleared, without touching
anything else. This will also be faster, too, since no read is required or
desired. I really don't see a downside, as long as it actually works for everyone.
It does work for me here.
--- linux-2.6.28/drivers/ata/sata_mv.c 2009-01-13 15:57:11.000000000 -0500
+++ linux/drivers/ata/sata_mv.c 2009-01-13 16:03:04.000000000 -0500
@@ -884,18 +884,14 @@
int hardport = mv_hardport_from_port(ap->port_no);
void __iomem *hc_mmio = mv_hc_base_from_port(
mv_host_base(ap->host), hardport);
- u32 hc_irq_cause, ipending;
+ u32 hc_irq_cause;
/* clear EDMA event indicators, if any */
writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
- /* clear EDMA interrupt indicator, if any */
- hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
- ipending = (DEV_IRQ | DMA_IRQ) << hardport;
- if (hc_irq_cause & ipending) {
- writelfl(hc_irq_cause & ~ipending,
- hc_mmio + HC_IRQ_CAUSE_OFS);
- }
+ /* clear EDMA interrupt indicators */
+ hc_irq_cause = (DEV_IRQ | DMA_IRQ) << hardport;
+ writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
mv_edma_cfg(ap, want_ncq);
@@ -2821,10 +2817,9 @@
/* clear EDMA errors on this port */
writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
- /* clear pending irq events */
- hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
- hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
- writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+ /* clear EDMA interrupt indicators */
+ hc_irq_cause = (DEV_IRQ | DMA_IRQ) << hardport;
+ writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
mv_enable_port_irqs(ap, ERR_IRQ);
}
next reply other threads:[~2009-01-13 21:17 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-13 21:17 Mark Lord [this message]
2009-01-14 21:06 ` sata_mv: trial fix for lost NCQ interrupts Harri Olin
2009-01-14 21:26 ` Jeff Garzik
2009-01-14 22:08 ` Mark Lord
2009-01-14 22:06 ` Mark Lord
2009-01-14 23:18 ` Harri Olin
2009-01-14 23:22 ` Brian Rademacher
2009-01-15 2:53 ` Mark Lord
2009-01-15 13:06 ` Artem Bokhan
2009-01-16 17:03 ` [PATCH] sata_mv: fix timeouts on lower ports of 508x/6081 chips Mark Lord
2009-01-16 20:08 ` Harri Olin
2009-01-17 2:10 ` Brian Rademacher
2009-01-14 22:01 ` sata_mv: trial fix for lost NCQ interrupts Brian Rademacher
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=496D04EB.3060803@rtr.ca \
--to=liml@rtr.ca \
--cc=EAMONN.HAMILTON@saic.com \
--cc=linux-ide@vger.kernel.org \
--cc=rad@radfiles.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).