root/arch/x86/pci/common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. raw_pci_read
  2. raw_pci_write
  3. pci_read
  4. pci_write
  5. can_skip_ioresource_align
  6. dmi_check_skip_isa_align
  7. pcibios_fixup_device_resources
  8. pcibios_fixup_bus
  9. pcibios_add_bus
  10. pcibios_remove_bus
  11. set_bf_sort
  12. read_dmi_type_b1
  13. find_sort_method
  14. assign_all_busses
  15. set_scan_all
  16. dmi_check_pciprobe
  17. pcibios_scan_root
  18. pcibios_set_cache_line_size
  19. pcibios_init
  20. pcibios_setup
  21. pcibios_assign_all_busses
  22. add_dma_domain
  23. del_dma_domain
  24. set_dma_domain_ops
  25. set_dma_domain_ops
  26. set_dev_domain_options
  27. pcibios_add_device
  28. pcibios_enable_device
  29. pcibios_disable_device
  30. pcibios_release_device
  31. pci_ext_cfg_avail

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *      Low-Level PCI Support for PC
   4  *
   5  *      (c) 1999--2000 Martin Mares <mj@ucw.cz>
   6  */
   7 
   8 #include <linux/sched.h>
   9 #include <linux/pci.h>
  10 #include <linux/pci-acpi.h>
  11 #include <linux/ioport.h>
  12 #include <linux/init.h>
  13 #include <linux/dmi.h>
  14 #include <linux/slab.h>
  15 
  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 static int pci_bf_sort;
  27 int pci_routeirq;
  28 int noioapicquirk;
  29 #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
  30 int noioapicreroute = 0;
  31 #else
  32 int noioapicreroute = 1;
  33 #endif
  34 int pcibios_last_bus = -1;
  35 unsigned long pirq_table_addr;
  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 configuration
  78  * space, except for the mmconfig (ECAM) based operations.
  79  */
  80 DEFINE_RAW_SPINLOCK(pci_config_lock);
  81 
  82 static int __init 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[] __initconst = {
  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 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 attempt 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 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 void pcibios_add_bus(struct pci_bus *bus)
 173 {
 174         acpi_pci_add_bus(bus);
 175 }
 176 
 177 void pcibios_remove_bus(struct pci_bus *bus)
 178 {
 179         acpi_pci_remove_bus(bus);
 180 }
 181 
 182 /*
 183  * Only use DMI information to set this if nothing was passed
 184  * on the kernel command line (which was parsed earlier).
 185  */
 186 
 187 static int __init set_bf_sort(const struct dmi_system_id *d)
 188 {
 189         if (pci_bf_sort == pci_bf_sort_default) {
 190                 pci_bf_sort = pci_dmi_bf;
 191                 printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident);
 192         }
 193         return 0;
 194 }
 195 
 196 static void __init read_dmi_type_b1(const struct dmi_header *dm,
 197                                     void *private_data)
 198 {
 199         u8 *data = (u8 *)dm + 4;
 200 
 201         if (dm->type != 0xB1)
 202                 return;
 203         if ((((*(u32 *)data) >> 9) & 0x03) == 0x01)
 204                 set_bf_sort((const struct dmi_system_id *)private_data);
 205 }
 206 
 207 static int __init find_sort_method(const struct dmi_system_id *d)
 208 {
 209         dmi_walk(read_dmi_type_b1, (void *)d);
 210         return 0;
 211 }
 212 
 213 /*
 214  * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
 215  */
 216 #ifdef __i386__
 217 static int __init assign_all_busses(const struct dmi_system_id *d)
 218 {
 219         pci_probe |= PCI_ASSIGN_ALL_BUSSES;
 220         printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
 221                         " (pci=assign-busses)\n", d->ident);
 222         return 0;
 223 }
 224 #endif
 225 
 226 static int __init set_scan_all(const struct dmi_system_id *d)
 227 {
 228         printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n",
 229                d->ident);
 230         pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
 231         return 0;
 232 }
 233 
 234 static const struct dmi_system_id pciprobe_dmi_table[] __initconst = {
 235 #ifdef __i386__
 236 /*
 237  * Laptops which need pci=assign-busses to see Cardbus cards
 238  */
 239         {
 240                 .callback = assign_all_busses,
 241                 .ident = "Samsung X20 Laptop",
 242                 .matches = {
 243                         DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
 244                         DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"),
 245                 },
 246         },
 247 #endif          /* __i386__ */
 248         {
 249                 .callback = set_bf_sort,
 250                 .ident = "Dell PowerEdge 1950",
 251                 .matches = {
 252                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 253                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
 254                 },
 255         },
 256         {
 257                 .callback = set_bf_sort,
 258                 .ident = "Dell PowerEdge 1955",
 259                 .matches = {
 260                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 261                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"),
 262                 },
 263         },
 264         {
 265                 .callback = set_bf_sort,
 266                 .ident = "Dell PowerEdge 2900",
 267                 .matches = {
 268                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 269                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"),
 270                 },
 271         },
 272         {
 273                 .callback = set_bf_sort,
 274                 .ident = "Dell PowerEdge 2950",
 275                 .matches = {
 276                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 277                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
 278                 },
 279         },
 280         {
 281                 .callback = set_bf_sort,
 282                 .ident = "Dell PowerEdge R900",
 283                 .matches = {
 284                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 285                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"),
 286                 },
 287         },
 288         {
 289                 .callback = find_sort_method,
 290                 .ident = "Dell System",
 291                 .matches = {
 292                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
 293                 },
 294         },
 295         {
 296                 .callback = set_bf_sort,
 297                 .ident = "HP ProLiant BL20p G3",
 298                 .matches = {
 299                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 300                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"),
 301                 },
 302         },
 303         {
 304                 .callback = set_bf_sort,
 305                 .ident = "HP ProLiant BL20p G4",
 306                 .matches = {
 307                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 308                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"),
 309                 },
 310         },
 311         {
 312                 .callback = set_bf_sort,
 313                 .ident = "HP ProLiant BL30p G1",
 314                 .matches = {
 315                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 316                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"),
 317                 },
 318         },
 319         {
 320                 .callback = set_bf_sort,
 321                 .ident = "HP ProLiant BL25p G1",
 322                 .matches = {
 323                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 324                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"),
 325                 },
 326         },
 327         {
 328                 .callback = set_bf_sort,
 329                 .ident = "HP ProLiant BL35p G1",
 330                 .matches = {
 331                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 332                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"),
 333                 },
 334         },
 335         {
 336                 .callback = set_bf_sort,
 337                 .ident = "HP ProLiant BL45p G1",
 338                 .matches = {
 339                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 340                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"),
 341                 },
 342         },
 343         {
 344                 .callback = set_bf_sort,
 345                 .ident = "HP ProLiant BL45p G2",
 346                 .matches = {
 347                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 348                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"),
 349                 },
 350         },
 351         {
 352                 .callback = set_bf_sort,
 353                 .ident = "HP ProLiant BL460c G1",
 354                 .matches = {
 355                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 356                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"),
 357                 },
 358         },
 359         {
 360                 .callback = set_bf_sort,
 361                 .ident = "HP ProLiant BL465c G1",
 362                 .matches = {
 363                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 364                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"),
 365                 },
 366         },
 367         {
 368                 .callback = set_bf_sort,
 369                 .ident = "HP ProLiant BL480c G1",
 370                 .matches = {
 371                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 372                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"),
 373                 },
 374         },
 375         {
 376                 .callback = set_bf_sort,
 377                 .ident = "HP ProLiant BL685c G1",
 378                 .matches = {
 379                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 380                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
 381                 },
 382         },
 383         {
 384                 .callback = set_bf_sort,
 385                 .ident = "HP ProLiant DL360",
 386                 .matches = {
 387                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 388                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"),
 389                 },
 390         },
 391         {
 392                 .callback = set_bf_sort,
 393                 .ident = "HP ProLiant DL380",
 394                 .matches = {
 395                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 396                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"),
 397                 },
 398         },
 399 #ifdef __i386__
 400         {
 401                 .callback = assign_all_busses,
 402                 .ident = "Compaq EVO N800c",
 403                 .matches = {
 404                         DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
 405                         DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"),
 406                 },
 407         },
 408 #endif
 409         {
 410                 .callback = set_bf_sort,
 411                 .ident = "HP ProLiant DL385 G2",
 412                 .matches = {
 413                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 414                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"),
 415                 },
 416         },
 417         {
 418                 .callback = set_bf_sort,
 419                 .ident = "HP ProLiant DL585 G2",
 420                 .matches = {
 421                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 422                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
 423                 },
 424         },
 425         {
 426                 .callback = set_scan_all,
 427                 .ident = "Stratus/NEC ftServer",
 428                 .matches = {
 429                         DMI_MATCH(DMI_SYS_VENDOR, "Stratus"),
 430                         DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"),
 431                 },
 432         },
 433         {
 434                 .callback = set_scan_all,
 435                 .ident = "Stratus/NEC ftServer",
 436                 .matches = {
 437                         DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
 438                         DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R32"),
 439                 },
 440         },
 441         {
 442                 .callback = set_scan_all,
 443                 .ident = "Stratus/NEC ftServer",
 444                 .matches = {
 445                         DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
 446                         DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R31"),
 447                 },
 448         },
 449         {}
 450 };
 451 
 452 void __init dmi_check_pciprobe(void)
 453 {
 454         dmi_check_system(pciprobe_dmi_table);
 455 }
 456 
 457 void pcibios_scan_root(int busnum)
 458 {
 459         struct pci_bus *bus;
 460         struct pci_sysdata *sd;
 461         LIST_HEAD(resources);
 462 
 463         sd = kzalloc(sizeof(*sd), GFP_KERNEL);
 464         if (!sd) {
 465                 printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
 466                 return;
 467         }
 468         sd->node = x86_pci_root_bus_node(busnum);
 469         x86_pci_root_bus_resources(busnum, &resources);
 470         printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
 471         bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
 472         if (!bus) {
 473                 pci_free_resource_list(&resources);
 474                 kfree(sd);
 475                 return;
 476         }
 477         pci_bus_add_devices(bus);
 478 }
 479 
 480 void __init pcibios_set_cache_line_size(void)
 481 {
 482         struct cpuinfo_x86 *c = &boot_cpu_data;
 483 
 484         /*
 485          * Set PCI cacheline size to that of the CPU if the CPU has reported it.
 486          * (For older CPUs that don't support cpuid, we se it to 32 bytes
 487          * It's also good for 386/486s (which actually have 16)
 488          * as quite a few PCI devices do not support smaller values.
 489          */
 490         if (c->x86_clflush_size > 0) {
 491                 pci_dfl_cache_line_size = c->x86_clflush_size >> 2;
 492                 printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
 493                         pci_dfl_cache_line_size << 2);
 494         } else {
 495                 pci_dfl_cache_line_size = 32 >> 2;
 496                 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
 497         }
 498 }
 499 
 500 int __init pcibios_init(void)
 501 {
 502         if (!raw_pci_ops && !raw_pci_ext_ops) {
 503                 printk(KERN_WARNING "PCI: System does not support PCI\n");
 504                 return 0;
 505         }
 506 
 507         pcibios_set_cache_line_size();
 508         pcibios_resource_survey();
 509 
 510         if (pci_bf_sort >= pci_force_bf)
 511                 pci_sort_breadthfirst();
 512         return 0;
 513 }
 514 
 515 char *__init pcibios_setup(char *str)
 516 {
 517         if (!strcmp(str, "off")) {
 518                 pci_probe = 0;
 519                 return NULL;
 520         } else if (!strcmp(str, "bfsort")) {
 521                 pci_bf_sort = pci_force_bf;
 522                 return NULL;
 523         } else if (!strcmp(str, "nobfsort")) {
 524                 pci_bf_sort = pci_force_nobf;
 525                 return NULL;
 526         }
 527 #ifdef CONFIG_PCI_BIOS
 528         else if (!strcmp(str, "bios")) {
 529                 pci_probe = PCI_PROBE_BIOS;
 530                 return NULL;
 531         } else if (!strcmp(str, "nobios")) {
 532                 pci_probe &= ~PCI_PROBE_BIOS;
 533                 return NULL;
 534         } else if (!strcmp(str, "biosirq")) {
 535                 pci_probe |= PCI_BIOS_IRQ_SCAN;
 536                 return NULL;
 537         } else if (!strncmp(str, "pirqaddr=", 9)) {
 538                 pirq_table_addr = simple_strtoul(str+9, NULL, 0);
 539                 return NULL;
 540         }
 541 #endif
 542 #ifdef CONFIG_PCI_DIRECT
 543         else if (!strcmp(str, "conf1")) {
 544                 pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
 545                 return NULL;
 546         }
 547         else if (!strcmp(str, "conf2")) {
 548                 pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
 549                 return NULL;
 550         }
 551 #endif
 552 #ifdef CONFIG_PCI_MMCONFIG
 553         else if (!strcmp(str, "nommconf")) {
 554                 pci_probe &= ~PCI_PROBE_MMCONF;
 555                 return NULL;
 556         }
 557         else if (!strcmp(str, "check_enable_amd_mmconf")) {
 558                 pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
 559                 return NULL;
 560         }
 561 #endif
 562         else if (!strcmp(str, "noacpi")) {
 563                 acpi_noirq_set();
 564                 return NULL;
 565         }
 566         else if (!strcmp(str, "noearly")) {
 567                 pci_probe |= PCI_PROBE_NOEARLY;
 568                 return NULL;
 569         }
 570         else if (!strcmp(str, "usepirqmask")) {
 571                 pci_probe |= PCI_USE_PIRQ_MASK;
 572                 return NULL;
 573         } else if (!strncmp(str, "irqmask=", 8)) {
 574                 pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
 575                 return NULL;
 576         } else if (!strncmp(str, "lastbus=", 8)) {
 577                 pcibios_last_bus = simple_strtol(str+8, NULL, 0);
 578                 return NULL;
 579         } else if (!strcmp(str, "rom")) {
 580                 pci_probe |= PCI_ASSIGN_ROMS;
 581                 return NULL;
 582         } else if (!strcmp(str, "norom")) {
 583                 pci_probe |= PCI_NOASSIGN_ROMS;
 584                 return NULL;
 585         } else if (!strcmp(str, "nobar")) {
 586                 pci_probe |= PCI_NOASSIGN_BARS;
 587                 return NULL;
 588         } else if (!strcmp(str, "assign-busses")) {
 589                 pci_probe |= PCI_ASSIGN_ALL_BUSSES;
 590                 return NULL;
 591         } else if (!strcmp(str, "use_crs")) {
 592                 pci_probe |= PCI_USE__CRS;
 593                 return NULL;
 594         } else if (!strcmp(str, "nocrs")) {
 595                 pci_probe |= PCI_ROOT_NO_CRS;
 596                 return NULL;
 597 #ifdef CONFIG_PHYS_ADDR_T_64BIT
 598         } else if (!strcmp(str, "big_root_window")) {
 599                 pci_probe |= PCI_BIG_ROOT_WINDOW;
 600                 return NULL;
 601 #endif
 602         } else if (!strcmp(str, "routeirq")) {
 603                 pci_routeirq = 1;
 604                 return NULL;
 605         } else if (!strcmp(str, "skip_isa_align")) {
 606                 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
 607                 return NULL;
 608         } else if (!strcmp(str, "noioapicquirk")) {
 609                 noioapicquirk = 1;
 610                 return NULL;
 611         } else if (!strcmp(str, "ioapicreroute")) {
 612                 if (noioapicreroute != -1)
 613                         noioapicreroute = 0;
 614                 return NULL;
 615         } else if (!strcmp(str, "noioapicreroute")) {
 616                 if (noioapicreroute != -1)
 617                         noioapicreroute = 1;
 618                 return NULL;
 619         }
 620         return str;
 621 }
 622 
 623 unsigned int pcibios_assign_all_busses(void)
 624 {
 625         return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 626 }
 627 
 628 #if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
 629 static LIST_HEAD(dma_domain_list);
 630 static DEFINE_SPINLOCK(dma_domain_list_lock);
 631 
 632 void add_dma_domain(struct dma_domain *domain)
 633 {
 634         spin_lock(&dma_domain_list_lock);
 635         list_add(&domain->node, &dma_domain_list);
 636         spin_unlock(&dma_domain_list_lock);
 637 }
 638 EXPORT_SYMBOL_GPL(add_dma_domain);
 639 
 640 void del_dma_domain(struct dma_domain *domain)
 641 {
 642         spin_lock(&dma_domain_list_lock);
 643         list_del(&domain->node);
 644         spin_unlock(&dma_domain_list_lock);
 645 }
 646 EXPORT_SYMBOL_GPL(del_dma_domain);
 647 
 648 static void set_dma_domain_ops(struct pci_dev *pdev)
 649 {
 650         struct dma_domain *domain;
 651 
 652         spin_lock(&dma_domain_list_lock);
 653         list_for_each_entry(domain, &dma_domain_list, node) {
 654                 if (pci_domain_nr(pdev->bus) == domain->domain_nr) {
 655                         pdev->dev.dma_ops = domain->dma_ops;
 656                         break;
 657                 }
 658         }
 659         spin_unlock(&dma_domain_list_lock);
 660 }
 661 #else
 662 static void set_dma_domain_ops(struct pci_dev *pdev) {}
 663 #endif
 664 
 665 static void set_dev_domain_options(struct pci_dev *pdev)
 666 {
 667         if (is_vmd(pdev->bus))
 668                 pdev->hotplug_user_indicators = 1;
 669 }
 670 
 671 int pcibios_add_device(struct pci_dev *dev)
 672 {
 673         struct setup_data *data;
 674         struct pci_setup_rom *rom;
 675         u64 pa_data;
 676 
 677         pa_data = boot_params.hdr.setup_data;
 678         while (pa_data) {
 679                 data = memremap(pa_data, sizeof(*rom), MEMREMAP_WB);
 680                 if (!data)
 681                         return -ENOMEM;
 682 
 683                 if (data->type == SETUP_PCI) {
 684                         rom = (struct pci_setup_rom *)data;
 685 
 686                         if ((pci_domain_nr(dev->bus) == rom->segment) &&
 687                             (dev->bus->number == rom->bus) &&
 688                             (PCI_SLOT(dev->devfn) == rom->device) &&
 689                             (PCI_FUNC(dev->devfn) == rom->function) &&
 690                             (dev->vendor == rom->vendor) &&
 691                             (dev->device == rom->devid)) {
 692                                 dev->rom = pa_data +
 693                                       offsetof(struct pci_setup_rom, romdata);
 694                                 dev->romlen = rom->pcilen;
 695                         }
 696                 }
 697                 pa_data = data->next;
 698                 memunmap(data);
 699         }
 700         set_dma_domain_ops(dev);
 701         set_dev_domain_options(dev);
 702         return 0;
 703 }
 704 
 705 int pcibios_enable_device(struct pci_dev *dev, int mask)
 706 {
 707         int err;
 708 
 709         if ((err = pci_enable_resources(dev, mask)) < 0)
 710                 return err;
 711 
 712         if (!pci_dev_msi_enabled(dev))
 713                 return pcibios_enable_irq(dev);
 714         return 0;
 715 }
 716 
 717 void pcibios_disable_device (struct pci_dev *dev)
 718 {
 719         if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
 720                 pcibios_disable_irq(dev);
 721 }
 722 
 723 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
 724 void pcibios_release_device(struct pci_dev *dev)
 725 {
 726         if (atomic_dec_return(&dev->enable_cnt) >= 0)
 727                 pcibios_disable_device(dev);
 728 
 729 }
 730 #endif
 731 
 732 int pci_ext_cfg_avail(void)
 733 {
 734         if (raw_pci_ext_ops)
 735                 return 1;
 736         else
 737                 return 0;
 738 }

/* [<][>][^][v][top][bottom][index][help] */