From b323e1dfd14fa4fed77f9360f16e80f23ed917f3 Mon Sep 17 00:00:00 2001 From: John Rose Date: Thu, 29 Jan 2004 00:54:22 -0800 Subject: [PATCH] PCI: Allow pci hotplug drivers to initialize individual devices. This lets the PPC pci hotplug driver initialize single devices, not just entire slots. --- drivers/pci/probe.c | 66 ++++++++++++++++++++++++++++++++--------------------- 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); -- cgit v1.2.3