ide: remove ->ide_dma_check (take 2)
[linux-2.6-block.git] / drivers / ide / pci / sgiioc4.c
index d396b2929ed87791564600b85675d72eda7af774..210f32d1e93cd6fc7c2351913ba47eae0350801c 100644 (file)
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/blkdev.h>
+#include <linux/scatterlist.h>
 #include <linux/ioc4.h>
 #include <asm/io.h>
 
 #include <linux/ide.h>
 
+#define DRV_NAME "SGIIOC4"
+
 /* IOC4 Specific Definitions */
 #define IOC4_CMD_OFFSET                0x100
 #define IOC4_CTRL_OFFSET       0x120
@@ -289,15 +292,8 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
        drive->hwif->dma_host_off(drive);
 }
 
-static int sgiioc4_ide_dma_check(ide_drive_t *drive)
+static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
-       /* FIXME: check for available DMA modes */
-       if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
-               printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
-                                   "using PIO instead\n", drive->name);
-               return -1;
-       } else
-               return 0;
 }
 
 /* returns 1 if dma irq issued, 0 otherwise */
@@ -353,7 +349,7 @@ sgiioc4_INB(unsigned long port)
 }
 
 /* Creates a dma map for the scatter-gather list entries */
-static void __devinit
+static int __devinit
 ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
 {
        void __iomem *virt_dma_base;
@@ -369,7 +365,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
                       "ALREADY in use\n",
                       __FUNCTION__, hwif->name, (void *) dma_base,
                       (void *) dma_base + num_ports - 1);
-               goto dma_alloc_failure;
+               return -1;
        }
 
        virt_dma_base = ioremap(dma_base, num_ports);
@@ -395,7 +391,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
 
        if (pad) {
                ide_set_hwifdata(hwif, pad);
-               return;
+               return 0;
        }
 
        pci_free_consistent(hwif->pci_dev,
@@ -413,10 +409,7 @@ dma_pci_alloc_failure:
 dma_remap_failure:
        release_mem_region(dma_base, num_ports);
 
-dma_alloc_failure:
-       /* Disable DMA because we couldnot allocate any DMA maps */
-       hwif->autodma = 0;
-       hwif->atapi_dma = 0;
+       return -1;
 }
 
 /* Initializes the IOC4 DMA Engine */
@@ -531,7 +524,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
                        }
                }
 
-               sg++;
+               sg = sg_next(sg);
                i--;
        }
 
@@ -581,13 +574,9 @@ static void __devinit
 ide_init_sgiioc4(ide_hwif_t * hwif)
 {
        hwif->mmio = 1;
-       hwif->autodma = 1;
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
-       hwif->mwdma_mask = 0x2; /* Multimode-2 DMA  */
-       hwif->swdma_mask = 0x2;
-       hwif->tuneproc = NULL;  /* Sets timing for PIO mode */
-       hwif->speedproc = NULL; /* Sets timing for DMA &/or PIO modes */
+       hwif->pio_mask = 0x00;
+       hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */
+       hwif->set_dma_mode = &sgiioc4_set_dma_mode;
        hwif->selectproc = NULL;/* Use the default routine to select drive */
        hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
        hwif->pre_reset = NULL; /* No HBA specific pre_set needed */
@@ -598,10 +587,17 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        hwif->quirkproc = NULL;
        hwif->busproc = NULL;
 
+       hwif->INB = &sgiioc4_INB;
+
+       if (hwif->dma_base == 0)
+               return;
+
+       hwif->atapi_dma = 1;
+       hwif->mwdma_mask = 0x04;
+
        hwif->dma_setup = &sgiioc4_ide_dma_setup;
        hwif->dma_start = &sgiioc4_ide_dma_start;
        hwif->ide_dma_end = &sgiioc4_ide_dma_end;
-       hwif->ide_dma_check = &sgiioc4_ide_dma_check;
        hwif->ide_dma_on = &sgiioc4_ide_dma_on;
        hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
        hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
@@ -609,12 +605,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        hwif->dma_host_off = &sgiioc4_dma_host_off;
        hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
        hwif->dma_timeout = &ide_dma_timeout;
-
-       hwif->INB = &sgiioc4_INB;
 }
 
 static int __devinit
-sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
+sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 {
        unsigned long cmd_base, dma_base, irqport;
        unsigned long bar0, cmd_phys_base, ctl;
@@ -631,7 +625,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
                        break;
        }
        if (h == MAX_HWIFS) {
-               printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name);
+               printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n",
+                               DRV_NAME);
                return -ENOMEM;
        }
 
@@ -640,7 +635,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
        virt_base = ioremap(bar0, pci_resource_len(dev, 0));
        if (virt_base == NULL) {
                printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n",
-                       d->name, bar0);
+                               DRV_NAME, bar0);
                return -ENOMEM;
        }
        cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET;
@@ -671,7 +666,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
        hwif->chipset = ide_pci;
        hwif->pci_dev = dev;
        hwif->channel = 0;      /* Single Channel chip */
-       hwif->cds = (struct ide_pci_device_s *) d;
        hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
 
        /* The IOC4 uses MMIO rather than Port IO. */
@@ -680,13 +674,16 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
        /* Initializing chipset IRQ Registers */
        writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
 
-       ide_init_sgiioc4(hwif);
+       hwif->autodma = 0;
 
-       if (dma_base)
-               ide_dma_sgiioc4(hwif, dma_base);
-       else
+       if (dma_base && ide_dma_sgiioc4(hwif, dma_base) == 0) {
+               hwif->autodma = 1;
+               hwif->drives[1].autodma = hwif->drives[0].autodma = 1;
+       } else
                printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
-                      hwif->name, d->name);
+                                hwif->name, DRV_NAME);
+
+       ide_init_sgiioc4(hwif);
 
        if (probe_hwif_init(hwif))
                return -EIO;
@@ -698,7 +695,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
 }
 
 static unsigned int __devinit
-pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
+pci_init_sgiioc4(struct pci_dev *dev)
 {
        unsigned int class_rev;
        int ret;
@@ -706,30 +703,20 @@ pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
        class_rev &= 0xff;
        printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
-                       d->name, pci_name(dev), class_rev);
+                        DRV_NAME, pci_name(dev), class_rev);
        if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
                printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
-                       "firmware is obsolete - please upgrade to revision"
-                       "46 or higher\n", d->name, pci_name(dev));
+                               "firmware is obsolete - please upgrade to "
+                               "revision46 or higher\n",
+                               DRV_NAME, pci_name(dev));
                ret = -EAGAIN;
                goto out;
        }
-       ret = sgiioc4_ide_setup_pci_device(dev, d);
+       ret = sgiioc4_ide_setup_pci_device(dev);
 out:
        return ret;
 }
 
-static ide_pci_device_t sgiioc4_chipset __devinitdata = {
-        /* Channel 0 */
-        .name = "SGIIOC4",
-        .init_hwif = ide_init_sgiioc4,
-        .init_dma = ide_dma_sgiioc4,
-        .channels = 1,
-        .autodma = AUTODMA,
-        /* SGI IOC4 doesn't have enablebits. */
-        .bootable = ON_BOARD,
-};
-
 int
 ioc4_ide_attach_one(struct ioc4_driver_data *idd)
 {
@@ -739,7 +726,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd)
        if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
                return 0;
 
-       return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset);
+       return pci_init_sgiioc4(idd->idd_pdev);
 }
 
 static struct ioc4_submodule ioc4_ide_submodule = {