--- zzzz-none-000/linux-2.6.32.61/drivers/pci/search.c 2013-06-10 09:43:48.000000000 +0000 +++ virian-300e-630/linux-2.6.32.61/drivers/pci/search.c 2012-10-17 09:15:08.000000000 +0000 @@ -14,6 +14,31 @@ #include "pci.h" DECLARE_RWSEM(pci_bus_sem); + +#if defined(CONFIG_IFX_PCIE) && defined (CONFIG_PCIEAER) +static DEFINE_SPINLOCK(pci_bus_spinlock); +static unsigned long pci_bus_lock_flags; +#endif /* CONFIG_IFX_PCIE */ + +static void pci_bus_lock(void) +{ +#if defined(CONFIG_IFX_PCIE) && defined (CONFIG_PCIEAER) + spin_lock_irqsave(&pci_bus_spinlock, pci_bus_lock_flags); +#else + WARN_ON(in_interrupt()); + down_read(&pci_bus_sem); +#endif +} + +static void pci_bus_unlock(void) +{ +#if defined(CONFIG_IFX_PCIE) && defined (CONFIG_PCIEAER) + spin_unlock_irqrestore(&pci_bus_spinlock, pci_bus_lock_flags); +#else + WARN_ON(in_interrupt()); + up_read(&pci_bus_sem); +#endif +} /* * find the upstream PCIE-to-PCI bridge of a PCI device * if the device is PCIE, return NULL @@ -114,6 +139,31 @@ } /** + * pci_find_preexist_bus_nr - find the maximum bus number before the current bus + * @from: the current bus number. + * + * Iterates through the list of known PCI busses and return the maximum bus number + * in front of the current bus. + */ +int +pci_find_preexist_bus_nr(const struct pci_bus *from) +{ + struct pci_bus *bus = NULL; + int max = 0; /* If only one host controller existed */ + + pci_bus_lock(); + list_for_each_entry(bus, &pci_root_buses, node) { + if (bus->sysdata == from->sysdata) { /* Hit the same host controller,skip */ + break; + } + max = pci_bus_max_busnr(bus) + 1; + } + pci_bus_unlock(); + return max; +} +EXPORT_SYMBOL(pci_find_preexist_bus_nr); + +/** * pci_get_slot - locate PCI device for a given PCI slot * @bus: PCI bus on which desired PCI device resides * @devfn: encodes number of PCI slot in which the desired PCI @@ -132,9 +182,7 @@ struct list_head *tmp; struct pci_dev *dev; - WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); - + pci_bus_lock(); list_for_each(tmp, &bus->devices) { dev = pci_dev_b(tmp); if (dev->devfn == devfn) @@ -144,7 +192,7 @@ dev = NULL; out: pci_dev_get(dev); - up_read(&pci_bus_sem); + pci_bus_unlock(); return dev; }