|
@@ -24,6 +24,9 @@
|
|
|
|
|
|
DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
|
|
DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
|
|
|
|
|
|
|
|
+/* Indicate if the mmcfg resources have been placed into the resource table. */
|
|
|
|
+static int __initdata pci_mmcfg_resources_inserted;
|
|
|
|
+
|
|
/* K8 systems have some devices (typically in the builtin northbridge)
|
|
/* K8 systems have some devices (typically in the builtin northbridge)
|
|
that are only accessible using type1
|
|
that are only accessible using type1
|
|
Normally this can be expressed in the MCFG by not listing them
|
|
Normally this can be expressed in the MCFG by not listing them
|
|
@@ -170,7 +173,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
|
|
return name != NULL;
|
|
return name != NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-static void __init pci_mmcfg_insert_resources(void)
|
|
|
|
|
|
+static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
|
|
{
|
|
{
|
|
#define PCI_MMCFG_RESOURCE_NAME_LEN 19
|
|
#define PCI_MMCFG_RESOURCE_NAME_LEN 19
|
|
int i;
|
|
int i;
|
|
@@ -194,10 +197,13 @@ static void __init pci_mmcfg_insert_resources(void)
|
|
cfg->pci_segment);
|
|
cfg->pci_segment);
|
|
res->start = cfg->address;
|
|
res->start = cfg->address;
|
|
res->end = res->start + (num_buses << 20) - 1;
|
|
res->end = res->start + (num_buses << 20) - 1;
|
|
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
|
|
|
|
|
+ res->flags = IORESOURCE_MEM | resource_flags;
|
|
insert_resource(&iomem_resource, res);
|
|
insert_resource(&iomem_resource, res);
|
|
names += PCI_MMCFG_RESOURCE_NAME_LEN;
|
|
names += PCI_MMCFG_RESOURCE_NAME_LEN;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /* Mark that the resources have been inserted. */
|
|
|
|
+ pci_mmcfg_resources_inserted = 1;
|
|
}
|
|
}
|
|
|
|
|
|
static void __init pci_mmcfg_reject_broken(int type)
|
|
static void __init pci_mmcfg_reject_broken(int type)
|
|
@@ -267,7 +273,43 @@ void __init pci_mmcfg_init(int type)
|
|
if (type == 1)
|
|
if (type == 1)
|
|
unreachable_devices();
|
|
unreachable_devices();
|
|
if (known_bridge)
|
|
if (known_bridge)
|
|
- pci_mmcfg_insert_resources();
|
|
|
|
|
|
+ pci_mmcfg_insert_resources(IORESOURCE_BUSY);
|
|
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
|
|
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
|
|
|
|
+ } else {
|
|
|
|
+ /*
|
|
|
|
+ * Signal not to attempt to insert mmcfg resources because
|
|
|
|
+ * the architecture mmcfg setup could not initialize.
|
|
|
|
+ */
|
|
|
|
+ pci_mmcfg_resources_inserted = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+static int __init pci_mmcfg_late_insert_resources(void)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * If resources are already inserted or we are not using MMCONFIG,
|
|
|
|
+ * don't insert the resources.
|
|
|
|
+ */
|
|
|
|
+ if ((pci_mmcfg_resources_inserted == 1) ||
|
|
|
|
+ (pci_probe & PCI_PROBE_MMCONF) == 0 ||
|
|
|
|
+ (pci_mmcfg_config_num == 0) ||
|
|
|
|
+ (pci_mmcfg_config == NULL) ||
|
|
|
|
+ (pci_mmcfg_config[0].address == 0))
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Attempt to insert the mmcfg resources but not with the busy flag
|
|
|
|
+ * marked so it won't cause request errors when __request_region is
|
|
|
|
+ * called.
|
|
|
|
+ */
|
|
|
|
+ pci_mmcfg_insert_resources(0);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Perform MMCONFIG resource insertion after PCI initialization to allow for
|
|
|
|
+ * misprogrammed MCFG tables that state larger sizes but actually conflict
|
|
|
|
+ * with other system resources.
|
|
|
|
+ */
|
|
|
|
+late_initcall(pci_mmcfg_late_insert_resources);
|