summaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
authorYinghai Lu <Yinghai.Lu@Sun.COM>2008-02-15 01:28:41 -0800
committerIngo Molnar <mingo@elte.hu>2008-04-26 23:41:03 +0200
commit0b64ad7123eb013c3de26750f2d4c356cd566231 (patch)
treef6c1f3ad3880a39eae7e309c0c24605063019fcf /arch/x86/pci
parent7752d5cfe3d11ca0bb9c673ec38bd78ba6578f8e (diff)
downloadlinux-0b64ad7123eb013c3de26750f2d4c356cd566231.tar.gz
linux-0b64ad7123eb013c3de26750f2d4c356cd566231.tar.bz2
linux-0b64ad7123eb013c3de26750f2d4c356cd566231.zip
x86: clear pci_mmcfg_virt when mmcfg get rejected
For x86_64, need to free pci_mmcfg_virt, and iounmap some pointers when MMCONF is not reserved in E820 or acpi _CRS and get rejected. Signed-off-by: Yinghai Lu <yinghai.lu@sun.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Greg KH <greg@kroah.com> Cc: Greg KH <greg@kroah.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/pci')
-rw-r--r--arch/x86/pci/mmconfig-shared.c1
-rw-r--r--arch/x86/pci/mmconfig_32.c4
-rw-r--r--arch/x86/pci/mmconfig_64.c22
-rw-r--r--arch/x86/pci/pci.h1
4 files changed, 27 insertions, 1 deletions
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 498e35ee428e..8f204955427c 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -300,6 +300,7 @@ static void __init pci_mmcfg_reject_broken(void)
reject:
printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
+ pci_mmcfg_arch_free();
kfree(pci_mmcfg_config);
pci_mmcfg_config = NULL;
pci_mmcfg_config_num = 0;
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 081816ada057..f3c761dce695 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -136,3 +136,7 @@ int __init pci_mmcfg_arch_init(void)
raw_pci_ext_ops = &pci_mmcfg;
return 1;
}
+
+void __init pci_mmcfg_arch_free(void)
+{
+}
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 9207fd49233c..a1994163c99d 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -127,7 +127,7 @@ static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
int __init pci_mmcfg_arch_init(void)
{
int i;
- pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) *
+ pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) *
pci_mmcfg_config_num, GFP_KERNEL);
if (pci_mmcfg_virt == NULL) {
printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
@@ -141,9 +141,29 @@ int __init pci_mmcfg_arch_init(void)
printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
"segment %d\n",
pci_mmcfg_config[i].pci_segment);
+ pci_mmcfg_arch_free();
return 0;
}
}
raw_pci_ext_ops = &pci_mmcfg;
return 1;
}
+
+void __init pci_mmcfg_arch_free(void)
+{
+ int i;
+
+ if (pci_mmcfg_virt == NULL)
+ return;
+
+ for (i = 0; i < pci_mmcfg_config_num; ++i) {
+ if (pci_mmcfg_virt[i].virt) {
+ iounmap(pci_mmcfg_virt[i].virt);
+ pci_mmcfg_virt[i].virt = NULL;
+ pci_mmcfg_virt[i].cfg = NULL;
+ }
+ }
+
+ kfree(pci_mmcfg_virt);
+ pci_mmcfg_virt = NULL;
+}
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index 28b9b72ce7c7..c8b89a832c66 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -101,6 +101,7 @@ extern void pci_pcbios_init(void);
/* pci-mmconfig.c */
extern int __init pci_mmcfg_arch_init(void);
+extern void __init pci_mmcfg_arch_free(void);
/*
* AMD Fam10h CPUs are buggy, and cannot access MMIO config space