]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/setup-pci.c
ide: factor out devices setup from init_irq()
[linux-2.6-omap-h63xx.git] / drivers / ide / setup-pci.c
index 676c66e728818aac177442847d50b1d73413ef6e..634e3f6a96087907b8053fc8bcdb29d3b20281d0 100644 (file)
@@ -1,9 +1,8 @@
 /*
- *  linux/drivers/ide/setup-pci.c              Version 1.10    2002/08/19
+ *  Copyright (C) 1998-2000  Andre Hedrick <andre@linux-ide.org>
+ *  Copyright (C) 1995-1998  Mark Lord
+ *  Copyright (C)      2007  Bartlomiej Zolnierkiewicz
  *
- *  Copyright (c) 1998-2000  Andre Hedrick <andre@linux-ide.org>
- *
- *  Copyright (c) 1995-1998  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
  */
 
@@ -140,6 +139,16 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+static void ide_pci_clear_simplex(unsigned long dma_base, const char *name)
+{
+       u8 dma_stat = inb(dma_base + 2);
+
+       outb(dma_stat & 0x60, dma_base + 2);
+       dma_stat = inb(dma_base + 2);
+       if (dma_stat & 0x80)
+               printk(KERN_INFO "%s: simplex device: DMA forced\n", name);
+}
+
 /**
  *     ide_get_or_set_dma_base         -       setup BMIBA
  *     @d: IDE port info
@@ -152,8 +161,9 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
 
 static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif)
 {
-       unsigned long   dma_base = 0;
-       struct pci_dev  *dev = hwif->pci_dev;
+       struct pci_dev *dev = to_pci_dev(hwif->dev);
+       unsigned long dma_base = 0;
+       u8 dma_stat = 0;
 
        if (hwif->mmio)
                return hwif->dma_base;
@@ -174,52 +184,30 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
        if (hwif->channel)
                dma_base += 8;
 
-       if ((d->host_flags & IDE_HFLAG_CS5520) == 0) {
-               u8 simplex_stat = 0;
-
-               switch(dev->device) {
-                       case PCI_DEVICE_ID_AL_M5219:
-                       case PCI_DEVICE_ID_AL_M5229:
-                       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 = inb(dma_base + 2);
-                               outb(simplex_stat & 0x60, dma_base + 2);
-                               simplex_stat = inb(dma_base + 2);
-                               if (simplex_stat & 0x80) {
-                                       printk(KERN_INFO "%s: simplex device: "
-                                                        "DMA forced\n",
-                                                        d->name);
-                               }
-                               break;
-                       default:
-                               /*
-                                * If the device claims "simplex" DMA,
-                                * this means only one of the two interfaces
-                                * can be trusted with DMA at any point in time.
-                                * So we should enable DMA only on one of the
-                                * two interfaces.
-                                */
-                               simplex_stat = hwif->INB(dma_base + 2);
-                               if (simplex_stat & 0x80) {
-                                       /* simplex device? */
-/*
- *     At this point we haven't probed the drives so we can't make the
- *     appropriate decision. Really we should defer this problem
- *     until we tune the drive then try to grab DMA ownership if we want
- *     to be the DMA end. This has to be become dynamic to handle hot
- *     plug.
- */
-                                       if (hwif->mate && hwif->mate->dma_base) {
-                                               printk(KERN_INFO "%s: simplex device: "
-                                                                "DMA disabled\n",
-                                                                d->name);
-                                               dma_base = 0;
-                                       }
-                               }
-               }
+       if (d->host_flags & IDE_HFLAG_CS5520)
+               goto out;
+
+       if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) {
+               ide_pci_clear_simplex(dma_base, d->name);
+               goto out;
+       }
+
+       /*
+        * If the device claims "simplex" DMA, this means that only one of
+        * the two interfaces can be trusted with DMA at any point in time
+        * (so we should enable DMA only on one of the two interfaces).
+        *
+        * FIXME: At this point we haven't probed the drives so we can't make
+        * the appropriate decision.  Really we should defer this problem until
+        * we tune the drive then try to grab DMA ownership if we want to be
+        * the DMA end.  This has to be become dynamic to handle hot-plug.
+        */
+       dma_stat = hwif->INB(dma_base + 2);
+       if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {
+               printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name);
+               dma_base = 0;
        }
+out:
        return dma_base;
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
@@ -240,7 +228,9 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
  *     @d: IDE port info
  *
  *     Enable the IDE PCI device. We attempt to enable the device in full
- *     but if that fails then we only need BAR4 so we will enable that.
+ *     but if that fails then we only need IO space. The PCI code should
+ *     have setup the proper resources for us already for controllers in
+ *     legacy mode.
  *     
  *     Returns zero on success or an error code
  */
