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#include <asm/irqdomain.h>
  23
  24unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
  25                                PCI_PROBE_MMCONF;
  26
  27static int pci_bf_sort;
  28int pci_routeirq;
  29int noioapicquirk;
  30#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
  31int noioapicreroute = 0;
  32#else
  33int noioapicreroute = 1;
  34#endif
  35int pcibios_last_bus = -1;
  36unsigned long pirq_table_addr;
  37const struct pci_raw_ops *__read_mostly raw_pci_ops;
  38const struct pci_raw_ops *__read_mostly raw_pci_ext_ops;
  39
  40int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
  41                                                int reg, int len, u32 *val)
  42{
  43        if (domain == 0 && reg < 256 && raw_pci_ops)
  44                return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
  45        if (raw_pci_ext_ops)
  46                return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
  47        return -EINVAL;
  48}
  49
  50int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
  51                                                int reg, int len, u32 val)
  52{
  53        if (domain == 0 && reg < 256 && raw_pci_ops)
  54                return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
  55        if (raw_pci_ext_ops)
  56                return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
  57        return -EINVAL;
  58}
  59
  60static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
  61{
  62        return raw_pci_read(pci_domain_nr(bus), bus->number,
  63                                 devfn, where, size, value);
  64}
  65
  66static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
  67{
  68        return raw_pci_write(pci_domain_nr(bus), bus->number,
  69                                  devfn, where, size, value);
  70}
  71
  72struct pci_ops pci_root_ops = {
  73        .read = pci_read,
  74        .write = pci_write,
  75};
  76
  77/*
  78 * This interrupt-safe spinlock protects all accesses to PCI configuration
  79 * space, except for the mmconfig (ECAM) based operations.
  80 */
  81DEFINE_RAW_SPINLOCK(pci_config_lock);
  82
  83static int __init can_skip_ioresource_align(const struct dmi_system_id *d)
  84{
  85        pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
  86        printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
  87        return 0;
  88}
  89
  90static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __initconst = {
  91/*
  92 * Systems where PCI IO resource ISA alignment can be skipped
  93 * when the ISA enable bit in the bridge control is not set
  94 */
  95        {
  96                .callback = can_skip_ioresource_align,
  97                .ident = "IBM System x3800",
  98                .matches = {
  99                        DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
 100                        DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
 101                },
 102        },
 103        {
 104                .callback = can_skip_ioresource_align,
 105                .ident = "IBM System x3850",
 106                .matches = {
 107                        DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
 108                        DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
 109                },
 110        },
 111        {
 112                .callback = can_skip_ioresource_align,
 113                .ident = "IBM System x3950",
 114                .matches = {
 115                        DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
 116                        DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
 117                },
 118        },
 119        {}
 120};
 121
 122void __init dmi_check_skip_isa_align(void)
 123{
 124        dmi_check_system(can_skip_pciprobe_dmi_table);
 125}
 126
 127static void pcibios_fixup_device_resources(struct pci_dev *dev)
 128{
 129        struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
 130        struct resource *bar_r;
 131        int bar;
 132
 133        if (pci_probe & PCI_NOASSIGN_BARS) {
 134                /*
 135                * If the BIOS did not assign the BAR, zero out the
 136                * resource so the kernel doesn't attempt to assign
 137                * it later on in pci_assign_unassigned_resources
 138                */
 139                for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
 140                        bar_r = &dev->resource[bar];
 141                        if (bar_r->start == 0 && bar_r->end != 0) {
 142                                bar_r->flags = 0;
 143                                bar_r->end = 0;
 144                        }
 145                }
 146        }
 147
 148        if (pci_probe & PCI_NOASSIGN_ROMS) {
 149                if (rom_r->parent)
 150                        return;
 151                if (rom_r->start) {
 152                        /* we deal with BIOS assigned ROM later */
 153                        return;
 154                }
 155                rom_r->start = rom_r->end = rom_r->flags = 0;
 156        }
 157}
 158
 159/*
 160 *  Called after each bus is probed, but before its children
 161 *  are examined.
 162 */
 163
 164void pcibios_fixup_bus(struct pci_bus *b)
 165{
 166        struct pci_dev *dev;
 167
 168        pci_read_bridge_bases(b);
 169        list_for_each_entry(dev, &b->devices, bus_list)
 170                pcibios_fixup_device_resources(dev);
 171}
 172
 173void pcibios_add_bus(struct pci_bus *bus)
 174{
 175        acpi_pci_add_bus(bus);
 176}
 177
 178void 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
 188static 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
 197static void __init read_dmi_type_b1(const struct dmi_header *dm,
 198                                    void *private_data)
 199{
 200        u8 *data = (u8 *)dm + 4;
 201
 202        if (dm->type != 0xB1)
 203                return;
 204        if ((((*(u32 *)data) >> 9) & 0x03) == 0x01)
 205                set_bf_sort((const struct dmi_system_id *)private_data);
 206}
 207
 208static int __init find_sort_method(const struct dmi_system_id *d)
 209{
 210        dmi_walk(read_dmi_type_b1, (void *)d);
 211        return 0;
 212}
 213
 214/*
 215 * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
 216 */
 217#ifdef __i386__
 218static int __init assign_all_busses(const struct dmi_system_id *d)
 219{
 220        pci_probe |= PCI_ASSIGN_ALL_BUSSES;
 221        printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
 222                        " (pci=assign-busses)\n", d->ident);
 223        return 0;
 224}
 225#endif
 226
 227static int __init set_scan_all(const struct dmi_system_id *d)
 228{
 229        printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n",
 230               d->ident);
 231        pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
 232        return 0;
 233}
 234
 235static const struct dmi_system_id pciprobe_dmi_table[] __initconst = {
 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 = set_bf_sort,
 251                .ident = "Dell PowerEdge 1950",
 252                .matches = {
 253                        DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 254                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
 255                },
 256        },
 257        {
 258                .callback = set_bf_sort,
 259                .ident = "Dell PowerEdge 1955",
 260                .matches = {
 261                        DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 262                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"),
 263                },
 264        },
 265        {
 266                .callback = set_bf_sort,
 267                .ident = "Dell PowerEdge 2900",
 268                .matches = {
 269                        DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 270                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"),
 271                },
 272        },
 273        {
 274                .callback = set_bf_sort,
 275                .ident = "Dell PowerEdge 2950",
 276                .matches = {
 277                        DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 278                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
 279                },
 280        },
 281        {
 282                .callback = set_bf_sort,
 283                .ident = "Dell PowerEdge R900",
 284                .matches = {
 285                        DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
 286                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"),
 287                },
 288        },
 289        {
 290                .callback = find_sort_method,
 291                .ident = "Dell System",
 292                .matches = {
 293                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
 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                .callback = set_scan_all,
 428                .ident = "Stratus/NEC ftServer",
 429                .matches = {
 430                        DMI_MATCH(DMI_SYS_VENDOR, "Stratus"),
 431                        DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"),
 432                },
 433        },
 434        {
 435                .callback = set_scan_all,
 436                .ident = "Stratus/NEC ftServer",
 437                .matches = {
 438                        DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
 439                        DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R32"),
 440                },
 441        },
 442        {
 443                .callback = set_scan_all,
 444                .ident = "Stratus/NEC ftServer",
 445                .matches = {
 446                        DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
 447                        DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R31"),
 448                },
 449        },
 450        {}
 451};
 452
 453void __init dmi_check_pciprobe(void)
 454{
 455        dmi_check_system(pciprobe_dmi_table);
 456}
 457
 458void pcibios_scan_root(int busnum)
 459{
 460        struct pci_bus *bus;
 461        struct pci_sysdata *sd;
 462        LIST_HEAD(resources);
 463
 464        sd = kzalloc(sizeof(*sd), GFP_KERNEL);
 465        if (!sd) {
 466                printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
 467                return;
 468        }
 469        sd->node = x86_pci_root_bus_node(busnum);
 470        x86_pci_root_bus_resources(busnum, &resources);
 471        printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
 472        bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
 473        if (!bus) {
 474                pci_free_resource_list(&resources);
 475                kfree(sd);
 476                return;
 477        }
 478        pci_bus_add_devices(bus);
 479}
 480
 481void __init pcibios_set_cache_line_size(void)
 482{
 483        struct cpuinfo_x86 *c = &boot_cpu_data;
 484
 485        /*
 486         * Set PCI cacheline size to that of the CPU if the CPU has reported it.
 487         * (For older CPUs that don't support cpuid, we se it to 32 bytes
 488         * It's also good for 386/486s (which actually have 16)
 489         * as quite a few PCI devices do not support smaller values.
 490         */
 491        if (c->x86_clflush_size > 0) {
 492                pci_dfl_cache_line_size = c->x86_clflush_size >> 2;
 493                printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
 494                        pci_dfl_cache_line_size << 2);
 495        } else {
 496                pci_dfl_cache_line_size = 32 >> 2;
 497                printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
 498        }
 499}
 500
 501int __init pcibios_init(void)
 502{
 503        if (!raw_pci_ops && !raw_pci_ext_ops) {
 504                printk(KERN_WARNING "PCI: System does not support PCI\n");
 505                return 0;
 506        }
 507
 508        pcibios_set_cache_line_size();
 509        pcibios_resource_survey();
 510
 511        if (pci_bf_sort >= pci_force_bf)
 512                pci_sort_breadthfirst();
 513        return 0;
 514}
 515
 516char *__init pcibios_setup(char *str)
 517{
 518        if (!strcmp(str, "off")) {
 519                pci_probe = 0;
 520                return NULL;
 521        } else if (!strcmp(str, "bfsort")) {
 522                pci_bf_sort = pci_force_bf;
 523                return NULL;
 524        } else if (!strcmp(str, "nobfsort")) {
 525                pci_bf_sort = pci_force_nobf;
 526                return NULL;
 527        }
 528#ifdef CONFIG_PCI_BIOS
 529        else if (!strcmp(str, "bios")) {
 530                pci_probe = PCI_PROBE_BIOS;
 531                return NULL;
 532        } else if (!strcmp(str, "nobios")) {
 533                pci_probe &= ~PCI_PROBE_BIOS;
 534                return NULL;
 535        } else if (!strcmp(str, "biosirq")) {
 536                pci_probe |= PCI_BIOS_IRQ_SCAN;
 537                return NULL;
 538        } else if (!strncmp(str, "pirqaddr=", 9)) {
 539                pirq_table_addr = simple_strtoul(str+9, NULL, 0);
 540                return NULL;
 541        }
 542#endif
 543#ifdef CONFIG_PCI_DIRECT
 544        else if (!strcmp(str, "conf1")) {
 545                pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
 546                return NULL;
 547        }
 548        else if (!strcmp(str, "conf2")) {
 549                pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
 550                return NULL;
 551        }
 552#endif
 553#ifdef CONFIG_PCI_MMCONFIG
 554        else if (!strcmp(str, "nommconf")) {
 555                pci_probe &= ~PCI_PROBE_MMCONF;
 556                return NULL;
 557        }
 558        else if (!strcmp(str, "check_enable_amd_mmconf")) {
 559                pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
 560                return NULL;
 561        }
 562#endif
 563        else if (!strcmp(str, "noacpi")) {
 564                acpi_noirq_set();
 565                return NULL;
 566        }
 567        else if (!strcmp(str, "noearly")) {
 568                pci_probe |= PCI_PROBE_NOEARLY;
 569                return NULL;
 570        }
 571        else if (!strcmp(str, "usepirqmask")) {
 572                pci_probe |= PCI_USE_PIRQ_MASK;
 573                return NULL;
 574        } else if (!strncmp(str, "irqmask=", 8)) {
 575                pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
 576                return NULL;
 577        } else if (!strncmp(str, "lastbus=", 8)) {
 578                pcibios_last_bus = simple_strtol(str+8, NULL, 0);
 579                return NULL;
 580        } else if (!strcmp(str, "rom")) {
 581                pci_probe |= PCI_ASSIGN_ROMS;
 582                return NULL;
 583        } else if (!strcmp(str, "norom")) {
 584                pci_probe |= PCI_NOASSIGN_ROMS;
 585                return NULL;
 586        } else if (!strcmp(str, "nobar")) {
 587                pci_probe |= PCI_NOASSIGN_BARS;
 588                return NULL;
 589        } else if (!strcmp(str, "assign-busses")) {
 590                pci_probe |= PCI_ASSIGN_ALL_BUSSES;
 591                return NULL;
 592        } else if (!strcmp(str, "use_crs")) {
 593                pci_probe |= PCI_USE__CRS;
 594                return NULL;
 595        } else if (!strcmp(str, "nocrs")) {
 596                pci_probe |= PCI_ROOT_NO_CRS;
 597                return NULL;
 598        } else if (!strcmp(str, "use_e820")) {
 599                pci_probe |= PCI_USE_E820;
 600                add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
 601                return NULL;
 602        } else if (!strcmp(str, "no_e820")) {
 603                pci_probe |= PCI_NO_E820;
 604                add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
 605                return NULL;
 606#ifdef CONFIG_PHYS_ADDR_T_64BIT
 607        } else if (!strcmp(str, "big_root_window")) {
 608                pci_probe |= PCI_BIG_ROOT_WINDOW;
 609                return NULL;
 610#endif
 611        } else if (!strcmp(str, "routeirq")) {
 612                pci_routeirq = 1;
 613                return NULL;
 614        } else if (!strcmp(str, "skip_isa_align")) {
 615                pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
 616                return NULL;
 617        } else if (!strcmp(str, "noioapicquirk")) {
 618                noioapicquirk = 1;
 619                return NULL;
 620        } else if (!strcmp(str, "ioapicreroute")) {
 621                if (noioapicreroute != -1)
 622                        noioapicreroute = 0;
 623                return NULL;
 624        } else if (!strcmp(str, "noioapicreroute")) {
 625                if (noioapicreroute != -1)
 626                        noioapicreroute = 1;
 627                return NULL;
 628        }
 629        return str;
 630}
 631
 632unsigned int pcibios_assign_all_busses(void)
 633{
 634        return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 635}
 636
 637static void set_dev_domain_options(struct pci_dev *pdev)
 638{
 639        if (is_vmd(pdev->bus))
 640                pdev->hotplug_user_indicators = 1;
 641}
 642
 643int pcibios_device_add(struct pci_dev *dev)
 644{
 645        struct pci_setup_rom *rom;
 646        struct irq_domain *msidom;
 647        struct setup_data *data;
 648        u64 pa_data;
 649
 650        pa_data = boot_params.hdr.setup_data;
 651        while (pa_data) {
 652                data = memremap(pa_data, sizeof(*rom), MEMREMAP_WB);
 653                if (!data)
 654                        return -ENOMEM;
 655
 656                if (data->type == SETUP_PCI) {
 657                        rom = (struct pci_setup_rom *)data;
 658
 659                        if ((pci_domain_nr(dev->bus) == rom->segment) &&
 660                            (dev->bus->number == rom->bus) &&
 661                            (PCI_SLOT(dev->devfn) == rom->device) &&
 662                            (PCI_FUNC(dev->devfn) == rom->function) &&
 663                            (dev->vendor == rom->vendor) &&
 664                            (dev->device == rom->devid)) {
 665                                dev->rom = pa_data +
 666                                      offsetof(struct pci_setup_rom, romdata);
 667                                dev->romlen = rom->pcilen;
 668                        }
 669                }
 670                pa_data = data->next;
 671                memunmap(data);
 672        }
 673        set_dev_domain_options(dev);
 674
 675        /*
 676         * Setup the initial MSI domain of the device. If the underlying
 677         * bus has a PCI/MSI irqdomain associated use the bus domain,
 678         * otherwise set the default domain. This ensures that special irq
 679         * domains e.g. VMD are preserved. The default ensures initial
 680         * operation if irq remapping is not active. If irq remapping is
 681         * active it will overwrite the domain pointer when the device is
 682         * associated to a remapping domain.
 683         */
 684        msidom = dev_get_msi_domain(&dev->bus->dev);
 685        if (!msidom)
 686                msidom = x86_pci_msi_default_domain;
 687        dev_set_msi_domain(&dev->dev, msidom);
 688        return 0;
 689}
 690
 691int pcibios_enable_device(struct pci_dev *dev, int mask)
 692{
 693        int err;
 694
 695        if ((err = pci_enable_resources(dev, mask)) < 0)
 696                return err;
 697
 698        if (!pci_dev_msi_enabled(dev))
 699                return pcibios_enable_irq(dev);
 700        return 0;
 701}
 702
 703void pcibios_disable_device (struct pci_dev *dev)
 704{
 705        if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
 706                pcibios_disable_irq(dev);
 707}
 708
 709#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
 710void pcibios_release_device(struct pci_dev *dev)
 711{
 712        if (atomic_dec_return(&dev->enable_cnt) >= 0)
 713                pcibios_disable_device(dev);
 714
 715}
 716#endif
 717
 718int pci_ext_cfg_avail(void)
 719{
 720        if (raw_pci_ext_ops)
 721                return 1;
 722        else
 723                return 0;
 724}
 725
 726#if IS_ENABLED(CONFIG_VMD)
 727struct pci_dev *pci_real_dma_dev(struct pci_dev *dev)
 728{
 729        if (is_vmd(dev->bus))
 730                return to_pci_sysdata(dev->bus)->vmd_dev;
 731
 732        return dev;
 733}
 734#endif
 735