aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2009-11-13 19:33:53 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-11-24 18:28:51 -0500
commit7da7d360ae025158d09aab18d66f5d2fe3c02252 (patch)
tree35aaf2c1c39e17f24e89dcb0e19aa26d778b5f7e /arch/x86
parentd3578ef7aab5b9bb874d085609b3ed5d9abffc48 (diff)
x86/PCI: MMCONFIG: centralize MCFG structure management
This patch encapsulate pci_mmcfg_config[] updates. All alloc/free is now done in pci_mmconfig_add() and free_all_mcfg(), so all updates to pci_mmcfg_config[] and pci_mmcfg_config_num are in those two functions. This replaces the previous sequence of extend_mmcfg(), fill_one_mmcfg() with the single pci_mmconfig_add() interface. This interface is currently static but will eventually be used in the host bridge hot-add path. Reviewed-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/pci/mmconfig-shared.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 7a7b6ba3abbb..62a8ecd96980 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -26,14 +26,24 @@
26/* Indicate if the mmcfg resources have been placed into the resource table. */ 26/* Indicate if the mmcfg resources have been placed into the resource table. */
27static int __initdata pci_mmcfg_resources_inserted; 27static int __initdata pci_mmcfg_resources_inserted;
28 28
29static __init int extend_mmcfg(int num) 29static __init void free_all_mmcfg(void)
30{
31 pci_mmcfg_arch_free();
32 pci_mmcfg_config_num = 0;
33 kfree(pci_mmcfg_config);
34 pci_mmcfg_config = NULL;
35}
36
37static __init struct acpi_mcfg_allocation *pci_mmconfig_add(int segment,
38 int start, int end, u64 addr)
30{ 39{
31 struct acpi_mcfg_allocation *new; 40 struct acpi_mcfg_allocation *new;
32 int new_num = pci_mmcfg_config_num + num; 41 int new_num = pci_mmcfg_config_num + 1;
42 int i = pci_mmcfg_config_num;
33 43
34 new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL); 44 new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL);
35 if (!new) 45 if (!new)
36 return -1; 46 return NULL;
37 47
38 if (pci_mmcfg_config) { 48 if (pci_mmcfg_config) {
39 memcpy(new, pci_mmcfg_config, 49 memcpy(new, pci_mmcfg_config,
@@ -42,18 +52,13 @@ static __init int extend_mmcfg(int num)
42 } 52 }
43 pci_mmcfg_config = new; 53 pci_mmcfg_config = new;
44 54
45 return 0;
46}
47
48static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end)
49{
50 int i = pci_mmcfg_config_num;
51
52 pci_mmcfg_config_num++; 55 pci_mmcfg_config_num++;
53 pci_mmcfg_config[i].address = addr; 56 pci_mmcfg_config[i].address = addr;
54 pci_mmcfg_config[i].pci_segment = segment; 57 pci_mmcfg_config[i].pci_segment = segment;
55 pci_mmcfg_config[i].start_bus_number = start; 58 pci_mmcfg_config[i].start_bus_number = start;
56 pci_mmcfg_config[i].end_bus_number = end; 59 pci_mmcfg_config[i].end_bus_number = end;
60
61 return &pci_mmcfg_config[i];
57} 62}
58 63
59static const char __init *pci_mmcfg_e7520(void) 64static const char __init *pci_mmcfg_e7520(void)
@@ -65,11 +70,9 @@ static const char __init *pci_mmcfg_e7520(void)
65 if (win == 0x0000 || win == 0xf000) 70 if (win == 0x0000 || win == 0xf000)
66 return NULL; 71 return NULL;
67 72
68 if (extend_mmcfg(1) == -1) 73 if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL)
69 return NULL; 74 return NULL;
70 75
71 fill_one_mmcfg(win << 16, 0, 0, 255);
72
73 return "Intel Corporation E7520 Memory Controller Hub"; 76 return "Intel Corporation E7520 Memory Controller Hub";
74} 77}
75 78
@@ -111,11 +114,9 @@ static const char __init *pci_mmcfg_intel_945(void)
111 if ((pciexbar & mask) >= 0xf0000000U) 114 if ((pciexbar & mask) >= 0xf0000000U)
112 return NULL; 115 return NULL;
113 116
114 if (extend_mmcfg(1) == -1) 117 if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
115 return NULL; 118 return NULL;
116 119
117 fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1);
118
119 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; 120 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
120} 121}
121 122
@@ -124,7 +125,7 @@ static const char __init *pci_mmcfg_amd_fam10h(void)
124 u32 low, high, address; 125 u32 low, high, address;
125 u64 base, msr; 126 u64 base, msr;
126 int i; 127 int i;
127 unsigned segnbits = 0, busnbits; 128 unsigned segnbits = 0, busnbits, end_bus;
128 129
129 if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF)) 130 if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF))
130 return NULL; 131 return NULL;
@@ -158,11 +159,13 @@ static const char __init *pci_mmcfg_amd_fam10h(void)
158 busnbits = 8; 159 busnbits = 8;
159 } 160 }
160 161
161 if (extend_mmcfg(1 << segnbits) == -1) 162 end_bus = (1 << busnbits) - 1;
162 return NULL;
163
164 for (i = 0; i < (1 << segnbits); i++) 163 for (i = 0; i < (1 << segnbits); i++)
165 fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1); 164 if (pci_mmconfig_add(i, 0, end_bus,
165 base + (1<<28) * i) == NULL) {
166 free_all_mmcfg();
167 return NULL;
168 }
166 169
167 return "AMD Family 10h NB"; 170 return "AMD Family 10h NB";
168} 171}
@@ -210,16 +213,14 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void)
210 if (!(extcfg & extcfg_enable_mask)) 213 if (!(extcfg & extcfg_enable_mask))
211 continue; 214 continue;
212 215
213 if (extend_mmcfg(1) == -1)
214 continue;
215
216 size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; 216 size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift;
217 base = extcfg & extcfg_base_mask[size_index]; 217 base = extcfg & extcfg_base_mask[size_index];
218 /* base could > 4G */ 218 /* base could > 4G */
219 base <<= extcfg_base_lshift; 219 base <<= extcfg_base_lshift;
220 start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; 220 start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
221 end = start + extcfg_sizebus[size_index] - 1; 221 end = start + extcfg_sizebus[size_index] - 1;
222 fill_one_mmcfg(base, 0, start, end); 222 if (pci_mmconfig_add(0, start, end, base) == NULL)
223 continue;
223 mcp55_mmconf_found++; 224 mcp55_mmconf_found++;
224 } 225 }
225 226
@@ -303,8 +304,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
303 if (!raw_pci_ops) 304 if (!raw_pci_ops)
304 return 0; 305 return 0;
305 306
306 pci_mmcfg_config_num = 0; 307 free_all_mmcfg();
307 pci_mmcfg_config = NULL;
308 308
309 for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { 309 for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
310 bus = pci_mmcfg_probes[i].bus; 310 bus = pci_mmcfg_probes[i].bus;
@@ -516,10 +516,7 @@ static void __init pci_mmcfg_reject_broken(int early)
516 516
517reject: 517reject:
518 printk(KERN_INFO "PCI: Not using MMCONFIG.\n"); 518 printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
519 pci_mmcfg_arch_free(); 519 free_all_mmcfg();
520 kfree(pci_mmcfg_config);
521 pci_mmcfg_config = NULL;
522 pci_mmcfg_config_num = 0;
523} 520}
524 521
525static int __initdata known_bridge; 522static int __initdata known_bridge;
@@ -556,7 +553,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)
556 struct acpi_table_mcfg *mcfg; 553 struct acpi_table_mcfg *mcfg;
557 struct acpi_mcfg_allocation *cfg_table, *cfg; 554 struct acpi_mcfg_allocation *cfg_table, *cfg;
558 unsigned long i; 555 unsigned long i;
559 int entries, config_size; 556 int entries;
560 557
561 if (!header) 558 if (!header)
562 return -EINVAL; 559 return -EINVAL;
@@ -564,7 +561,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)
564 mcfg = (struct acpi_table_mcfg *)header; 561 mcfg = (struct acpi_table_mcfg *)header;
565 562
566 /* how many config structures do we have */ 563 /* how many config structures do we have */
567 pci_mmcfg_config_num = 0; 564 free_all_mmcfg();
568 entries = 0; 565 entries = 0;
569 i = header->length - sizeof(struct acpi_table_mcfg); 566 i = header->length - sizeof(struct acpi_table_mcfg);
570 while (i >= sizeof(struct acpi_mcfg_allocation)) { 567 while (i >= sizeof(struct acpi_mcfg_allocation)) {
@@ -576,25 +573,21 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)
576 return -ENODEV; 573 return -ENODEV;
577 } 574 }
578 575
579 config_size = entries * sizeof(*pci_mmcfg_config);
580 pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
581 if (!pci_mmcfg_config) {
582 printk(KERN_WARNING PREFIX
583 "No memory for MCFG config tables\n");
584 return -ENOMEM;
585 }
586
587 memcpy(pci_mmcfg_config, &mcfg[1], config_size);
588 pci_mmcfg_config_num = entries;
589
590 cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1]; 576 cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
591 for (i = 0; i < entries; i++) { 577 for (i = 0; i < entries; i++) {
592 cfg = &cfg_table[i]; 578 cfg = &cfg_table[i];
593 if (acpi_mcfg_check_entry(mcfg, cfg)) { 579 if (acpi_mcfg_check_entry(mcfg, cfg)) {
594 kfree(pci_mmcfg_config); 580 free_all_mmcfg();
595 pci_mmcfg_config_num = 0;
596 return -ENODEV; 581 return -ENODEV;
597 } 582 }
583
584 if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
585 cfg->end_bus_number, cfg->address) == NULL) {
586 printk(KERN_WARNING PREFIX
587 "no memory for MCFG entries\n");
588 free_all_mmcfg();
589 return -ENOMEM;
590 }
598 } 591 }
599 592
600 return 0; 593 return 0;