[PATCH 02/23] powerpc/eeh: Function to tranverse PCI devices
Benjamin Herrenschmidt
benh at kernel.crashing.org
Sat Jun 1 14:13:03 EST 2013
On Thu, 2013-05-30 at 16:23 +0800, Gavin Shan wrote:
> For EEH on PowerNV platform, the PCI devices will be probed to
> check if they support EEH functionality. Different from the case
> of EEH for pSeries platform, we will probe real PCI device instead
> of device tree node for EEH capability on PowerNV platform.
>
> The patch introduces function eeh_pci_dev_traverse() to traverse
> PCI devices for the indicated PCI bus from top to bottom.
This seems racy vs. hotplug etc... Any reason you can't use
pci_walk_bus() from drivers/pci/bus.c ?
Cheers,
Ben.
> Signed-off-by: Gavin Shan <shangw at linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/eeh.h | 3 ++
> arch/powerpc/platforms/pseries/eeh_dev.c | 35 ++++++++++++++++++++++++++++++
> 2 files changed, 38 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
> index e32c3c5..eeaeab6 100644
> --- a/arch/powerpc/include/asm/eeh.h
> +++ b/arch/powerpc/include/asm/eeh.h
> @@ -183,6 +183,7 @@ static inline void eeh_unlock(void)
> #define EEH_MAX_ALLOWED_FREEZES 5
>
> typedef void *(*eeh_traverse_func)(void *data, void *flag);
> +typedef void *(*eeh_pci_traverse_func)(struct pci_dev *dev, void *flag);
> int eeh_phb_pe_create(struct pci_controller *phb);
> int eeh_add_to_parent_pe(struct eeh_dev *edev);
> int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe);
> @@ -191,6 +192,8 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root,
> void eeh_pe_restore_bars(struct eeh_pe *pe);
> struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);
>
> +void eeh_pci_dev_traverse(struct pci_bus *bus,
> + eeh_pci_traverse_func fn, void *flag);
> void *eeh_dev_init(struct device_node *dn, void *data);
> void eeh_dev_phb_init_dynamic(struct pci_controller *phb);
> int __init eeh_ops_register(struct eeh_ops *ops);
> diff --git a/arch/powerpc/platforms/pseries/eeh_dev.c b/arch/powerpc/platforms/pseries/eeh_dev.c
> index 1efa28f..12c445d 100644
> --- a/arch/powerpc/platforms/pseries/eeh_dev.c
> +++ b/arch/powerpc/platforms/pseries/eeh_dev.c
> @@ -41,6 +41,41 @@
> #include <asm/pci-bridge.h>
> #include <asm/ppc-pci.h>
>
> +
> +/**
> + * eeh_pci_dev_traverse - Traverse PCI devices for the indicated bus
> + * @bus: PCI bus
> + * @fn: callback function
> + * @flag: extra flag
> + *
> + * The function traverses the PCI devices for the indicated PCI bus
> + * from top to bottom fashion until the supplied callback function
> + * returns non-zero value on the specific PCI device.
> + */
> +void eeh_pci_dev_traverse(struct pci_bus *bus,
> + eeh_pci_traverse_func fn, void *flag)
> +{
> + struct pci_dev *dev;
> + void *ret;
> +
> + if (!bus)
> + return;
> +
> + /*
> + * We should make sure the parent devices are scanned
> + * prior to the child devices so that the parent PE
> + * could be created before the child PEs.
> + */
> + list_for_each_entry(dev, &bus->devices, bus_list) {
> + ret = fn(dev, flag);
> + if (ret)
> + return;
> +
> + if (dev->subordinate)
> + eeh_pci_dev_traverse(dev->subordinate, fn, flag);
> + }
> +}
> +
> /**
> * eeh_dev_init - Create EEH device according to OF node
> * @dn: device node
More information about the Linuxppc-dev
mailing list