From garzik@havoc.gtf.org Fri Dec 2 19:24:13 2005 Date: Fri, 2 Dec 2005 20:40:33 -0500 From: Jeff Garzik To: linux-kernel@vger.kernel.org Cc: , Subject: [PATCH 3/3] x86 PCI domain support: the meat Message-ID: <20051203014033.GC2663@havoc.gtf.org> Content-Disposition: inline [x86, PCI] add PCI domain support * Store PCI domain in struct pci_sysdata * Add magic inlines to pass PCI domain to read/write config hooks * Support ACPI's notion of PCI domains (PCI segments) From: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/acpi.c | 20 ++++++++++++++++++-- include/asm-i386/pci.h | 14 ++++++++++++++ include/asm-x86_64/pci.h | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) --- gregkh-2.6.orig/arch/i386/pci/acpi.c +++ gregkh-2.6/arch/i386/pci/acpi.c @@ -8,18 +8,34 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) { struct pci_bus *bus; + struct pci_sysdata *sd; + /* Allocate per-root-bus (not per bus) arch-specific data. + * TODO: leak; this memory is never freed. + * It's arguable whether it's worth the trouble to care. + */ + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { + printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); + return NULL; + } + +#ifdef CONFIG_PCI_DOMAINS + sd->domain = domain; +#else if (domain != 0) { printk(KERN_WARNING "PCI: Multiple domains not supported\n"); return NULL; } +#endif /* CONFIG_PCI_DOMAINS */ - bus = pcibios_scan_root(busnum); + bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); + if (!bus) + kfree(sd); #ifdef CONFIG_ACPI_NUMA if (bus != NULL) { int pxm = acpi_get_pxm(device->handle); if (pxm >= 0) { - struct pci_sysdata *sd = bus->sysdata; sd->node = pxm_to_node(pxm); printk("bus %d -> pxm %d -> node %d\n", busnum, pxm, sd->node); --- gregkh-2.6.orig/include/asm-i386/pci.h +++ gregkh-2.6/include/asm-i386/pci.h @@ -6,9 +6,23 @@ #ifdef __KERNEL__ struct pci_sysdata { + int domain; /* PCI domain */ int node; /* NUMA node */ }; +#ifdef CONFIG_PCI_DOMAINS +static inline int pci_domain_nr(struct pci_bus *bus) +{ + struct pci_sysdata *sd = bus->sysdata; + return sd->domain; +} + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return pci_domain_nr(bus); +} +#endif /* CONFIG_PCI_DOMAINS */ + #include /* for struct page */ /* Can be used to override the logic in pci_scan_bus for skipping --- gregkh-2.6.orig/include/asm-x86_64/pci.h +++ gregkh-2.6/include/asm-x86_64/pci.h @@ -7,9 +7,23 @@ #ifdef __KERNEL__ struct pci_sysdata { + int domain; /* PCI domain */ int node; /* NUMA node */ }; +#ifdef CONFIG_PCI_DOMAINS +static inline int pci_domain_nr(struct pci_bus *bus) +{ + struct pci_sysdata *sd = bus->sysdata; + return sd->domain; +} + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return pci_domain_nr(bus); +} +#endif /* CONFIG_PCI_DOMAINS */ + #include /* for struct page */ /* Can be used to override the logic in pci_scan_bus for skipping