From: Yijing Wang <hidden> Date: 2015-02-26 08:24:46
v3->v4:
Fix the rebase issue.
v2->v3:
Rebase this series on v4.0-rc1.
v1->v2:
Split pci_host_bridge_list into a new patch, remove .phb_probe_mode
and rework powerpc .phb_of_scan_bus() for simpilicty suggested by
Arnd. Refresh some patch description log, and add a new patch to fix
build warning in ia64.
This series is based on Bjorn's pci-next branch.
Patch 1-4 ripped out pci_bus_add_devices() from pci scan interfaces
for better pci scan flow.
Patch 5-11 make a generic pci_host_bridge to hold pci_host_bridge
related informations, and introduce a pci_host_bridge_ops to
support platform host drivers provide its own pci_host_bridge
related operations to setup pci_host_bridge during pci enumeration.
Patch 12-28 apply the new pci scan interfaces to platform pci host
bridge drivers.
Now in kernel, we scan pci bus use the following ways:
1. pci_scan_bus.
parent = NULL, default io/mem/bus resources
call pci_bus_add_devices()
2. pci_scan_bus_parented() + pci_bus_add_devices()
default io/mem/bus resources, only used by xen
3. pci_scan_root_bus() + pci_bus_add_devices()
4. pci_create_root_bus() + pci_scan_child_bus() + pci_bus_add_devices()
5. pci_create_root_bus() + xx_of_scan_bus() + pci_bus_add_devices()
And we have a lot of arch specific pci_domain_nr() and other platform
specific weak function like pcibios_root_bridge_prepare().
After applied this series, we have following scan interfaces:
1. pci_scan_bus_legacy()
parent = NULL, default io/mem/bus resources.
for legacy pci scan
2. pci_scan_root_bus()
for callers provide its own parent and io/mem/bus resources
but no platform specific pci_host_bridge operations
3. pci_scan_root_bridge()
for callers provide its own parent and io/mem/bus resources
Arnd Bergmann (1):
xen/PCI: Don't use deprecated function pci_scan_bus_parented()
Yijing Wang (29):
PCI: Rip out pci_bus_add_devices() from pci_scan_bus()
PCI: Rip out pci_bus_add_devices() from pci_scan_root_bus()
PCI: Remove deprecated pci_scan_bus_parented()
PCI: Rename pci_scan_bus() to pci_scan_bus_legacy()
PCI: Combine PCI domain and bus number in u32 arg
PCI: Pass PCI domain number combined with root bus number
PCI: Introduce pci_host_assign_domain_nr() to assign domain
PCI: Separate pci_host_bridge creation out of pci_create_root_bus()
PCI: Introduce pci_host_bridge_list to manage host bridges
PCI: Save sysdata in pci_host_bridge drvdata
PCI: Introduce pci_host_bridge_ops to support host specific
operations
PCI: Introduce new scan function pci_scan_root_bridge()
PCI/x86: Refine pci_acpi_scan_root() with generic pci_host_bridge
PCI/IA64: Refine pci_acpi_scan_root() with generic pci_host_bridge
PCI/IA64: Fix the build warning about pci_domain_nr()
PCI/powerpc: Rename pcibios_root_bridge_prepare()
PCI/powerpc: Use pci_scan_root_bridge() for simplicity
PCI: Remove weak pcibios_root_bridge_prepare()
PCI/sparc: Use pci_scan_root_bridge() for simplicity
PCI: Introduce pci_bus_child_max_busnr()
PCI/Parisc: Use pci_scan_root_bus() for simplicity
PCI/mvebu: Use pci_common_init_dev() to simplify code
PCI/tegra: Remove redundant tegra_pcie_scan_bus()
PCI/designware: Use pci_scan_root_bus() for simplicity
PCI/xgene: Use pci_scan_root_bus() instead of pci_create_root_bus()
PCI: Rename __pci_create_root_bus() to pci_create_root_bus()
PCI: Export find_pci_host_bridge()
PCI: Remove platform specific pci_domain_nr()
PCI: Remove pci_bus_assign_domain_nr()
arch/alpha/include/asm/pci.h | 2 -
arch/alpha/kernel/pci.c | 7 +-
arch/alpha/kernel/sys_nautilus.c | 4 +-
arch/frv/mb93090-mb00/pci-vdk.c | 6 +-
arch/ia64/include/asm/pci.h | 1 -
arch/ia64/pci/pci.c | 34 +++---
arch/ia64/sn/kernel/io_acpi_init.c | 6 +-
arch/ia64/sn/kernel/io_init.c | 8 +-
arch/m68k/coldfire/pci.c | 3 +-
arch/microblaze/pci/pci-common.c | 17 +--
arch/mips/include/asm/pci.h | 2 -
arch/mips/pci/pci.c | 5 +-
arch/mn10300/unit-asb2305/pci.c | 5 +-
arch/powerpc/include/asm/machdep.h | 2 +-
arch/powerpc/kernel/pci-common.c | 77 ++++++------
arch/powerpc/platforms/pseries/pci.c | 8 +-
arch/powerpc/platforms/pseries/pseries.h | 2 +-
arch/powerpc/platforms/pseries/setup.c | 2 +-
arch/s390/pci/pci.c | 13 +--
arch/sh/drivers/pci/pci.c | 6 +-
arch/sh/include/asm/pci.h | 2 -
arch/sparc/kernel/leon_pci.c | 1 +
arch/sparc/kernel/pci.c | 50 ++++----
arch/sparc/kernel/pcic.c | 4 +-
arch/tile/include/asm/pci.h | 2 -
arch/tile/kernel/pci.c | 6 +-
arch/tile/kernel/pci_gx.c | 7 +-
arch/unicore32/kernel/pci.c | 13 +--
arch/x86/include/asm/pci.h | 6 -
arch/x86/pci/acpi.c | 38 +++---
arch/x86/pci/common.c | 4 +-
arch/xtensa/kernel/pci.c | 2 +
drivers/parisc/dino.c | 11 +--
drivers/parisc/lba_pci.c | 7 +-
drivers/pci/host-bridge.c | 90 ++++++++++++++-
drivers/pci/host/pci-mvebu.c | 18 +---
drivers/pci/host/pci-tegra.c | 16 ---
drivers/pci/host/pci-xgene.c | 3 +-
drivers/pci/host/pcie-designware.c | 4 +-
drivers/pci/hotplug/acpiphp_glue.c | 29 +-----
drivers/pci/hotplug/ibmphp_core.c | 6 +-
drivers/pci/pci.c | 42 ++++++-
drivers/pci/probe.c | 195 ++++++++++++------------------
drivers/pci/xen-pcifront.c | 11 ++-
include/linux/pci.h | 47 +++++---
include/uapi/linux/pci.h | 3 +
46 files changed, 423 insertions(+), 404 deletions(-)
@@ -488,7 +492,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev,list_add(&bus_entry->list,&pdev->root_buses);-/* pci_scan_bus_parented skips devices which do not have a have+/* pci_scan_root_bus skips devices which do not have a have*devfn==0.Thepcifront_scan_busenumeratesalldevfn.*/err=pcifront_scan_bus(pdev,domain,bus,b);
From: Yijing Wang <hidden> Date: 2015-02-26 08:15:36
Pci_bus_add_devices() should not be placed in pci_scan_bus().
Now pci device will be added to driver core once its
creation. All things left in pci_bus_add_devices() are
driver attachment and other trivial sysfs things.
Pci_scan_bus() should be the function responsible for
scanning PCI devices, not including driver attachment.
Other, some callers(m68k,unicore32,alpha) of pci_scan_bus()
will call pci_bus_size_bridges() and pci_bus_assign_resources()
after pci_scan_bus().
E.g.
In m68k
mcf_pci_init()
pci_scan_bus()
...
pci_bus_add_devices() --- try to attach driver
pci_fixup_irqs()
pci_bus_size_bridges()
pci_bus_assign_resources()
Above code flow make pci scan logic obscure, resources should
be assigned correctly before attaching driver. Because
pci_scan_bus() mostly be called in system boot path, when
before drivers are loaded(in module_init), so no pci scan
issues will occur. Most pci_scan_bus() callers additionally
call pci_bus_size_bridges() and pci_bus_assign_resources()
after pci_scan_bus(), we could rip out pci_bus_add_devices()
for better code readability. After applied this patch,
pci_scan_bus() should be used like:
pci_scan_bus() (mandatory)
pci_fixup_irqs() (optional)
pci_bus_size_bridges() (optional)
pci_pci_bus_assign_resources() (optional)
pci_bus_add_devices() (mandatory)
Signed-off-by: Yijing Wang <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: Geert Uytterhoeven <geert@linux-m68k.org>
CC: Guan Xuetao <redacted>
CC: Richard Henderson <redacted>
CC: Ivan Kokshaysky <redacted>
CC: Matt Turner <mattst88@gmail.com>
CC: linux-alpha@vger.kernel.org
CC: linux-m68k@lists.linux-m68k.org
CC: sparclinux@vger.kernel.org
---
arch/alpha/kernel/sys_nautilus.c | 1 +
arch/m68k/coldfire/pci.c | 1 +
arch/sparc/kernel/pcic.c | 2 ++
arch/unicore32/kernel/pci.c | 11 +++--------
drivers/pci/hotplug/ibmphp_core.c | 6 ++++--
drivers/pci/probe.c | 1 -
6 files changed, 11 insertions(+), 11 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:15:47
Introduce pci_host_bridge_list to manage pci host
bridges in system, so we could detect whether
the host in domain:bus is alreay registered.
Then we could remove bus alreay exist test in
__pci_create_root_bus().
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/host-bridge.c | 24 +++++++++++++++++++++++-
drivers/pci/probe.c | 8 +-------
include/linux/pci.h | 1 +
3 files changed, 25 insertions(+), 8 deletions(-)
@@ -1886,12 +1886,6 @@ static struct pci_bus *__pci_create_root_bus(b->ops=ops;b->number=b->busn_res.start=bridge->busnum;pci_bus_assign_domain_nr(b,parent);-b2=pci_find_bus(pci_domain_nr(b),b->number);-if(b2){-/* If we already got to this bus through a different bridge, ignore it */-dev_dbg(&b2->dev,"bus already known\n");-gotoerr_out;-}bridge->bus=b;b->bridge=get_device(&bridge->dev);
@@ -129,7 +129,7 @@ struct machdep_calls {void(*pcibios_fixup)(void);int(*pci_probe_mode)(structpci_bus*);void(*pci_irq_fixup)(structpci_dev*dev);-int(*pcibios_set_root_bus_speed)(structpci_host_bridge+void(*pcibios_set_root_bus_speed)(structpci_host_bridge*bridge);/* To setup PHBs when using automatic OF platform driver for PCI */
@@ -767,14 +767,33 @@ int pci_proc_domain(struct pci_bus *bus)return1;}-intpcibios_root_bridge_prepare(structpci_host_bridge*bridge)+staticvoidpci_host_bridge_set_root_bus_speed(+structpci_host_bridge*bridge){if(ppc_md.pcibios_set_root_bus_speed)-returnppc_md.pcibios_set_root_bus_speed(bridge);--return0;+ppc_md.pcibios_set_root_bus_speed(bridge);}+staticvoidpci_host_bridge_of_scan_bus(structpci_host_bridge*host)+{+intmode=PCI_PROBE_NORMAL;+structpci_bus*bus=host->bus;+structpci_controller*hose=dev_get_drvdata(&host->dev);++/* Get probe mode and perform scan */+if(hose->dn&&ppc_md.pci_probe_mode)+mode=ppc_md.pci_probe_mode(bus);++pr_debug(" probe mode: %d\n",mode);+if(mode==PCI_PROBE_DEVTREE)+of_scan_bus(hose->dn,bus);++if(mode==PCI_PROBE_NORMAL){+pci_bus_update_busn_res_end(bus,255);+hose->last_busno=pci_scan_child_bus(bus);+pci_bus_update_busn_res_end(bus,hose->last_busno);+}+}/* This header fixup will do the resource fixup for all devices as they are*probed,butnotforbridgeranges*/
@@ -1612,30 +1635,16 @@ void pcibios_scan_phb(struct pci_controller *hose)pci_add_resource(&resources,&hose->busn);/* Create an empty bus for the toplevel */-bus=pci_create_root_bus(hose->parent,+host=pci_scan_root_bridge(hose->parent,PCI_DOMBUS(hose->global_number,hose->first_busno),-hose->ops,hose,&resources);-if(bus==NULL){-pr_err("Failed to create bus for PCI domain %04x\n",+hose->ops,hose,&resources,&phb_ops);+if(host==NULL){+pr_err("Failed to create host bridge for PCI domain %04x\n",hose->global_number);pci_free_resource_list(&resources);return;}-hose->bus=bus;--/* Get probe mode and perform scan */-mode=PCI_PROBE_NORMAL;-if(node&&ppc_md.pci_probe_mode)-mode=ppc_md.pci_probe_mode(bus);-pr_debug(" probe mode: %d\n",mode);-if(mode==PCI_PROBE_DEVTREE)-of_scan_bus(node,bus);--if(mode==PCI_PROBE_NORMAL){-pci_bus_update_busn_res_end(bus,255);-hose->last_busno=pci_scan_child_bus(bus);-pci_bus_update_busn_res_end(bus,hose->last_busno);-}+hose->bus=host->bus;/* Platform gets a chance to do some global fixups before*weproceedtoresourceallocation
@@ -164,7 +164,7 @@ sn_io_slot_fixup(struct pci_dev *dev)panic("%s: Unable to alloc memory for sn_irq_info",__func__);/* Call to retrieve pci device information needed by kernel. */-status=sal_get_pcidev_info((u64)pci_domain_nr(dev),+status=sal_get_pcidev_info((u64)pci_domain_nr(dev->bus),(u64)dev->bus->number,dev->devfn,(u64)__pa(pcidev_info),
From: Yijing Wang <hidden> Date: 2015-02-26 08:16:31
Now we could use pci_scan_root_bridge() to scan
pci buses, provide sparc specific pci_host_bridge_ops.
Signed-off-by: Yijing Wang <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: sparclinux@vger.kernel.org
---
arch/sparc/kernel/pci.c | 32 ++++++++++++++++++++++----------
1 files changed, 22 insertions(+), 10 deletions(-)
@@ -667,23 +680,22 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,pbm->busn.end=pbm->pci_last_busno;pbm->busn.flags=IORESOURCE_BUS;pci_add_resource(&resources,&pbm->busn);-bus=pci_create_root_bus(parent,+host=pci_scan_root_bridge(parent,PCI_DOMBUS(pbm->index,pbm->pci_first_busno),-pbm->pci_ops,pbm,&resources);-if(!bus){-printk(KERN_ERR"Failed to create bus for %s\n",+pbm->pci_ops,pbm,&resources,&phb_ops);+if(!host){+printk(KERN_ERR"Failed to create host bridge for %s\n",node->full_name);pci_free_resource_list(&resources);returnNULL;}-pci_of_scan_bus(pbm,node,bus);-pci_bus_add_devices(bus);-pci_bus_register_of_sysfs(bus);+pci_bus_add_devices(host->bus);+pci_bus_register_of_sysfs(host->bus);-pci_claim_bus_resources(bus);+pci_claim_bus_resources(host->bus);-returnbus;+returnhost->bus;}voidpcibios_fixup_bus(structpci_bus*pbus)
From: Yijing Wang <hidden> Date: 2015-02-26 08:16:37
Sometimes, we need to know the highest reserved
busnr for children bus. Because parent's
bus->busn_res could have padding in it.
This function return the max child busnr as
pci_scan_child_bus().
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/hotplug/acpiphp_glue.c | 29 +----------------------------
drivers/pci/pci.c | 25 ++++++++++++++++++++++++-
include/linux/pci.h | 2 +-
3 files changed, 26 insertions(+), 30 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:16:40
From: Yijing Wang <redacted>
Now pci_bus_add_devices() has been ripped out
from pci_scan_root_bus(), we could use pci_scan_root_bus()
instead of pci_create_root_bus() + pci_scan_child_bus()
for simplicity. We could also remove the pci bus
resource(dino_current_bus,255) and pci_bus_update_busn_res_end(),
because pci_scan_root_bus() would do the same thing.
Signed-off-by: Yijing Wang <redacted>
CC: "James E.J. Bottomley" <redacted>
CC: linux-parisc@vger.kernel.org
---
drivers/parisc/dino.c | 11 ++---------
drivers/parisc/lba_pci.c | 7 ++-----
2 files changed, 4 insertions(+), 14 deletions(-)
@@ -977,15 +977,11 @@ static int __init dino_probe(struct parisc_device *dev)if(dino_dev->hba.gmmio_space.flags)pci_add_resource(&resources,&dino_dev->hba.gmmio_space);-dino_dev->hba.bus_num.start=dino_current_bus;-dino_dev->hba.bus_num.end=255;-dino_dev->hba.bus_num.flags=IORESOURCE_BUS;-pci_add_resource(&resources,&dino_dev->hba.bus_num);/***It'snotusedtoavoidchicken/eggproblems**withconfigurationaccessorfunctions.*/-dino_dev->hba.hba_bus=bus=pci_create_root_bus(&dev->dev,+dino_dev->hba.hba_bus=bus=pci_scan_root_bus(&dev->dev,dino_current_bus,&dino_cfg_ops,NULL,&resources);if(!bus){printk(KERN_ERR"ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n",
@@ -996,13 +992,10 @@ static int __init dino_probe(struct parisc_device *dev)return0;}-max=pci_scan_child_bus(bus);-pci_bus_update_busn_res_end(bus,max);-/* This code *depends* on scanning being single threaded*ifitisn't,thisglobalbusnumbercountwillfail*/-dino_current_bus=max+1;+dino_current_bus=bus->busn_res.end+1;pci_bus_assign_resources(bus);pci_bus_add_devices(bus);return0;
@@ -1563,15 +1562,13 @@ lba_driver_probe(struct parisc_device *dev)dev->dev.platform_data=lba_dev;lba_bus=lba_dev->hba.hba_bus=-pci_create_root_bus(&dev->dev,lba_dev->hba.bus_num.start,+pci_scan_root_bus(&dev->dev,lba_dev->hba.bus_num.start,cfg_ops,NULL,&resources);if(!lba_bus){pci_free_resource_list(&resources);return0;}-max=pci_scan_child_bus(lba_bus);-/* This is in lieu of calling pci_assign_unassigned_resources() */if(is_pdc_pat()){/* assign resources to un-initialized devices */
@@ -1599,7 +1596,7 @@ lba_driver_probe(struct parisc_device *dev)lba_dev->flags|=LBA_FLAG_SKIP_PROBE;}-lba_next_bus=max+1;+lba_next_bus=pci_bus_child_max_busnr(lba_bus)+1;pci_bus_add_devices(lba_bus);/* Whew! Finally done! Tell services we got this one covered. */
From: Yijing Wang <hidden> Date: 2015-02-26 08:16:41
Now no one use pci_create_root_bus(), we could remove it
and rename __pci_create_root_bus() to pci_create_root_bus().
Signed-off-by: wangyijing@huawei.com
---
drivers/pci/probe.c | 27 ++++++++-------------------
include/linux/pci.h | 3 ---
2 files changed, 8 insertions(+), 22 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:16:43
Mvebu_pcie_scan_bus() is not necessary, we could use
pci_common_init_dev() instead of pci_common_init(),
and pass the device pointer as the parent. Then
pci_scan_root_bus() will be called to scan the pci busses.
Signed-off-by: Yijing Wang <redacted>
CC: Thomas Petazzoni <redacted>
CC: Jason Cooper <redacted>
---
drivers/pci/host/pci-mvebu.c | 18 +-----------------
1 files changed, 1 insertions(+), 17 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:16:44
Now pci_scan_root_bus() is almost simliar to
pci_create_root_bus() + pci_scan_child_bus().
So we could use common pci_scan_root_bus() in
pci_common_init_dev() to scan pci busses.
tegra_pcie_scan_bus() is redundant, remove it.
Signed-off-by: Yijing Wang <redacted>
CC: Thierry Reding <redacted>
CC: linux-tegra@vger.kernel.org
---
drivers/pci/host/pci-tegra.c | 16 ----------------
1 files changed, 0 insertions(+), 16 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:17:49
Now we could pass PCI domain combined with bus number
in u32 argu. Because in arm/arm64, PCI domain number
is assigned by pci_bus_assign_domain_nr(). So we leave
pci_scan_root_bus() and pci_create_root_bus() in arm/arm64
unchanged. A new function pci_host_assign_domain_nr()
will be introduced for arm/arm64 to assign domain number
in later patch.
Signed-off-by: Yijing Wang <redacted>
CC: Richard Henderson <redacted>
CC: Ivan Kokshaysky <redacted>
CC: Matt Turner <mattst88@gmail.com>
CC: Tony Luck <tony.luck@intel.com>
CC: Fenghua Yu <redacted>
CC: Michal Simek <monstr@monstr.eu>
CC: Ralf Baechle <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Michael Ellerman <mpe@ellerman.id.au>
CC: Sebastian Ott <redacted>
CC: Gerald Schaefer <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: Chris Metcalf <redacted>
CC: Thomas Gleixner <redacted>
CC: Konrad Rzeszutek Wilk <redacted>
CC: linux-alpha@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-ia64@vger.kernel.org
CC: linux-mips@linux-mips.org
CC: linuxppc-dev@lists.ozlabs.org
CC: linux-s390@vger.kernel.org
CC: linux-sh@vger.kernel.org
CC: sparclinux@vger.kernel.org
CC: xen-devel@lists.xenproject.org
---
arch/alpha/kernel/pci.c | 5 +++--
arch/alpha/kernel/sys_nautilus.c | 3 ++-
arch/ia64/pci/pci.c | 4 ++--
arch/ia64/sn/kernel/io_init.c | 5 +++--
arch/microblaze/pci/pci-common.c | 5 +++--
arch/mips/pci/pci.c | 4 ++--
arch/powerpc/kernel/pci-common.c | 5 +++--
arch/s390/pci/pci.c | 5 +++--
arch/sh/drivers/pci/pci.c | 5 +++--
arch/sparc/kernel/pci.c | 5 +++--
arch/tile/kernel/pci.c | 4 ++--
arch/tile/kernel/pci_gx.c | 5 +++--
arch/x86/pci/acpi.c | 6 +++---
arch/x86/pci/common.c | 3 ++-
drivers/pci/xen-pcifront.c | 5 +++--
15 files changed, 40 insertions(+), 29 deletions(-)
@@ -1612,8 +1612,9 @@ void pcibios_scan_phb(struct pci_controller *hose)pci_add_resource(&resources,&hose->busn);/* Create an empty bus for the toplevel */-bus=pci_create_root_bus(hose->parent,hose->first_busno,-hose->ops,hose,&resources);+bus=pci_create_root_bus(hose->parent,+PCI_DOMBUS(hose->global_number,hose->first_busno),+hose->ops,hose,&resources);if(bus==NULL){pr_err("Failed to create bus for PCI domain %04x\n",hose->global_number);
@@ -667,8 +667,9 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,pbm->busn.end=pbm->pci_last_busno;pbm->busn.flags=IORESOURCE_BUS;pci_add_resource(&resources,&pbm->busn);-bus=pci_create_root_bus(parent,pbm->pci_first_busno,pbm->pci_ops,-pbm,&resources);+bus=pci_create_root_bus(parent,+PCI_DOMBUS(pbm->index,pbm->pci_first_busno),+pbm->pci_ops,pbm,&resources);if(!bus){printk(KERN_ERR"Failed to create bus for %s\n",node->full_name);
@@ -123,17 +123,6 @@ unsigned long pci_address_to_pio(phys_addr_t address)}EXPORT_SYMBOL_GPL(pci_address_to_pio);-/*-*Returnthedomainnumberforthisbus.-*/-intpci_domain_nr(structpci_bus*bus)-{-structpci_controller*hose=pci_bus_to_host(bus);--returnhose->global_number;-}-EXPORT_SYMBOL(pci_domain_nr);-/* This routine is meant to be used early during boot, when the*PCIbusnumbershavenotyetbeenassigned,andyouneedto*issuePCIconfigcyclestoanOFdevice.
@@ -181,17 +181,6 @@ unsigned long pci_address_to_pio(phys_addr_t address)}EXPORT_SYMBOL_GPL(pci_address_to_pio);-/*-*Returnthedomainnumberforthisbus.-*/-intpci_domain_nr(structpci_bus*bus)-{-structpci_controller*hose=pci_bus_to_host(bus);--returnhose->global_number;-}-EXPORT_SYMBOL(pci_domain_nr);-/* This routine is meant to be used early during boot, when the*PCIbusnumbershavenotyetbeenassigned,andyouneedto*issuePCIconfigcyclestoanOFdevice.
@@ -903,23 +903,6 @@ int pcibus_to_node(struct pci_bus *pbus)EXPORT_SYMBOL(pcibus_to_node);#endif-/* Return the domain number for this pci bus */--intpci_domain_nr(structpci_bus*pbus)-{-structpci_pbm_info*pbm=pbus->sysdata;-intret;--if(!pbm){-ret=-ENXIO;-}else{-ret=pbm->index;-}--returnret;-}-EXPORT_SYMBOL(pci_domain_nr);-#ifdef CONFIG_PCI_MSIintarch_setup_msi_irq(structpci_dev*pdev,structmsi_desc*desc){
From: Yijing Wang <hidden> Date: 2015-02-26 08:19:15
Now we save the domain number in pci_host_bridge,
we could remove pci_bus_assign_domain_nr() and
clean the domain member in pci_bus.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/pci.c | 5 -----
drivers/pci/probe.c | 12 ++++--------
include/linux/pci.h | 3 ---
3 files changed, 4 insertions(+), 16 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:19:57
Just like pci_scan_bus(), we also should rip out
pci_bus_add_devices() from pci_scan_root_bus().
Lots platforms first call pci_scan_root_bus(), but
after that, they call pci_bus_size_bridges() and
pci_bus_assign_resources(). Place pci_bus_add_devices()
in pci_scan_root_bus() hurts PCI scan logic.
For arm hw_pci->scan() functions which call
pci_scan_root_bus(), it's no need to change anything,
because pci_bus_add_devices() will be called later
in pci_common_init_dev().
Signed-off-by: Yijing Wang <redacted>
CC: Richard Henderson <redacted>
CC: Ivan Kokshaysky <redacted>
CC: Matt Turner <mattst88@gmail.com>
CC: David Howells <dhowells@redhat.com>
CC: Tony Luck <tony.luck@intel.com>
CC: Michal Simek <monstr@monstr.eu>
CC: Ralf Baechle <redacted>
CC: Koichi Yasutake <redacted>
CC: Sebastian Ott <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: Chris Metcalf <redacted>
CC: Chris Zankel <chris@zankel.net>
CC: Max Filippov <jcmvbkbc@gmail.com>
CC: Thomas Gleixner <redacted>
CC: linux-alpha@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-mips@linux-mips.org
CC: linux-am33-list@redhat.com
CC: linux-s390@vger.kernel.org
CC: linux-sh@vger.kernel.org
CC: sparclinux@vger.kernel.org
CC: linux-xtensa@linux-xtensa.org
---
arch/alpha/kernel/pci.c | 2 ++
arch/frv/mb93090-mb00/pci-vdk.c | 6 ++++--
arch/ia64/sn/kernel/io_init.c | 1 +
arch/microblaze/pci/pci-common.c | 1 +
arch/mips/pci/pci.c | 1 +
arch/mn10300/unit-asb2305/pci.c | 5 ++++-
arch/s390/pci/pci.c | 2 +-
arch/sh/drivers/pci/pci.c | 1 +
arch/sparc/kernel/leon_pci.c | 1 +
arch/tile/kernel/pci.c | 2 ++
arch/tile/kernel/pci_gx.c | 2 ++
arch/x86/pci/common.c | 1 +
arch/xtensa/kernel/pci.c | 2 ++
drivers/pci/probe.c | 1 -
14 files changed, 23 insertions(+), 5 deletions(-)
@@ -916,6 +916,8 @@ int __init pcibios_init(void)/* Configure the max_payload_size values for this domain. */fixup_read_and_payload_sizes(controller);+pci_bus_add_devices(root_bus);+/* Alloc a PIO region for PCI memory access for each RC port. */ret=gxio_trio_alloc_pio_regions(trio_context,1,0,0);if(ret<0){
From: Yijing Wang <hidden> Date: 2015-02-26 08:21:24
Pcibios_root_bridge_prepare() in powerpc is used
to set root bus speed. Rename it to
pcibios_set_root_bus_speed() for better readability.
Signed-off-by: Yijing Wang <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: linuxppc-dev@lists.ozlabs.org
---
arch/powerpc/include/asm/machdep.h | 2 +-
arch/powerpc/kernel/pci-common.c | 6 +++---
arch/powerpc/platforms/pseries/pci.c | 2 +-
arch/powerpc/platforms/pseries/pseries.h | 2 +-
arch/powerpc/platforms/pseries/setup.c | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
@@ -129,7 +129,7 @@ struct machdep_calls {void(*pcibios_fixup)(void);int(*pci_probe_mode)(structpci_bus*);void(*pci_irq_fixup)(structpci_dev*dev);-int(*pcibios_root_bridge_prepare)(structpci_host_bridge+int(*pcibios_set_root_bus_speed)(structpci_host_bridge*bridge);/* To setup PHBs when using automatic OF platform driver for PCI */
From: Yijing Wang <hidden> Date: 2015-02-26 08:21:26
Now no one use weak pcibios_root_bridge_prepare(),
we could remove it.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/probe.c | 15 ---------------
include/linux/pci.h | 2 --
2 files changed, 0 insertions(+), 17 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:22:45
Introduce new scan function pci_scan_root_bridge() to
support host bridge drivers that need to provide platform
own pci_host_bridge_ops.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/probe.c | 21 +++++++++++++++++++++
include/linux/pci.h | 3 +++
2 files changed, 24 insertions(+), 0 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:22:47
Save platform specific sysdata in pci_host_bridge
drvdata, host bridge specific operation need to
access it before the pci bus creation.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/host-bridge.c | 4 +++-
drivers/pci/probe.c | 18 ++++++++----------
include/linux/pci.h | 3 ++-
3 files changed, 13 insertions(+), 12 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:22:49
Now we have weak functions like pcibios_root_bridge_prepare()
to setup pci host bridge, We could introduce pci_host_bridge_ops
which contain host bridge specific ops to setup pci_host_bridge.
Then host bridge driver could add pci_host_bridge_ops hooks
intead of weak function to setup pci_host_bridge.
This patch add following pci_host_bridge_ops hooks:
pci_host_bridge_ops {
/* set root bus speed, some platform need this like powerpc */
void (*phb_set_root_bus_speed)(struct pci_host_bridge *host);
/* setup pci_host_bridge before pci_host_bridge be added to driver core */
int (*phb_prepare)(struct pci_host_bridge *host);
/* platform specific of scan hook to scan pci device */
void (*phb_of_scan_bus)(struct pci_host_bridge *);
}
We could easily extend it to support different host bridge
specific operations.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/host-bridge.c | 12 ++++++++++--
drivers/pci/probe.c | 17 +++++++++++------
include/linux/pci.h | 12 ++++++++++--
3 files changed, 31 insertions(+), 10 deletions(-)
From: Yijing Wang <hidden> Date: 2015-02-26 08:25:40
This patch separate pci_host_bridge creation out
of pci_create_root_bus(), and try to make a generic
pci_host_bridge, then we could place generic PCI
infos like domain number in it. Also Ripping out
pci_host_bridge creation from pci_create_root_bus()
make code more better readability. Further more,
we could use the generic pci_host_bridge to hold
host bridge specific operations like
pcibios_root_bridge_prepare(). The changes are
transparent to platform host bridge drivers.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/host-bridge.c | 56 ++++++++++++++++++++++
drivers/pci/probe.c | 114 ++++++++++++++++++++-------------------------
include/linux/pci.h | 5 ++-
3 files changed, 110 insertions(+), 65 deletions(-)
@@ -8,6 +8,62 @@#include"pci.h"+staticvoidpci_release_host_bridge_dev(structdevice*dev)+{+structpci_host_bridge*bridge=to_pci_host_bridge(dev);++if(bridge->release_fn)+bridge->release_fn(bridge);++pci_free_resource_list(&bridge->windows);+kfree(bridge);+}++structpci_host_bridge*pci_create_host_bridge(+structdevice*parent,u32db,structlist_head*resources)+{+interror;+intbus=PCI_BUSNUM(db);+intdomain=PCI_DOMAIN(db);+structpci_host_bridge*host;+structresource_entry*window,*n;++host=kzalloc(sizeof(*host),GFP_KERNEL);+if(!host)+returnNULL;++host->busnum=bus;+host->domain=domain;+/* If support CONFIG_PCI_DOMAINS_GENERIC, use+*pci_host_assign_domain_nr()toassigndomain+*numberinsteadPCI_DOMAIN(db).+*/+pci_host_assign_domain_nr(host);++host->dev.parent=parent;+INIT_LIST_HEAD(&host->windows);+host->dev.release=pci_release_host_bridge_dev;+dev_set_name(&host->dev,"pci%04x:%02x",host->domain,+host->busnum);++error=device_register(&host->dev);+if(error){+put_device(&host->dev);+returnNULL;+}++resource_list_for_each_entry_safe(window,n,resources)+list_move_tail(&window->node,&host->windows);++returnhost;+}+EXPORT_SYMBOL(pci_create_host_bridge);++voidpci_free_host_bridge(structpci_host_bridge*host)+{+device_unregister(&host->dev);+}+staticstructpci_bus*find_pci_root_bus(structpci_bus*bus){while(bus->parent)
@@ -1889,54 +1864,41 @@ void __weak pcibios_remove_bus(struct pci_bus *bus){}-structpci_bus*pci_create_root_bus(structdevice*parent,u32db,-structpci_ops*ops,void*sysdata,structlist_head*resources)+staticstructpci_bus*__pci_create_root_bus(+structpci_host_bridge*bridge,structpci_ops*ops,+void*sysdata){interror;-structpci_host_bridge*bridge;structpci_bus*b,*b2;-structresource_entry*window,*n;+structresource_entry*window;+structdevice*parent;structresource*res;resource_size_toffset;charbus_addr[64];char*fmt;-u8bus=PCI_BUSNUM(db);+parent=bridge->dev.parent;b=pci_alloc_bus(NULL);if(!b)returnNULL;b->sysdata=sysdata;b->ops=ops;-b->number=b->busn_res.start=bus;+b->number=b->busn_res.start=bridge->busnum;pci_bus_assign_domain_nr(b,parent);-b2=pci_find_bus(pci_domain_nr(b),bus);+b2=pci_find_bus(pci_domain_nr(b),b->number);if(b2){/* If we already got to this bus through a different bridge, ignore it */dev_dbg(&b2->dev,"bus already known\n");gotoerr_out;}-bridge=pci_alloc_host_bridge(b);-if(!bridge)-gotoerr_out;--bridge->domain=PCI_DOMAIN(db);-bridge->dev.parent=parent;-bridge->dev.release=pci_release_host_bridge_dev;-dev_set_name(&bridge->dev,"pci%04x:%02x",pci_domain_nr(b),bus);+bridge->bus=b;+b->bridge=get_device(&bridge->dev);error=pcibios_root_bridge_prepare(bridge);-if(error){-kfree(bridge);+if(error)gotoerr_out;-}-error=device_register(&bridge->dev);-if(error){-put_device(&bridge->dev);-gotoerr_out;-}-b->bridge=get_device(&bridge->dev);device_enable_async_suspend(b->bridge);pci_set_bus_of_node(b);
@@ -1961,12 +1924,11 @@ struct pci_bus *pci_create_root_bus(struct device *parent, u32 db,printk(KERN_INFO"PCI host bridge to bus %s\n",dev_name(&b->dev));/* Add initial resources to the bus */-resource_list_for_each_entry_safe(window,n,resources){-list_move_tail(&window->node,&bridge->windows);+resource_list_for_each_entry(window,&bridge->windows){res=window->res;offset=window->offset;if(res->flags&IORESOURCE_BUS)-pci_bus_insert_busn_res(b,bus,res->end);+pci_bus_insert_busn_res(b,b->number,res->end);elsepci_bus_add_resource(b,res,0);if(offset){
@@ -2059,29 +2030,32 @@ void pci_bus_release_busn_res(struct pci_bus *b)res,ret?"can not be":"is");}-structpci_bus*pci_scan_root_bus(structdevice*parent,u32db,-structpci_ops*ops,void*sysdata,structlist_head*resources)+staticstructpci_bus*__pci_scan_root_bus(+structpci_host_bridge*host,structpci_ops*ops,+void*sysdata){structresource_entry*window;boolfound=false;structpci_bus*b;intmax;-resource_list_for_each_entry(window,resources)+resource_list_for_each_entry(window,&host->windows)if(window->res->flags&IORESOURCE_BUS){found=true;break;}-b=pci_create_root_bus(parent,db,ops,sysdata,resources);-if(!b)+b=__pci_create_root_bus(host,ops,sysdata);+if(!b){+pci_free_host_bridge(host);returnNULL;+}if(!found){dev_info(&b->dev,"No busn resource found for root bus, will use [bus %02x-ff]\n",-PCI_BUSNUM(db));-pci_bus_insert_busn_res(b,PCI_BUSNUM(db),255);+host->busnum);+pci_bus_insert_busn_res(b,b->number,255);}max=pci_scan_child_bus(b);
From: Yijing Wang <hidden> Date: 2015-02-26 08:26:01
Introduce pci_host_assign_domain_nr() to assign domain
number for pci_host_bridge. Later we will remove
pci_bus_assign_domain_nr().
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/pci.c | 14 +++++++++++---
include/linux/pci.h | 4 ++++
2 files changed, 15 insertions(+), 3 deletions(-)
@@ -1327,11 +1327,15 @@ static inline int pci_domain_nr(struct pci_bus *bus)returnbus->domain_nr;}voidpci_bus_assign_domain_nr(structpci_bus*bus,structdevice*parent);+voidpci_host_assign_domain_nr(structpci_host_bridge*host);#elsestaticinlinevoidpci_bus_assign_domain_nr(structpci_bus*bus,structdevice*parent){}+staticinlinevoidpci_host_assign_domain_nr(structpci_host_bridge*host)+{+}#endif/* some architectures require additional setup to direct VGA traffic */
From: Yijing Wang <hidden> Date: 2015-02-26 08:26:40
Currently, we use int type for bus number in
pci_create_root_bus(), pci_scan_root_bus() and
pci_scan_bus_legacy. Because PCI bus number
always <= 255, so we could change the bus number
argument type to u32, and combine PCI domain and
bus number in one. Also add a domain member in
pci_host_bridge to save domain number. Finally,
we could eliminate lots of the platform specific
pci_domain_nr() in the last of the series.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/probe.c | 16 +++++++++-------
include/linux/pci.h | 7 ++++---
include/uapi/linux/pci.h | 3 +++
3 files changed, 16 insertions(+), 10 deletions(-)
@@ -2057,7 +2059,7 @@ void pci_bus_release_busn_res(struct pci_bus *b)res,ret?"can not be":"is");}-structpci_bus*pci_scan_root_bus(structdevice*parent,intbus,+structpci_bus*pci_scan_root_bus(structdevice*parent,u32db,structpci_ops*ops,void*sysdata,structlist_head*resources){structresource_entry*window;
@@ -2071,15 +2073,15 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,break;}-b=pci_create_root_bus(parent,bus,ops,sysdata,resources);+b=pci_create_root_bus(parent,db,ops,sysdata,resources);if(!b)returnNULL;if(!found){dev_info(&b->dev,"No busn resource found for root bus, will use [bus %02x-ff]\n",-bus);-pci_bus_insert_busn_res(b,bus,255);+PCI_BUSNUM(db));+pci_bus_insert_busn_res(b,PCI_BUSNUM(db),255);}max=pci_scan_child_bus(b);
On Thu, Feb 26, 2015 at 04:11:54PM +0800, Yijing Wang wrote:
v3->v4:
Fix the rebase issue.
This did apply on v4.0-rc1, but with many whitespace complaints:
Importing patch "pci-pass-pci-domain-number" ... <stdin>:29: trailing whitespace.
bus = pci_scan_root_bus(NULL,
<stdin>:44: trailing whitespace.
bus = pci_scan_bus_legacy(PCI_DOMBUS(hose->index, 0),
<stdin>:59: trailing whitespace.
pbus = pci_create_root_bus(NULL, PCI_DOMBUS(domain, bus),
<stdin>:74: trailing whitespace.
bus = pci_scan_root_bus(NULL,
<stdin>:75: trailing whitespace.
PCI_DOMBUS(controller->segment, busnum),
warning: squelched 15 whitespace errors
warning: 20 lines add whitespace errors.
done
Importing patch "pci-introduce" ... done
Importing patch "pci-separate-pci_host_bridge" ... <stdin>:50: trailing whitespace.
dev_set_name(&host->dev, "pci%04x:%02x", host->domain,
<stdin>:181: trailing whitespace.
dev_set_name(&b->dev, "%04x:%02x", bridge->domain,
<stdin>:225: trailing whitespace.
warning: 3 lines add whitespace errors.
I'll fix them myself this time because I want to make progress on this and
I need something to do on the plane tomorrow, but please try to fix them
yourself in the future.
Bjorn
From: Yijing Wang <hidden> Date: 2015-02-27 00:57:08
On 2015/2/27 7:57, Bjorn Helgaas wrote:
On Thu, Feb 26, 2015 at 04:11:54PM +0800, Yijing Wang wrote:
quoted
v3->v4:
Fix the rebase issue.
This did apply on v4.0-rc1, but with many whitespace complaints:
Importing patch "pci-pass-pci-domain-number" ... <stdin>:29: trailing whitespace.
bus = pci_scan_root_bus(NULL,
<stdin>:44: trailing whitespace.
bus = pci_scan_bus_legacy(PCI_DOMBUS(hose->index, 0),
<stdin>:59: trailing whitespace.
pbus = pci_create_root_bus(NULL, PCI_DOMBUS(domain, bus),
<stdin>:74: trailing whitespace.
bus = pci_scan_root_bus(NULL,
<stdin>:75: trailing whitespace.
PCI_DOMBUS(controller->segment, busnum),
warning: squelched 15 whitespace errors
warning: 20 lines add whitespace errors.
done
Importing patch "pci-introduce" ... done
Importing patch "pci-separate-pci_host_bridge" ... <stdin>:50: trailing whitespace.
dev_set_name(&host->dev, "pci%04x:%02x", host->domain,
<stdin>:181: trailing whitespace.
dev_set_name(&b->dev, "%04x:%02x", bridge->domain,
<stdin>:225: trailing whitespace.
warning: 3 lines add whitespace errors.
I'll fix them myself this time because I want to make progress on this and
I need something to do on the plane tomorrow, but please try to fix them
yourself in the future.
On Thu, Feb 26, 2015 at 04:11:55PM +0800, Yijing Wang wrote:
quoted hunk
Pci_bus_add_devices() should not be placed in pci_scan_bus().
Now pci device will be added to driver core once its
creation. All things left in pci_bus_add_devices() are
driver attachment and other trivial sysfs things.
Pci_scan_bus() should be the function responsible for
scanning PCI devices, not including driver attachment.
Other, some callers(m68k,unicore32,alpha) of pci_scan_bus()
will call pci_bus_size_bridges() and pci_bus_assign_resources()
after pci_scan_bus().
E.g.
In m68k
mcf_pci_init()
pci_scan_bus()
...
pci_bus_add_devices() --- try to attach driver
pci_fixup_irqs()
pci_bus_size_bridges()
pci_bus_assign_resources()
Above code flow make pci scan logic obscure, resources should
be assigned correctly before attaching driver. Because
pci_scan_bus() mostly be called in system boot path, when
before drivers are loaded(in module_init), so no pci scan
issues will occur. Most pci_scan_bus() callers additionally
call pci_bus_size_bridges() and pci_bus_assign_resources()
after pci_scan_bus(), we could rip out pci_bus_add_devices()
for better code readability. After applied this patch,
pci_scan_bus() should be used like:
pci_scan_bus() (mandatory)
pci_fixup_irqs() (optional)
pci_bus_size_bridges() (optional)
pci_pci_bus_assign_resources() (optional)
pci_bus_add_devices() (mandatory)
Signed-off-by: Yijing Wang <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: Geert Uytterhoeven <geert@linux-m68k.org>
CC: Guan Xuetao <redacted>
CC: Richard Henderson <redacted>
CC: Ivan Kokshaysky <redacted>
CC: Matt Turner <mattst88@gmail.com>
CC: linux-alpha@vger.kernel.org
CC: linux-m68k@lists.linux-m68k.org
CC: sparclinux@vger.kernel.org
---
arch/alpha/kernel/sys_nautilus.c | 1 +
arch/m68k/coldfire/pci.c | 1 +
arch/sparc/kernel/pcic.c | 2 ++
arch/unicore32/kernel/pci.c | 11 +++--------
drivers/pci/hotplug/ibmphp_core.c | 6 ++++--
drivers/pci/probe.c | 1 -
6 files changed, 11 insertions(+), 11 deletions(-)
This is correct, but it should look like this instead:
if (!pbm->pci_bus)
return;
#if 0 /* deadwood ... */
...
#endif
pci_bus_add_devices(pbm->pci_bus);
}
That way the mainline code is the normal path, and pci_bus_add_devices() is
in the correct place even if the "deadwood" code is resurrected.
This is correct, but it should look like this instead:
if (!pbm->pci_bus)
return;
#if 0 /* deadwood ... */
...
#endif
pci_bus_add_devices(pbm->pci_bus);
}
That way the mainline code is the normal path, and pci_bus_add_devices() is
in the correct place even if the "deadwood" code is resurrected.
On Thu, Feb 26, 2015 at 04:11:56PM +0800, Yijing Wang wrote:
quoted hunk
Just like pci_scan_bus(), we also should rip out
pci_bus_add_devices() from pci_scan_root_bus().
Lots platforms first call pci_scan_root_bus(), but
after that, they call pci_bus_size_bridges() and
pci_bus_assign_resources(). Place pci_bus_add_devices()
in pci_scan_root_bus() hurts PCI scan logic.
For arm hw_pci->scan() functions which call
pci_scan_root_bus(), it's no need to change anything,
because pci_bus_add_devices() will be called later
in pci_common_init_dev().
Signed-off-by: Yijing Wang <redacted>
CC: Richard Henderson <redacted>
CC: Ivan Kokshaysky <redacted>
CC: Matt Turner <mattst88@gmail.com>
CC: David Howells <dhowells@redhat.com>
CC: Tony Luck <tony.luck@intel.com>
CC: Michal Simek <monstr@monstr.eu>
CC: Ralf Baechle <redacted>
CC: Koichi Yasutake <redacted>
CC: Sebastian Ott <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: Chris Metcalf <redacted>
CC: Chris Zankel <chris@zankel.net>
CC: Max Filippov <jcmvbkbc@gmail.com>
CC: Thomas Gleixner <redacted>
CC: linux-alpha@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-mips@linux-mips.org
CC: linux-am33-list@redhat.com
CC: linux-s390@vger.kernel.org
CC: linux-sh@vger.kernel.org
CC: sparclinux@vger.kernel.org
CC: linux-xtensa@linux-xtensa.org
---
arch/alpha/kernel/pci.c | 2 ++
arch/frv/mb93090-mb00/pci-vdk.c | 6 ++++--
arch/ia64/sn/kernel/io_init.c | 1 +
arch/microblaze/pci/pci-common.c | 1 +
arch/mips/pci/pci.c | 1 +
arch/mn10300/unit-asb2305/pci.c | 5 ++++-
arch/s390/pci/pci.c | 2 +-
arch/sh/drivers/pci/pci.c | 1 +
arch/sparc/kernel/leon_pci.c | 1 +
arch/tile/kernel/pci.c | 2 ++
arch/tile/kernel/pci_gx.c | 2 ++
arch/x86/pci/common.c | 1 +
arch/xtensa/kernel/pci.c | 2 ++
drivers/pci/probe.c | 1 -
14 files changed, 23 insertions(+), 5 deletions(-)
This doesn't look right. The code above is inside a loop, and just after
the loop we have:
pci_assign_unassigned_resources();
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
I think the pci_bus_add_devices() needs to go inside another loop after
the assign and fixup_irqs code.
You didn't fix arm, but I think it has the same problem:
pci_common_init_dev
pcibios_init_hw
pci_scan_root_bus
pci_fixup_irqs
pci_bus_size_bridges
pci_bus_assign_resources
I would add a new patch at the end of your series to cosmetically
restructure this as:
if (!bus)
return;
next_busno = bus->busn_res.end + 1;
...
pci_bus_add_devices(bus);
Cosmetic restructure (new patch at end of series):
if (!bus) {
pci_free_resource_list(&resources);
return;
}
next_busno = bus->busn_res.end + 1;
...
pci_bus_add_devices(bus);
@@ -916,6 +916,8 @@ int __init pcibios_init(void)/* Configure the max_payload_size values for this domain. */fixup_read_and_payload_sizes(controller);+pci_bus_add_devices(root_bus);+/* Alloc a PIO region for PCI memory access for each RC port. */ret=gxio_trio_alloc_pio_regions(trio_context,1,0,0);if(ret<0){
I don't know what all the magic gxio_trio_alloc and init stuff after this
is, but it looks to me like the pci_bus_add_devices(root_bus) should be
done *after* all of it.
This one is tricky. I don't think your patch makes it any worse than it is
today, but it doesn't fix the problem. We need to either fix it or call it
out in the changelog.
pci_subsys_init # subsys_initcall (level 4)
pci_legacy_init
pcibios_scan_root
pci_scan_root_bus
pci_bus_add_devices
pcibios_assign_resources # fs_initcall (level 5)
@@ -185,6 +185,8 @@ static int __init pcibios_init(void)pci_controller_apertures(pci_ctrl,&resources);bus=pci_scan_root_bus(NULL,pci_ctrl->first_busno,pci_ctrl->ops,pci_ctrl,&resources);+if(bus)+pci_bus_add_devices(bus);pci_ctrl->bus=bus;pci_ctrl->last_busno=bus->busn_res.end;
Oops, we just dereferenced a potentially NULL pointer here (of course, this
could happen even before your patch).
I don't understand the platform_pcibios_fixup() that follows. I can't find
a definition of that, but it sounds like something that maybe should happen
before pci_bus_add_devices().
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
@@ -446,6 +446,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev,unsignedintdomain,unsignedintbus){structpci_bus*b;+LIST_HEAD(resources);structpcifront_sd*sd=NULL;structpci_bus_entry*bus_entry=NULL;interr=0;
@@ -470,17 +471,20 @@ static int pcifront_scan_root(struct pcifront_device *pdev,err=-ENOMEM;gotoerr_out;}+pci_add_resource(&resources,&ioport_resource);+pci_add_resource(&resources,&iomem_resource);
This doesn't add &busn_resource like pci_scan_bus_parented() does.
That might be OK, but I think we'll now emit "No busn resource found for
root bus, will use [bus %02x-ff]" when we didn't before. I don't know how
xen-pcifront works; it would be nice if it could supply the correct
bus resource (and ioport and iomem).
@@ -488,7 +492,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev, list_add(&bus_entry->list, &pdev->root_buses);- /* pci_scan_bus_parented skips devices which do not have a have+ /* pci_scan_root_bus skips devices which do not have a have
Please fix the comment typo at the same time ("have a have").
* devfn==0. The pcifront_scan_bus enumerates all devfn. */
err = pcifront_scan_bus(pdev, domain, bus, b);
--
1.7.1
On Thu, Feb 26, 2015 at 04:11:59PM +0800, Yijing Wang wrote:
Pci_scan_bus() is called by legacy pci host drivers,
the legacy host drivers mean they use NULL as parent
device, use all IO/MEM as default resources. Rename
pci_scan_bus() to pci_scan_bus_legacy() for better
readability.
We should mention that this changes an exported symbol, because that's
potentially an issue for distros.
I'm not saying we can't change it, but I don't want to do it unless there's
real benefit. I'm not convinced of the benefit yet, but maybe I will be by
the end of the series.
On Thu, Feb 26, 2015 at 04:12:03PM +0800, Yijing Wang wrote:
quoted hunk
This patch separate pci_host_bridge creation out
of pci_create_root_bus(), and try to make a generic
pci_host_bridge, then we could place generic PCI
infos like domain number in it. Also Ripping out
pci_host_bridge creation from pci_create_root_bus()
make code more better readability. Further more,
we could use the generic pci_host_bridge to hold
host bridge specific operations like
pcibios_root_bridge_prepare(). The changes are
transparent to platform host bridge drivers.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/host-bridge.c | 56 ++++++++++++++++++++++
drivers/pci/probe.c | 114 ++++++++++++++++++++-------------------------
include/linux/pci.h | 5 ++-
3 files changed, 110 insertions(+), 65 deletions(-)
@@ -8,6 +8,62 @@#include"pci.h"+staticvoidpci_release_host_bridge_dev(structdevice*dev)+{+structpci_host_bridge*bridge=to_pci_host_bridge(dev);++if(bridge->release_fn)+bridge->release_fn(bridge);++pci_free_resource_list(&bridge->windows);+kfree(bridge);+}++structpci_host_bridge*pci_create_host_bridge(+structdevice*parent,u32db,structlist_head*resources)+{+interror;+intbus=PCI_BUSNUM(db);+intdomain=PCI_DOMAIN(db);+structpci_host_bridge*host;+structresource_entry*window,*n;++host=kzalloc(sizeof(*host),GFP_KERNEL);+if(!host)+returnNULL;++host->busnum=bus;+host->domain=domain;+/* If support CONFIG_PCI_DOMAINS_GENERIC, use+*pci_host_assign_domain_nr()toassigndomain+*numberinsteadPCI_DOMAIN(db).+*/+pci_host_assign_domain_nr(host);++host->dev.parent=parent;+INIT_LIST_HEAD(&host->windows);+host->dev.release=pci_release_host_bridge_dev;+dev_set_name(&host->dev,"pci%04x:%02x",host->domain,+host->busnum);++error=device_register(&host->dev);+if(error){+put_device(&host->dev);+returnNULL;+}++resource_list_for_each_entry_safe(window,n,resources)+list_move_tail(&window->node,&host->windows);++returnhost;+}+EXPORT_SYMBOL(pci_create_host_bridge);
Why does this need to be exported? I don't want code outside drivers/pci
using something like this.
Can these function declarations go in drivers/pci/pci.h instead? I'd
rather not expose them to the rest of the kernel unless we have to.
quoted hunk
/*
* The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
* to P2P or CardBus bridge windows) go in a table. Additional ones (for
@@ -774,6 +776,7 @@ struct pci_bus *pci_scan_bus_legacy(u32 dombus, struct pci_ops *ops, void *sysda struct pci_bus *pci_create_root_bus(struct device *parent, u32 dombus, struct pci_ops *ops, void *sysdata, struct list_head *resources);+void pci_free_host_bridge(struct pci_host_bridge *host); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b);
On Thu, Feb 26, 2015 at 04:12:06PM +0800, Yijing Wang wrote:
quoted hunk
Now we have weak functions like pcibios_root_bridge_prepare()
to setup pci host bridge, We could introduce pci_host_bridge_ops
which contain host bridge specific ops to setup pci_host_bridge.
Then host bridge driver could add pci_host_bridge_ops hooks
intead of weak function to setup pci_host_bridge.
This patch add following pci_host_bridge_ops hooks:
pci_host_bridge_ops {
/* set root bus speed, some platform need this like powerpc */
void (*phb_set_root_bus_speed)(struct pci_host_bridge *host);
/* setup pci_host_bridge before pci_host_bridge be added to driver core */
int (*phb_prepare)(struct pci_host_bridge *host);
/* platform specific of scan hook to scan pci device */
void (*phb_of_scan_bus)(struct pci_host_bridge *);
}
We could easily extend it to support different host bridge
specific operations.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/host-bridge.c | 12 ++++++++++--
drivers/pci/probe.c | 17 +++++++++++------
include/linux/pci.h | 12 ++++++++++--
3 files changed, 31 insertions(+), 10 deletions(-)
On Thu, Feb 26, 2015 at 04:12:07PM +0800, Yijing Wang wrote:
quoted hunk
Introduce new scan function pci_scan_root_bridge() to
support host bridge drivers that need to provide platform
own pci_host_bridge_ops.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/probe.c | 21 +++++++++++++++++++++
include/linux/pci.h | 3 +++
2 files changed, 24 insertions(+), 0 deletions(-)
@@ -164,7 +164,7 @@ sn_io_slot_fixup(struct pci_dev *dev)panic("%s: Unable to alloc memory for sn_irq_info",__func__);/* Call to retrieve pci device information needed by kernel. */-status=sal_get_pcidev_info((u64)pci_domain_nr(dev),+status=sal_get_pcidev_info((u64)pci_domain_nr(dev->bus),(u64)dev->bus->number,dev->devfn,(u64)__pa(pcidev_info),
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Feb 26, 2015 at 04:12:06PM +0800, Yijing Wang wrote:
Now we have weak functions like pcibios_root_bridge_prepare()
to setup pci host bridge, We could introduce pci_host_bridge_ops
which contain host bridge specific ops to setup pci_host_bridge.
Then host bridge driver could add pci_host_bridge_ops hooks
intead of weak function to setup pci_host_bridge.
This patch add following pci_host_bridge_ops hooks:
pci_host_bridge_ops {
/* set root bus speed, some platform need this like powerpc */
void (*phb_set_root_bus_speed)(struct pci_host_bridge *host);
/* setup pci_host_bridge before pci_host_bridge be added to driver core */
int (*phb_prepare)(struct pci_host_bridge *host);
/* platform specific of scan hook to scan pci device */
void (*phb_of_scan_bus)(struct pci_host_bridge *);
}
We could easily extend it to support different host bridge
specific operations.
Signed-off-by: Yijing Wang <redacted>
...
quoted hunk
@@ -2050,10 +2052,13 @@ static struct pci_bus *__pci_scan_root_bus( pci_bus_insert_busn_res(b, b->number, 255); }- max = pci_scan_child_bus(b);-- if (!found)- pci_bus_update_busn_res_end(b, max);+ if (host->ops && host->ops->phb_of_scan_bus) {+ host->ops->phb_of_scan_bus(host);
The important thing here is not the use of OF (Open Firmware/Device Tree),
is it? Why would we want "_of_" in the function name? I assume the intent
is that this host bridge op performs the same function as
pci_scan_child_bus(), so I think the op should be called "scan_bus".
+ } else {
+ max = pci_scan_child_bus(b);
+ if (!found)
+ pci_bus_update_busn_res_end(b, max);
+ }
return b;
}
On Thu, Feb 26, 2015 at 04:12:14PM +0800, Yijing Wang wrote:
quoted hunk
Now we could use pci_scan_root_bridge() to scan
pci buses, provide sparc specific pci_host_bridge_ops.
Signed-off-by: Yijing Wang <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: sparclinux@vger.kernel.org
---
arch/sparc/kernel/pci.c | 32 ++++++++++++++++++++++----------
1 files changed, 22 insertions(+), 10 deletions(-)
@@ -667,23 +680,22 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,pbm->busn.end=pbm->pci_last_busno;pbm->busn.flags=IORESOURCE_BUS;pci_add_resource(&resources,&pbm->busn);-bus=pci_create_root_bus(parent,+host=pci_scan_root_bridge(parent,PCI_DOMBUS(pbm->index,pbm->pci_first_busno),-pbm->pci_ops,pbm,&resources);-if(!bus){-printk(KERN_ERR"Failed to create bus for %s\n",+pbm->pci_ops,pbm,&resources,&phb_ops);+if(!host){+printk(KERN_ERR"Failed to create host bridge for %s\n",node->full_name);pci_free_resource_list(&resources);returnNULL;}-pci_of_scan_bus(pbm,node,bus);-pci_bus_add_devices(bus);-pci_bus_register_of_sysfs(bus);+pci_bus_add_devices(host->bus);+pci_bus_register_of_sysfs(host->bus);-pci_claim_bus_resources(bus);+pci_claim_bus_resources(host->bus);
Isn't this a case where pci_claim_bus_resources() should be done before
pci_bus_add_devices()? You didn't introduce this problem, but since you're
fixing similar issues, seems like we should fix this one, too. In a patch
of its own, of course.
- return bus;
+ return host->bus;
}
void pcibios_fixup_bus(struct pci_bus *pbus)
--
1.7.1
--
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/
From: Yijing Wang <hidden> Date: 2015-03-03 03:17:43
On 2015/3/3 9:57, Bjorn Helgaas wrote:
On Thu, Feb 26, 2015 at 04:11:56PM +0800, Yijing Wang wrote:
quoted
Just like pci_scan_bus(), we also should rip out
pci_bus_add_devices() from pci_scan_root_bus().
Lots platforms first call pci_scan_root_bus(), but
after that, they call pci_bus_size_bridges() and
pci_bus_assign_resources(). Place pci_bus_add_devices()
in pci_scan_root_bus() hurts PCI scan logic.
For arm hw_pci->scan() functions which call
pci_scan_root_bus(), it's no need to change anything,
because pci_bus_add_devices() will be called later
in pci_common_init_dev().
Signed-off-by: Yijing Wang <redacted>
CC: Richard Henderson <redacted>
CC: Ivan Kokshaysky <redacted>
CC: Matt Turner <mattst88@gmail.com>
CC: David Howells <dhowells@redhat.com>
CC: Tony Luck <tony.luck@intel.com>
CC: Michal Simek <monstr@monstr.eu>
CC: Ralf Baechle <redacted>
CC: Koichi Yasutake <redacted>
CC: Sebastian Ott <redacted>
CC: "David S. Miller" <davem@davemloft.net>
CC: Chris Metcalf <redacted>
CC: Chris Zankel <chris@zankel.net>
CC: Max Filippov <jcmvbkbc@gmail.com>
CC: Thomas Gleixner <redacted>
CC: linux-alpha@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-mips@linux-mips.org
CC: linux-am33-list@redhat.com
CC: linux-s390@vger.kernel.org
CC: linux-sh@vger.kernel.org
CC: sparclinux@vger.kernel.org
CC: linux-xtensa@linux-xtensa.org
---
arch/alpha/kernel/pci.c | 2 ++
arch/frv/mb93090-mb00/pci-vdk.c | 6 ++++--
arch/ia64/sn/kernel/io_init.c | 1 +
arch/microblaze/pci/pci-common.c | 1 +
arch/mips/pci/pci.c | 1 +
arch/mn10300/unit-asb2305/pci.c | 5 ++++-
arch/s390/pci/pci.c | 2 +-
arch/sh/drivers/pci/pci.c | 1 +
arch/sparc/kernel/leon_pci.c | 1 +
arch/tile/kernel/pci.c | 2 ++
arch/tile/kernel/pci_gx.c | 2 ++
arch/x86/pci/common.c | 1 +
arch/xtensa/kernel/pci.c | 2 ++
drivers/pci/probe.c | 1 -
14 files changed, 23 insertions(+), 5 deletions(-)
This doesn't look right. The code above is inside a loop, and just after
the loop we have:
pci_assign_unassigned_resources();
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
I think the pci_bus_add_devices() needs to go inside another loop after
the assign and fixup_irqs code.
What about introduce a new function to add all pci bus here like:
pci_bus_add_devices_all()
{
struct pci_bus *root_bus;
list_for_each_entry(root_bus, &pci_root_buses, node)
pci_bus_add_devices(root_bus);
}
pci_assign_unassigned_resources();
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
pci_bus_add_devices_all();
You didn't fix arm, but I think it has the same problem:
pci_common_init_dev
pcibios_init_hw
pci_scan_root_bus
pci_fixup_irqs
pci_bus_size_bridges
pci_bus_assign_resources
void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
{
struct pci_sys_data *sys;
LIST_HEAD(head);
pci_add_flags(PCI_REASSIGN_ALL_RSRC);
if (hw->preinit)
hw->preinit();
pcibios_init_hw(parent, hw, &head); --------> scan root bus
if (hw->postinit)
hw->postinit();
pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
list_for_each_entry(sys, &head, node) {
struct pci_bus *bus = sys->bus;
if (!pci_has_flag(PCI_PROBE_ONLY)) {
/*
* Size the bridge windows.
*/
pci_bus_size_bridges(bus);
/*
* Assign resources.
*/
pci_bus_assign_resources(bus);
}
/*
* Tell drivers about devices found.
*/
pci_bus_add_devices(bus); ------>try to attach driver
}
pci_bus_add_devices() is already in loops, so what problem here do you mean ?
I would add a new patch at the end of your series to cosmetically
restructure this as:
if (!bus)
return;
next_busno = bus->busn_res.end + 1;
...
pci_bus_add_devices(bus);
Cosmetic restructure (new patch at end of series):
if (!bus) {
pci_free_resource_list(&resources);
return;
}
next_busno = bus->busn_res.end + 1;
...
pci_bus_add_devices(bus);
@@ -916,6 +916,8 @@ int __init pcibios_init(void)/* Configure the max_payload_size values for this domain. */fixup_read_and_payload_sizes(controller);+pci_bus_add_devices(root_bus);+/* Alloc a PIO region for PCI memory access for each RC port. */ret=gxio_trio_alloc_pio_regions(trio_context,1,0,0);if(ret<0){
I don't know what all the magic gxio_trio_alloc and init stuff after this
is, but it looks to me like the pci_bus_add_devices(root_bus) should be
done *after* all of it.
I don't know much too, but I agree it, I would poke arch tile guys.
This one is tricky. I don't think your patch makes it any worse than it is
today, but it doesn't fix the problem. We need to either fix it or call it
out in the changelog.
pci_subsys_init # subsys_initcall (level 4)
pci_legacy_init
pcibios_scan_root
pci_scan_root_bus
pci_bus_add_devices
pcibios_assign_resources # fs_initcall (level 5)
I would like to keep it here, and we know that in this routine,
it is always in system boot up context. Which do you prefer ?
@@ -185,6 +185,8 @@ static int __init pcibios_init(void)pci_controller_apertures(pci_ctrl,&resources);bus=pci_scan_root_bus(NULL,pci_ctrl->first_busno,pci_ctrl->ops,pci_ctrl,&resources);+if(bus)+pci_bus_add_devices(bus);pci_ctrl->bus=bus;pci_ctrl->last_busno=bus->busn_res.end;
Oops, we just dereferenced a potentially NULL pointer here (of course, this
could happen even before your patch).
I don't understand the platform_pcibios_fixup() that follows. I can't find
a definition of that, but it sounds like something that maybe should happen
before pci_bus_add_devices().
I Will move the pci_bus_add_devices() after the platform_pcibios_fixup(),
because now only driver attachment in it, I think delay it is safe.
Thanks!
Yijing.
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Feb 26, 2015 at 04:12:16PM +0800, Yijing Wang wrote:
From: Yijing Wang <redacted>
When you write subject lines, I think it's friendly to run
"git log --oneline" on the file you're changing, and make yours
match the previous ones.
$ git log --oneline drivers/parisc/dino.c
3f05536d226d PCI/Parisc: Use pci_scan_root_bus() for simplicity
3335f75a8877 parisc: dino: fix %d confusingly prefixed with 0x in format string
3fad9b8d597f drivers/parisc: Use printf extension %pR for struct resource
0fe763c570ad Drivers: misc: remove __dev* attributes.
0b79ca2a800d parisc/PCI: Use list_for_each_entry() for bus->devices traversal
30aa80da43a5 parisc/PCI: register busn_res for root buses
...
Yours doesn't match any of them, but "parisc/PCI" seems the best match.
quoted hunk
Now pci_bus_add_devices() has been ripped out
from pci_scan_root_bus(), we could use pci_scan_root_bus()
instead of pci_create_root_bus() + pci_scan_child_bus()
for simplicity. We could also remove the pci bus
resource(dino_current_bus,255) and pci_bus_update_busn_res_end(),
because pci_scan_root_bus() would do the same thing.
Signed-off-by: Yijing Wang <redacted>
CC: "James E.J. Bottomley" <redacted>
CC: linux-parisc@vger.kernel.org
---
drivers/parisc/dino.c | 11 ++---------
drivers/parisc/lba_pci.c | 7 ++-----
2 files changed, 4 insertions(+), 14 deletions(-)
@@ -977,15 +977,11 @@ static int __init dino_probe(struct parisc_device *dev)if(dino_dev->hba.gmmio_space.flags)pci_add_resource(&resources,&dino_dev->hba.gmmio_space);-dino_dev->hba.bus_num.start=dino_current_bus;-dino_dev->hba.bus_num.end=255;-dino_dev->hba.bus_num.flags=IORESOURCE_BUS;-pci_add_resource(&resources,&dino_dev->hba.bus_num);
I know pci_scan_root_bus() does default to bus 0-255, but I don't really
like that behavior, and I think it's a bug for drivers like this to rely on
that. The PCI core has no way to discover the actual bus number range, and
the only reason it supplies a default is because it was inconvenient to
change all the callers. The host bridge driver is the only code that has
any chance of discovering and/or configuring the correct range.
So I think it's more correct to leave the existing code here, even though
this code is is likely incorrect. At least then if we trip over an issue
with the bus range being incorrect, it will be clear that the fix should
be in dino.c rather than the PCI core.
On Thu, Feb 26, 2015 at 04:12:17PM +0800, Yijing Wang wrote:
quoted hunk
Mvebu_pcie_scan_bus() is not necessary, we could use
pci_common_init_dev() instead of pci_common_init(),
and pass the device pointer as the parent. Then
pci_scan_root_bus() will be called to scan the pci busses.
Signed-off-by: Yijing Wang <redacted>
CC: Thomas Petazzoni <redacted>
CC: Jason Cooper <redacted>
---
drivers/pci/host/pci-mvebu.c | 18 +-----------------
1 files changed, 1 insertions(+), 17 deletions(-)
I'm not necessarily opposed to this, but it seems unrelated to the rest of
the series. And I think it changes the behavior slightly (now we call
pci_common_init_dev() with &pcie->pdev->dev instead of NULL). So I'll wait
for an ack from Thomas and/or Jason.
@@ -446,6 +446,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev,unsignedintdomain,unsignedintbus){structpci_bus*b;+LIST_HEAD(resources);structpcifront_sd*sd=NULL;structpci_bus_entry*bus_entry=NULL;interr=0;
@@ -470,17 +471,20 @@ static int pcifront_scan_root(struct pcifront_device *pdev,err=-ENOMEM;gotoerr_out;}+pci_add_resource(&resources,&ioport_resource);+pci_add_resource(&resources,&iomem_resource);
This doesn't add &busn_resource like pci_scan_bus_parented() does.
That might be OK, but I think we'll now emit "No busn resource found for
root bus, will use [bus %02x-ff]" when we didn't before. I don't know how
xen-pcifront works; it would be nice if it could supply the correct
bus resource (and ioport and iomem).
Because the pci_scan_bus_parented() add the default busn_resource for it,
I would add the default busn_resource in pcifront_scan_root() too to fix the
"No busn resource found ..." debug info.
@@ -488,7 +492,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev, list_add(&bus_entry->list, &pdev->root_buses);- /* pci_scan_bus_parented skips devices which do not have a have+ /* pci_scan_root_bus skips devices which do not have a have
Please fix the comment typo at the same time ("have a have").
Ok.
quoted
* devfn==0. The pcifront_scan_bus enumerates all devfn. */
err = pcifront_scan_bus(pdev, domain, bus, b);
--
1.7.1
I'm not sure this needs to be in include/linux/pci.h. Wouldn't
drivers/pci/pci.h be enough?
/*
* The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
* to P2P or CardBus bridge windows) go in a table. Additional ones (for
--
1.7.1
From: Yijing Wang <hidden> Date: 2015-03-03 03:42:31
On 2015/3/3 10:06, Bjorn Helgaas wrote:
On Thu, Feb 26, 2015 at 04:11:59PM +0800, Yijing Wang wrote:
quoted
Pci_scan_bus() is called by legacy pci host drivers,
the legacy host drivers mean they use NULL as parent
device, use all IO/MEM as default resources. Rename
pci_scan_bus() to pci_scan_bus_legacy() for better
readability.
We should mention that this changes an exported symbol, because that's
potentially an issue for distros.
I'm not saying we can't change it, but I don't want to do it unless there's
real benefit. I'm not convinced of the benefit yet, but maybe I will be by
the end of the series.
Ok, I would move this one out of this series temporarily.
Can these function declarations go in drivers/pci/pci.h instead? I'd
rather not expose them to the rest of the kernel unless we have to.
I would move it in drivers/pci/pci.h, thanks.
quoted
/*
* The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
* to P2P or CardBus bridge windows) go in a table. Additional ones (for
@@ -774,6 +776,7 @@ struct pci_bus *pci_scan_bus_legacy(u32 dombus, struct pci_ops *ops, void *sysda struct pci_bus *pci_create_root_bus(struct device *parent, u32 dombus, struct pci_ops *ops, void *sysdata, struct list_head *resources);+void pci_free_host_bridge(struct pci_host_bridge *host); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b);
From: Yijing Wang <hidden> Date: 2015-03-03 08:13:04
On 2015/3/3 10:52, Bjorn Helgaas wrote:
On Thu, Feb 26, 2015 at 04:12:07PM +0800, Yijing Wang wrote:
quoted
Introduce new scan function pci_scan_root_bridge() to
support host bridge drivers that need to provide platform
own pci_host_bridge_ops.
Signed-off-by: Yijing Wang <redacted>
---
drivers/pci/probe.c | 21 +++++++++++++++++++++
include/linux/pci.h | 3 +++
2 files changed, 24 insertions(+), 0 deletions(-)
@@ -164,7 +164,7 @@ sn_io_slot_fixup(struct pci_dev *dev)panic("%s: Unable to alloc memory for sn_irq_info",__func__);/* Call to retrieve pci device information needed by kernel. */-status=sal_get_pcidev_info((u64)pci_domain_nr(dev),+status=sal_get_pcidev_info((u64)pci_domain_nr(dev->bus),(u64)dev->bus->number,dev->devfn,(u64)__pa(pcidev_info),
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Yijing Wang <hidden> Date: 2015-03-03 08:42:19
On 2015/3/3 11:03, Bjorn Helgaas wrote:
On Thu, Feb 26, 2015 at 04:12:06PM +0800, Yijing Wang wrote:
quoted
Now we have weak functions like pcibios_root_bridge_prepare()
to setup pci host bridge, We could introduce pci_host_bridge_ops
which contain host bridge specific ops to setup pci_host_bridge.
Then host bridge driver could add pci_host_bridge_ops hooks
intead of weak function to setup pci_host_bridge.
This patch add following pci_host_bridge_ops hooks:
pci_host_bridge_ops {
/* set root bus speed, some platform need this like powerpc */
void (*phb_set_root_bus_speed)(struct pci_host_bridge *host);
/* setup pci_host_bridge before pci_host_bridge be added to driver core */
int (*phb_prepare)(struct pci_host_bridge *host);
/* platform specific of scan hook to scan pci device */
void (*phb_of_scan_bus)(struct pci_host_bridge *);
}
We could easily extend it to support different host bridge
specific operations.
Signed-off-by: Yijing Wang <redacted>
...
quoted
@@ -2050,10 +2052,13 @@ static struct pci_bus *__pci_scan_root_bus( pci_bus_insert_busn_res(b, b->number, 255); }- max = pci_scan_child_bus(b);-- if (!found)- pci_bus_update_busn_res_end(b, max);+ if (host->ops && host->ops->phb_of_scan_bus) {+ host->ops->phb_of_scan_bus(host);
The important thing here is not the use of OF (Open Firmware/Device Tree),
is it? Why would we want "_of_" in the function name? I assume the intent
is that this host bridge op performs the same function as
pci_scan_child_bus(), so I think the op should be called "scan_bus".
Yes, because now only OF code need the private scan_child_bus, so I named it
phb_of_scan_bus(). I agree that rename it to scan_bus.
quoted
+ } else {
+ max = pci_scan_child_bus(b);
+ if (!found)
+ pci_bus_update_busn_res_end(b, max);
+ }
return b;
}
Isn't this a case where pci_claim_bus_resources() should be done before
pci_bus_add_devices()? You didn't introduce this problem, but since you're
fixing similar issues, seems like we should fix this one, too. In a patch
of its own, of course.
OK, will fix in a another patch.
quoted
- return bus;
+ return host->bus;
}
void pcibios_fixup_bus(struct pci_bus *pbus)
--
1.7.1
--
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/
From: Yijing Wang <hidden> Date: 2015-03-03 09:32:11
On 2015/3/3 11:24, Bjorn Helgaas wrote:
On Thu, Feb 26, 2015 at 04:12:16PM +0800, Yijing Wang wrote:
quoted
From: Yijing Wang <redacted>
When you write subject lines, I think it's friendly to run
"git log --oneline" on the file you're changing, and make yours
match the previous ones.
$ git log --oneline drivers/parisc/dino.c
3f05536d226d PCI/Parisc: Use pci_scan_root_bus() for simplicity
3335f75a8877 parisc: dino: fix %d confusingly prefixed with 0x in format string
3fad9b8d597f drivers/parisc: Use printf extension %pR for struct resource
0fe763c570ad Drivers: misc: remove __dev* attributes.
0b79ca2a800d parisc/PCI: Use list_for_each_entry() for bus->devices traversal
30aa80da43a5 parisc/PCI: register busn_res for root buses
...
Yours doesn't match any of them, but "parisc/PCI" seems the best match.
OK, I will refresh the title, sorry.
quoted
Now pci_bus_add_devices() has been ripped out
from pci_scan_root_bus(), we could use pci_scan_root_bus()
instead of pci_create_root_bus() + pci_scan_child_bus()
for simplicity. We could also remove the pci bus
resource(dino_current_bus,255) and pci_bus_update_busn_res_end(),
because pci_scan_root_bus() would do the same thing.
Signed-off-by: Yijing Wang <redacted>
CC: "James E.J. Bottomley" <redacted>
CC: linux-parisc@vger.kernel.org
---
drivers/parisc/dino.c | 11 ++---------
drivers/parisc/lba_pci.c | 7 ++-----
2 files changed, 4 insertions(+), 14 deletions(-)
@@ -977,15 +977,11 @@ static int __init dino_probe(struct parisc_device *dev)if(dino_dev->hba.gmmio_space.flags)pci_add_resource(&resources,&dino_dev->hba.gmmio_space);-dino_dev->hba.bus_num.start=dino_current_bus;-dino_dev->hba.bus_num.end=255;-dino_dev->hba.bus_num.flags=IORESOURCE_BUS;-pci_add_resource(&resources,&dino_dev->hba.bus_num);
I know pci_scan_root_bus() does default to bus 0-255, but I don't really
like that behavior, and I think it's a bug for drivers like this to rely on
that. The PCI core has no way to discover the actual bus number range, and
the only reason it supplies a default is because it was inconvenient to
change all the callers. The host bridge driver is the only code that has
any chance of discovering and/or configuring the correct range.
So I think it's more correct to leave the existing code here, even though
this code is is likely incorrect. At least then if we trip over an issue
with the bus range being incorrect, it will be clear that the fix should
be in dino.c rather than the PCI core.
I'm not sure this needs to be in include/linux/pci.h. Wouldn't
drivers/pci/pci.h be enough?
It's enough for this series, so I would move it to drivers/pci/pci.h, thanks!
quoted
/*
* The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
* to P2P or CardBus bridge windows) go in a table. Additional ones (for
--
1.7.1