162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Low-Level PCI Support for PC 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * (c) 1999--2000 Martin Mares <mj@ucw.cz> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/sched.h> 962306a36Sopenharmony_ci#include <linux/pci.h> 1062306a36Sopenharmony_ci#include <linux/pci-acpi.h> 1162306a36Sopenharmony_ci#include <linux/ioport.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/dmi.h> 1462306a36Sopenharmony_ci#include <linux/slab.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <asm/acpi.h> 1762306a36Sopenharmony_ci#include <asm/segment.h> 1862306a36Sopenharmony_ci#include <asm/io.h> 1962306a36Sopenharmony_ci#include <asm/smp.h> 2062306a36Sopenharmony_ci#include <asm/pci_x86.h> 2162306a36Sopenharmony_ci#include <asm/setup.h> 2262306a36Sopenharmony_ci#include <asm/irqdomain.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciunsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | 2562306a36Sopenharmony_ci PCI_PROBE_MMCONF; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic int pci_bf_sort; 2862306a36Sopenharmony_ciint pci_routeirq; 2962306a36Sopenharmony_ciint noioapicquirk; 3062306a36Sopenharmony_ci#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS 3162306a36Sopenharmony_ciint noioapicreroute = 0; 3262306a36Sopenharmony_ci#else 3362306a36Sopenharmony_ciint noioapicreroute = 1; 3462306a36Sopenharmony_ci#endif 3562306a36Sopenharmony_ciint pcibios_last_bus = -1; 3662306a36Sopenharmony_ciunsigned long pirq_table_addr; 3762306a36Sopenharmony_ciconst struct pci_raw_ops *__read_mostly raw_pci_ops; 3862306a36Sopenharmony_ciconst struct pci_raw_ops *__read_mostly raw_pci_ext_ops; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciint raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, 4162306a36Sopenharmony_ci int reg, int len, u32 *val) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci if (domain == 0 && reg < 256 && raw_pci_ops) 4462306a36Sopenharmony_ci return raw_pci_ops->read(domain, bus, devfn, reg, len, val); 4562306a36Sopenharmony_ci if (raw_pci_ext_ops) 4662306a36Sopenharmony_ci return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val); 4762306a36Sopenharmony_ci return -EINVAL; 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciint raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, 5162306a36Sopenharmony_ci int reg, int len, u32 val) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci if (domain == 0 && reg < 256 && raw_pci_ops) 5462306a36Sopenharmony_ci return raw_pci_ops->write(domain, bus, devfn, reg, len, val); 5562306a36Sopenharmony_ci if (raw_pci_ext_ops) 5662306a36Sopenharmony_ci return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val); 5762306a36Sopenharmony_ci return -EINVAL; 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci return raw_pci_read(pci_domain_nr(bus), bus->number, 6362306a36Sopenharmony_ci devfn, where, size, value); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci return raw_pci_write(pci_domain_nr(bus), bus->number, 6962306a36Sopenharmony_ci devfn, where, size, value); 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistruct pci_ops pci_root_ops = { 7362306a36Sopenharmony_ci .read = pci_read, 7462306a36Sopenharmony_ci .write = pci_write, 7562306a36Sopenharmony_ci}; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* 7862306a36Sopenharmony_ci * This interrupt-safe spinlock protects all accesses to PCI configuration 7962306a36Sopenharmony_ci * space, except for the mmconfig (ECAM) based operations. 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ciDEFINE_RAW_SPINLOCK(pci_config_lock); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistatic int __init can_skip_ioresource_align(const struct dmi_system_id *d) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 8662306a36Sopenharmony_ci printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); 8762306a36Sopenharmony_ci return 0; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic const struct dmi_system_id can_skip_pciprobe_dmi_table[] __initconst = { 9162306a36Sopenharmony_ci/* 9262306a36Sopenharmony_ci * Systems where PCI IO resource ISA alignment can be skipped 9362306a36Sopenharmony_ci * when the ISA enable bit in the bridge control is not set 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_ci { 9662306a36Sopenharmony_ci .callback = can_skip_ioresource_align, 9762306a36Sopenharmony_ci .ident = "IBM System x3800", 9862306a36Sopenharmony_ci .matches = { 9962306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 10062306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), 10162306a36Sopenharmony_ci }, 10262306a36Sopenharmony_ci }, 10362306a36Sopenharmony_ci { 10462306a36Sopenharmony_ci .callback = can_skip_ioresource_align, 10562306a36Sopenharmony_ci .ident = "IBM System x3850", 10662306a36Sopenharmony_ci .matches = { 10762306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 10862306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), 10962306a36Sopenharmony_ci }, 11062306a36Sopenharmony_ci }, 11162306a36Sopenharmony_ci { 11262306a36Sopenharmony_ci .callback = can_skip_ioresource_align, 11362306a36Sopenharmony_ci .ident = "IBM System x3950", 11462306a36Sopenharmony_ci .matches = { 11562306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 11662306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), 11762306a36Sopenharmony_ci }, 11862306a36Sopenharmony_ci }, 11962306a36Sopenharmony_ci {} 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_civoid __init dmi_check_skip_isa_align(void) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci dmi_check_system(can_skip_pciprobe_dmi_table); 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic void pcibios_fixup_device_resources(struct pci_dev *dev) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; 13062306a36Sopenharmony_ci struct resource *bar_r; 13162306a36Sopenharmony_ci int bar; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci if (pci_probe & PCI_NOASSIGN_BARS) { 13462306a36Sopenharmony_ci /* 13562306a36Sopenharmony_ci * If the BIOS did not assign the BAR, zero out the 13662306a36Sopenharmony_ci * resource so the kernel doesn't attempt to assign 13762306a36Sopenharmony_ci * it later on in pci_assign_unassigned_resources 13862306a36Sopenharmony_ci */ 13962306a36Sopenharmony_ci for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) { 14062306a36Sopenharmony_ci bar_r = &dev->resource[bar]; 14162306a36Sopenharmony_ci if (bar_r->start == 0 && bar_r->end != 0) { 14262306a36Sopenharmony_ci bar_r->flags = 0; 14362306a36Sopenharmony_ci bar_r->end = 0; 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci } 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci if (pci_probe & PCI_NOASSIGN_ROMS) { 14962306a36Sopenharmony_ci if (rom_r->parent) 15062306a36Sopenharmony_ci return; 15162306a36Sopenharmony_ci if (rom_r->start) { 15262306a36Sopenharmony_ci /* we deal with BIOS assigned ROM later */ 15362306a36Sopenharmony_ci return; 15462306a36Sopenharmony_ci } 15562306a36Sopenharmony_ci rom_r->start = rom_r->end = rom_r->flags = 0; 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci/* 16062306a36Sopenharmony_ci * Called after each bus is probed, but before its children 16162306a36Sopenharmony_ci * are examined. 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_civoid pcibios_fixup_bus(struct pci_bus *b) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci struct pci_dev *dev; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci pci_read_bridge_bases(b); 16962306a36Sopenharmony_ci list_for_each_entry(dev, &b->devices, bus_list) 17062306a36Sopenharmony_ci pcibios_fixup_device_resources(dev); 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_civoid pcibios_add_bus(struct pci_bus *bus) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci acpi_pci_add_bus(bus); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_civoid pcibios_remove_bus(struct pci_bus *bus) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci acpi_pci_remove_bus(bus); 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci/* 18462306a36Sopenharmony_ci * Only use DMI information to set this if nothing was passed 18562306a36Sopenharmony_ci * on the kernel command line (which was parsed earlier). 18662306a36Sopenharmony_ci */ 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistatic int __init set_bf_sort(const struct dmi_system_id *d) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci if (pci_bf_sort == pci_bf_sort_default) { 19162306a36Sopenharmony_ci pci_bf_sort = pci_dmi_bf; 19262306a36Sopenharmony_ci printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci return 0; 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic void __init read_dmi_type_b1(const struct dmi_header *dm, 19862306a36Sopenharmony_ci void *private_data) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci u8 *data = (u8 *)dm + 4; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci if (dm->type != 0xB1) 20362306a36Sopenharmony_ci return; 20462306a36Sopenharmony_ci if ((((*(u32 *)data) >> 9) & 0x03) == 0x01) 20562306a36Sopenharmony_ci set_bf_sort((const struct dmi_system_id *)private_data); 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic int __init find_sort_method(const struct dmi_system_id *d) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci dmi_walk(read_dmi_type_b1, (void *)d); 21162306a36Sopenharmony_ci return 0; 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* 21562306a36Sopenharmony_ci * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) 21662306a36Sopenharmony_ci */ 21762306a36Sopenharmony_ci#ifdef __i386__ 21862306a36Sopenharmony_cistatic int __init assign_all_busses(const struct dmi_system_id *d) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci pci_probe |= PCI_ASSIGN_ALL_BUSSES; 22162306a36Sopenharmony_ci printk(KERN_INFO "%s detected: enabling PCI bus# renumbering" 22262306a36Sopenharmony_ci " (pci=assign-busses)\n", d->ident); 22362306a36Sopenharmony_ci return 0; 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci#endif 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_cistatic int __init set_scan_all(const struct dmi_system_id *d) 22862306a36Sopenharmony_ci{ 22962306a36Sopenharmony_ci printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n", 23062306a36Sopenharmony_ci d->ident); 23162306a36Sopenharmony_ci pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); 23262306a36Sopenharmony_ci return 0; 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic const struct dmi_system_id pciprobe_dmi_table[] __initconst = { 23662306a36Sopenharmony_ci#ifdef __i386__ 23762306a36Sopenharmony_ci/* 23862306a36Sopenharmony_ci * Laptops which need pci=assign-busses to see Cardbus cards 23962306a36Sopenharmony_ci */ 24062306a36Sopenharmony_ci { 24162306a36Sopenharmony_ci .callback = assign_all_busses, 24262306a36Sopenharmony_ci .ident = "Samsung X20 Laptop", 24362306a36Sopenharmony_ci .matches = { 24462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), 24562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"), 24662306a36Sopenharmony_ci }, 24762306a36Sopenharmony_ci }, 24862306a36Sopenharmony_ci#endif /* __i386__ */ 24962306a36Sopenharmony_ci { 25062306a36Sopenharmony_ci .callback = set_bf_sort, 25162306a36Sopenharmony_ci .ident = "Dell PowerEdge 1950", 25262306a36Sopenharmony_ci .matches = { 25362306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 25462306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), 25562306a36Sopenharmony_ci }, 25662306a36Sopenharmony_ci }, 25762306a36Sopenharmony_ci { 25862306a36Sopenharmony_ci .callback = set_bf_sort, 25962306a36Sopenharmony_ci .ident = "Dell PowerEdge 1955", 26062306a36Sopenharmony_ci .matches = { 26162306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 26262306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), 26362306a36Sopenharmony_ci }, 26462306a36Sopenharmony_ci }, 26562306a36Sopenharmony_ci { 26662306a36Sopenharmony_ci .callback = set_bf_sort, 26762306a36Sopenharmony_ci .ident = "Dell PowerEdge 2900", 26862306a36Sopenharmony_ci .matches = { 26962306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 27062306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), 27162306a36Sopenharmony_ci }, 27262306a36Sopenharmony_ci }, 27362306a36Sopenharmony_ci { 27462306a36Sopenharmony_ci .callback = set_bf_sort, 27562306a36Sopenharmony_ci .ident = "Dell PowerEdge 2950", 27662306a36Sopenharmony_ci .matches = { 27762306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 27862306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), 27962306a36Sopenharmony_ci }, 28062306a36Sopenharmony_ci }, 28162306a36Sopenharmony_ci { 28262306a36Sopenharmony_ci .callback = set_bf_sort, 28362306a36Sopenharmony_ci .ident = "Dell PowerEdge R900", 28462306a36Sopenharmony_ci .matches = { 28562306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 28662306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"), 28762306a36Sopenharmony_ci }, 28862306a36Sopenharmony_ci }, 28962306a36Sopenharmony_ci { 29062306a36Sopenharmony_ci .callback = find_sort_method, 29162306a36Sopenharmony_ci .ident = "Dell System", 29262306a36Sopenharmony_ci .matches = { 29362306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 29462306a36Sopenharmony_ci }, 29562306a36Sopenharmony_ci }, 29662306a36Sopenharmony_ci { 29762306a36Sopenharmony_ci .callback = set_bf_sort, 29862306a36Sopenharmony_ci .ident = "HP ProLiant BL20p G3", 29962306a36Sopenharmony_ci .matches = { 30062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 30162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"), 30262306a36Sopenharmony_ci }, 30362306a36Sopenharmony_ci }, 30462306a36Sopenharmony_ci { 30562306a36Sopenharmony_ci .callback = set_bf_sort, 30662306a36Sopenharmony_ci .ident = "HP ProLiant BL20p G4", 30762306a36Sopenharmony_ci .matches = { 30862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 30962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"), 31062306a36Sopenharmony_ci }, 31162306a36Sopenharmony_ci }, 31262306a36Sopenharmony_ci { 31362306a36Sopenharmony_ci .callback = set_bf_sort, 31462306a36Sopenharmony_ci .ident = "HP ProLiant BL30p G1", 31562306a36Sopenharmony_ci .matches = { 31662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 31762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"), 31862306a36Sopenharmony_ci }, 31962306a36Sopenharmony_ci }, 32062306a36Sopenharmony_ci { 32162306a36Sopenharmony_ci .callback = set_bf_sort, 32262306a36Sopenharmony_ci .ident = "HP ProLiant BL25p G1", 32362306a36Sopenharmony_ci .matches = { 32462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 32562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"), 32662306a36Sopenharmony_ci }, 32762306a36Sopenharmony_ci }, 32862306a36Sopenharmony_ci { 32962306a36Sopenharmony_ci .callback = set_bf_sort, 33062306a36Sopenharmony_ci .ident = "HP ProLiant BL35p G1", 33162306a36Sopenharmony_ci .matches = { 33262306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 33362306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"), 33462306a36Sopenharmony_ci }, 33562306a36Sopenharmony_ci }, 33662306a36Sopenharmony_ci { 33762306a36Sopenharmony_ci .callback = set_bf_sort, 33862306a36Sopenharmony_ci .ident = "HP ProLiant BL45p G1", 33962306a36Sopenharmony_ci .matches = { 34062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 34162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"), 34262306a36Sopenharmony_ci }, 34362306a36Sopenharmony_ci }, 34462306a36Sopenharmony_ci { 34562306a36Sopenharmony_ci .callback = set_bf_sort, 34662306a36Sopenharmony_ci .ident = "HP ProLiant BL45p G2", 34762306a36Sopenharmony_ci .matches = { 34862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 34962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"), 35062306a36Sopenharmony_ci }, 35162306a36Sopenharmony_ci }, 35262306a36Sopenharmony_ci { 35362306a36Sopenharmony_ci .callback = set_bf_sort, 35462306a36Sopenharmony_ci .ident = "HP ProLiant BL460c G1", 35562306a36Sopenharmony_ci .matches = { 35662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 35762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"), 35862306a36Sopenharmony_ci }, 35962306a36Sopenharmony_ci }, 36062306a36Sopenharmony_ci { 36162306a36Sopenharmony_ci .callback = set_bf_sort, 36262306a36Sopenharmony_ci .ident = "HP ProLiant BL465c G1", 36362306a36Sopenharmony_ci .matches = { 36462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 36562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"), 36662306a36Sopenharmony_ci }, 36762306a36Sopenharmony_ci }, 36862306a36Sopenharmony_ci { 36962306a36Sopenharmony_ci .callback = set_bf_sort, 37062306a36Sopenharmony_ci .ident = "HP ProLiant BL480c G1", 37162306a36Sopenharmony_ci .matches = { 37262306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 37362306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"), 37462306a36Sopenharmony_ci }, 37562306a36Sopenharmony_ci }, 37662306a36Sopenharmony_ci { 37762306a36Sopenharmony_ci .callback = set_bf_sort, 37862306a36Sopenharmony_ci .ident = "HP ProLiant BL685c G1", 37962306a36Sopenharmony_ci .matches = { 38062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 38162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), 38262306a36Sopenharmony_ci }, 38362306a36Sopenharmony_ci }, 38462306a36Sopenharmony_ci { 38562306a36Sopenharmony_ci .callback = set_bf_sort, 38662306a36Sopenharmony_ci .ident = "HP ProLiant DL360", 38762306a36Sopenharmony_ci .matches = { 38862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 38962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"), 39062306a36Sopenharmony_ci }, 39162306a36Sopenharmony_ci }, 39262306a36Sopenharmony_ci { 39362306a36Sopenharmony_ci .callback = set_bf_sort, 39462306a36Sopenharmony_ci .ident = "HP ProLiant DL380", 39562306a36Sopenharmony_ci .matches = { 39662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 39762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"), 39862306a36Sopenharmony_ci }, 39962306a36Sopenharmony_ci }, 40062306a36Sopenharmony_ci#ifdef __i386__ 40162306a36Sopenharmony_ci { 40262306a36Sopenharmony_ci .callback = assign_all_busses, 40362306a36Sopenharmony_ci .ident = "Compaq EVO N800c", 40462306a36Sopenharmony_ci .matches = { 40562306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), 40662306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"), 40762306a36Sopenharmony_ci }, 40862306a36Sopenharmony_ci }, 40962306a36Sopenharmony_ci#endif 41062306a36Sopenharmony_ci { 41162306a36Sopenharmony_ci .callback = set_bf_sort, 41262306a36Sopenharmony_ci .ident = "HP ProLiant DL385 G2", 41362306a36Sopenharmony_ci .matches = { 41462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 41562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"), 41662306a36Sopenharmony_ci }, 41762306a36Sopenharmony_ci }, 41862306a36Sopenharmony_ci { 41962306a36Sopenharmony_ci .callback = set_bf_sort, 42062306a36Sopenharmony_ci .ident = "HP ProLiant DL585 G2", 42162306a36Sopenharmony_ci .matches = { 42262306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "HP"), 42362306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), 42462306a36Sopenharmony_ci }, 42562306a36Sopenharmony_ci }, 42662306a36Sopenharmony_ci { 42762306a36Sopenharmony_ci .callback = set_scan_all, 42862306a36Sopenharmony_ci .ident = "Stratus/NEC ftServer", 42962306a36Sopenharmony_ci .matches = { 43062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Stratus"), 43162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"), 43262306a36Sopenharmony_ci }, 43362306a36Sopenharmony_ci }, 43462306a36Sopenharmony_ci { 43562306a36Sopenharmony_ci .callback = set_scan_all, 43662306a36Sopenharmony_ci .ident = "Stratus/NEC ftServer", 43762306a36Sopenharmony_ci .matches = { 43862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "NEC"), 43962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R32"), 44062306a36Sopenharmony_ci }, 44162306a36Sopenharmony_ci }, 44262306a36Sopenharmony_ci { 44362306a36Sopenharmony_ci .callback = set_scan_all, 44462306a36Sopenharmony_ci .ident = "Stratus/NEC ftServer", 44562306a36Sopenharmony_ci .matches = { 44662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "NEC"), 44762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R31"), 44862306a36Sopenharmony_ci }, 44962306a36Sopenharmony_ci }, 45062306a36Sopenharmony_ci {} 45162306a36Sopenharmony_ci}; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_civoid __init dmi_check_pciprobe(void) 45462306a36Sopenharmony_ci{ 45562306a36Sopenharmony_ci dmi_check_system(pciprobe_dmi_table); 45662306a36Sopenharmony_ci} 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_civoid pcibios_scan_root(int busnum) 45962306a36Sopenharmony_ci{ 46062306a36Sopenharmony_ci struct pci_bus *bus; 46162306a36Sopenharmony_ci struct pci_sysdata *sd; 46262306a36Sopenharmony_ci LIST_HEAD(resources); 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci sd = kzalloc(sizeof(*sd), GFP_KERNEL); 46562306a36Sopenharmony_ci if (!sd) { 46662306a36Sopenharmony_ci printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum); 46762306a36Sopenharmony_ci return; 46862306a36Sopenharmony_ci } 46962306a36Sopenharmony_ci sd->node = x86_pci_root_bus_node(busnum); 47062306a36Sopenharmony_ci x86_pci_root_bus_resources(busnum, &resources); 47162306a36Sopenharmony_ci printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); 47262306a36Sopenharmony_ci bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); 47362306a36Sopenharmony_ci if (!bus) { 47462306a36Sopenharmony_ci pci_free_resource_list(&resources); 47562306a36Sopenharmony_ci kfree(sd); 47662306a36Sopenharmony_ci return; 47762306a36Sopenharmony_ci } 47862306a36Sopenharmony_ci pci_bus_add_devices(bus); 47962306a36Sopenharmony_ci} 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_civoid __init pcibios_set_cache_line_size(void) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci struct cpuinfo_x86 *c = &boot_cpu_data; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci /* 48662306a36Sopenharmony_ci * Set PCI cacheline size to that of the CPU if the CPU has reported it. 48762306a36Sopenharmony_ci * (For older CPUs that don't support cpuid, we se it to 32 bytes 48862306a36Sopenharmony_ci * It's also good for 386/486s (which actually have 16) 48962306a36Sopenharmony_ci * as quite a few PCI devices do not support smaller values. 49062306a36Sopenharmony_ci */ 49162306a36Sopenharmony_ci if (c->x86_clflush_size > 0) { 49262306a36Sopenharmony_ci pci_dfl_cache_line_size = c->x86_clflush_size >> 2; 49362306a36Sopenharmony_ci printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n", 49462306a36Sopenharmony_ci pci_dfl_cache_line_size << 2); 49562306a36Sopenharmony_ci } else { 49662306a36Sopenharmony_ci pci_dfl_cache_line_size = 32 >> 2; 49762306a36Sopenharmony_ci printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci} 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ciint __init pcibios_init(void) 50262306a36Sopenharmony_ci{ 50362306a36Sopenharmony_ci if (!raw_pci_ops && !raw_pci_ext_ops) { 50462306a36Sopenharmony_ci printk(KERN_WARNING "PCI: System does not support PCI\n"); 50562306a36Sopenharmony_ci return 0; 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci pcibios_set_cache_line_size(); 50962306a36Sopenharmony_ci pcibios_resource_survey(); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci if (pci_bf_sort >= pci_force_bf) 51262306a36Sopenharmony_ci pci_sort_breadthfirst(); 51362306a36Sopenharmony_ci return 0; 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cichar *__init pcibios_setup(char *str) 51762306a36Sopenharmony_ci{ 51862306a36Sopenharmony_ci if (!strcmp(str, "off")) { 51962306a36Sopenharmony_ci pci_probe = 0; 52062306a36Sopenharmony_ci return NULL; 52162306a36Sopenharmony_ci } else if (!strcmp(str, "bfsort")) { 52262306a36Sopenharmony_ci pci_bf_sort = pci_force_bf; 52362306a36Sopenharmony_ci return NULL; 52462306a36Sopenharmony_ci } else if (!strcmp(str, "nobfsort")) { 52562306a36Sopenharmony_ci pci_bf_sort = pci_force_nobf; 52662306a36Sopenharmony_ci return NULL; 52762306a36Sopenharmony_ci } 52862306a36Sopenharmony_ci#ifdef CONFIG_PCI_BIOS 52962306a36Sopenharmony_ci else if (!strcmp(str, "bios")) { 53062306a36Sopenharmony_ci pci_probe = PCI_PROBE_BIOS; 53162306a36Sopenharmony_ci return NULL; 53262306a36Sopenharmony_ci } else if (!strcmp(str, "nobios")) { 53362306a36Sopenharmony_ci pci_probe &= ~PCI_PROBE_BIOS; 53462306a36Sopenharmony_ci return NULL; 53562306a36Sopenharmony_ci } else if (!strcmp(str, "biosirq")) { 53662306a36Sopenharmony_ci pci_probe |= PCI_BIOS_IRQ_SCAN; 53762306a36Sopenharmony_ci return NULL; 53862306a36Sopenharmony_ci } else if (!strncmp(str, "pirqaddr=", 9)) { 53962306a36Sopenharmony_ci pirq_table_addr = simple_strtoul(str+9, NULL, 0); 54062306a36Sopenharmony_ci return NULL; 54162306a36Sopenharmony_ci } 54262306a36Sopenharmony_ci#endif 54362306a36Sopenharmony_ci#ifdef CONFIG_PCI_DIRECT 54462306a36Sopenharmony_ci else if (!strcmp(str, "conf1")) { 54562306a36Sopenharmony_ci pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS; 54662306a36Sopenharmony_ci return NULL; 54762306a36Sopenharmony_ci } 54862306a36Sopenharmony_ci else if (!strcmp(str, "conf2")) { 54962306a36Sopenharmony_ci pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; 55062306a36Sopenharmony_ci return NULL; 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci#endif 55362306a36Sopenharmony_ci#ifdef CONFIG_PCI_MMCONFIG 55462306a36Sopenharmony_ci else if (!strcmp(str, "nommconf")) { 55562306a36Sopenharmony_ci pci_probe &= ~PCI_PROBE_MMCONF; 55662306a36Sopenharmony_ci return NULL; 55762306a36Sopenharmony_ci } 55862306a36Sopenharmony_ci else if (!strcmp(str, "check_enable_amd_mmconf")) { 55962306a36Sopenharmony_ci pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; 56062306a36Sopenharmony_ci return NULL; 56162306a36Sopenharmony_ci } 56262306a36Sopenharmony_ci#endif 56362306a36Sopenharmony_ci else if (!strcmp(str, "noacpi")) { 56462306a36Sopenharmony_ci acpi_noirq_set(); 56562306a36Sopenharmony_ci return NULL; 56662306a36Sopenharmony_ci } 56762306a36Sopenharmony_ci else if (!strcmp(str, "noearly")) { 56862306a36Sopenharmony_ci pci_probe |= PCI_PROBE_NOEARLY; 56962306a36Sopenharmony_ci return NULL; 57062306a36Sopenharmony_ci } 57162306a36Sopenharmony_ci else if (!strcmp(str, "usepirqmask")) { 57262306a36Sopenharmony_ci pci_probe |= PCI_USE_PIRQ_MASK; 57362306a36Sopenharmony_ci return NULL; 57462306a36Sopenharmony_ci } else if (!strncmp(str, "irqmask=", 8)) { 57562306a36Sopenharmony_ci pcibios_irq_mask = simple_strtol(str+8, NULL, 0); 57662306a36Sopenharmony_ci return NULL; 57762306a36Sopenharmony_ci } else if (!strncmp(str, "lastbus=", 8)) { 57862306a36Sopenharmony_ci pcibios_last_bus = simple_strtol(str+8, NULL, 0); 57962306a36Sopenharmony_ci return NULL; 58062306a36Sopenharmony_ci } else if (!strcmp(str, "rom")) { 58162306a36Sopenharmony_ci pci_probe |= PCI_ASSIGN_ROMS; 58262306a36Sopenharmony_ci return NULL; 58362306a36Sopenharmony_ci } else if (!strcmp(str, "norom")) { 58462306a36Sopenharmony_ci pci_probe |= PCI_NOASSIGN_ROMS; 58562306a36Sopenharmony_ci return NULL; 58662306a36Sopenharmony_ci } else if (!strcmp(str, "nobar")) { 58762306a36Sopenharmony_ci pci_probe |= PCI_NOASSIGN_BARS; 58862306a36Sopenharmony_ci return NULL; 58962306a36Sopenharmony_ci } else if (!strcmp(str, "assign-busses")) { 59062306a36Sopenharmony_ci pci_probe |= PCI_ASSIGN_ALL_BUSSES; 59162306a36Sopenharmony_ci return NULL; 59262306a36Sopenharmony_ci } else if (!strcmp(str, "use_crs")) { 59362306a36Sopenharmony_ci pci_probe |= PCI_USE__CRS; 59462306a36Sopenharmony_ci return NULL; 59562306a36Sopenharmony_ci } else if (!strcmp(str, "nocrs")) { 59662306a36Sopenharmony_ci pci_probe |= PCI_ROOT_NO_CRS; 59762306a36Sopenharmony_ci return NULL; 59862306a36Sopenharmony_ci } else if (!strcmp(str, "use_e820")) { 59962306a36Sopenharmony_ci pci_probe |= PCI_USE_E820; 60062306a36Sopenharmony_ci add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); 60162306a36Sopenharmony_ci return NULL; 60262306a36Sopenharmony_ci } else if (!strcmp(str, "no_e820")) { 60362306a36Sopenharmony_ci pci_probe |= PCI_NO_E820; 60462306a36Sopenharmony_ci add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); 60562306a36Sopenharmony_ci return NULL; 60662306a36Sopenharmony_ci#ifdef CONFIG_PHYS_ADDR_T_64BIT 60762306a36Sopenharmony_ci } else if (!strcmp(str, "big_root_window")) { 60862306a36Sopenharmony_ci pci_probe |= PCI_BIG_ROOT_WINDOW; 60962306a36Sopenharmony_ci return NULL; 61062306a36Sopenharmony_ci#endif 61162306a36Sopenharmony_ci } else if (!strcmp(str, "routeirq")) { 61262306a36Sopenharmony_ci pci_routeirq = 1; 61362306a36Sopenharmony_ci return NULL; 61462306a36Sopenharmony_ci } else if (!strcmp(str, "skip_isa_align")) { 61562306a36Sopenharmony_ci pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 61662306a36Sopenharmony_ci return NULL; 61762306a36Sopenharmony_ci } else if (!strcmp(str, "noioapicquirk")) { 61862306a36Sopenharmony_ci noioapicquirk = 1; 61962306a36Sopenharmony_ci return NULL; 62062306a36Sopenharmony_ci } else if (!strcmp(str, "ioapicreroute")) { 62162306a36Sopenharmony_ci if (noioapicreroute != -1) 62262306a36Sopenharmony_ci noioapicreroute = 0; 62362306a36Sopenharmony_ci return NULL; 62462306a36Sopenharmony_ci } else if (!strcmp(str, "noioapicreroute")) { 62562306a36Sopenharmony_ci if (noioapicreroute != -1) 62662306a36Sopenharmony_ci noioapicreroute = 1; 62762306a36Sopenharmony_ci return NULL; 62862306a36Sopenharmony_ci } 62962306a36Sopenharmony_ci return str; 63062306a36Sopenharmony_ci} 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ciunsigned int pcibios_assign_all_busses(void) 63362306a36Sopenharmony_ci{ 63462306a36Sopenharmony_ci return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; 63562306a36Sopenharmony_ci} 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_cistatic void set_dev_domain_options(struct pci_dev *pdev) 63862306a36Sopenharmony_ci{ 63962306a36Sopenharmony_ci if (is_vmd(pdev->bus)) 64062306a36Sopenharmony_ci pdev->hotplug_user_indicators = 1; 64162306a36Sopenharmony_ci} 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ciint pcibios_device_add(struct pci_dev *dev) 64462306a36Sopenharmony_ci{ 64562306a36Sopenharmony_ci struct pci_setup_rom *rom; 64662306a36Sopenharmony_ci struct irq_domain *msidom; 64762306a36Sopenharmony_ci struct setup_data *data; 64862306a36Sopenharmony_ci u64 pa_data; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci pa_data = boot_params.hdr.setup_data; 65162306a36Sopenharmony_ci while (pa_data) { 65262306a36Sopenharmony_ci data = memremap(pa_data, sizeof(*rom), MEMREMAP_WB); 65362306a36Sopenharmony_ci if (!data) 65462306a36Sopenharmony_ci return -ENOMEM; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci if (data->type == SETUP_PCI) { 65762306a36Sopenharmony_ci rom = (struct pci_setup_rom *)data; 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci if ((pci_domain_nr(dev->bus) == rom->segment) && 66062306a36Sopenharmony_ci (dev->bus->number == rom->bus) && 66162306a36Sopenharmony_ci (PCI_SLOT(dev->devfn) == rom->device) && 66262306a36Sopenharmony_ci (PCI_FUNC(dev->devfn) == rom->function) && 66362306a36Sopenharmony_ci (dev->vendor == rom->vendor) && 66462306a36Sopenharmony_ci (dev->device == rom->devid)) { 66562306a36Sopenharmony_ci dev->rom = pa_data + 66662306a36Sopenharmony_ci offsetof(struct pci_setup_rom, romdata); 66762306a36Sopenharmony_ci dev->romlen = rom->pcilen; 66862306a36Sopenharmony_ci } 66962306a36Sopenharmony_ci } 67062306a36Sopenharmony_ci pa_data = data->next; 67162306a36Sopenharmony_ci memunmap(data); 67262306a36Sopenharmony_ci } 67362306a36Sopenharmony_ci set_dev_domain_options(dev); 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci /* 67662306a36Sopenharmony_ci * Setup the initial MSI domain of the device. If the underlying 67762306a36Sopenharmony_ci * bus has a PCI/MSI irqdomain associated use the bus domain, 67862306a36Sopenharmony_ci * otherwise set the default domain. This ensures that special irq 67962306a36Sopenharmony_ci * domains e.g. VMD are preserved. The default ensures initial 68062306a36Sopenharmony_ci * operation if irq remapping is not active. If irq remapping is 68162306a36Sopenharmony_ci * active it will overwrite the domain pointer when the device is 68262306a36Sopenharmony_ci * associated to a remapping domain. 68362306a36Sopenharmony_ci */ 68462306a36Sopenharmony_ci msidom = dev_get_msi_domain(&dev->bus->dev); 68562306a36Sopenharmony_ci if (!msidom) 68662306a36Sopenharmony_ci msidom = x86_pci_msi_default_domain; 68762306a36Sopenharmony_ci dev_set_msi_domain(&dev->dev, msidom); 68862306a36Sopenharmony_ci return 0; 68962306a36Sopenharmony_ci} 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ciint pcibios_enable_device(struct pci_dev *dev, int mask) 69262306a36Sopenharmony_ci{ 69362306a36Sopenharmony_ci int err; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci if ((err = pci_enable_resources(dev, mask)) < 0) 69662306a36Sopenharmony_ci return err; 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci if (!pci_dev_msi_enabled(dev)) 69962306a36Sopenharmony_ci return pcibios_enable_irq(dev); 70062306a36Sopenharmony_ci return 0; 70162306a36Sopenharmony_ci} 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_civoid pcibios_disable_device (struct pci_dev *dev) 70462306a36Sopenharmony_ci{ 70562306a36Sopenharmony_ci if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) 70662306a36Sopenharmony_ci pcibios_disable_irq(dev); 70762306a36Sopenharmony_ci} 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC 71062306a36Sopenharmony_civoid pcibios_release_device(struct pci_dev *dev) 71162306a36Sopenharmony_ci{ 71262306a36Sopenharmony_ci if (atomic_dec_return(&dev->enable_cnt) >= 0) 71362306a36Sopenharmony_ci pcibios_disable_device(dev); 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci} 71662306a36Sopenharmony_ci#endif 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ciint pci_ext_cfg_avail(void) 71962306a36Sopenharmony_ci{ 72062306a36Sopenharmony_ci if (raw_pci_ext_ops) 72162306a36Sopenharmony_ci return 1; 72262306a36Sopenharmony_ci else 72362306a36Sopenharmony_ci return 0; 72462306a36Sopenharmony_ci} 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_VMD) 72762306a36Sopenharmony_cistruct pci_dev *pci_real_dma_dev(struct pci_dev *dev) 72862306a36Sopenharmony_ci{ 72962306a36Sopenharmony_ci if (is_vmd(dev->bus)) 73062306a36Sopenharmony_ci return to_pci_sysdata(dev->bus)->vmd_dev; 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci return dev; 73362306a36Sopenharmony_ci} 73462306a36Sopenharmony_ci#endif 735