1fb9aa6f1SThomas Gleixner /* 2fb9aa6f1SThomas Gleixner * Low-Level PCI Support for PC 3fb9aa6f1SThomas Gleixner * 4fb9aa6f1SThomas Gleixner * (c) 1999--2000 Martin Mares <mj@ucw.cz> 5fb9aa6f1SThomas Gleixner */ 6fb9aa6f1SThomas Gleixner 7fb9aa6f1SThomas Gleixner #include <linux/sched.h> 8fb9aa6f1SThomas Gleixner #include <linux/pci.h> 989016506SJiang Liu #include <linux/pci-acpi.h> 10fb9aa6f1SThomas Gleixner #include <linux/ioport.h> 11fb9aa6f1SThomas Gleixner #include <linux/init.h> 12fb9aa6f1SThomas Gleixner #include <linux/dmi.h> 135a0e3ad6STejun Heo #include <linux/slab.h> 14fb9aa6f1SThomas Gleixner 15284f5f9dSBjorn Helgaas #include <asm-generic/pci-bridge.h> 16fb9aa6f1SThomas Gleixner #include <asm/acpi.h> 17fb9aa6f1SThomas Gleixner #include <asm/segment.h> 18fb9aa6f1SThomas Gleixner #include <asm/io.h> 19fb9aa6f1SThomas Gleixner #include <asm/smp.h> 2082487711SJaswinder Singh Rajput #include <asm/pci_x86.h> 21f9a37be0SMatthew Garrett #include <asm/setup.h> 22fb9aa6f1SThomas Gleixner 23fb9aa6f1SThomas Gleixner unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | 24fb9aa6f1SThomas Gleixner PCI_PROBE_MMCONF; 25fb9aa6f1SThomas Gleixner 26e3f2baebSYinghai Lu unsigned int pci_early_dump_regs; 27fb9aa6f1SThomas Gleixner static int pci_bf_sort; 286e8af08dSNarendra_K@Dell.com static int smbios_type_b1_flag; 29fb9aa6f1SThomas Gleixner int pci_routeirq; 30a9322f64SStefan Assmann int noioapicquirk; 3141b9eb26SStefan Assmann #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS 3241b9eb26SStefan Assmann int noioapicreroute = 0; 3341b9eb26SStefan Assmann #else 349197979bSStefan Assmann int noioapicreroute = 1; 3541b9eb26SStefan Assmann #endif 36fb9aa6f1SThomas Gleixner int pcibios_last_bus = -1; 37fb9aa6f1SThomas Gleixner unsigned long pirq_table_addr; 3872da0b07SJan Beulich const struct pci_raw_ops *__read_mostly raw_pci_ops; 3972da0b07SJan Beulich const struct pci_raw_ops *__read_mostly raw_pci_ext_ops; 40b6ce068aSMatthew Wilcox 41b6ce068aSMatthew Wilcox int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, 42b6ce068aSMatthew Wilcox int reg, int len, u32 *val) 43b6ce068aSMatthew Wilcox { 44beef3129SMatthew Wilcox if (domain == 0 && reg < 256 && raw_pci_ops) 45b6ce068aSMatthew Wilcox return raw_pci_ops->read(domain, bus, devfn, reg, len, val); 46b6ce068aSMatthew Wilcox if (raw_pci_ext_ops) 47b6ce068aSMatthew Wilcox return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val); 48b6ce068aSMatthew Wilcox return -EINVAL; 49b6ce068aSMatthew Wilcox } 50b6ce068aSMatthew Wilcox 51b6ce068aSMatthew Wilcox int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, 52b6ce068aSMatthew Wilcox int reg, int len, u32 val) 53b6ce068aSMatthew Wilcox { 54beef3129SMatthew Wilcox if (domain == 0 && reg < 256 && raw_pci_ops) 55b6ce068aSMatthew Wilcox return raw_pci_ops->write(domain, bus, devfn, reg, len, val); 56b6ce068aSMatthew Wilcox if (raw_pci_ext_ops) 57b6ce068aSMatthew Wilcox return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val); 58b6ce068aSMatthew Wilcox return -EINVAL; 59b6ce068aSMatthew Wilcox } 60fb9aa6f1SThomas Gleixner 61fb9aa6f1SThomas Gleixner static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 62fb9aa6f1SThomas Gleixner { 63b6ce068aSMatthew Wilcox return raw_pci_read(pci_domain_nr(bus), bus->number, 64a79e4198SJeff Garzik devfn, where, size, value); 65fb9aa6f1SThomas Gleixner } 66fb9aa6f1SThomas Gleixner 67fb9aa6f1SThomas Gleixner static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) 68fb9aa6f1SThomas Gleixner { 69b6ce068aSMatthew Wilcox return raw_pci_write(pci_domain_nr(bus), bus->number, 70a79e4198SJeff Garzik devfn, where, size, value); 71fb9aa6f1SThomas Gleixner } 72fb9aa6f1SThomas Gleixner 73fb9aa6f1SThomas Gleixner struct pci_ops pci_root_ops = { 74fb9aa6f1SThomas Gleixner .read = pci_read, 75fb9aa6f1SThomas Gleixner .write = pci_write, 76fb9aa6f1SThomas Gleixner }; 77fb9aa6f1SThomas Gleixner 78fb9aa6f1SThomas Gleixner /* 79fb9aa6f1SThomas Gleixner * This interrupt-safe spinlock protects all accesses to PCI 80fb9aa6f1SThomas Gleixner * configuration space. 81fb9aa6f1SThomas Gleixner */ 82d19f61f0SThomas Gleixner DEFINE_RAW_SPINLOCK(pci_config_lock); 83fb9aa6f1SThomas Gleixner 844ac9cbfaSMathias Krause static int __init can_skip_ioresource_align(const struct dmi_system_id *d) 8513a6ddb0SYinghai Lu { 8613a6ddb0SYinghai Lu pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 8713a6ddb0SYinghai Lu printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); 8813a6ddb0SYinghai Lu return 0; 8913a6ddb0SYinghai Lu } 9013a6ddb0SYinghai Lu 914ac9cbfaSMathias Krause static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __initconst = { 9213a6ddb0SYinghai Lu /* 9313a6ddb0SYinghai Lu * Systems where PCI IO resource ISA alignment can be skipped 9413a6ddb0SYinghai Lu * when the ISA enable bit in the bridge control is not set 9513a6ddb0SYinghai Lu */ 9613a6ddb0SYinghai Lu { 9713a6ddb0SYinghai Lu .callback = can_skip_ioresource_align, 9813a6ddb0SYinghai Lu .ident = "IBM System x3800", 9913a6ddb0SYinghai Lu .matches = { 10013a6ddb0SYinghai Lu DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 10113a6ddb0SYinghai Lu DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), 10213a6ddb0SYinghai Lu }, 10313a6ddb0SYinghai Lu }, 10413a6ddb0SYinghai Lu { 10513a6ddb0SYinghai Lu .callback = can_skip_ioresource_align, 10613a6ddb0SYinghai Lu .ident = "IBM System x3850", 10713a6ddb0SYinghai Lu .matches = { 10813a6ddb0SYinghai Lu DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 10913a6ddb0SYinghai Lu DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), 11013a6ddb0SYinghai Lu }, 11113a6ddb0SYinghai Lu }, 11213a6ddb0SYinghai Lu { 11313a6ddb0SYinghai Lu .callback = can_skip_ioresource_align, 11413a6ddb0SYinghai Lu .ident = "IBM System x3950", 11513a6ddb0SYinghai Lu .matches = { 11613a6ddb0SYinghai Lu DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 11713a6ddb0SYinghai Lu DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), 11813a6ddb0SYinghai Lu }, 11913a6ddb0SYinghai Lu }, 12013a6ddb0SYinghai Lu {} 12113a6ddb0SYinghai Lu }; 12213a6ddb0SYinghai Lu 12313a6ddb0SYinghai Lu void __init dmi_check_skip_isa_align(void) 12413a6ddb0SYinghai Lu { 12513a6ddb0SYinghai Lu dmi_check_system(can_skip_pciprobe_dmi_table); 12613a6ddb0SYinghai Lu } 12713a6ddb0SYinghai Lu 128a18e3690SGreg Kroah-Hartman static void pcibios_fixup_device_resources(struct pci_dev *dev) 129bb71ad88SGary Hade { 130bb71ad88SGary Hade struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; 1317bd1c365SMike Habeck struct resource *bar_r; 1327bd1c365SMike Habeck int bar; 1337bd1c365SMike Habeck 1347bd1c365SMike Habeck if (pci_probe & PCI_NOASSIGN_BARS) { 1357bd1c365SMike Habeck /* 1367bd1c365SMike Habeck * If the BIOS did not assign the BAR, zero out the 1377bd1c365SMike Habeck * resource so the kernel doesn't attmept to assign 1387bd1c365SMike Habeck * it later on in pci_assign_unassigned_resources 1397bd1c365SMike Habeck */ 1407bd1c365SMike Habeck for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { 1417bd1c365SMike Habeck bar_r = &dev->resource[bar]; 1427bd1c365SMike Habeck if (bar_r->start == 0 && bar_r->end != 0) { 1437bd1c365SMike Habeck bar_r->flags = 0; 1447bd1c365SMike Habeck bar_r->end = 0; 1457bd1c365SMike Habeck } 1467bd1c365SMike Habeck } 1477bd1c365SMike Habeck } 148bb71ad88SGary Hade 149bb71ad88SGary Hade if (pci_probe & PCI_NOASSIGN_ROMS) { 150bb71ad88SGary Hade if (rom_r->parent) 151bb71ad88SGary Hade return; 152bb71ad88SGary Hade if (rom_r->start) { 153bb71ad88SGary Hade /* we deal with BIOS assigned ROM later */ 154bb71ad88SGary Hade return; 155bb71ad88SGary Hade } 156bb71ad88SGary Hade rom_r->start = rom_r->end = rom_r->flags = 0; 157bb71ad88SGary Hade } 158bb71ad88SGary Hade } 159bb71ad88SGary Hade 160fb9aa6f1SThomas Gleixner /* 161fb9aa6f1SThomas Gleixner * Called after each bus is probed, but before its children 162fb9aa6f1SThomas Gleixner * are examined. 163fb9aa6f1SThomas Gleixner */ 164fb9aa6f1SThomas Gleixner 165a18e3690SGreg Kroah-Hartman void pcibios_fixup_bus(struct pci_bus *b) 166fb9aa6f1SThomas Gleixner { 167bb71ad88SGary Hade struct pci_dev *dev; 168bb71ad88SGary Hade 169fb9aa6f1SThomas Gleixner pci_read_bridge_bases(b); 170bb71ad88SGary Hade list_for_each_entry(dev, &b->devices, bus_list) 171bb71ad88SGary Hade pcibios_fixup_device_resources(dev); 172fb9aa6f1SThomas Gleixner } 173fb9aa6f1SThomas Gleixner 17489016506SJiang Liu void pcibios_add_bus(struct pci_bus *bus) 17589016506SJiang Liu { 17689016506SJiang Liu acpi_pci_add_bus(bus); 17789016506SJiang Liu } 17889016506SJiang Liu 17989016506SJiang Liu void pcibios_remove_bus(struct pci_bus *bus) 18089016506SJiang Liu { 18189016506SJiang Liu acpi_pci_remove_bus(bus); 18289016506SJiang Liu } 18389016506SJiang Liu 184fb9aa6f1SThomas Gleixner /* 185fb9aa6f1SThomas Gleixner * Only use DMI information to set this if nothing was passed 186fb9aa6f1SThomas Gleixner * on the kernel command line (which was parsed earlier). 187fb9aa6f1SThomas Gleixner */ 188fb9aa6f1SThomas Gleixner 1894ac9cbfaSMathias Krause static int __init set_bf_sort(const struct dmi_system_id *d) 190fb9aa6f1SThomas Gleixner { 191fb9aa6f1SThomas Gleixner if (pci_bf_sort == pci_bf_sort_default) { 192fb9aa6f1SThomas Gleixner pci_bf_sort = pci_dmi_bf; 193fb9aa6f1SThomas Gleixner printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); 194fb9aa6f1SThomas Gleixner } 195fb9aa6f1SThomas Gleixner return 0; 196fb9aa6f1SThomas Gleixner } 197fb9aa6f1SThomas Gleixner 1984ac9cbfaSMathias Krause static void __init read_dmi_type_b1(const struct dmi_header *dm, 1996e8af08dSNarendra_K@Dell.com void *private_data) 2006e8af08dSNarendra_K@Dell.com { 2016e8af08dSNarendra_K@Dell.com u8 *d = (u8 *)dm + 4; 2026e8af08dSNarendra_K@Dell.com 2036e8af08dSNarendra_K@Dell.com if (dm->type != 0xB1) 2046e8af08dSNarendra_K@Dell.com return; 2056e8af08dSNarendra_K@Dell.com switch (((*(u32 *)d) >> 9) & 0x03) { 2066e8af08dSNarendra_K@Dell.com case 0x00: 2076e8af08dSNarendra_K@Dell.com printk(KERN_INFO "dmi type 0xB1 record - unknown flag\n"); 2086e8af08dSNarendra_K@Dell.com break; 2096e8af08dSNarendra_K@Dell.com case 0x01: /* set pci=bfsort */ 2106e8af08dSNarendra_K@Dell.com smbios_type_b1_flag = 1; 2116e8af08dSNarendra_K@Dell.com break; 2126e8af08dSNarendra_K@Dell.com case 0x02: /* do not set pci=bfsort */ 2136e8af08dSNarendra_K@Dell.com smbios_type_b1_flag = 2; 2146e8af08dSNarendra_K@Dell.com break; 2156e8af08dSNarendra_K@Dell.com default: 2166e8af08dSNarendra_K@Dell.com break; 2176e8af08dSNarendra_K@Dell.com } 2186e8af08dSNarendra_K@Dell.com } 2196e8af08dSNarendra_K@Dell.com 2204ac9cbfaSMathias Krause static int __init find_sort_method(const struct dmi_system_id *d) 2216e8af08dSNarendra_K@Dell.com { 2226e8af08dSNarendra_K@Dell.com dmi_walk(read_dmi_type_b1, NULL); 2236e8af08dSNarendra_K@Dell.com 2246e8af08dSNarendra_K@Dell.com if (smbios_type_b1_flag == 1) { 2256e8af08dSNarendra_K@Dell.com set_bf_sort(d); 2266e8af08dSNarendra_K@Dell.com return 0; 2276e8af08dSNarendra_K@Dell.com } 2286e8af08dSNarendra_K@Dell.com return -1; 2296e8af08dSNarendra_K@Dell.com } 2306e8af08dSNarendra_K@Dell.com 231fb9aa6f1SThomas Gleixner /* 232fb9aa6f1SThomas Gleixner * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) 233fb9aa6f1SThomas Gleixner */ 234fb9aa6f1SThomas Gleixner #ifdef __i386__ 2354ac9cbfaSMathias Krause static int __init assign_all_busses(const struct dmi_system_id *d) 236fb9aa6f1SThomas Gleixner { 237fb9aa6f1SThomas Gleixner pci_probe |= PCI_ASSIGN_ALL_BUSSES; 238fb9aa6f1SThomas Gleixner printk(KERN_INFO "%s detected: enabling PCI bus# renumbering" 239fb9aa6f1SThomas Gleixner " (pci=assign-busses)\n", d->ident); 240fb9aa6f1SThomas Gleixner return 0; 241fb9aa6f1SThomas Gleixner } 242fb9aa6f1SThomas Gleixner #endif 243fb9aa6f1SThomas Gleixner 2444ac9cbfaSMathias Krause static int __init set_scan_all(const struct dmi_system_id *d) 245284f5f9dSBjorn Helgaas { 246284f5f9dSBjorn Helgaas printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n", 247284f5f9dSBjorn Helgaas d->ident); 248284f5f9dSBjorn Helgaas pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); 249284f5f9dSBjorn Helgaas return 0; 250284f5f9dSBjorn Helgaas } 251284f5f9dSBjorn Helgaas 2524ac9cbfaSMathias Krause static const struct dmi_system_id pciprobe_dmi_table[] __initconst = { 253fb9aa6f1SThomas Gleixner #ifdef __i386__ 254fb9aa6f1SThomas Gleixner /* 255fb9aa6f1SThomas Gleixner * Laptops which need pci=assign-busses to see Cardbus cards 256fb9aa6f1SThomas Gleixner */ 257fb9aa6f1SThomas Gleixner { 258fb9aa6f1SThomas Gleixner .callback = assign_all_busses, 259fb9aa6f1SThomas Gleixner .ident = "Samsung X20 Laptop", 260fb9aa6f1SThomas Gleixner .matches = { 261fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), 262fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"), 263fb9aa6f1SThomas Gleixner }, 264fb9aa6f1SThomas Gleixner }, 265fb9aa6f1SThomas Gleixner #endif /* __i386__ */ 266fb9aa6f1SThomas Gleixner { 267fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 268fb9aa6f1SThomas Gleixner .ident = "Dell PowerEdge 1950", 269fb9aa6f1SThomas Gleixner .matches = { 270fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 271fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), 272fb9aa6f1SThomas Gleixner }, 273fb9aa6f1SThomas Gleixner }, 274fb9aa6f1SThomas Gleixner { 275fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 276fb9aa6f1SThomas Gleixner .ident = "Dell PowerEdge 1955", 277fb9aa6f1SThomas Gleixner .matches = { 278fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 279fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), 280fb9aa6f1SThomas Gleixner }, 281fb9aa6f1SThomas Gleixner }, 282fb9aa6f1SThomas Gleixner { 283fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 284fb9aa6f1SThomas Gleixner .ident = "Dell PowerEdge 2900", 285fb9aa6f1SThomas Gleixner .matches = { 286fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 287fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), 288fb9aa6f1SThomas Gleixner }, 289fb9aa6f1SThomas Gleixner }, 290fb9aa6f1SThomas Gleixner { 291fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 292fb9aa6f1SThomas Gleixner .ident = "Dell PowerEdge 2950", 293fb9aa6f1SThomas Gleixner .matches = { 294fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 295fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), 296fb9aa6f1SThomas Gleixner }, 297fb9aa6f1SThomas Gleixner }, 298fb9aa6f1SThomas Gleixner { 299fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 300fb9aa6f1SThomas Gleixner .ident = "Dell PowerEdge R900", 301fb9aa6f1SThomas Gleixner .matches = { 302fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 303fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"), 304fb9aa6f1SThomas Gleixner }, 305fb9aa6f1SThomas Gleixner }, 306fb9aa6f1SThomas Gleixner { 3079b373ed1SNarendra_K@Dell.com .callback = find_sort_method, 3089b373ed1SNarendra_K@Dell.com .ident = "Dell System", 3099b373ed1SNarendra_K@Dell.com .matches = { 3109b373ed1SNarendra_K@Dell.com DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 3119b373ed1SNarendra_K@Dell.com }, 3129b373ed1SNarendra_K@Dell.com }, 3139b373ed1SNarendra_K@Dell.com { 314fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 315fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL20p G3", 316fb9aa6f1SThomas Gleixner .matches = { 317fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 318fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"), 319fb9aa6f1SThomas Gleixner }, 320fb9aa6f1SThomas Gleixner }, 321fb9aa6f1SThomas Gleixner { 322fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 323fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL20p G4", 324fb9aa6f1SThomas Gleixner .matches = { 325fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 326fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"), 327fb9aa6f1SThomas Gleixner }, 328fb9aa6f1SThomas Gleixner }, 329fb9aa6f1SThomas Gleixner { 330fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 331fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL30p G1", 332fb9aa6f1SThomas Gleixner .matches = { 333fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 334fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"), 335fb9aa6f1SThomas Gleixner }, 336fb9aa6f1SThomas Gleixner }, 337fb9aa6f1SThomas Gleixner { 338fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 339fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL25p G1", 340fb9aa6f1SThomas Gleixner .matches = { 341fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 342fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"), 343fb9aa6f1SThomas Gleixner }, 344fb9aa6f1SThomas Gleixner }, 345fb9aa6f1SThomas Gleixner { 346fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 347fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL35p G1", 348fb9aa6f1SThomas Gleixner .matches = { 349fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 350fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"), 351fb9aa6f1SThomas Gleixner }, 352fb9aa6f1SThomas Gleixner }, 353fb9aa6f1SThomas Gleixner { 354fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 355fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL45p G1", 356fb9aa6f1SThomas Gleixner .matches = { 357fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 358fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"), 359fb9aa6f1SThomas Gleixner }, 360fb9aa6f1SThomas Gleixner }, 361fb9aa6f1SThomas Gleixner { 362fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 363fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL45p G2", 364fb9aa6f1SThomas Gleixner .matches = { 365fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 366fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"), 367fb9aa6f1SThomas Gleixner }, 368fb9aa6f1SThomas Gleixner }, 369fb9aa6f1SThomas Gleixner { 370fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 371fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL460c G1", 372fb9aa6f1SThomas Gleixner .matches = { 373fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 374fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"), 375fb9aa6f1SThomas Gleixner }, 376fb9aa6f1SThomas Gleixner }, 377fb9aa6f1SThomas Gleixner { 378fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 379fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL465c G1", 380fb9aa6f1SThomas Gleixner .matches = { 381fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 382fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"), 383fb9aa6f1SThomas Gleixner }, 384fb9aa6f1SThomas Gleixner }, 385fb9aa6f1SThomas Gleixner { 386fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 387fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL480c G1", 388fb9aa6f1SThomas Gleixner .matches = { 389fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 390fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"), 391fb9aa6f1SThomas Gleixner }, 392fb9aa6f1SThomas Gleixner }, 393fb9aa6f1SThomas Gleixner { 394fb9aa6f1SThomas Gleixner .callback = set_bf_sort, 395fb9aa6f1SThomas Gleixner .ident = "HP ProLiant BL685c G1", 396fb9aa6f1SThomas Gleixner .matches = { 397fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_SYS_VENDOR, "HP"), 398fb9aa6f1SThomas Gleixner DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), 399fb9aa6f1SThomas Gleixner }, 400fb9aa6f1SThomas Gleixner }, 4018f8ae1a7SMichal Schmidt { 4028f8ae1a7SMichal Schmidt .callback = set_bf_sort, 4038d64c781STony Camuso .ident = "HP ProLiant DL360", 4048f8ae1a7SMichal Schmidt .matches = { 4058f8ae1a7SMichal Schmidt DMI_MATCH(DMI_SYS_VENDOR, "HP"), 4068d64c781STony Camuso DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"), 4078f8ae1a7SMichal Schmidt }, 4088f8ae1a7SMichal Schmidt }, 4098f8ae1a7SMichal Schmidt { 4108f8ae1a7SMichal Schmidt .callback = set_bf_sort, 4118d64c781STony Camuso .ident = "HP ProLiant DL380", 4128f8ae1a7SMichal Schmidt .matches = { 4138f8ae1a7SMichal Schmidt DMI_MATCH(DMI_SYS_VENDOR, "HP"), 4148d64c781STony Camuso DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"), 4158f8ae1a7SMichal Schmidt }, 4168f8ae1a7SMichal Schmidt }, 4175b1ea82fSJuha Laiho #ifdef __i386__ 4185b1ea82fSJuha Laiho { 4195b1ea82fSJuha Laiho .callback = assign_all_busses, 4205b1ea82fSJuha Laiho .ident = "Compaq EVO N800c", 4215b1ea82fSJuha Laiho .matches = { 4225b1ea82fSJuha Laiho DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), 4235b1ea82fSJuha Laiho DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"), 4245b1ea82fSJuha Laiho }, 4255b1ea82fSJuha Laiho }, 4265b1ea82fSJuha Laiho #endif 427c82bc5adSMichal Schmidt { 428c82bc5adSMichal Schmidt .callback = set_bf_sort, 429739db07fSJesse Barnes .ident = "HP ProLiant DL385 G2", 430c82bc5adSMichal Schmidt .matches = { 431c82bc5adSMichal Schmidt DMI_MATCH(DMI_SYS_VENDOR, "HP"), 432739db07fSJesse Barnes DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"), 433c82bc5adSMichal Schmidt }, 434c82bc5adSMichal Schmidt }, 435c82bc5adSMichal Schmidt { 436c82bc5adSMichal Schmidt .callback = set_bf_sort, 437739db07fSJesse Barnes .ident = "HP ProLiant DL585 G2", 438c82bc5adSMichal Schmidt .matches = { 439c82bc5adSMichal Schmidt DMI_MATCH(DMI_SYS_VENDOR, "HP"), 440739db07fSJesse Barnes DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), 441c82bc5adSMichal Schmidt }, 442c82bc5adSMichal Schmidt }, 443284f5f9dSBjorn Helgaas { 444284f5f9dSBjorn Helgaas .callback = set_scan_all, 445284f5f9dSBjorn Helgaas .ident = "Stratus/NEC ftServer", 446284f5f9dSBjorn Helgaas .matches = { 4471278998fSMyron Stowe DMI_MATCH(DMI_SYS_VENDOR, "Stratus"), 4481278998fSMyron Stowe DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"), 449284f5f9dSBjorn Helgaas }, 450284f5f9dSBjorn Helgaas }, 45151ac3d2fSCharlotte Richardson { 45251ac3d2fSCharlotte Richardson .callback = set_scan_all, 45351ac3d2fSCharlotte Richardson .ident = "Stratus/NEC ftServer", 45451ac3d2fSCharlotte Richardson .matches = { 45551ac3d2fSCharlotte Richardson DMI_MATCH(DMI_SYS_VENDOR, "NEC"), 45651ac3d2fSCharlotte Richardson DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R32"), 45751ac3d2fSCharlotte Richardson }, 45851ac3d2fSCharlotte Richardson }, 45951ac3d2fSCharlotte Richardson { 46051ac3d2fSCharlotte Richardson .callback = set_scan_all, 46151ac3d2fSCharlotte Richardson .ident = "Stratus/NEC ftServer", 46251ac3d2fSCharlotte Richardson .matches = { 46351ac3d2fSCharlotte Richardson DMI_MATCH(DMI_SYS_VENDOR, "NEC"), 46451ac3d2fSCharlotte Richardson DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R31"), 46551ac3d2fSCharlotte Richardson }, 46651ac3d2fSCharlotte Richardson }, 467fb9aa6f1SThomas Gleixner {} 468fb9aa6f1SThomas Gleixner }; 469fb9aa6f1SThomas Gleixner 4700df18ff3SYinghai Lu void __init dmi_check_pciprobe(void) 4710df18ff3SYinghai Lu { 4720df18ff3SYinghai Lu dmi_check_system(pciprobe_dmi_table); 4730df18ff3SYinghai Lu } 4740df18ff3SYinghai Lu 47549886cf4SBjorn Helgaas void pcibios_scan_root(int busnum) 476fb9aa6f1SThomas Gleixner { 477289a24a6SBjorn Helgaas struct pci_bus *bus; 478289a24a6SBjorn Helgaas struct pci_sysdata *sd; 479289a24a6SBjorn Helgaas LIST_HEAD(resources); 480289a24a6SBjorn Helgaas 481289a24a6SBjorn Helgaas sd = kzalloc(sizeof(*sd), GFP_KERNEL); 482289a24a6SBjorn Helgaas if (!sd) { 483289a24a6SBjorn Helgaas printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum); 48449886cf4SBjorn Helgaas return; 485289a24a6SBjorn Helgaas } 4866616dbdfSBjorn Helgaas sd->node = x86_pci_root_bus_node(busnum); 487289a24a6SBjorn Helgaas x86_pci_root_bus_resources(busnum, &resources); 488289a24a6SBjorn Helgaas printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); 489289a24a6SBjorn Helgaas bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); 490289a24a6SBjorn Helgaas if (!bus) { 491289a24a6SBjorn Helgaas pci_free_resource_list(&resources); 492289a24a6SBjorn Helgaas kfree(sd); 493289a24a6SBjorn Helgaas } 494fb9aa6f1SThomas Gleixner } 495fb9aa6f1SThomas Gleixner 49644de3395SAlex Nixon void __init pcibios_set_cache_line_size(void) 497fb9aa6f1SThomas Gleixner { 498fb9aa6f1SThomas Gleixner struct cpuinfo_x86 *c = &boot_cpu_data; 499fb9aa6f1SThomas Gleixner 500fb9aa6f1SThomas Gleixner /* 50176b1a87bSDave Jones * Set PCI cacheline size to that of the CPU if the CPU has reported it. 50276b1a87bSDave Jones * (For older CPUs that don't support cpuid, we se it to 32 bytes 50376b1a87bSDave Jones * It's also good for 386/486s (which actually have 16) 504fb9aa6f1SThomas Gleixner * as quite a few PCI devices do not support smaller values. 505fb9aa6f1SThomas Gleixner */ 50676b1a87bSDave Jones if (c->x86_clflush_size > 0) { 50776b1a87bSDave Jones pci_dfl_cache_line_size = c->x86_clflush_size >> 2; 50876b1a87bSDave Jones printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n", 50976b1a87bSDave Jones pci_dfl_cache_line_size << 2); 51076b1a87bSDave Jones } else { 511ac1aa47bSJesse Barnes pci_dfl_cache_line_size = 32 >> 2; 51276b1a87bSDave Jones printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); 51376b1a87bSDave Jones } 51444de3395SAlex Nixon } 515fb9aa6f1SThomas Gleixner 51644de3395SAlex Nixon int __init pcibios_init(void) 51744de3395SAlex Nixon { 51844de3395SAlex Nixon if (!raw_pci_ops) { 51944de3395SAlex Nixon printk(KERN_WARNING "PCI: System does not support PCI\n"); 52044de3395SAlex Nixon return 0; 52144de3395SAlex Nixon } 52244de3395SAlex Nixon 52344de3395SAlex Nixon pcibios_set_cache_line_size(); 524fb9aa6f1SThomas Gleixner pcibios_resource_survey(); 525fb9aa6f1SThomas Gleixner 526fb9aa6f1SThomas Gleixner if (pci_bf_sort >= pci_force_bf) 527fb9aa6f1SThomas Gleixner pci_sort_breadthfirst(); 528fb9aa6f1SThomas Gleixner return 0; 529fb9aa6f1SThomas Gleixner } 530fb9aa6f1SThomas Gleixner 53115fa325bSMyron Stowe char *__init pcibios_setup(char *str) 532fb9aa6f1SThomas Gleixner { 533fb9aa6f1SThomas Gleixner if (!strcmp(str, "off")) { 534fb9aa6f1SThomas Gleixner pci_probe = 0; 535fb9aa6f1SThomas Gleixner return NULL; 536fb9aa6f1SThomas Gleixner } else if (!strcmp(str, "bfsort")) { 537fb9aa6f1SThomas Gleixner pci_bf_sort = pci_force_bf; 538fb9aa6f1SThomas Gleixner return NULL; 539fb9aa6f1SThomas Gleixner } else if (!strcmp(str, "nobfsort")) { 540fb9aa6f1SThomas Gleixner pci_bf_sort = pci_force_nobf; 541fb9aa6f1SThomas Gleixner return NULL; 542fb9aa6f1SThomas Gleixner } 543fb9aa6f1SThomas Gleixner #ifdef CONFIG_PCI_BIOS 544fb9aa6f1SThomas Gleixner else if (!strcmp(str, "bios")) { 545fb9aa6f1SThomas Gleixner pci_probe = PCI_PROBE_BIOS; 546fb9aa6f1SThomas Gleixner return NULL; 547fb9aa6f1SThomas Gleixner } else if (!strcmp(str, "nobios")) { 548fb9aa6f1SThomas Gleixner pci_probe &= ~PCI_PROBE_BIOS; 549fb9aa6f1SThomas Gleixner return NULL; 550fb9aa6f1SThomas Gleixner } else if (!strcmp(str, "biosirq")) { 551fb9aa6f1SThomas Gleixner pci_probe |= PCI_BIOS_IRQ_SCAN; 552fb9aa6f1SThomas Gleixner return NULL; 553fb9aa6f1SThomas Gleixner } else if (!strncmp(str, "pirqaddr=", 9)) { 554fb9aa6f1SThomas Gleixner pirq_table_addr = simple_strtoul(str+9, NULL, 0); 555fb9aa6f1SThomas Gleixner return NULL; 556fb9aa6f1SThomas Gleixner } 557fb9aa6f1SThomas Gleixner #endif 558fb9aa6f1SThomas Gleixner #ifdef CONFIG_PCI_DIRECT 559fb9aa6f1SThomas Gleixner else if (!strcmp(str, "conf1")) { 560fb9aa6f1SThomas Gleixner pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS; 561fb9aa6f1SThomas Gleixner return NULL; 562fb9aa6f1SThomas Gleixner } 563fb9aa6f1SThomas Gleixner else if (!strcmp(str, "conf2")) { 564fb9aa6f1SThomas Gleixner pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; 565fb9aa6f1SThomas Gleixner return NULL; 566fb9aa6f1SThomas Gleixner } 567fb9aa6f1SThomas Gleixner #endif 568fb9aa6f1SThomas Gleixner #ifdef CONFIG_PCI_MMCONFIG 569fb9aa6f1SThomas Gleixner else if (!strcmp(str, "nommconf")) { 570fb9aa6f1SThomas Gleixner pci_probe &= ~PCI_PROBE_MMCONF; 571fb9aa6f1SThomas Gleixner return NULL; 572fb9aa6f1SThomas Gleixner } 5735f0b2976SYinghai Lu else if (!strcmp(str, "check_enable_amd_mmconf")) { 5745f0b2976SYinghai Lu pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; 5755f0b2976SYinghai Lu return NULL; 5765f0b2976SYinghai Lu } 577fb9aa6f1SThomas Gleixner #endif 578fb9aa6f1SThomas Gleixner else if (!strcmp(str, "noacpi")) { 579fb9aa6f1SThomas Gleixner acpi_noirq_set(); 580fb9aa6f1SThomas Gleixner return NULL; 581fb9aa6f1SThomas Gleixner } 582fb9aa6f1SThomas Gleixner else if (!strcmp(str, "noearly")) { 583fb9aa6f1SThomas Gleixner pci_probe |= PCI_PROBE_NOEARLY; 584fb9aa6f1SThomas Gleixner return NULL; 585fb9aa6f1SThomas Gleixner } 586fb9aa6f1SThomas Gleixner else if (!strcmp(str, "usepirqmask")) { 587fb9aa6f1SThomas Gleixner pci_probe |= PCI_USE_PIRQ_MASK; 588fb9aa6f1SThomas Gleixner return NULL; 589fb9aa6f1SThomas Gleixner } else if (!strncmp(str, "irqmask=", 8)) { 590fb9aa6f1SThomas Gleixner pcibios_irq_mask = simple_strtol(str+8, NULL, 0); 591fb9aa6f1SThomas Gleixner return NULL; 592fb9aa6f1SThomas Gleixner } else if (!strncmp(str, "lastbus=", 8)) { 593fb9aa6f1SThomas Gleixner pcibios_last_bus = simple_strtol(str+8, NULL, 0); 594fb9aa6f1SThomas Gleixner return NULL; 595c5f9ee3dSH. Peter Anvin } else if (!strcmp(str, "rom")) { 596fb9aa6f1SThomas Gleixner pci_probe |= PCI_ASSIGN_ROMS; 597fb9aa6f1SThomas Gleixner return NULL; 598bb71ad88SGary Hade } else if (!strcmp(str, "norom")) { 599bb71ad88SGary Hade pci_probe |= PCI_NOASSIGN_ROMS; 600bb71ad88SGary Hade return NULL; 6017bd1c365SMike Habeck } else if (!strcmp(str, "nobar")) { 6027bd1c365SMike Habeck pci_probe |= PCI_NOASSIGN_BARS; 6037bd1c365SMike Habeck return NULL; 604fb9aa6f1SThomas Gleixner } else if (!strcmp(str, "assign-busses")) { 605fb9aa6f1SThomas Gleixner pci_probe |= PCI_ASSIGN_ALL_BUSSES; 606fb9aa6f1SThomas Gleixner return NULL; 607236e946bSLinus Torvalds } else if (!strcmp(str, "use_crs")) { 608236e946bSLinus Torvalds pci_probe |= PCI_USE__CRS; 60962f420f8SGary Hade return NULL; 6107bc5e3f2SBjorn Helgaas } else if (!strcmp(str, "nocrs")) { 6117bc5e3f2SBjorn Helgaas pci_probe |= PCI_ROOT_NO_CRS; 6127bc5e3f2SBjorn Helgaas return NULL; 613e3f2baebSYinghai Lu } else if (!strcmp(str, "earlydump")) { 614e3f2baebSYinghai Lu pci_early_dump_regs = 1; 615e3f2baebSYinghai Lu return NULL; 616fb9aa6f1SThomas Gleixner } else if (!strcmp(str, "routeirq")) { 617fb9aa6f1SThomas Gleixner pci_routeirq = 1; 618fb9aa6f1SThomas Gleixner return NULL; 61913a6ddb0SYinghai Lu } else if (!strcmp(str, "skip_isa_align")) { 62013a6ddb0SYinghai Lu pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 62113a6ddb0SYinghai Lu return NULL; 622a9322f64SStefan Assmann } else if (!strcmp(str, "noioapicquirk")) { 623a9322f64SStefan Assmann noioapicquirk = 1; 624a9322f64SStefan Assmann return NULL; 6259197979bSStefan Assmann } else if (!strcmp(str, "ioapicreroute")) { 6269197979bSStefan Assmann if (noioapicreroute != -1) 6279197979bSStefan Assmann noioapicreroute = 0; 6289197979bSStefan Assmann return NULL; 62941b9eb26SStefan Assmann } else if (!strcmp(str, "noioapicreroute")) { 63041b9eb26SStefan Assmann if (noioapicreroute != -1) 63141b9eb26SStefan Assmann noioapicreroute = 1; 63241b9eb26SStefan Assmann return NULL; 633fb9aa6f1SThomas Gleixner } 634fb9aa6f1SThomas Gleixner return str; 635fb9aa6f1SThomas Gleixner } 636fb9aa6f1SThomas Gleixner 637fb9aa6f1SThomas Gleixner unsigned int pcibios_assign_all_busses(void) 638fb9aa6f1SThomas Gleixner { 639fb9aa6f1SThomas Gleixner return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; 640fb9aa6f1SThomas Gleixner } 641fb9aa6f1SThomas Gleixner 642f9a37be0SMatthew Garrett int pcibios_add_device(struct pci_dev *dev) 643f9a37be0SMatthew Garrett { 644f9a37be0SMatthew Garrett struct setup_data *data; 645f9a37be0SMatthew Garrett struct pci_setup_rom *rom; 646f9a37be0SMatthew Garrett u64 pa_data; 647f9a37be0SMatthew Garrett 648f9a37be0SMatthew Garrett pa_data = boot_params.hdr.setup_data; 649f9a37be0SMatthew Garrett while (pa_data) { 65065694c5aSMatt Fleming data = ioremap(pa_data, sizeof(*rom)); 65165694c5aSMatt Fleming if (!data) 65265694c5aSMatt Fleming return -ENOMEM; 653f9a37be0SMatthew Garrett 654f9a37be0SMatthew Garrett if (data->type == SETUP_PCI) { 655f9a37be0SMatthew Garrett rom = (struct pci_setup_rom *)data; 656f9a37be0SMatthew Garrett 657f9a37be0SMatthew Garrett if ((pci_domain_nr(dev->bus) == rom->segment) && 658f9a37be0SMatthew Garrett (dev->bus->number == rom->bus) && 659f9a37be0SMatthew Garrett (PCI_SLOT(dev->devfn) == rom->device) && 660f9a37be0SMatthew Garrett (PCI_FUNC(dev->devfn) == rom->function) && 661f9a37be0SMatthew Garrett (dev->vendor == rom->vendor) && 662f9a37be0SMatthew Garrett (dev->device == rom->devid)) { 663dbd3fc33SBjorn Helgaas dev->rom = pa_data + 664dbd3fc33SBjorn Helgaas offsetof(struct pci_setup_rom, romdata); 665f9a37be0SMatthew Garrett dev->romlen = rom->pcilen; 666f9a37be0SMatthew Garrett } 667f9a37be0SMatthew Garrett } 668f9a37be0SMatthew Garrett pa_data = data->next; 66965694c5aSMatt Fleming iounmap(data); 670f9a37be0SMatthew Garrett } 671f9a37be0SMatthew Garrett return 0; 672f9a37be0SMatthew Garrett } 673f9a37be0SMatthew Garrett 674fb9aa6f1SThomas Gleixner int pcibios_enable_device(struct pci_dev *dev, int mask) 675fb9aa6f1SThomas Gleixner { 676fb9aa6f1SThomas Gleixner int err; 677fb9aa6f1SThomas Gleixner 678b81d988cSBjorn Helgaas if ((err = pci_enable_resources(dev, mask)) < 0) 679fb9aa6f1SThomas Gleixner return err; 680fb9aa6f1SThomas Gleixner 68116cf0ebcSRafael J. Wysocki if (!pci_dev_msi_enabled(dev)) 682fb9aa6f1SThomas Gleixner return pcibios_enable_irq(dev); 683fb9aa6f1SThomas Gleixner return 0; 684fb9aa6f1SThomas Gleixner } 685fb9aa6f1SThomas Gleixner 686fb9aa6f1SThomas Gleixner void pcibios_disable_device (struct pci_dev *dev) 687fb9aa6f1SThomas Gleixner { 68816cf0ebcSRafael J. Wysocki if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) 689fb9aa6f1SThomas Gleixner pcibios_disable_irq(dev); 690fb9aa6f1SThomas Gleixner } 691fb9aa6f1SThomas Gleixner 692642c92daSTaku Izumi int pci_ext_cfg_avail(void) 6930ef5f8f6SAndrew Patterson { 6940ef5f8f6SAndrew Patterson if (raw_pci_ext_ops) 6950ef5f8f6SAndrew Patterson return 1; 6960ef5f8f6SAndrew Patterson else 6970ef5f8f6SAndrew Patterson return 0; 6980ef5f8f6SAndrew Patterson } 699