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