summaryrefslogtreecommitdiff
path: root/drivers/ide/pci/piix.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/pci/piix.c')
-rw-r--r--drivers/ide/pci/piix.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index a909684ee61b..56feb939f82a 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -215,17 +215,26 @@ static unsigned int init_chipset_ich(struct pci_dev *dev)
}
/**
- * piix_dma_clear_irq - clear BMDMA status
- * @drive: IDE drive to clear
+ * ich_clear_irq - clear BMDMA status
+ * @drive: IDE drive
*
- * Called from ide_intr() for PIO interrupts
- * to clear BMDMA status as needed by ICHx
+ * ICHx contollers set DMA INTR no matter DMA or PIO.
+ * BMDMA status might need to be cleared even for
+ * PIO interrupts to prevent spurious/lost IRQ.
*/
-static void piix_dma_clear_irq(ide_drive_t *drive)
+static void ich_clear_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat;
+ /*
+ * ide_dma_end() needs BMDMA status for error checking.
+ * So, skip clearing BMDMA status here and leave it
+ * to ide_dma_end() if this is DMA interrupt.
+ */
+ if (drive->waiting_for_dma || hwif->dma_base == 0)
+ return;
+
/* clear the INTR & ERROR bits */
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* Should we force the bit as well ? */
@@ -293,21 +302,19 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
}
-static void __devinit init_hwif_ich(ide_hwif_t *hwif)
-{
- init_hwif_piix(hwif);
-
- /* ICHx need to clear the BMDMA status for all interrupts */
- if (hwif->dma_base)
- hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
-}
-
static const struct ide_port_ops piix_port_ops = {
.set_pio_mode = piix_set_pio_mode,
.set_dma_mode = piix_set_dma_mode,
.cable_detect = piix_cable_detect,
};
+static const struct ide_port_ops ich_port_ops = {
+ .set_pio_mode = piix_set_pio_mode,
+ .set_dma_mode = piix_set_dma_mode,
+ .clear_irq = ich_clear_irq,
+ .cable_detect = piix_cable_detect,
+};
+
#ifndef CONFIG_IA64
#define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
#else
@@ -331,9 +338,9 @@ static const struct ide_port_ops piix_port_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_ich, \
- .init_hwif = init_hwif_ich, \
+ .init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
- .port_ops = &piix_port_ops, \
+ .port_ops = &ich_port_ops, \
.host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \