On Fri, Feb 10, 2012 at 9:24 AM, Bjorn Helgaas <bhelgaas@xxxxxxxxxx> wrote: > On Fri, Feb 10, 2012 at 9:20 AM, Yinghai Lu <yinghai@xxxxxxxxxx> wrote: > > That's exactly what I said above, isn't it? (In the paragraph > starting "Let me try again.") no, not create one. make them looks like one struct with some common fields. > > As I said, the reason I don't like that approach is that I don't want > a dozen copies of first_busno, last_busno, domain, node, io_offset, > mem_offset, etc. That information is not architecture-specific, so we > shouldn't keep it in an architecture-specific struct. but you want to add hostbridge struct list and that just produce duplicated info. and search hostbridge for dev looks not good. Now you try to: for every device or resource find root bus and then check hostbridge list to get hostbridge and get offset. use sysdata pointer to get sys data like hostbridge info quickly i drafted one patch, and it seems not ugly with macro. please check it. Thanks Yinghai
[RFC PATCH] PCI: unify sysdata to pci_sys_data use macro, so core code could access common member in sysdata As example, plut first_busno/end_busno there. for sparc, need to change pci_first_busno to first_busno... arm already has that. x86 need to add them. ... Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx> diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h index 28d0497..f6f8cc6 100644 --- a/arch/alpha/include/asm/pci.h +++ b/arch/alpha/include/asm/pci.h @@ -18,6 +18,8 @@ struct resource; struct pci_iommu_arena; struct page; +#define pci_sys_data pci_controller + /* A controller. Used to manage multiple PCI busses. */ struct pci_controller { @@ -26,6 +28,9 @@ struct pci_controller { struct resource *io_space; struct resource *mem_space; + unsigned int first_busno; + unsigned int last_busno; + /* The following are for reporting to userland. The invariant is that if we report a BWX-capable dense memory, we do not report a sparse memory at all, even if it exists. */ diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index d943b7d..f49a853 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -28,6 +28,8 @@ struct hw_pci { int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); }; +#define pci_sys_data pci_sys_data + /* * Per-controller structure */ @@ -37,6 +39,8 @@ struct pci_sys_data { #endif struct list_head node; int busnr; /* primary bus number */ + unsigned int first_busno; /* bus number start */ + unsigned int last_busno; /* bus number end */ u64 mem_offset; /* bus->cpu memory mapping offset */ unsigned long io_offset; /* bus->cpu IO mapping offset */ struct pci_bus *bus; /* PCI bus */ diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 279b38a..336fd9f 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -86,12 +86,17 @@ struct pci_window { u64 offset; }; +#define pci_sys_data pci_controller + struct pci_controller { void *acpi_handle; void *iommu; int segment; int node; /* nearest node with memory or -1 for global allocation */ + unsigned int first_busno; + unsigned int last_busno; + unsigned int windows; struct pci_window *window; diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index e9834b2..23fe4a4 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -24,6 +24,7 @@ static inline int pcibios_vaddr_is_ioport(void __iomem *address) } #endif +#define pci_sys_data pci_controller /* * Structure of a PCI controller (host bridge) */ @@ -34,8 +35,8 @@ struct pci_controller { struct list_head list_node; struct device *parent; - int first_busno; - int last_busno; + unsigned int first_busno; + unsigned int last_busno; int self_busno; diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index 2242a5c..9a1c241 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h @@ -28,6 +28,7 @@ */ #define pci_post_reset_delay 50 +#define pci_sys_data pci_hba_data /* ** pci_hba_data (aka H2P_OBJECT in HP/UX) @@ -48,6 +49,8 @@ struct pci_hba_data { struct resource lmmio_space; /* bus addresses < 4Gb */ struct resource elmmio_space; /* additional bus addresses < 4Gb */ struct resource gmmio_space; /* bus addresses > 4Gb */ + unsigned int first_busno; + unsigned int last_busno; /* NOTE: Dino code assumes it can use *all* of the lmmio_space, * elmmio_space and gmmio_space as a contiguous array of diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index cb21e23..e99d56e 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -9,6 +9,8 @@ #define pcibios_assign_all_busses() 1 +#define pci_sys_data pci_channel + /* * A board can define one or more PCI channels that represent built-in (or * external) PCI controllers. @@ -25,6 +27,9 @@ struct pci_channel { unsigned long io_offset; unsigned long mem_offset; + unsigned int first_busno; + unsigned int last_busno; + unsigned long reg_base; unsigned long io_map_base; diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index bb8bc2e..d9667f5 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -693,7 +693,7 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, pci_add_resource(&resources, &pbm->io_space); pci_add_resource(&resources, &pbm->mem_space); - bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops, + bus = pci_create_root_bus(parent, pbm->first_busno, pbm->pci_ops, pbm, &resources); if (!bus) { printk(KERN_ERR "Failed to create bus for %s\n", @@ -701,8 +701,8 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, pci_free_resource_list(&resources); return NULL; } - bus->secondary = pbm->pci_first_busno; - bus->subordinate = pbm->pci_last_busno; + bus->secondary = pbm->first_busno; + bus->subordinate = pbm->last_busno; pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index a689598..5d0a2e6 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -21,8 +21,8 @@ static int config_out_of_range(struct pci_pbm_info *pbm, unsigned long devfn, unsigned long reg) { - if (bus < pbm->pci_first_busno || - bus > pbm->pci_last_busno) + if (bus < pbm->first_busno || + bus > pbm->last_busno) return 1; return 0; } @@ -319,8 +319,8 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm) { const u32 *val = of_get_property(pbm->op->dev.of_node, "bus-range", NULL); - pbm->pci_first_busno = val[0]; - pbm->pci_last_busno = val[1]; + pbm->first_busno = val[0]; + pbm->last_busno = val[1]; val = of_get_property(pbm->op->dev.of_node, "ino-bitmap", NULL); if (val) { diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 6beb60d..664f548 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h @@ -57,6 +57,8 @@ struct sparc64_msiq_cookie { }; #endif +#define pci_sys_data pci_pbm_info + struct pci_pbm_info { struct pci_pbm_info *next; struct pci_pbm_info *sibling; @@ -144,8 +146,8 @@ struct pci_pbm_info { struct iommu *iommu; /* Now things for the actual PCI bus probes. */ - unsigned int pci_first_busno; - unsigned int pci_last_busno; + unsigned int first_busno; + unsigned int last_busno; struct pci_bus *pci_bus; struct pci_ops *pci_ops; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index f4d29e1..764efbe 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -356,12 +356,12 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) /* Set cache-line size to 64 bytes, this is actually * a nop but I do it for completeness. */ - addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno, + addr = psycho_pci_config_mkaddr(pbm, pbm->first_busno, 0, PCI_CACHE_LINE_SIZE); pci_config_write8(addr, 64 / sizeof(u32)); /* Set PBM latency timer to 64 PCI clocks. */ - addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno, + addr = psycho_pci_config_mkaddr(pbm, pbm->first_busno, 0, PCI_LATENCY_TIMER); pci_config_write8(addr, 64); } diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 13d4aa2..898308d 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -82,7 +82,7 @@ static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm, { if (!pbm) return NULL; - bus -= pbm->pci_first_busno; + bus -= pbm->first_busno; return (void *) (SCHIZO_CONFIG_BASE(pbm) | SCHIZO_CONFIG_ENCODE(bus, devfn, where)); @@ -1054,12 +1054,12 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) /* Set cache-line size to 64 bytes, this is actually * a nop but I do it for completeness. */ - addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno, + addr = schizo_pci_config_mkaddr(pbm, pbm->first_busno, 0, PCI_CACHE_LINE_SIZE); pci_config_write8(addr, 64 / sizeof(u32)); /* Set PBM latency timer to 64 PCI clocks. */ - addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno, + addr = schizo_pci_config_mkaddr(pbm, pbm->first_busno, 0, PCI_LATENCY_TIMER); pci_config_write8(addr, 64); } diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index df75d07..c6bc4f3 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -11,12 +11,16 @@ #ifdef __KERNEL__ +#define pci_sys_data pci_sysdata + struct pci_sysdata { int domain; /* PCI domain */ int node; /* NUMA node */ #ifdef CONFIG_X86_64 void *iommu; /* IOMMU private data */ #endif + unsigned int first_busno; + unsigned int last_busno; }; extern int pci_routeirq; diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h index 00fcbd7..edc021b 100644 --- a/arch/xtensa/include/asm/pci-bridge.h +++ b/arch/xtensa/include/asm/pci-bridge.h @@ -28,6 +28,8 @@ struct pci_space { unsigned long base; }; +#define pci_sys_data pci_controller + /* * Structure of a PCI controller (host bridge) */ @@ -38,8 +40,8 @@ struct pci_controller { struct pci_bus *bus; void *arch_data; - int first_busno; - int last_busno; + unsigned int first_busno; + unsigned int last_busno; struct pci_ops *ops; volatile unsigned int *cfg_addr; diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 7ff10c1..cdb527c 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -1004,7 +1004,7 @@ static int __init dino_probe(struct parisc_device *dev) ** with configuration accessor functions. */ dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev, - dino_current_bus, &dino_cfg_ops, NULL, &resources); + dino_current_bus, &dino_cfg_ops, &dino_dev->hba, &resources); if (!bus) { printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n", dev_name(&dev->dev), dino_current_bus); diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index d5f3d75..fd62f79 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1525,7 +1525,7 @@ 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, - cfg_ops, NULL, &resources); + cfg_ops, &lba_dev->hba, &resources); if (!lba_bus) { pci_free_resource_list(&resources); return 0; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a114173..bcb387d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1608,6 +1608,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, dev_info(&b->dev, "root bus resource %pR\n", res); } + if (sysdata) { + struct pci_sys_data *data = sysdata; + + dev_printk(KERN_DEBUG, &b->dev, "bus range: %02x-%02x\n", data->first_busno, data->last_busno); + } else { + dev_printk(KERN_DEBUG, &b->dev, "bus range: %02x-%02x\n", 0, 0xff); + } + return b; class_dev_reg_err: diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 98387ca..d60fc5b 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -50,7 +50,15 @@ struct pcifront_device { }; struct pcifront_sd { +/* begin same as pci_sysdata for arch/x86/include/asm/pci.h */ int domain; + int node; /* NUMA node */ +#ifdef CONFIG_X86_64 + void *iommu; /* IOMMU private data */ +#endif + unsigned int first_busno; + unsigned int last_busno; +/* end */ struct pcifront_device *pdev; }; diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h index 26373cf..1506b06 100644 --- a/include/asm-generic/pci.h +++ b/include/asm-generic/pci.h @@ -6,6 +6,15 @@ #ifndef _ASM_GENERIC_PCI_H #define _ASM_GENERIC_PCI_H +#ifndef pci_sys_data +#define pci_sys_data pci_sys_data + +struct pci_sys_data { + unsigned int first busno; + unsigned int last_busno; +}; +#endif + /** * pcibios_resource_to_bus - convert resource to PCI bus address * @dev: device which owns this resource