linux/arch/x86/pci/common.c
<<
>>
Prefs
   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
  23unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
  24                                PCI_PROBE_MMCONF;
  25
  26static int pci_bf_sort;
  27int pci_routeirq;
  28int noioapicquirk;
  29#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
  30int noioapicreroute = 0;
  31#else
  32int noioapicreroute = 1;
  33#endif
  34int pcibios_last_bus = -1;
  35unsigned long pirq_table_addr;
  36const struct pci_raw_ops *__read_mostly raw_pci_ops;
  37const struct pci_raw_ops *__read_mostly raw_pci_ext_ops;
  38
  39int 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
  49int 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
  59static 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
  65static 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
  71struct 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 */
  80DEFINE_RAW_SPINLOCK(pci_config_lock);
  81
  82static 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
  89static 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
 121void __init dmi_check_skip_isa_align(void)
 122{
 123        dmi_check_system(can_skip_pciprobe_dmi_table);
 124}
 125
 126static 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
 163void 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
 172void pcibios_add_bus(struct pci_bus *bus)
 173{
 174        acpi_pci_add_bus(bus);
 175}
 176
 177void 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
 187static 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
 196static 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
 207static 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__
 217static 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
 226static 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
 234static 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
 452void __init dmi_check_pciprobe(void)
 453{
 454        dmi_check_system(pciprobe_dmi_table);
 455}
 456
 457void 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
 480void __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
 500int __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
 515char *__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
 623unsigned 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)
 629static LIST_HEAD(dma_domain_list);
 630static DEFINE_SPINLOCK(dma_domain_list_lock);
 631
 632void 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}
 638EXPORT_SYMBOL_GPL(add_dma_domain);
 639
 640void 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}
 646EXPORT_SYMBOL_GPL(del_dma_domain);
 647
 648static 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
 662static void set_dma_domain_ops(struct pci_dev *pdev) {}
 663#endif
 664
 665static void set_dev_domain_options(struct pci_dev *pdev)
 666{
 667        if (is_vmd(pdev->bus))
 668                pdev->hotplug_user_indicators = 1;
 669}
 670
 671int 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
 705int 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
 717void 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
 724void 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
 732int pci_ext_cfg_avail(void)
 733{
 734        if (raw_pci_ext_ops)
 735                return 1;
 736        else
 737                return 0;
 738}
 739