int __init acpi_parse_mcfg(struct acpi_table_header *header) { struct acpi_table_mcfg *mcfg; struct acpi_mcfg_allocation *cfg_table, *cfg; unsigned long i; int entries; if (!header) return -EINVAL; mcfg = (struct acpi_table_mcfg *)header; /* how many config structures do we have */ free_all_mmcfg(); entries = 0; i = header->length - sizeof(struct acpi_table_mcfg); while (i >= sizeof(struct acpi_mcfg_allocation)) { entries++; i -= sizeof(struct acpi_mcfg_allocation); } if (entries == 0) { pr_err(PREFIX "MCFG table has no entries\n"); return -ENODEV; } cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1]; for (i = 0; i < entries; i++) { cfg = &cfg_table[i]; if (acpi_mcfg_check_entry(mcfg, cfg)) { free_all_mmcfg(); return -ENODEV; } if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number, cfg->address) == NULL) { pr_warn(PREFIX "no memory for MCFG entries\n"); free_all_mmcfg(); return -ENOMEM; } } return 0; }
static int __init jailhouse_pci_arch_init(void) { pci_direct_init(1); /* * There are no bridges on the virtual PCI root bus under Jailhouse, * thus no other way to discover all devices than a full scan. * Respect any overrides via the command line, though. */ if (pcibios_last_bus < 0) pcibios_last_bus = 0xff; #ifdef CONFIG_PCI_MMCONFIG if (setup_data.pci_mmconfig_base) { pci_mmconfig_add(0, 0, pcibios_last_bus, setup_data.pci_mmconfig_base); pci_mmcfg_arch_init(); } #endif return 0; }