mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 09:14:19 +08:00
[PATCH] mmconfig: Reject a broken MCFG tables on Asus etc
This rejects broken MCFG tables on Asus. When the table looks bogus just disable mmconfig Arjan and Andi suggested this. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andi Kleen <ak@suse.de>
This commit is contained in:
parent
faed197b7b
commit
44de0203fa
@ -197,6 +197,26 @@ static __init void pci_mmcfg_insert_resources(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void __init pci_mmcfg_reject_broken(void)
|
||||
{
|
||||
typeof(pci_mmcfg_config[0]) *cfg = &pci_mmcfg_config[0];
|
||||
|
||||
/*
|
||||
* Handle more broken MCFG tables on Asus etc.
|
||||
* They only contain a single entry for bus 0-0.
|
||||
*/
|
||||
if (pci_mmcfg_config_num == 1 &&
|
||||
cfg->pci_segment == 0 &&
|
||||
(cfg->start_bus_number | cfg->end_bus_number) == 0) {
|
||||
kfree(pci_mmcfg_config);
|
||||
pci_mmcfg_config = NULL;
|
||||
pci_mmcfg_config_num = 0;
|
||||
|
||||
printk(KERN_ERR "PCI: start and end of bus number is 0. "
|
||||
"Rejected as broken MCFG.");
|
||||
}
|
||||
}
|
||||
|
||||
void __init pci_mmcfg_init(int type)
|
||||
{
|
||||
int known_bridge = 0;
|
||||
@ -207,8 +227,10 @@ void __init pci_mmcfg_init(int type)
|
||||
if (type == 1 && pci_mmcfg_check_hostbridge())
|
||||
known_bridge = 1;
|
||||
|
||||
if (!known_bridge)
|
||||
if (!known_bridge) {
|
||||
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
|
||||
pci_mmcfg_reject_broken();
|
||||
}
|
||||
|
||||
if ((pci_mmcfg_config_num == 0) ||
|
||||
(pci_mmcfg_config == NULL) ||
|
||||
|
@ -47,15 +47,6 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
|
||||
return cfg->address;
|
||||
}
|
||||
|
||||
/* Handle more broken MCFG tables on Asus etc.
|
||||
They only contain a single entry for bus 0-0. Assume
|
||||
this applies to all busses. */
|
||||
cfg = &pci_mmcfg_config[0];
|
||||
if (pci_mmcfg_config_num == 1 &&
|
||||
cfg->pci_segment == 0 &&
|
||||
(cfg->start_bus_number | cfg->end_bus_number) == 0)
|
||||
return cfg->address;
|
||||
|
||||
/* Fall back to type 0 */
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,39 +28,6 @@ struct mmcfg_virt {
|
||||
};
|
||||
static struct mmcfg_virt *pci_mmcfg_virt;
|
||||
|
||||
static inline int mcfg_broken(void)
|
||||
{
|
||||
struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[0];
|
||||
|
||||
/* Handle more broken MCFG tables on Asus etc.
|
||||
They only contain a single entry for bus 0-0. Assume
|
||||
this applies to all busses. */
|
||||
if (pci_mmcfg_config_num == 1 &&
|
||||
cfg->pci_segment_group_number == 0 &&
|
||||
(cfg->start_bus_number | cfg->end_bus_number) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __iomem *mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
|
||||
{
|
||||
void __iomem *addr;
|
||||
u32 size;
|
||||
|
||||
if (mcfg_broken())
|
||||
size = 256 << 20;
|
||||
else
|
||||
size = (cfg->end_bus_number + 1) << 20;
|
||||
|
||||
addr = ioremap_nocache(cfg->base_address, size);
|
||||
if (addr) {
|
||||
printk(KERN_INFO "PCI: Using MMCONFIG at %x - %x\n",
|
||||
cfg->base_address,
|
||||
cfg->base_address + size - 1);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
static char __iomem *get_virt(unsigned int seg, unsigned bus)
|
||||
{
|
||||
int cfg_num = -1;
|
||||
@ -78,9 +45,6 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus)
|
||||
return pci_mmcfg_virt[cfg_num].virt;
|
||||
}
|
||||
|
||||
if (mcfg_broken())
|
||||
return pci_mmcfg_virt[0].virt;
|
||||
|
||||
/* Fall back to type 0 */
|
||||
return NULL;
|
||||
}
|
||||
@ -160,6 +124,20 @@ static struct pci_raw_ops pci_mmcfg = {
|
||||
.write = pci_mmcfg_write,
|
||||
};
|
||||
|
||||
static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
|
||||
{
|
||||
void __iomem *addr;
|
||||
u32 size;
|
||||
|
||||
size = (cfg->end_bus_number + 1) << 20;
|
||||
addr = ioremap_nocache(cfg->address, size);
|
||||
if (addr) {
|
||||
printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
|
||||
cfg->address, cfg->address + size - 1);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
int __init pci_mmcfg_arch_init(void)
|
||||
{
|
||||
int i;
|
||||
|
Loading…
Reference in New Issue
Block a user