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