vserver 1.9.5.x5
[linux-2.6.git] / drivers / ide / setup-pci.c
index b485e6b..e501675 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/ide.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -185,19 +186,16 @@ static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
 second_chance_to_dma:
 #endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
 
-       if ((hwif->mmio) && (hwif->dma_base))
+       if (hwif->mmio)
                return hwif->dma_base;
 
        if (hwif->mate && hwif->mate->dma_base) {
                dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
        } else {
-               dma_base = (hwif->mmio) ?
-                       ((unsigned long) hwif->hwif_data) :
-                       (pci_resource_start(dev, 4));
+               dma_base = pci_resource_start(dev, 4);
                if (!dma_base) {
-                       printk(KERN_ERR "%s: dma_base is invalid (0x%04lx)\n",
-                               hwif->cds->name, dma_base);
-                       dma_base = 0;
+                       printk(KERN_ERR "%s: dma_base is invalid\n",
+                                       hwif->cds->name);
                }
        }
 
@@ -251,7 +249,6 @@ second_chance_to_dma:
                                simplex_stat = hwif->INB(dma_base + 2);
                                if (simplex_stat & 0x80) {
                                        /* simplex device? */
-#if 0                                  
 /*
  *     At this point we haven't probed the drives so we can't make the
  *     appropriate decision. Really we should defer this problem
@@ -259,18 +256,7 @@ second_chance_to_dma:
  *     to be the DMA end. This has to be become dynamic to handle hot
  *     plug.
  */
-                                       /* Don't enable DMA on a simplex channel with no drives */
-                                       if (!hwif->drives[0].present && !hwif->drives[1].present)
-                                       {
-                                               printk(KERN_INFO "%s: simplex device with no drives: DMA disabled\n",
-                                                               hwif->cds->name);
-                                               dma_base = 0;
-                                       }
-                                       /* If our other channel has DMA then we cannot */
-                                       else 
-#endif                                 
-                                       if(hwif->mate && hwif->mate->dma_base) 
-                                       {
+                                       if (hwif->mate && hwif->mate->dma_base) {
                                                printk(KERN_INFO "%s: simplex device: "
                                                        "DMA disabled\n",
                                                        hwif->cds->name);
@@ -305,14 +291,16 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
  
 static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
 {
-       
+       int ret;
+
        if (pci_enable_device(dev)) {
-               if (pci_enable_device_bars(dev, 1 << 4)) {
+               ret = pci_enable_device_bars(dev, 1 << 4);
+               if (ret < 0) {
                        printk(KERN_WARNING "%s: (ide_setup_pci_device:) "
                                "Could not enable device.\n", d->name);
-                       return -EBUSY;
-               } else
-                       printk(KERN_WARNING "%s: BIOS configuration fixed.\n", d->name);
+                       goto out;
+               }
+               printk(KERN_WARNING "%s: BIOS configuration fixed.\n", d->name);
        }
 
        /*
@@ -320,18 +308,21 @@ static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
         * dma mask field to the ide_pci_device_t if we need it (or let
         * lower level driver set the dma mask)
         */
-       if (pci_set_dma_mask(dev, 0xffffffff)) {
+       ret = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+       if (ret < 0) {
                printk(KERN_ERR "%s: can't set dma mask\n", d->name);
-               return -EBUSY;
+               goto out;
        }
-        
+
        /* FIXME: Temporary - until we put in the hotplug interface logic
-          Check that the bits we want are not in use by someone else */
-       if (pci_request_region(dev, 4, "ide_tmp"))
-               return -EBUSY;
+          Check that the bits we want are not in use by someone else. */
+       ret = pci_request_region(dev, 4, "ide_tmp");
+       if (ret < 0)
+               goto out;
+
        pci_release_region(dev, 4);
-       
-       return 0;       
+out:
+       return ret;
 }
 
 /**
@@ -440,7 +431,12 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
        if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
            hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
                memset(&hwif->hw, 0, sizeof(hwif->hw));
+#ifndef IDE_ARCH_OBSOLETE_INIT
+               ide_std_init_ports(&hwif->hw, base, (ctl | 2));
+               hwif->hw.io_ports[IDE_IRQ_OFFSET] = 0;
+#else
                ide_init_hwif_ports(&hwif->hw, base, (ctl | 2), NULL);
+#endif
                memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
                hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
        }
@@ -488,13 +484,8 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
                         * Set up BM-DMA capability
                         * (PnP BIOS should have done this)
                         */
-                       if ((d->flags & IDEPCI_FLAG_FORCE_MASTER) == 0) {
-                               /*
-                                * default DMA off if we had to
-                                * configure it here
-                                */
-                               hwif->autodma = 0;
-                       }
+                       /* default DMA off if we had to configure it here */
+                       hwif->autodma = 0;
                        pci_set_master(dev);
                        if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) {
                                printk(KERN_ERR "%s: %s error updating PCICMD\n",
@@ -514,6 +505,11 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
                }
        }
 }
+
+#ifndef CONFIG_IDEDMA_PCI_AUTO
+#warning CONFIG_IDEDMA_PCI_AUTO=n support is obsolete, and will be removed soon.
+#endif
+
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
 
 /**
@@ -530,28 +526,26 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
  
 static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config)
 {
-       int ret = 0;
+       int ret;
        u32 class_rev;
        u16 pcicmd;
 
-       if (!noautodma)
-               ret = 1;
-
        if (noisy)
                ide_setup_pci_noise(dev, d);
 
-       if (ide_pci_enable(dev, d))
-               return -EBUSY;
-               
-       if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) {
+       ret = ide_pci_enable(dev, d);
+       if (ret < 0)
+               goto out;
+
+       ret = pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
+       if (ret < 0) {
                printk(KERN_ERR "%s: error accessing PCI regs\n", d->name);
-               return -EIO;
+               goto out;
        }
        if (!(pcicmd & PCI_COMMAND_IO)) {       /* is device disabled? */
-               if (ide_pci_configure(dev, d))
-                       return -ENODEV;
-               /* default DMA off if we had to configure it here */
-               ret = 0;
+               ret = ide_pci_configure(dev, d);
+               if (ret < 0)
+                       goto out;
                *config = 1;
                printk(KERN_INFO "%s: device enabled (Linux)\n", d->name);
        }
@@ -560,6 +554,7 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in
        class_rev &= 0xff;
        if (noisy)
                printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev);
