0001
0002 #include <linux/pci.h>
0003 #include <linux/acpi.h>
0004 #include <linux/init.h>
0005 #include <linux/irq.h>
0006 #include <linux/dmi.h>
0007 #include <linux/slab.h>
0008 #include <linux/pci-acpi.h>
0009 #include <asm/numa.h>
0010 #include <asm/pci_x86.h>
0011
0012 struct pci_root_info {
0013 struct acpi_pci_root_info common;
0014 struct pci_sysdata sd;
0015 #ifdef CONFIG_PCI_MMCONFIG
0016 bool mcfg_added;
0017 u8 start_bus;
0018 u8 end_bus;
0019 #endif
0020 };
0021
0022 bool pci_use_e820 = true;
0023 static bool pci_use_crs = true;
0024 static bool pci_ignore_seg;
0025
0026 static int __init set_use_crs(const struct dmi_system_id *id)
0027 {
0028 pci_use_crs = true;
0029 return 0;
0030 }
0031
0032 static int __init set_nouse_crs(const struct dmi_system_id *id)
0033 {
0034 pci_use_crs = false;
0035 return 0;
0036 }
0037
0038 static int __init set_ignore_seg(const struct dmi_system_id *id)
0039 {
0040 printk(KERN_INFO "PCI: %s detected: ignoring ACPI _SEG\n", id->ident);
0041 pci_ignore_seg = true;
0042 return 0;
0043 }
0044
0045 static int __init set_no_e820(const struct dmi_system_id *id)
0046 {
0047 printk(KERN_INFO "PCI: %s detected: not clipping E820 regions from _CRS\n",
0048 id->ident);
0049 pci_use_e820 = false;
0050 return 0;
0051 }
0052
0053 static const struct dmi_system_id pci_crs_quirks[] __initconst = {
0054
0055 {
0056 .callback = set_use_crs,
0057 .ident = "IBM System x3800",
0058 .matches = {
0059 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
0060 DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
0061 },
0062 },
0063
0064
0065 {
0066 .callback = set_use_crs,
0067 .ident = "ASRock ALiveSATA2-GLAN",
0068 .matches = {
0069 DMI_MATCH(DMI_PRODUCT_NAME, "ALiveSATA2-GLAN"),
0070 },
0071 },
0072
0073
0074 {
0075 .callback = set_use_crs,
0076 .ident = "ASUS M2V-MX SE",
0077 .matches = {
0078 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
0079 DMI_MATCH(DMI_BOARD_NAME, "M2V-MX SE"),
0080 DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
0081 },
0082 },
0083
0084 {
0085 .callback = set_use_crs,
0086 .ident = "MSI MS-7253",
0087 .matches = {
0088 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
0089 DMI_MATCH(DMI_BOARD_NAME, "MS-7253"),
0090 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
0091 },
0092 },
0093
0094
0095 {
0096 .callback = set_use_crs,
0097 .ident = "Foxconn K8M890-8237A",
0098 .matches = {
0099 DMI_MATCH(DMI_BOARD_VENDOR, "Foxconn"),
0100 DMI_MATCH(DMI_BOARD_NAME, "K8M890-8237A"),
0101 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
0102 },
0103 },
0104
0105
0106
0107
0108 {
0109 .callback = set_nouse_crs,
0110 .ident = "Dell Studio 1557",
0111 .matches = {
0112 DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
0113 DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
0114 DMI_MATCH(DMI_BIOS_VERSION, "A09"),
0115 },
0116 },
0117
0118 {
0119 .callback = set_nouse_crs,
0120 .ident = "Thinkpad SL510",
0121 .matches = {
0122 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
0123 DMI_MATCH(DMI_BOARD_NAME, "2847DFG"),
0124 DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"),
0125 },
0126 },
0127
0128 {
0129 .callback = set_nouse_crs,
0130 .ident = "Supermicro X8DTH",
0131 .matches = {
0132 DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
0133 DMI_MATCH(DMI_PRODUCT_NAME, "X8DTH-i/6/iF/6F"),
0134 DMI_MATCH(DMI_BIOS_VERSION, "2.0a"),
0135 },
0136 },
0137
0138
0139 {
0140 .callback = set_ignore_seg,
0141 .ident = "HP xw9300",
0142 .matches = {
0143 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
0144 DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"),
0145 },
0146 },
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 {
0158 .callback = set_no_e820,
0159 .ident = "Lenovo *IIL* product version",
0160 .matches = {
0161 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0162 DMI_MATCH(DMI_PRODUCT_VERSION, "IIL"),
0163 },
0164 },
0165
0166
0167
0168
0169
0170
0171 {
0172 .callback = set_no_e820,
0173 .ident = "Acer Spin 5 (SP513-54N)",
0174 .matches = {
0175 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0176 DMI_MATCH(DMI_PRODUCT_NAME, "Spin SP513-54N"),
0177 },
0178 },
0179
0180
0181
0182
0183
0184
0185 {
0186 .callback = set_no_e820,
0187 .ident = "Clevo X170KM-G Barebone",
0188 .matches = {
0189 DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"),
0190 },
0191 },
0192 {}
0193 };
0194
0195 void __init pci_acpi_crs_quirks(void)
0196 {
0197 int year = dmi_get_bios_year();
0198
0199 if (year >= 0 && year < 2008 && iomem_resource.end <= 0xffffffff)
0200 pci_use_crs = false;
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 if (year >= 2023)
0221 pci_use_e820 = false;
0222
0223 dmi_check_system(pci_crs_quirks);
0224
0225
0226
0227
0228
0229 if (pci_probe & PCI_ROOT_NO_CRS)
0230 pci_use_crs = false;
0231 else if (pci_probe & PCI_USE__CRS)
0232 pci_use_crs = true;
0233
0234 printk(KERN_INFO "PCI: %s host bridge windows from ACPI; "
0235 "if necessary, use \"pci=%s\" and report a bug\n",
0236 pci_use_crs ? "Using" : "Ignoring",
0237 pci_use_crs ? "nocrs" : "use_crs");
0238
0239
0240 if (pci_probe & PCI_NO_E820)
0241 pci_use_e820 = false;
0242 else if (pci_probe & PCI_USE_E820)
0243 pci_use_e820 = true;
0244
0245 printk(KERN_INFO "PCI: %s E820 reservations for host bridge windows\n",
0246 pci_use_e820 ? "Using" : "Ignoring");
0247 if (pci_probe & (PCI_NO_E820 | PCI_USE_E820))
0248 printk(KERN_INFO "PCI: Please notify linux-pci@vger.kernel.org so future kernels can this automatically\n");
0249 }
0250
0251 #ifdef CONFIG_PCI_MMCONFIG
0252 static int check_segment(u16 seg, struct device *dev, char *estr)
0253 {
0254 if (seg) {
0255 dev_err(dev,
0256 "%s can't access PCI configuration "
0257 "space under this host bridge.\n",
0258 estr);
0259 return -EIO;
0260 }
0261
0262
0263
0264
0265
0266
0267 dev_warn(dev,
0268 "%s can't access extended PCI configuration "
0269 "space under this bridge.\n",
0270 estr);
0271
0272 return 0;
0273 }
0274
0275 static int setup_mcfg_map(struct acpi_pci_root_info *ci)
0276 {
0277 int result, seg;
0278 struct pci_root_info *info;
0279 struct acpi_pci_root *root = ci->root;
0280 struct device *dev = &ci->bridge->dev;
0281
0282 info = container_of(ci, struct pci_root_info, common);
0283 info->start_bus = (u8)root->secondary.start;
0284 info->end_bus = (u8)root->secondary.end;
0285 info->mcfg_added = false;
0286 seg = info->sd.domain;
0287
0288
0289 if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
0290 return 0;
0291
0292 if (!(pci_probe & PCI_PROBE_MMCONF))
0293 return check_segment(seg, dev, "MMCONFIG is disabled,");
0294
0295 result = pci_mmconfig_insert(dev, seg, info->start_bus, info->end_bus,
0296 root->mcfg_addr);
0297 if (result == 0) {
0298
0299 if (raw_pci_ext_ops == NULL)
0300 raw_pci_ext_ops = &pci_mmcfg;
0301 info->mcfg_added = true;
0302 } else if (result != -EEXIST)
0303 return check_segment(seg, dev,
0304 "fail to add MMCONFIG information,");
0305
0306 return 0;
0307 }
0308
0309 static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
0310 {
0311 struct pci_root_info *info;
0312
0313 info = container_of(ci, struct pci_root_info, common);
0314 if (info->mcfg_added) {
0315 pci_mmconfig_delete(info->sd.domain,
0316 info->start_bus, info->end_bus);
0317 info->mcfg_added = false;
0318 }
0319 }
0320 #else
0321 static int setup_mcfg_map(struct acpi_pci_root_info *ci)
0322 {
0323 return 0;
0324 }
0325
0326 static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
0327 {
0328 }
0329 #endif
0330
0331 static int pci_acpi_root_get_node(struct acpi_pci_root *root)
0332 {
0333 int busnum = root->secondary.start;
0334 struct acpi_device *device = root->device;
0335 int node = acpi_get_node(device->handle);
0336
0337 if (node == NUMA_NO_NODE) {
0338 node = x86_pci_root_bus_node(busnum);
0339 if (node != 0 && node != NUMA_NO_NODE)
0340 dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
0341 node);
0342 }
0343 if (node != NUMA_NO_NODE && !node_online(node))
0344 node = NUMA_NO_NODE;
0345
0346 return node;
0347 }
0348
0349 static int pci_acpi_root_init_info(struct acpi_pci_root_info *ci)
0350 {
0351 return setup_mcfg_map(ci);
0352 }
0353
0354 static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
0355 {
0356 teardown_mcfg_map(ci);
0357 kfree(container_of(ci, struct pci_root_info, common));
0358 }
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 static bool resource_is_pcicfg_ioport(struct resource *res)
0375 {
0376 return (res->flags & IORESOURCE_IO) &&
0377 res->start == 0xCF8 && res->end == 0xCFF;
0378 }
0379
0380 static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
0381 {
0382 struct acpi_device *device = ci->bridge;
0383 int busnum = ci->root->secondary.start;
0384 struct resource_entry *entry, *tmp;
0385 int status;
0386
0387 status = acpi_pci_probe_root_resources(ci);
0388
0389 if (pci_use_crs) {
0390 resource_list_for_each_entry_safe(entry, tmp, &ci->resources)
0391 if (resource_is_pcicfg_ioport(entry->res))
0392 resource_list_destroy_entry(entry);
0393 return status;
0394 }
0395
0396 resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
0397 dev_printk(KERN_DEBUG, &device->dev,
0398 "host bridge window %pR (ignored)\n", entry->res);
0399 resource_list_destroy_entry(entry);
0400 }
0401 x86_pci_root_bus_resources(busnum, &ci->resources);
0402
0403 return 0;
0404 }
0405
0406 static struct acpi_pci_root_ops acpi_pci_root_ops = {
0407 .pci_ops = &pci_root_ops,
0408 .init_info = pci_acpi_root_init_info,
0409 .release_info = pci_acpi_root_release_info,
0410 .prepare_resources = pci_acpi_root_prepare_resources,
0411 };
0412
0413 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
0414 {
0415 int domain = root->segment;
0416 int busnum = root->secondary.start;
0417 int node = pci_acpi_root_get_node(root);
0418 struct pci_bus *bus;
0419
0420 if (pci_ignore_seg)
0421 root->segment = domain = 0;
0422
0423 if (domain && !pci_domains_supported) {
0424 printk(KERN_WARNING "pci_bus %04x:%02x: "
0425 "ignored (multiple domains not supported)\n",
0426 domain, busnum);
0427 return NULL;
0428 }
0429
0430 bus = pci_find_bus(domain, busnum);
0431 if (bus) {
0432
0433
0434
0435
0436 struct pci_sysdata sd = {
0437 .domain = domain,
0438 .node = node,
0439 .companion = root->device
0440 };
0441
0442 memcpy(bus->sysdata, &sd, sizeof(sd));
0443 } else {
0444 struct pci_root_info *info;
0445
0446 info = kzalloc(sizeof(*info), GFP_KERNEL);
0447 if (!info)
0448 dev_err(&root->device->dev,
0449 "pci_bus %04x:%02x: ignored (out of memory)\n",
0450 domain, busnum);
0451 else {
0452 info->sd.domain = domain;
0453 info->sd.node = node;
0454 info->sd.companion = root->device;
0455 bus = acpi_pci_root_create(root, &acpi_pci_root_ops,
0456 &info->common, &info->sd);
0457 }
0458 }
0459
0460
0461
0462
0463 if (bus) {
0464 struct pci_bus *child;
0465 list_for_each_entry(child, &bus->children, node)
0466 pcie_bus_configure_settings(child);
0467 }
0468
0469 return bus;
0470 }
0471
0472 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
0473 {
0474
0475
0476
0477
0478
0479
0480 if (!bridge->dev.parent) {
0481 struct pci_sysdata *sd = bridge->bus->sysdata;
0482 ACPI_COMPANION_SET(&bridge->dev, sd->companion);
0483 }
0484 return 0;
0485 }
0486
0487 int __init pci_acpi_init(void)
0488 {
0489 struct pci_dev *dev = NULL;
0490
0491 if (acpi_noirq)
0492 return -ENODEV;
0493
0494 printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
0495 acpi_irq_penalty_init();
0496 pcibios_enable_irq = acpi_pci_irq_enable;
0497 pcibios_disable_irq = acpi_pci_irq_disable;
0498 x86_init.pci.init_irq = x86_init_noop;
0499
0500 if (pci_routeirq) {
0501
0502
0503
0504
0505
0506 printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
0507 for_each_pci_dev(dev)
0508 acpi_pci_irq_enable(dev);
0509 }
0510
0511 return 0;
0512 }