linux/drivers/ide/ide-scan-pci.c
<<
>>
Prefs
   1/*
   2 * support for probing IDE PCI devices in the PCI bus order
   3 *
   4 * Copyright (c) 1998-2000  Andre Hedrick <andre@linux-ide.org>
   5 * Copyright (c) 1995-1998  Mark Lord
   6 *
   7 * May be copied or modified under the terms of the GNU General Public License
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/init.h>
  12#include <linux/module.h>
  13#include <linux/ide.h>
  14
  15/*
  16 *      Module interfaces
  17 */
  18
  19static int pre_init = 1;                /* Before first ordered IDE scan */
  20static LIST_HEAD(ide_pci_drivers);
  21
  22/*
  23 *      __ide_pci_register_driver       -       attach IDE driver
  24 *      @driver: pci driver
  25 *      @module: owner module of the driver
  26 *
  27 *      Registers a driver with the IDE layer. The IDE layer arranges that
  28 *      boot time setup is done in the expected device order and then
  29 *      hands the controllers off to the core PCI code to do the rest of
  30 *      the work.
  31 *
  32 *      Returns are the same as for pci_register_driver
  33 */
  34
  35int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
  36                              const char *mod_name)
  37{
  38        if (!pre_init)
  39                return __pci_register_driver(driver, module, mod_name);
  40        driver->driver.owner = module;
  41        list_add_tail(&driver->node, &ide_pci_drivers);
  42        return 0;
  43}
  44EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
  45
  46/**
  47 *      ide_scan_pcidev         -       find an IDE driver for a device
  48 *      @dev: PCI device to check
  49 *
  50 *      Look for an IDE driver to handle the device we are considering.
  51 *      This is only used during boot up to get the ordering correct. After
  52 *      boot up the pci layer takes over the job.
  53 */
  54
  55static int __init ide_scan_pcidev(struct pci_dev *dev)
  56{
  57        struct list_head *l;
  58        struct pci_driver *d;
  59        int ret;
  60
  61        list_for_each(l, &ide_pci_drivers) {
  62                d = list_entry(l, struct pci_driver, node);
  63                if (d->id_table) {
  64                        const struct pci_device_id *id =
  65                                pci_match_id(d->id_table, dev);
  66
  67                        if (id != NULL) {
  68                                pci_assign_irq(dev);
  69                                ret = d->probe(dev, id);
  70                                if (ret >= 0) {
  71                                        dev->driver = d;
  72                                        pci_dev_get(dev);
  73                                        return 1;
  74                                }
  75                        }
  76                }
  77        }
  78        return 0;
  79}
  80
  81/**
  82 *      ide_scan_pcibus         -       perform the initial IDE driver scan
  83 *
  84 *      Perform the initial bus rather than driver ordered scan of the
  85 *      PCI drivers. After this all IDE pci handling becomes standard
  86 *      module ordering not traditionally ordered.
  87 */
  88
  89static int __init ide_scan_pcibus(void)
  90{
  91        struct pci_dev *dev = NULL;
  92        struct pci_driver *d;
  93        struct list_head *l, *n;
  94
  95        pre_init = 0;
  96        for_each_pci_dev(dev)
  97                ide_scan_pcidev(dev);
  98
  99        /*
 100         *      Hand the drivers over to the PCI layer now we
 101         *      are post init.
 102         */
 103
 104        list_for_each_safe(l, n, &ide_pci_drivers) {
 105                list_del(l);
 106                d = list_entry(l, struct pci_driver, node);
 107                if (__pci_register_driver(d, d->driver.owner,
 108                                          d->driver.mod_name))
 109                        printk(KERN_ERR "%s: failed to register %s driver\n",
 110                                        __func__, d->driver.mod_name);
 111        }
 112
 113        return 0;
 114}
 115device_initcall(ide_scan_pcibus);
 116