18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * support for probing IDE PCI devices in the PCI bus order
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (c) 1998-2000  Andre Hedrick <andre@linux-ide.org>
58c2ecf20Sopenharmony_ci * Copyright (c) 1995-1998  Mark Lord
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * May be copied or modified under the terms of the GNU General Public License
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/kernel.h>
118c2ecf20Sopenharmony_ci#include <linux/init.h>
128c2ecf20Sopenharmony_ci#include <linux/module.h>
138c2ecf20Sopenharmony_ci#include <linux/ide.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/*
168c2ecf20Sopenharmony_ci *	Module interfaces
178c2ecf20Sopenharmony_ci */
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistatic int pre_init = 1;		/* Before first ordered IDE scan */
208c2ecf20Sopenharmony_cistatic LIST_HEAD(ide_pci_drivers);
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/*
238c2ecf20Sopenharmony_ci *	__ide_pci_register_driver	-	attach IDE driver
248c2ecf20Sopenharmony_ci *	@driver: pci driver
258c2ecf20Sopenharmony_ci *	@module: owner module of the driver
268c2ecf20Sopenharmony_ci *
278c2ecf20Sopenharmony_ci *	Registers a driver with the IDE layer. The IDE layer arranges that
288c2ecf20Sopenharmony_ci *	boot time setup is done in the expected device order and then
298c2ecf20Sopenharmony_ci *	hands the controllers off to the core PCI code to do the rest of
308c2ecf20Sopenharmony_ci *	the work.
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci *	Returns are the same as for pci_register_driver
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ciint __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
368c2ecf20Sopenharmony_ci			      const char *mod_name)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	if (!pre_init)
398c2ecf20Sopenharmony_ci		return __pci_register_driver(driver, module, mod_name);
408c2ecf20Sopenharmony_ci	driver->driver.owner = module;
418c2ecf20Sopenharmony_ci	list_add_tail(&driver->node, &ide_pci_drivers);
428c2ecf20Sopenharmony_ci	return 0;
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__ide_pci_register_driver);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/**
478c2ecf20Sopenharmony_ci *	ide_scan_pcidev		-	find an IDE driver for a device
488c2ecf20Sopenharmony_ci *	@dev: PCI device to check
498c2ecf20Sopenharmony_ci *
508c2ecf20Sopenharmony_ci *	Look for an IDE driver to handle the device we are considering.
518c2ecf20Sopenharmony_ci *	This is only used during boot up to get the ordering correct. After
528c2ecf20Sopenharmony_ci *	boot up the pci layer takes over the job.
538c2ecf20Sopenharmony_ci */
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic int __init ide_scan_pcidev(struct pci_dev *dev)
568c2ecf20Sopenharmony_ci{
578c2ecf20Sopenharmony_ci	struct list_head *l;
588c2ecf20Sopenharmony_ci	struct pci_driver *d;
598c2ecf20Sopenharmony_ci	int ret;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	list_for_each(l, &ide_pci_drivers) {
628c2ecf20Sopenharmony_ci		d = list_entry(l, struct pci_driver, node);
638c2ecf20Sopenharmony_ci		if (d->id_table) {
648c2ecf20Sopenharmony_ci			const struct pci_device_id *id =
658c2ecf20Sopenharmony_ci				pci_match_id(d->id_table, dev);
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci			if (id != NULL) {
688c2ecf20Sopenharmony_ci				pci_assign_irq(dev);
698c2ecf20Sopenharmony_ci				ret = d->probe(dev, id);
708c2ecf20Sopenharmony_ci				if (ret >= 0) {
718c2ecf20Sopenharmony_ci					dev->driver = d;
728c2ecf20Sopenharmony_ci					pci_dev_get(dev);
738c2ecf20Sopenharmony_ci					return 1;
748c2ecf20Sopenharmony_ci				}
758c2ecf20Sopenharmony_ci			}
768c2ecf20Sopenharmony_ci		}
778c2ecf20Sopenharmony_ci	}
788c2ecf20Sopenharmony_ci	return 0;
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/**
828c2ecf20Sopenharmony_ci *	ide_scan_pcibus		-	perform the initial IDE driver scan
838c2ecf20Sopenharmony_ci *
848c2ecf20Sopenharmony_ci *	Perform the initial bus rather than driver ordered scan of the
858c2ecf20Sopenharmony_ci *	PCI drivers. After this all IDE pci handling becomes standard
868c2ecf20Sopenharmony_ci *	module ordering not traditionally ordered.
878c2ecf20Sopenharmony_ci */
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic int __init ide_scan_pcibus(void)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	struct pci_dev *dev = NULL;
928c2ecf20Sopenharmony_ci	struct pci_driver *d, *tmp;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	pre_init = 0;
958c2ecf20Sopenharmony_ci	for_each_pci_dev(dev)
968c2ecf20Sopenharmony_ci		ide_scan_pcidev(dev);
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	/*
998c2ecf20Sopenharmony_ci	 *	Hand the drivers over to the PCI layer now we
1008c2ecf20Sopenharmony_ci	 *	are post init.
1018c2ecf20Sopenharmony_ci	 */
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	list_for_each_entry_safe(d, tmp, &ide_pci_drivers, node) {
1048c2ecf20Sopenharmony_ci		list_del(&d->node);
1058c2ecf20Sopenharmony_ci		if (__pci_register_driver(d, d->driver.owner,
1068c2ecf20Sopenharmony_ci					  d->driver.mod_name))
1078c2ecf20Sopenharmony_ci			printk(KERN_ERR "%s: failed to register %s driver\n",
1088c2ecf20Sopenharmony_ci					__func__, d->driver.mod_name);
1098c2ecf20Sopenharmony_ci	}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	return 0;
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_cidevice_initcall(ide_scan_pcibus);
114