Merge branch 'devel' into next
[pandora-kernel.git] / drivers / ide / ide-dma.c
index d61e578..7ee44f8 100644 (file)
@@ -102,7 +102,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
 {
        u8 stat = 0, dma_stat = 0;
 
-       dma_stat = HWIF(drive)->ide_dma_end(drive);
+       dma_stat = drive->hwif->dma_ops->dma_end(drive);
        stat = ide_read_status(drive);
 
        if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
@@ -394,7 +394,7 @@ void ide_dma_off_quietly(ide_drive_t *drive)
        drive->using_dma = 0;
        ide_toggle_bounce(drive, 0);
 
-       drive->hwif->dma_host_set(drive, 0);
+       drive->hwif->dma_ops->dma_host_set(drive, 0);
 }
 
 EXPORT_SYMBOL(ide_dma_off_quietly);
@@ -427,7 +427,7 @@ void ide_dma_on(ide_drive_t *drive)
        drive->using_dma = 1;
        ide_toggle_bounce(drive, 1);
 
-       drive->hwif->dma_host_set(drive, 1);
+       drive->hwif->dma_ops->dma_host_set(drive, 1);
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_SFF
@@ -463,10 +463,11 @@ int ide_dma_setup(ide_drive_t *drive)
        }
 
        /* PRD table */
-       if (hwif->mmio)
-               writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable);
+       if (hwif->host_flags & IDE_HFLAG_MMIO)
+               writel(hwif->dmatable_dma,
+                      (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
        else
-               outl(hwif->dmatable_dma, hwif->dma_prdtable);
+               outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS);
 
        /* specify r/w */
        hwif->OUTB(reading, hwif->dma_command);
@@ -482,11 +483,12 @@ int ide_dma_setup(ide_drive_t *drive)
 
 EXPORT_SYMBOL_GPL(ide_dma_setup);
 
-static void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
        /* issue cmd to drive */
        ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
 }
+EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
 
 void ide_dma_start(ide_drive_t *drive)
 {
@@ -532,7 +534,7 @@ int __ide_dma_end (ide_drive_t *drive)
 EXPORT_SYMBOL(__ide_dma_end);
 
 /* returns 1 if dma irq issued, 0 otherwise */
-static int __ide_dma_test_irq(ide_drive_t *drive)
+int ide_dma_test_irq(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        u8 dma_stat             = hwif->INB(hwif->dma_status);
@@ -542,9 +544,10 @@ static int __ide_dma_test_irq(ide_drive_t *drive)
                return 1;
        if (!drive->waiting_for_dma)
                printk(KERN_WARNING "%s: (%s) called while not waiting\n",
-                       drive->name, __FUNCTION__);
+                       drive->name, __func__);
        return 0;
 }
+EXPORT_SYMBOL_GPL(ide_dma_test_irq);
 #else
 static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
@@ -574,6 +577,7 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
 {
        struct hd_driveid *id = drive->id;
        ide_hwif_t *hwif = drive->hwif;
+       const struct ide_port_ops *port_ops = hwif->port_ops;
        unsigned int mask = 0;
 
        switch(base) {
@@ -581,8 +585,8 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
                if ((id->field_valid & 4) == 0)
                        break;
 
-               if (hwif->udma_filter)
-                       mask = hwif->udma_filter(drive);
+               if (port_ops && port_ops->udma_filter)
+                       mask = port_ops->udma_filter(drive);
                else
                        mask = hwif->ultra_mask;
                mask &= id->dma_ultra;
@@ -598,8 +602,8 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
        case XFER_MW_DMA_0:
                if ((id->field_valid & 2) == 0)
                        break;
-               if (hwif->mdma_filter)
-                       mask = hwif->mdma_filter(drive);
+               if (port_ops && port_ops->mdma_filter)
+                       mask = port_ops->mdma_filter(drive);
                else
                        mask = hwif->mwdma_mask;
                mask &= id->dma_mword;
@@ -688,7 +692,7 @@ static int ide_tune_dma(ide_drive_t *drive)
        ide_hwif_t *hwif = drive->hwif;
        u8 speed;
 
-       if (noautodma || drive->nodma || (drive->id->capability & 1) == 0)
+       if (drive->nodma || (drive->id->capability & 1) == 0)
                return 0;
 
        /* consult the list of known "bad" drives */
@@ -703,17 +707,8 @@ static int ide_tune_dma(ide_drive_t *drive)
 
        speed = ide_max_dma_mode(drive);
 
-       if (!speed) {
-                /* is this really correct/needed? */
-               if ((hwif->host_flags & IDE_HFLAG_CY82C693) &&
-                   ide_dma_good_drive(drive))
-                       return 1;
-               else
-                       return 0;
-       }
-
-       if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
-               return 1;
+       if (!speed)
+               return 0;
 
        if (ide_set_dma_mode(drive, speed))
                return 0;
@@ -810,15 +805,15 @@ void ide_dma_timeout (ide_drive_t *drive)
 
        printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
 
-       if (hwif->ide_dma_test_irq(drive))
+       if (hwif->dma_ops->dma_test_irq(drive))
                return;
 
-       hwif->ide_dma_end(drive);
+       hwif->dma_ops->dma_end(drive);
 }
 
 EXPORT_SYMBOL(ide_dma_timeout);
 
-static void ide_release_dma_engine(ide_hwif_t *hwif)
+void ide_release_dma_engine(ide_hwif_t *hwif)
 {
        if (hwif->dmatable_cpu) {
                struct pci_dev *pdev = to_pci_dev(hwif->dev);
@@ -829,28 +824,7 @@ static void ide_release_dma_engine(ide_hwif_t *hwif)
        }
 }
 
-static int ide_release_iomio_dma(ide_hwif_t *hwif)
-{
-       release_region(hwif->dma_base, 8);
-       if (hwif->extra_ports)
-               release_region(hwif->extra_base, hwif->extra_ports);
-       return 1;
-}
-
-/*
- * Needed for allowing full modular support of ide-driver
- */
-int ide_release_dma(ide_hwif_t *hwif)
-{
-       ide_release_dma_engine(hwif);
-
-       if (hwif->mmio)
-               return 1;
-       else
-               return ide_release_iomio_dma(hwif);
-}
-
-static int ide_allocate_dma_engine(ide_hwif_t *hwif)
+int ide_allocate_dma_engine(ide_hwif_t *hwif)
 {
        struct pci_dev *pdev = to_pci_dev(hwif->dev);
 
@@ -862,99 +836,33 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif)
                return 0;
 
        printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n",
-              hwif->cds->name);
+                       hwif->name);
 
        return 1;
 }
