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 struct pci_raw_ops *raw_pci_ops; 37 struct pci_raw_ops *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 /* root bus? */ 168 if (!b->parent) 169 x86_pci_root_bus_res_quirks(b); 170 pci_read_bridge_bases(b); 171 list_for_each_entry(dev, &b->devices, bus_list) 172 pcibios_fixup_device_resources(dev); 173 } 174 175 /* 176 * Only use DMI information to set this if nothing was passed 177 * on the kernel command line (which was parsed earlier). 178 */ 179 180 static int __devinit set_bf_sort(const struct dmi_system_id *d) 181 { 182 if (pci_bf_sort == pci_bf_sort_default) { 183 pci_bf_sort = pci_dmi_bf; 184 printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); 185 } 186 return 0; 187 } 188 189 static void __devinit read_dmi_type_b1(const struct dmi_header *dm, 190 void *private_data) 191 { 192 u8 *d = (u8 *)dm + 4; 193 194 if (dm->type != 0xB1) 195 return; 196 switch (((*(u32 *)d) >> 9) & 0x03) { 197 case 0x00: 198 printk(KERN_INFO "dmi type 0xB1 record - unknown flag\n"); 199 break; 200 case 0x01: /* set pci=bfsort */ 201 smbios_type_b1_flag = 1; 202 break; 203 case 0x02: /* do not set pci=bfsort */ 204 smbios_type_b1_flag = 2; 205 break; 206 default: 207 break; 208 } 209 } 210 211 static int __devinit find_sort_method(const struct dmi_system_id *d) 212 { 213 dmi_walk(read_dmi_type_b1, NULL); 214 215 if (smbios_type_b1_flag == 1) { 216 set_bf_sort(d); 217 return 0; 218 } 219 return -1; 220 } 221 222 /* 223 * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) 224 */ 225 #ifdef __i386__ 226 static int __devinit assign_all_busses(const struct dmi_system_id *d) 227 { 228 pci_probe |= PCI_ASSIGN_ALL_BUSSES; 229 printk(KERN_INFO "%s detected: enabling PCI bus# renumbering" 230 " (pci=assign-busses)\n", d->ident); 231 return 0; 232 } 233 #endif 234 235 static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { 236 #ifdef __i386__ 237 /* 238 * Laptops which need pci=assign-busses to see Cardbus cards 239 */ 240 { 241 .callback = assign_all_busses, 242 .ident = "Samsung X20 Laptop", 243 .matches = { 244 DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), 245 DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"), 246 }, 247 }, 248 #endif /* __i386__ */ 249 { 250 .callback = find_sort_method, 251 .ident = "Dell System", 252 .matches = { 253 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 254 }, 255 }, 256 { 257 .callback = set_bf_sort, 258 .ident = "Dell PowerEdge 1950", 259 .matches = { 260 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 261 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), 262 }, 263 }, 264 { 265 .callback = set_bf_sort, 266 .ident = "Dell PowerEdge 1955", 267 .matches = { 268 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 269 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), 270 }, 271 }, 272 { 273 .callback = set_bf_sort, 274 .ident = "Dell PowerEdge 2900", 275 .matches = { 276 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 277 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), 278 }, 279 }, 280 { 281 .callback = set_bf_sort, 282 .ident = "Dell PowerEdge 2950", 283 .matches = { 284 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 285 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), 286 }, 287 }, 288 { 289 .callback = set_bf_sort, 290 .ident = "Dell PowerEdge R900", 291 .matches = { 292 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 293 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"), 294 }, 295 }, 296 { 297 .callback = set_bf_sort, 298 .ident = "HP ProLiant BL20p G3", 299 .matches = { 300 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 301 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"), 302 }, 303 }, 304 { 305 .callback = set_bf_sort, 306 .ident = "HP ProLiant BL20p G4", 307 .matches = { 308 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 309 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"), 310 }, 311 }, 312 { 313 .callback = set_bf_sort, 314 .ident = "HP ProLiant BL30p G1", 315 .matches = { 316 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 317 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"), 318 }, 319 }, 320 { 321 .callback = set_bf_sort, 322 .ident = "HP ProLiant BL25p G1", 323 .matches = { 324 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 325 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"), 326 }, 327 }, 328 { 329 .callback = set_bf_sort, 330 .ident = "HP ProLiant BL35p G1", 331 .matches = { 332 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 333 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"), 334 }, 335 }, 336 { 337 .callback = set_bf_sort, 338 .ident = "HP ProLiant BL45p G1", 339 .matches = { 340 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 341 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"), 342 }, 343 }, 344 { 345 .callback = set_bf_sort, 346 .ident = "HP ProLiant BL45p G2", 347 .matches = { 348 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 349 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"), 350 }, 351 }, 352 { 353 .callback = set_bf_sort, 354 .ident = "HP ProLiant BL460c G1", 355 .matches = { 356 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 357 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"), 358 }, 359 }, 360 { 361 .callback = set_bf_sort, 362 .ident = "HP ProLiant BL465c G1", 363 .matches = { 364 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 365 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"), 366 }, 367 }, 368 { 369 .callback = set_bf_sort, 370 .ident = "HP ProLiant BL480c G1", 371 .matches = { 372 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 373 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"), 374 }, 375 }, 376 { 377 .callback = set_bf_sort, 378 .ident = "HP ProLiant BL685c G1", 379 .matches = { 380 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 381 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), 382 }, 383 }, 384 { 385 .callback = set_bf_sort, 386 .ident = "HP ProLiant DL360", 387 .matches = { 388 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 389 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"), 390 }, 391 }, 392 { 393 .callback = set_bf_sort, 394 .ident = "HP ProLiant DL380", 395 .matches = { 396 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 397 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"), 398 }, 399 }, 400 #ifdef __i386__ 401 { 402 .callback = assign_all_busses, 403 .ident = "Compaq EVO N800c", 404 .matches = { 405 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), 406 DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"), 407 }, 408 }, 409 #endif 410 { 411 .callback = set_bf_sort, 412 .ident = "HP ProLiant DL385 G2", 413 .matches = { 414 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 415 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"), 416 }, 417 }, 418 { 419 .callback = set_bf_sort, 420 .ident = "HP ProLiant DL585 G2", 421 .matches = { 422 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 423 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), 424 }, 425 }, 426 {} 427 }; 428 429 void __init dmi_check_pciprobe(void) 430 { 431 dmi_check_system(pciprobe_dmi_table); 432 } 433 434 struct pci_bus * __devinit pcibios_scan_root(int busnum) 435 { 436 struct pci_bus *bus = NULL; 437 struct pci_sysdata *sd; 438 439 while ((bus = pci_find_next_bus(bus)) != NULL) { 440 if (bus->number == busnum) { 441 /* Already scanned */ 442 return bus; 443 } 444 } 445 446 /* Allocate per-root-bus (not per bus) arch-specific data. 447 * TODO: leak; this memory is never freed. 448 * It's arguable whether it's worth the trouble to care. 449 */ 450 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 451 if (!sd) { 452 printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); 453 return NULL; 454 } 455 456 sd->node = get_mp_bus_to_node(busnum); 457 458 printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); 459 bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); 460 if (!bus) 461 kfree(sd); 462 463 return bus; 464 } 465 void __init pcibios_set_cache_line_size(void) 466 { 467 struct cpuinfo_x86 *c = &boot_cpu_data; 468 469 /* 470 * Set PCI cacheline size to that of the CPU if the CPU has reported it. 471 * (For older CPUs that don't support cpuid, we se it to 32 bytes 472 * It's also good for 386/486s (which actually have 16) 473 * as quite a few PCI devices do not support smaller values. 474 */ 475 if (c->x86_clflush_size > 0) { 476 pci_dfl_cache_line_size = c->x86_clflush_size >> 2; 477 printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n", 478 pci_dfl_cache_line_size << 2); 479 } else { 480 pci_dfl_cache_line_size = 32 >> 2; 481 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); 482 } 483 } 484 485 int __init pcibios_init(void) 486 { 487 if (!raw_pci_ops) { 488 printk(KERN_WARNING "PCI: System does not support PCI\n"); 489 return 0; 490 } 491 492 pcibios_set_cache_line_size(); 493 pcibios_resource_survey(); 494 495 if (pci_bf_sort >= pci_force_bf) 496 pci_sort_breadthfirst(); 497 return 0; 498 } 499 500 char * __devinit pcibios_setup(char *str) 501 { 502 if (!strcmp(str, "off")) { 503 pci_probe = 0; 504 return NULL; 505 } else if (!strcmp(str, "bfsort")) { 506 pci_bf_sort = pci_force_bf; 507 return NULL; 508 } else if (!strcmp(str, "nobfsort")) { 509 pci_bf_sort = pci_force_nobf; 510 return NULL; 511 } 512 #ifdef CONFIG_PCI_BIOS 513 else if (!strcmp(str, "bios")) { 514 pci_probe = PCI_PROBE_BIOS; 515 return NULL; 516 } else if (!strcmp(str, "nobios")) { 517 pci_probe &= ~PCI_PROBE_BIOS; 518 return NULL; 519 } else if (!strcmp(str, "biosirq")) { 520 pci_probe |= PCI_BIOS_IRQ_SCAN; 521 return NULL; 522 } else if (!strncmp(str, "pirqaddr=", 9)) { 523 pirq_table_addr = simple_strtoul(str+9, NULL, 0); 524 return NULL; 525 } 526 #endif 527 #ifdef CONFIG_PCI_DIRECT 528 else if (!strcmp(str, "conf1")) { 529 pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS; 530 return NULL; 531 } 532 else if (!strcmp(str, "conf2")) { 533 pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; 534 return NULL; 535 } 536 #endif 537 #ifdef CONFIG_PCI_MMCONFIG 538 else if (!strcmp(str, "nommconf")) { 539 pci_probe &= ~PCI_PROBE_MMCONF; 540 return NULL; 541 } 542 else if (!strcmp(str, "check_enable_amd_mmconf")) { 543 pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; 544 return NULL; 545 } 546 #endif 547 else if (!strcmp(str, "noacpi")) { 548 acpi_noirq_set(); 549 return NULL; 550 } 551 else if (!strcmp(str, "noearly")) { 552 pci_probe |= PCI_PROBE_NOEARLY; 553 return NULL; 554 } 555 #ifndef CONFIG_X86_VISWS 556 else if (!strcmp(str, "usepirqmask")) { 557 pci_probe |= PCI_USE_PIRQ_MASK; 558 return NULL; 559 } else if (!strncmp(str, "irqmask=", 8)) { 560 pcibios_irq_mask = simple_strtol(str+8, NULL, 0); 561 return NULL; 562 } else if (!strncmp(str, "lastbus=", 8)) { 563 pcibios_last_bus = simple_strtol(str+8, NULL, 0); 564 return NULL; 565 } 566 #endif 567 else if (!strcmp(str, "rom")) { 568 pci_probe |= PCI_ASSIGN_ROMS; 569 return NULL; 570 } else if (!strcmp(str, "norom")) { 571 pci_probe |= PCI_NOASSIGN_ROMS; 572 return NULL; 573 } else if (!strcmp(str, "nobar")) { 574 pci_probe |= PCI_NOASSIGN_BARS; 575 return NULL; 576 } else if (!strcmp(str, "assign-busses")) { 577 pci_probe |= PCI_ASSIGN_ALL_BUSSES; 578 return NULL; 579 } else if (!strcmp(str, "use_crs")) { 580 pci_probe |= PCI_USE__CRS; 581 return NULL; 582 } else if (!strcmp(str, "nocrs")) { 583 pci_probe |= PCI_ROOT_NO_CRS; 584 return NULL; 585 } else if (!strcmp(str, "earlydump")) { 586 pci_early_dump_regs = 1; 587 return NULL; 588 } else if (!strcmp(str, "routeirq")) { 589 pci_routeirq = 1; 590 return NULL; 591 } else if (!strcmp(str, "skip_isa_align")) { 592 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 593 return NULL; 594 } else if (!strcmp(str, "noioapicquirk")) { 595 noioapicquirk = 1; 596 return NULL; 597 } else if (!strcmp(str, "ioapicreroute")) { 598 if (noioapicreroute != -1) 599 noioapicreroute = 0; 600 return NULL; 601 } else if (!strcmp(str, "noioapicreroute")) { 602 if (noioapicreroute != -1) 603 noioapicreroute = 1; 604 return NULL; 605 } 606 return str; 607 } 608 609 unsigned int pcibios_assign_all_busses(void) 610 { 611 return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; 612 } 613 614 int pcibios_enable_device(struct pci_dev *dev, int mask) 615 { 616 int err; 617 618 if ((err = pci_enable_resources(dev, mask)) < 0) 619 return err; 620 621 if (!pci_dev_msi_enabled(dev)) 622 return pcibios_enable_irq(dev); 623 return 0; 624 } 625 626 void pcibios_disable_device (struct pci_dev *dev) 627 { 628 if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) 629 pcibios_disable_irq(dev); 630 } 631 632 int pci_ext_cfg_avail(struct pci_dev *dev) 633 { 634 if (raw_pci_ext_ops) 635 return 1; 636 else 637 return 0; 638 } 639 640 struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) 641 { 642 struct pci_bus *bus = NULL; 643 struct pci_sysdata *sd; 644 645 /* 646 * Allocate per-root-bus (not per bus) arch-specific data. 647 * TODO: leak; this memory is never freed. 648 * It's arguable whether it's worth the trouble to care. 649 */ 650 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 651 if (!sd) { 652 printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); 653 return NULL; 654 } 655 sd->node = node; 656 bus = pci_scan_bus(busno, ops, sd); 657 if (!bus) 658 kfree(sd); 659 660 return bus; 661 } 662 663 struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno) 664 { 665 return pci_scan_bus_on_node(busno, &pci_root_ops, -1); 666 } 667 668 /* 669 * NUMA info for PCI busses 670 * 671 * Early arch code is responsible for filling in reasonable values here. 672 * A node id of "-1" means "use current node". In other words, if a bus 673 * has a -1 node id, it's not tightly coupled to any particular chunk 674 * of memory (as is the case on some Nehalem systems). 675 */ 676 #ifdef CONFIG_NUMA 677 678 #define BUS_NR 256 679 680 #ifdef CONFIG_X86_64 681 682 static int mp_bus_to_node[BUS_NR] = { 683 [0 ... BUS_NR - 1] = -1 684 }; 685 686 void set_mp_bus_to_node(int busnum, int node) 687 { 688 if (busnum >= 0 && busnum < BUS_NR) 689 mp_bus_to_node[busnum] = node; 690 } 691 692 int get_mp_bus_to_node(int busnum) 693 { 694 int node = -1; 695 696 if (busnum < 0 || busnum > (BUS_NR - 1)) 697 return node; 698 699 node = mp_bus_to_node[busnum]; 700 701 /* 702 * let numa_node_id to decide it later in dma_alloc_pages 703 * if there is no ram on that node 704 */ 705 if (node != -1 && !node_online(node)) 706 node = -1; 707 708 return node; 709 } 710 711 #else /* CONFIG_X86_32 */ 712 713 static int mp_bus_to_node[BUS_NR] = { 714 [0 ... BUS_NR - 1] = -1 715 }; 716 717 void set_mp_bus_to_node(int busnum, int node) 718 { 719 if (busnum >= 0 && busnum < BUS_NR) 720 mp_bus_to_node[busnum] = (unsigned char) node; 721 } 722 723 int get_mp_bus_to_node(int busnum) 724 { 725 int node; 726 727 if (busnum < 0 || busnum > (BUS_NR - 1)) 728 return 0; 729 node = mp_bus_to_node[busnum]; 730 return node; 731 } 732 733 #endif /* CONFIG_X86_32 */ 734 735 #endif /* CONFIG_NUMA */ 736