summaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-scan-pci.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-26 22:54:32 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-26 22:54:32 -0800
commit1c7c2cdec3a6b2873439096983794a550d7ff65b (patch)
tree10ea67846407e9882d50e95a9db675140dd423eb /drivers/ide/ide-scan-pci.c
parent0444fa78751260b38f0db3418e001bf86593f05f (diff)
parent7267c3377443322588cddaf457cf106839a60463 (diff)
downloadlinux-1c7c2cdec3a6b2873439096983794a550d7ff65b.tar.gz
linux-1c7c2cdec3a6b2873439096983794a550d7ff65b.tar.bz2
linux-1c7c2cdec3a6b2873439096983794a550d7ff65b.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (63 commits) ide: remove REQ_TYPE_ATA_CMD ide: switch ide_cmd_ioctl() to use REQ_TYPE_ATA_TASKFILE requests ide: switch set_xfer_rate() to use REQ_TYPE_ATA_TASKFILE requests ide: fix final status check in drive_cmd_intr() ide: check BUSY and ERROR status bits before reading data in drive_cmd_intr() ide: don't enable local IRQs for PIO-in in driver_cmd_intr() (take 2) ide: convert "empty" REQ_TYPE_ATA_CMD requests to use REQ_TYPE_ATA_TASKFILE ide: initialize rq->cmd_type in ide_init_drive_cmd() callers ide: use wait_drive_not_busy() in drive_cmd_intr() (take 2) ide: kill DATA_READY define ide: task_end_request() fix ide: use rq->nr_sectors in task_end_request() ide: remove needless ->cursg clearing from task_end_request() ide: set IDE_TFLAG_IN_* flags before queuing/executing command ide-tape: fix handling of non-special requests in ->end_request method ide: fix final status check in task_in_intr() ide: clear HOB bit for REQ_TYPE_ATA_CMD requests in ide_end_drive_cmd() ide: fix ->io_32bit race in ide_taskfile_ioctl() cmd64x: remove /proc/ide/cmd64x ide: remove broken disk byte-swapping support ...
Diffstat (limited to 'drivers/ide/ide-scan-pci.c')
-rw-r--r--drivers/ide/ide-scan-pci.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c
new file mode 100644
index 000000000000..7ffa332d77ce
--- /dev/null
+++ b/drivers/ide/ide-scan-pci.c
@@ -0,0 +1,121 @@
+/*
+ * 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
+ */
+
+#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.
+ */
+
+int __init ide_scan_pcibus(void)
+{
+ struct pci_dev *dev = NULL;
+ struct pci_driver *d;
+ struct list_head *l, *n;
+
+ pre_init = 0;
+ if (!ide_scan_direction)
+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
+ ide_scan_pcidev(dev);
+ else
+ while ((dev = pci_get_device_reverse(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;
+}
+
+static int __init ide_scan_pci(void)
+{
+ return ide_scan_pcibus();
+}
+
+module_init(ide_scan_pci);