@@ -250,7 +240,7 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
        int ret;
 
        if (pci_enable_device(dev)) {
-               ret = pci_enable_device_bars(dev, 1 << 4);
+               ret = pci_enable_device_io(dev);
                if (ret < 0) {
                        printk(KERN_WARNING "%s: (ide_setup_pci_device:) "
                                "Could not enable device.\n", d->name);
@@ -349,7 +339,8 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
  *     ide_hwif_configure      -       configure an IDE interface
  *     @dev: PCI device holding interface
  *     @d: IDE port info
- *     @mate: Paired interface if any
+ *     @port: port number
+ *     @irq: PCI IRQ
  *
  *     Perform the initial set up for the hardware interface structure. This
  *     is done per interface port rather than per PCI device. There may be
@@ -358,7 +349,9 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
  *     Returns the new hardware interface structure, or NULL on a failure
  */
 
-static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *mate, int port, int irq)
+static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
+                                     const struct ide_port_info *d,
+                                     unsigned int port, int irq)
 {
        unsigned long ctl = 0, base = 0;
        ide_hwif_t *hwif;
@@ -402,31 +395,26 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
 
        hwif->noprobe = oldnoprobe;
 
-       hwif->pci_dev = dev;
+       hwif->dev = &dev->dev;
        hwif->cds = d;
-       hwif->channel = port;
 
-       if (mate) {
-               hwif->mate = mate;
-               mate->mate = hwif;
-       }
        return hwif;
 }
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *     ide_hwif_setup_dma      -       configure DMA interface
- *     @dev: PCI device
- *     @d: IDE port info
  *     @hwif: IDE interface
+ *     @d: IDE port info
  *
  *     Set up the DMA base for the interface. Enable the master bits as
  *     necessary and attempt to bring the device DMA into a ready to use
  *     state
  */
 
-static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif)
+void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+       struct pci_dev *dev = to_pci_dev(hwif->dev);
        u16 pcicmd;
 
        pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
@@ -451,15 +439,15 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *
                        if (d->init_dma) {
                                d->init_dma(hwif, dma_base);
                        } else {
-                               ide_setup_dma(hwif, dma_base, 8);
+                               ide_setup_dma(hwif, dma_base);
                        }
                } else {
                        printk(KERN_INFO "%s: %s Bus-Master DMA disabled "
                                "(BIOS)\n", hwif->name, d->name);
                }
        }
-#endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
 }
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 /**
  *     ide_setup_pci_controller        -       set up IDE PCI
@@ -521,7 +509,7 @@ out:
 void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int pciirq, u8 *idx)
 {
        int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
-       ide_hwif_t *hwif, *mate = NULL;
+       ide_hwif_t *hwif;
        u8 tmp;
 
        /*
@@ -537,56 +525,11 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
                        continue;       /* port not enabled */
                }
 
-               if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
+               hwif = ide_hwif_configure(dev, d, port, pciirq);
+               if (hwif == NULL)
                        continue;
 
                *(idx + port) = hwif->index;
-
-               if (d->init_iops)
-                       d->init_iops(hwif);
-
-               if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
-                       ide_hwif_setup_dma(dev, d, hwif);
-
-               if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
-                   (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
-                       hwif->irq = port ? 15 : 14;
-
-               hwif->host_flags = d->host_flags;
-               hwif->pio_mask = d->pio_mask;
-
-               if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
-                       hwif->mate->serialized = hwif->serialized = 1;
-
-               if (d->host_flags & IDE_HFLAG_IO_32BIT) {
-                       hwif->drives[0].io_32bit = 1;
-                       hwif->drives[1].io_32bit = 1;
-               }
-
-               if (d->host_flags & IDE_HFLAG_UNMASK_IRQS) {
-                       hwif->drives[0].unmask = 1;
-                       hwif->drives[1].unmask = 1;
-               }
-
-               if (hwif->dma_base) {
-                       hwif->swdma_mask = d->swdma_mask;
-                       hwif->mwdma_mask = d->mwdma_mask;
-                       hwif->ultra_mask = d->udma_mask;
-               }
-
-               hwif->drives[0].autotune = 1;
-               hwif->drives[1].autotune = 1;
-
-               if (d->host_flags & IDE_HFLAG_RQSIZE_256)
-                       hwif->rqsize = 256;
-
-               if (d->init_hwif)
-                       /* Call chipset-specific routine
-                        * for each enabled hwif
-                        */
-                       d->init_hwif(hwif);
-
-               mate = hwif;
        }
 }
 
@@ -668,7 +611,7 @@ int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
        ret = do_ide_setup_pci_device(dev, d, &idx[0], 1);
 
        if (ret >= 0)
-               ide_device_add(idx);
+               ide_device_add(idx, d);
 
        return ret;
 }
@@ -692,7 +635,7 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
                        goto out;
        }
 
-       ide_device_add(idx);
+       ide_device_add(idx, d);
 out:
        return ret;
 }