Messages in this thread Patch in this message |  | | Date | Wed, 5 Mar 2003 00:40:04 +0000 | From | Russell King <> | Subject | Re: [CFT] PCI probing for cardbus (3/5) |
| |
diff -u orig/drivers/pci/bus.c linux/drivers/pci/bus.c --- orig/drivers/pci/bus.c Mon Mar 3 21:24:55 2003 +++ orig/drivers/pci/bus.c Mon Mar 3 21:26:41 2003 @@ -12,6 +12,10 @@ #include <linux/pci.h> #include <linux/errno.h> #include <linux/ioport.h> +#include <linux/proc_fs.h> +#include <linux/init.h> + +#include "pci.h" /** * pci_bus_alloc_resource - allocate a resource from a parent bus @@ -64,6 +68,47 @@ return ret; } +/** + * pci_bus_add_devices - insert newly discovered PCI devices + * @bus: bus to check for new devices + * + * Add newly discovered PCI devices (which are on the bus->devices + * list) to the global PCI device list, add the sysfs and procfs + * entries. Where a bridge is found, add the discovered bus to + * the parents list of child buses, and recurse. + * + * Call hotplug for each new devices. + */ +void __devinit pci_bus_add_devices(struct pci_bus *bus) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + /* + * Skip already-present devices (which are on the + * global device list.) + */ + if (!list_empty(&dev->global_list)) + continue; + + device_register(&dev->dev); + list_add_tail(&dev->global_list, &pci_devices); +#ifdef CONFIG_PROC_FS + pci_proc_attach_device(dev); +#endif + pci_create_sysfs_dev_files(dev); + + /* + * If there is an unattached subordinate bus, attach + * it and then scan for unattached PCI devices. + */ + if (dev->subordinate && list_empty(&dev->subordinate->node)) { + list_add_tail(&dev->subordinate->node, &dev->bus->children); + pci_bus_add_devices(dev->subordinate); + } + } +} + void pci_enable_bridges(struct pci_bus *bus) { struct pci_dev *dev; @@ -78,4 +123,5 @@ } EXPORT_SYMBOL(pci_bus_alloc_resource); +EXPORT_SYMBOL(pci_bus_add_devices); EXPORT_SYMBOL(pci_enable_bridges); diff -u orig/drivers/pci/probe.c linux/drivers/pci/probe.c --- orig/drivers/pci/probe.c Mon Mar 3 21:24:47 2003 +++ linux/drivers/pci/probe.c Mon Mar 3 21:25:47 2003 @@ -221,6 +221,7 @@ b = kmalloc(sizeof(*b), GFP_KERNEL); if (b) { memset(b, 0, sizeof(*b)); + INIT_LIST_HEAD(&b->node); INIT_LIST_HEAD(&b->children); INIT_LIST_HEAD(&b->devices); } @@ -477,10 +478,18 @@ return dev; } -struct pci_dev * __devinit pci_scan_slot(struct pci_bus *bus, int devfn) +/** + * pci_scan_slot - scan a PCI slot on a bus for devices. + * @bus: PCI bus to scan + * @devfn: slot number to scan (must have zero function.) + * + * Scan a PCI slot on the specified PCI bus for devices, adding + * discovered devices to the @bus->devices list. New devices + * will have an empty dev->global_list head. + */ +int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) { - struct pci_dev *first_dev = NULL; - int func; + int func, nr = 0; for (func = 0; func < 8; func++, devfn++) { struct pci_dev *dev; @@ -489,22 +498,19 @@ if (!dev) continue; - if (func == 0) { - first_dev = dev; - } else { + if (func != 0) dev->multifunction = 1; - } /* Fix up broken headers */ pci_fixup_device(PCI_FIXUP_HEADER, dev); /* - * Link the device to both the global PCI device chain and - * the per-bus list of devices and add the /proc entry. - * Note: this also runs the hotplug notifiers (bad!) --rmk + * Add the device to our list of discovered devices + * and the bus list for fixup functions, etc. */ - device_register(&dev->dev); - pci_insert_device (dev, bus); + INIT_LIST_HEAD(&dev->global_list); + list_add_tail(&dev->bus_list, &bus->devices); + nr++; /* * If this is a single function device, @@ -513,17 +519,15 @@ if (!dev->multifunction) break; } - return first_dev; + return nr; } -unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) +static unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) { - unsigned int devfn, max, pass; - struct list_head *ln; + unsigned int devfn, pass, max = bus->secondary; struct pci_dev *dev; DBG("Scanning bus %02x\n", bus->number); - max = bus->secondary; /* Go find them, Rover! */ for (devfn = 0; devfn < 0x100; devfn += 8) @@ -550,6 +554,20 @@ * Return how far we've got finding sub-buses. */ DBG("Bus scan for %02x returning with max=%02x\n", bus->number, max); + return max; +} + +unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) +{ + unsigned int max; + + max = pci_scan_child_bus(bus); + + /* + * Make the discovered devices available. + */ + pci_bus_add_devices(bus); + return max; } --- orig/include/linux/pci.h Tue Feb 25 23:34:29 2003 +++ linux/include/linux/pci.h Tue Feb 25 23:37:27 2003 @@ -549,7 +549,8 @@ { return pci_alloc_primary_bus_parented(NULL, bus); } -struct pci_dev *pci_scan_slot(struct pci_bus *bus, int devfn); +int pci_scan_slot(struct pci_bus *bus, int devfn); +void pci_bus_add_devices(struct pci_bus *bus); int pci_proc_attach_device(struct pci_dev *dev); int pci_proc_detach_device(struct pci_dev *dev); int pci_proc_attach_bus(struct pci_bus *bus); -- Russell King (rmk@arm.linux.org.uk) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |