[PATCH] x86/x86-64 PCI domain support

From: Jeff Garzik
Date: Sat Sep 01 2007 - 10:32:31 EST



Now that the dust has settled and the prep work is upstream, adding PCI
domain support to x86 is a lot more straightforward.

Targetted for 2.6.24.



commit c7b14cf6aa39e09aef89a0cd08c553dba1ee7e98
Author: Jeff Garzik <jeff@xxxxxxxxxx>
Date: Sat Sep 1 07:36:25 2007 -0400

PCI domain support for x86[-64]

aka "PCI segment" support, in ACPI lingo.

Signed-off-by: Jeff Garzik <jeff@xxxxxxxxxx>

arch/i386/pci/acpi.c | 15 ++++++++++-----
arch/i386/pci/common.c | 6 ++++--
arch/x86_64/Kconfig | 4 ++++
include/asm-i386/pci.h | 14 ++++++++++++++
include/asm-x86_64/pci.h | 14 ++++++++++++++
5 files changed, 46 insertions(+), 7 deletions(-)

c7b14cf6aa39e09aef89a0cd08c553dba1ee7e98
diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c
index bc8a44b..6beb789 100644
--- a/arch/i386/pci/acpi.c
+++ b/arch/i386/pci/acpi.c
@@ -11,6 +11,13 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
struct pci_sysdata *sd;
int pxm;

+#ifndef CONFIG_PCI_DOMAINS
+ if (domain != 0) {
+ printk(KERN_WARNING "PCI: Multiple domains not supported\n");
+ return NULL;
+ }
+#endif
+
/* 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.
@@ -21,11 +28,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
return NULL;
}

- if (domain != 0) {
- printk(KERN_WARNING "PCI: Multiple domains not supported\n");
- kfree(sd);
- return NULL;
- }
+#ifdef CONFIG_PCI_DOMAINS
+ sd->domain = domain;
+#endif

sd->node = -1;

diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index ebc6f3c..6d7a274 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -29,12 +29,14 @@ struct pci_raw_ops *raw_pci_ops;

static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
- return raw_pci_ops->read(0, bus->number, devfn, where, size, value);
+ return raw_pci_ops->read(pci_domain_nr(bus), bus->number,
+ devfn, where, size, value);
}

static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
- return raw_pci_ops->write(0, bus->number, devfn, where, size, value);
+ return raw_pci_ops->write(pci_domain_nr(bus), bus->number,
+ devfn, where, size, value);
}

struct pci_ops pci_root_ops = {
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index ffa0364..1cb16c6 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -732,6 +732,10 @@ config PCI_MMCONFIG
bool "Support mmconfig PCI config space access"
depends on PCI && ACPI

+config PCI_DOMAINS
+ bool "PCI domain support"
+ depends on PCI
+
source "drivers/pci/pcie/Kconfig"

source "drivers/pci/Kconfig"
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h
index 4fcacc7..37d3322 100644
--- a/include/asm-i386/pci.h
+++ b/include/asm-i386/pci.h
@@ -5,12 +5,26 @@
#ifdef __KERNEL__

struct pci_sysdata {
+ int domain; /* PCI domain */
int node; /* NUMA node */
};

/* scan a bus after allocating a pci_sysdata for it */
extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);

+#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 <linux/mm.h> /* for struct page */

/* Can be used to override the logic in pci_scan_bus for skipping
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
index 5da8cb0..6ce2731 100644
--- a/include/asm-x86_64/pci.h
+++ b/include/asm-x86_64/pci.h
@@ -6,12 +6,26 @@
#ifdef __KERNEL__

struct pci_sysdata {
+ int domain; /* PCI domain */
int node; /* NUMA node */
void* iommu; /* IOMMU private data */
};

extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);

+#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 */
+
#ifdef CONFIG_CALGARY_IOMMU
static inline void* pci_iommu(struct pci_bus *bus)
{
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/