mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-08 07:38:10 +00:00
x86/PCI: prepare pci_mmcfg_check_reserved() to be called at runtime
Prepare function pci_mmcfg_check_reserved() to be called at runtime for PCI host bridge hot-plugging Reviewed-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jiang Liu <liuj97@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
9cf0105da5
commit
95c5e92f4f
1 changed files with 67 additions and 35 deletions
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
/* Indicate if the mmcfg resources have been placed into the resource table. */
|
/* Indicate if the mmcfg resources have been placed into the resource table. */
|
||||||
static int __initdata pci_mmcfg_resources_inserted;
|
static int __initdata pci_mmcfg_resources_inserted;
|
||||||
|
static bool pci_mmcfg_running_state;
|
||||||
static DEFINE_MUTEX(pci_mmcfg_lock);
|
static DEFINE_MUTEX(pci_mmcfg_lock);
|
||||||
|
|
||||||
LIST_HEAD(pci_mmcfg_list);
|
LIST_HEAD(pci_mmcfg_list);
|
||||||
|
@ -375,13 +376,14 @@ static void __init pci_mmcfg_insert_resources(void)
|
||||||
struct pci_mmcfg_region *cfg;
|
struct pci_mmcfg_region *cfg;
|
||||||
|
|
||||||
list_for_each_entry(cfg, &pci_mmcfg_list, list)
|
list_for_each_entry(cfg, &pci_mmcfg_list, list)
|
||||||
|
if (!cfg->res.parent)
|
||||||
insert_resource(&iomem_resource, &cfg->res);
|
insert_resource(&iomem_resource, &cfg->res);
|
||||||
|
|
||||||
/* Mark that the resources have been inserted. */
|
/* Mark that the resources have been inserted. */
|
||||||
pci_mmcfg_resources_inserted = 1;
|
pci_mmcfg_resources_inserted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
|
static acpi_status __devinit check_mcfg_resource(struct acpi_resource *res,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct resource *mcfg_res = data;
|
struct resource *mcfg_res = data;
|
||||||
|
@ -418,7 +420,7 @@ static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
|
static acpi_status __devinit find_mboard_resource(acpi_handle handle, u32 lvl,
|
||||||
void *context, void **rv)
|
void *context, void **rv)
|
||||||
{
|
{
|
||||||
struct resource *mcfg_res = context;
|
struct resource *mcfg_res = context;
|
||||||
|
@ -432,7 +434,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
|
static int __devinit is_acpi_reserved(u64 start, u64 end, unsigned not_used)
|
||||||
{
|
{
|
||||||
struct resource mcfg_res;
|
struct resource mcfg_res;
|
||||||
|
|
||||||
|
@ -451,13 +453,15 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
|
||||||
|
|
||||||
typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
|
typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
|
||||||
|
|
||||||
static int __init is_mmconf_reserved(check_reserved_t is_reserved,
|
static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
|
||||||
struct pci_mmcfg_region *cfg, int with_e820)
|
struct pci_mmcfg_region *cfg,
|
||||||
|
struct device *dev, int with_e820)
|
||||||
{
|
{
|
||||||
u64 addr = cfg->res.start;
|
u64 addr = cfg->res.start;
|
||||||
u64 size = resource_size(&cfg->res);
|
u64 size = resource_size(&cfg->res);
|
||||||
u64 old_size = size;
|
u64 old_size = size;
|
||||||
int valid = 0, num_buses;
|
int num_buses;
|
||||||
|
char *method = with_e820 ? "E820" : "ACPI motherboard resources";
|
||||||
|
|
||||||
while (!is_reserved(addr, addr + size, E820_RESERVED)) {
|
while (!is_reserved(addr, addr + size, E820_RESERVED)) {
|
||||||
size >>= 1;
|
size >>= 1;
|
||||||
|
@ -465,11 +469,16 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size >= (16UL<<20) || size == old_size) {
|
if (size < (16UL<<20) && size != old_size)
|
||||||
printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n",
|
return 0;
|
||||||
&cfg->res,
|
|
||||||
with_e820 ? "E820" : "ACPI motherboard resources");
|
if (dev)
|
||||||
valid = 1;
|
dev_info(dev, "MMCONFIG at %pR reserved in %s\n",
|
||||||
|
&cfg->res, method);
|
||||||
|
else
|
||||||
|
printk(KERN_INFO PREFIX
|
||||||
|
"MMCONFIG at %pR reserved in %s\n",
|
||||||
|
&cfg->res, method);
|
||||||
|
|
||||||
if (old_size != size) {
|
if (old_size != size) {
|
||||||
/* update end_bus */
|
/* update end_bus */
|
||||||
|
@ -480,34 +489,55 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
|
||||||
snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
|
snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
|
||||||
"PCI MMCONFIG %04x [bus %02x-%02x]",
|
"PCI MMCONFIG %04x [bus %02x-%02x]",
|
||||||
cfg->segment, cfg->start_bus, cfg->end_bus);
|
cfg->segment, cfg->start_bus, cfg->end_bus);
|
||||||
|
|
||||||
|
if (dev)
|
||||||
|
dev_info(dev,
|
||||||
|
"MMCONFIG "
|
||||||
|
"at %pR (base %#lx) (size reduced!)\n",
|
||||||
|
&cfg->res, (unsigned long) cfg->address);
|
||||||
|
else
|
||||||
printk(KERN_INFO PREFIX
|
printk(KERN_INFO PREFIX
|
||||||
"MMCONFIG for %04x [bus%02x-%02x] "
|
"MMCONFIG for %04x [bus%02x-%02x] "
|
||||||
"at %pR (base %#lx) (size reduced!)\n",
|
"at %pR (base %#lx) (size reduced!)\n",
|
||||||
cfg->segment, cfg->start_bus, cfg->end_bus,
|
cfg->segment, cfg->start_bus, cfg->end_bus,
|
||||||
&cfg->res, (unsigned long) cfg->address);
|
&cfg->res, (unsigned long) cfg->address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
static int __ref pci_mmcfg_check_reserved(struct device *dev,
|
||||||
}
|
struct pci_mmcfg_region *cfg, int early)
|
||||||
|
|
||||||
static int __devinit pci_mmcfg_check_reserved(struct pci_mmcfg_region *cfg,
|
|
||||||
int early)
|
|
||||||
{
|
{
|
||||||
if (!early && !acpi_disabled) {
|
if (!early && !acpi_disabled) {
|
||||||
if (is_mmconf_reserved(is_acpi_reserved, cfg, 0))
|
if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (dev)
|
||||||
|
dev_info(dev, FW_INFO
|
||||||
|
"MMCONFIG at %pR not reserved in "
|
||||||
|
"ACPI motherboard resources\n",
|
||||||
|
&cfg->res);
|
||||||
else
|
else
|
||||||
printk(KERN_ERR FW_BUG PREFIX
|
printk(KERN_INFO FW_INFO PREFIX
|
||||||
"MMCONFIG at %pR not reserved in "
|
"MMCONFIG at %pR not reserved in "
|
||||||
"ACPI motherboard resources\n",
|
"ACPI motherboard resources\n",
|
||||||
&cfg->res);
|
&cfg->res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e820_all_mapped() is marked as __init.
|
||||||
|
* All entries from ACPI MCFG table have been checked at boot time.
|
||||||
|
* For MCFG information constructed from hotpluggable host bridge's
|
||||||
|
* _CBA method, just assume it's reserved.
|
||||||
|
*/
|
||||||
|
if (pci_mmcfg_running_state)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* Don't try to do this check unless configuration
|
/* Don't try to do this check unless configuration
|
||||||
type 1 is available. how about type 2 ?*/
|
type 1 is available. how about type 2 ?*/
|
||||||
if (raw_pci_ops)
|
if (raw_pci_ops)
|
||||||
return is_mmconf_reserved(e820_all_mapped, cfg, 1);
|
return is_mmconf_reserved(e820_all_mapped, cfg, dev, 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -517,7 +547,7 @@ static void __init pci_mmcfg_reject_broken(int early)
|
||||||
struct pci_mmcfg_region *cfg;
|
struct pci_mmcfg_region *cfg;
|
||||||
|
|
||||||
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
|
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
|
||||||
if (pci_mmcfg_check_reserved(cfg, early) == 0) {
|
if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) {
|
||||||
printk(KERN_INFO PREFIX "not using MMCONFIG\n");
|
printk(KERN_INFO PREFIX "not using MMCONFIG\n");
|
||||||
free_all_mmcfg();
|
free_all_mmcfg();
|
||||||
return;
|
return;
|
||||||
|
@ -656,6 +686,8 @@ void __init pci_mmcfg_late_init(void)
|
||||||
|
|
||||||
static int __init pci_mmcfg_late_insert_resources(void)
|
static int __init pci_mmcfg_late_insert_resources(void)
|
||||||
{
|
{
|
||||||
|
pci_mmcfg_running_state = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If resources are already inserted or we are not using MMCONFIG,
|
* If resources are already inserted or we are not using MMCONFIG,
|
||||||
* don't insert the resources.
|
* don't insert the resources.
|
||||||
|
|
Loading…
Add table
Reference in a new issue