+out:
        return ret;
 }
 
@@ -567,7 +562,6 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in
  *     ide_pci_setup_ports     -       configure ports/devices on PCI IDE
  *     @dev: PCI device
  *     @d: IDE pci device info
- *     @autodma: Should we enable DMA
  *     @pciirq: IRQ line
  *     @index: ata index to update
  *
@@ -580,7 +574,7 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in
  *     where the chipset setup is not the default PCI IDE one.
  */
  
-void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int autodma, int pciirq, ata_index_t *index)
+void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, ata_index_t *index)
 {
        int port;
        int at_least_one_hwif_enabled = 0;
@@ -634,11 +628,7 @@ controller_ok:
 
                if (d->autodma == NODMA)
                        goto bypass_legacy_dma;
-               if (d->autodma == NOAUTODMA)
-                       autodma = 0;
-               if (autodma)
-                       hwif->autodma = 1;
-                       
+
                if(d->init_setup_dma)
                        d->init_setup_dma(dev, d, hwif);
                else
@@ -669,15 +659,16 @@ EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
  * we "know" about, this information is in the ide_pci_device_t struct;
  * for all other chipsets, we just assume both interfaces are enabled.
  */
-static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d, u8 noisy)
+static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d,
+                                  ata_index_t *index, u8 noisy)
 {
-       int autodma = 0;
-       int pciirq = 0;
+       static ata_index_t ata_index = { .b = { .low = 0xff, .high = 0xff } };
        int tried_config = 0;
-       ata_index_t index = { .b = { .low = 0xff, .high = 0xff } };
+       int pciirq, ret;
 
-       if((autodma = ide_setup_pci_controller(dev, d, noisy, &tried_config)) < 0)
-               return index;
+       ret = ide_setup_pci_controller(dev, d, noisy, &tried_config);
+       if (ret < 0)
+               goto out;
 
        /*
         * Can we trust the reported IRQ?
@@ -695,7 +686,10 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_
                 * space, place chipset into init-mode, and/or preserve
                 * an interrupt if the card is not native ide support.
                 */
-               pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : 0;
+               ret = d->init_chipset ? d->init_chipset(dev, d->name) : 0;
+               if (ret < 0)
+                       goto out;
+               pciirq = ret;
        } else if (tried_config) {
                if (noisy)
                        printk(KERN_INFO "%s: will probe irqs later\n", d->name);
@@ -706,10 +700,10 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_
                                d->name, pciirq);
                pciirq = 0;
        } else {
-               if (d->init_chipset)
-               {
-                       if(d->init_chipset(dev, d->name) < 0)
-                               return index;
+               if (d->init_chipset) {
+                       ret = d->init_chipset(dev, d->name);
+                       if (ret < 0)
+                               goto out;
                }
                if (noisy)
 #ifdef __sparc__
@@ -720,44 +714,66 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_
                                d->name, pciirq);
 #endif
        }
