aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/pci/mmconfig-shared.c52
-rw-r--r--arch/i386/pci/mmconfig.c13
-rw-r--r--arch/i386/pci/pci.h4
3 files changed, 29 insertions, 40 deletions
diff --git a/arch/i386/pci/mmconfig-shared.c b/arch/i386/pci/mmconfig-shared.c
index 77de6de94f1f..4ea0852487a4 100644
--- a/arch/i386/pci/mmconfig-shared.c
+++ b/arch/i386/pci/mmconfig-shared.c
@@ -22,10 +22,6 @@
22#define MMCONFIG_APER_MIN (2 * 1024*1024) 22#define MMCONFIG_APER_MIN (2 * 1024*1024)
23#define MMCONFIG_APER_MAX (256 * 1024*1024) 23#define MMCONFIG_APER_MAX (256 * 1024*1024)
24 24
25/* Verify the first 16 busses. We assume that systems with more busses
26 get MCFG right. */
27#define PCI_MMCFG_MAX_CHECK_BUS 16
28
29DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); 25DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
30 26
31/* K8 systems have some devices (typically in the builtin northbridge) 27/* K8 systems have some devices (typically in the builtin northbridge)
@@ -34,29 +30,30 @@ DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
34 and assigning suitable _SEGs, but this isn't implemented in some BIOS. 30 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
35 Instead try to discover all devices on bus 0 that are unreachable using MM 31 Instead try to discover all devices on bus 0 that are unreachable using MM
36 and fallback for them. */ 32 and fallback for them. */
37static __init void unreachable_devices(void) 33static void __init unreachable_devices(void)
38{ 34{
39 int i, k; 35 int i, bus;
40 /* Use the max bus number from ACPI here? */ 36 /* Use the max bus number from ACPI here? */
41 for (k = 0; k < PCI_MMCFG_MAX_CHECK_BUS; k++) { 37 for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
42 for (i = 0; i < 32; i++) { 38 for (i = 0; i < 32; i++) {
39 unsigned int devfn = PCI_DEVFN(i, 0);
43 u32 val1, val2; 40 u32 val1, val2;
44 41
45 pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1); 42 pci_conf1_read(0, bus, devfn, 0, 4, &val1);
46 if (val1 == 0xffffffff) 43 if (val1 == 0xffffffff)
47 continue; 44 continue;
48 45
49 raw_pci_ops->read(0, k, PCI_DEVFN(i, 0), 0, 4, &val2); 46 raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
50 if (val1 != val2) { 47 if (val1 != val2) {
51 set_bit(i + 32*k, pci_mmcfg_fallback_slots); 48 set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
52 printk(KERN_NOTICE "PCI: No mmconfig possible" 49 printk(KERN_NOTICE "PCI: No mmconfig possible"
53 " on device %02x:%02x\n", k, i); 50 " on device %02x:%02x\n", bus, i);
54 } 51 }
55 } 52 }
56 } 53 }
57} 54}
58 55
59static __init const char *pci_mmcfg_e7520(void) 56static const char __init *pci_mmcfg_e7520(void)
60{ 57{
61 u32 win; 58 u32 win;
62 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win); 59 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
@@ -73,7 +70,7 @@ static __init const char *pci_mmcfg_e7520(void)
73 return "Intel Corporation E7520 Memory Controller Hub"; 70 return "Intel Corporation E7520 Memory Controller Hub";
74} 71}
75 72
76static __init const char *pci_mmcfg_intel_945(void) 73static const char __init *pci_mmcfg_intel_945(void)
77{ 74{
78 u32 pciexbar, mask = 0, len = 0; 75 u32 pciexbar, mask = 0, len = 0;
79 76
@@ -128,7 +125,7 @@ struct pci_mmcfg_hostbridge_probe {
128 const char *(*probe)(void); 125 const char *(*probe)(void);
129}; 126};
130 127
131static __initdata struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] = { 128static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
132 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 }, 129 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
133 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 }, 130 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
134}; 131};
@@ -148,25 +145,21 @@ static int __init pci_mmcfg_check_hostbridge(void)
148 pci_mmcfg_config = NULL; 145 pci_mmcfg_config = NULL;
149 name = NULL; 146 name = NULL;
150 147
151 for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) 148 for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
152 if ((pci_mmcfg_probes[i].vendor == PCI_ANY_ID || 149 if (pci_mmcfg_probes[i].vendor == vendor &&
153 pci_mmcfg_probes[i].vendor == vendor) && 150 pci_mmcfg_probes[i].device == device)
154 (pci_mmcfg_probes[i].device == PCI_ANY_ID ||
155 pci_mmcfg_probes[i].device == device))
156 name = pci_mmcfg_probes[i].probe(); 151 name = pci_mmcfg_probes[i].probe();
152 }
157 153
158 if (name) { 154 if (name) {
159 if (pci_mmcfg_config_num) 155 printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
160 printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", name); 156 name, pci_mmcfg_config_num ? "with" : "without");
161 else
162 printk(KERN_INFO "PCI: Found %s without MMCONFIG support.\n",
163 name);
164 } 157 }
165 158
166 return name != NULL; 159 return name != NULL;
167} 160}
168 161
169static __init void pci_mmcfg_insert_resources(void) 162static void __init pci_mmcfg_insert_resources(void)
170{ 163{
171#define PCI_MMCFG_RESOURCE_NAME_LEN 19 164#define PCI_MMCFG_RESOURCE_NAME_LEN 19
172 int i; 165 int i;
@@ -176,7 +169,6 @@ static __init void pci_mmcfg_insert_resources(void)
176 169
177 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), 170 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
178 pci_mmcfg_config_num, GFP_KERNEL); 171 pci_mmcfg_config_num, GFP_KERNEL);
179
180 if (!res) { 172 if (!res) {
181 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); 173 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
182 return; 174 return;
@@ -184,12 +176,12 @@ static __init void pci_mmcfg_insert_resources(void)
184 176
185 names = (void *)&res[pci_mmcfg_config_num]; 177 names = (void *)&res[pci_mmcfg_config_num];
186 for (i = 0; i < pci_mmcfg_config_num; i++, res++) { 178 for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
187 num_buses = pci_mmcfg_config[i].end_bus_number - 179 struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
188 pci_mmcfg_config[i].start_bus_number + 1; 180 num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
189 res->name = names; 181 res->name = names;
190 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", 182 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
191 pci_mmcfg_config[i].pci_segment); 183 cfg->pci_segment);
192 res->start = pci_mmcfg_config[i].address; 184 res->start = cfg->address;
193 res->end = res->start + (num_buses << 20) - 1; 185 res->end = res->start + (num_buses << 20) - 1;
194 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; 186 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
195 insert_resource(&iomem_resource, res); 187 insert_resource(&iomem_resource, res);
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 3325b79e651c..11be089efd7d 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -27,22 +27,17 @@ static int mmcfg_last_accessed_cpu;
27 */ 27 */
28static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) 28static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
29{ 29{
30 int cfg_num = -1;
31 struct acpi_mcfg_allocation *cfg; 30 struct acpi_mcfg_allocation *cfg;
31 int cfg_num;
32 32
33 if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS && 33 if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
34 test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots)) 34 test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots))
35 return 0; 35 return 0;
36 36
37 while (1) { 37 for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
38 ++cfg_num;
39 if (cfg_num >= pci_mmcfg_config_num) {
40 break;
41 }
42 cfg = &pci_mmcfg_config[cfg_num]; 38 cfg = &pci_mmcfg_config[cfg_num];
43 if (cfg->pci_segment != seg) 39 if (cfg->pci_segment == seg &&
44 continue; 40 (cfg->start_bus_number <= bus) &&
45 if ((cfg->start_bus_number <= bus) &&
46 (cfg->end_bus_number >= bus)) 41 (cfg->end_bus_number >= bus))
47 return cfg->address; 42 return cfg->address;
48 } 43 }
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index 0270c80d99cc..2ce3d44b09d4 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -96,7 +96,9 @@ extern void pcibios_sort(void);
96 96
97/* pci-mmconfig.c */ 97/* pci-mmconfig.c */
98 98
99/* Verify the first 16 busses. We assume that systems with more busses
100 get MCFG right. */
99#define PCI_MMCFG_MAX_CHECK_BUS 16 101#define PCI_MMCFG_MAX_CHECK_BUS 16
100extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); 102extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
101 103
102extern int pci_mmcfg_arch_init(void); 104extern int __init pci_mmcfg_arch_init(void);