diff options
Diffstat (limited to 'drivers/ide/ide-dma-sff.c')
-rw-r--r-- | drivers/ide/ide-dma-sff.c | 105 |
1 files changed, 53 insertions, 52 deletions
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index cac431f0df1..123d393658a 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c @@ -50,6 +50,27 @@ int config_drive_for_dma(ide_drive_t *drive) return 0; } +u8 ide_dma_sff_read_status(ide_hwif_t *hwif) +{ + unsigned long addr = hwif->dma_base + ATA_DMA_STATUS; + + if (hwif->host_flags & IDE_HFLAG_MMIO) + return readb((void __iomem *)addr); + else + return inb(addr); +} +EXPORT_SYMBOL_GPL(ide_dma_sff_read_status); + +static void ide_dma_sff_write_status(ide_hwif_t *hwif, u8 val) +{ + unsigned long addr = hwif->dma_base + ATA_DMA_STATUS; + + if (hwif->host_flags & IDE_HFLAG_MMIO) + writeb(val, (void __iomem *)addr); + else + outb(val, addr); +} + /** * ide_dma_host_set - Enable/disable DMA on a host * @drive: drive to control @@ -62,18 +83,14 @@ void ide_dma_host_set(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; u8 unit = drive->dn & 1; - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); if (on) dma_stat |= (1 << (5 + unit)); else dma_stat &= ~(1 << (5 + unit)); - if (hwif->host_flags & IDE_HFLAG_MMIO) - writeb(dma_stat, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); + ide_dma_sff_write_status(hwif, dma_stat); } EXPORT_SYMBOL_GPL(ide_dma_host_set); @@ -98,10 +115,10 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; __le32 *table = (__le32 *)hwif->dmatable_cpu; - unsigned int is_trm290 = (hwif->chipset == ide_trm290) ? 1 : 0; unsigned int count = 0; int i; struct scatterlist *sg; + u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290); hwif->sg_nents = ide_build_sglist(drive, rq); if (hwif->sg_nents == 0) @@ -175,16 +192,11 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); int ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct request *rq = hwif->hwgroup->rq; - unsigned int reading; + struct request *rq = hwif->rq; + unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 dma_stat; - if (rq_data_dir(rq)) - reading = 0; - else - reading = 1 << 3; - /* fall back to pio! */ if (!ide_build_dmatable(drive, rq)) { ide_map_sg(drive, rq); @@ -192,7 +204,7 @@ int ide_dma_setup(ide_drive_t *drive) } /* PRD table */ - if (hwif->host_flags & IDE_HFLAG_MMIO) + if (mmio) writel(hwif->dmatable_dma, (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); else @@ -205,14 +217,10 @@ int ide_dma_setup(ide_drive_t *drive) outb(reading, hwif->dma_base + ATA_DMA_CMD); /* read DMA status for INTR & ERROR flags */ - dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); /* clear INTR & ERROR flags */ - if (mmio) - writeb(dma_stat | 6, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); drive->waiting_for_dma = 1; return 0; @@ -236,7 +244,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup); static int dma_timer_expiry(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n", drive->name, __func__, dma_stat); @@ -244,16 +252,15 @@ static int dma_timer_expiry(ide_drive_t *drive) if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ return WAIT_CMD; - hwif->hwgroup->expiry = NULL; /* one free ride for now */ + hwif->expiry = NULL; /* one free ride for now */ - /* 1 dmaing, 2 error, 4 intr */ - if (dma_stat & 2) /* ERROR */ + if (dma_stat & ATA_DMA_ERR) /* ERROR */ return -1; - if (dma_stat & 1) /* DMAing */ + if (dma_stat & ATA_DMA_ACTIVE) /* DMAing */ return WAIT_CMD; - if (dma_stat & 4) /* Got an Interrupt */ + if (dma_stat & ATA_DMA_INTR) /* Got an Interrupt */ return WAIT_CMD; return 0; /* Status is unknown -- reset the bus */ @@ -279,12 +286,11 @@ void ide_dma_start(ide_drive_t *drive) */ if (hwif->host_flags & IDE_HFLAG_MMIO) { dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* start DMA */ - writeb(dma_cmd | 1, + writeb(dma_cmd | ATA_DMA_START, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); } else { dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); } wmb(); @@ -295,37 +301,35 @@ EXPORT_SYMBOL_GPL(ide_dma_start); int ide_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 dma_stat = 0, dma_cmd = 0; + u8 dma_stat = 0, dma_cmd = 0, mask; drive->waiting_for_dma = 0; - if (mmio) { - /* get DMA command mode */ + /* stop DMA */ + if (hwif->host_flags & IDE_HFLAG_MMIO) { dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* stop DMA */ - writeb(dma_cmd & ~1, + writeb(dma_cmd & ~ATA_DMA_START, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); } else { dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); } /* get DMA status */ - dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); - if (mmio) - /* clear the INTR & ERROR bits */ - writeb(dma_stat | 6, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + /* clear INTR & ERROR bits */ + ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); /* purge DMA mappings */ ide_destroy_dmatable(drive); - /* verify good DMA status */ wmb(); - return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; + + /* verify good DMA status */ + mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR; + if ((dma_stat & mask) != ATA_DMA_INTR) + return 0x10 | dma_stat; + return 0; } EXPORT_SYMBOL_GPL(ide_dma_end); @@ -333,13 +337,9 @@ EXPORT_SYMBOL_GPL(ide_dma_end); int ide_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) - return 1; - - return 0; + return (dma_stat & ATA_DMA_INTR) ? 1 : 0; } EXPORT_SYMBOL_GPL(ide_dma_test_irq); @@ -352,5 +352,6 @@ const struct ide_dma_ops sff_dma_ops = { .dma_test_irq = ide_dma_test_irq, .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, + .dma_sff_read_status = ide_dma_sff_read_status, }; EXPORT_SYMBOL_GPL(sff_dma_ops); |