X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fide%2Fsetup-pci.c;h=e501675ad72e6d03f1cf8e190ef6a127ac410204;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=b485e6b706c89a4ffb1f84327f27c4316ab7677d;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index b485e6b70..e501675ad 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -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);