]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/setup-pci.c
iwlwifi: add iwl5000_tx_response structure
[linux-2.6-omap-h63xx.git] / drivers / ide / setup-pci.c
index 6302010fd8e232ab17ad71d56f2c4e615aebc9da..5171601fb2556646544587466a14b8e973389a15 100644 (file)
@@ -72,16 +72,16 @@ static void ide_pci_clear_simplex(unsigned long dma_base, const char *name)
 }
 
 /**
- *     ide_get_or_set_dma_base         -       setup BMIBA
- *     @d: IDE port info
+ *     ide_pci_dma_base        -       setup BMIBA
  *     @hwif: IDE interface
+ *     @d: IDE port info
  *
  *     Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
  *     Where a device has a partner that is already in DMA mode we check
  *     and enforce IDE simplex rules.
  */
 
-static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif)
+unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
        struct pci_dev *dev = to_pci_dev(hwif->dev);
        unsigned long dma_base = 0;
@@ -132,6 +132,31 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
 out:
        return dma_base;
 }
+EXPORT_SYMBOL_GPL(ide_pci_dma_base);
+
+/*
+ * Set up BM-DMA capability (PnP BIOS should have done this)
+ */
+int ide_pci_set_master(struct pci_dev *dev, const char *name)
+{
+       u16 pcicmd;
+
+       pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
+
+       if ((pcicmd & PCI_COMMAND_MASTER) == 0) {
+               pci_set_master(dev);
+
+               if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) ||
+                   (pcicmd & PCI_COMMAND_MASTER) == 0) {
+                       printk(KERN_ERR "%s: error updating PCICMD on %s\n",
+                                       name, pci_name(dev));
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ide_pci_set_master);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
@@ -158,7 +183,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
 
 static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
 {
-       int ret;
+       int ret, bars;
 
        if (pci_enable_device(dev)) {
                ret = pci_enable_device_io(dev);
@@ -181,13 +206,21 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
                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. */
-       ret = pci_request_region(dev, 4, "ide_tmp");
-       if (ret < 0)
-               goto out;
+       if (d->host_flags & IDE_HFLAG_SINGLE)
+               bars = (1 << 2) - 1;
+       else
+               bars = (1 << 4) - 1;
 
-       pci_release_region(dev, 4);
+       if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
+               if (d->host_flags & IDE_HFLAG_CS5520)
+                       bars |= (1 << 2);
+               else
+                       bars |= (1 << 4);
+       }
+
+       ret = pci_request_selected_regions(dev, bars, d->name);
+       if (ret < 0)
+               printk(KERN_ERR "%s: can't reserve resources\n", d->name);
 out:
        return ret;
 }
@@ -314,7 +347,6 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
        ide_init_port_hw(hwif, &hw);
 
        hwif->dev = &dev->dev;
-       hwif->cds = d;
 
        return hwif;
 }
@@ -330,40 +362,33 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
  *     state
  */
 
-void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
+int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
        struct pci_dev *dev = to_pci_dev(hwif->dev);
-       u16 pcicmd;
-
-       pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
 
        if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
            ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
             (dev->class & 0x80))) {
-               unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);
-               if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
-                       /*
-                        * Set up BM-DMA capability
-                        * (PnP BIOS should have done this)
-                        */
-                       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",
-                                       hwif->name, d->name);
-                               dma_base = 0;
-                       }
-               }
-               if (dma_base) {
-                       if (d->init_dma) {
-                               d->init_dma(hwif, dma_base);
-                       } else {
-                               ide_setup_dma(hwif, dma_base);
-                       }
-               } else {
-                       printk(KERN_INFO "%s: %s Bus-Master DMA disabled "
-                               "(BIOS)\n", hwif->name, d->name);
-               }
+               unsigned long base = ide_pci_dma_base(hwif, d);
+
+               if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
+                       return -1;
+
+               if (hwif->mmio)
+                       printk(KERN_INFO "    %s: MMIO-DMA\n", hwif->name);
+               else
+                       printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx\n",
+                                        hwif->name, base, base + 7);
+
+               hwif->extra_base = base + (hwif->channel ? 8 : 16);
+
+               if (ide_allocate_dma_engine(hwif))
+                       return -1;
+
+               ide_setup_dma(hwif, base);
        }
+
+       return 0;
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */