aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2009-11-13 19:34:29 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-11-24 18:29:41 -0500
commit56ddf4d3cf04e80254d3d721c6bea2f8ec44c41a (patch)
tree9b09f7d7daf480138e4e178520d03d537a49959b
parent95cf1cf0c5a767feb811dfed298b95b1df8824c7 (diff)
x86/PCI: MMCONFIG: add resource to struct pci_mmcfg_region
This patch adds a resource and corresponding name to the MMCONFIG structure. This makes allocation simpler (we can allocate the resource and name at the same time we allocate the pci_mmcfg_region), and gives us a way to hang onto the resource after inserting it. This will be needed so we can release and free it when hot-removing a host bridge. Reviewed-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--arch/x86/include/asm/pci_x86.h5
-rw-r--r--arch/x86/pci/mmconfig-shared.c64
2 files changed, 38 insertions, 31 deletions
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index a752d618f196..a6d42c10b017 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -118,11 +118,16 @@ extern int __init pcibios_init(void);
118 118
119/* pci-mmconfig.c */ 119/* pci-mmconfig.c */
120 120
121/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
122#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
123
121struct pci_mmcfg_region { 124struct pci_mmcfg_region {
125 struct resource res;
122 u64 address; 126 u64 address;
123 u16 segment; 127 u16 segment;
124 u8 start_bus; 128 u8 start_bus;
125 u8 end_bus; 129 u8 end_bus;
130 char name[PCI_MMCFG_RESOURCE_NAME_LEN];
126}; 131};
127 132
128extern int __init pci_mmcfg_arch_init(void); 133extern int __init pci_mmcfg_arch_init(void);
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 28ac9f58a986..ba3aa3697418 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -28,7 +28,15 @@ static int __initdata pci_mmcfg_resources_inserted;
28 28
29static __init void free_all_mmcfg(void) 29static __init void free_all_mmcfg(void)
30{ 30{
31 int i;
32 struct pci_mmcfg_region *cfg;
33
31 pci_mmcfg_arch_free(); 34 pci_mmcfg_arch_free();
35 for (i = 0; i < pci_mmcfg_config_num; i++) {
36 cfg = &pci_mmcfg_config[i];
37 if (cfg->res.parent)
38 release_resource(&cfg->res);
39 }
32 pci_mmcfg_config_num = 0; 40 pci_mmcfg_config_num = 0;
33 kfree(pci_mmcfg_config); 41 kfree(pci_mmcfg_config);
34 pci_mmcfg_config = NULL; 42 pci_mmcfg_config = NULL;
@@ -40,6 +48,8 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
40 struct pci_mmcfg_region *new; 48 struct pci_mmcfg_region *new;
41 int new_num = pci_mmcfg_config_num + 1; 49 int new_num = pci_mmcfg_config_num + 1;
42 int i = pci_mmcfg_config_num; 50 int i = pci_mmcfg_config_num;
51 int num_buses;
52 struct resource *res;
43 53
44 if (addr == 0) 54 if (addr == 0)
45 return NULL; 55 return NULL;
@@ -63,6 +73,15 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
63 new->start_bus = start; 73 new->start_bus = start;
64 new->end_bus = end; 74 new->end_bus = end;
65 75
76 num_buses = end - start + 1;
77 res = &new->res;
78 res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
79 res->end = addr + PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
80 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
81 snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
82 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
83 res->name = new->name;
84
66 return &pci_mmcfg_config[i]; 85 return &pci_mmcfg_config[i];
67} 86}
68 87
@@ -336,33 +355,12 @@ static int __init pci_mmcfg_check_hostbridge(void)
336 355
337static void __init pci_mmcfg_insert_resources(void) 356static void __init pci_mmcfg_insert_resources(void)
338{ 357{
339#define PCI_MMCFG_RESOURCE_NAME_LEN 24
340 int i; 358 int i;
341 struct resource *res; 359 struct pci_mmcfg_region *cfg;
342 char *names;
343 unsigned num_buses;
344
345 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
346 pci_mmcfg_config_num, GFP_KERNEL);
347 if (!res) {
348 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
349 return;
350 }
351 360
352 names = (void *)&res[pci_mmcfg_config_num]; 361 for (i = 0; i < pci_mmcfg_config_num; i++) {
353 for (i = 0; i < pci_mmcfg_config_num; i++, res++) { 362 cfg = &pci_mmcfg_config[i];
354 struct pci_mmcfg_region *cfg = &pci_mmcfg_config[i]; 363 insert_resource(&iomem_resource, &cfg->res);
355 num_buses = cfg->end_bus - cfg->start_bus + 1;
356 res->name = names;
357 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN,
358 "PCI MMCONFIG %u [%02x-%02x]", cfg->segment,
359 cfg->start_bus, cfg->end_bus);
360 res->start = cfg->address +
361 PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
362 res->end = res->start + PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
363 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
364 insert_resource(&iomem_resource, res);
365 names += PCI_MMCFG_RESOURCE_NAME_LEN;
366 } 364 }
367 365
368 /* Mark that the resources have been inserted. */ 366 /* Mark that the resources have been inserted. */
@@ -444,7 +442,7 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
444 typeof(pci_mmcfg_config[0]) *cfg, int with_e820) 442 typeof(pci_mmcfg_config[0]) *cfg, int with_e820)
445{ 443{
446 u64 old_size = size; 444 u64 old_size = size;
447 int valid = 0; 445 int valid = 0, num_buses;
448 446
449 while (!is_reserved(addr, addr + size, E820_RESERVED)) { 447 while (!is_reserved(addr, addr + size, E820_RESERVED)) {
450 size >>= 1; 448 size >>= 1;
@@ -461,6 +459,12 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
461 if (old_size != size) { 459 if (old_size != size) {
462 /* update end_bus */ 460 /* update end_bus */
463 cfg->end_bus = cfg->start_bus + ((size>>20) - 1); 461 cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
462 num_buses = cfg->end_bus - cfg->start_bus + 1;
463 cfg->res.end = cfg->res.start +
464 PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
465 snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
466 "PCI MMCONFIG %04x [bus %02x-%02x]",
467 cfg->segment, cfg->start_bus, cfg->end_bus);
464 printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx " 468 printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx "
465 "segment %hu buses %u - %u\n", 469 "segment %hu buses %u - %u\n",
466 i, (unsigned long)cfg->address, cfg->segment, 470 i, (unsigned long)cfg->address, cfg->segment,
@@ -481,14 +485,12 @@ static void __init pci_mmcfg_reject_broken(int early)
481 return; 485 return;
482 486
483 for (i = 0; i < pci_mmcfg_config_num; i++) { 487 for (i = 0; i < pci_mmcfg_config_num; i++) {
484 int num_buses, valid = 0; 488 int valid = 0;
485 u64 addr, size; 489 u64 addr, size;
486 490
487 cfg = &pci_mmcfg_config[i]; 491 cfg = &pci_mmcfg_config[i];
488 addr = cfg->address + 492 addr = cfg->res.start;
489 PCI_MMCFG_BUS_OFFSET(cfg->start_bus); 493 size = resource_size(&cfg->res);
490 num_buses = cfg->end_bus - cfg->start_bus + 1;
491 size = PCI_MMCFG_BUS_OFFSET(num_buses);
492 printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " 494 printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
493 "segment %hu buses %u - %u\n", 495 "segment %hu buses %u - %u\n",
494 i, (unsigned long)cfg->address, cfg->segment, 496 i, (unsigned long)cfg->address, cfg->segment,