int __init acpi_parse_mcfg(struct acpi_table_header *header) { struct acpi_table_mcfg *mcfg; unsigned long i; if (!header) return -EINVAL; mcfg = (struct acpi_table_mcfg *)header; /* how many config structures do we have */ pci_mmcfg_config_num = 0; i = header->length - sizeof(struct acpi_table_mcfg); while (i >= sizeof(struct acpi_mcfg_allocation)) { ++pci_mmcfg_config_num; i -= sizeof(struct acpi_mcfg_allocation); }; if (pci_mmcfg_config_num == 0) { printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } pci_mmcfg_config = xmalloc_array(struct acpi_mcfg_allocation, pci_mmcfg_config_num); if (!pci_mmcfg_config) { printk(KERN_WARNING PREFIX "No memory for MCFG config tables\n"); return -ENOMEM; } memcpy(pci_mmcfg_config, &mcfg[1], pci_mmcfg_config_num * sizeof(*pci_mmcfg_config)); for (i = 0; i < pci_mmcfg_config_num; ++i) { if (acpi_mcfg_check_entry(mcfg, &pci_mmcfg_config[i])) { xfree(pci_mmcfg_config); pci_mmcfg_config_num = 0; return -ENODEV; } pci_add_segment(pci_mmcfg_config[i].pci_segment); } return 0; }
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; }