-       
-       if(pciirq < 0)          /* Error not an IRQ */
-               return index;
 
-       ide_pci_setup_ports(dev, d, autodma, pciirq, &index);
+       /* FIXME: silent failure can happen */
 
-       return index;
+       *index = ata_index;
+       ide_pci_setup_ports(dev, d, pciirq, index);
+out:
+       return ret;
 }
 
-void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d)
+int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
 {
-       ata_index_t index_list = do_ide_setup_pci_device(dev, d, 1);
+       ata_index_t index_list;
+       int ret;
+
+       ret = do_ide_setup_pci_device(dev, d, &index_list, 1);
+       if (ret < 0)
+               goto out;
 
        if ((index_list.b.low & 0xf0) != 0xf0)
-               probe_hwif_init(&ide_hwifs[index_list.b.low]);
+               probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.low], d->fixup);
        if ((index_list.b.high & 0xf0) != 0xf0)
-               probe_hwif_init(&ide_hwifs[index_list.b.high]);
+               probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.high], d->fixup);
 
        create_proc_ide_interfaces();
+out:
+       return ret;
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_device);
 
-void ide_setup_pci_devices (struct pci_dev *dev, struct pci_dev *dev2, ide_pci_device_t *d)
+int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
+                         ide_pci_device_t *d)
 {
-       ata_index_t index_list  = do_ide_setup_pci_device(dev, d, 1);
-       ata_index_t index_list2 = do_ide_setup_pci_device(dev2, d, 0);
+       struct pci_dev *pdev[] = { dev1, dev2 };
+       ata_index_t index_list[2];
+       int ret, i;
 
-       if ((index_list.b.low & 0xf0) != 0xf0)
-               probe_hwif_init(&ide_hwifs[index_list.b.low]);
-       if ((index_list.b.high & 0xf0) != 0xf0)
-               probe_hwif_init(&ide_hwifs[index_list.b.high]);
-       if ((index_list2.b.low & 0xf0) != 0xf0)
-               probe_hwif_init(&ide_hwifs[index_list2.b.low]);
-       if ((index_list2.b.high & 0xf0) != 0xf0)
-               probe_hwif_init(&ide_hwifs[index_list2.b.high]);
+       for (i = 0; i < 2; i++) {
+               ret = do_ide_setup_pci_device(pdev[i], d, index_list + i, !i);
+               /*
+                * FIXME: Mom, mom, they stole me the helper function to undo
+                * do_ide_setup_pci_device() on the first device!
+                */
+               if (ret < 0)
+                       goto out;
+       }
+
+       for (i = 0; i < 2; i++) {
+               u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
+               int j;
+
+               for (j = 0; j < 2; j++) {
+                       if ((idx[j] & 0xf0) != 0xf0)
+                               probe_hwif_init(ide_hwifs + idx[j]);
+               }
+       }
 
        create_proc_ide_interfaces();
+out:
+       return ret;
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_devices);