--- libata-core.c-orig 2003-12-07 01:54:19.000000000 +0000 +++ libata-core.c 2003-12-07 16:25:11.961806872 +0000 @@ -2386,6 +2386,37 @@ } /** + * ata_chk_spurious_int - Check for spurious interrupts + * @ap: port to which command is being issued + * + * Examines the DMA status registers and clears + * unexpected interrupts + * + * LOCKING: + */ +static inline void ata_chk_spurious_int(struct ata_port *ap) { + int host_stat; + + if (ap->flags & ATA_FLAG_MMIO) { + void *mmio = (void *) ap->ioaddr.bmdma_addr; + host_stat = readb(mmio + ATA_DMA_STATUS); + } else + host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + + if ((host_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == ATA_DMA_INTR) { + if (ap->flags & ATA_FLAG_MMIO) { + void *mmio = (void *) ap->ioaddr.bmdma_addr; + writeb(host_stat & ~ATA_DMA_ERR, mmio + ATA_DMA_STATUS); + } else + outb(host_stat & ~ATA_DMA_ERR, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + + DPRINTK("ata%u: Caught spurious interrupt, status 0x%X\n", ap->id, host_stat); + udelay(1); + } +} + + +/** * ata_interrupt - * @irq: * @dev_instance: @@ -2417,6 +2448,7 @@ qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0)) handled += ata_host_intr(ap, qc); + ata_chk_spurious_int(ap); } }