Commit e857f141 authored by Mark Lord's avatar Mark Lord Committed by Jeff Garzik

[PATCH] sata_mv: spurious interrupt workaround

The 60xx chips, and possibly others, incorrectly assert DEV_IRQ interrupts
on a regular basis.  The cause of this is under investigation (by me and
in theory by Marvell also), but regardless we do need to deal with these events.

This patch tidies up some interrupt handler code, and ensures that we ignore
DEV_IRQ interrupts when the drive still  has ATA_BUSY asserted.
Signed-off-by: default avatarMark Lord <liml@rtr.ca>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent eb46d684
...@@ -1380,12 +1380,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, ...@@ -1380,12 +1380,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
struct ata_port *ap = host_set->ports[port]; struct ata_port *ap = host_set->ports[port];
struct mv_port_priv *pp = ap->private_data; struct mv_port_priv *pp = ap->private_data;
hard_port = port & MV_PORT_MASK; /* range 0-3 */ hard_port = mv_hardport_from_port(port); /* range 0..3 */
handled = 0; /* ensure ata_status is set if handled++ */ handled = 0; /* ensure ata_status is set if handled++ */
/* Note that DEV_IRQ might happen spuriously during EDMA, /* Note that DEV_IRQ might happen spuriously during EDMA,
* and should be ignored in such cases. We could mask it, * and should be ignored in such cases.
* but it's pretty rare and may not be worth the overhead. * The cause of this is still under investigation.
*/ */
if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
/* EDMA: check for response queue interrupt */ /* EDMA: check for response queue interrupt */
...@@ -1399,6 +1399,11 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, ...@@ -1399,6 +1399,11 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
ata_status = readb((void __iomem *) ata_status = readb((void __iomem *)
ap->ioaddr.status_addr); ap->ioaddr.status_addr);
handled = 1; handled = 1;
/* ignore spurious intr if drive still BUSY */
if (ata_status & ATA_BUSY) {
ata_status = 0;
handled = 0;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment