aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/acpi/boot.c57
-rw-r--r--arch/i386/pci/common.c8
-rw-r--r--arch/i386/pci/irq.c51
-rw-r--r--arch/i386/pci/legacy.c2
-rw-r--r--arch/i386/pci/mmconfig.c39
-rw-r--r--arch/i386/pci/numa.c2
-rw-r--r--arch/i386/pci/pci.h1
-rw-r--r--arch/ia64/kernel/acpi.c30
-rw-r--r--arch/ia64/kernel/iosapic.c134
-rw-r--r--arch/ia64/pci/pci.c38
-rw-r--r--arch/ppc/kernel/pci.c21
-rw-r--r--arch/ppc64/kernel/pci.c22
-rw-r--r--arch/x86_64/pci/mmconfig.c68
13 files changed, 393 insertions, 80 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 9f63ae0f404b..b7808a89d945 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
159#endif 159#endif
160 160
161#ifdef CONFIG_PCI_MMCONFIG 161#ifdef CONFIG_PCI_MMCONFIG
162static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) 162/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
163struct acpi_table_mcfg_config *pci_mmcfg_config;
164int pci_mmcfg_config_num;
165
166int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
163{ 167{
164 struct acpi_table_mcfg *mcfg; 168 struct acpi_table_mcfg *mcfg;
169 unsigned long i;
170 int config_size;
165 171
166 if (!phys_addr || !size) 172 if (!phys_addr || !size)
167 return -EINVAL; 173 return -EINVAL;
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
172 return -ENODEV; 178 return -ENODEV;
173 } 179 }
174 180
175 if (mcfg->base_reserved) { 181 /* how many config structures do we have */
176 printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); 182 pci_mmcfg_config_num = 0;
183 i = size - sizeof(struct acpi_table_mcfg);
184 while (i >= sizeof(struct acpi_table_mcfg_config)) {
185 ++pci_mmcfg_config_num;
186 i -= sizeof(struct acpi_table_mcfg_config);
187 };
188 if (pci_mmcfg_config_num == 0) {
189 printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
177 return -ENODEV; 190 return -ENODEV;
178 } 191 }
179 192
180 pci_mmcfg_base_addr = mcfg->base_address; 193 config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
194 pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
195 if (!pci_mmcfg_config) {
196 printk(KERN_WARNING PREFIX
197 "No memory for MCFG config tables\n");
198 return -ENOMEM;
199 }
200
201 memcpy(pci_mmcfg_config, &mcfg->config, config_size);
202 for (i = 0; i < pci_mmcfg_config_num; ++i) {
203 if (mcfg->config[i].base_reserved) {
204 printk(KERN_ERR PREFIX
205 "MMCONFIG not in low 4GB of memory\n");
206 return -ENODEV;
207 }
208 }
181 209
182 return 0; 210 return 0;
183} 211}
184#else 212#endif /* CONFIG_PCI_MMCONFIG */
185#define acpi_parse_mcfg NULL
186#endif /* !CONFIG_PCI_MMCONFIG */
187 213
188#ifdef CONFIG_X86_LOCAL_APIC 214#ifdef CONFIG_X86_LOCAL_APIC
189static int __init 215static int __init
@@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu)
507EXPORT_SYMBOL(acpi_unmap_lsapic); 533EXPORT_SYMBOL(acpi_unmap_lsapic);
508#endif /* CONFIG_ACPI_HOTPLUG_CPU */ 534#endif /* CONFIG_ACPI_HOTPLUG_CPU */
509 535
536int
537acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
538{
539 /* TBD */
540 return -EINVAL;
541}
542EXPORT_SYMBOL(acpi_register_ioapic);
543
544int
545acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
546{
547 /* TBD */
548 return -EINVAL;
549}
550EXPORT_SYMBOL(acpi_unregister_ioapic);
551
510static unsigned long __init 552static unsigned long __init
511acpi_scan_rsdp ( 553acpi_scan_rsdp (
512 unsigned long start, 554 unsigned long start,
@@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void)
1123 acpi_process_madt(); 1165 acpi_process_madt();
1124 1166
1125 acpi_table_parse(ACPI_HPET, acpi_parse_hpet); 1167 acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
1126 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
1127 1168
1128 return 0; 1169 return 0;
1129} 1170}
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 720975e1af50..87325263cd4f 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
25 25
26int pci_routeirq; 26int pci_routeirq;
27int pcibios_last_bus = -1; 27int pcibios_last_bus = -1;
28struct pci_bus *pci_root_bus = NULL; 28unsigned long pirq_table_addr;
29struct pci_bus *pci_root_bus;
29struct pci_raw_ops *raw_pci_ops; 30struct pci_raw_ops *raw_pci_ops;
30 31
31static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 32static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
133 134
134 printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); 135 printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
135 136
136 return pci_scan_bus(busnum, &pci_root_ops, NULL); 137 return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
137} 138}
138 139
139extern u8 pci_cache_line_size; 140extern u8 pci_cache_line_size;
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str)
188 } else if (!strcmp(str, "biosirq")) { 189 } else if (!strcmp(str, "biosirq")) {
189 pci_probe |= PCI_BIOS_IRQ_SCAN; 190 pci_probe |= PCI_BIOS_IRQ_SCAN;
190 return NULL; 191 return NULL;
192 } else if (!strncmp(str, "pirqaddr=", 9)) {
193 pirq_table_addr = simple_strtoul(str+9, NULL, 0);
194 return NULL;
191 } 195 }
192#endif 196#endif
193#ifdef CONFIG_PCI_DIRECT 197#ifdef CONFIG_PCI_DIRECT
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index 83458f81e661..78ca1ecbb907 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -58,6 +58,35 @@ struct irq_router_handler {
58int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; 58int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
59 59
60/* 60/*
61 * Check passed address for the PCI IRQ Routing Table signature
62 * and perform checksum verification.
63 */
64
65static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
66{
67 struct irq_routing_table *rt;
68 int i;
69 u8 sum;
70
71 rt = (struct irq_routing_table *) addr;
72 if (rt->signature != PIRQ_SIGNATURE ||
73 rt->version != PIRQ_VERSION ||
74 rt->size % 16 ||
75 rt->size < sizeof(struct irq_routing_table))
76 return NULL;
77 sum = 0;
78 for (i=0; i < rt->size; i++)
79 sum += addr[i];
80 if (!sum) {
81 DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
82 return rt;
83 }
84 return NULL;
85}
86
87
88
89/*
61 * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. 90 * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
62 */ 91 */
63 92
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void)
65{ 94{
66 u8 *addr; 95 u8 *addr;
67 struct irq_routing_table *rt; 96 struct irq_routing_table *rt;
68 int i;
69 u8 sum;
70 97
98 if (pirq_table_addr) {
99 rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
100 if (rt)
101 return rt;
102 printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
103 }
71 for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { 104 for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
72 rt = (struct irq_routing_table *) addr; 105 rt = pirq_check_routing_table(addr);
73 if (rt->signature != PIRQ_SIGNATURE || 106 if (rt)
74 rt->version != PIRQ_VERSION ||
75 rt->size % 16 ||
76 rt->size < sizeof(struct irq_routing_table))
77 continue;
78 sum = 0;
79 for(i=0; i<rt->size; i++)
80 sum += addr[i];
81 if (!sum) {
82 DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
83 return rt; 107 return rt;
84 }
85 } 108 }
86 return NULL; 109 return NULL;
87} 110}
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
index 1492e3753869..149a9588c256 100644
--- a/arch/i386/pci/legacy.c
+++ b/arch/i386/pci/legacy.c
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void)
45 45
46 printk("PCI: Probing PCI hardware\n"); 46 printk("PCI: Probing PCI hardware\n");
47 pci_root_bus = pcibios_scan_root(0); 47 pci_root_bus = pcibios_scan_root(0);
48 if (pci_root_bus)
49 pci_bus_add_devices(pci_root_bus);
48 50
49 pcibios_fixup_peer_bridges(); 51 pcibios_fixup_peer_bridges();
50 52
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 021a50aa51f4..60f0e7a1162a 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -11,11 +11,9 @@
11 11
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/acpi.h>
14#include "pci.h" 15#include "pci.h"
15 16
16/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
17u32 pci_mmcfg_base_addr;
18
19#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) 17#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
20 18
21/* The base address of the last MMCONFIG device accessed */ 19/* The base address of the last MMCONFIG device accessed */
@@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device;
24/* 22/*
25 * Functions for accessing PCI configuration space with MMCONFIG accesses 23 * Functions for accessing PCI configuration space with MMCONFIG accesses
26 */ 24 */
25static u32 get_base_addr(unsigned int seg, int bus)
26{
27 int cfg_num = -1;
28 struct acpi_table_mcfg_config *cfg;
29
30 while (1) {
31 ++cfg_num;
32 if (cfg_num >= pci_mmcfg_config_num) {
33 /* something bad is going on, no cfg table is found. */
34 /* so we fall back to the old way we used to do this */
35 /* and just rely on the first entry to be correct. */
36 return pci_mmcfg_config[0].base_address;
37 }
38 cfg = &pci_mmcfg_config[cfg_num];
39 if (cfg->pci_segment_group_number != seg)
40 continue;
41 if ((cfg->start_bus_number <= bus) &&
42 (cfg->end_bus_number >= bus))
43 return cfg->base_address;
44 }
45}
27 46
28static inline void pci_exp_set_dev_base(int bus, int devfn) 47static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)
29{ 48{
30 u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); 49 u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);
31 if (dev_base != mmcfg_last_accessed_device) { 50 if (dev_base != mmcfg_last_accessed_device) {
32 mmcfg_last_accessed_device = dev_base; 51 mmcfg_last_accessed_device = dev_base;
33 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); 52 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
@@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
44 63
45 spin_lock_irqsave(&pci_config_lock, flags); 64 spin_lock_irqsave(&pci_config_lock, flags);
46 65
47 pci_exp_set_dev_base(bus, devfn); 66 pci_exp_set_dev_base(seg, bus, devfn);
48 67
49 switch (len) { 68 switch (len) {
50 case 1: 69 case 1:
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
73 92
74 spin_lock_irqsave(&pci_config_lock, flags); 93 spin_lock_irqsave(&pci_config_lock, flags);
75 94
76 pci_exp_set_dev_base(bus, devfn); 95 pci_exp_set_dev_base(seg, bus, devfn);
77 96
78 switch (len) { 97 switch (len) {
79 case 1: 98 case 1:
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void)
101{ 120{
102 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 121 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
103 goto out; 122 goto out;
104 if (!pci_mmcfg_base_addr) 123
124 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
125 if ((pci_mmcfg_config_num == 0) ||
126 (pci_mmcfg_config == NULL) ||
127 (pci_mmcfg_config[0].base_address == 0))
105 goto out; 128 goto out;
106 129
107 /* Kludge for now. Don't use mmconfig on AMD systems because 130 /* Kludge for now. Don't use mmconfig on AMD systems because
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c
index 9e3695461899..adbe17a38f6f 100644
--- a/arch/i386/pci/numa.c
+++ b/arch/i386/pci/numa.c
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void)
115 return 0; 115 return 0;
116 116
117 pci_root_bus = pcibios_scan_root(0); 117 pci_root_bus = pcibios_scan_root(0);
118 if (pci_root_bus)
119 pci_bus_add_devices(pci_root_bus);
118 if (num_online_nodes() > 1) 120 if (num_online_nodes() > 1)
119 for_each_online_node(quad) { 121 for_each_online_node(quad) {
120 if (quad == 0) 122 if (quad == 0)
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index a8fc80ca69f3..a80f0f55ff51 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -27,6 +27,7 @@
27#define PCI_ASSIGN_ALL_BUSSES 0x4000 27#define PCI_ASSIGN_ALL_BUSSES 0x4000
28 28
29extern unsigned int pci_probe; 29extern unsigned int pci_probe;
30extern unsigned long pirq_table_addr;
30 31
31/* pci-i386.c */ 32/* pci-i386.c */
32 33
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 72dfd9e7de0f..cda06f88c66e 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
236 if (BAD_MADT_ENTRY(iosapic, end)) 236 if (BAD_MADT_ENTRY(iosapic, end))
237 return -EINVAL; 237 return -EINVAL;
238 238
239 iosapic_init(iosapic->address, iosapic->global_irq_base); 239 return iosapic_init(iosapic->address, iosapic->global_irq_base);
240
241 return 0;
242} 240}
243 241
244 242
@@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
772 770
773 771
774#ifdef CONFIG_ACPI_NUMA 772#ifdef CONFIG_ACPI_NUMA
775acpi_status __init 773acpi_status __devinit
776acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) 774acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
777{ 775{
778 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 776 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -825,4 +823,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
825 return AE_OK; 823 return AE_OK;
826} 824}
827#endif /* CONFIG_NUMA */ 825#endif /* CONFIG_NUMA */
826
827int
828acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
829{
830 int err;
831
832 if ((err = iosapic_init(phys_addr, gsi_base)))
833 return err;
834
835#if CONFIG_ACPI_NUMA
836 acpi_map_iosapic(handle, 0, NULL, NULL);
837#endif /* CONFIG_ACPI_NUMA */
838
839 return 0;
840}
841EXPORT_SYMBOL(acpi_register_ioapic);
842
843int
844acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
845{
846 return iosapic_remove(gsi_base);
847}
848EXPORT_SYMBOL(acpi_unregister_ioapic);
849
828#endif /* CONFIG_ACPI_BOOT */ 850#endif /* CONFIG_ACPI_BOOT */
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 88b014381df5..c170be095ccd 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -129,14 +129,13 @@ static struct iosapic {
129 char __iomem *addr; /* base address of IOSAPIC */ 129 char __iomem *addr; /* base address of IOSAPIC */
130 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ 130 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
131 unsigned short num_rte; /* number of RTE in this IOSAPIC */ 131 unsigned short num_rte; /* number of RTE in this IOSAPIC */
132 int rtes_inuse; /* # of RTEs in use on this IOSAPIC */
132#ifdef CONFIG_NUMA 133#ifdef CONFIG_NUMA
133 unsigned short node; /* numa node association via pxm */ 134 unsigned short node; /* numa node association via pxm */
134#endif 135#endif
135} iosapic_lists[NR_IOSAPICS]; 136} iosapic_lists[NR_IOSAPICS];
136 137
137static int num_iosapic; 138static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
138
139static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */
140 139
141static int iosapic_kmalloc_ok; 140static int iosapic_kmalloc_ok;
142static LIST_HEAD(free_rte_list); 141static LIST_HEAD(free_rte_list);
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi)
149{ 148{
150 int i; 149 int i;
151 150
152 for (i = 0; i < num_iosapic; i++) { 151 for (i = 0; i < NR_IOSAPICS; i++) {
153 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) 152 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
154 return i; 153 return i;
155 } 154 }
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
598 rte->refcnt++; 597 rte->refcnt++;
599 list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); 598 list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
600 iosapic_intr_info[vector].count++; 599 iosapic_intr_info[vector].count++;
600 iosapic_lists[index].rtes_inuse++;
601 } 601 }
602 else if (vector_is_shared(vector)) { 602 else if (vector_is_shared(vector)) {
603 struct iosapic_intr_info *info = &iosapic_intr_info[vector]; 603 struct iosapic_intr_info *info = &iosapic_intr_info[vector];
@@ -778,7 +778,7 @@ void
778iosapic_unregister_intr (unsigned int gsi) 778iosapic_unregister_intr (unsigned int gsi)
779{ 779{
780 unsigned long flags; 780 unsigned long flags;
781 int irq, vector; 781 int irq, vector, index;
782 irq_desc_t *idesc; 782 irq_desc_t *idesc;
783 u32 low32; 783 u32 low32;
784 unsigned long trigger, polarity; 784 unsigned long trigger, polarity;
@@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi)
819 list_del(&rte->rte_list); 819 list_del(&rte->rte_list);
820 iosapic_intr_info[vector].count--; 820 iosapic_intr_info[vector].count--;
821 iosapic_free_rte(rte); 821 iosapic_free_rte(rte);
822 index = find_iosapic(gsi);
823 iosapic_lists[index].rtes_inuse--;
824 WARN_ON(iosapic_lists[index].rtes_inuse < 0);
822 825
823 trigger = iosapic_intr_info[vector].trigger; 826 trigger = iosapic_intr_info[vector].trigger;
824 polarity = iosapic_intr_info[vector].polarity; 827 polarity = iosapic_intr_info[vector].polarity;
@@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat)
952 } 955 }
953} 956}
954 957
955void __init 958static inline int
959iosapic_alloc (void)
960{
961 int index;
962
963 for (index = 0; index < NR_IOSAPICS; index++)
964 if (!iosapic_lists[index].addr)
965 return index;
966
967 printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
968 return -1;
969}
970
971static inline void
972iosapic_free (int index)
973{
974 memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
975}
976
977static inline int
978iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
979{
980 int index;
981 unsigned int gsi_end, base, end;
982
983 /* check gsi range */
984 gsi_end = gsi_base + ((ver >> 16) & 0xff);
985 for (index = 0; index < NR_IOSAPICS; index++) {
986 if (!iosapic_lists[index].addr)
987 continue;
988
989 base = iosapic_lists[index].gsi_base;
990 end = base + iosapic_lists[index].num_rte - 1;
991
992 if (gsi_base < base && gsi_end < base)
993 continue;/* OK */
994
995 if (gsi_base > end && gsi_end > end)
996 continue; /* OK */
997
998 return -EBUSY;
999 }
1000 return 0;
1001}
1002
1003int __devinit
956iosapic_init (unsigned long phys_addr, unsigned int gsi_base) 1004iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
957{ 1005{
958 int num_rte; 1006 int num_rte, err, index;
959 unsigned int isa_irq, ver; 1007 unsigned int isa_irq, ver;
960 char __iomem *addr; 1008 char __iomem *addr;
1009 unsigned long flags;
1010
1011 spin_lock_irqsave(&iosapic_lock, flags);
1012 {
1013 addr = ioremap(phys_addr, 0);
1014 ver = iosapic_version(addr);
961 1015
962 addr = ioremap(phys_addr, 0); 1016 if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
963 ver = iosapic_version(addr); 1017 iounmap(addr);
1018 spin_unlock_irqrestore(&iosapic_lock, flags);
1019 return err;
1020 }
964 1021
965 /* 1022 /*
966 * The MAX_REDIR register holds the highest input pin 1023 * The MAX_REDIR register holds the highest input pin
967 * number (starting from 0). 1024 * number (starting from 0).
968 * We add 1 so that we can use it for number of pins (= RTEs) 1025 * We add 1 so that we can use it for number of pins (= RTEs)
969 */ 1026 */
970 num_rte = ((ver >> 16) & 0xff) + 1; 1027 num_rte = ((ver >> 16) & 0xff) + 1;
971 1028
972 iosapic_lists[num_iosapic].addr = addr; 1029 index = iosapic_alloc();
973 iosapic_lists[num_iosapic].gsi_base = gsi_base; 1030 iosapic_lists[index].addr = addr;
974 iosapic_lists[num_iosapic].num_rte = num_rte; 1031 iosapic_lists[index].gsi_base = gsi_base;
1032 iosapic_lists[index].num_rte = num_rte;
975#ifdef CONFIG_NUMA 1033#ifdef CONFIG_NUMA
976 iosapic_lists[num_iosapic].node = MAX_NUMNODES; 1034 iosapic_lists[index].node = MAX_NUMNODES;
977#endif 1035#endif
978 num_iosapic++; 1036 }
1037 spin_unlock_irqrestore(&iosapic_lock, flags);
979 1038
980 if ((gsi_base == 0) && pcat_compat) { 1039 if ((gsi_base == 0) && pcat_compat) {
981 /* 1040 /*
@@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
986 for (isa_irq = 0; isa_irq < 16; ++isa_irq) 1045 for (isa_irq = 0; isa_irq < 16; ++isa_irq)
987 iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); 1046 iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
988 } 1047 }
1048 return 0;
1049}
1050
1051#ifdef CONFIG_HOTPLUG
1052int
1053iosapic_remove (unsigned int gsi_base)
1054{
1055 int index, err = 0;
1056 unsigned long flags;
1057
1058 spin_lock_irqsave(&iosapic_lock, flags);
1059 {
1060 index = find_iosapic(gsi_base);
1061 if (index < 0) {
1062 printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
1063 __FUNCTION__, gsi_base);
1064 goto out;
1065 }
1066
1067 if (iosapic_lists[index].rtes_inuse) {
1068 err = -EBUSY;
1069 printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
1070 __FUNCTION__, gsi_base);
1071 goto out;
1072 }
1073
1074 iounmap(iosapic_lists[index].addr);
1075 iosapic_free(index);
1076 }
1077 out:
1078 spin_unlock_irqrestore(&iosapic_lock, flags);
1079 return err;
989} 1080}
1081#endif /* CONFIG_HOTPLUG */
990 1082
991#ifdef CONFIG_NUMA 1083#ifdef CONFIG_NUMA
992void __init 1084void __devinit
993map_iosapic_to_node(unsigned int gsi_base, int node) 1085map_iosapic_to_node(unsigned int gsi_base, int node)
994{ 1086{
995 int index; 1087 int index;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index e3fc4edea113..720a861f88be 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
312 acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, 312 acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
313 &info); 313 &info);
314 314
315 pbus = pci_scan_bus(bus, &pci_root_ops, controller); 315 pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
316 if (pbus) 316 if (pbus)
317 pcibios_setup_root_windows(pbus, controller); 317 pcibios_setup_root_windows(pbus, controller);
318 318
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
373 res->end = region->end + offset; 373 res->end = region->end + offset;
374} 374}
375 375
376static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
377{
378 unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
379 struct resource *devr = &dev->resource[idx];
380
381 if (!dev->bus)
382 return 0;
383 for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
384 struct resource *busr = dev->bus->resource[i];
385
386 if (!busr || ((busr->flags ^ devr->flags) & type_mask))
387 continue;
388 if ((devr->start) && (devr->start >= busr->start) &&
389 (devr->end <= busr->end))
390 return 1;
391 }
392 return 0;
393}
394
376static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) 395static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
377{ 396{
378 struct pci_bus_region region; 397 struct pci_bus_region region;
@@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
386 region.start = dev->resource[i].start; 405 region.start = dev->resource[i].start;
387 region.end = dev->resource[i].end; 406 region.end = dev->resource[i].end;
388 pcibios_bus_to_resource(dev, &dev->resource[i], &region); 407 pcibios_bus_to_resource(dev, &dev->resource[i], &region);
389 pci_claim_resource(dev, i); 408 if ((is_valid_resource(dev, i)))
409 pci_claim_resource(dev, i);
390 } 410 }
391} 411}
392 412
@@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b)
398{ 418{
399 struct pci_dev *dev; 419 struct pci_dev *dev;
400 420
421 if (b->self) {
422 pci_read_bridge_bases(b);
423 pcibios_fixup_device_resources(b->self);
424 }
401 list_for_each_entry(dev, &b->devices, bus_list) 425 list_for_each_entry(dev, &b->devices, bus_list)
402 pcibios_fixup_device_resources(dev); 426 pcibios_fixup_device_resources(dev);
403 427
@@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
418 u16 cmd, old_cmd; 442 u16 cmd, old_cmd;
419 int idx; 443 int idx;
420 struct resource *r; 444 struct resource *r;
445 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
421 446
422 if (!dev) 447 if (!dev)
423 return -EINVAL; 448 return -EINVAL;
424 449
425 pci_read_config_word(dev, PCI_COMMAND, &cmd); 450 pci_read_config_word(dev, PCI_COMMAND, &cmd);
426 old_cmd = cmd; 451 old_cmd = cmd;
427 for (idx=0; idx<6; idx++) { 452 for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {
428 /* Only set up the desired resources. */ 453 /* Only set up the desired resources. */
429 if (!(mask & (1 << idx))) 454 if (!(mask & (1 << idx)))
430 continue; 455 continue;
431 456
432 r = &dev->resource[idx]; 457 r = &dev->resource[idx];
458 if (!(r->flags & type_mask))
459 continue;
460 if ((idx == PCI_ROM_RESOURCE) &&
461 (!(r->flags & IORESOURCE_ROM_ENABLE)))
462 continue;
433 if (!r->start && r->end) { 463 if (!r->start && r->end) {
434 printk(KERN_ERR 464 printk(KERN_ERR
435 "PCI: Device %s not available because of resource collisions\n", 465 "PCI: Device %s not available because of resource collisions\n",
@@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
441 if (r->flags & IORESOURCE_MEM) 471 if (r->flags & IORESOURCE_MEM)
442 cmd |= PCI_COMMAND_MEMORY; 472 cmd |= PCI_COMMAND_MEMORY;
443 } 473 }
444 if (dev->resource[PCI_ROM_RESOURCE].start)
445 cmd |= PCI_COMMAND_MEMORY;
446 if (cmd != old_cmd) { 474 if (cmd != old_cmd) {
447 printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); 475 printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
448 pci_write_config_word(dev, PCI_COMMAND, cmd); 476 pci_write_config_word(dev, PCI_COMMAND, cmd);
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 6d7b92d72458..70cfb6ffd877 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
1495 *offset += hose->pci_mem_offset; 1495 *offset += hose->pci_mem_offset;
1496 res_bit = IORESOURCE_MEM; 1496 res_bit = IORESOURCE_MEM;
1497 } else { 1497 } else {
1498 io_offset = (unsigned long)hose->io_base_virt; 1498 io_offset = hose->io_base_virt - ___IO_BASE;
1499 *offset += io_offset; 1499 *offset += io_offset;
1500 res_bit = IORESOURCE_IO; 1500 res_bit = IORESOURCE_IO;
1501 } 1501 }
@@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
1522 1522
1523 /* found it! construct the final physical address */ 1523 /* found it! construct the final physical address */
1524 if (mmap_state == pci_mmap_io) 1524 if (mmap_state == pci_mmap_io)
1525 *offset += hose->io_base_phys - _IO_BASE; 1525 *offset += hose->io_base_phys - io_offset;
1526 return rp; 1526 return rp;
1527 } 1527 }
1528 1528
@@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
1739 return result; 1739 return result;
1740} 1740}
1741 1741
1742void pci_resource_to_user(const struct pci_dev *dev, int bar,
1743 const struct resource *rsrc,
1744 u64 *start, u64 *end)
1745{
1746 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
1747 unsigned long offset = 0;
1748
1749 if (hose == NULL)
1750 return;
1751
1752 if (rsrc->flags & IORESOURCE_IO)
1753 offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;
1754
1755 *start = rsrc->start + offset;
1756 *end = rsrc->end + offset;
1757}
1758
1742void __init 1759void __init
1743pci_init_resource(struct resource *res, unsigned long start, unsigned long end, 1760pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
1744 int flags, char *name) 1761 int flags, char *name)
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index 580676f87d23..ae6f579d3fa0 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
351 *offset += hose->pci_mem_offset; 351 *offset += hose->pci_mem_offset;
352 res_bit = IORESOURCE_MEM; 352 res_bit = IORESOURCE_MEM;
353 } else { 353 } else {
354 io_offset = (unsigned long)hose->io_base_virt; 354 io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
355 *offset += io_offset; 355 *offset += io_offset;
356 res_bit = IORESOURCE_IO; 356 res_bit = IORESOURCE_IO;
357 } 357 }
@@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
378 378
379 /* found it! construct the final physical address */ 379 /* found it! construct the final physical address */
380 if (mmap_state == pci_mmap_io) 380 if (mmap_state == pci_mmap_io)
381 *offset += hose->io_base_phys - io_offset; 381 *offset += hose->io_base_phys - io_offset;
382 return rp; 382 return rp;
383 } 383 }
384 384
@@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
944} 944}
945EXPORT_SYMBOL(pci_read_irq_line); 945EXPORT_SYMBOL(pci_read_irq_line);
946 946
947void pci_resource_to_user(const struct pci_dev *dev, int bar,
948 const struct resource *rsrc,
949 u64 *start, u64 *end)
950{
951 struct pci_controller *hose = pci_bus_to_host(dev->bus);
952 unsigned long offset = 0;
953
954 if (hose == NULL)
955 return;
956
957 if (rsrc->flags & IORESOURCE_IO)
958 offset = pci_io_base - (unsigned long)hose->io_base_virt +
959 hose->io_base_phys;
960
961 *start = rsrc->start + offset;
962 *end = rsrc->end + offset;
963}
964
947#endif /* CONFIG_PPC_MULTIPLATFORM */ 965#endif /* CONFIG_PPC_MULTIPLATFORM */
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index b693c232fd07..657e88aa0902 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -7,25 +7,50 @@
7 7
8#include <linux/pci.h> 8#include <linux/pci.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/acpi.h>
10#include "pci.h" 11#include "pci.h"
11 12
12#define MMCONFIG_APER_SIZE (256*1024*1024) 13#define MMCONFIG_APER_SIZE (256*1024*1024)
13 14
14/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
15u32 pci_mmcfg_base_addr;
16
17/* Static virtual mapping of the MMCONFIG aperture */ 15/* Static virtual mapping of the MMCONFIG aperture */
18char *pci_mmcfg_virt; 16struct mmcfg_virt {
17 struct acpi_table_mcfg_config *cfg;
18 char *virt;
19};
20static struct mmcfg_virt *pci_mmcfg_virt;
19 21
20static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) 22static char *get_virt(unsigned int seg, int bus)
21{ 23{
22 return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); 24 int cfg_num = -1;
25 struct acpi_table_mcfg_config *cfg;
26
27 while (1) {
28 ++cfg_num;
29 if (cfg_num >= pci_mmcfg_config_num) {
30 /* something bad is going on, no cfg table is found. */
31 /* so we fall back to the old way we used to do this */
32 /* and just rely on the first entry to be correct. */
33 return pci_mmcfg_virt[0].virt;
34 }
35 cfg = pci_mmcfg_virt[cfg_num].cfg;
36 if (cfg->pci_segment_group_number != seg)
37 continue;
38 if ((cfg->start_bus_number <= bus) &&
39 (cfg->end_bus_number >= bus))
40 return pci_mmcfg_virt[cfg_num].virt;
41 }
42}
43
44static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
45{
46
47 return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));
23} 48}
24 49
25static int pci_mmcfg_read(unsigned int seg, unsigned int bus, 50static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
26 unsigned int devfn, int reg, int len, u32 *value) 51 unsigned int devfn, int reg, int len, u32 *value)
27{ 52{
28 char *addr = pci_dev_base(bus, devfn); 53 char *addr = pci_dev_base(seg, bus, devfn);
29 54
30 if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) 55 if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
31 return -EINVAL; 56 return -EINVAL;
@@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
48static int pci_mmcfg_write(unsigned int seg, unsigned int bus, 73static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
49 unsigned int devfn, int reg, int len, u32 value) 74 unsigned int devfn, int reg, int len, u32 value)
50{ 75{
51 char *addr = pci_dev_base(bus,devfn); 76 char *addr = pci_dev_base(seg, bus, devfn);
52 77
53 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) 78 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
54 return -EINVAL; 79 return -EINVAL;
@@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = {
75 100
76static int __init pci_mmcfg_init(void) 101static int __init pci_mmcfg_init(void)
77{ 102{
103 int i;
104
78 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 105 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
79 return 0; 106 return 0;
80 if (!pci_mmcfg_base_addr) 107
108 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
109 if ((pci_mmcfg_config_num == 0) ||
110 (pci_mmcfg_config == NULL) ||
111 (pci_mmcfg_config[0].base_address == 0))
81 return 0; 112 return 0;
82 113
83 /* Kludge for now. Don't use mmconfig on AMD systems because 114 /* Kludge for now. Don't use mmconfig on AMD systems because
@@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void)
88 return 0; 119 return 0;
89 120
90 /* RED-PEN i386 doesn't do _nocache right now */ 121 /* RED-PEN i386 doesn't do _nocache right now */
91 pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); 122 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
92 if (!pci_mmcfg_virt) { 123 if (pci_mmcfg_virt == NULL) {
93 printk("PCI: Cannot map mmconfig aperture\n"); 124 printk("PCI: Can not allocate memory for mmconfig structures\n");
94 return 0; 125 return 0;
95 } 126 }
127 for (i = 0; i < pci_mmcfg_config_num; ++i) {
128 pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
129 pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
130 if (!pci_mmcfg_virt[i].virt) {
131 printk("PCI: Cannot map mmconfig aperture for segment %d\n",
132 pci_mmcfg_config[i].pci_segment_group_number);
133 return 0;
134 }
135 printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
136 }
96 137
97 printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr);
98 raw_pci_ops = &pci_mmcfg; 138 raw_pci_ops = &pci_mmcfg;
99 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 139 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
100 140