diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2009-11-13 19:34:29 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-11-24 18:29:41 -0500 |
commit | 56ddf4d3cf04e80254d3d721c6bea2f8ec44c41a (patch) | |
tree | 9b09f7d7daf480138e4e178520d03d537a49959b /arch | |
parent | 95cf1cf0c5a767feb811dfed298b95b1df8824c7 (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 5 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 64 |
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 | |||
121 | struct pci_mmcfg_region { | 124 | struct 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 | ||
128 | extern int __init pci_mmcfg_arch_init(void); | 133 | extern 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 | ||
29 | static __init void free_all_mmcfg(void) | 29 | static __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 | ||
337 | static void __init pci_mmcfg_insert_resources(void) | 356 | static 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, |