diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/pci/mmconfig-shared.c | 52 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 13 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 4 |
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 | |||
29 | DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); | 25 | DECLARE_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. */ |
37 | static __init void unreachable_devices(void) | 33 | static 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 | ||
59 | static __init const char *pci_mmcfg_e7520(void) | 56 | static 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 | ||
76 | static __init const char *pci_mmcfg_intel_945(void) | 73 | static 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 | ||
131 | static __initdata struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] = { | 128 | static 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 | ||
169 | static __init void pci_mmcfg_insert_resources(void) | 162 | static 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 | */ |
28 | static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | 28 | static 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 |
100 | extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); | 102 | extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); |
101 | 103 | ||
102 | extern int pci_mmcfg_arch_init(void); | 104 | extern int __init pci_mmcfg_arch_init(void); |