Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / ide / setup-pci.c
index da02fa0..462ed30 100644 (file)
@@ -1,8 +1,7 @@
 /*
- *  linux/drivers/ide/setup-pci.c              Version 1.14    2004/08/10
+ *  linux/drivers/ide/setup-pci.c              Version 1.10    2002/08/19
  *
  *  Copyright (c) 1998-2000  Andre Hedrick <andre@linux-ide.org>
- *  Copyright (c) 2004 Red Hat <alan@redhat.com>
  *
  *  Copyright (c) 1995-1998  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
@@ -12,7 +11,6 @@
  *     Use pci_set_master
  *     Fix misreporting of I/O v MMIO problems
  *     Initial fixups for simplex devices
- *     Hot unplug paths
  */
 
 /*
@@ -30,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>
@@ -44,7 +43,7 @@
  *     Match a PCI IDE port against an entry in ide_hwifs[],
  *     based on io_base port if possible. Return the matching hwif,
  *     or a new hwif. If we find an error (clashing, out of devices, etc)
- *     return NULL. The caller must hold the ide_cfg_sem.
+ *     return NULL
  *
  *     FIXME: we need to handle mmio matches here too
  */
@@ -89,8 +88,6 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char
         *
         * Unless there is a bootable card that does not use the standard
         * ports 1f0/170 (the ide0/ide1 defaults). The (bootable) flag.
-        *
-        * FIXME: migrate use of ide_unknown to also use ->configured
         */
        if (bootable) {
                for (h = 0; h < MAX_HWIFS; ++h) {
@@ -189,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);
                }
        }
 
@@ -235,6 +229,7 @@ second_chance_to_dma:
                        case PCI_DEVICE_ID_AMD_VIPER_7409:
                        case PCI_DEVICE_ID_CMD_643:
                        case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
+                       case PCI_DEVICE_ID_REVOLUTION:
                                simplex_stat = hwif->INB(dma_base + 2);
                                hwif->OUTB((simplex_stat&0x60),(dma_base + 2));
                                simplex_stat = hwif->INB(dma_base + 2);
@@ -255,7 +250,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
@@ -263,18 +257,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);
@@ -309,14 +292,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);
        }
 
        /*
@@ -324,18 +309,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;
 }
 
 /**
@@ -439,22 +427,17 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
                ctl = port ? 0x374 : 0x3f4;
                base = port ? 0x170 : 0x1f0;
        }
-       
-       /*
-        * Protect against a hwif being unloaded as we attach to it
-        */
-       down(&ide_cfg_sem);
-       
        if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL)
-       {
-               up(&ide_cfg_sem);
                return NULL;    /* no room in ide_hwifs[] */
-       }
-       
        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];
        }
@@ -462,9 +445,6 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
        hwif->pci_dev = dev;
        hwif->cds = (struct ide_pci_device_s *) d;
        hwif->channel = port;
-       hwif->configured = 1;
-       
-       up(&ide_cfg_sem);
 
        if (!hwif->irq)
                hwif->irq = irq;
@@ -505,13 +485,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",
@@ -531,6 +506,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*/
 
 /**
@@ -547,28 +527,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);
        }
@@ -577,6 +555,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;
 }
 
@@ -584,7 +563,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
  *
@@ -597,12 +575,11 @@ 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;
        ide_hwif_t *hwif, *mate = NULL;
-       static int secondpdc = 0;
        u8 tmp;
 
        index->all = 0xf0f0;
@@ -614,21 +591,9 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int autodma,
        for (port = 0; port <= 1; ++port) {
                ide_pci_enablebit_t *e = &(d->enablebits[port]);
        
-               /* 
-                * If this is a Promise FakeRaid controller,
-                * the 2nd controller will be marked as 
-                * disabled while it is actually there and enabled
-                * by the bios for raid purposes. 
-                * Skip the normal "is it enabled" test for those.
-                */
-               if ((d->flags & IDEPCI_FLAG_FORCE_PDC) &&
-                   (secondpdc++==1) && (port==1))
-                       goto controller_ok;
-                       
                if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
                    (tmp & e->mask) != e->val))
                        continue;       /* port not enabled */
-controller_ok:
 
                if (d->channels <= port)
                        break;
@@ -651,11 +616,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
@@ -686,15 +647,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?
@@ -712,7 +674,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);
@@ -723,10 +688,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__
@@ -737,106 +702,69 @@ 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;
-}
-
-/**
- *     probe_pci_hwif_init     -       probe the hwif then allow fixups
- *     @hwif: interface to probe
- *     @d: PCI device
- *
- *     Perform the generic probe and if it is successful invoke any
- *     remaining post probe fixup logic in the driver itself.
- */
-static void probe_pci_hwif_init(ide_hwif_t *hwif, ide_pci_device_t *d) {
-       probe_hwif_init_with_fixup(hwif, d->fixup);
+       *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_pci_hwif_init(&ide_hwifs[index_list.b.low], d);
+               probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.low], d->fixup);
        if ((index_list.b.high & 0xf0) != 0xf0)
