1 /* 2 * Low-Level PCI Support for PC 3 * 4 * (c) 1999--2000 Martin Mares <mj@ucw.cz> 5 */ 6 7 #include <linux/sched.h> 8 #include <linux/pci.h> 9 #include <linux/ioport.h> 10 #include <linux/init.h> 11 #include <linux/dmi.h> 12 #include <linux/slab.h> 13 14 #include <asm/acpi.h> 15 #include <asm/segment.h> 16 #include <asm/io.h> 17 #include <asm/smp.h> 18 #include <asm/pci_x86.h> 19 20 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | 21 PCI_PROBE_MMCONF; 22 23 unsigned int pci_early_dump_regs; 24 static int pci_bf_sort; 25 static int smbios_type_b1_flag; 26 int pci_routeirq; 27 int noioapicquirk; 28 #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS 29 int noioapicreroute = 0; 30 #else 31 int noioapicreroute = 1; 32 #endif 33 int pcibios_last_bus = -1; 34 unsigned long pirq_table_addr; 35 struct pci_bus *pci_root_bus; 36 const struct pci_raw_ops *__read_mostly raw_pci_ops; 37 const struct pci_raw_ops *__read_mostly raw_pci_ext_ops; 38 39 int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, 40 int reg, int len, u32 *val) 41 { 42 if (domain == 0 && reg < 256 && raw_pci_ops) 43 return raw_pci_ops->read(domain, bus, devfn, reg, len, val); 44 if (raw_pci_ext_ops) 45 return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val); 46 return -EINVAL; 47 } 48 49 int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, 50 int reg, int len, u32 val) 51 { 52 if (domain == 0 && reg < 256 && raw_pci_ops) 53 return raw_pci_ops->write(domain, bus, devfn, reg, len, val); 54 if (raw_pci_ext_ops) 55 return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val); 56 return -EINVAL; 57 } 58 59 static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 60 { 61 return raw_pci_read(pci_domain_nr(bus), bus->number, 62 devfn, where, size, value); 63 } 64 65 static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) 66 { 67 return raw_pci_write(pci_domain_nr(bus), bus->number, 68 devfn, where, size, value); 69 } 70 71 struct pci_ops pci_root_ops = { 72 .read = pci_read, 73 .write = pci_write, 74 }; 75 76 /* 77 * This interrupt-safe spinlock protects all accesses to PCI 78 * configuration space. 79 */ 80 DEFINE_RAW_SPINLOCK(pci_config_lock); 81 82 static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) 83 { 84 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 85 printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); 86 return 0; 87 } 88 89 static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitconst = { 90 /* 91 * Systems where PCI IO resource ISA alignment can be skipped 92 * when the ISA enable bit in the bridge control is not set 93 */ 94 { 95 .callback = can_skip_ioresource_align, 96 .ident = "IBM System x3800", 97 .matches = { 98 DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 99 DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), 100 }, 101 }, 102 { 103 .callback = can_skip_ioresource_align, 104 .ident = "IBM System x3850", 105 .matches = { 106 DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 107 DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), 108 }, 109 }, 110 { 111 .callback = can_skip_ioresource_align, 112 .ident = "IBM System x3950", 113 .matches = { 114 DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 115 DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), 116 }, 117 }, 118 {} 119 }; 120 121 void __init dmi_check_skip_isa_align(void) 122 { 123 dmi_check_system(can_skip_pciprobe_dmi_table); 124 } 125 126 static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) 127 { 128 struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; 129 struct resource *bar_r; 130 int bar; 131 132 if (pci_probe & PCI_NOASSIGN_BARS) { 133 /* 134 * If the BIOS did not assign the BAR, zero out the 135 * resource so the kernel doesn't attmept to assign 136 * it later on in pci_assign_unassigned_resources 137 */ 138 for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { 139 bar_r = &dev->resource[bar]; 140 if (bar_r->start == 0 && bar_r->end != 0) { 141 bar_r->flags = 0; 142 bar_r->end = 0; 143 } 144 } 145 } 146 147 if (pci_probe & PCI_NOASSIGN_ROMS) { 148 if (rom_r->parent) 149 return; 150 if (rom_r->start) { 151 /* we deal with BIOS assigned ROM later */ 152 return; 153 } 154 rom_r->start = rom_r->end = rom_r->flags = 0; 155 } 156 } 157 158 /* 159 * Called after each bus is probed, but before its children 160 * are examined. 161 */ 162 163 void __devinit pcibios_fixup_bus(struct pci_bus *b) 164 { 165 struct pci_dev *dev; 166 167 pci_read_bridge_bases(b); 168 list_for_each_entry(dev, &b->devices, bus_list) 169 pcibios_fixup_device_resources(dev); 170 } 171 172 /* 173 * Only use DMI information to set this if nothing was passed 174 * on the kernel command line (which was parsed earlier). 175 */ 176 177 static int __devinit set_bf_sort(const struct dmi_system_id *d) 178 { 179 if (pci_bf_sort == pci_bf_sort_default) { 180 pci_bf_sort = pci_dmi_bf; 181 printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); 182 } 183 return 0; 184 } 185 186 static void __devinit read_dmi_type_b1(const struct dmi_header *dm, 187 void *private_data) 188 { 189 u8 *d = (u8 *)dm + 4; 190 191 if (dm->type != 0xB1) 192 return; 193 switch (((*(u32 *)d) >> 9) & 0x03) { 194 case 0x00: 195 printk(KERN_INFO "dmi type 0xB1 record - unknown flag\n"); 196 break; 197 case 0x01: /* set pci=bfsort */ 198 smbios_type_b1_flag = 1; 199 break; 200 case 0x02: /* do not set pci=bfsort */ 201 smbios_type_b1_flag = 2; 202 break; 203 default: 204 break; 205 } 206 } 207 208 static int __devinit find_sort_method(const struct dmi_system_id *d) 209 { 210 dmi_walk(read_dmi_type_b1, NULL); 211 212 if (smbios_type_b1_flag == 1) { 213 set_bf_sort(d); 214 return 0; 215 } 216 return -1; 217 } 218 219 /* 220 * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) 221 */ 222 #ifdef __i386__ 223 static int __devinit assign_all_busses(const struct dmi_system_id *d) 224 { 225 pci_probe |= PCI_ASSIGN_ALL_BUSSES; 226 printk(KERN_INFO "%s detected: enabling PCI bus# renumbering" 227 " (pci=assign-busses)\n", d->ident); 228 return 0; 229 } 230 #endif 231 232 static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { 233 #ifdef __i386__ 234 /* 235 * Laptops which need pci=assign-busses to see Cardbus cards 236 */ 237 { 238 .callback = assign_all_busses, 239 .ident = "Samsung X20 Laptop", 240 .matches = { 241 DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), 242 DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"), 243 }, 244 }, 245 #endif /* __i386__ */ 246 { 247 .callback = set_bf_sort, 248 .ident = "Dell PowerEdge 1950", 249 .matches = { 250 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 251 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), 252 }, 253 }, 254 { 255 .callback = set_bf_sort, 256 .ident = "Dell PowerEdge 1955", 257 .matches = { 258 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 259 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), 260 }, 261 }, 262 { 263 .callback = set_bf_sort, 264 .ident = "Dell PowerEdge 2900", 265 .matches = { 266 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 267 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), 268 }, 269 }, 270 { 271 .callback = set_bf_sort, 272 .ident = "Dell PowerEdge 2950", 273 .matches = { 274 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 275 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), 276 }, 277 }, 278 { 279 .callback = set_bf_sort, 280 .ident = "Dell PowerEdge R900", 281 .matches = { 282 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 283 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"), 284 }, 285 }, 286 { 287 .callback = find_sort_method, 288 .ident = "Dell System", 289 .matches = { 290 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 291 }, 292 }, 293 { 294 .callback = set_bf_sort, 295 .ident = "HP ProLiant BL20p G3", 296 .matches = { 297 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 298 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"), 299 }, 300 }, 301 { 302 .callback = set_bf_sort, 303 .ident = "HP ProLiant BL20p G4", 304 .matches = { 305 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 306 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"), 307 }, 308 }, 309 { 310 .callback = set_bf_sort, 311 .ident = "HP ProLiant BL30p G1", 312 .matches = { 313 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 314 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"), 315 }, 316 }, 317 { 318 .callback = set_bf_sort, 319 .ident = "HP ProLiant BL25p G1", 320 .matches = { 321 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 322 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"), 323 }, 324 }, 325 { 326 .callback = set_bf_sort, 327 .ident = "HP ProLiant BL35p G1", 328 .matches = { 329 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 330 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"), 331 }, 332 }, 333 { 334 .callback = set_bf_sort, 335 .ident = "HP ProLiant BL45p G1", 336 .matches = { 337 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 338 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"), 339 }, 340 }, 341 { 342 .callback = set_bf_sort, 343 .ident = "HP ProLiant BL45p G2", 344 .matches = { 345 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 346 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"), 347 }, 348 }, 349 { 350 .callback = set_bf_sort, 351 .ident = "HP ProLiant BL460c G1", 352 .matches = { 353 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 354 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"), 355 }, 356 }, 357 { 358 .callback = set_bf_sort, 359 .ident = "HP ProLiant BL465c G1", 360 .matches = { 361 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 362 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"), 363 }, 364 }, 365 { 366 .callback = set_bf_sort, 367 .ident = "HP ProLiant BL480c G1", 368 .matches = { 369 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 370 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"), 371 }, 372 }, 373 { 374 .callback = set_bf_sort, 375 .ident = "HP ProLiant BL685c G1", 376 .matches = { 377 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 378 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), 379 }, 380 }, 381 { 382 .callback = set_bf_sort, 383 .ident = "HP ProLiant DL360", 384 .matches = { 385 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 386 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"), 387 }, 388 }, 389 { 390 .callback = set_bf_sort, 391 .ident = "HP ProLiant DL380", 392 .matches = { 393 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 394 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"), 395 }, 396 }, 397 #ifdef __i386__ 398 { 399 .callback = assign_all_busses, 400 .ident = "Compaq EVO N800c", 401 .matches = { 402 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), 403 DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"), 404 }, 405 }, 406 #endif 407 { 408 .callback = set_bf_sort, 409 .ident = "HP ProLiant DL385 G2", 410 .matches = { 411 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 412 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"), 413 }, 414 }, 415 { 416 .callback = set_bf_sort, 417 .ident = "HP ProLiant DL585 G2", 418 .matches = { 419 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 420 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), 421 }, 422 }, 423 {} 424 }; 425 426 void __init dmi_check_pciprobe(void) 427 { 428 dmi_check_system(pciprobe_dmi_table); 429 } 430 431 struct pci_bus * __devinit pcibios_scan_root(int busnum) 432 { 433 LIST_HEAD(resources); 434 struct pci_bus *bus = NULL; 435 struct pci_sysdata *sd; 436 437 while ((bus = pci_find_next_bus(bus)) != NULL) { 438 if (bus->number == busnum) { 439 /* Already scanned */ 440 return bus; 441 } 442 } 443 444 /* Allocate per-root-bus (not per bus) arch-specific data. 445 * TODO: leak; this memory is never freed. 446 * It's arguable whether it's worth the trouble to care. 447 */ 448 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 449 if (!sd) { 450 printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); 451 return NULL; 452 } 453 454 sd->node = get_mp_bus_to_node(busnum); 455 456 printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); 457 x86_pci_root_bus_resources(busnum, &resources); 458 bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); 459 if (!bus) { 460 pci_free_resource_list(&resources); 461 kfree(sd); 462 } 463 464 return bus; 465 } 466 void __init pcibios_set_cache_line_size(void) 467 { 468 struct cpuinfo_x86 *c = &boot_cpu_data; 469 470 /* 471 * Set PCI cacheline size to that of the CPU if the CPU has reported it. 472 * (For older CPUs that don't support cpuid, we se it to 32 bytes 473 * It's also good for 386/486s (which actually have 16) 474 * as quite a few PCI devices do not support smaller values. 475 */ 476 if (c->x86_clflush_size > 0) { 477 pci_dfl_cache_line_size = c->x86_clflush_size >> 2; 478 printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n", 479 pci_dfl_cache_line_size << 2); 480 } else { 481 pci_dfl_cache_line_size = 32 >> 2; 482 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); 483 } 484 } 485 486 int __init pcibios_init(void) 487 { 488 if (!raw_pci_ops) { 489 printk(KERN_WARNING "PCI: System does not support PCI\n"); 490 return 0; 491 } 492 493 pcibios_set_cache_line_size(); 494 pcibios_resource_survey(); 495 496 if (pci_bf_sort >= pci_force_bf) 497 pci_sort_breadthfirst(); 498 return 0; 499 } 500 501 char * __devinit pcibios_setup(char *str) 502 { 503 if (!strcmp(str, "off")) { 504 pci_probe = 0; 505 return NULL; 506 } else if (!strcmp(str, "bfsort")) { 507 pci_bf_sort = pci_force_bf; 508 return NULL; 509 } else if (!strcmp(str, "nobfsort")) { 510 pci_bf_sort = pci_force_nobf; 511 return NULL; 512 } 513 #ifdef CONFIG_PCI_BIOS 514 else if (!strcmp(str, "bios")) { 515 pci_probe = PCI_PROBE_BIOS; 516 return NULL; 517 } else if (!strcmp(str, "nobios")) { 518 pci_probe &= ~PCI_PROBE_BIOS; 519 return NULL; 520 } else if (!strcmp(str, "biosirq")) { 521 pci_probe |= PCI_BIOS_IRQ_SCAN; 522 return NULL; 523 } else if (!strncmp(str, "pirqaddr=", 9)) { 524 pirq_table_addr = simple_strtoul(str+9, NULL, 0); 525 return NULL; 526 } 527 #endif 528 #ifdef CONFIG_PCI_DIRECT 529 else if (!strcmp(str, "conf1")) { 530 pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS; 531 return NULL; 532 } 533 else if (!strcmp(str, "conf2")) { 534 pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; 535 return NULL; 536 } 537 #endif 538 #ifdef CONFIG_PCI_MMCONFIG 539 else if (!strcmp(str, "nommconf")) { 540 pci_probe &= ~PCI_PROBE_MMCONF; 541 return NULL; 542 } 543 else if (!strcmp(str, "check_enable_amd_mmconf")) { 544 pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; 545 return NULL; 546 } 547 #endif 548 else if (!strcmp(str, "noacpi")) { 549 acpi_noirq_set(); 550 return NULL; 551 } 552 else if (!strcmp(str, "noearly")) { 553 pci_probe |= PCI_PROBE_NOEARLY; 554 return NULL; 555 } 556 #ifndef CONFIG_X86_VISWS 557 else if (!strcmp(str, "usepirqmask")) { 558 pci_probe |= PCI_USE_PIRQ_MASK; 559 return NULL; 560 } else if (!strncmp(str, "irqmask=", 8)) { 561 pcibios_irq_mask = simple_strtol(str+8, NULL, 0); 562 return NULL; 563 } else if (!strncmp(str, "lastbus=", 8)) { 564 pcibios_last_bus = simple_strtol(str+8, NULL, 0); 565 return NULL; 566 } 567 #endif 568 else if (!strcmp(str, "rom")) { 569 pci_probe |= PCI_ASSIGN_ROMS; 570 return NULL; 571 } else if (!strcmp(str, "norom")) { 572 pci_probe |= PCI_NOASSIGN_ROMS; 573 return NULL; 574 } else if (!strcmp(str, "nobar")) { 575 pci_probe |= PCI_NOASSIGN_BARS; 576 return NULL; 577 } else if (!strcmp(str, "assign-busses")) { 578 pci_probe |= PCI_ASSIGN_ALL_BUSSES; 579 return NULL; 580 } else if (!strcmp(str, "use_crs")) { 581 pci_probe |= PCI_USE__CRS; 582 return NULL; 583 } else if (!strcmp(str, "nocrs")) { 584 pci_probe |= PCI_ROOT_NO_CRS; 585 return NULL; 586 } else if (!strcmp(str, "earlydump")) { 587 pci_early_dump_regs = 1; 588 return NULL; 589 } else if (!strcmp(str, "routeirq")) { 590 pci_routeirq = 1; 591 return NULL; 592 } else if (!strcmp(str, "skip_isa_align")) { 593 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 594 return NULL; 595 } else if (!strcmp(str, "noioapicquirk")) { 596 noioapicquirk = 1; 597 return NULL; 598 } else if (!strcmp(str, "ioapicreroute")) { 599 if (noioapicreroute != -1) 600 noioapicreroute = 0; 601 return NULL; 602 } else if (!strcmp(str, "noioapicreroute")) { 603 if (noioapicreroute != -1) 604 noioapicreroute = 1; 605 return NULL; 606 } 607 return str; 608 } 609 610 unsigned int pcibios_assign_all_busses(void) 611 { 612 return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; 613 } 614 615 int pcibios_enable_device(struct pci_dev *dev, int mask) 616 { 617 int err; 618 619 if ((err = pci_enable_resources(dev, mask)) < 0) 620 return err; 621 622 if (!pci_dev_msi_enabled(dev)) 623 return pcibios_enable_irq(dev); 624 return 0; 625 } 626 627 void pcibios_disable_device (struct pci_dev *dev) 628 { 629 if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) 630 pcibios_disable_irq(dev); 631 } 632 633 int pci_ext_cfg_avail(struct pci_dev *dev) 634 { 635 if (raw_pci_ext_ops) 636 return 1; 637 else 638 return 0; 639 } 640 641 struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) 642 { 643 LIST_HEAD(resources); 644 struct pci_bus *bus = NULL; 645 struct pci_sysdata *sd; 646 647 /* 648 * Allocate per-root-bus (not per bus) arch-specific data. 649 * TODO: leak; this memory is never freed. 650 * It's arguable whether it's worth the trouble to care. 651 */ 652 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 653 if (!sd) { 654 printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); 655 return NULL; 656 } 657 sd->node = node; 658 x86_pci_root_bus_resources(busno, &resources); 659 bus = pci_scan_root_bus(NULL, busno, ops, sd, &resources); 660 if (!bus) { 661 pci_free_resource_list(&resources); 662 kfree(sd); 663 } 664 665 return bus; 666 } 667 668 struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno) 669 { 670 return pci_scan_bus_on_node(busno, &pci_root_ops, -1); 671 } 672 673 /* 674 * NUMA info for PCI busses 675 * 676 * Early arch code is responsible for filling in reasonable values here. 677 * A node id of "-1" means "use current node". In other words, if a bus 678 * has a -1 node id, it's not tightly coupled to any particular chunk 679 * of memory (as is the case on some Nehalem systems). 680 */ 681 #ifdef CONFIG_NUMA 682 683 #define BUS_NR 256 684 685 #ifdef CONFIG_X86_64 686 687 static int mp_bus_to_node[BUS_NR] = { 688 [0 ... BUS_NR - 1] = -1 689 }; 690 691 void set_mp_bus_to_node(int busnum, int node) 692 { 693 if (busnum >= 0 && busnum < BUS_NR) 694 mp_bus_to_node[busnum] = node; 695 } 696 697 int get_mp_bus_to_node(int busnum) 698 { 699 int node = -1; 700 701 if (busnum < 0 || busnum > (BUS_NR - 1)) 702 return node; 703 704 node = mp_bus_to_node[busnum]; 705 706 /* 707 * let numa_node_id to decide it later in dma_alloc_pages 708 * if there is no ram on that node 709 */ 710 if (node != -1 && !node_online(node)) 711 node = -1; 712 713 return node; 714 } 715 716 #else /* CONFIG_X86_32 */ 717 718 static int mp_bus_to_node[BUS_NR] = { 719 [0 ... BUS_NR - 1] = -1 720 }; 721 722 void set_mp_bus_to_node(int busnum, int node) 723 { 724 if (busnum >= 0 && busnum < BUS_NR) 725 mp_bus_to_node[busnum] = (unsigned char) node; 726 } 727 728 int get_mp_bus_to_node(int busnum) 729 { 730 int node; 731 732 if (busnum < 0 || busnum > (BUS_NR - 1)) 733 return 0; 734 node = mp_bus_to_node[busnum]; 735 return node; 736 } 737 738 #endif /* CONFIG_X86_32 */ 739 740 #endif /* CONFIG_NUMA */ 741