diff options
| author | John Rose <johnrose@austin.ibm.com> | 2004-01-29 00:54:22 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2004-01-29 00:54:22 -0800 |
| commit | b323e1dfd14fa4fed77f9360f16e80f23ed917f3 (patch) | |
| tree | 9a6b3718a748c734553798e617dd2e538cc02641 | |
| parent | 66f070bafd53464d330435d4fc549cc7f6dea91c (diff) | |
[PATCH] PCI: Allow pci hotplug drivers to initialize individual devices.
This lets the PPC pci hotplug driver initialize single devices, not just
entire slots.
| -rw-r--r-- | drivers/pci/probe.c | 66 | ||||
| -rw-r--r-- | include/linux/pci.h | 1 |
2 files changed, 41 insertions, 26 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index be87193cff59..50391a0fd11e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -580,6 +580,30 @@ pci_scan_device(struct pci_bus *bus, int devfn) return dev; } +struct pci_dev * __devinit +pci_scan_single_device(struct pci_bus *bus, int devfn) +{ + struct pci_dev *dev; + + dev = pci_scan_device(bus, devfn); + pci_scan_msi_device(dev); + + if (!dev) + return NULL; + + /* Fix up broken headers */ + pci_fixup_device(PCI_FIXUP_HEADER, dev); + + /* + * Add the device to our list of discovered devices + * and the bus list for fixup functions, etc. + */ + INIT_LIST_HEAD(&dev->global_list); + list_add_tail(&dev->bus_list, &bus->devices); + + return dev; +} + /** * pci_scan_slot - scan a PCI slot on a bus for devices. * @bus: PCI bus to scan @@ -596,34 +620,23 @@ int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) for (func = 0; func < 8; func++, devfn++) { struct pci_dev *dev; - dev = pci_scan_device(bus, devfn); - pci_scan_msi_device(dev); - if (func == 0) { - if (!dev) - break; + dev = pci_scan_single_device(bus, devfn); + if (dev) { + nr++; + + /* + * If this is a single function device, + * don't scan past the first function. + */ + if (!dev->multifunction) + if (func > 0) + dev->multifunction = 1; + else + break; } else { - if (!dev) - continue; - dev->multifunction = 1; + if (func == 0) + break; } - - /* Fix up broken headers */ - pci_fixup_device(PCI_FIXUP_HEADER, dev); - - /* - * Add the device to our list of discovered devices - * and the bus list for fixup functions, etc. - */ - INIT_LIST_HEAD(&dev->global_list); - list_add_tail(&dev->bus_list, &bus->devices); - nr++; - - /* - * If this is a single function device, - * don't scan past the first function. - */ - if (!dev->multifunction) - break; } return nr; } @@ -734,4 +747,5 @@ EXPORT_SYMBOL(pci_add_new_bus); EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_bridge); +EXPORT_SYMBOL(pci_scan_single_device); #endif diff --git a/include/linux/pci.h b/include/linux/pci.h index 4178a8b148bb..3ffb95a8f4d2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -587,6 +587,7 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s return pci_scan_bus_parented(NULL, bus, ops, sysdata); } int pci_scan_slot(struct pci_bus *bus, int devfn); +struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); void pci_bus_add_devices(struct pci_bus *bus); void pci_name_device(struct pci_dev *dev); char *pci_class_name(u32 class); |
