X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fide%2Fsetup-pci.c;h=5171601fb2556646544587466a14b8e973389a15;hb=854a989546c12683186c84601d4902591dddd8a9;hp=3d101f73f9108399ba093e7a0ae4e3fdfdc6331b;hpb=9ff6f72f432364991d68e99cae72cb141c166e70;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 3d101f7..5171601 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -1,17 +1,11 @@ /* - * linux/drivers/ide/setup-pci.c Version 1.10 2002/08/19 + * Copyright (C) 1998-2000 Andre Hedrick + * Copyright (C) 1995-1998 Mark Lord + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * - * Copyright (c) 1998-2000 Andre Hedrick - * - * Copyright (c) 1995-1998 Mark Lord * May be copied or modified under the terms of the GNU General Public License */ -/* - * This module provides support for automatic detection and - * configuration of all PCI IDE interfaces present in a system. - */ - #include #include #include @@ -26,84 +20,6 @@ #include #include - -/** - * ide_match_hwif - match a PCI IDE against an ide_hwif - * @io_base: I/O base of device - * @bootable: set if its bootable - * @name: name of device - * - * 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 - * - * FIXME: we need to handle mmio matches here too - */ - -static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char *name) -{ - int h; - ide_hwif_t *hwif; - - /* - * Look for a hwif with matching io_base specified using - * parameters to ide_setup(). - */ - for (h = 0; h < MAX_HWIFS; ++h) { - hwif = &ide_hwifs[h]; - if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) { - if (hwif->chipset == ide_forced) - return hwif; /* a perfect match */ - } - } - /* - * Look for a hwif with matching io_base default value. - * If chipset is "ide_unknown", then claim that hwif slot. - * Otherwise, some other chipset has already claimed it.. :( - */ - for (h = 0; h < MAX_HWIFS; ++h) { - hwif = &ide_hwifs[h]; - if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) { - if (hwif->chipset == ide_unknown) - return hwif; /* match */ - printk(KERN_ERR "%s: port 0x%04lx already claimed by %s\n", - name, io_base, hwif->name); - return NULL; /* already claimed */ - } - } - /* - * Okay, there is no hwif matching our io_base, - * so we'll just claim an unassigned slot. - * Give preference to claiming other slots before claiming ide0/ide1, - * just in case there's another interface yet-to-be-scanned - * which uses ports 1f0/170 (the ide0/ide1 defaults). - * - * Unless there is a bootable card that does not use the standard - * ports 1f0/170 (the ide0/ide1 defaults). The (bootable) flag. - */ - if (bootable) { - for (h = 0; h < MAX_HWIFS; ++h) { - hwif = &ide_hwifs[h]; - if (hwif->chipset == ide_unknown) - return hwif; /* pick an unused entry */ - } - } else { - for (h = 2; h < MAX_HWIFS; ++h) { - hwif = ide_hwifs + h; - if (hwif->chipset == ide_unknown) - return hwif; /* pick an unused entry */ - } - } - for (h = 0; h < 2 && h < MAX_HWIFS; ++h) { - hwif = ide_hwifs + h; - if (hwif->chipset == ide_unknown) - return hwif; /* pick an unused entry */ - } - printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", name); - return NULL; -} - /** * ide_setup_pci_baseregs - place a PCI IDE controller native * @dev: PCI device of interface to switch native @@ -111,13 +27,13 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char * * We attempt to place the PCI interface into PCI native mode. If * we succeed the BARs are ok and the controller is in PCI mode. - * Returns 0 on success or an errno code. + * Returns 0 on success or an errno code. * * FIXME: if we program the interface and then fail to set the BARS * we don't switch it back to legacy mode. Do we actually care ?? */ - -static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) + +static int ide_setup_pci_baseregs(struct pci_dev *dev, const char *name) { u8 progif = 0; @@ -145,19 +61,31 @@ 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 - * @hwif: Interface + * 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 (ide_hwif_t *hwif) +unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) { - 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; @@ -165,90 +93,100 @@ static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif) if (hwif->mate && hwif->mate->dma_base) { dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8); } else { - dma_base = pci_resource_start(dev, 4); - if (!dma_base) { - printk(KERN_ERR "%s: dma_base is invalid\n", - hwif->cds->name); + u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4; + + dma_base = pci_resource_start(dev, baridx); + + if (dma_base == 0) { + printk(KERN_ERR "%s: DMA base is invalid\n", d->name); + return 0; } } - if (dma_base) { - u8 simplex_stat = 0; - dma_base += hwif->channel ? 8 : 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 = hwif->INB(dma_base + 2); - hwif->OUTB((simplex_stat&0x60),(dma_base + 2)); - simplex_stat = hwif->INB(dma_base + 2); - if (simplex_stat & 0x80) { - printk(KERN_INFO "%s: simplex device: " - "DMA forced\n", - hwif->cds->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? */ + if (hwif->channel) + dma_base += 8; + + 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; +} +EXPORT_SYMBOL_GPL(ide_pci_dma_base); + /* - * 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. + * Set up BM-DMA capability (PnP BIOS should have done this) */ - if (hwif->mate && hwif->mate->dma_base) { - printk(KERN_INFO "%s: simplex device: " - "DMA disabled\n", - hwif->cds->name); - dma_base = 0; - } - } +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 dma_base; + + return 0; } +EXPORT_SYMBOL_GPL(ide_pci_set_master); #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ -void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d) +void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d) { - printk(KERN_INFO "%s: IDE controller at PCI slot %s\n", - d->name, pci_name(dev)); + printk(KERN_INFO "%s: IDE controller (0x%04x:0x%04x rev 0x%02x) at " + " PCI slot %s\n", d->name, dev->vendor, dev->device, + dev->revision, pci_name(dev)); } - EXPORT_SYMBOL_GPL(ide_setup_pci_noise); /** * ide_pci_enable - do PCI enables * @dev: PCI device - * @d: IDE pci device data + * @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 */ - -static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d) + +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_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); @@ -258,9 +196,9 @@ static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d) } /* - * assume all devices can do 32-bit dma for now. we can add a - * dma mask field to the ide_pci_device_t if we need it (or let - * lower level driver set the dma mask) + * assume all devices can do 32-bit DMA for now, we can add + * a DMA mask field to the struct ide_port_info if we need it + * (or let lower level driver set the DMA mask) */ ret = pci_set_dma_mask(dev, DMA_32BIT_MASK); if (ret < 0) { @@ -268,13 +206,21 @@ static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *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; } @@ -282,13 +228,13 @@ out: /** * ide_pci_configure - configure an unconfigured device * @dev: PCI device - * @d: IDE pci device data + * @d: IDE port info * * Enable and configure the PCI device we have been passed. * Returns zero on success or an error code. */ - -static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d) + +static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d) { u16 pcicmd = 0; /* @@ -298,8 +244,8 @@ static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d) * Maybe the user deliberately *disabled* the device, * but we'll eventually ignore it again if no drives respond. */ - if (ide_setup_pci_baseregs(dev, d->name) || pci_write_config_word(dev, PCI_COMMAND, pcicmd|PCI_COMMAND_IO)) - { + if (ide_setup_pci_baseregs(dev, d->name) || + pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_IO)) { printk(KERN_INFO "%s: device disabled (BIOS)\n", d->name); return -ENODEV; } @@ -316,38 +262,37 @@ static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d) /** * ide_pci_check_iomem - check a register is I/O - * @dev: pci device - * @d: ide_pci_device - * @bar: bar number + * @dev: PCI device + * @d: IDE port info + * @bar: BAR number * - * Checks if a BAR is configured and points to MMIO space. If so - * print an error and return an error code. Otherwise return 0 + * Checks if a BAR is configured and points to MMIO space. If so, + * return an error code. Otherwise return 0 */ - -static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar) + +static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, + int bar) { ulong flags = pci_resource_flags(dev, bar); - + /* Unconfigured ? */ if (!flags || pci_resource_len(dev, bar) == 0) return 0; - /* I/O space */ - if(flags & PCI_BASE_ADDRESS_IO_MASK) + /* I/O space */ + if (flags & IORESOURCE_IO) return 0; - + /* Bad */ - printk(KERN_ERR "%s: IO baseregs (BIOS) are reported " - "as MEM, report to " - ".\n", d->name); return -EINVAL; } /** * ide_hwif_configure - configure an IDE interface * @dev: PCI device holding interface - * @d: IDE pci data - * @mate: Paired interface if any + * @d: IDE port info + * @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 @@ -355,17 +300,23 @@ static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar * * Returns the new hardware interface structure, or NULL on a failure */ - -static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *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; + struct hw_regs_s hw; if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { - /* Possibly we should fail if these checks report true */ - ide_pci_check_iomem(dev, d, 2*port); - ide_pci_check_iomem(dev, d, 2*port+1); - + if (ide_pci_check_iomem(dev, d, 2 * port) || + ide_pci_check_iomem(dev, d, 2 * port + 1)) { + printk(KERN_ERR "%s: I/O baseregs (BIOS) are reported " + "as MEM for port %d!\n", d->name, port); + return NULL; + } + ctl = pci_resource_start(dev, 2*port+1); base = pci_resource_start(dev, 2*port); if ((ctl && !base) || (base && !ctl)) { @@ -374,95 +325,77 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d, return NULL; } } - if (!ctl) - { + if (!ctl) { /* Use default values */ ctl = port ? 0x374 : 0x3f4; base = port ? 0x170 : 0x1f0; } - if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL) - 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]; - } - hwif->chipset = ide_pci; - hwif->pci_dev = dev; - hwif->cds = (struct ide_pci_device_s *) d; - hwif->channel = port; - - if (!hwif->irq) - hwif->irq = irq; - if (mate) { - hwif->mate = mate; - mate->mate = hwif; + + hwif = ide_find_port_slot(d); + if (hwif == NULL) { + printk(KERN_ERR "%s: too many IDE interfaces, no room in " + "table\n", d->name); + return NULL; } + + memset(&hw, 0, sizeof(hw)); + hw.irq = irq; + hw.dev = &dev->dev; + hw.chipset = d->chipset ? d->chipset : ide_pci; + ide_std_init_ports(&hw, base, ctl | 2); + + ide_init_port_hw(hwif, &hw); + + hwif->dev = &dev->dev; + return hwif; } +#ifdef CONFIG_BLK_DEV_IDEDMA_PCI /** * ide_hwif_setup_dma - configure DMA interface - * @dev: PCI device - * @d: IDE pci data - * @hwif: Hardware interface we are configuring + * @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 */ - -#ifndef CONFIG_BLK_DEV_IDEDMA_PCI -static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif) -{ -} -#else -static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif) + +int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) { - u16 pcicmd; - pci_read_config_word(dev, PCI_COMMAND, &pcicmd); + struct pci_dev *dev = to_pci_dev(hwif->dev); - if ((d->autodma == AUTODMA) || + 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(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, 8); - } - } 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*/ +#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ /** * ide_setup_pci_controller - set up IDE PCI * @dev: PCI device - * @d: IDE PCI data + * @d: IDE port info * @noisy: verbose flag * @config: returned as 1 if we configured the hardware * @@ -470,11 +403,10 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi * up the PCI side of the device, checks that the device is enabled * and enables it if need be */ - -static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config) + +static int ide_setup_pci_controller(struct pci_dev *dev, const struct ide_port_info *d, int noisy, int *config) { int ret; - u32 class_rev; u16 pcicmd; if (noisy) @@ -497,10 +429,6 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in printk(KERN_INFO "%s: device enabled (Linux)\n", d->name); } - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - if (noisy) - printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev); out: return ret; } @@ -508,9 +436,9 @@ out: /** * ide_pci_setup_ports - configure ports/devices on PCI IDE * @dev: PCI device - * @d: IDE pci device info + * @d: IDE port info * @pciirq: IRQ line - * @index: ata index to update + * @idx: ATA index table to update * * Scan the interfaces attached to this device and do any * necessary per port setup. Attach the devices and ask the @@ -520,67 +448,33 @@ out: * but is also used directly as a helper function by some controllers * 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 pciirq, ata_index_t *index) + +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; - int at_least_one_hwif_enabled = 0; - ide_hwif_t *hwif, *mate = NULL; + ide_hwif_t *hwif; u8 tmp; - index->all = 0xf0f0; - /* * Set up the IDE ports */ - + for (port = 0; port < channels; ++port) { - ide_pci_enablebit_t *e = &(d->enablebits[port]); - + const ide_pci_enablebit_t *e = &(d->enablebits[port]); + if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || - (tmp & e->mask) != e->val)) + (tmp & e->mask) != e->val)) { + printk(KERN_INFO "%s: IDE port disabled\n", d->name); continue; /* port not enabled */ - - if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL) - continue; - - /* setup proper ancestral information */ - hwif->gendev.parent = &dev->dev; - - if (hwif->channel) { - index->b.high = hwif->index; - } else { - index->b.low = hwif->index; } - - if (d->init_iops) - d->init_iops(hwif); - - if (d->autodma == NODMA) - goto bypass_legacy_dma; + hwif = ide_hwif_configure(dev, d, port, pciirq); + if (hwif == NULL) + continue; - if(d->init_setup_dma) - d->init_setup_dma(dev, d, hwif); - else - ide_hwif_setup_dma(dev, d, hwif); -bypass_legacy_dma: - hwif->host_flags = d->host_flags; - hwif->pio_mask = d->pio_mask; - - if (d->init_hwif) - /* Call chipset-specific routine - * for each enabled hwif - */ - d->init_hwif(hwif); - - mate = hwif; - at_least_one_hwif_enabled = 1; + *(idx + port) = hwif->index; } - if (!at_least_one_hwif_enabled) - printk(KERN_INFO "%s: neither IDE port enabled (BIOS)\n", d->name); } - EXPORT_SYMBOL_GPL(ide_pci_setup_ports); /* @@ -590,13 +484,13 @@ EXPORT_SYMBOL_GPL(ide_pci_setup_ports); * * One thing that is not standardized is the location of the * primary/secondary interface "enable/disable" bits. For chipsets that - * we "know" about, this information is in the ide_pci_device_t struct; + * we "know" about, this information is in the struct ide_port_info; * for all other chipsets, we just assume both interfaces are enabled. */ -static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d, - ata_index_t *index, u8 noisy) +static int do_ide_setup_pci_device(struct pci_dev *dev, + const struct ide_port_info *d, + u8 *idx, u8 noisy) { - static ata_index_t ata_index = { .b = { .low = 0xff, .high = 0xff } }; int tried_config = 0; int pciirq, ret; @@ -646,51 +540,34 @@ static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d, /* FIXME: silent failure can happen */ - *index = ata_index; - ide_pci_setup_ports(dev, d, pciirq, index); + ide_pci_setup_ports(dev, d, pciirq, idx); out: return ret; } -int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) +int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d) { - ide_hwif_t *hwif = NULL, *mate = NULL; - ata_index_t index_list; + u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; 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) - hwif = &ide_hwifs[index_list.b.low]; - if ((index_list.b.high & 0xf0) != 0xf0) - mate = &ide_hwifs[index_list.b.high]; + ret = do_ide_setup_pci_device(dev, d, &idx[0], 1); - if (hwif) - probe_hwif_init_with_fixup(hwif, d->fixup); - if (mate) - probe_hwif_init_with_fixup(mate, d->fixup); + if (ret >= 0) + ide_device_add(idx, d); - if (hwif) - ide_proc_register_port(hwif); - if (mate) - ide_proc_register_port(mate); -out: return ret; } - EXPORT_SYMBOL_GPL(ide_setup_pci_device); int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, - ide_pci_device_t *d) + const struct ide_port_info *d) { struct pci_dev *pdev[] = { dev1, dev2 }; - ata_index_t index_list[2]; int ret, i; + u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; for (i = 0; i < 2; i++) { - ret = do_ide_setup_pci_device(pdev[i], d, index_list + i, !i); + ret = do_ide_setup_pci_device(pdev[i], d, &idx[i*2], !i); /* * FIXME: Mom, mom, they stole me the helper function to undo * do_ide_setup_pci_device() on the first device! @@ -699,131 +576,8 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, 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]); - } - } - - 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) - ide_proc_register_port(ide_hwifs + idx[j]); - } - } + ide_device_add(idx, d); out: return ret; } - EXPORT_SYMBOL_GPL(ide_setup_pci_devices); - -#ifdef CONFIG_IDEPCI_PCIBUS_ORDER -/* - * Module interfaces - */ - -static int pre_init = 1; /* Before first ordered IDE scan */ -static LIST_HEAD(ide_pci_drivers); - -/* - * __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 - * hands the controllers off to the core PCI code to do the rest of - * the work. - * - * The driver_data of the driver table must point to an ide_pci_device_t - * describing the interface. - * - * Returns are the same as for pci_register_driver - */ - -int __ide_pci_register_driver(struct pci_driver *driver, struct module *module, - const char *mod_name) -{ - if(!pre_init) - return __pci_register_driver(driver, module, mod_name); - driver->driver.owner = module; - list_add_tail(&driver->node, &ide_pci_drivers); - return 0; -} - -EXPORT_SYMBOL_GPL(__ide_pci_register_driver); - -/** - * ide_scan_pcidev - find an IDE driver for a device - * @dev: PCI device to check - * - * Look for an IDE driver to handle the device we are considering. - * This is only used during boot up to get the ordering correct. After - * boot up the pci layer takes over the job. - */ - -static int __init ide_scan_pcidev(struct pci_dev *dev) -{ - struct list_head *l; - struct pci_driver *d; - - list_for_each(l, &ide_pci_drivers) { - d = list_entry(l, struct pci_driver, node); - if (d->id_table) { - const struct pci_device_id *id = pci_match_id(d->id_table, - dev); - if (id != NULL && d->probe(dev, id) >= 0) { - dev->driver = d; - pci_dev_get(dev); - return 1; - } - } - } - return 0; -} - -/** - * ide_scan_pcibus - perform the initial IDE driver scan - * @scan_direction: set for reverse order scanning - * - * Perform the initial bus rather than driver ordered scan of the - * PCI drivers. After this all IDE pci handling becomes standard - * module ordering not traditionally ordered. - */ - -void __init ide_scan_pcibus (int scan_direction) -{ - struct pci_dev *dev = NULL; - struct pci_driver *d; - struct list_head *l, *n; - - pre_init = 0; - if (!scan_direction) - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) - ide_scan_pcidev(dev); - else - while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, dev)) - != NULL) - ide_scan_pcidev(dev); - - /* - * Hand the drivers over to the PCI layer now we - * are post init. - */ - - list_for_each_safe(l, n, &ide_pci_drivers) { - list_del(l); - d = list_entry(l, struct pci_driver, node); - if (__pci_register_driver(d, d->driver.owner, d->driver.mod_name)) - printk(KERN_ERR "%s: failed to register driver for %s\n", - __FUNCTION__, d->driver.mod_name); - } -} -#endif