aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2007-10-11 16:58:30 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 18:03:19 -0400
commita79e4198d1effbba040e9bf407a95fc9b3418789 (patch)
treebbfeed15db3a03c3e7f50ae36f18c017fb940b9e
parent32a2eea795643929a43cbbba00d8c4a176b309bf (diff)
PCI: X86: Introduce and enable PCI domain support
* fix bug in pci_read() and pci_write() which prevented PCI domain support from working (hardcoded domain 0). * unconditionally enable CONFIG_PCI_DOMAINS * implement pci_domain_nr() and pci_proc_domain(), as required of all arches when CONFIG_PCI_DOMAINS is enabled. * store domain in struct pci_sysdata, as assigned by ACPI * support "pci=nodomains" Signed-off-by: Jeff Garzik <jgarzik@redhat.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/i386/Kconfig5
-rw-r--r--arch/x86/pci/acpi.c13
-rw-r--r--arch/x86/pci/common.c6
-rw-r--r--arch/x86_64/Kconfig5
-rw-r--r--include/asm-x86/pci_32.h12
-rw-r--r--include/asm-x86/pci_64.h12
6 files changed, 45 insertions, 8 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 2d85e4b87307..515abb98d41d 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -1137,6 +1137,11 @@ config PCI_MMCONFIG
1137 depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) 1137 depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
1138 default y 1138 default y
1139 1139
1140config PCI_DOMAINS
1141 bool
1142 depends on PCI
1143 default y
1144
1140source "drivers/pci/pcie/Kconfig" 1145source "drivers/pci/pcie/Kconfig"
1141 1146
1142source "drivers/pci/Kconfig" 1147source "drivers/pci/Kconfig"
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index c6fd3a6afa42..27a391da9a98 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -189,6 +189,12 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
189 189
190 dmi_check_system(acpi_pciprobe_dmi_table); 190 dmi_check_system(acpi_pciprobe_dmi_table);
191 191
192 if (domain && !pci_domains_supported) {
193 printk(KERN_WARNING "PCI: Multiple domains not supported "
194 "(dom %d, bus %d)\n", domain, busnum);
195 return NULL;
196 }
197
192 /* Allocate per-root-bus (not per bus) arch-specific data. 198 /* Allocate per-root-bus (not per bus) arch-specific data.
193 * TODO: leak; this memory is never freed. 199 * TODO: leak; this memory is never freed.
194 * It's arguable whether it's worth the trouble to care. 200 * It's arguable whether it's worth the trouble to care.
@@ -199,12 +205,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
199 return NULL; 205 return NULL;
200 } 206 }
201 207
202 if (domain != 0) { 208 sd->domain = domain;
203 printk(KERN_WARNING "PCI: Multiple domains not supported\n");
204 kfree(sd);
205 return NULL;
206 }
207
208 sd->node = -1; 209 sd->node = -1;
209 210
210 pxm = acpi_get_pxm(device->handle); 211 pxm = acpi_get_pxm(device->handle);
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7d6a9a5aa7cd..2d71bbc411d2 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -29,12 +29,14 @@ struct pci_raw_ops *raw_pci_ops;
29 29
30static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 30static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
31{ 31{
32 return raw_pci_ops->read(0, bus->number, devfn, where, size, value); 32 return raw_pci_ops->read(pci_domain_nr(bus), bus->number,
33 devfn, where, size, value);
33} 34}
34 35
35static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) 36static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
36{ 37{
37 return raw_pci_ops->write(0, bus->number, devfn, where, size, value); 38 return raw_pci_ops->write(pci_domain_nr(bus), bus->number,
39 devfn, where, size, value);
38} 40}
39 41
40struct pci_ops pci_root_ops = { 42struct pci_ops pci_root_ops = {
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index b1b98e614f7c..04d324cc72d8 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -724,6 +724,11 @@ config PCI_MMCONFIG
724 bool "Support mmconfig PCI config space access" 724 bool "Support mmconfig PCI config space access"
725 depends on PCI && ACPI 725 depends on PCI && ACPI
726 726
727config PCI_DOMAINS
728 bool
729 depends on PCI
730 default y
731
727source "drivers/pci/pcie/Kconfig" 732source "drivers/pci/pcie/Kconfig"
728 733
729source "drivers/pci/Kconfig" 734source "drivers/pci/Kconfig"
diff --git a/include/asm-x86/pci_32.h b/include/asm-x86/pci_32.h
index 4fcacc711385..0d91605cd1e2 100644
--- a/include/asm-x86/pci_32.h
+++ b/include/asm-x86/pci_32.h
@@ -5,12 +5,24 @@
5#ifdef __KERNEL__ 5#ifdef __KERNEL__
6 6
7struct pci_sysdata { 7struct pci_sysdata {
8 int domain; /* PCI domain */
8 int node; /* NUMA node */ 9 int node; /* NUMA node */
9}; 10};
10 11
11/* scan a bus after allocating a pci_sysdata for it */ 12/* scan a bus after allocating a pci_sysdata for it */
12extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); 13extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
13 14
15static inline int pci_domain_nr(struct pci_bus *bus)
16{
17 struct pci_sysdata *sd = bus->sysdata;
18 return sd->domain;
19}
20
21static inline int pci_proc_domain(struct pci_bus *bus)
22{
23 return pci_domain_nr(bus);
24}
25
14#include <linux/mm.h> /* for struct page */ 26#include <linux/mm.h> /* for struct page */
15 27
16/* Can be used to override the logic in pci_scan_bus for skipping 28/* Can be used to override the logic in pci_scan_bus for skipping
diff --git a/include/asm-x86/pci_64.h b/include/asm-x86/pci_64.h
index 5da8cb0c0599..0a123d6a820f 100644
--- a/include/asm-x86/pci_64.h
+++ b/include/asm-x86/pci_64.h
@@ -6,12 +6,24 @@
6#ifdef __KERNEL__ 6#ifdef __KERNEL__
7 7
8struct pci_sysdata { 8struct pci_sysdata {
9 int domain; /* PCI domain */
9 int node; /* NUMA node */ 10 int node; /* NUMA node */
10 void* iommu; /* IOMMU private data */ 11 void* iommu; /* IOMMU private data */
11}; 12};
12 13
13extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); 14extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
14 15
16static inline int pci_domain_nr(struct pci_bus *bus)
17{
18 struct pci_sysdata *sd = bus->sysdata;
19 return sd->domain;
20}
21
22static inline int pci_proc_domain(struct pci_bus *bus)
23{
24 return pci_domain_nr(bus);
25}
26
15#ifdef CONFIG_CALGARY_IOMMU 27#ifdef CONFIG_CALGARY_IOMMU
16static inline void* pci_iommu(struct pci_bus *bus) 28static inline void* pci_iommu(struct pci_bus *bus)
17{ 29{