-               probe_pci_hwif_init(&ide_hwifs[index_list.b.high], d);
+               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);
-
-       if ((index_list.b.low & 0xf0) != 0xf0)
-               probe_pci_hwif_init(&ide_hwifs[index_list.b.low], d);
-       if ((index_list.b.high & 0xf0) != 0xf0)
-               probe_pci_hwif_init(&ide_hwifs[index_list.b.high], d);
-       if ((index_list2.b.low & 0xf0) != 0xf0)
-               probe_pci_hwif_init(&ide_hwifs[index_list2.b.low], d);
-       if ((index_list2.b.high & 0xf0) != 0xf0)
-               probe_pci_hwif_init(&ide_hwifs[index_list2.b.high], d);
-
-       create_proc_ide_interfaces();
-}
+       struct pci_dev *pdev[] = { dev1, dev2 };
+       ata_index_t index_list[2];
+       int ret, i;
 
-EXPORT_SYMBOL_GPL(ide_setup_pci_devices);
+       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;
+       }
 
-/**
- *     ide_pci_remove_hwifs    -       remove PCI interfaces
- *     @dev: PCI device
- *
- *     Remove any hwif attached to this PCI device. This will call
- *     back the various hwif->remove functions. In order to get the
- *     best results when delays occur we kill the iops before we
- *     potentially start blocking for long periods untangling the
- *     IDE layer.
- *
- *     Takes the ide_cfg_sem in order to protect against races with
- *     new/old hwifs. Calls functions that take all the other locks
- *     so should be called with no locks held.
- */
-void ide_pci_remove_hwifs(struct pci_dev *dev)
-{
-       int i;
-       ide_hwif_t *hwif = ide_hwifs;
+       for (i = 0; i < 2; i++) {
+               u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
+               int j;
 
-       down(&ide_cfg_sem);
-#if 0
-       for(i = 0; i < MAX_HWIFS; i++)
-       {
-               if(hwif->configured && hwif->pci_dev == dev)
-               {
-                       removed_hwif_iops(hwif);
+               for (j = 0; j < 2; j++) {
+                       if ((idx[j] & 0xf0) != 0xf0)
+                               probe_hwif_init(ide_hwifs + idx[j]);
                }
-               i++;
-               hwif++;
        }
-#endif
-       hwif = ide_hwifs;
-       
-       for(i = 0; i < MAX_HWIFS; i++)
-       {
-               if(hwif->configured && hwif->pci_dev == dev)
-                       __ide_unregister_hwif(hwif);
-               i++;
-               hwif++;
-       }
-       up(&ide_cfg_sem);
-}
 
-EXPORT_SYMBOL_GPL(ide_pci_remove_hwifs);
+       create_proc_ide_interfaces();
+out:
+       return ret;
+}
 
+EXPORT_SYMBOL_GPL(ide_setup_pci_devices);
 
 /*
  *     Module interfaces
@@ -846,8 +774,9 @@ static int pre_init = 1;            /* Before first ordered IDE scan */
 static LIST_HEAD(ide_pci_drivers);
 
 /*
- *     ide_register_pci_driver         -       attach IDE driver
+ *     __ide_pci_register_driver       -       attach IDE driver
  *     @driver: pci driver
+ *     @module: owner module of the driver
  *
  *     Registers a driver with the IDE layer. The IDE layer arranges that
  *     boot time setup is done in the expected device order and then 
@@ -860,15 +789,16 @@ static LIST_HEAD(ide_pci_drivers);
  *     Returns are the same as for pci_register_driver
  */
 
-int ide_pci_register_driver(struct pci_driver *driver)
+int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
 {
        if(!pre_init)
-               return pci_module_init(driver);
+               return __pci_register_driver(driver, module);
+       driver->driver.owner = module;
        list_add_tail(&driver->node, &ide_pci_drivers);
        return 0;
 }
 
-EXPORT_SYMBOL_GPL(ide_pci_register_driver);
+EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
 
 /**
  *     ide_unregister_pci_driver       -       unregister an IDE driver
@@ -907,7 +837,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev)
                d = list_entry(l, struct pci_driver, node);
                if(d->id_table)
                {
-                       const struct pci_device_id *id = pci_match_device(d->id_table, dev);
+                       const struct pci_device_id *id = pci_match_id(d->id_table, dev);
                        if(id != NULL)
                        {
                                if(d->probe(dev, id) >= 0)
@@ -956,6 +886,6 @@ void __init ide_scan_pcibus (int scan_direction)
        {
                list_del(l);
                d = list_entry(l, struct pci_driver, node);
-               pci_register_driver(d);
+               __pci_register_driver(d, d->driver.owner);
        }
 }