-
-static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base)
-{
-       printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
-
-       return 0;
-}
-
-static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base)
-{
-       printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx",
-              hwif->name, base, base + 7);
-
-       if (!request_region(base, 8, hwif->name)) {
-               printk(" -- Error, ports in use.\n");
-               return 1;
-       }
-
-       if (hwif->cds->extra) {
-               hwif->extra_base = base + (hwif->channel ? 8 : 16);
-
-               if (!hwif->mate || !hwif->mate->extra_ports) {
-                       if (!request_region(hwif->extra_base,
-                                           hwif->cds->extra, hwif->cds->name)) {
-                               printk(" -- Error, extra ports in use.\n");
-                               release_region(base, 8);
-                               return 1;
-                       }
-                       hwif->extra_ports = hwif->cds->extra;
-               }
-       }
-
-       return 0;
-}
-
-static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base)
-{
-       if (hwif->mmio)
-               return ide_mapped_mmio_dma(hwif, base);
-
-       return ide_iomio_dma(hwif, base);
-}
+EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
+
+static const struct ide_dma_ops sff_dma_ops = {
+       .dma_host_set           = ide_dma_host_set,
+       .dma_setup              = ide_dma_setup,
+       .dma_exec_cmd           = ide_dma_exec_cmd,
+       .dma_start              = ide_dma_start,
+       .dma_end                = __ide_dma_end,
+       .dma_test_irq           = ide_dma_test_irq,
+       .dma_timeout            = ide_dma_timeout,
+       .dma_lost_irq           = ide_dma_lost_irq,
+};
 
 void ide_setup_dma(ide_hwif_t *hwif, unsigned long base)
 {
-       u8 dma_stat;
-
-       if (ide_dma_iobase(hwif, base))
-               return;
-
-       if (ide_allocate_dma_engine(hwif)) {
-               ide_release_dma(hwif);
-               return;
-       }
-
        hwif->dma_base = base;
 
        if (!hwif->dma_command)
                hwif->dma_command       = hwif->dma_base + 0;
-       if (!hwif->dma_vendor1)
-               hwif->dma_vendor1       = hwif->dma_base + 1;
        if (!hwif->dma_status)
                hwif->dma_status        = hwif->dma_base + 2;
-       if (!hwif->dma_vendor3)
-               hwif->dma_vendor3       = hwif->dma_base + 3;
-       if (!hwif->dma_prdtable)
-               hwif->dma_prdtable      = hwif->dma_base + 4;
-
-       if (!hwif->dma_host_set)
-               hwif->dma_host_set = &ide_dma_host_set;
-       if (!hwif->dma_setup)
-               hwif->dma_setup = &ide_dma_setup;
-       if (!hwif->dma_exec_cmd)
-               hwif->dma_exec_cmd = &ide_dma_exec_cmd;
-       if (!hwif->dma_start)
-               hwif->dma_start = &ide_dma_start;
-       if (!hwif->ide_dma_end)
-               hwif->ide_dma_end = &__ide_dma_end;
-       if (!hwif->ide_dma_test_irq)
-               hwif->ide_dma_test_irq = &__ide_dma_test_irq;
-       if (!hwif->dma_timeout)
-               hwif->dma_timeout = &ide_dma_timeout;
-       if (!hwif->dma_lost_irq)
-               hwif->dma_lost_irq = &ide_dma_lost_irq;
 
-       dma_stat = hwif->INB(hwif->dma_status);
-       printk(KERN_CONT ", BIOS settings: %s:%s, %s:%s\n",
-              hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "PIO",
-              hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "PIO");
+       hwif->dma_ops = &sff_dma_ops;
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_dma);