aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2006-05-19 16:33:03 -0400
committerJeff Garzik <jeff@garzik.org>2006-05-20 00:31:45 -0400
commite857f141945f29c16f72ffcfdbce097f8be6c4e9 (patch)
treecd6bcdeaed84701fddc693eedfddae0fcba68e27 /drivers
parenteb46d684600ac145501805a294c94675e82eab2e (diff)
[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: Mark Lord <liml@rtr.ca> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sata_mv.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index bb2409e761d0..65dc65304f51 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1380,12 +1380,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
1380 struct ata_port *ap = host_set->ports[port]; 1380 struct ata_port *ap = host_set->ports[port];
1381 struct mv_port_priv *pp = ap->private_data; 1381 struct mv_port_priv *pp = ap->private_data;
1382 1382
1383 hard_port = port & MV_PORT_MASK; /* range 0-3 */ 1383 hard_port = mv_hardport_from_port(port); /* range 0..3 */
1384 handled = 0; /* ensure ata_status is set if handled++ */ 1384 handled = 0; /* ensure ata_status is set if handled++ */
1385 1385
1386 /* Note that DEV_IRQ might happen spuriously during EDMA, 1386 /* Note that DEV_IRQ might happen spuriously during EDMA,
1387 * and should be ignored in such cases. We could mask it, 1387 * and should be ignored in such cases.
1388 * but it's pretty rare and may not be worth the overhead. 1388 * The cause of this is still under investigation.
1389 */ 1389 */
1390 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { 1390 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
1391 /* EDMA: check for response queue interrupt */ 1391 /* EDMA: check for response queue interrupt */
@@ -1399,6 +1399,11 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
1399 ata_status = readb((void __iomem *) 1399 ata_status = readb((void __iomem *)
1400 ap->ioaddr.status_addr); 1400 ap->ioaddr.status_addr);
1401 handled = 1; 1401 handled = 1;
1402 /* ignore spurious intr if drive still BUSY */
1403 if (ata_status & ATA_BUSY) {
1404 ata_status = 0;
1405 handled = 0;
1406 }
1402 } 1407 }
1403 } 1408 }
1404 1409