linux/drivers/ide/ide-scan-pci.c

112 lines
2.7 KiB
C
Raw Normal View History

/*
* support for probing IDE PCI devices in the PCI bus order
*
* 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
*/
ide: make remaining built-in only IDE host drivers modular (take 2) * Make remaining built-in only IDE host drivers modular, add ide-scan-pci.c file for probing PCI host drivers registered with IDE core (special case for built-in IDE and CONFIG_IDEPCI_PCIBUS_ORDER=y) and then take care of the ordering in which all IDE host drivers are probed when IDE is built-in during link time. * Move probing of gayle, falconide, macide, q40ide and buddha (m68k arch specific) host drivers, before PCI ones (no PCI on m68k), ide-cris (cris arch specific), cmd640 (x86 arch specific) and pmac (ppc arch specific). * Move probing of ide-cris (cris arch specific) host driver before cmd640 (x86 arch specific). * Move probing of mpc8xx (ppc specific) host driver before ide-pnp (depends on ISA and none of ppc platform that use mpc8xx supports ISA) and ide-h8300 (h8300 arch specific). * Add "probe_vlb" kernel parameter to cmd640 host driver and update Documentation/ide.txt accordingly. * Make IDE_ARM config option visible so it can also be disabled if needed. * Remove bogus comment from ide.c while at it. v2: * Fix two issues spotted by Sergei: - replace ENOMEM error value by ENOENT in ide-h8300 host driver - fix MODULE_PARM_DESC() in cmd640 host driver Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: Mikael Starvik <starvik@axis.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Roman Zippel <zippel@linux-m68k.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-01-26 20:13:07 +01:00
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
/*
* 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.
*
* 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
*
* 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.
*/
static int __init ide_scan_pcibus(void)
{
struct pci_dev *dev = NULL;
struct pci_driver *d;
struct list_head *l, *n;
pre_init = 0;
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
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 %s driver\n",
__FUNCTION__, d->driver.mod_name);
}
return 0;
}
module_init(ide_scan_pcibus);