18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * PCI detection and setup code 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/kernel.h> 78c2ecf20Sopenharmony_ci#include <linux/delay.h> 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/pci.h> 108c2ecf20Sopenharmony_ci#include <linux/msi.h> 118c2ecf20Sopenharmony_ci#include <linux/of_device.h> 128c2ecf20Sopenharmony_ci#include <linux/of_pci.h> 138c2ecf20Sopenharmony_ci#include <linux/pci_hotplug.h> 148c2ecf20Sopenharmony_ci#include <linux/slab.h> 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci#include <linux/cpumask.h> 178c2ecf20Sopenharmony_ci#include <linux/aer.h> 188c2ecf20Sopenharmony_ci#include <linux/acpi.h> 198c2ecf20Sopenharmony_ci#include <linux/hypervisor.h> 208c2ecf20Sopenharmony_ci#include <linux/irqdomain.h> 218c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h> 228c2ecf20Sopenharmony_ci#include "pci.h" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ 258c2ecf20Sopenharmony_ci#define CARDBUS_RESERVE_BUSNR 3 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic struct resource busn_resource = { 288c2ecf20Sopenharmony_ci .name = "PCI busn", 298c2ecf20Sopenharmony_ci .start = 0, 308c2ecf20Sopenharmony_ci .end = 255, 318c2ecf20Sopenharmony_ci .flags = IORESOURCE_BUS, 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci/* Ugh. Need to stop exporting this to modules. */ 358c2ecf20Sopenharmony_ciLIST_HEAD(pci_root_buses); 368c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_root_buses); 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic LIST_HEAD(pci_domain_busn_res_list); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistruct pci_domain_busn_res { 418c2ecf20Sopenharmony_ci struct list_head list; 428c2ecf20Sopenharmony_ci struct resource res; 438c2ecf20Sopenharmony_ci int domain_nr; 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic struct resource *get_pci_domain_busn_res(int domain_nr) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci struct pci_domain_busn_res *r; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci list_for_each_entry(r, &pci_domain_busn_res_list, list) 518c2ecf20Sopenharmony_ci if (r->domain_nr == domain_nr) 528c2ecf20Sopenharmony_ci return &r->res; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci r = kzalloc(sizeof(*r), GFP_KERNEL); 558c2ecf20Sopenharmony_ci if (!r) 568c2ecf20Sopenharmony_ci return NULL; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci r->domain_nr = domain_nr; 598c2ecf20Sopenharmony_ci r->res.start = 0; 608c2ecf20Sopenharmony_ci r->res.end = 0xff; 618c2ecf20Sopenharmony_ci r->res.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci list_add_tail(&r->list, &pci_domain_busn_res_list); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return &r->res; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * Some device drivers need know if PCI is initiated. 708c2ecf20Sopenharmony_ci * Basically, we think PCI is not initiated when there 718c2ecf20Sopenharmony_ci * is no device to be found on the pci_bus_type. 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ciint no_pci_devices(void) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci struct device *dev; 768c2ecf20Sopenharmony_ci int no_devices; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci dev = bus_find_next_device(&pci_bus_type, NULL); 798c2ecf20Sopenharmony_ci no_devices = (dev == NULL); 808c2ecf20Sopenharmony_ci put_device(dev); 818c2ecf20Sopenharmony_ci return no_devices; 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ciEXPORT_SYMBOL(no_pci_devices); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci/* 868c2ecf20Sopenharmony_ci * PCI Bus Class 878c2ecf20Sopenharmony_ci */ 888c2ecf20Sopenharmony_cistatic void release_pcibus_dev(struct device *dev) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci struct pci_bus *pci_bus = to_pci_bus(dev); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci put_device(pci_bus->bridge); 938c2ecf20Sopenharmony_ci pci_bus_remove_resources(pci_bus); 948c2ecf20Sopenharmony_ci pci_release_bus_of_node(pci_bus); 958c2ecf20Sopenharmony_ci kfree(pci_bus); 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic struct class pcibus_class = { 998c2ecf20Sopenharmony_ci .name = "pci_bus", 1008c2ecf20Sopenharmony_ci .dev_release = &release_pcibus_dev, 1018c2ecf20Sopenharmony_ci .dev_groups = pcibus_groups, 1028c2ecf20Sopenharmony_ci}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic int __init pcibus_class_init(void) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci return class_register(&pcibus_class); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_cipostcore_initcall(pcibus_class_init); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic u64 pci_size(u64 base, u64 maxbase, u64 mask) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci u64 size = mask & maxbase; /* Find the significant bits */ 1138c2ecf20Sopenharmony_ci if (!size) 1148c2ecf20Sopenharmony_ci return 0; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* 1178c2ecf20Sopenharmony_ci * Get the lowest of them to find the decode size, and from that 1188c2ecf20Sopenharmony_ci * the extent. 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ci size = size & ~(size-1); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci /* 1238c2ecf20Sopenharmony_ci * base == maxbase can be valid only if the BAR has already been 1248c2ecf20Sopenharmony_ci * programmed with all 1s. 1258c2ecf20Sopenharmony_ci */ 1268c2ecf20Sopenharmony_ci if (base == maxbase && ((base | (size - 1)) & mask) != mask) 1278c2ecf20Sopenharmony_ci return 0; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci return size; 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic inline unsigned long decode_bar(struct pci_dev *dev, u32 bar) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci u32 mem_type; 1358c2ecf20Sopenharmony_ci unsigned long flags; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { 1388c2ecf20Sopenharmony_ci flags = bar & ~PCI_BASE_ADDRESS_IO_MASK; 1398c2ecf20Sopenharmony_ci flags |= IORESOURCE_IO; 1408c2ecf20Sopenharmony_ci return flags; 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK; 1448c2ecf20Sopenharmony_ci flags |= IORESOURCE_MEM; 1458c2ecf20Sopenharmony_ci if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH) 1468c2ecf20Sopenharmony_ci flags |= IORESOURCE_PREFETCH; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci mem_type = bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK; 1498c2ecf20Sopenharmony_ci switch (mem_type) { 1508c2ecf20Sopenharmony_ci case PCI_BASE_ADDRESS_MEM_TYPE_32: 1518c2ecf20Sopenharmony_ci break; 1528c2ecf20Sopenharmony_ci case PCI_BASE_ADDRESS_MEM_TYPE_1M: 1538c2ecf20Sopenharmony_ci /* 1M mem BAR treated as 32-bit BAR */ 1548c2ecf20Sopenharmony_ci break; 1558c2ecf20Sopenharmony_ci case PCI_BASE_ADDRESS_MEM_TYPE_64: 1568c2ecf20Sopenharmony_ci flags |= IORESOURCE_MEM_64; 1578c2ecf20Sopenharmony_ci break; 1588c2ecf20Sopenharmony_ci default: 1598c2ecf20Sopenharmony_ci /* mem unknown type treated as 32-bit BAR */ 1608c2ecf20Sopenharmony_ci break; 1618c2ecf20Sopenharmony_ci } 1628c2ecf20Sopenharmony_ci return flags; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci#define PCI_COMMAND_DECODE_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_IO) 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci/** 1688c2ecf20Sopenharmony_ci * pci_read_base - Read a PCI BAR 1698c2ecf20Sopenharmony_ci * @dev: the PCI device 1708c2ecf20Sopenharmony_ci * @type: type of the BAR 1718c2ecf20Sopenharmony_ci * @res: resource buffer to be filled in 1728c2ecf20Sopenharmony_ci * @pos: BAR position in the config space 1738c2ecf20Sopenharmony_ci * 1748c2ecf20Sopenharmony_ci * Returns 1 if the BAR is 64-bit, or 0 if 32-bit. 1758c2ecf20Sopenharmony_ci */ 1768c2ecf20Sopenharmony_ciint __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, 1778c2ecf20Sopenharmony_ci struct resource *res, unsigned int pos) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci u32 l = 0, sz = 0, mask; 1808c2ecf20Sopenharmony_ci u64 l64, sz64, mask64; 1818c2ecf20Sopenharmony_ci u16 orig_cmd; 1828c2ecf20Sopenharmony_ci struct pci_bus_region region, inverted_region; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci mask = type ? PCI_ROM_ADDRESS_MASK : ~0; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci /* No printks while decoding is disabled! */ 1878c2ecf20Sopenharmony_ci if (!dev->mmio_always_on) { 1888c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); 1898c2ecf20Sopenharmony_ci if (orig_cmd & PCI_COMMAND_DECODE_ENABLE) { 1908c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, 1918c2ecf20Sopenharmony_ci orig_cmd & ~PCI_COMMAND_DECODE_ENABLE); 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci res->name = pci_name(dev); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci pci_read_config_dword(dev, pos, &l); 1988c2ecf20Sopenharmony_ci pci_write_config_dword(dev, pos, l | mask); 1998c2ecf20Sopenharmony_ci pci_read_config_dword(dev, pos, &sz); 2008c2ecf20Sopenharmony_ci pci_write_config_dword(dev, pos, l); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci /* 2038c2ecf20Sopenharmony_ci * All bits set in sz means the device isn't working properly. 2048c2ecf20Sopenharmony_ci * If the BAR isn't implemented, all bits must be 0. If it's a 2058c2ecf20Sopenharmony_ci * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit 2068c2ecf20Sopenharmony_ci * 1 must be clear. 2078c2ecf20Sopenharmony_ci */ 2088c2ecf20Sopenharmony_ci if (sz == 0xffffffff) 2098c2ecf20Sopenharmony_ci sz = 0; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci /* 2128c2ecf20Sopenharmony_ci * I don't know how l can have all bits set. Copied from old code. 2138c2ecf20Sopenharmony_ci * Maybe it fixes a bug on some ancient platform. 2148c2ecf20Sopenharmony_ci */ 2158c2ecf20Sopenharmony_ci if (l == 0xffffffff) 2168c2ecf20Sopenharmony_ci l = 0; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci if (type == pci_bar_unknown) { 2198c2ecf20Sopenharmony_ci res->flags = decode_bar(dev, l); 2208c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_SIZEALIGN; 2218c2ecf20Sopenharmony_ci if (res->flags & IORESOURCE_IO) { 2228c2ecf20Sopenharmony_ci l64 = l & PCI_BASE_ADDRESS_IO_MASK; 2238c2ecf20Sopenharmony_ci sz64 = sz & PCI_BASE_ADDRESS_IO_MASK; 2248c2ecf20Sopenharmony_ci mask64 = PCI_BASE_ADDRESS_IO_MASK & (u32)IO_SPACE_LIMIT; 2258c2ecf20Sopenharmony_ci } else { 2268c2ecf20Sopenharmony_ci l64 = l & PCI_BASE_ADDRESS_MEM_MASK; 2278c2ecf20Sopenharmony_ci sz64 = sz & PCI_BASE_ADDRESS_MEM_MASK; 2288c2ecf20Sopenharmony_ci mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK; 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci } else { 2318c2ecf20Sopenharmony_ci if (l & PCI_ROM_ADDRESS_ENABLE) 2328c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_ROM_ENABLE; 2338c2ecf20Sopenharmony_ci l64 = l & PCI_ROM_ADDRESS_MASK; 2348c2ecf20Sopenharmony_ci sz64 = sz & PCI_ROM_ADDRESS_MASK; 2358c2ecf20Sopenharmony_ci mask64 = PCI_ROM_ADDRESS_MASK; 2368c2ecf20Sopenharmony_ci } 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci if (res->flags & IORESOURCE_MEM_64) { 2398c2ecf20Sopenharmony_ci pci_read_config_dword(dev, pos + 4, &l); 2408c2ecf20Sopenharmony_ci pci_write_config_dword(dev, pos + 4, ~0); 2418c2ecf20Sopenharmony_ci pci_read_config_dword(dev, pos + 4, &sz); 2428c2ecf20Sopenharmony_ci pci_write_config_dword(dev, pos + 4, l); 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci l64 |= ((u64)l << 32); 2458c2ecf20Sopenharmony_ci sz64 |= ((u64)sz << 32); 2468c2ecf20Sopenharmony_ci mask64 |= ((u64)~0 << 32); 2478c2ecf20Sopenharmony_ci } 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci if (!dev->mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE)) 2508c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, orig_cmd); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci if (!sz64) 2538c2ecf20Sopenharmony_ci goto fail; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci sz64 = pci_size(l64, sz64, mask64); 2568c2ecf20Sopenharmony_ci if (!sz64) { 2578c2ecf20Sopenharmony_ci pci_info(dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n", 2588c2ecf20Sopenharmony_ci pos); 2598c2ecf20Sopenharmony_ci goto fail; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci if (res->flags & IORESOURCE_MEM_64) { 2638c2ecf20Sopenharmony_ci if ((sizeof(pci_bus_addr_t) < 8 || sizeof(resource_size_t) < 8) 2648c2ecf20Sopenharmony_ci && sz64 > 0x100000000ULL) { 2658c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; 2668c2ecf20Sopenharmony_ci res->start = 0; 2678c2ecf20Sopenharmony_ci res->end = 0; 2688c2ecf20Sopenharmony_ci pci_err(dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n", 2698c2ecf20Sopenharmony_ci pos, (unsigned long long)sz64); 2708c2ecf20Sopenharmony_ci goto out; 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci if ((sizeof(pci_bus_addr_t) < 8) && l) { 2748c2ecf20Sopenharmony_ci /* Above 32-bit boundary; try to reallocate */ 2758c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_UNSET; 2768c2ecf20Sopenharmony_ci res->start = 0; 2778c2ecf20Sopenharmony_ci res->end = sz64 - 1; 2788c2ecf20Sopenharmony_ci pci_info(dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n", 2798c2ecf20Sopenharmony_ci pos, (unsigned long long)l64); 2808c2ecf20Sopenharmony_ci goto out; 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci } 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci region.start = l64; 2858c2ecf20Sopenharmony_ci region.end = l64 + sz64 - 1; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 2888c2ecf20Sopenharmony_ci pcibios_resource_to_bus(dev->bus, &inverted_region, res); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci /* 2918c2ecf20Sopenharmony_ci * If "A" is a BAR value (a bus address), "bus_to_resource(A)" is 2928c2ecf20Sopenharmony_ci * the corresponding resource address (the physical address used by 2938c2ecf20Sopenharmony_ci * the CPU. Converting that resource address back to a bus address 2948c2ecf20Sopenharmony_ci * should yield the original BAR value: 2958c2ecf20Sopenharmony_ci * 2968c2ecf20Sopenharmony_ci * resource_to_bus(bus_to_resource(A)) == A 2978c2ecf20Sopenharmony_ci * 2988c2ecf20Sopenharmony_ci * If it doesn't, CPU accesses to "bus_to_resource(A)" will not 2998c2ecf20Sopenharmony_ci * be claimed by the device. 3008c2ecf20Sopenharmony_ci */ 3018c2ecf20Sopenharmony_ci if (inverted_region.start != region.start) { 3028c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_UNSET; 3038c2ecf20Sopenharmony_ci res->start = 0; 3048c2ecf20Sopenharmony_ci res->end = region.end - region.start; 3058c2ecf20Sopenharmony_ci pci_info(dev, "reg 0x%x: initial BAR value %#010llx invalid\n", 3068c2ecf20Sopenharmony_ci pos, (unsigned long long)region.start); 3078c2ecf20Sopenharmony_ci } 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci goto out; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cifail: 3138c2ecf20Sopenharmony_ci res->flags = 0; 3148c2ecf20Sopenharmony_ciout: 3158c2ecf20Sopenharmony_ci if (res->flags) 3168c2ecf20Sopenharmony_ci pci_info(dev, "reg 0x%x: %pR\n", pos, res); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistatic void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) 3228c2ecf20Sopenharmony_ci{ 3238c2ecf20Sopenharmony_ci unsigned int pos, reg; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci if (dev->non_compliant_bars) 3268c2ecf20Sopenharmony_ci return; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci /* Per PCIe r4.0, sec 9.3.4.1.11, the VF BARs are all RO Zero */ 3298c2ecf20Sopenharmony_ci if (dev->is_virtfn) 3308c2ecf20Sopenharmony_ci return; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci for (pos = 0; pos < howmany; pos++) { 3338c2ecf20Sopenharmony_ci struct resource *res = &dev->resource[pos]; 3348c2ecf20Sopenharmony_ci reg = PCI_BASE_ADDRESS_0 + (pos << 2); 3358c2ecf20Sopenharmony_ci pos += __pci_read_base(dev, pci_bar_unknown, res, reg); 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci if (rom) { 3398c2ecf20Sopenharmony_ci struct resource *res = &dev->resource[PCI_ROM_RESOURCE]; 3408c2ecf20Sopenharmony_ci dev->rom_base_reg = rom; 3418c2ecf20Sopenharmony_ci res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | 3428c2ecf20Sopenharmony_ci IORESOURCE_READONLY | IORESOURCE_SIZEALIGN; 3438c2ecf20Sopenharmony_ci __pci_read_base(dev, pci_bar_mem32, res, rom); 3448c2ecf20Sopenharmony_ci } 3458c2ecf20Sopenharmony_ci} 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistatic void pci_read_bridge_windows(struct pci_dev *bridge) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci u16 io; 3508c2ecf20Sopenharmony_ci u32 pmem, tmp; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci pci_read_config_word(bridge, PCI_IO_BASE, &io); 3538c2ecf20Sopenharmony_ci if (!io) { 3548c2ecf20Sopenharmony_ci pci_write_config_word(bridge, PCI_IO_BASE, 0xe0f0); 3558c2ecf20Sopenharmony_ci pci_read_config_word(bridge, PCI_IO_BASE, &io); 3568c2ecf20Sopenharmony_ci pci_write_config_word(bridge, PCI_IO_BASE, 0x0); 3578c2ecf20Sopenharmony_ci } 3588c2ecf20Sopenharmony_ci if (io) 3598c2ecf20Sopenharmony_ci bridge->io_window = 1; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci /* 3628c2ecf20Sopenharmony_ci * DECchip 21050 pass 2 errata: the bridge may miss an address 3638c2ecf20Sopenharmony_ci * disconnect boundary by one PCI data phase. Workaround: do not 3648c2ecf20Sopenharmony_ci * use prefetching on this device. 3658c2ecf20Sopenharmony_ci */ 3668c2ecf20Sopenharmony_ci if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001) 3678c2ecf20Sopenharmony_ci return; 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); 3708c2ecf20Sopenharmony_ci if (!pmem) { 3718c2ecf20Sopenharmony_ci pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 3728c2ecf20Sopenharmony_ci 0xffe0fff0); 3738c2ecf20Sopenharmony_ci pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); 3748c2ecf20Sopenharmony_ci pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); 3758c2ecf20Sopenharmony_ci } 3768c2ecf20Sopenharmony_ci if (!pmem) 3778c2ecf20Sopenharmony_ci return; 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci bridge->pref_window = 1; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci /* 3848c2ecf20Sopenharmony_ci * Bridge claims to have a 64-bit prefetchable memory 3858c2ecf20Sopenharmony_ci * window; verify that the upper bits are actually 3868c2ecf20Sopenharmony_ci * writable. 3878c2ecf20Sopenharmony_ci */ 3888c2ecf20Sopenharmony_ci pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &pmem); 3898c2ecf20Sopenharmony_ci pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 3908c2ecf20Sopenharmony_ci 0xffffffff); 3918c2ecf20Sopenharmony_ci pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp); 3928c2ecf20Sopenharmony_ci pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, pmem); 3938c2ecf20Sopenharmony_ci if (tmp) 3948c2ecf20Sopenharmony_ci bridge->pref_64_window = 1; 3958c2ecf20Sopenharmony_ci } 3968c2ecf20Sopenharmony_ci} 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_cistatic void pci_read_bridge_io(struct pci_bus *child) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci struct pci_dev *dev = child->self; 4018c2ecf20Sopenharmony_ci u8 io_base_lo, io_limit_lo; 4028c2ecf20Sopenharmony_ci unsigned long io_mask, io_granularity, base, limit; 4038c2ecf20Sopenharmony_ci struct pci_bus_region region; 4048c2ecf20Sopenharmony_ci struct resource *res; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci io_mask = PCI_IO_RANGE_MASK; 4078c2ecf20Sopenharmony_ci io_granularity = 0x1000; 4088c2ecf20Sopenharmony_ci if (dev->io_window_1k) { 4098c2ecf20Sopenharmony_ci /* Support 1K I/O space granularity */ 4108c2ecf20Sopenharmony_ci io_mask = PCI_IO_1K_RANGE_MASK; 4118c2ecf20Sopenharmony_ci io_granularity = 0x400; 4128c2ecf20Sopenharmony_ci } 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci res = child->resource[0]; 4158c2ecf20Sopenharmony_ci pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); 4168c2ecf20Sopenharmony_ci pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); 4178c2ecf20Sopenharmony_ci base = (io_base_lo & io_mask) << 8; 4188c2ecf20Sopenharmony_ci limit = (io_limit_lo & io_mask) << 8; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { 4218c2ecf20Sopenharmony_ci u16 io_base_hi, io_limit_hi; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi); 4248c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi); 4258c2ecf20Sopenharmony_ci base |= ((unsigned long) io_base_hi << 16); 4268c2ecf20Sopenharmony_ci limit |= ((unsigned long) io_limit_hi << 16); 4278c2ecf20Sopenharmony_ci } 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci if (base <= limit) { 4308c2ecf20Sopenharmony_ci res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; 4318c2ecf20Sopenharmony_ci region.start = base; 4328c2ecf20Sopenharmony_ci region.end = limit + io_granularity - 1; 4338c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 4348c2ecf20Sopenharmony_ci pci_info(dev, " bridge window %pR\n", res); 4358c2ecf20Sopenharmony_ci } 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic void pci_read_bridge_mmio(struct pci_bus *child) 4398c2ecf20Sopenharmony_ci{ 4408c2ecf20Sopenharmony_ci struct pci_dev *dev = child->self; 4418c2ecf20Sopenharmony_ci u16 mem_base_lo, mem_limit_lo; 4428c2ecf20Sopenharmony_ci unsigned long base, limit; 4438c2ecf20Sopenharmony_ci struct pci_bus_region region; 4448c2ecf20Sopenharmony_ci struct resource *res; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci res = child->resource[1]; 4478c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); 4488c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); 4498c2ecf20Sopenharmony_ci base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; 4508c2ecf20Sopenharmony_ci limit = ((unsigned long) mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; 4518c2ecf20Sopenharmony_ci if (base <= limit) { 4528c2ecf20Sopenharmony_ci res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; 4538c2ecf20Sopenharmony_ci region.start = base; 4548c2ecf20Sopenharmony_ci region.end = limit + 0xfffff; 4558c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 4568c2ecf20Sopenharmony_ci pci_info(dev, " bridge window %pR\n", res); 4578c2ecf20Sopenharmony_ci } 4588c2ecf20Sopenharmony_ci} 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_cistatic void pci_read_bridge_mmio_pref(struct pci_bus *child) 4618c2ecf20Sopenharmony_ci{ 4628c2ecf20Sopenharmony_ci struct pci_dev *dev = child->self; 4638c2ecf20Sopenharmony_ci u16 mem_base_lo, mem_limit_lo; 4648c2ecf20Sopenharmony_ci u64 base64, limit64; 4658c2ecf20Sopenharmony_ci pci_bus_addr_t base, limit; 4668c2ecf20Sopenharmony_ci struct pci_bus_region region; 4678c2ecf20Sopenharmony_ci struct resource *res; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci res = child->resource[2]; 4708c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); 4718c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); 4728c2ecf20Sopenharmony_ci base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; 4738c2ecf20Sopenharmony_ci limit64 = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { 4768c2ecf20Sopenharmony_ci u32 mem_base_hi, mem_limit_hi; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); 4798c2ecf20Sopenharmony_ci pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci /* 4828c2ecf20Sopenharmony_ci * Some bridges set the base > limit by default, and some 4838c2ecf20Sopenharmony_ci * (broken) BIOSes do not initialize them. If we find 4848c2ecf20Sopenharmony_ci * this, just assume they are not being used. 4858c2ecf20Sopenharmony_ci */ 4868c2ecf20Sopenharmony_ci if (mem_base_hi <= mem_limit_hi) { 4878c2ecf20Sopenharmony_ci base64 |= (u64) mem_base_hi << 32; 4888c2ecf20Sopenharmony_ci limit64 |= (u64) mem_limit_hi << 32; 4898c2ecf20Sopenharmony_ci } 4908c2ecf20Sopenharmony_ci } 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci base = (pci_bus_addr_t) base64; 4938c2ecf20Sopenharmony_ci limit = (pci_bus_addr_t) limit64; 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci if (base != base64) { 4968c2ecf20Sopenharmony_ci pci_err(dev, "can't handle bridge window above 4GB (bus address %#010llx)\n", 4978c2ecf20Sopenharmony_ci (unsigned long long) base64); 4988c2ecf20Sopenharmony_ci return; 4998c2ecf20Sopenharmony_ci } 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci if (base <= limit) { 5028c2ecf20Sopenharmony_ci res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | 5038c2ecf20Sopenharmony_ci IORESOURCE_MEM | IORESOURCE_PREFETCH; 5048c2ecf20Sopenharmony_ci if (res->flags & PCI_PREF_RANGE_TYPE_64) 5058c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_MEM_64; 5068c2ecf20Sopenharmony_ci region.start = base; 5078c2ecf20Sopenharmony_ci region.end = limit + 0xfffff; 5088c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 5098c2ecf20Sopenharmony_ci pci_info(dev, " bridge window %pR\n", res); 5108c2ecf20Sopenharmony_ci } 5118c2ecf20Sopenharmony_ci} 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_civoid pci_read_bridge_bases(struct pci_bus *child) 5148c2ecf20Sopenharmony_ci{ 5158c2ecf20Sopenharmony_ci struct pci_dev *dev = child->self; 5168c2ecf20Sopenharmony_ci struct resource *res; 5178c2ecf20Sopenharmony_ci int i; 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ 5208c2ecf20Sopenharmony_ci return; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci pci_info(dev, "PCI bridge to %pR%s\n", 5238c2ecf20Sopenharmony_ci &child->busn_res, 5248c2ecf20Sopenharmony_ci dev->transparent ? " (subtractive decode)" : ""); 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci pci_bus_remove_resources(child); 5278c2ecf20Sopenharmony_ci for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) 5288c2ecf20Sopenharmony_ci child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i]; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci pci_read_bridge_io(child); 5318c2ecf20Sopenharmony_ci pci_read_bridge_mmio(child); 5328c2ecf20Sopenharmony_ci pci_read_bridge_mmio_pref(child); 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci if (dev->transparent) { 5358c2ecf20Sopenharmony_ci pci_bus_for_each_resource(child->parent, res, i) { 5368c2ecf20Sopenharmony_ci if (res && res->flags) { 5378c2ecf20Sopenharmony_ci pci_bus_add_resource(child, res, 5388c2ecf20Sopenharmony_ci PCI_SUBTRACTIVE_DECODE); 5398c2ecf20Sopenharmony_ci pci_info(dev, " bridge window %pR (subtractive decode)\n", 5408c2ecf20Sopenharmony_ci res); 5418c2ecf20Sopenharmony_ci } 5428c2ecf20Sopenharmony_ci } 5438c2ecf20Sopenharmony_ci } 5448c2ecf20Sopenharmony_ci} 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_cistatic struct pci_bus *pci_alloc_bus(struct pci_bus *parent) 5478c2ecf20Sopenharmony_ci{ 5488c2ecf20Sopenharmony_ci struct pci_bus *b; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci b = kzalloc(sizeof(*b), GFP_KERNEL); 5518c2ecf20Sopenharmony_ci if (!b) 5528c2ecf20Sopenharmony_ci return NULL; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&b->node); 5558c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&b->children); 5568c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&b->devices); 5578c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&b->slots); 5588c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&b->resources); 5598c2ecf20Sopenharmony_ci b->max_bus_speed = PCI_SPEED_UNKNOWN; 5608c2ecf20Sopenharmony_ci b->cur_bus_speed = PCI_SPEED_UNKNOWN; 5618c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_DOMAINS_GENERIC 5628c2ecf20Sopenharmony_ci if (parent) 5638c2ecf20Sopenharmony_ci b->domain_nr = parent->domain_nr; 5648c2ecf20Sopenharmony_ci#endif 5658c2ecf20Sopenharmony_ci return b; 5668c2ecf20Sopenharmony_ci} 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_cistatic void pci_release_host_bridge_dev(struct device *dev) 5698c2ecf20Sopenharmony_ci{ 5708c2ecf20Sopenharmony_ci struct pci_host_bridge *bridge = to_pci_host_bridge(dev); 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci if (bridge->release_fn) 5738c2ecf20Sopenharmony_ci bridge->release_fn(bridge); 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci pci_free_resource_list(&bridge->windows); 5768c2ecf20Sopenharmony_ci pci_free_resource_list(&bridge->dma_ranges); 5778c2ecf20Sopenharmony_ci kfree(bridge); 5788c2ecf20Sopenharmony_ci} 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_cistatic void pci_init_host_bridge(struct pci_host_bridge *bridge) 5818c2ecf20Sopenharmony_ci{ 5828c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&bridge->windows); 5838c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&bridge->dma_ranges); 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci /* 5868c2ecf20Sopenharmony_ci * We assume we can manage these PCIe features. Some systems may 5878c2ecf20Sopenharmony_ci * reserve these for use by the platform itself, e.g., an ACPI BIOS 5888c2ecf20Sopenharmony_ci * may implement its own AER handling and use _OSC to prevent the 5898c2ecf20Sopenharmony_ci * OS from interfering. 5908c2ecf20Sopenharmony_ci */ 5918c2ecf20Sopenharmony_ci bridge->native_aer = 1; 5928c2ecf20Sopenharmony_ci bridge->native_pcie_hotplug = 1; 5938c2ecf20Sopenharmony_ci bridge->native_shpc_hotplug = 1; 5948c2ecf20Sopenharmony_ci bridge->native_pme = 1; 5958c2ecf20Sopenharmony_ci bridge->native_ltr = 1; 5968c2ecf20Sopenharmony_ci bridge->native_dpc = 1; 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci device_initialize(&bridge->dev); 5998c2ecf20Sopenharmony_ci} 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_cistruct pci_host_bridge *pci_alloc_host_bridge(size_t priv) 6028c2ecf20Sopenharmony_ci{ 6038c2ecf20Sopenharmony_ci struct pci_host_bridge *bridge; 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci bridge = kzalloc(sizeof(*bridge) + priv, GFP_KERNEL); 6068c2ecf20Sopenharmony_ci if (!bridge) 6078c2ecf20Sopenharmony_ci return NULL; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci pci_init_host_bridge(bridge); 6108c2ecf20Sopenharmony_ci bridge->dev.release = pci_release_host_bridge_dev; 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci return bridge; 6138c2ecf20Sopenharmony_ci} 6148c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_alloc_host_bridge); 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_cistatic void devm_pci_alloc_host_bridge_release(void *data) 6178c2ecf20Sopenharmony_ci{ 6188c2ecf20Sopenharmony_ci pci_free_host_bridge(data); 6198c2ecf20Sopenharmony_ci} 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_cistruct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev, 6228c2ecf20Sopenharmony_ci size_t priv) 6238c2ecf20Sopenharmony_ci{ 6248c2ecf20Sopenharmony_ci int ret; 6258c2ecf20Sopenharmony_ci struct pci_host_bridge *bridge; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci bridge = pci_alloc_host_bridge(priv); 6288c2ecf20Sopenharmony_ci if (!bridge) 6298c2ecf20Sopenharmony_ci return NULL; 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci bridge->dev.parent = dev; 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci ret = devm_add_action_or_reset(dev, devm_pci_alloc_host_bridge_release, 6348c2ecf20Sopenharmony_ci bridge); 6358c2ecf20Sopenharmony_ci if (ret) 6368c2ecf20Sopenharmony_ci return NULL; 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci ret = devm_of_pci_bridge_init(dev, bridge); 6398c2ecf20Sopenharmony_ci if (ret) 6408c2ecf20Sopenharmony_ci return NULL; 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci return bridge; 6438c2ecf20Sopenharmony_ci} 6448c2ecf20Sopenharmony_ciEXPORT_SYMBOL(devm_pci_alloc_host_bridge); 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_civoid pci_free_host_bridge(struct pci_host_bridge *bridge) 6478c2ecf20Sopenharmony_ci{ 6488c2ecf20Sopenharmony_ci put_device(&bridge->dev); 6498c2ecf20Sopenharmony_ci} 6508c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_free_host_bridge); 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci/* Indexed by PCI_X_SSTATUS_FREQ (secondary bus mode and frequency) */ 6538c2ecf20Sopenharmony_cistatic const unsigned char pcix_bus_speed[] = { 6548c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 0 */ 6558c2ecf20Sopenharmony_ci PCI_SPEED_66MHz_PCIX, /* 1 */ 6568c2ecf20Sopenharmony_ci PCI_SPEED_100MHz_PCIX, /* 2 */ 6578c2ecf20Sopenharmony_ci PCI_SPEED_133MHz_PCIX, /* 3 */ 6588c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 4 */ 6598c2ecf20Sopenharmony_ci PCI_SPEED_66MHz_PCIX_ECC, /* 5 */ 6608c2ecf20Sopenharmony_ci PCI_SPEED_100MHz_PCIX_ECC, /* 6 */ 6618c2ecf20Sopenharmony_ci PCI_SPEED_133MHz_PCIX_ECC, /* 7 */ 6628c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 8 */ 6638c2ecf20Sopenharmony_ci PCI_SPEED_66MHz_PCIX_266, /* 9 */ 6648c2ecf20Sopenharmony_ci PCI_SPEED_100MHz_PCIX_266, /* A */ 6658c2ecf20Sopenharmony_ci PCI_SPEED_133MHz_PCIX_266, /* B */ 6668c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* C */ 6678c2ecf20Sopenharmony_ci PCI_SPEED_66MHz_PCIX_533, /* D */ 6688c2ecf20Sopenharmony_ci PCI_SPEED_100MHz_PCIX_533, /* E */ 6698c2ecf20Sopenharmony_ci PCI_SPEED_133MHz_PCIX_533 /* F */ 6708c2ecf20Sopenharmony_ci}; 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci/* Indexed by PCI_EXP_LNKCAP_SLS, PCI_EXP_LNKSTA_CLS */ 6738c2ecf20Sopenharmony_ciconst unsigned char pcie_link_speed[] = { 6748c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 0 */ 6758c2ecf20Sopenharmony_ci PCIE_SPEED_2_5GT, /* 1 */ 6768c2ecf20Sopenharmony_ci PCIE_SPEED_5_0GT, /* 2 */ 6778c2ecf20Sopenharmony_ci PCIE_SPEED_8_0GT, /* 3 */ 6788c2ecf20Sopenharmony_ci PCIE_SPEED_16_0GT, /* 4 */ 6798c2ecf20Sopenharmony_ci PCIE_SPEED_32_0GT, /* 5 */ 6808c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 6 */ 6818c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 7 */ 6828c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 8 */ 6838c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* 9 */ 6848c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* A */ 6858c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* B */ 6868c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* C */ 6878c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* D */ 6888c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN, /* E */ 6898c2ecf20Sopenharmony_ci PCI_SPEED_UNKNOWN /* F */ 6908c2ecf20Sopenharmony_ci}; 6918c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pcie_link_speed); 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ciconst char *pci_speed_string(enum pci_bus_speed speed) 6948c2ecf20Sopenharmony_ci{ 6958c2ecf20Sopenharmony_ci /* Indexed by the pci_bus_speed enum */ 6968c2ecf20Sopenharmony_ci static const char *speed_strings[] = { 6978c2ecf20Sopenharmony_ci "33 MHz PCI", /* 0x00 */ 6988c2ecf20Sopenharmony_ci "66 MHz PCI", /* 0x01 */ 6998c2ecf20Sopenharmony_ci "66 MHz PCI-X", /* 0x02 */ 7008c2ecf20Sopenharmony_ci "100 MHz PCI-X", /* 0x03 */ 7018c2ecf20Sopenharmony_ci "133 MHz PCI-X", /* 0x04 */ 7028c2ecf20Sopenharmony_ci NULL, /* 0x05 */ 7038c2ecf20Sopenharmony_ci NULL, /* 0x06 */ 7048c2ecf20Sopenharmony_ci NULL, /* 0x07 */ 7058c2ecf20Sopenharmony_ci NULL, /* 0x08 */ 7068c2ecf20Sopenharmony_ci "66 MHz PCI-X 266", /* 0x09 */ 7078c2ecf20Sopenharmony_ci "100 MHz PCI-X 266", /* 0x0a */ 7088c2ecf20Sopenharmony_ci "133 MHz PCI-X 266", /* 0x0b */ 7098c2ecf20Sopenharmony_ci "Unknown AGP", /* 0x0c */ 7108c2ecf20Sopenharmony_ci "1x AGP", /* 0x0d */ 7118c2ecf20Sopenharmony_ci "2x AGP", /* 0x0e */ 7128c2ecf20Sopenharmony_ci "4x AGP", /* 0x0f */ 7138c2ecf20Sopenharmony_ci "8x AGP", /* 0x10 */ 7148c2ecf20Sopenharmony_ci "66 MHz PCI-X 533", /* 0x11 */ 7158c2ecf20Sopenharmony_ci "100 MHz PCI-X 533", /* 0x12 */ 7168c2ecf20Sopenharmony_ci "133 MHz PCI-X 533", /* 0x13 */ 7178c2ecf20Sopenharmony_ci "2.5 GT/s PCIe", /* 0x14 */ 7188c2ecf20Sopenharmony_ci "5.0 GT/s PCIe", /* 0x15 */ 7198c2ecf20Sopenharmony_ci "8.0 GT/s PCIe", /* 0x16 */ 7208c2ecf20Sopenharmony_ci "16.0 GT/s PCIe", /* 0x17 */ 7218c2ecf20Sopenharmony_ci "32.0 GT/s PCIe", /* 0x18 */ 7228c2ecf20Sopenharmony_ci }; 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci if (speed < ARRAY_SIZE(speed_strings)) 7258c2ecf20Sopenharmony_ci return speed_strings[speed]; 7268c2ecf20Sopenharmony_ci return "Unknown"; 7278c2ecf20Sopenharmony_ci} 7288c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_speed_string); 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_civoid pcie_update_link_speed(struct pci_bus *bus, u16 linksta) 7318c2ecf20Sopenharmony_ci{ 7328c2ecf20Sopenharmony_ci bus->cur_bus_speed = pcie_link_speed[linksta & PCI_EXP_LNKSTA_CLS]; 7338c2ecf20Sopenharmony_ci} 7348c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pcie_update_link_speed); 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_cistatic unsigned char agp_speeds[] = { 7378c2ecf20Sopenharmony_ci AGP_UNKNOWN, 7388c2ecf20Sopenharmony_ci AGP_1X, 7398c2ecf20Sopenharmony_ci AGP_2X, 7408c2ecf20Sopenharmony_ci AGP_4X, 7418c2ecf20Sopenharmony_ci AGP_8X 7428c2ecf20Sopenharmony_ci}; 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_cistatic enum pci_bus_speed agp_speed(int agp3, int agpstat) 7458c2ecf20Sopenharmony_ci{ 7468c2ecf20Sopenharmony_ci int index = 0; 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci if (agpstat & 4) 7498c2ecf20Sopenharmony_ci index = 3; 7508c2ecf20Sopenharmony_ci else if (agpstat & 2) 7518c2ecf20Sopenharmony_ci index = 2; 7528c2ecf20Sopenharmony_ci else if (agpstat & 1) 7538c2ecf20Sopenharmony_ci index = 1; 7548c2ecf20Sopenharmony_ci else 7558c2ecf20Sopenharmony_ci goto out; 7568c2ecf20Sopenharmony_ci 7578c2ecf20Sopenharmony_ci if (agp3) { 7588c2ecf20Sopenharmony_ci index += 2; 7598c2ecf20Sopenharmony_ci if (index == 5) 7608c2ecf20Sopenharmony_ci index = 0; 7618c2ecf20Sopenharmony_ci } 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_ci out: 7648c2ecf20Sopenharmony_ci return agp_speeds[index]; 7658c2ecf20Sopenharmony_ci} 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_cistatic void pci_set_bus_speed(struct pci_bus *bus) 7688c2ecf20Sopenharmony_ci{ 7698c2ecf20Sopenharmony_ci struct pci_dev *bridge = bus->self; 7708c2ecf20Sopenharmony_ci int pos; 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci pos = pci_find_capability(bridge, PCI_CAP_ID_AGP); 7738c2ecf20Sopenharmony_ci if (!pos) 7748c2ecf20Sopenharmony_ci pos = pci_find_capability(bridge, PCI_CAP_ID_AGP3); 7758c2ecf20Sopenharmony_ci if (pos) { 7768c2ecf20Sopenharmony_ci u32 agpstat, agpcmd; 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci pci_read_config_dword(bridge, pos + PCI_AGP_STATUS, &agpstat); 7798c2ecf20Sopenharmony_ci bus->max_bus_speed = agp_speed(agpstat & 8, agpstat & 7); 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_ci pci_read_config_dword(bridge, pos + PCI_AGP_COMMAND, &agpcmd); 7828c2ecf20Sopenharmony_ci bus->cur_bus_speed = agp_speed(agpstat & 8, agpcmd & 7); 7838c2ecf20Sopenharmony_ci } 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX); 7868c2ecf20Sopenharmony_ci if (pos) { 7878c2ecf20Sopenharmony_ci u16 status; 7888c2ecf20Sopenharmony_ci enum pci_bus_speed max; 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci pci_read_config_word(bridge, pos + PCI_X_BRIDGE_SSTATUS, 7918c2ecf20Sopenharmony_ci &status); 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci if (status & PCI_X_SSTATUS_533MHZ) { 7948c2ecf20Sopenharmony_ci max = PCI_SPEED_133MHz_PCIX_533; 7958c2ecf20Sopenharmony_ci } else if (status & PCI_X_SSTATUS_266MHZ) { 7968c2ecf20Sopenharmony_ci max = PCI_SPEED_133MHz_PCIX_266; 7978c2ecf20Sopenharmony_ci } else if (status & PCI_X_SSTATUS_133MHZ) { 7988c2ecf20Sopenharmony_ci if ((status & PCI_X_SSTATUS_VERS) == PCI_X_SSTATUS_V2) 7998c2ecf20Sopenharmony_ci max = PCI_SPEED_133MHz_PCIX_ECC; 8008c2ecf20Sopenharmony_ci else 8018c2ecf20Sopenharmony_ci max = PCI_SPEED_133MHz_PCIX; 8028c2ecf20Sopenharmony_ci } else { 8038c2ecf20Sopenharmony_ci max = PCI_SPEED_66MHz_PCIX; 8048c2ecf20Sopenharmony_ci } 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_ci bus->max_bus_speed = max; 8078c2ecf20Sopenharmony_ci bus->cur_bus_speed = pcix_bus_speed[ 8088c2ecf20Sopenharmony_ci (status & PCI_X_SSTATUS_FREQ) >> 6]; 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci return; 8118c2ecf20Sopenharmony_ci } 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci if (pci_is_pcie(bridge)) { 8148c2ecf20Sopenharmony_ci u32 linkcap; 8158c2ecf20Sopenharmony_ci u16 linksta; 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci pcie_capability_read_dword(bridge, PCI_EXP_LNKCAP, &linkcap); 8188c2ecf20Sopenharmony_ci bus->max_bus_speed = pcie_link_speed[linkcap & PCI_EXP_LNKCAP_SLS]; 8198c2ecf20Sopenharmony_ci bridge->link_active_reporting = !!(linkcap & PCI_EXP_LNKCAP_DLLLARC); 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta); 8228c2ecf20Sopenharmony_ci pcie_update_link_speed(bus, linksta); 8238c2ecf20Sopenharmony_ci } 8248c2ecf20Sopenharmony_ci} 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_cistatic struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) 8278c2ecf20Sopenharmony_ci{ 8288c2ecf20Sopenharmony_ci struct irq_domain *d; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci /* 8318c2ecf20Sopenharmony_ci * Any firmware interface that can resolve the msi_domain 8328c2ecf20Sopenharmony_ci * should be called from here. 8338c2ecf20Sopenharmony_ci */ 8348c2ecf20Sopenharmony_ci d = pci_host_bridge_of_msi_domain(bus); 8358c2ecf20Sopenharmony_ci if (!d) 8368c2ecf20Sopenharmony_ci d = pci_host_bridge_acpi_msi_domain(bus); 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN 8398c2ecf20Sopenharmony_ci /* 8408c2ecf20Sopenharmony_ci * If no IRQ domain was found via the OF tree, try looking it up 8418c2ecf20Sopenharmony_ci * directly through the fwnode_handle. 8428c2ecf20Sopenharmony_ci */ 8438c2ecf20Sopenharmony_ci if (!d) { 8448c2ecf20Sopenharmony_ci struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus); 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_ci if (fwnode) 8478c2ecf20Sopenharmony_ci d = irq_find_matching_fwnode(fwnode, 8488c2ecf20Sopenharmony_ci DOMAIN_BUS_PCI_MSI); 8498c2ecf20Sopenharmony_ci } 8508c2ecf20Sopenharmony_ci#endif 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci return d; 8538c2ecf20Sopenharmony_ci} 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_cistatic void pci_set_bus_msi_domain(struct pci_bus *bus) 8568c2ecf20Sopenharmony_ci{ 8578c2ecf20Sopenharmony_ci struct irq_domain *d; 8588c2ecf20Sopenharmony_ci struct pci_bus *b; 8598c2ecf20Sopenharmony_ci 8608c2ecf20Sopenharmony_ci /* 8618c2ecf20Sopenharmony_ci * The bus can be a root bus, a subordinate bus, or a virtual bus 8628c2ecf20Sopenharmony_ci * created by an SR-IOV device. Walk up to the first bridge device 8638c2ecf20Sopenharmony_ci * found or derive the domain from the host bridge. 8648c2ecf20Sopenharmony_ci */ 8658c2ecf20Sopenharmony_ci for (b = bus, d = NULL; !d && !pci_is_root_bus(b); b = b->parent) { 8668c2ecf20Sopenharmony_ci if (b->self) 8678c2ecf20Sopenharmony_ci d = dev_get_msi_domain(&b->self->dev); 8688c2ecf20Sopenharmony_ci } 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_ci if (!d) 8718c2ecf20Sopenharmony_ci d = pci_host_bridge_msi_domain(b); 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_ci dev_set_msi_domain(&bus->dev, d); 8748c2ecf20Sopenharmony_ci} 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_cistatic int pci_register_host_bridge(struct pci_host_bridge *bridge) 8778c2ecf20Sopenharmony_ci{ 8788c2ecf20Sopenharmony_ci struct device *parent = bridge->dev.parent; 8798c2ecf20Sopenharmony_ci struct resource_entry *window, *n; 8808c2ecf20Sopenharmony_ci struct pci_bus *bus, *b; 8818c2ecf20Sopenharmony_ci resource_size_t offset; 8828c2ecf20Sopenharmony_ci LIST_HEAD(resources); 8838c2ecf20Sopenharmony_ci struct resource *res; 8848c2ecf20Sopenharmony_ci char addr[64], *fmt; 8858c2ecf20Sopenharmony_ci const char *name; 8868c2ecf20Sopenharmony_ci int err; 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_ci bus = pci_alloc_bus(NULL); 8898c2ecf20Sopenharmony_ci if (!bus) 8908c2ecf20Sopenharmony_ci return -ENOMEM; 8918c2ecf20Sopenharmony_ci 8928c2ecf20Sopenharmony_ci bridge->bus = bus; 8938c2ecf20Sopenharmony_ci 8948c2ecf20Sopenharmony_ci /* Temporarily move resources off the list */ 8958c2ecf20Sopenharmony_ci list_splice_init(&bridge->windows, &resources); 8968c2ecf20Sopenharmony_ci bus->sysdata = bridge->sysdata; 8978c2ecf20Sopenharmony_ci bus->msi = bridge->msi; 8988c2ecf20Sopenharmony_ci bus->ops = bridge->ops; 8998c2ecf20Sopenharmony_ci bus->backup_ops = bus->ops; 9008c2ecf20Sopenharmony_ci bus->number = bus->busn_res.start = bridge->busnr; 9018c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_DOMAINS_GENERIC 9028c2ecf20Sopenharmony_ci bus->domain_nr = pci_bus_find_domain_nr(bus, parent); 9038c2ecf20Sopenharmony_ci#endif 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci b = pci_find_bus(pci_domain_nr(bus), bridge->busnr); 9068c2ecf20Sopenharmony_ci if (b) { 9078c2ecf20Sopenharmony_ci /* Ignore it if we already got here via a different bridge */ 9088c2ecf20Sopenharmony_ci dev_dbg(&b->dev, "bus already known\n"); 9098c2ecf20Sopenharmony_ci err = -EEXIST; 9108c2ecf20Sopenharmony_ci goto free; 9118c2ecf20Sopenharmony_ci } 9128c2ecf20Sopenharmony_ci 9138c2ecf20Sopenharmony_ci dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(bus), 9148c2ecf20Sopenharmony_ci bridge->busnr); 9158c2ecf20Sopenharmony_ci 9168c2ecf20Sopenharmony_ci err = pcibios_root_bridge_prepare(bridge); 9178c2ecf20Sopenharmony_ci if (err) 9188c2ecf20Sopenharmony_ci goto free; 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci err = device_add(&bridge->dev); 9218c2ecf20Sopenharmony_ci if (err) { 9228c2ecf20Sopenharmony_ci put_device(&bridge->dev); 9238c2ecf20Sopenharmony_ci goto free; 9248c2ecf20Sopenharmony_ci } 9258c2ecf20Sopenharmony_ci bus->bridge = get_device(&bridge->dev); 9268c2ecf20Sopenharmony_ci device_enable_async_suspend(bus->bridge); 9278c2ecf20Sopenharmony_ci pci_set_bus_of_node(bus); 9288c2ecf20Sopenharmony_ci pci_set_bus_msi_domain(bus); 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_ci if (!parent) 9318c2ecf20Sopenharmony_ci set_dev_node(bus->bridge, pcibus_to_node(bus)); 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_ci bus->dev.class = &pcibus_class; 9348c2ecf20Sopenharmony_ci bus->dev.parent = bus->bridge; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci dev_set_name(&bus->dev, "%04x:%02x", pci_domain_nr(bus), bus->number); 9378c2ecf20Sopenharmony_ci name = dev_name(&bus->dev); 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci err = device_register(&bus->dev); 9408c2ecf20Sopenharmony_ci if (err) 9418c2ecf20Sopenharmony_ci goto unregister; 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci pcibios_add_bus(bus); 9448c2ecf20Sopenharmony_ci 9458c2ecf20Sopenharmony_ci if (bus->ops->add_bus) { 9468c2ecf20Sopenharmony_ci err = bus->ops->add_bus(bus); 9478c2ecf20Sopenharmony_ci if (WARN_ON(err < 0)) 9488c2ecf20Sopenharmony_ci dev_err(&bus->dev, "failed to add bus: %d\n", err); 9498c2ecf20Sopenharmony_ci } 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci /* Create legacy_io and legacy_mem files for this bus */ 9528c2ecf20Sopenharmony_ci pci_create_legacy_files(bus); 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci if (parent) 9558c2ecf20Sopenharmony_ci dev_info(parent, "PCI host bridge to bus %s\n", name); 9568c2ecf20Sopenharmony_ci else 9578c2ecf20Sopenharmony_ci pr_info("PCI host bridge to bus %s\n", name); 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE) 9608c2ecf20Sopenharmony_ci dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n"); 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci /* Add initial resources to the bus */ 9638c2ecf20Sopenharmony_ci resource_list_for_each_entry_safe(window, n, &resources) { 9648c2ecf20Sopenharmony_ci list_move_tail(&window->node, &bridge->windows); 9658c2ecf20Sopenharmony_ci offset = window->offset; 9668c2ecf20Sopenharmony_ci res = window->res; 9678c2ecf20Sopenharmony_ci 9688c2ecf20Sopenharmony_ci if (res->flags & IORESOURCE_BUS) 9698c2ecf20Sopenharmony_ci pci_bus_insert_busn_res(bus, bus->number, res->end); 9708c2ecf20Sopenharmony_ci else 9718c2ecf20Sopenharmony_ci pci_bus_add_resource(bus, res, 0); 9728c2ecf20Sopenharmony_ci 9738c2ecf20Sopenharmony_ci if (offset) { 9748c2ecf20Sopenharmony_ci if (resource_type(res) == IORESOURCE_IO) 9758c2ecf20Sopenharmony_ci fmt = " (bus address [%#06llx-%#06llx])"; 9768c2ecf20Sopenharmony_ci else 9778c2ecf20Sopenharmony_ci fmt = " (bus address [%#010llx-%#010llx])"; 9788c2ecf20Sopenharmony_ci 9798c2ecf20Sopenharmony_ci snprintf(addr, sizeof(addr), fmt, 9808c2ecf20Sopenharmony_ci (unsigned long long)(res->start - offset), 9818c2ecf20Sopenharmony_ci (unsigned long long)(res->end - offset)); 9828c2ecf20Sopenharmony_ci } else 9838c2ecf20Sopenharmony_ci addr[0] = '\0'; 9848c2ecf20Sopenharmony_ci 9858c2ecf20Sopenharmony_ci dev_info(&bus->dev, "root bus resource %pR%s\n", res, addr); 9868c2ecf20Sopenharmony_ci } 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci down_write(&pci_bus_sem); 9898c2ecf20Sopenharmony_ci list_add_tail(&bus->node, &pci_root_buses); 9908c2ecf20Sopenharmony_ci up_write(&pci_bus_sem); 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_ci return 0; 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_ciunregister: 9958c2ecf20Sopenharmony_ci put_device(&bridge->dev); 9968c2ecf20Sopenharmony_ci device_del(&bridge->dev); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_cifree: 9998c2ecf20Sopenharmony_ci kfree(bus); 10008c2ecf20Sopenharmony_ci return err; 10018c2ecf20Sopenharmony_ci} 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_cistatic bool pci_bridge_child_ext_cfg_accessible(struct pci_dev *bridge) 10048c2ecf20Sopenharmony_ci{ 10058c2ecf20Sopenharmony_ci int pos; 10068c2ecf20Sopenharmony_ci u32 status; 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci /* 10098c2ecf20Sopenharmony_ci * If extended config space isn't accessible on a bridge's primary 10108c2ecf20Sopenharmony_ci * bus, we certainly can't access it on the secondary bus. 10118c2ecf20Sopenharmony_ci */ 10128c2ecf20Sopenharmony_ci if (bridge->bus->bus_flags & PCI_BUS_FLAGS_NO_EXTCFG) 10138c2ecf20Sopenharmony_ci return false; 10148c2ecf20Sopenharmony_ci 10158c2ecf20Sopenharmony_ci /* 10168c2ecf20Sopenharmony_ci * PCIe Root Ports and switch ports are PCIe on both sides, so if 10178c2ecf20Sopenharmony_ci * extended config space is accessible on the primary, it's also 10188c2ecf20Sopenharmony_ci * accessible on the secondary. 10198c2ecf20Sopenharmony_ci */ 10208c2ecf20Sopenharmony_ci if (pci_is_pcie(bridge) && 10218c2ecf20Sopenharmony_ci (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT || 10228c2ecf20Sopenharmony_ci pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM || 10238c2ecf20Sopenharmony_ci pci_pcie_type(bridge) == PCI_EXP_TYPE_DOWNSTREAM)) 10248c2ecf20Sopenharmony_ci return true; 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_ci /* 10278c2ecf20Sopenharmony_ci * For the other bridge types: 10288c2ecf20Sopenharmony_ci * - PCI-to-PCI bridges 10298c2ecf20Sopenharmony_ci * - PCIe-to-PCI/PCI-X forward bridges 10308c2ecf20Sopenharmony_ci * - PCI/PCI-X-to-PCIe reverse bridges 10318c2ecf20Sopenharmony_ci * extended config space on the secondary side is only accessible 10328c2ecf20Sopenharmony_ci * if the bridge supports PCI-X Mode 2. 10338c2ecf20Sopenharmony_ci */ 10348c2ecf20Sopenharmony_ci pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX); 10358c2ecf20Sopenharmony_ci if (!pos) 10368c2ecf20Sopenharmony_ci return false; 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci pci_read_config_dword(bridge, pos + PCI_X_STATUS, &status); 10398c2ecf20Sopenharmony_ci return status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ); 10408c2ecf20Sopenharmony_ci} 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_cistatic struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, 10438c2ecf20Sopenharmony_ci struct pci_dev *bridge, int busnr) 10448c2ecf20Sopenharmony_ci{ 10458c2ecf20Sopenharmony_ci struct pci_bus *child; 10468c2ecf20Sopenharmony_ci struct pci_host_bridge *host; 10478c2ecf20Sopenharmony_ci int i; 10488c2ecf20Sopenharmony_ci int ret; 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_ci /* Allocate a new bus and inherit stuff from the parent */ 10518c2ecf20Sopenharmony_ci child = pci_alloc_bus(parent); 10528c2ecf20Sopenharmony_ci if (!child) 10538c2ecf20Sopenharmony_ci return NULL; 10548c2ecf20Sopenharmony_ci 10558c2ecf20Sopenharmony_ci child->parent = parent; 10568c2ecf20Sopenharmony_ci child->msi = parent->msi; 10578c2ecf20Sopenharmony_ci child->sysdata = parent->sysdata; 10588c2ecf20Sopenharmony_ci child->bus_flags = parent->bus_flags; 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci host = pci_find_host_bridge(parent); 10618c2ecf20Sopenharmony_ci if (host->child_ops) { 10628c2ecf20Sopenharmony_ci child->ops = host->child_ops; 10638c2ecf20Sopenharmony_ci } else { 10648c2ecf20Sopenharmony_ci if (parent->backup_ops) 10658c2ecf20Sopenharmony_ci child->ops = parent->backup_ops; 10668c2ecf20Sopenharmony_ci else 10678c2ecf20Sopenharmony_ci child->ops = parent->ops; 10688c2ecf20Sopenharmony_ci } 10698c2ecf20Sopenharmony_ci child->backup_ops = child->ops; 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci /* 10728c2ecf20Sopenharmony_ci * Initialize some portions of the bus device, but don't register 10738c2ecf20Sopenharmony_ci * it now as the parent is not properly set up yet. 10748c2ecf20Sopenharmony_ci */ 10758c2ecf20Sopenharmony_ci child->dev.class = &pcibus_class; 10768c2ecf20Sopenharmony_ci dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr); 10778c2ecf20Sopenharmony_ci 10788c2ecf20Sopenharmony_ci /* Set up the primary, secondary and subordinate bus numbers */ 10798c2ecf20Sopenharmony_ci child->number = child->busn_res.start = busnr; 10808c2ecf20Sopenharmony_ci child->primary = parent->busn_res.start; 10818c2ecf20Sopenharmony_ci child->busn_res.end = 0xff; 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_ci if (!bridge) { 10848c2ecf20Sopenharmony_ci child->dev.parent = parent->bridge; 10858c2ecf20Sopenharmony_ci goto add_dev; 10868c2ecf20Sopenharmony_ci } 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci child->self = bridge; 10898c2ecf20Sopenharmony_ci child->bridge = get_device(&bridge->dev); 10908c2ecf20Sopenharmony_ci child->dev.parent = child->bridge; 10918c2ecf20Sopenharmony_ci pci_set_bus_of_node(child); 10928c2ecf20Sopenharmony_ci pci_set_bus_speed(child); 10938c2ecf20Sopenharmony_ci 10948c2ecf20Sopenharmony_ci /* 10958c2ecf20Sopenharmony_ci * Check whether extended config space is accessible on the child 10968c2ecf20Sopenharmony_ci * bus. Note that we currently assume it is always accessible on 10978c2ecf20Sopenharmony_ci * the root bus. 10988c2ecf20Sopenharmony_ci */ 10998c2ecf20Sopenharmony_ci if (!pci_bridge_child_ext_cfg_accessible(bridge)) { 11008c2ecf20Sopenharmony_ci child->bus_flags |= PCI_BUS_FLAGS_NO_EXTCFG; 11018c2ecf20Sopenharmony_ci pci_info(child, "extended config space not accessible\n"); 11028c2ecf20Sopenharmony_ci } 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci /* Set up default resource pointers and names */ 11058c2ecf20Sopenharmony_ci for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { 11068c2ecf20Sopenharmony_ci child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; 11078c2ecf20Sopenharmony_ci child->resource[i]->name = child->name; 11088c2ecf20Sopenharmony_ci } 11098c2ecf20Sopenharmony_ci bridge->subordinate = child; 11108c2ecf20Sopenharmony_ci 11118c2ecf20Sopenharmony_ciadd_dev: 11128c2ecf20Sopenharmony_ci pci_set_bus_msi_domain(child); 11138c2ecf20Sopenharmony_ci ret = device_register(&child->dev); 11148c2ecf20Sopenharmony_ci WARN_ON(ret < 0); 11158c2ecf20Sopenharmony_ci 11168c2ecf20Sopenharmony_ci pcibios_add_bus(child); 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_ci if (child->ops->add_bus) { 11198c2ecf20Sopenharmony_ci ret = child->ops->add_bus(child); 11208c2ecf20Sopenharmony_ci if (WARN_ON(ret < 0)) 11218c2ecf20Sopenharmony_ci dev_err(&child->dev, "failed to add bus: %d\n", ret); 11228c2ecf20Sopenharmony_ci } 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci /* Create legacy_io and legacy_mem files for this bus */ 11258c2ecf20Sopenharmony_ci pci_create_legacy_files(child); 11268c2ecf20Sopenharmony_ci 11278c2ecf20Sopenharmony_ci return child; 11288c2ecf20Sopenharmony_ci} 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_cistruct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, 11318c2ecf20Sopenharmony_ci int busnr) 11328c2ecf20Sopenharmony_ci{ 11338c2ecf20Sopenharmony_ci struct pci_bus *child; 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_ci child = pci_alloc_child_bus(parent, dev, busnr); 11368c2ecf20Sopenharmony_ci if (child) { 11378c2ecf20Sopenharmony_ci down_write(&pci_bus_sem); 11388c2ecf20Sopenharmony_ci list_add_tail(&child->node, &parent->children); 11398c2ecf20Sopenharmony_ci up_write(&pci_bus_sem); 11408c2ecf20Sopenharmony_ci } 11418c2ecf20Sopenharmony_ci return child; 11428c2ecf20Sopenharmony_ci} 11438c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_add_new_bus); 11448c2ecf20Sopenharmony_ci 11458c2ecf20Sopenharmony_cistatic void pci_enable_crs(struct pci_dev *pdev) 11468c2ecf20Sopenharmony_ci{ 11478c2ecf20Sopenharmony_ci u16 root_cap = 0; 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ci /* Enable CRS Software Visibility if supported */ 11508c2ecf20Sopenharmony_ci pcie_capability_read_word(pdev, PCI_EXP_RTCAP, &root_cap); 11518c2ecf20Sopenharmony_ci if (root_cap & PCI_EXP_RTCAP_CRSVIS) 11528c2ecf20Sopenharmony_ci pcie_capability_set_word(pdev, PCI_EXP_RTCTL, 11538c2ecf20Sopenharmony_ci PCI_EXP_RTCTL_CRSSVE); 11548c2ecf20Sopenharmony_ci} 11558c2ecf20Sopenharmony_ci 11568c2ecf20Sopenharmony_cistatic unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, 11578c2ecf20Sopenharmony_ci unsigned int available_buses); 11588c2ecf20Sopenharmony_ci/** 11598c2ecf20Sopenharmony_ci * pci_ea_fixed_busnrs() - Read fixed Secondary and Subordinate bus 11608c2ecf20Sopenharmony_ci * numbers from EA capability. 11618c2ecf20Sopenharmony_ci * @dev: Bridge 11628c2ecf20Sopenharmony_ci * @sec: updated with secondary bus number from EA 11638c2ecf20Sopenharmony_ci * @sub: updated with subordinate bus number from EA 11648c2ecf20Sopenharmony_ci * 11658c2ecf20Sopenharmony_ci * If @dev is a bridge with EA capability that specifies valid secondary 11668c2ecf20Sopenharmony_ci * and subordinate bus numbers, return true with the bus numbers in @sec 11678c2ecf20Sopenharmony_ci * and @sub. Otherwise return false. 11688c2ecf20Sopenharmony_ci */ 11698c2ecf20Sopenharmony_cistatic bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) 11708c2ecf20Sopenharmony_ci{ 11718c2ecf20Sopenharmony_ci int ea, offset; 11728c2ecf20Sopenharmony_ci u32 dw; 11738c2ecf20Sopenharmony_ci u8 ea_sec, ea_sub; 11748c2ecf20Sopenharmony_ci 11758c2ecf20Sopenharmony_ci if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) 11768c2ecf20Sopenharmony_ci return false; 11778c2ecf20Sopenharmony_ci 11788c2ecf20Sopenharmony_ci /* find PCI EA capability in list */ 11798c2ecf20Sopenharmony_ci ea = pci_find_capability(dev, PCI_CAP_ID_EA); 11808c2ecf20Sopenharmony_ci if (!ea) 11818c2ecf20Sopenharmony_ci return false; 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_ci offset = ea + PCI_EA_FIRST_ENT; 11848c2ecf20Sopenharmony_ci pci_read_config_dword(dev, offset, &dw); 11858c2ecf20Sopenharmony_ci ea_sec = dw & PCI_EA_SEC_BUS_MASK; 11868c2ecf20Sopenharmony_ci ea_sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; 11878c2ecf20Sopenharmony_ci if (ea_sec == 0 || ea_sub < ea_sec) 11888c2ecf20Sopenharmony_ci return false; 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci *sec = ea_sec; 11918c2ecf20Sopenharmony_ci *sub = ea_sub; 11928c2ecf20Sopenharmony_ci return true; 11938c2ecf20Sopenharmony_ci} 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_ci/* 11968c2ecf20Sopenharmony_ci * pci_scan_bridge_extend() - Scan buses behind a bridge 11978c2ecf20Sopenharmony_ci * @bus: Parent bus the bridge is on 11988c2ecf20Sopenharmony_ci * @dev: Bridge itself 11998c2ecf20Sopenharmony_ci * @max: Starting subordinate number of buses behind this bridge 12008c2ecf20Sopenharmony_ci * @available_buses: Total number of buses available for this bridge and 12018c2ecf20Sopenharmony_ci * the devices below. After the minimal bus space has 12028c2ecf20Sopenharmony_ci * been allocated the remaining buses will be 12038c2ecf20Sopenharmony_ci * distributed equally between hotplug-capable bridges. 12048c2ecf20Sopenharmony_ci * @pass: Either %0 (scan already configured bridges) or %1 (scan bridges 12058c2ecf20Sopenharmony_ci * that need to be reconfigured. 12068c2ecf20Sopenharmony_ci * 12078c2ecf20Sopenharmony_ci * If it's a bridge, configure it and scan the bus behind it. 12088c2ecf20Sopenharmony_ci * For CardBus bridges, we don't scan behind as the devices will 12098c2ecf20Sopenharmony_ci * be handled by the bridge driver itself. 12108c2ecf20Sopenharmony_ci * 12118c2ecf20Sopenharmony_ci * We need to process bridges in two passes -- first we scan those 12128c2ecf20Sopenharmony_ci * already configured by the BIOS and after we are done with all of 12138c2ecf20Sopenharmony_ci * them, we proceed to assigning numbers to the remaining buses in 12148c2ecf20Sopenharmony_ci * order to avoid overlaps between old and new bus numbers. 12158c2ecf20Sopenharmony_ci * 12168c2ecf20Sopenharmony_ci * Return: New subordinate number covering all buses behind this bridge. 12178c2ecf20Sopenharmony_ci */ 12188c2ecf20Sopenharmony_cistatic int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, 12198c2ecf20Sopenharmony_ci int max, unsigned int available_buses, 12208c2ecf20Sopenharmony_ci int pass) 12218c2ecf20Sopenharmony_ci{ 12228c2ecf20Sopenharmony_ci struct pci_bus *child; 12238c2ecf20Sopenharmony_ci int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); 12248c2ecf20Sopenharmony_ci u32 buses, i, j = 0; 12258c2ecf20Sopenharmony_ci u16 bctl; 12268c2ecf20Sopenharmony_ci u8 primary, secondary, subordinate; 12278c2ecf20Sopenharmony_ci int broken = 0; 12288c2ecf20Sopenharmony_ci bool fixed_buses; 12298c2ecf20Sopenharmony_ci u8 fixed_sec, fixed_sub; 12308c2ecf20Sopenharmony_ci int next_busnr; 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_ci /* 12338c2ecf20Sopenharmony_ci * Make sure the bridge is powered on to be able to access config 12348c2ecf20Sopenharmony_ci * space of devices below it. 12358c2ecf20Sopenharmony_ci */ 12368c2ecf20Sopenharmony_ci pm_runtime_get_sync(&dev->dev); 12378c2ecf20Sopenharmony_ci 12388c2ecf20Sopenharmony_ci pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); 12398c2ecf20Sopenharmony_ci primary = buses & 0xFF; 12408c2ecf20Sopenharmony_ci secondary = (buses >> 8) & 0xFF; 12418c2ecf20Sopenharmony_ci subordinate = (buses >> 16) & 0xFF; 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci pci_dbg(dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", 12448c2ecf20Sopenharmony_ci secondary, subordinate, pass); 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_ci if (!primary && (primary != bus->number) && secondary && subordinate) { 12478c2ecf20Sopenharmony_ci pci_warn(dev, "Primary bus is hard wired to 0\n"); 12488c2ecf20Sopenharmony_ci primary = bus->number; 12498c2ecf20Sopenharmony_ci } 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_ci /* Check if setup is sensible at all */ 12528c2ecf20Sopenharmony_ci if (!pass && 12538c2ecf20Sopenharmony_ci (primary != bus->number || secondary <= bus->number || 12548c2ecf20Sopenharmony_ci secondary > subordinate)) { 12558c2ecf20Sopenharmony_ci pci_info(dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", 12568c2ecf20Sopenharmony_ci secondary, subordinate); 12578c2ecf20Sopenharmony_ci broken = 1; 12588c2ecf20Sopenharmony_ci } 12598c2ecf20Sopenharmony_ci 12608c2ecf20Sopenharmony_ci /* 12618c2ecf20Sopenharmony_ci * Disable Master-Abort Mode during probing to avoid reporting of 12628c2ecf20Sopenharmony_ci * bus errors in some architectures. 12638c2ecf20Sopenharmony_ci */ 12648c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl); 12658c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_BRIDGE_CONTROL, 12668c2ecf20Sopenharmony_ci bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_ci pci_enable_crs(dev); 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci if ((secondary || subordinate) && !pcibios_assign_all_busses() && 12718c2ecf20Sopenharmony_ci !is_cardbus && !broken) { 12728c2ecf20Sopenharmony_ci unsigned int cmax; 12738c2ecf20Sopenharmony_ci 12748c2ecf20Sopenharmony_ci /* 12758c2ecf20Sopenharmony_ci * Bus already configured by firmware, process it in the 12768c2ecf20Sopenharmony_ci * first pass and just note the configuration. 12778c2ecf20Sopenharmony_ci */ 12788c2ecf20Sopenharmony_ci if (pass) 12798c2ecf20Sopenharmony_ci goto out; 12808c2ecf20Sopenharmony_ci 12818c2ecf20Sopenharmony_ci /* 12828c2ecf20Sopenharmony_ci * The bus might already exist for two reasons: Either we 12838c2ecf20Sopenharmony_ci * are rescanning the bus or the bus is reachable through 12848c2ecf20Sopenharmony_ci * more than one bridge. The second case can happen with 12858c2ecf20Sopenharmony_ci * the i450NX chipset. 12868c2ecf20Sopenharmony_ci */ 12878c2ecf20Sopenharmony_ci child = pci_find_bus(pci_domain_nr(bus), secondary); 12888c2ecf20Sopenharmony_ci if (!child) { 12898c2ecf20Sopenharmony_ci child = pci_add_new_bus(bus, dev, secondary); 12908c2ecf20Sopenharmony_ci if (!child) 12918c2ecf20Sopenharmony_ci goto out; 12928c2ecf20Sopenharmony_ci child->primary = primary; 12938c2ecf20Sopenharmony_ci pci_bus_insert_busn_res(child, secondary, subordinate); 12948c2ecf20Sopenharmony_ci child->bridge_ctl = bctl; 12958c2ecf20Sopenharmony_ci } 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci cmax = pci_scan_child_bus(child); 12988c2ecf20Sopenharmony_ci if (cmax > subordinate) 12998c2ecf20Sopenharmony_ci pci_warn(dev, "bridge has subordinate %02x but max busn %02x\n", 13008c2ecf20Sopenharmony_ci subordinate, cmax); 13018c2ecf20Sopenharmony_ci 13028c2ecf20Sopenharmony_ci /* Subordinate should equal child->busn_res.end */ 13038c2ecf20Sopenharmony_ci if (subordinate > max) 13048c2ecf20Sopenharmony_ci max = subordinate; 13058c2ecf20Sopenharmony_ci } else { 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_ci /* 13088c2ecf20Sopenharmony_ci * We need to assign a number to this bus which we always 13098c2ecf20Sopenharmony_ci * do in the second pass. 13108c2ecf20Sopenharmony_ci */ 13118c2ecf20Sopenharmony_ci if (!pass) { 13128c2ecf20Sopenharmony_ci if (pcibios_assign_all_busses() || broken || is_cardbus) 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_ci /* 13158c2ecf20Sopenharmony_ci * Temporarily disable forwarding of the 13168c2ecf20Sopenharmony_ci * configuration cycles on all bridges in 13178c2ecf20Sopenharmony_ci * this bus segment to avoid possible 13188c2ecf20Sopenharmony_ci * conflicts in the second pass between two 13198c2ecf20Sopenharmony_ci * bridges programmed with overlapping bus 13208c2ecf20Sopenharmony_ci * ranges. 13218c2ecf20Sopenharmony_ci */ 13228c2ecf20Sopenharmony_ci pci_write_config_dword(dev, PCI_PRIMARY_BUS, 13238c2ecf20Sopenharmony_ci buses & ~0xffffff); 13248c2ecf20Sopenharmony_ci goto out; 13258c2ecf20Sopenharmony_ci } 13268c2ecf20Sopenharmony_ci 13278c2ecf20Sopenharmony_ci /* Clear errors */ 13288c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_STATUS, 0xffff); 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_ci /* Read bus numbers from EA Capability (if present) */ 13318c2ecf20Sopenharmony_ci fixed_buses = pci_ea_fixed_busnrs(dev, &fixed_sec, &fixed_sub); 13328c2ecf20Sopenharmony_ci if (fixed_buses) 13338c2ecf20Sopenharmony_ci next_busnr = fixed_sec; 13348c2ecf20Sopenharmony_ci else 13358c2ecf20Sopenharmony_ci next_busnr = max + 1; 13368c2ecf20Sopenharmony_ci 13378c2ecf20Sopenharmony_ci /* 13388c2ecf20Sopenharmony_ci * Prevent assigning a bus number that already exists. 13398c2ecf20Sopenharmony_ci * This can happen when a bridge is hot-plugged, so in this 13408c2ecf20Sopenharmony_ci * case we only re-scan this bus. 13418c2ecf20Sopenharmony_ci */ 13428c2ecf20Sopenharmony_ci child = pci_find_bus(pci_domain_nr(bus), next_busnr); 13438c2ecf20Sopenharmony_ci if (!child) { 13448c2ecf20Sopenharmony_ci child = pci_add_new_bus(bus, dev, next_busnr); 13458c2ecf20Sopenharmony_ci if (!child) 13468c2ecf20Sopenharmony_ci goto out; 13478c2ecf20Sopenharmony_ci pci_bus_insert_busn_res(child, next_busnr, 13488c2ecf20Sopenharmony_ci bus->busn_res.end); 13498c2ecf20Sopenharmony_ci } 13508c2ecf20Sopenharmony_ci max++; 13518c2ecf20Sopenharmony_ci if (available_buses) 13528c2ecf20Sopenharmony_ci available_buses--; 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci buses = (buses & 0xff000000) 13558c2ecf20Sopenharmony_ci | ((unsigned int)(child->primary) << 0) 13568c2ecf20Sopenharmony_ci | ((unsigned int)(child->busn_res.start) << 8) 13578c2ecf20Sopenharmony_ci | ((unsigned int)(child->busn_res.end) << 16); 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci /* 13608c2ecf20Sopenharmony_ci * yenta.c forces a secondary latency timer of 176. 13618c2ecf20Sopenharmony_ci * Copy that behaviour here. 13628c2ecf20Sopenharmony_ci */ 13638c2ecf20Sopenharmony_ci if (is_cardbus) { 13648c2ecf20Sopenharmony_ci buses &= ~0xff000000; 13658c2ecf20Sopenharmony_ci buses |= CARDBUS_LATENCY_TIMER << 24; 13668c2ecf20Sopenharmony_ci } 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci /* We need to blast all three values with a single write */ 13698c2ecf20Sopenharmony_ci pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); 13708c2ecf20Sopenharmony_ci 13718c2ecf20Sopenharmony_ci if (!is_cardbus) { 13728c2ecf20Sopenharmony_ci child->bridge_ctl = bctl; 13738c2ecf20Sopenharmony_ci max = pci_scan_child_bus_extend(child, available_buses); 13748c2ecf20Sopenharmony_ci } else { 13758c2ecf20Sopenharmony_ci 13768c2ecf20Sopenharmony_ci /* 13778c2ecf20Sopenharmony_ci * For CardBus bridges, we leave 4 bus numbers as 13788c2ecf20Sopenharmony_ci * cards with a PCI-to-PCI bridge can be inserted 13798c2ecf20Sopenharmony_ci * later. 13808c2ecf20Sopenharmony_ci */ 13818c2ecf20Sopenharmony_ci for (i = 0; i < CARDBUS_RESERVE_BUSNR; i++) { 13828c2ecf20Sopenharmony_ci struct pci_bus *parent = bus; 13838c2ecf20Sopenharmony_ci if (pci_find_bus(pci_domain_nr(bus), 13848c2ecf20Sopenharmony_ci max+i+1)) 13858c2ecf20Sopenharmony_ci break; 13868c2ecf20Sopenharmony_ci while (parent->parent) { 13878c2ecf20Sopenharmony_ci if ((!pcibios_assign_all_busses()) && 13888c2ecf20Sopenharmony_ci (parent->busn_res.end > max) && 13898c2ecf20Sopenharmony_ci (parent->busn_res.end <= max+i)) { 13908c2ecf20Sopenharmony_ci j = 1; 13918c2ecf20Sopenharmony_ci } 13928c2ecf20Sopenharmony_ci parent = parent->parent; 13938c2ecf20Sopenharmony_ci } 13948c2ecf20Sopenharmony_ci if (j) { 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci /* 13978c2ecf20Sopenharmony_ci * Often, there are two CardBus 13988c2ecf20Sopenharmony_ci * bridges -- try to leave one 13998c2ecf20Sopenharmony_ci * valid bus number for each one. 14008c2ecf20Sopenharmony_ci */ 14018c2ecf20Sopenharmony_ci i /= 2; 14028c2ecf20Sopenharmony_ci break; 14038c2ecf20Sopenharmony_ci } 14048c2ecf20Sopenharmony_ci } 14058c2ecf20Sopenharmony_ci max += i; 14068c2ecf20Sopenharmony_ci } 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_ci /* 14098c2ecf20Sopenharmony_ci * Set subordinate bus number to its real value. 14108c2ecf20Sopenharmony_ci * If fixed subordinate bus number exists from EA 14118c2ecf20Sopenharmony_ci * capability then use it. 14128c2ecf20Sopenharmony_ci */ 14138c2ecf20Sopenharmony_ci if (fixed_buses) 14148c2ecf20Sopenharmony_ci max = fixed_sub; 14158c2ecf20Sopenharmony_ci pci_bus_update_busn_res_end(child, max); 14168c2ecf20Sopenharmony_ci pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); 14178c2ecf20Sopenharmony_ci } 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci sprintf(child->name, 14208c2ecf20Sopenharmony_ci (is_cardbus ? "PCI CardBus %04x:%02x" : "PCI Bus %04x:%02x"), 14218c2ecf20Sopenharmony_ci pci_domain_nr(bus), child->number); 14228c2ecf20Sopenharmony_ci 14238c2ecf20Sopenharmony_ci /* Check that all devices are accessible */ 14248c2ecf20Sopenharmony_ci while (bus->parent) { 14258c2ecf20Sopenharmony_ci if ((child->busn_res.end > bus->busn_res.end) || 14268c2ecf20Sopenharmony_ci (child->number > bus->busn_res.end) || 14278c2ecf20Sopenharmony_ci (child->number < bus->number) || 14288c2ecf20Sopenharmony_ci (child->busn_res.end < bus->number)) { 14298c2ecf20Sopenharmony_ci dev_info(&dev->dev, "devices behind bridge are unusable because %pR cannot be assigned for them\n", 14308c2ecf20Sopenharmony_ci &child->busn_res); 14318c2ecf20Sopenharmony_ci break; 14328c2ecf20Sopenharmony_ci } 14338c2ecf20Sopenharmony_ci bus = bus->parent; 14348c2ecf20Sopenharmony_ci } 14358c2ecf20Sopenharmony_ci 14368c2ecf20Sopenharmony_ciout: 14378c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); 14388c2ecf20Sopenharmony_ci 14398c2ecf20Sopenharmony_ci pm_runtime_put(&dev->dev); 14408c2ecf20Sopenharmony_ci 14418c2ecf20Sopenharmony_ci return max; 14428c2ecf20Sopenharmony_ci} 14438c2ecf20Sopenharmony_ci 14448c2ecf20Sopenharmony_ci/* 14458c2ecf20Sopenharmony_ci * pci_scan_bridge() - Scan buses behind a bridge 14468c2ecf20Sopenharmony_ci * @bus: Parent bus the bridge is on 14478c2ecf20Sopenharmony_ci * @dev: Bridge itself 14488c2ecf20Sopenharmony_ci * @max: Starting subordinate number of buses behind this bridge 14498c2ecf20Sopenharmony_ci * @pass: Either %0 (scan already configured bridges) or %1 (scan bridges 14508c2ecf20Sopenharmony_ci * that need to be reconfigured. 14518c2ecf20Sopenharmony_ci * 14528c2ecf20Sopenharmony_ci * If it's a bridge, configure it and scan the bus behind it. 14538c2ecf20Sopenharmony_ci * For CardBus bridges, we don't scan behind as the devices will 14548c2ecf20Sopenharmony_ci * be handled by the bridge driver itself. 14558c2ecf20Sopenharmony_ci * 14568c2ecf20Sopenharmony_ci * We need to process bridges in two passes -- first we scan those 14578c2ecf20Sopenharmony_ci * already configured by the BIOS and after we are done with all of 14588c2ecf20Sopenharmony_ci * them, we proceed to assigning numbers to the remaining buses in 14598c2ecf20Sopenharmony_ci * order to avoid overlaps between old and new bus numbers. 14608c2ecf20Sopenharmony_ci * 14618c2ecf20Sopenharmony_ci * Return: New subordinate number covering all buses behind this bridge. 14628c2ecf20Sopenharmony_ci */ 14638c2ecf20Sopenharmony_ciint pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) 14648c2ecf20Sopenharmony_ci{ 14658c2ecf20Sopenharmony_ci return pci_scan_bridge_extend(bus, dev, max, 0, pass); 14668c2ecf20Sopenharmony_ci} 14678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_scan_bridge); 14688c2ecf20Sopenharmony_ci 14698c2ecf20Sopenharmony_ci/* 14708c2ecf20Sopenharmony_ci * Read interrupt line and base address registers. 14718c2ecf20Sopenharmony_ci * The architecture-dependent code can tweak these, of course. 14728c2ecf20Sopenharmony_ci */ 14738c2ecf20Sopenharmony_cistatic void pci_read_irq(struct pci_dev *dev) 14748c2ecf20Sopenharmony_ci{ 14758c2ecf20Sopenharmony_ci unsigned char irq; 14768c2ecf20Sopenharmony_ci 14778c2ecf20Sopenharmony_ci /* VFs are not allowed to use INTx, so skip the config reads */ 14788c2ecf20Sopenharmony_ci if (dev->is_virtfn) { 14798c2ecf20Sopenharmony_ci dev->pin = 0; 14808c2ecf20Sopenharmony_ci dev->irq = 0; 14818c2ecf20Sopenharmony_ci return; 14828c2ecf20Sopenharmony_ci } 14838c2ecf20Sopenharmony_ci 14848c2ecf20Sopenharmony_ci pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); 14858c2ecf20Sopenharmony_ci dev->pin = irq; 14868c2ecf20Sopenharmony_ci if (irq) 14878c2ecf20Sopenharmony_ci pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); 14888c2ecf20Sopenharmony_ci dev->irq = irq; 14898c2ecf20Sopenharmony_ci} 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_civoid set_pcie_port_type(struct pci_dev *pdev) 14928c2ecf20Sopenharmony_ci{ 14938c2ecf20Sopenharmony_ci int pos; 14948c2ecf20Sopenharmony_ci u16 reg16; 14958c2ecf20Sopenharmony_ci int type; 14968c2ecf20Sopenharmony_ci struct pci_dev *parent; 14978c2ecf20Sopenharmony_ci 14988c2ecf20Sopenharmony_ci pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 14998c2ecf20Sopenharmony_ci if (!pos) 15008c2ecf20Sopenharmony_ci return; 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci pdev->pcie_cap = pos; 15038c2ecf20Sopenharmony_ci pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); 15048c2ecf20Sopenharmony_ci pdev->pcie_flags_reg = reg16; 15058c2ecf20Sopenharmony_ci pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); 15068c2ecf20Sopenharmony_ci pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_ci parent = pci_upstream_bridge(pdev); 15098c2ecf20Sopenharmony_ci if (!parent) 15108c2ecf20Sopenharmony_ci return; 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci /* 15138c2ecf20Sopenharmony_ci * Some systems do not identify their upstream/downstream ports 15148c2ecf20Sopenharmony_ci * correctly so detect impossible configurations here and correct 15158c2ecf20Sopenharmony_ci * the port type accordingly. 15168c2ecf20Sopenharmony_ci */ 15178c2ecf20Sopenharmony_ci type = pci_pcie_type(pdev); 15188c2ecf20Sopenharmony_ci if (type == PCI_EXP_TYPE_DOWNSTREAM) { 15198c2ecf20Sopenharmony_ci /* 15208c2ecf20Sopenharmony_ci * If pdev claims to be downstream port but the parent 15218c2ecf20Sopenharmony_ci * device is also downstream port assume pdev is actually 15228c2ecf20Sopenharmony_ci * upstream port. 15238c2ecf20Sopenharmony_ci */ 15248c2ecf20Sopenharmony_ci if (pcie_downstream_port(parent)) { 15258c2ecf20Sopenharmony_ci pci_info(pdev, "claims to be downstream port but is acting as upstream port, correcting type\n"); 15268c2ecf20Sopenharmony_ci pdev->pcie_flags_reg &= ~PCI_EXP_FLAGS_TYPE; 15278c2ecf20Sopenharmony_ci pdev->pcie_flags_reg |= PCI_EXP_TYPE_UPSTREAM; 15288c2ecf20Sopenharmony_ci } 15298c2ecf20Sopenharmony_ci } else if (type == PCI_EXP_TYPE_UPSTREAM) { 15308c2ecf20Sopenharmony_ci /* 15318c2ecf20Sopenharmony_ci * If pdev claims to be upstream port but the parent 15328c2ecf20Sopenharmony_ci * device is also upstream port assume pdev is actually 15338c2ecf20Sopenharmony_ci * downstream port. 15348c2ecf20Sopenharmony_ci */ 15358c2ecf20Sopenharmony_ci if (pci_pcie_type(parent) == PCI_EXP_TYPE_UPSTREAM) { 15368c2ecf20Sopenharmony_ci pci_info(pdev, "claims to be upstream port but is acting as downstream port, correcting type\n"); 15378c2ecf20Sopenharmony_ci pdev->pcie_flags_reg &= ~PCI_EXP_FLAGS_TYPE; 15388c2ecf20Sopenharmony_ci pdev->pcie_flags_reg |= PCI_EXP_TYPE_DOWNSTREAM; 15398c2ecf20Sopenharmony_ci } 15408c2ecf20Sopenharmony_ci } 15418c2ecf20Sopenharmony_ci} 15428c2ecf20Sopenharmony_ci 15438c2ecf20Sopenharmony_civoid set_pcie_hotplug_bridge(struct pci_dev *pdev) 15448c2ecf20Sopenharmony_ci{ 15458c2ecf20Sopenharmony_ci u32 reg32; 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_ci pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32); 15488c2ecf20Sopenharmony_ci if (reg32 & PCI_EXP_SLTCAP_HPC) 15498c2ecf20Sopenharmony_ci pdev->is_hotplug_bridge = 1; 15508c2ecf20Sopenharmony_ci} 15518c2ecf20Sopenharmony_ci 15528c2ecf20Sopenharmony_cistatic void set_pcie_thunderbolt(struct pci_dev *dev) 15538c2ecf20Sopenharmony_ci{ 15548c2ecf20Sopenharmony_ci int vsec = 0; 15558c2ecf20Sopenharmony_ci u32 header; 15568c2ecf20Sopenharmony_ci 15578c2ecf20Sopenharmony_ci while ((vsec = pci_find_next_ext_capability(dev, vsec, 15588c2ecf20Sopenharmony_ci PCI_EXT_CAP_ID_VNDR))) { 15598c2ecf20Sopenharmony_ci pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, &header); 15608c2ecf20Sopenharmony_ci 15618c2ecf20Sopenharmony_ci /* Is the device part of a Thunderbolt controller? */ 15628c2ecf20Sopenharmony_ci if (dev->vendor == PCI_VENDOR_ID_INTEL && 15638c2ecf20Sopenharmony_ci PCI_VNDR_HEADER_ID(header) == PCI_VSEC_ID_INTEL_TBT) { 15648c2ecf20Sopenharmony_ci dev->is_thunderbolt = 1; 15658c2ecf20Sopenharmony_ci return; 15668c2ecf20Sopenharmony_ci } 15678c2ecf20Sopenharmony_ci } 15688c2ecf20Sopenharmony_ci} 15698c2ecf20Sopenharmony_ci 15708c2ecf20Sopenharmony_cistatic void set_pcie_untrusted(struct pci_dev *dev) 15718c2ecf20Sopenharmony_ci{ 15728c2ecf20Sopenharmony_ci struct pci_dev *parent; 15738c2ecf20Sopenharmony_ci 15748c2ecf20Sopenharmony_ci /* 15758c2ecf20Sopenharmony_ci * If the upstream bridge is untrusted we treat this device 15768c2ecf20Sopenharmony_ci * untrusted as well. 15778c2ecf20Sopenharmony_ci */ 15788c2ecf20Sopenharmony_ci parent = pci_upstream_bridge(dev); 15798c2ecf20Sopenharmony_ci if (parent && (parent->untrusted || parent->external_facing)) 15808c2ecf20Sopenharmony_ci dev->untrusted = true; 15818c2ecf20Sopenharmony_ci} 15828c2ecf20Sopenharmony_ci 15838c2ecf20Sopenharmony_ci/** 15848c2ecf20Sopenharmony_ci * pci_ext_cfg_is_aliased - Is ext config space just an alias of std config? 15858c2ecf20Sopenharmony_ci * @dev: PCI device 15868c2ecf20Sopenharmony_ci * 15878c2ecf20Sopenharmony_ci * PCI Express to PCI/PCI-X Bridge Specification, rev 1.0, 4.1.4 says that 15888c2ecf20Sopenharmony_ci * when forwarding a type1 configuration request the bridge must check that 15898c2ecf20Sopenharmony_ci * the extended register address field is zero. The bridge is not permitted 15908c2ecf20Sopenharmony_ci * to forward the transactions and must handle it as an Unsupported Request. 15918c2ecf20Sopenharmony_ci * Some bridges do not follow this rule and simply drop the extended register 15928c2ecf20Sopenharmony_ci * bits, resulting in the standard config space being aliased, every 256 15938c2ecf20Sopenharmony_ci * bytes across the entire configuration space. Test for this condition by 15948c2ecf20Sopenharmony_ci * comparing the first dword of each potential alias to the vendor/device ID. 15958c2ecf20Sopenharmony_ci * Known offenders: 15968c2ecf20Sopenharmony_ci * ASM1083/1085 PCIe-to-PCI Reversible Bridge (1b21:1080, rev 01 & 03) 15978c2ecf20Sopenharmony_ci * AMD/ATI SBx00 PCI to PCI Bridge (1002:4384, rev 40) 15988c2ecf20Sopenharmony_ci */ 15998c2ecf20Sopenharmony_cistatic bool pci_ext_cfg_is_aliased(struct pci_dev *dev) 16008c2ecf20Sopenharmony_ci{ 16018c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_QUIRKS 16028c2ecf20Sopenharmony_ci int pos; 16038c2ecf20Sopenharmony_ci u32 header, tmp; 16048c2ecf20Sopenharmony_ci 16058c2ecf20Sopenharmony_ci pci_read_config_dword(dev, PCI_VENDOR_ID, &header); 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_ci for (pos = PCI_CFG_SPACE_SIZE; 16088c2ecf20Sopenharmony_ci pos < PCI_CFG_SPACE_EXP_SIZE; pos += PCI_CFG_SPACE_SIZE) { 16098c2ecf20Sopenharmony_ci if (pci_read_config_dword(dev, pos, &tmp) != PCIBIOS_SUCCESSFUL 16108c2ecf20Sopenharmony_ci || header != tmp) 16118c2ecf20Sopenharmony_ci return false; 16128c2ecf20Sopenharmony_ci } 16138c2ecf20Sopenharmony_ci 16148c2ecf20Sopenharmony_ci return true; 16158c2ecf20Sopenharmony_ci#else 16168c2ecf20Sopenharmony_ci return false; 16178c2ecf20Sopenharmony_ci#endif 16188c2ecf20Sopenharmony_ci} 16198c2ecf20Sopenharmony_ci 16208c2ecf20Sopenharmony_ci/** 16218c2ecf20Sopenharmony_ci * pci_cfg_space_size - Get the configuration space size of the PCI device 16228c2ecf20Sopenharmony_ci * @dev: PCI device 16238c2ecf20Sopenharmony_ci * 16248c2ecf20Sopenharmony_ci * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices 16258c2ecf20Sopenharmony_ci * have 4096 bytes. Even if the device is capable, that doesn't mean we can 16268c2ecf20Sopenharmony_ci * access it. Maybe we don't have a way to generate extended config space 16278c2ecf20Sopenharmony_ci * accesses, or the device is behind a reverse Express bridge. So we try 16288c2ecf20Sopenharmony_ci * reading the dword at 0x100 which must either be 0 or a valid extended 16298c2ecf20Sopenharmony_ci * capability header. 16308c2ecf20Sopenharmony_ci */ 16318c2ecf20Sopenharmony_cistatic int pci_cfg_space_size_ext(struct pci_dev *dev) 16328c2ecf20Sopenharmony_ci{ 16338c2ecf20Sopenharmony_ci u32 status; 16348c2ecf20Sopenharmony_ci int pos = PCI_CFG_SPACE_SIZE; 16358c2ecf20Sopenharmony_ci 16368c2ecf20Sopenharmony_ci if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) 16378c2ecf20Sopenharmony_ci return PCI_CFG_SPACE_SIZE; 16388c2ecf20Sopenharmony_ci if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev)) 16398c2ecf20Sopenharmony_ci return PCI_CFG_SPACE_SIZE; 16408c2ecf20Sopenharmony_ci 16418c2ecf20Sopenharmony_ci return PCI_CFG_SPACE_EXP_SIZE; 16428c2ecf20Sopenharmony_ci} 16438c2ecf20Sopenharmony_ci 16448c2ecf20Sopenharmony_ciint pci_cfg_space_size(struct pci_dev *dev) 16458c2ecf20Sopenharmony_ci{ 16468c2ecf20Sopenharmony_ci int pos; 16478c2ecf20Sopenharmony_ci u32 status; 16488c2ecf20Sopenharmony_ci u16 class; 16498c2ecf20Sopenharmony_ci 16508c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_IOV 16518c2ecf20Sopenharmony_ci /* 16528c2ecf20Sopenharmony_ci * Per the SR-IOV specification (rev 1.1, sec 3.5), VFs are required to 16538c2ecf20Sopenharmony_ci * implement a PCIe capability and therefore must implement extended 16548c2ecf20Sopenharmony_ci * config space. We can skip the NO_EXTCFG test below and the 16558c2ecf20Sopenharmony_ci * reachability/aliasing test in pci_cfg_space_size_ext() by virtue of 16568c2ecf20Sopenharmony_ci * the fact that the SR-IOV capability on the PF resides in extended 16578c2ecf20Sopenharmony_ci * config space and must be accessible and non-aliased to have enabled 16588c2ecf20Sopenharmony_ci * support for this VF. This is a micro performance optimization for 16598c2ecf20Sopenharmony_ci * systems supporting many VFs. 16608c2ecf20Sopenharmony_ci */ 16618c2ecf20Sopenharmony_ci if (dev->is_virtfn) 16628c2ecf20Sopenharmony_ci return PCI_CFG_SPACE_EXP_SIZE; 16638c2ecf20Sopenharmony_ci#endif 16648c2ecf20Sopenharmony_ci 16658c2ecf20Sopenharmony_ci if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_EXTCFG) 16668c2ecf20Sopenharmony_ci return PCI_CFG_SPACE_SIZE; 16678c2ecf20Sopenharmony_ci 16688c2ecf20Sopenharmony_ci class = dev->class >> 8; 16698c2ecf20Sopenharmony_ci if (class == PCI_CLASS_BRIDGE_HOST) 16708c2ecf20Sopenharmony_ci return pci_cfg_space_size_ext(dev); 16718c2ecf20Sopenharmony_ci 16728c2ecf20Sopenharmony_ci if (pci_is_pcie(dev)) 16738c2ecf20Sopenharmony_ci return pci_cfg_space_size_ext(dev); 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); 16768c2ecf20Sopenharmony_ci if (!pos) 16778c2ecf20Sopenharmony_ci return PCI_CFG_SPACE_SIZE; 16788c2ecf20Sopenharmony_ci 16798c2ecf20Sopenharmony_ci pci_read_config_dword(dev, pos + PCI_X_STATUS, &status); 16808c2ecf20Sopenharmony_ci if (status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)) 16818c2ecf20Sopenharmony_ci return pci_cfg_space_size_ext(dev); 16828c2ecf20Sopenharmony_ci 16838c2ecf20Sopenharmony_ci return PCI_CFG_SPACE_SIZE; 16848c2ecf20Sopenharmony_ci} 16858c2ecf20Sopenharmony_ci 16868c2ecf20Sopenharmony_cistatic u32 pci_class(struct pci_dev *dev) 16878c2ecf20Sopenharmony_ci{ 16888c2ecf20Sopenharmony_ci u32 class; 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_IOV 16918c2ecf20Sopenharmony_ci if (dev->is_virtfn) 16928c2ecf20Sopenharmony_ci return dev->physfn->sriov->class; 16938c2ecf20Sopenharmony_ci#endif 16948c2ecf20Sopenharmony_ci pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); 16958c2ecf20Sopenharmony_ci return class; 16968c2ecf20Sopenharmony_ci} 16978c2ecf20Sopenharmony_ci 16988c2ecf20Sopenharmony_cistatic void pci_subsystem_ids(struct pci_dev *dev, u16 *vendor, u16 *device) 16998c2ecf20Sopenharmony_ci{ 17008c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_IOV 17018c2ecf20Sopenharmony_ci if (dev->is_virtfn) { 17028c2ecf20Sopenharmony_ci *vendor = dev->physfn->sriov->subsystem_vendor; 17038c2ecf20Sopenharmony_ci *device = dev->physfn->sriov->subsystem_device; 17048c2ecf20Sopenharmony_ci return; 17058c2ecf20Sopenharmony_ci } 17068c2ecf20Sopenharmony_ci#endif 17078c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, vendor); 17088c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_SUBSYSTEM_ID, device); 17098c2ecf20Sopenharmony_ci} 17108c2ecf20Sopenharmony_ci 17118c2ecf20Sopenharmony_cistatic u8 pci_hdr_type(struct pci_dev *dev) 17128c2ecf20Sopenharmony_ci{ 17138c2ecf20Sopenharmony_ci u8 hdr_type; 17148c2ecf20Sopenharmony_ci 17158c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_IOV 17168c2ecf20Sopenharmony_ci if (dev->is_virtfn) 17178c2ecf20Sopenharmony_ci return dev->physfn->sriov->hdr_type; 17188c2ecf20Sopenharmony_ci#endif 17198c2ecf20Sopenharmony_ci pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type); 17208c2ecf20Sopenharmony_ci return hdr_type; 17218c2ecf20Sopenharmony_ci} 17228c2ecf20Sopenharmony_ci 17238c2ecf20Sopenharmony_ci#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) 17248c2ecf20Sopenharmony_ci 17258c2ecf20Sopenharmony_cistatic void pci_msi_setup_pci_dev(struct pci_dev *dev) 17268c2ecf20Sopenharmony_ci{ 17278c2ecf20Sopenharmony_ci /* 17288c2ecf20Sopenharmony_ci * Disable the MSI hardware to avoid screaming interrupts 17298c2ecf20Sopenharmony_ci * during boot. This is the power on reset default so 17308c2ecf20Sopenharmony_ci * usually this should be a noop. 17318c2ecf20Sopenharmony_ci */ 17328c2ecf20Sopenharmony_ci dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI); 17338c2ecf20Sopenharmony_ci if (dev->msi_cap) 17348c2ecf20Sopenharmony_ci pci_msi_set_enable(dev, 0); 17358c2ecf20Sopenharmony_ci 17368c2ecf20Sopenharmony_ci dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); 17378c2ecf20Sopenharmony_ci if (dev->msix_cap) 17388c2ecf20Sopenharmony_ci pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); 17398c2ecf20Sopenharmony_ci} 17408c2ecf20Sopenharmony_ci 17418c2ecf20Sopenharmony_ci/** 17428c2ecf20Sopenharmony_ci * pci_intx_mask_broken - Test PCI_COMMAND_INTX_DISABLE writability 17438c2ecf20Sopenharmony_ci * @dev: PCI device 17448c2ecf20Sopenharmony_ci * 17458c2ecf20Sopenharmony_ci * Test whether PCI_COMMAND_INTX_DISABLE is writable for @dev. Check this 17468c2ecf20Sopenharmony_ci * at enumeration-time to avoid modifying PCI_COMMAND at run-time. 17478c2ecf20Sopenharmony_ci */ 17488c2ecf20Sopenharmony_cistatic int pci_intx_mask_broken(struct pci_dev *dev) 17498c2ecf20Sopenharmony_ci{ 17508c2ecf20Sopenharmony_ci u16 orig, toggle, new; 17518c2ecf20Sopenharmony_ci 17528c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_COMMAND, &orig); 17538c2ecf20Sopenharmony_ci toggle = orig ^ PCI_COMMAND_INTX_DISABLE; 17548c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, toggle); 17558c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_COMMAND, &new); 17568c2ecf20Sopenharmony_ci 17578c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, orig); 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci /* 17608c2ecf20Sopenharmony_ci * PCI_COMMAND_INTX_DISABLE was reserved and read-only prior to PCI 17618c2ecf20Sopenharmony_ci * r2.3, so strictly speaking, a device is not *broken* if it's not 17628c2ecf20Sopenharmony_ci * writable. But we'll live with the misnomer for now. 17638c2ecf20Sopenharmony_ci */ 17648c2ecf20Sopenharmony_ci if (new != toggle) 17658c2ecf20Sopenharmony_ci return 1; 17668c2ecf20Sopenharmony_ci return 0; 17678c2ecf20Sopenharmony_ci} 17688c2ecf20Sopenharmony_ci 17698c2ecf20Sopenharmony_cistatic void early_dump_pci_device(struct pci_dev *pdev) 17708c2ecf20Sopenharmony_ci{ 17718c2ecf20Sopenharmony_ci u32 value[256 / 4]; 17728c2ecf20Sopenharmony_ci int i; 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_ci pci_info(pdev, "config space:\n"); 17758c2ecf20Sopenharmony_ci 17768c2ecf20Sopenharmony_ci for (i = 0; i < 256; i += 4) 17778c2ecf20Sopenharmony_ci pci_read_config_dword(pdev, i, &value[i / 4]); 17788c2ecf20Sopenharmony_ci 17798c2ecf20Sopenharmony_ci print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, 17808c2ecf20Sopenharmony_ci value, 256, false); 17818c2ecf20Sopenharmony_ci} 17828c2ecf20Sopenharmony_ci 17838c2ecf20Sopenharmony_ci/** 17848c2ecf20Sopenharmony_ci * pci_setup_device - Fill in class and map information of a device 17858c2ecf20Sopenharmony_ci * @dev: the device structure to fill 17868c2ecf20Sopenharmony_ci * 17878c2ecf20Sopenharmony_ci * Initialize the device structure with information about the device's 17888c2ecf20Sopenharmony_ci * vendor,class,memory and IO-space addresses, IRQ lines etc. 17898c2ecf20Sopenharmony_ci * Called at initialisation of the PCI subsystem and by CardBus services. 17908c2ecf20Sopenharmony_ci * Returns 0 on success and negative if unknown type of device (not normal, 17918c2ecf20Sopenharmony_ci * bridge or CardBus). 17928c2ecf20Sopenharmony_ci */ 17938c2ecf20Sopenharmony_ciint pci_setup_device(struct pci_dev *dev) 17948c2ecf20Sopenharmony_ci{ 17958c2ecf20Sopenharmony_ci u32 class; 17968c2ecf20Sopenharmony_ci u16 cmd; 17978c2ecf20Sopenharmony_ci u8 hdr_type; 17988c2ecf20Sopenharmony_ci int pos = 0; 17998c2ecf20Sopenharmony_ci struct pci_bus_region region; 18008c2ecf20Sopenharmony_ci struct resource *res; 18018c2ecf20Sopenharmony_ci 18028c2ecf20Sopenharmony_ci hdr_type = pci_hdr_type(dev); 18038c2ecf20Sopenharmony_ci 18048c2ecf20Sopenharmony_ci dev->sysdata = dev->bus->sysdata; 18058c2ecf20Sopenharmony_ci dev->dev.parent = dev->bus->bridge; 18068c2ecf20Sopenharmony_ci dev->dev.bus = &pci_bus_type; 18078c2ecf20Sopenharmony_ci dev->hdr_type = hdr_type & 0x7f; 18088c2ecf20Sopenharmony_ci dev->multifunction = !!(hdr_type & 0x80); 18098c2ecf20Sopenharmony_ci dev->error_state = pci_channel_io_normal; 18108c2ecf20Sopenharmony_ci set_pcie_port_type(dev); 18118c2ecf20Sopenharmony_ci 18128c2ecf20Sopenharmony_ci pci_dev_assign_slot(dev); 18138c2ecf20Sopenharmony_ci 18148c2ecf20Sopenharmony_ci /* 18158c2ecf20Sopenharmony_ci * Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) 18168c2ecf20Sopenharmony_ci * set this higher, assuming the system even supports it. 18178c2ecf20Sopenharmony_ci */ 18188c2ecf20Sopenharmony_ci dev->dma_mask = 0xffffffff; 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), 18218c2ecf20Sopenharmony_ci dev->bus->number, PCI_SLOT(dev->devfn), 18228c2ecf20Sopenharmony_ci PCI_FUNC(dev->devfn)); 18238c2ecf20Sopenharmony_ci 18248c2ecf20Sopenharmony_ci class = pci_class(dev); 18258c2ecf20Sopenharmony_ci 18268c2ecf20Sopenharmony_ci dev->revision = class & 0xff; 18278c2ecf20Sopenharmony_ci dev->class = class >> 8; /* upper 3 bytes */ 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci if (pci_early_dump) 18308c2ecf20Sopenharmony_ci early_dump_pci_device(dev); 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ci /* Need to have dev->class ready */ 18338c2ecf20Sopenharmony_ci dev->cfg_size = pci_cfg_space_size(dev); 18348c2ecf20Sopenharmony_ci 18358c2ecf20Sopenharmony_ci /* Need to have dev->cfg_size ready */ 18368c2ecf20Sopenharmony_ci set_pcie_thunderbolt(dev); 18378c2ecf20Sopenharmony_ci 18388c2ecf20Sopenharmony_ci set_pcie_untrusted(dev); 18398c2ecf20Sopenharmony_ci 18408c2ecf20Sopenharmony_ci /* "Unknown power state" */ 18418c2ecf20Sopenharmony_ci dev->current_state = PCI_UNKNOWN; 18428c2ecf20Sopenharmony_ci 18438c2ecf20Sopenharmony_ci /* Early fixups, before probing the BARs */ 18448c2ecf20Sopenharmony_ci pci_fixup_device(pci_fixup_early, dev); 18458c2ecf20Sopenharmony_ci 18468c2ecf20Sopenharmony_ci pci_info(dev, "[%04x:%04x] type %02x class %#08x\n", 18478c2ecf20Sopenharmony_ci dev->vendor, dev->device, dev->hdr_type, dev->class); 18488c2ecf20Sopenharmony_ci 18498c2ecf20Sopenharmony_ci /* Device class may be changed after fixup */ 18508c2ecf20Sopenharmony_ci class = dev->class >> 8; 18518c2ecf20Sopenharmony_ci 18528c2ecf20Sopenharmony_ci if (dev->non_compliant_bars && !dev->mmio_always_on) { 18538c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_COMMAND, &cmd); 18548c2ecf20Sopenharmony_ci if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { 18558c2ecf20Sopenharmony_ci pci_info(dev, "device has non-compliant BARs; disabling IO/MEM decoding\n"); 18568c2ecf20Sopenharmony_ci cmd &= ~PCI_COMMAND_IO; 18578c2ecf20Sopenharmony_ci cmd &= ~PCI_COMMAND_MEMORY; 18588c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, cmd); 18598c2ecf20Sopenharmony_ci } 18608c2ecf20Sopenharmony_ci } 18618c2ecf20Sopenharmony_ci 18628c2ecf20Sopenharmony_ci dev->broken_intx_masking = pci_intx_mask_broken(dev); 18638c2ecf20Sopenharmony_ci 18648c2ecf20Sopenharmony_ci switch (dev->hdr_type) { /* header type */ 18658c2ecf20Sopenharmony_ci case PCI_HEADER_TYPE_NORMAL: /* standard header */ 18668c2ecf20Sopenharmony_ci if (class == PCI_CLASS_BRIDGE_PCI) 18678c2ecf20Sopenharmony_ci goto bad; 18688c2ecf20Sopenharmony_ci pci_read_irq(dev); 18698c2ecf20Sopenharmony_ci pci_read_bases(dev, 6, PCI_ROM_ADDRESS); 18708c2ecf20Sopenharmony_ci 18718c2ecf20Sopenharmony_ci pci_subsystem_ids(dev, &dev->subsystem_vendor, &dev->subsystem_device); 18728c2ecf20Sopenharmony_ci 18738c2ecf20Sopenharmony_ci /* 18748c2ecf20Sopenharmony_ci * Do the ugly legacy mode stuff here rather than broken chip 18758c2ecf20Sopenharmony_ci * quirk code. Legacy mode ATA controllers have fixed 18768c2ecf20Sopenharmony_ci * addresses. These are not always echoed in BAR0-3, and 18778c2ecf20Sopenharmony_ci * BAR0-3 in a few cases contain junk! 18788c2ecf20Sopenharmony_ci */ 18798c2ecf20Sopenharmony_ci if (class == PCI_CLASS_STORAGE_IDE) { 18808c2ecf20Sopenharmony_ci u8 progif; 18818c2ecf20Sopenharmony_ci pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); 18828c2ecf20Sopenharmony_ci if ((progif & 1) == 0) { 18838c2ecf20Sopenharmony_ci region.start = 0x1F0; 18848c2ecf20Sopenharmony_ci region.end = 0x1F7; 18858c2ecf20Sopenharmony_ci res = &dev->resource[0]; 18868c2ecf20Sopenharmony_ci res->flags = LEGACY_IO_RESOURCE; 18878c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 18888c2ecf20Sopenharmony_ci pci_info(dev, "legacy IDE quirk: reg 0x10: %pR\n", 18898c2ecf20Sopenharmony_ci res); 18908c2ecf20Sopenharmony_ci region.start = 0x3F6; 18918c2ecf20Sopenharmony_ci region.end = 0x3F6; 18928c2ecf20Sopenharmony_ci res = &dev->resource[1]; 18938c2ecf20Sopenharmony_ci res->flags = LEGACY_IO_RESOURCE; 18948c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 18958c2ecf20Sopenharmony_ci pci_info(dev, "legacy IDE quirk: reg 0x14: %pR\n", 18968c2ecf20Sopenharmony_ci res); 18978c2ecf20Sopenharmony_ci } 18988c2ecf20Sopenharmony_ci if ((progif & 4) == 0) { 18998c2ecf20Sopenharmony_ci region.start = 0x170; 19008c2ecf20Sopenharmony_ci region.end = 0x177; 19018c2ecf20Sopenharmony_ci res = &dev->resource[2]; 19028c2ecf20Sopenharmony_ci res->flags = LEGACY_IO_RESOURCE; 19038c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 19048c2ecf20Sopenharmony_ci pci_info(dev, "legacy IDE quirk: reg 0x18: %pR\n", 19058c2ecf20Sopenharmony_ci res); 19068c2ecf20Sopenharmony_ci region.start = 0x376; 19078c2ecf20Sopenharmony_ci region.end = 0x376; 19088c2ecf20Sopenharmony_ci res = &dev->resource[3]; 19098c2ecf20Sopenharmony_ci res->flags = LEGACY_IO_RESOURCE; 19108c2ecf20Sopenharmony_ci pcibios_bus_to_resource(dev->bus, res, ®ion); 19118c2ecf20Sopenharmony_ci pci_info(dev, "legacy IDE quirk: reg 0x1c: %pR\n", 19128c2ecf20Sopenharmony_ci res); 19138c2ecf20Sopenharmony_ci } 19148c2ecf20Sopenharmony_ci } 19158c2ecf20Sopenharmony_ci break; 19168c2ecf20Sopenharmony_ci 19178c2ecf20Sopenharmony_ci case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ 19188c2ecf20Sopenharmony_ci /* 19198c2ecf20Sopenharmony_ci * The PCI-to-PCI bridge spec requires that subtractive 19208c2ecf20Sopenharmony_ci * decoding (i.e. transparent) bridge must have programming 19218c2ecf20Sopenharmony_ci * interface code of 0x01. 19228c2ecf20Sopenharmony_ci */ 19238c2ecf20Sopenharmony_ci pci_read_irq(dev); 19248c2ecf20Sopenharmony_ci dev->transparent = ((dev->class & 0xff) == 1); 19258c2ecf20Sopenharmony_ci pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); 19268c2ecf20Sopenharmony_ci pci_read_bridge_windows(dev); 19278c2ecf20Sopenharmony_ci set_pcie_hotplug_bridge(dev); 19288c2ecf20Sopenharmony_ci pos = pci_find_capability(dev, PCI_CAP_ID_SSVID); 19298c2ecf20Sopenharmony_ci if (pos) { 19308c2ecf20Sopenharmony_ci pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID, &dev->subsystem_vendor); 19318c2ecf20Sopenharmony_ci pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID, &dev->subsystem_device); 19328c2ecf20Sopenharmony_ci } 19338c2ecf20Sopenharmony_ci break; 19348c2ecf20Sopenharmony_ci 19358c2ecf20Sopenharmony_ci case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ 19368c2ecf20Sopenharmony_ci if (class != PCI_CLASS_BRIDGE_CARDBUS) 19378c2ecf20Sopenharmony_ci goto bad; 19388c2ecf20Sopenharmony_ci pci_read_irq(dev); 19398c2ecf20Sopenharmony_ci pci_read_bases(dev, 1, 0); 19408c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); 19418c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device); 19428c2ecf20Sopenharmony_ci break; 19438c2ecf20Sopenharmony_ci 19448c2ecf20Sopenharmony_ci default: /* unknown header */ 19458c2ecf20Sopenharmony_ci pci_err(dev, "unknown header type %02x, ignoring device\n", 19468c2ecf20Sopenharmony_ci dev->hdr_type); 19478c2ecf20Sopenharmony_ci return -EIO; 19488c2ecf20Sopenharmony_ci 19498c2ecf20Sopenharmony_ci bad: 19508c2ecf20Sopenharmony_ci pci_err(dev, "ignoring class %#08x (doesn't match header type %02x)\n", 19518c2ecf20Sopenharmony_ci dev->class, dev->hdr_type); 19528c2ecf20Sopenharmony_ci dev->class = PCI_CLASS_NOT_DEFINED << 8; 19538c2ecf20Sopenharmony_ci } 19548c2ecf20Sopenharmony_ci 19558c2ecf20Sopenharmony_ci /* We found a fine healthy device, go go go... */ 19568c2ecf20Sopenharmony_ci return 0; 19578c2ecf20Sopenharmony_ci} 19588c2ecf20Sopenharmony_ci 19598c2ecf20Sopenharmony_cistatic void pci_configure_mps(struct pci_dev *dev) 19608c2ecf20Sopenharmony_ci{ 19618c2ecf20Sopenharmony_ci struct pci_dev *bridge = pci_upstream_bridge(dev); 19628c2ecf20Sopenharmony_ci int mps, mpss, p_mps, rc; 19638c2ecf20Sopenharmony_ci 19648c2ecf20Sopenharmony_ci if (!pci_is_pcie(dev)) 19658c2ecf20Sopenharmony_ci return; 19668c2ecf20Sopenharmony_ci 19678c2ecf20Sopenharmony_ci /* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */ 19688c2ecf20Sopenharmony_ci if (dev->is_virtfn) 19698c2ecf20Sopenharmony_ci return; 19708c2ecf20Sopenharmony_ci 19718c2ecf20Sopenharmony_ci /* 19728c2ecf20Sopenharmony_ci * For Root Complex Integrated Endpoints, program the maximum 19738c2ecf20Sopenharmony_ci * supported value unless limited by the PCIE_BUS_PEER2PEER case. 19748c2ecf20Sopenharmony_ci */ 19758c2ecf20Sopenharmony_ci if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) { 19768c2ecf20Sopenharmony_ci if (pcie_bus_config == PCIE_BUS_PEER2PEER) 19778c2ecf20Sopenharmony_ci mps = 128; 19788c2ecf20Sopenharmony_ci else 19798c2ecf20Sopenharmony_ci mps = 128 << dev->pcie_mpss; 19808c2ecf20Sopenharmony_ci rc = pcie_set_mps(dev, mps); 19818c2ecf20Sopenharmony_ci if (rc) { 19828c2ecf20Sopenharmony_ci pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", 19838c2ecf20Sopenharmony_ci mps); 19848c2ecf20Sopenharmony_ci } 19858c2ecf20Sopenharmony_ci return; 19868c2ecf20Sopenharmony_ci } 19878c2ecf20Sopenharmony_ci 19888c2ecf20Sopenharmony_ci if (!bridge || !pci_is_pcie(bridge)) 19898c2ecf20Sopenharmony_ci return; 19908c2ecf20Sopenharmony_ci 19918c2ecf20Sopenharmony_ci mps = pcie_get_mps(dev); 19928c2ecf20Sopenharmony_ci p_mps = pcie_get_mps(bridge); 19938c2ecf20Sopenharmony_ci 19948c2ecf20Sopenharmony_ci if (mps == p_mps) 19958c2ecf20Sopenharmony_ci return; 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_ci if (pcie_bus_config == PCIE_BUS_TUNE_OFF) { 19988c2ecf20Sopenharmony_ci pci_warn(dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", 19998c2ecf20Sopenharmony_ci mps, pci_name(bridge), p_mps); 20008c2ecf20Sopenharmony_ci return; 20018c2ecf20Sopenharmony_ci } 20028c2ecf20Sopenharmony_ci 20038c2ecf20Sopenharmony_ci /* 20048c2ecf20Sopenharmony_ci * Fancier MPS configuration is done later by 20058c2ecf20Sopenharmony_ci * pcie_bus_configure_settings() 20068c2ecf20Sopenharmony_ci */ 20078c2ecf20Sopenharmony_ci if (pcie_bus_config != PCIE_BUS_DEFAULT) 20088c2ecf20Sopenharmony_ci return; 20098c2ecf20Sopenharmony_ci 20108c2ecf20Sopenharmony_ci mpss = 128 << dev->pcie_mpss; 20118c2ecf20Sopenharmony_ci if (mpss < p_mps && pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) { 20128c2ecf20Sopenharmony_ci pcie_set_mps(bridge, mpss); 20138c2ecf20Sopenharmony_ci pci_info(dev, "Upstream bridge's Max Payload Size set to %d (was %d, max %d)\n", 20148c2ecf20Sopenharmony_ci mpss, p_mps, 128 << bridge->pcie_mpss); 20158c2ecf20Sopenharmony_ci p_mps = pcie_get_mps(bridge); 20168c2ecf20Sopenharmony_ci } 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci rc = pcie_set_mps(dev, p_mps); 20198c2ecf20Sopenharmony_ci if (rc) { 20208c2ecf20Sopenharmony_ci pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", 20218c2ecf20Sopenharmony_ci p_mps); 20228c2ecf20Sopenharmony_ci return; 20238c2ecf20Sopenharmony_ci } 20248c2ecf20Sopenharmony_ci 20258c2ecf20Sopenharmony_ci pci_info(dev, "Max Payload Size set to %d (was %d, max %d)\n", 20268c2ecf20Sopenharmony_ci p_mps, mps, mpss); 20278c2ecf20Sopenharmony_ci} 20288c2ecf20Sopenharmony_ci 20298c2ecf20Sopenharmony_ciint pci_configure_extended_tags(struct pci_dev *dev, void *ign) 20308c2ecf20Sopenharmony_ci{ 20318c2ecf20Sopenharmony_ci struct pci_host_bridge *host; 20328c2ecf20Sopenharmony_ci u32 cap; 20338c2ecf20Sopenharmony_ci u16 ctl; 20348c2ecf20Sopenharmony_ci int ret; 20358c2ecf20Sopenharmony_ci 20368c2ecf20Sopenharmony_ci if (!pci_is_pcie(dev)) 20378c2ecf20Sopenharmony_ci return 0; 20388c2ecf20Sopenharmony_ci 20398c2ecf20Sopenharmony_ci ret = pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); 20408c2ecf20Sopenharmony_ci if (ret) 20418c2ecf20Sopenharmony_ci return 0; 20428c2ecf20Sopenharmony_ci 20438c2ecf20Sopenharmony_ci if (!(cap & PCI_EXP_DEVCAP_EXT_TAG)) 20448c2ecf20Sopenharmony_ci return 0; 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci ret = pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl); 20478c2ecf20Sopenharmony_ci if (ret) 20488c2ecf20Sopenharmony_ci return 0; 20498c2ecf20Sopenharmony_ci 20508c2ecf20Sopenharmony_ci host = pci_find_host_bridge(dev->bus); 20518c2ecf20Sopenharmony_ci if (!host) 20528c2ecf20Sopenharmony_ci return 0; 20538c2ecf20Sopenharmony_ci 20548c2ecf20Sopenharmony_ci /* 20558c2ecf20Sopenharmony_ci * If some device in the hierarchy doesn't handle Extended Tags 20568c2ecf20Sopenharmony_ci * correctly, make sure they're disabled. 20578c2ecf20Sopenharmony_ci */ 20588c2ecf20Sopenharmony_ci if (host->no_ext_tags) { 20598c2ecf20Sopenharmony_ci if (ctl & PCI_EXP_DEVCTL_EXT_TAG) { 20608c2ecf20Sopenharmony_ci pci_info(dev, "disabling Extended Tags\n"); 20618c2ecf20Sopenharmony_ci pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, 20628c2ecf20Sopenharmony_ci PCI_EXP_DEVCTL_EXT_TAG); 20638c2ecf20Sopenharmony_ci } 20648c2ecf20Sopenharmony_ci return 0; 20658c2ecf20Sopenharmony_ci } 20668c2ecf20Sopenharmony_ci 20678c2ecf20Sopenharmony_ci if (!(ctl & PCI_EXP_DEVCTL_EXT_TAG)) { 20688c2ecf20Sopenharmony_ci pci_info(dev, "enabling Extended Tags\n"); 20698c2ecf20Sopenharmony_ci pcie_capability_set_word(dev, PCI_EXP_DEVCTL, 20708c2ecf20Sopenharmony_ci PCI_EXP_DEVCTL_EXT_TAG); 20718c2ecf20Sopenharmony_ci } 20728c2ecf20Sopenharmony_ci return 0; 20738c2ecf20Sopenharmony_ci} 20748c2ecf20Sopenharmony_ci 20758c2ecf20Sopenharmony_ci/** 20768c2ecf20Sopenharmony_ci * pcie_relaxed_ordering_enabled - Probe for PCIe relaxed ordering enable 20778c2ecf20Sopenharmony_ci * @dev: PCI device to query 20788c2ecf20Sopenharmony_ci * 20798c2ecf20Sopenharmony_ci * Returns true if the device has enabled relaxed ordering attribute. 20808c2ecf20Sopenharmony_ci */ 20818c2ecf20Sopenharmony_cibool pcie_relaxed_ordering_enabled(struct pci_dev *dev) 20828c2ecf20Sopenharmony_ci{ 20838c2ecf20Sopenharmony_ci u16 v; 20848c2ecf20Sopenharmony_ci 20858c2ecf20Sopenharmony_ci pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &v); 20868c2ecf20Sopenharmony_ci 20878c2ecf20Sopenharmony_ci return !!(v & PCI_EXP_DEVCTL_RELAX_EN); 20888c2ecf20Sopenharmony_ci} 20898c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcie_relaxed_ordering_enabled); 20908c2ecf20Sopenharmony_ci 20918c2ecf20Sopenharmony_cistatic void pci_configure_relaxed_ordering(struct pci_dev *dev) 20928c2ecf20Sopenharmony_ci{ 20938c2ecf20Sopenharmony_ci struct pci_dev *root; 20948c2ecf20Sopenharmony_ci 20958c2ecf20Sopenharmony_ci /* PCI_EXP_DEVICE_RELAX_EN is RsvdP in VFs */ 20968c2ecf20Sopenharmony_ci if (dev->is_virtfn) 20978c2ecf20Sopenharmony_ci return; 20988c2ecf20Sopenharmony_ci 20998c2ecf20Sopenharmony_ci if (!pcie_relaxed_ordering_enabled(dev)) 21008c2ecf20Sopenharmony_ci return; 21018c2ecf20Sopenharmony_ci 21028c2ecf20Sopenharmony_ci /* 21038c2ecf20Sopenharmony_ci * For now, we only deal with Relaxed Ordering issues with Root 21048c2ecf20Sopenharmony_ci * Ports. Peer-to-Peer DMA is another can of worms. 21058c2ecf20Sopenharmony_ci */ 21068c2ecf20Sopenharmony_ci root = pcie_find_root_port(dev); 21078c2ecf20Sopenharmony_ci if (!root) 21088c2ecf20Sopenharmony_ci return; 21098c2ecf20Sopenharmony_ci 21108c2ecf20Sopenharmony_ci if (root->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) { 21118c2ecf20Sopenharmony_ci pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, 21128c2ecf20Sopenharmony_ci PCI_EXP_DEVCTL_RELAX_EN); 21138c2ecf20Sopenharmony_ci pci_info(dev, "Relaxed Ordering disabled because the Root Port didn't support it\n"); 21148c2ecf20Sopenharmony_ci } 21158c2ecf20Sopenharmony_ci} 21168c2ecf20Sopenharmony_ci 21178c2ecf20Sopenharmony_cistatic void pci_configure_ltr(struct pci_dev *dev) 21188c2ecf20Sopenharmony_ci{ 21198c2ecf20Sopenharmony_ci#ifdef CONFIG_PCIEASPM 21208c2ecf20Sopenharmony_ci struct pci_host_bridge *host = pci_find_host_bridge(dev->bus); 21218c2ecf20Sopenharmony_ci struct pci_dev *bridge; 21228c2ecf20Sopenharmony_ci u32 cap, ctl; 21238c2ecf20Sopenharmony_ci 21248c2ecf20Sopenharmony_ci if (!pci_is_pcie(dev)) 21258c2ecf20Sopenharmony_ci return; 21268c2ecf20Sopenharmony_ci 21278c2ecf20Sopenharmony_ci /* Read L1 PM substate capabilities */ 21288c2ecf20Sopenharmony_ci dev->l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS); 21298c2ecf20Sopenharmony_ci 21308c2ecf20Sopenharmony_ci pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap); 21318c2ecf20Sopenharmony_ci if (!(cap & PCI_EXP_DEVCAP2_LTR)) 21328c2ecf20Sopenharmony_ci return; 21338c2ecf20Sopenharmony_ci 21348c2ecf20Sopenharmony_ci pcie_capability_read_dword(dev, PCI_EXP_DEVCTL2, &ctl); 21358c2ecf20Sopenharmony_ci if (ctl & PCI_EXP_DEVCTL2_LTR_EN) { 21368c2ecf20Sopenharmony_ci if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) { 21378c2ecf20Sopenharmony_ci dev->ltr_path = 1; 21388c2ecf20Sopenharmony_ci return; 21398c2ecf20Sopenharmony_ci } 21408c2ecf20Sopenharmony_ci 21418c2ecf20Sopenharmony_ci bridge = pci_upstream_bridge(dev); 21428c2ecf20Sopenharmony_ci if (bridge && bridge->ltr_path) 21438c2ecf20Sopenharmony_ci dev->ltr_path = 1; 21448c2ecf20Sopenharmony_ci 21458c2ecf20Sopenharmony_ci return; 21468c2ecf20Sopenharmony_ci } 21478c2ecf20Sopenharmony_ci 21488c2ecf20Sopenharmony_ci if (!host->native_ltr) 21498c2ecf20Sopenharmony_ci return; 21508c2ecf20Sopenharmony_ci 21518c2ecf20Sopenharmony_ci /* 21528c2ecf20Sopenharmony_ci * Software must not enable LTR in an Endpoint unless the Root 21538c2ecf20Sopenharmony_ci * Complex and all intermediate Switches indicate support for LTR. 21548c2ecf20Sopenharmony_ci * PCIe r4.0, sec 6.18. 21558c2ecf20Sopenharmony_ci */ 21568c2ecf20Sopenharmony_ci if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT || 21578c2ecf20Sopenharmony_ci ((bridge = pci_upstream_bridge(dev)) && 21588c2ecf20Sopenharmony_ci bridge->ltr_path)) { 21598c2ecf20Sopenharmony_ci pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, 21608c2ecf20Sopenharmony_ci PCI_EXP_DEVCTL2_LTR_EN); 21618c2ecf20Sopenharmony_ci dev->ltr_path = 1; 21628c2ecf20Sopenharmony_ci } 21638c2ecf20Sopenharmony_ci#endif 21648c2ecf20Sopenharmony_ci} 21658c2ecf20Sopenharmony_ci 21668c2ecf20Sopenharmony_cistatic void pci_configure_eetlp_prefix(struct pci_dev *dev) 21678c2ecf20Sopenharmony_ci{ 21688c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_PASID 21698c2ecf20Sopenharmony_ci struct pci_dev *bridge; 21708c2ecf20Sopenharmony_ci int pcie_type; 21718c2ecf20Sopenharmony_ci u32 cap; 21728c2ecf20Sopenharmony_ci 21738c2ecf20Sopenharmony_ci if (!pci_is_pcie(dev)) 21748c2ecf20Sopenharmony_ci return; 21758c2ecf20Sopenharmony_ci 21768c2ecf20Sopenharmony_ci pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap); 21778c2ecf20Sopenharmony_ci if (!(cap & PCI_EXP_DEVCAP2_EE_PREFIX)) 21788c2ecf20Sopenharmony_ci return; 21798c2ecf20Sopenharmony_ci 21808c2ecf20Sopenharmony_ci pcie_type = pci_pcie_type(dev); 21818c2ecf20Sopenharmony_ci if (pcie_type == PCI_EXP_TYPE_ROOT_PORT || 21828c2ecf20Sopenharmony_ci pcie_type == PCI_EXP_TYPE_RC_END) 21838c2ecf20Sopenharmony_ci dev->eetlp_prefix_path = 1; 21848c2ecf20Sopenharmony_ci else { 21858c2ecf20Sopenharmony_ci bridge = pci_upstream_bridge(dev); 21868c2ecf20Sopenharmony_ci if (bridge && bridge->eetlp_prefix_path) 21878c2ecf20Sopenharmony_ci dev->eetlp_prefix_path = 1; 21888c2ecf20Sopenharmony_ci } 21898c2ecf20Sopenharmony_ci#endif 21908c2ecf20Sopenharmony_ci} 21918c2ecf20Sopenharmony_ci 21928c2ecf20Sopenharmony_cistatic void pci_configure_serr(struct pci_dev *dev) 21938c2ecf20Sopenharmony_ci{ 21948c2ecf20Sopenharmony_ci u16 control; 21958c2ecf20Sopenharmony_ci 21968c2ecf20Sopenharmony_ci if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 21978c2ecf20Sopenharmony_ci 21988c2ecf20Sopenharmony_ci /* 21998c2ecf20Sopenharmony_ci * A bridge will not forward ERR_ messages coming from an 22008c2ecf20Sopenharmony_ci * endpoint unless SERR# forwarding is enabled. 22018c2ecf20Sopenharmony_ci */ 22028c2ecf20Sopenharmony_ci pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &control); 22038c2ecf20Sopenharmony_ci if (!(control & PCI_BRIDGE_CTL_SERR)) { 22048c2ecf20Sopenharmony_ci control |= PCI_BRIDGE_CTL_SERR; 22058c2ecf20Sopenharmony_ci pci_write_config_word(dev, PCI_BRIDGE_CONTROL, control); 22068c2ecf20Sopenharmony_ci } 22078c2ecf20Sopenharmony_ci } 22088c2ecf20Sopenharmony_ci} 22098c2ecf20Sopenharmony_ci 22108c2ecf20Sopenharmony_cistatic void pci_configure_device(struct pci_dev *dev) 22118c2ecf20Sopenharmony_ci{ 22128c2ecf20Sopenharmony_ci pci_configure_mps(dev); 22138c2ecf20Sopenharmony_ci pci_configure_extended_tags(dev, NULL); 22148c2ecf20Sopenharmony_ci pci_configure_relaxed_ordering(dev); 22158c2ecf20Sopenharmony_ci pci_configure_ltr(dev); 22168c2ecf20Sopenharmony_ci pci_configure_eetlp_prefix(dev); 22178c2ecf20Sopenharmony_ci pci_configure_serr(dev); 22188c2ecf20Sopenharmony_ci 22198c2ecf20Sopenharmony_ci pci_acpi_program_hp_params(dev); 22208c2ecf20Sopenharmony_ci} 22218c2ecf20Sopenharmony_ci 22228c2ecf20Sopenharmony_cistatic void pci_release_capabilities(struct pci_dev *dev) 22238c2ecf20Sopenharmony_ci{ 22248c2ecf20Sopenharmony_ci pci_aer_exit(dev); 22258c2ecf20Sopenharmony_ci pci_vpd_release(dev); 22268c2ecf20Sopenharmony_ci pci_iov_release(dev); 22278c2ecf20Sopenharmony_ci pci_free_cap_save_buffers(dev); 22288c2ecf20Sopenharmony_ci} 22298c2ecf20Sopenharmony_ci 22308c2ecf20Sopenharmony_ci/** 22318c2ecf20Sopenharmony_ci * pci_release_dev - Free a PCI device structure when all users of it are 22328c2ecf20Sopenharmony_ci * finished 22338c2ecf20Sopenharmony_ci * @dev: device that's been disconnected 22348c2ecf20Sopenharmony_ci * 22358c2ecf20Sopenharmony_ci * Will be called only by the device core when all users of this PCI device are 22368c2ecf20Sopenharmony_ci * done. 22378c2ecf20Sopenharmony_ci */ 22388c2ecf20Sopenharmony_cistatic void pci_release_dev(struct device *dev) 22398c2ecf20Sopenharmony_ci{ 22408c2ecf20Sopenharmony_ci struct pci_dev *pci_dev; 22418c2ecf20Sopenharmony_ci 22428c2ecf20Sopenharmony_ci pci_dev = to_pci_dev(dev); 22438c2ecf20Sopenharmony_ci pci_release_capabilities(pci_dev); 22448c2ecf20Sopenharmony_ci pci_release_of_node(pci_dev); 22458c2ecf20Sopenharmony_ci pcibios_release_device(pci_dev); 22468c2ecf20Sopenharmony_ci pci_bus_put(pci_dev->bus); 22478c2ecf20Sopenharmony_ci kfree(pci_dev->driver_override); 22488c2ecf20Sopenharmony_ci bitmap_free(pci_dev->dma_alias_mask); 22498c2ecf20Sopenharmony_ci kfree(pci_dev); 22508c2ecf20Sopenharmony_ci} 22518c2ecf20Sopenharmony_ci 22528c2ecf20Sopenharmony_cistruct pci_dev *pci_alloc_dev(struct pci_bus *bus) 22538c2ecf20Sopenharmony_ci{ 22548c2ecf20Sopenharmony_ci struct pci_dev *dev; 22558c2ecf20Sopenharmony_ci 22568c2ecf20Sopenharmony_ci dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); 22578c2ecf20Sopenharmony_ci if (!dev) 22588c2ecf20Sopenharmony_ci return NULL; 22598c2ecf20Sopenharmony_ci 22608c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev->bus_list); 22618c2ecf20Sopenharmony_ci dev->dev.type = &pci_dev_type; 22628c2ecf20Sopenharmony_ci dev->bus = pci_bus_get(bus); 22638c2ecf20Sopenharmony_ci 22648c2ecf20Sopenharmony_ci return dev; 22658c2ecf20Sopenharmony_ci} 22668c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_alloc_dev); 22678c2ecf20Sopenharmony_ci 22688c2ecf20Sopenharmony_cistatic bool pci_bus_crs_vendor_id(u32 l) 22698c2ecf20Sopenharmony_ci{ 22708c2ecf20Sopenharmony_ci return (l & 0xffff) == 0x0001; 22718c2ecf20Sopenharmony_ci} 22728c2ecf20Sopenharmony_ci 22738c2ecf20Sopenharmony_cistatic bool pci_bus_wait_crs(struct pci_bus *bus, int devfn, u32 *l, 22748c2ecf20Sopenharmony_ci int timeout) 22758c2ecf20Sopenharmony_ci{ 22768c2ecf20Sopenharmony_ci int delay = 1; 22778c2ecf20Sopenharmony_ci 22788c2ecf20Sopenharmony_ci if (!pci_bus_crs_vendor_id(*l)) 22798c2ecf20Sopenharmony_ci return true; /* not a CRS completion */ 22808c2ecf20Sopenharmony_ci 22818c2ecf20Sopenharmony_ci if (!timeout) 22828c2ecf20Sopenharmony_ci return false; /* CRS, but caller doesn't want to wait */ 22838c2ecf20Sopenharmony_ci 22848c2ecf20Sopenharmony_ci /* 22858c2ecf20Sopenharmony_ci * We got the reserved Vendor ID that indicates a completion with 22868c2ecf20Sopenharmony_ci * Configuration Request Retry Status (CRS). Retry until we get a 22878c2ecf20Sopenharmony_ci * valid Vendor ID or we time out. 22888c2ecf20Sopenharmony_ci */ 22898c2ecf20Sopenharmony_ci while (pci_bus_crs_vendor_id(*l)) { 22908c2ecf20Sopenharmony_ci if (delay > timeout) { 22918c2ecf20Sopenharmony_ci pr_warn("pci %04x:%02x:%02x.%d: not ready after %dms; giving up\n", 22928c2ecf20Sopenharmony_ci pci_domain_nr(bus), bus->number, 22938c2ecf20Sopenharmony_ci PCI_SLOT(devfn), PCI_FUNC(devfn), delay - 1); 22948c2ecf20Sopenharmony_ci 22958c2ecf20Sopenharmony_ci return false; 22968c2ecf20Sopenharmony_ci } 22978c2ecf20Sopenharmony_ci if (delay >= 1000) 22988c2ecf20Sopenharmony_ci pr_info("pci %04x:%02x:%02x.%d: not ready after %dms; waiting\n", 22998c2ecf20Sopenharmony_ci pci_domain_nr(bus), bus->number, 23008c2ecf20Sopenharmony_ci PCI_SLOT(devfn), PCI_FUNC(devfn), delay - 1); 23018c2ecf20Sopenharmony_ci 23028c2ecf20Sopenharmony_ci msleep(delay); 23038c2ecf20Sopenharmony_ci delay *= 2; 23048c2ecf20Sopenharmony_ci 23058c2ecf20Sopenharmony_ci if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) 23068c2ecf20Sopenharmony_ci return false; 23078c2ecf20Sopenharmony_ci } 23088c2ecf20Sopenharmony_ci 23098c2ecf20Sopenharmony_ci if (delay >= 1000) 23108c2ecf20Sopenharmony_ci pr_info("pci %04x:%02x:%02x.%d: ready after %dms\n", 23118c2ecf20Sopenharmony_ci pci_domain_nr(bus), bus->number, 23128c2ecf20Sopenharmony_ci PCI_SLOT(devfn), PCI_FUNC(devfn), delay - 1); 23138c2ecf20Sopenharmony_ci 23148c2ecf20Sopenharmony_ci return true; 23158c2ecf20Sopenharmony_ci} 23168c2ecf20Sopenharmony_ci 23178c2ecf20Sopenharmony_cibool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, 23188c2ecf20Sopenharmony_ci int timeout) 23198c2ecf20Sopenharmony_ci{ 23208c2ecf20Sopenharmony_ci if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) 23218c2ecf20Sopenharmony_ci return false; 23228c2ecf20Sopenharmony_ci 23238c2ecf20Sopenharmony_ci /* Some broken boards return 0 or ~0 if a slot is empty: */ 23248c2ecf20Sopenharmony_ci if (*l == 0xffffffff || *l == 0x00000000 || 23258c2ecf20Sopenharmony_ci *l == 0x0000ffff || *l == 0xffff0000) 23268c2ecf20Sopenharmony_ci return false; 23278c2ecf20Sopenharmony_ci 23288c2ecf20Sopenharmony_ci if (pci_bus_crs_vendor_id(*l)) 23298c2ecf20Sopenharmony_ci return pci_bus_wait_crs(bus, devfn, l, timeout); 23308c2ecf20Sopenharmony_ci 23318c2ecf20Sopenharmony_ci return true; 23328c2ecf20Sopenharmony_ci} 23338c2ecf20Sopenharmony_ci 23348c2ecf20Sopenharmony_cibool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, 23358c2ecf20Sopenharmony_ci int timeout) 23368c2ecf20Sopenharmony_ci{ 23378c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_QUIRKS 23388c2ecf20Sopenharmony_ci struct pci_dev *bridge = bus->self; 23398c2ecf20Sopenharmony_ci 23408c2ecf20Sopenharmony_ci /* 23418c2ecf20Sopenharmony_ci * Certain IDT switches have an issue where they improperly trigger 23428c2ecf20Sopenharmony_ci * ACS Source Validation errors on completions for config reads. 23438c2ecf20Sopenharmony_ci */ 23448c2ecf20Sopenharmony_ci if (bridge && bridge->vendor == PCI_VENDOR_ID_IDT && 23458c2ecf20Sopenharmony_ci bridge->device == 0x80b5) 23468c2ecf20Sopenharmony_ci return pci_idt_bus_quirk(bus, devfn, l, timeout); 23478c2ecf20Sopenharmony_ci#endif 23488c2ecf20Sopenharmony_ci 23498c2ecf20Sopenharmony_ci return pci_bus_generic_read_dev_vendor_id(bus, devfn, l, timeout); 23508c2ecf20Sopenharmony_ci} 23518c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_bus_read_dev_vendor_id); 23528c2ecf20Sopenharmony_ci 23538c2ecf20Sopenharmony_ci/* 23548c2ecf20Sopenharmony_ci * Read the config data for a PCI device, sanity-check it, 23558c2ecf20Sopenharmony_ci * and fill in the dev structure. 23568c2ecf20Sopenharmony_ci */ 23578c2ecf20Sopenharmony_cistatic struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) 23588c2ecf20Sopenharmony_ci{ 23598c2ecf20Sopenharmony_ci struct pci_dev *dev; 23608c2ecf20Sopenharmony_ci u32 l; 23618c2ecf20Sopenharmony_ci 23628c2ecf20Sopenharmony_ci if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) 23638c2ecf20Sopenharmony_ci return NULL; 23648c2ecf20Sopenharmony_ci 23658c2ecf20Sopenharmony_ci dev = pci_alloc_dev(bus); 23668c2ecf20Sopenharmony_ci if (!dev) 23678c2ecf20Sopenharmony_ci return NULL; 23688c2ecf20Sopenharmony_ci 23698c2ecf20Sopenharmony_ci dev->devfn = devfn; 23708c2ecf20Sopenharmony_ci dev->vendor = l & 0xffff; 23718c2ecf20Sopenharmony_ci dev->device = (l >> 16) & 0xffff; 23728c2ecf20Sopenharmony_ci 23738c2ecf20Sopenharmony_ci pci_set_of_node(dev); 23748c2ecf20Sopenharmony_ci 23758c2ecf20Sopenharmony_ci if (pci_setup_device(dev)) { 23768c2ecf20Sopenharmony_ci pci_release_of_node(dev); 23778c2ecf20Sopenharmony_ci pci_bus_put(dev->bus); 23788c2ecf20Sopenharmony_ci kfree(dev); 23798c2ecf20Sopenharmony_ci return NULL; 23808c2ecf20Sopenharmony_ci } 23818c2ecf20Sopenharmony_ci 23828c2ecf20Sopenharmony_ci return dev; 23838c2ecf20Sopenharmony_ci} 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_civoid pcie_report_downtraining(struct pci_dev *dev) 23868c2ecf20Sopenharmony_ci{ 23878c2ecf20Sopenharmony_ci if (!pci_is_pcie(dev)) 23888c2ecf20Sopenharmony_ci return; 23898c2ecf20Sopenharmony_ci 23908c2ecf20Sopenharmony_ci /* Look from the device up to avoid downstream ports with no devices */ 23918c2ecf20Sopenharmony_ci if ((pci_pcie_type(dev) != PCI_EXP_TYPE_ENDPOINT) && 23928c2ecf20Sopenharmony_ci (pci_pcie_type(dev) != PCI_EXP_TYPE_LEG_END) && 23938c2ecf20Sopenharmony_ci (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM)) 23948c2ecf20Sopenharmony_ci return; 23958c2ecf20Sopenharmony_ci 23968c2ecf20Sopenharmony_ci /* Multi-function PCIe devices share the same link/status */ 23978c2ecf20Sopenharmony_ci if (PCI_FUNC(dev->devfn) != 0 || dev->is_virtfn) 23988c2ecf20Sopenharmony_ci return; 23998c2ecf20Sopenharmony_ci 24008c2ecf20Sopenharmony_ci /* Print link status only if the device is constrained by the fabric */ 24018c2ecf20Sopenharmony_ci __pcie_print_link_status(dev, false); 24028c2ecf20Sopenharmony_ci} 24038c2ecf20Sopenharmony_ci 24048c2ecf20Sopenharmony_cistatic void pci_init_capabilities(struct pci_dev *dev) 24058c2ecf20Sopenharmony_ci{ 24068c2ecf20Sopenharmony_ci pci_ea_init(dev); /* Enhanced Allocation */ 24078c2ecf20Sopenharmony_ci 24088c2ecf20Sopenharmony_ci /* Setup MSI caps & disable MSI/MSI-X interrupts */ 24098c2ecf20Sopenharmony_ci pci_msi_setup_pci_dev(dev); 24108c2ecf20Sopenharmony_ci 24118c2ecf20Sopenharmony_ci /* Buffers for saving PCIe and PCI-X capabilities */ 24128c2ecf20Sopenharmony_ci pci_allocate_cap_save_buffers(dev); 24138c2ecf20Sopenharmony_ci 24148c2ecf20Sopenharmony_ci pci_pm_init(dev); /* Power Management */ 24158c2ecf20Sopenharmony_ci pci_vpd_init(dev); /* Vital Product Data */ 24168c2ecf20Sopenharmony_ci pci_configure_ari(dev); /* Alternative Routing-ID Forwarding */ 24178c2ecf20Sopenharmony_ci pci_iov_init(dev); /* Single Root I/O Virtualization */ 24188c2ecf20Sopenharmony_ci pci_ats_init(dev); /* Address Translation Services */ 24198c2ecf20Sopenharmony_ci pci_pri_init(dev); /* Page Request Interface */ 24208c2ecf20Sopenharmony_ci pci_pasid_init(dev); /* Process Address Space ID */ 24218c2ecf20Sopenharmony_ci pci_acs_init(dev); /* Access Control Services */ 24228c2ecf20Sopenharmony_ci pci_ptm_init(dev); /* Precision Time Measurement */ 24238c2ecf20Sopenharmony_ci pci_aer_init(dev); /* Advanced Error Reporting */ 24248c2ecf20Sopenharmony_ci pci_dpc_init(dev); /* Downstream Port Containment */ 24258c2ecf20Sopenharmony_ci 24268c2ecf20Sopenharmony_ci pcie_report_downtraining(dev); 24278c2ecf20Sopenharmony_ci 24288c2ecf20Sopenharmony_ci if (pci_probe_reset_function(dev) == 0) 24298c2ecf20Sopenharmony_ci dev->reset_fn = 1; 24308c2ecf20Sopenharmony_ci} 24318c2ecf20Sopenharmony_ci 24328c2ecf20Sopenharmony_ci/* 24338c2ecf20Sopenharmony_ci * This is the equivalent of pci_host_bridge_msi_domain() that acts on 24348c2ecf20Sopenharmony_ci * devices. Firmware interfaces that can select the MSI domain on a 24358c2ecf20Sopenharmony_ci * per-device basis should be called from here. 24368c2ecf20Sopenharmony_ci */ 24378c2ecf20Sopenharmony_cistatic struct irq_domain *pci_dev_msi_domain(struct pci_dev *dev) 24388c2ecf20Sopenharmony_ci{ 24398c2ecf20Sopenharmony_ci struct irq_domain *d; 24408c2ecf20Sopenharmony_ci 24418c2ecf20Sopenharmony_ci /* 24428c2ecf20Sopenharmony_ci * If a domain has been set through the pcibios_add_device() 24438c2ecf20Sopenharmony_ci * callback, then this is the one (platform code knows best). 24448c2ecf20Sopenharmony_ci */ 24458c2ecf20Sopenharmony_ci d = dev_get_msi_domain(&dev->dev); 24468c2ecf20Sopenharmony_ci if (d) 24478c2ecf20Sopenharmony_ci return d; 24488c2ecf20Sopenharmony_ci 24498c2ecf20Sopenharmony_ci /* 24508c2ecf20Sopenharmony_ci * Let's see if we have a firmware interface able to provide 24518c2ecf20Sopenharmony_ci * the domain. 24528c2ecf20Sopenharmony_ci */ 24538c2ecf20Sopenharmony_ci d = pci_msi_get_device_domain(dev); 24548c2ecf20Sopenharmony_ci if (d) 24558c2ecf20Sopenharmony_ci return d; 24568c2ecf20Sopenharmony_ci 24578c2ecf20Sopenharmony_ci return NULL; 24588c2ecf20Sopenharmony_ci} 24598c2ecf20Sopenharmony_ci 24608c2ecf20Sopenharmony_cistatic void pci_set_msi_domain(struct pci_dev *dev) 24618c2ecf20Sopenharmony_ci{ 24628c2ecf20Sopenharmony_ci struct irq_domain *d; 24638c2ecf20Sopenharmony_ci 24648c2ecf20Sopenharmony_ci /* 24658c2ecf20Sopenharmony_ci * If the platform or firmware interfaces cannot supply a 24668c2ecf20Sopenharmony_ci * device-specific MSI domain, then inherit the default domain 24678c2ecf20Sopenharmony_ci * from the host bridge itself. 24688c2ecf20Sopenharmony_ci */ 24698c2ecf20Sopenharmony_ci d = pci_dev_msi_domain(dev); 24708c2ecf20Sopenharmony_ci if (!d) 24718c2ecf20Sopenharmony_ci d = dev_get_msi_domain(&dev->bus->dev); 24728c2ecf20Sopenharmony_ci 24738c2ecf20Sopenharmony_ci dev_set_msi_domain(&dev->dev, d); 24748c2ecf20Sopenharmony_ci} 24758c2ecf20Sopenharmony_ci 24768c2ecf20Sopenharmony_civoid pci_device_add(struct pci_dev *dev, struct pci_bus *bus) 24778c2ecf20Sopenharmony_ci{ 24788c2ecf20Sopenharmony_ci int ret; 24798c2ecf20Sopenharmony_ci 24808c2ecf20Sopenharmony_ci pci_configure_device(dev); 24818c2ecf20Sopenharmony_ci 24828c2ecf20Sopenharmony_ci device_initialize(&dev->dev); 24838c2ecf20Sopenharmony_ci dev->dev.release = pci_release_dev; 24848c2ecf20Sopenharmony_ci 24858c2ecf20Sopenharmony_ci set_dev_node(&dev->dev, pcibus_to_node(bus)); 24868c2ecf20Sopenharmony_ci dev->dev.dma_mask = &dev->dma_mask; 24878c2ecf20Sopenharmony_ci dev->dev.dma_parms = &dev->dma_parms; 24888c2ecf20Sopenharmony_ci dev->dev.coherent_dma_mask = 0xffffffffull; 24898c2ecf20Sopenharmony_ci 24908c2ecf20Sopenharmony_ci dma_set_max_seg_size(&dev->dev, 65536); 24918c2ecf20Sopenharmony_ci dma_set_seg_boundary(&dev->dev, 0xffffffff); 24928c2ecf20Sopenharmony_ci 24938c2ecf20Sopenharmony_ci /* Fix up broken headers */ 24948c2ecf20Sopenharmony_ci pci_fixup_device(pci_fixup_header, dev); 24958c2ecf20Sopenharmony_ci 24968c2ecf20Sopenharmony_ci pci_reassigndev_resource_alignment(dev); 24978c2ecf20Sopenharmony_ci 24988c2ecf20Sopenharmony_ci dev->state_saved = false; 24998c2ecf20Sopenharmony_ci 25008c2ecf20Sopenharmony_ci pci_init_capabilities(dev); 25018c2ecf20Sopenharmony_ci 25028c2ecf20Sopenharmony_ci /* 25038c2ecf20Sopenharmony_ci * Add the device to our list of discovered devices 25048c2ecf20Sopenharmony_ci * and the bus list for fixup functions, etc. 25058c2ecf20Sopenharmony_ci */ 25068c2ecf20Sopenharmony_ci down_write(&pci_bus_sem); 25078c2ecf20Sopenharmony_ci list_add_tail(&dev->bus_list, &bus->devices); 25088c2ecf20Sopenharmony_ci up_write(&pci_bus_sem); 25098c2ecf20Sopenharmony_ci 25108c2ecf20Sopenharmony_ci ret = pcibios_add_device(dev); 25118c2ecf20Sopenharmony_ci WARN_ON(ret < 0); 25128c2ecf20Sopenharmony_ci 25138c2ecf20Sopenharmony_ci /* Set up MSI IRQ domain */ 25148c2ecf20Sopenharmony_ci pci_set_msi_domain(dev); 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_ci /* Notifier could use PCI capabilities */ 25178c2ecf20Sopenharmony_ci dev->match_driver = false; 25188c2ecf20Sopenharmony_ci ret = device_add(&dev->dev); 25198c2ecf20Sopenharmony_ci WARN_ON(ret < 0); 25208c2ecf20Sopenharmony_ci} 25218c2ecf20Sopenharmony_ci 25228c2ecf20Sopenharmony_cistruct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) 25238c2ecf20Sopenharmony_ci{ 25248c2ecf20Sopenharmony_ci struct pci_dev *dev; 25258c2ecf20Sopenharmony_ci 25268c2ecf20Sopenharmony_ci dev = pci_get_slot(bus, devfn); 25278c2ecf20Sopenharmony_ci if (dev) { 25288c2ecf20Sopenharmony_ci pci_dev_put(dev); 25298c2ecf20Sopenharmony_ci return dev; 25308c2ecf20Sopenharmony_ci } 25318c2ecf20Sopenharmony_ci 25328c2ecf20Sopenharmony_ci dev = pci_scan_device(bus, devfn); 25338c2ecf20Sopenharmony_ci if (!dev) 25348c2ecf20Sopenharmony_ci return NULL; 25358c2ecf20Sopenharmony_ci 25368c2ecf20Sopenharmony_ci pci_device_add(dev, bus); 25378c2ecf20Sopenharmony_ci 25388c2ecf20Sopenharmony_ci return dev; 25398c2ecf20Sopenharmony_ci} 25408c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_scan_single_device); 25418c2ecf20Sopenharmony_ci 25428c2ecf20Sopenharmony_cistatic unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn) 25438c2ecf20Sopenharmony_ci{ 25448c2ecf20Sopenharmony_ci int pos; 25458c2ecf20Sopenharmony_ci u16 cap = 0; 25468c2ecf20Sopenharmony_ci unsigned next_fn; 25478c2ecf20Sopenharmony_ci 25488c2ecf20Sopenharmony_ci if (pci_ari_enabled(bus)) { 25498c2ecf20Sopenharmony_ci if (!dev) 25508c2ecf20Sopenharmony_ci return 0; 25518c2ecf20Sopenharmony_ci pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); 25528c2ecf20Sopenharmony_ci if (!pos) 25538c2ecf20Sopenharmony_ci return 0; 25548c2ecf20Sopenharmony_ci 25558c2ecf20Sopenharmony_ci pci_read_config_word(dev, pos + PCI_ARI_CAP, &cap); 25568c2ecf20Sopenharmony_ci next_fn = PCI_ARI_CAP_NFN(cap); 25578c2ecf20Sopenharmony_ci if (next_fn <= fn) 25588c2ecf20Sopenharmony_ci return 0; /* protect against malformed list */ 25598c2ecf20Sopenharmony_ci 25608c2ecf20Sopenharmony_ci return next_fn; 25618c2ecf20Sopenharmony_ci } 25628c2ecf20Sopenharmony_ci 25638c2ecf20Sopenharmony_ci /* dev may be NULL for non-contiguous multifunction devices */ 25648c2ecf20Sopenharmony_ci if (!dev || dev->multifunction) 25658c2ecf20Sopenharmony_ci return (fn + 1) % 8; 25668c2ecf20Sopenharmony_ci 25678c2ecf20Sopenharmony_ci return 0; 25688c2ecf20Sopenharmony_ci} 25698c2ecf20Sopenharmony_ci 25708c2ecf20Sopenharmony_cistatic int only_one_child(struct pci_bus *bus) 25718c2ecf20Sopenharmony_ci{ 25728c2ecf20Sopenharmony_ci struct pci_dev *bridge = bus->self; 25738c2ecf20Sopenharmony_ci 25748c2ecf20Sopenharmony_ci /* 25758c2ecf20Sopenharmony_ci * Systems with unusual topologies set PCI_SCAN_ALL_PCIE_DEVS so 25768c2ecf20Sopenharmony_ci * we scan for all possible devices, not just Device 0. 25778c2ecf20Sopenharmony_ci */ 25788c2ecf20Sopenharmony_ci if (pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) 25798c2ecf20Sopenharmony_ci return 0; 25808c2ecf20Sopenharmony_ci 25818c2ecf20Sopenharmony_ci /* 25828c2ecf20Sopenharmony_ci * A PCIe Downstream Port normally leads to a Link with only Device 25838c2ecf20Sopenharmony_ci * 0 on it (PCIe spec r3.1, sec 7.3.1). As an optimization, scan 25848c2ecf20Sopenharmony_ci * only for Device 0 in that situation. 25858c2ecf20Sopenharmony_ci */ 25868c2ecf20Sopenharmony_ci if (bridge && pci_is_pcie(bridge) && pcie_downstream_port(bridge)) 25878c2ecf20Sopenharmony_ci return 1; 25888c2ecf20Sopenharmony_ci 25898c2ecf20Sopenharmony_ci return 0; 25908c2ecf20Sopenharmony_ci} 25918c2ecf20Sopenharmony_ci 25928c2ecf20Sopenharmony_ci/** 25938c2ecf20Sopenharmony_ci * pci_scan_slot - Scan a PCI slot on a bus for devices 25948c2ecf20Sopenharmony_ci * @bus: PCI bus to scan 25958c2ecf20Sopenharmony_ci * @devfn: slot number to scan (must have zero function) 25968c2ecf20Sopenharmony_ci * 25978c2ecf20Sopenharmony_ci * Scan a PCI slot on the specified PCI bus for devices, adding 25988c2ecf20Sopenharmony_ci * discovered devices to the @bus->devices list. New devices 25998c2ecf20Sopenharmony_ci * will not have is_added set. 26008c2ecf20Sopenharmony_ci * 26018c2ecf20Sopenharmony_ci * Returns the number of new devices found. 26028c2ecf20Sopenharmony_ci */ 26038c2ecf20Sopenharmony_ciint pci_scan_slot(struct pci_bus *bus, int devfn) 26048c2ecf20Sopenharmony_ci{ 26058c2ecf20Sopenharmony_ci unsigned fn, nr = 0; 26068c2ecf20Sopenharmony_ci struct pci_dev *dev; 26078c2ecf20Sopenharmony_ci 26088c2ecf20Sopenharmony_ci if (only_one_child(bus) && (devfn > 0)) 26098c2ecf20Sopenharmony_ci return 0; /* Already scanned the entire slot */ 26108c2ecf20Sopenharmony_ci 26118c2ecf20Sopenharmony_ci dev = pci_scan_single_device(bus, devfn); 26128c2ecf20Sopenharmony_ci if (!dev) 26138c2ecf20Sopenharmony_ci return 0; 26148c2ecf20Sopenharmony_ci if (!pci_dev_is_added(dev)) 26158c2ecf20Sopenharmony_ci nr++; 26168c2ecf20Sopenharmony_ci 26178c2ecf20Sopenharmony_ci for (fn = next_fn(bus, dev, 0); fn > 0; fn = next_fn(bus, dev, fn)) { 26188c2ecf20Sopenharmony_ci dev = pci_scan_single_device(bus, devfn + fn); 26198c2ecf20Sopenharmony_ci if (dev) { 26208c2ecf20Sopenharmony_ci if (!pci_dev_is_added(dev)) 26218c2ecf20Sopenharmony_ci nr++; 26228c2ecf20Sopenharmony_ci dev->multifunction = 1; 26238c2ecf20Sopenharmony_ci } 26248c2ecf20Sopenharmony_ci } 26258c2ecf20Sopenharmony_ci 26268c2ecf20Sopenharmony_ci /* Only one slot has PCIe device */ 26278c2ecf20Sopenharmony_ci if (bus->self && nr) 26288c2ecf20Sopenharmony_ci pcie_aspm_init_link_state(bus->self); 26298c2ecf20Sopenharmony_ci 26308c2ecf20Sopenharmony_ci return nr; 26318c2ecf20Sopenharmony_ci} 26328c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_scan_slot); 26338c2ecf20Sopenharmony_ci 26348c2ecf20Sopenharmony_cistatic int pcie_find_smpss(struct pci_dev *dev, void *data) 26358c2ecf20Sopenharmony_ci{ 26368c2ecf20Sopenharmony_ci u8 *smpss = data; 26378c2ecf20Sopenharmony_ci 26388c2ecf20Sopenharmony_ci if (!pci_is_pcie(dev)) 26398c2ecf20Sopenharmony_ci return 0; 26408c2ecf20Sopenharmony_ci 26418c2ecf20Sopenharmony_ci /* 26428c2ecf20Sopenharmony_ci * We don't have a way to change MPS settings on devices that have 26438c2ecf20Sopenharmony_ci * drivers attached. A hot-added device might support only the minimum 26448c2ecf20Sopenharmony_ci * MPS setting (MPS=128). Therefore, if the fabric contains a bridge 26458c2ecf20Sopenharmony_ci * where devices may be hot-added, we limit the fabric MPS to 128 so 26468c2ecf20Sopenharmony_ci * hot-added devices will work correctly. 26478c2ecf20Sopenharmony_ci * 26488c2ecf20Sopenharmony_ci * However, if we hot-add a device to a slot directly below a Root 26498c2ecf20Sopenharmony_ci * Port, it's impossible for there to be other existing devices below 26508c2ecf20Sopenharmony_ci * the port. We don't limit the MPS in this case because we can 26518c2ecf20Sopenharmony_ci * reconfigure MPS on both the Root Port and the hot-added device, 26528c2ecf20Sopenharmony_ci * and there are no other devices involved. 26538c2ecf20Sopenharmony_ci * 26548c2ecf20Sopenharmony_ci * Note that this PCIE_BUS_SAFE path assumes no peer-to-peer DMA. 26558c2ecf20Sopenharmony_ci */ 26568c2ecf20Sopenharmony_ci if (dev->is_hotplug_bridge && 26578c2ecf20Sopenharmony_ci pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) 26588c2ecf20Sopenharmony_ci *smpss = 0; 26598c2ecf20Sopenharmony_ci 26608c2ecf20Sopenharmony_ci if (*smpss > dev->pcie_mpss) 26618c2ecf20Sopenharmony_ci *smpss = dev->pcie_mpss; 26628c2ecf20Sopenharmony_ci 26638c2ecf20Sopenharmony_ci return 0; 26648c2ecf20Sopenharmony_ci} 26658c2ecf20Sopenharmony_ci 26668c2ecf20Sopenharmony_cistatic void pcie_write_mps(struct pci_dev *dev, int mps) 26678c2ecf20Sopenharmony_ci{ 26688c2ecf20Sopenharmony_ci int rc; 26698c2ecf20Sopenharmony_ci 26708c2ecf20Sopenharmony_ci if (pcie_bus_config == PCIE_BUS_PERFORMANCE) { 26718c2ecf20Sopenharmony_ci mps = 128 << dev->pcie_mpss; 26728c2ecf20Sopenharmony_ci 26738c2ecf20Sopenharmony_ci if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT && 26748c2ecf20Sopenharmony_ci dev->bus->self) 26758c2ecf20Sopenharmony_ci 26768c2ecf20Sopenharmony_ci /* 26778c2ecf20Sopenharmony_ci * For "Performance", the assumption is made that 26788c2ecf20Sopenharmony_ci * downstream communication will never be larger than 26798c2ecf20Sopenharmony_ci * the MRRS. So, the MPS only needs to be configured 26808c2ecf20Sopenharmony_ci * for the upstream communication. This being the case, 26818c2ecf20Sopenharmony_ci * walk from the top down and set the MPS of the child 26828c2ecf20Sopenharmony_ci * to that of the parent bus. 26838c2ecf20Sopenharmony_ci * 26848c2ecf20Sopenharmony_ci * Configure the device MPS with the smaller of the 26858c2ecf20Sopenharmony_ci * device MPSS or the bridge MPS (which is assumed to be 26868c2ecf20Sopenharmony_ci * properly configured at this point to the largest 26878c2ecf20Sopenharmony_ci * allowable MPS based on its parent bus). 26888c2ecf20Sopenharmony_ci */ 26898c2ecf20Sopenharmony_ci mps = min(mps, pcie_get_mps(dev->bus->self)); 26908c2ecf20Sopenharmony_ci } 26918c2ecf20Sopenharmony_ci 26928c2ecf20Sopenharmony_ci rc = pcie_set_mps(dev, mps); 26938c2ecf20Sopenharmony_ci if (rc) 26948c2ecf20Sopenharmony_ci pci_err(dev, "Failed attempting to set the MPS\n"); 26958c2ecf20Sopenharmony_ci} 26968c2ecf20Sopenharmony_ci 26978c2ecf20Sopenharmony_cistatic void pcie_write_mrrs(struct pci_dev *dev) 26988c2ecf20Sopenharmony_ci{ 26998c2ecf20Sopenharmony_ci int rc, mrrs; 27008c2ecf20Sopenharmony_ci 27018c2ecf20Sopenharmony_ci /* 27028c2ecf20Sopenharmony_ci * In the "safe" case, do not configure the MRRS. There appear to be 27038c2ecf20Sopenharmony_ci * issues with setting MRRS to 0 on a number of devices. 27048c2ecf20Sopenharmony_ci */ 27058c2ecf20Sopenharmony_ci if (pcie_bus_config != PCIE_BUS_PERFORMANCE) 27068c2ecf20Sopenharmony_ci return; 27078c2ecf20Sopenharmony_ci 27088c2ecf20Sopenharmony_ci /* 27098c2ecf20Sopenharmony_ci * For max performance, the MRRS must be set to the largest supported 27108c2ecf20Sopenharmony_ci * value. However, it cannot be configured larger than the MPS the 27118c2ecf20Sopenharmony_ci * device or the bus can support. This should already be properly 27128c2ecf20Sopenharmony_ci * configured by a prior call to pcie_write_mps(). 27138c2ecf20Sopenharmony_ci */ 27148c2ecf20Sopenharmony_ci mrrs = pcie_get_mps(dev); 27158c2ecf20Sopenharmony_ci 27168c2ecf20Sopenharmony_ci /* 27178c2ecf20Sopenharmony_ci * MRRS is a R/W register. Invalid values can be written, but a 27188c2ecf20Sopenharmony_ci * subsequent read will verify if the value is acceptable or not. 27198c2ecf20Sopenharmony_ci * If the MRRS value provided is not acceptable (e.g., too large), 27208c2ecf20Sopenharmony_ci * shrink the value until it is acceptable to the HW. 27218c2ecf20Sopenharmony_ci */ 27228c2ecf20Sopenharmony_ci while (mrrs != pcie_get_readrq(dev) && mrrs >= 128) { 27238c2ecf20Sopenharmony_ci rc = pcie_set_readrq(dev, mrrs); 27248c2ecf20Sopenharmony_ci if (!rc) 27258c2ecf20Sopenharmony_ci break; 27268c2ecf20Sopenharmony_ci 27278c2ecf20Sopenharmony_ci pci_warn(dev, "Failed attempting to set the MRRS\n"); 27288c2ecf20Sopenharmony_ci mrrs /= 2; 27298c2ecf20Sopenharmony_ci } 27308c2ecf20Sopenharmony_ci 27318c2ecf20Sopenharmony_ci if (mrrs < 128) 27328c2ecf20Sopenharmony_ci pci_err(dev, "MRRS was unable to be configured with a safe value. If problems are experienced, try running with pci=pcie_bus_safe\n"); 27338c2ecf20Sopenharmony_ci} 27348c2ecf20Sopenharmony_ci 27358c2ecf20Sopenharmony_cistatic int pcie_bus_configure_set(struct pci_dev *dev, void *data) 27368c2ecf20Sopenharmony_ci{ 27378c2ecf20Sopenharmony_ci int mps, orig_mps; 27388c2ecf20Sopenharmony_ci 27398c2ecf20Sopenharmony_ci if (!pci_is_pcie(dev)) 27408c2ecf20Sopenharmony_ci return 0; 27418c2ecf20Sopenharmony_ci 27428c2ecf20Sopenharmony_ci if (pcie_bus_config == PCIE_BUS_TUNE_OFF || 27438c2ecf20Sopenharmony_ci pcie_bus_config == PCIE_BUS_DEFAULT) 27448c2ecf20Sopenharmony_ci return 0; 27458c2ecf20Sopenharmony_ci 27468c2ecf20Sopenharmony_ci mps = 128 << *(u8 *)data; 27478c2ecf20Sopenharmony_ci orig_mps = pcie_get_mps(dev); 27488c2ecf20Sopenharmony_ci 27498c2ecf20Sopenharmony_ci pcie_write_mps(dev, mps); 27508c2ecf20Sopenharmony_ci pcie_write_mrrs(dev); 27518c2ecf20Sopenharmony_ci 27528c2ecf20Sopenharmony_ci pci_info(dev, "Max Payload Size set to %4d/%4d (was %4d), Max Read Rq %4d\n", 27538c2ecf20Sopenharmony_ci pcie_get_mps(dev), 128 << dev->pcie_mpss, 27548c2ecf20Sopenharmony_ci orig_mps, pcie_get_readrq(dev)); 27558c2ecf20Sopenharmony_ci 27568c2ecf20Sopenharmony_ci return 0; 27578c2ecf20Sopenharmony_ci} 27588c2ecf20Sopenharmony_ci 27598c2ecf20Sopenharmony_ci/* 27608c2ecf20Sopenharmony_ci * pcie_bus_configure_settings() requires that pci_walk_bus work in a top-down, 27618c2ecf20Sopenharmony_ci * parents then children fashion. If this changes, then this code will not 27628c2ecf20Sopenharmony_ci * work as designed. 27638c2ecf20Sopenharmony_ci */ 27648c2ecf20Sopenharmony_civoid pcie_bus_configure_settings(struct pci_bus *bus) 27658c2ecf20Sopenharmony_ci{ 27668c2ecf20Sopenharmony_ci u8 smpss = 0; 27678c2ecf20Sopenharmony_ci 27688c2ecf20Sopenharmony_ci if (!bus->self) 27698c2ecf20Sopenharmony_ci return; 27708c2ecf20Sopenharmony_ci 27718c2ecf20Sopenharmony_ci if (!pci_is_pcie(bus->self)) 27728c2ecf20Sopenharmony_ci return; 27738c2ecf20Sopenharmony_ci 27748c2ecf20Sopenharmony_ci /* 27758c2ecf20Sopenharmony_ci * FIXME - Peer to peer DMA is possible, though the endpoint would need 27768c2ecf20Sopenharmony_ci * to be aware of the MPS of the destination. To work around this, 27778c2ecf20Sopenharmony_ci * simply force the MPS of the entire system to the smallest possible. 27788c2ecf20Sopenharmony_ci */ 27798c2ecf20Sopenharmony_ci if (pcie_bus_config == PCIE_BUS_PEER2PEER) 27808c2ecf20Sopenharmony_ci smpss = 0; 27818c2ecf20Sopenharmony_ci 27828c2ecf20Sopenharmony_ci if (pcie_bus_config == PCIE_BUS_SAFE) { 27838c2ecf20Sopenharmony_ci smpss = bus->self->pcie_mpss; 27848c2ecf20Sopenharmony_ci 27858c2ecf20Sopenharmony_ci pcie_find_smpss(bus->self, &smpss); 27868c2ecf20Sopenharmony_ci pci_walk_bus(bus, pcie_find_smpss, &smpss); 27878c2ecf20Sopenharmony_ci } 27888c2ecf20Sopenharmony_ci 27898c2ecf20Sopenharmony_ci pcie_bus_configure_set(bus->self, &smpss); 27908c2ecf20Sopenharmony_ci pci_walk_bus(bus, pcie_bus_configure_set, &smpss); 27918c2ecf20Sopenharmony_ci} 27928c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pcie_bus_configure_settings); 27938c2ecf20Sopenharmony_ci 27948c2ecf20Sopenharmony_ci/* 27958c2ecf20Sopenharmony_ci * Called after each bus is probed, but before its children are examined. This 27968c2ecf20Sopenharmony_ci * is marked as __weak because multiple architectures define it. 27978c2ecf20Sopenharmony_ci */ 27988c2ecf20Sopenharmony_civoid __weak pcibios_fixup_bus(struct pci_bus *bus) 27998c2ecf20Sopenharmony_ci{ 28008c2ecf20Sopenharmony_ci /* nothing to do, expected to be removed in the future */ 28018c2ecf20Sopenharmony_ci} 28028c2ecf20Sopenharmony_ci 28038c2ecf20Sopenharmony_ci/** 28048c2ecf20Sopenharmony_ci * pci_scan_child_bus_extend() - Scan devices below a bus 28058c2ecf20Sopenharmony_ci * @bus: Bus to scan for devices 28068c2ecf20Sopenharmony_ci * @available_buses: Total number of buses available (%0 does not try to 28078c2ecf20Sopenharmony_ci * extend beyond the minimal) 28088c2ecf20Sopenharmony_ci * 28098c2ecf20Sopenharmony_ci * Scans devices below @bus including subordinate buses. Returns new 28108c2ecf20Sopenharmony_ci * subordinate number including all the found devices. Passing 28118c2ecf20Sopenharmony_ci * @available_buses causes the remaining bus space to be distributed 28128c2ecf20Sopenharmony_ci * equally between hotplug-capable bridges to allow future extension of the 28138c2ecf20Sopenharmony_ci * hierarchy. 28148c2ecf20Sopenharmony_ci */ 28158c2ecf20Sopenharmony_cistatic unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, 28168c2ecf20Sopenharmony_ci unsigned int available_buses) 28178c2ecf20Sopenharmony_ci{ 28188c2ecf20Sopenharmony_ci unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0; 28198c2ecf20Sopenharmony_ci unsigned int start = bus->busn_res.start; 28208c2ecf20Sopenharmony_ci unsigned int devfn, fn, cmax, max = start; 28218c2ecf20Sopenharmony_ci struct pci_dev *dev; 28228c2ecf20Sopenharmony_ci int nr_devs; 28238c2ecf20Sopenharmony_ci 28248c2ecf20Sopenharmony_ci dev_dbg(&bus->dev, "scanning bus\n"); 28258c2ecf20Sopenharmony_ci 28268c2ecf20Sopenharmony_ci /* Go find them, Rover! */ 28278c2ecf20Sopenharmony_ci for (devfn = 0; devfn < 256; devfn += 8) { 28288c2ecf20Sopenharmony_ci nr_devs = pci_scan_slot(bus, devfn); 28298c2ecf20Sopenharmony_ci 28308c2ecf20Sopenharmony_ci /* 28318c2ecf20Sopenharmony_ci * The Jailhouse hypervisor may pass individual functions of a 28328c2ecf20Sopenharmony_ci * multi-function device to a guest without passing function 0. 28338c2ecf20Sopenharmony_ci * Look for them as well. 28348c2ecf20Sopenharmony_ci */ 28358c2ecf20Sopenharmony_ci if (jailhouse_paravirt() && nr_devs == 0) { 28368c2ecf20Sopenharmony_ci for (fn = 1; fn < 8; fn++) { 28378c2ecf20Sopenharmony_ci dev = pci_scan_single_device(bus, devfn + fn); 28388c2ecf20Sopenharmony_ci if (dev) 28398c2ecf20Sopenharmony_ci dev->multifunction = 1; 28408c2ecf20Sopenharmony_ci } 28418c2ecf20Sopenharmony_ci } 28428c2ecf20Sopenharmony_ci } 28438c2ecf20Sopenharmony_ci 28448c2ecf20Sopenharmony_ci /* Reserve buses for SR-IOV capability */ 28458c2ecf20Sopenharmony_ci used_buses = pci_iov_bus_range(bus); 28468c2ecf20Sopenharmony_ci max += used_buses; 28478c2ecf20Sopenharmony_ci 28488c2ecf20Sopenharmony_ci /* 28498c2ecf20Sopenharmony_ci * After performing arch-dependent fixup of the bus, look behind 28508c2ecf20Sopenharmony_ci * all PCI-to-PCI bridges on this bus. 28518c2ecf20Sopenharmony_ci */ 28528c2ecf20Sopenharmony_ci if (!bus->is_added) { 28538c2ecf20Sopenharmony_ci dev_dbg(&bus->dev, "fixups for bus\n"); 28548c2ecf20Sopenharmony_ci pcibios_fixup_bus(bus); 28558c2ecf20Sopenharmony_ci bus->is_added = 1; 28568c2ecf20Sopenharmony_ci } 28578c2ecf20Sopenharmony_ci 28588c2ecf20Sopenharmony_ci /* 28598c2ecf20Sopenharmony_ci * Calculate how many hotplug bridges and normal bridges there 28608c2ecf20Sopenharmony_ci * are on this bus. We will distribute the additional available 28618c2ecf20Sopenharmony_ci * buses between hotplug bridges. 28628c2ecf20Sopenharmony_ci */ 28638c2ecf20Sopenharmony_ci for_each_pci_bridge(dev, bus) { 28648c2ecf20Sopenharmony_ci if (dev->is_hotplug_bridge) 28658c2ecf20Sopenharmony_ci hotplug_bridges++; 28668c2ecf20Sopenharmony_ci else 28678c2ecf20Sopenharmony_ci normal_bridges++; 28688c2ecf20Sopenharmony_ci } 28698c2ecf20Sopenharmony_ci 28708c2ecf20Sopenharmony_ci /* 28718c2ecf20Sopenharmony_ci * Scan bridges that are already configured. We don't touch them 28728c2ecf20Sopenharmony_ci * unless they are misconfigured (which will be done in the second 28738c2ecf20Sopenharmony_ci * scan below). 28748c2ecf20Sopenharmony_ci */ 28758c2ecf20Sopenharmony_ci for_each_pci_bridge(dev, bus) { 28768c2ecf20Sopenharmony_ci cmax = max; 28778c2ecf20Sopenharmony_ci max = pci_scan_bridge_extend(bus, dev, max, 0, 0); 28788c2ecf20Sopenharmony_ci 28798c2ecf20Sopenharmony_ci /* 28808c2ecf20Sopenharmony_ci * Reserve one bus for each bridge now to avoid extending 28818c2ecf20Sopenharmony_ci * hotplug bridges too much during the second scan below. 28828c2ecf20Sopenharmony_ci */ 28838c2ecf20Sopenharmony_ci used_buses++; 28848c2ecf20Sopenharmony_ci if (cmax - max > 1) 28858c2ecf20Sopenharmony_ci used_buses += cmax - max - 1; 28868c2ecf20Sopenharmony_ci } 28878c2ecf20Sopenharmony_ci 28888c2ecf20Sopenharmony_ci /* Scan bridges that need to be reconfigured */ 28898c2ecf20Sopenharmony_ci for_each_pci_bridge(dev, bus) { 28908c2ecf20Sopenharmony_ci unsigned int buses = 0; 28918c2ecf20Sopenharmony_ci 28928c2ecf20Sopenharmony_ci if (!hotplug_bridges && normal_bridges == 1) { 28938c2ecf20Sopenharmony_ci 28948c2ecf20Sopenharmony_ci /* 28958c2ecf20Sopenharmony_ci * There is only one bridge on the bus (upstream 28968c2ecf20Sopenharmony_ci * port) so it gets all available buses which it 28978c2ecf20Sopenharmony_ci * can then distribute to the possible hotplug 28988c2ecf20Sopenharmony_ci * bridges below. 28998c2ecf20Sopenharmony_ci */ 29008c2ecf20Sopenharmony_ci buses = available_buses; 29018c2ecf20Sopenharmony_ci } else if (dev->is_hotplug_bridge) { 29028c2ecf20Sopenharmony_ci 29038c2ecf20Sopenharmony_ci /* 29048c2ecf20Sopenharmony_ci * Distribute the extra buses between hotplug 29058c2ecf20Sopenharmony_ci * bridges if any. 29068c2ecf20Sopenharmony_ci */ 29078c2ecf20Sopenharmony_ci buses = available_buses / hotplug_bridges; 29088c2ecf20Sopenharmony_ci buses = min(buses, available_buses - used_buses + 1); 29098c2ecf20Sopenharmony_ci } 29108c2ecf20Sopenharmony_ci 29118c2ecf20Sopenharmony_ci cmax = max; 29128c2ecf20Sopenharmony_ci max = pci_scan_bridge_extend(bus, dev, cmax, buses, 1); 29138c2ecf20Sopenharmony_ci /* One bus is already accounted so don't add it again */ 29148c2ecf20Sopenharmony_ci if (max - cmax > 1) 29158c2ecf20Sopenharmony_ci used_buses += max - cmax - 1; 29168c2ecf20Sopenharmony_ci } 29178c2ecf20Sopenharmony_ci 29188c2ecf20Sopenharmony_ci /* 29198c2ecf20Sopenharmony_ci * Make sure a hotplug bridge has at least the minimum requested 29208c2ecf20Sopenharmony_ci * number of buses but allow it to grow up to the maximum available 29218c2ecf20Sopenharmony_ci * bus number of there is room. 29228c2ecf20Sopenharmony_ci */ 29238c2ecf20Sopenharmony_ci if (bus->self && bus->self->is_hotplug_bridge) { 29248c2ecf20Sopenharmony_ci used_buses = max_t(unsigned int, available_buses, 29258c2ecf20Sopenharmony_ci pci_hotplug_bus_size - 1); 29268c2ecf20Sopenharmony_ci if (max - start < used_buses) { 29278c2ecf20Sopenharmony_ci max = start + used_buses; 29288c2ecf20Sopenharmony_ci 29298c2ecf20Sopenharmony_ci /* Do not allocate more buses than we have room left */ 29308c2ecf20Sopenharmony_ci if (max > bus->busn_res.end) 29318c2ecf20Sopenharmony_ci max = bus->busn_res.end; 29328c2ecf20Sopenharmony_ci 29338c2ecf20Sopenharmony_ci dev_dbg(&bus->dev, "%pR extended by %#02x\n", 29348c2ecf20Sopenharmony_ci &bus->busn_res, max - start); 29358c2ecf20Sopenharmony_ci } 29368c2ecf20Sopenharmony_ci } 29378c2ecf20Sopenharmony_ci 29388c2ecf20Sopenharmony_ci /* 29398c2ecf20Sopenharmony_ci * We've scanned the bus and so we know all about what's on 29408c2ecf20Sopenharmony_ci * the other side of any bridges that may be on this bus plus 29418c2ecf20Sopenharmony_ci * any devices. 29428c2ecf20Sopenharmony_ci * 29438c2ecf20Sopenharmony_ci * Return how far we've got finding sub-buses. 29448c2ecf20Sopenharmony_ci */ 29458c2ecf20Sopenharmony_ci dev_dbg(&bus->dev, "bus scan returning with max=%02x\n", max); 29468c2ecf20Sopenharmony_ci return max; 29478c2ecf20Sopenharmony_ci} 29488c2ecf20Sopenharmony_ci 29498c2ecf20Sopenharmony_ci/** 29508c2ecf20Sopenharmony_ci * pci_scan_child_bus() - Scan devices below a bus 29518c2ecf20Sopenharmony_ci * @bus: Bus to scan for devices 29528c2ecf20Sopenharmony_ci * 29538c2ecf20Sopenharmony_ci * Scans devices below @bus including subordinate buses. Returns new 29548c2ecf20Sopenharmony_ci * subordinate number including all the found devices. 29558c2ecf20Sopenharmony_ci */ 29568c2ecf20Sopenharmony_ciunsigned int pci_scan_child_bus(struct pci_bus *bus) 29578c2ecf20Sopenharmony_ci{ 29588c2ecf20Sopenharmony_ci return pci_scan_child_bus_extend(bus, 0); 29598c2ecf20Sopenharmony_ci} 29608c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_scan_child_bus); 29618c2ecf20Sopenharmony_ci 29628c2ecf20Sopenharmony_ci/** 29638c2ecf20Sopenharmony_ci * pcibios_root_bridge_prepare - Platform-specific host bridge setup 29648c2ecf20Sopenharmony_ci * @bridge: Host bridge to set up 29658c2ecf20Sopenharmony_ci * 29668c2ecf20Sopenharmony_ci * Default empty implementation. Replace with an architecture-specific setup 29678c2ecf20Sopenharmony_ci * routine, if necessary. 29688c2ecf20Sopenharmony_ci */ 29698c2ecf20Sopenharmony_ciint __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) 29708c2ecf20Sopenharmony_ci{ 29718c2ecf20Sopenharmony_ci return 0; 29728c2ecf20Sopenharmony_ci} 29738c2ecf20Sopenharmony_ci 29748c2ecf20Sopenharmony_civoid __weak pcibios_add_bus(struct pci_bus *bus) 29758c2ecf20Sopenharmony_ci{ 29768c2ecf20Sopenharmony_ci} 29778c2ecf20Sopenharmony_ci 29788c2ecf20Sopenharmony_civoid __weak pcibios_remove_bus(struct pci_bus *bus) 29798c2ecf20Sopenharmony_ci{ 29808c2ecf20Sopenharmony_ci} 29818c2ecf20Sopenharmony_ci 29828c2ecf20Sopenharmony_cistruct pci_bus *pci_create_root_bus(struct device *parent, int bus, 29838c2ecf20Sopenharmony_ci struct pci_ops *ops, void *sysdata, struct list_head *resources) 29848c2ecf20Sopenharmony_ci{ 29858c2ecf20Sopenharmony_ci int error; 29868c2ecf20Sopenharmony_ci struct pci_host_bridge *bridge; 29878c2ecf20Sopenharmony_ci 29888c2ecf20Sopenharmony_ci bridge = pci_alloc_host_bridge(0); 29898c2ecf20Sopenharmony_ci if (!bridge) 29908c2ecf20Sopenharmony_ci return NULL; 29918c2ecf20Sopenharmony_ci 29928c2ecf20Sopenharmony_ci bridge->dev.parent = parent; 29938c2ecf20Sopenharmony_ci 29948c2ecf20Sopenharmony_ci list_splice_init(resources, &bridge->windows); 29958c2ecf20Sopenharmony_ci bridge->sysdata = sysdata; 29968c2ecf20Sopenharmony_ci bridge->busnr = bus; 29978c2ecf20Sopenharmony_ci bridge->ops = ops; 29988c2ecf20Sopenharmony_ci 29998c2ecf20Sopenharmony_ci error = pci_register_host_bridge(bridge); 30008c2ecf20Sopenharmony_ci if (error < 0) 30018c2ecf20Sopenharmony_ci goto err_out; 30028c2ecf20Sopenharmony_ci 30038c2ecf20Sopenharmony_ci return bridge->bus; 30048c2ecf20Sopenharmony_ci 30058c2ecf20Sopenharmony_cierr_out: 30068c2ecf20Sopenharmony_ci put_device(&bridge->dev); 30078c2ecf20Sopenharmony_ci return NULL; 30088c2ecf20Sopenharmony_ci} 30098c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_create_root_bus); 30108c2ecf20Sopenharmony_ci 30118c2ecf20Sopenharmony_ciint pci_host_probe(struct pci_host_bridge *bridge) 30128c2ecf20Sopenharmony_ci{ 30138c2ecf20Sopenharmony_ci struct pci_bus *bus, *child; 30148c2ecf20Sopenharmony_ci int ret; 30158c2ecf20Sopenharmony_ci 30168c2ecf20Sopenharmony_ci ret = pci_scan_root_bus_bridge(bridge); 30178c2ecf20Sopenharmony_ci if (ret < 0) { 30188c2ecf20Sopenharmony_ci dev_err(bridge->dev.parent, "Scanning root bridge failed"); 30198c2ecf20Sopenharmony_ci return ret; 30208c2ecf20Sopenharmony_ci } 30218c2ecf20Sopenharmony_ci 30228c2ecf20Sopenharmony_ci bus = bridge->bus; 30238c2ecf20Sopenharmony_ci 30248c2ecf20Sopenharmony_ci /* 30258c2ecf20Sopenharmony_ci * We insert PCI resources into the iomem_resource and 30268c2ecf20Sopenharmony_ci * ioport_resource trees in either pci_bus_claim_resources() 30278c2ecf20Sopenharmony_ci * or pci_bus_assign_resources(). 30288c2ecf20Sopenharmony_ci */ 30298c2ecf20Sopenharmony_ci if (pci_has_flag(PCI_PROBE_ONLY)) { 30308c2ecf20Sopenharmony_ci pci_bus_claim_resources(bus); 30318c2ecf20Sopenharmony_ci } else { 30328c2ecf20Sopenharmony_ci pci_bus_size_bridges(bus); 30338c2ecf20Sopenharmony_ci pci_bus_assign_resources(bus); 30348c2ecf20Sopenharmony_ci 30358c2ecf20Sopenharmony_ci list_for_each_entry(child, &bus->children, node) 30368c2ecf20Sopenharmony_ci pcie_bus_configure_settings(child); 30378c2ecf20Sopenharmony_ci } 30388c2ecf20Sopenharmony_ci 30398c2ecf20Sopenharmony_ci pci_bus_add_devices(bus); 30408c2ecf20Sopenharmony_ci return 0; 30418c2ecf20Sopenharmony_ci} 30428c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_host_probe); 30438c2ecf20Sopenharmony_ci 30448c2ecf20Sopenharmony_ciint pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) 30458c2ecf20Sopenharmony_ci{ 30468c2ecf20Sopenharmony_ci struct resource *res = &b->busn_res; 30478c2ecf20Sopenharmony_ci struct resource *parent_res, *conflict; 30488c2ecf20Sopenharmony_ci 30498c2ecf20Sopenharmony_ci res->start = bus; 30508c2ecf20Sopenharmony_ci res->end = bus_max; 30518c2ecf20Sopenharmony_ci res->flags = IORESOURCE_BUS; 30528c2ecf20Sopenharmony_ci 30538c2ecf20Sopenharmony_ci if (!pci_is_root_bus(b)) 30548c2ecf20Sopenharmony_ci parent_res = &b->parent->busn_res; 30558c2ecf20Sopenharmony_ci else { 30568c2ecf20Sopenharmony_ci parent_res = get_pci_domain_busn_res(pci_domain_nr(b)); 30578c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_PCI_FIXED; 30588c2ecf20Sopenharmony_ci } 30598c2ecf20Sopenharmony_ci 30608c2ecf20Sopenharmony_ci conflict = request_resource_conflict(parent_res, res); 30618c2ecf20Sopenharmony_ci 30628c2ecf20Sopenharmony_ci if (conflict) 30638c2ecf20Sopenharmony_ci dev_info(&b->dev, 30648c2ecf20Sopenharmony_ci "busn_res: can not insert %pR under %s%pR (conflicts with %s %pR)\n", 30658c2ecf20Sopenharmony_ci res, pci_is_root_bus(b) ? "domain " : "", 30668c2ecf20Sopenharmony_ci parent_res, conflict->name, conflict); 30678c2ecf20Sopenharmony_ci 30688c2ecf20Sopenharmony_ci return conflict == NULL; 30698c2ecf20Sopenharmony_ci} 30708c2ecf20Sopenharmony_ci 30718c2ecf20Sopenharmony_ciint pci_bus_update_busn_res_end(struct pci_bus *b, int bus_max) 30728c2ecf20Sopenharmony_ci{ 30738c2ecf20Sopenharmony_ci struct resource *res = &b->busn_res; 30748c2ecf20Sopenharmony_ci struct resource old_res = *res; 30758c2ecf20Sopenharmony_ci resource_size_t size; 30768c2ecf20Sopenharmony_ci int ret; 30778c2ecf20Sopenharmony_ci 30788c2ecf20Sopenharmony_ci if (res->start > bus_max) 30798c2ecf20Sopenharmony_ci return -EINVAL; 30808c2ecf20Sopenharmony_ci 30818c2ecf20Sopenharmony_ci size = bus_max - res->start + 1; 30828c2ecf20Sopenharmony_ci ret = adjust_resource(res, res->start, size); 30838c2ecf20Sopenharmony_ci dev_info(&b->dev, "busn_res: %pR end %s updated to %02x\n", 30848c2ecf20Sopenharmony_ci &old_res, ret ? "can not be" : "is", bus_max); 30858c2ecf20Sopenharmony_ci 30868c2ecf20Sopenharmony_ci if (!ret && !res->parent) 30878c2ecf20Sopenharmony_ci pci_bus_insert_busn_res(b, res->start, res->end); 30888c2ecf20Sopenharmony_ci 30898c2ecf20Sopenharmony_ci return ret; 30908c2ecf20Sopenharmony_ci} 30918c2ecf20Sopenharmony_ci 30928c2ecf20Sopenharmony_civoid pci_bus_release_busn_res(struct pci_bus *b) 30938c2ecf20Sopenharmony_ci{ 30948c2ecf20Sopenharmony_ci struct resource *res = &b->busn_res; 30958c2ecf20Sopenharmony_ci int ret; 30968c2ecf20Sopenharmony_ci 30978c2ecf20Sopenharmony_ci if (!res->flags || !res->parent) 30988c2ecf20Sopenharmony_ci return; 30998c2ecf20Sopenharmony_ci 31008c2ecf20Sopenharmony_ci ret = release_resource(res); 31018c2ecf20Sopenharmony_ci dev_info(&b->dev, "busn_res: %pR %s released\n", 31028c2ecf20Sopenharmony_ci res, ret ? "can not be" : "is"); 31038c2ecf20Sopenharmony_ci} 31048c2ecf20Sopenharmony_ci 31058c2ecf20Sopenharmony_ciint pci_scan_root_bus_bridge(struct pci_host_bridge *bridge) 31068c2ecf20Sopenharmony_ci{ 31078c2ecf20Sopenharmony_ci struct resource_entry *window; 31088c2ecf20Sopenharmony_ci bool found = false; 31098c2ecf20Sopenharmony_ci struct pci_bus *b; 31108c2ecf20Sopenharmony_ci int max, bus, ret; 31118c2ecf20Sopenharmony_ci 31128c2ecf20Sopenharmony_ci if (!bridge) 31138c2ecf20Sopenharmony_ci return -EINVAL; 31148c2ecf20Sopenharmony_ci 31158c2ecf20Sopenharmony_ci resource_list_for_each_entry(window, &bridge->windows) 31168c2ecf20Sopenharmony_ci if (window->res->flags & IORESOURCE_BUS) { 31178c2ecf20Sopenharmony_ci bridge->busnr = window->res->start; 31188c2ecf20Sopenharmony_ci found = true; 31198c2ecf20Sopenharmony_ci break; 31208c2ecf20Sopenharmony_ci } 31218c2ecf20Sopenharmony_ci 31228c2ecf20Sopenharmony_ci ret = pci_register_host_bridge(bridge); 31238c2ecf20Sopenharmony_ci if (ret < 0) 31248c2ecf20Sopenharmony_ci return ret; 31258c2ecf20Sopenharmony_ci 31268c2ecf20Sopenharmony_ci b = bridge->bus; 31278c2ecf20Sopenharmony_ci bus = bridge->busnr; 31288c2ecf20Sopenharmony_ci 31298c2ecf20Sopenharmony_ci if (!found) { 31308c2ecf20Sopenharmony_ci dev_info(&b->dev, 31318c2ecf20Sopenharmony_ci "No busn resource found for root bus, will use [bus %02x-ff]\n", 31328c2ecf20Sopenharmony_ci bus); 31338c2ecf20Sopenharmony_ci pci_bus_insert_busn_res(b, bus, 255); 31348c2ecf20Sopenharmony_ci } 31358c2ecf20Sopenharmony_ci 31368c2ecf20Sopenharmony_ci max = pci_scan_child_bus(b); 31378c2ecf20Sopenharmony_ci 31388c2ecf20Sopenharmony_ci if (!found) 31398c2ecf20Sopenharmony_ci pci_bus_update_busn_res_end(b, max); 31408c2ecf20Sopenharmony_ci 31418c2ecf20Sopenharmony_ci return 0; 31428c2ecf20Sopenharmony_ci} 31438c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_scan_root_bus_bridge); 31448c2ecf20Sopenharmony_ci 31458c2ecf20Sopenharmony_cistruct pci_bus *pci_scan_root_bus(struct device *parent, int bus, 31468c2ecf20Sopenharmony_ci struct pci_ops *ops, void *sysdata, struct list_head *resources) 31478c2ecf20Sopenharmony_ci{ 31488c2ecf20Sopenharmony_ci struct resource_entry *window; 31498c2ecf20Sopenharmony_ci bool found = false; 31508c2ecf20Sopenharmony_ci struct pci_bus *b; 31518c2ecf20Sopenharmony_ci int max; 31528c2ecf20Sopenharmony_ci 31538c2ecf20Sopenharmony_ci resource_list_for_each_entry(window, resources) 31548c2ecf20Sopenharmony_ci if (window->res->flags & IORESOURCE_BUS) { 31558c2ecf20Sopenharmony_ci found = true; 31568c2ecf20Sopenharmony_ci break; 31578c2ecf20Sopenharmony_ci } 31588c2ecf20Sopenharmony_ci 31598c2ecf20Sopenharmony_ci b = pci_create_root_bus(parent, bus, ops, sysdata, resources); 31608c2ecf20Sopenharmony_ci if (!b) 31618c2ecf20Sopenharmony_ci return NULL; 31628c2ecf20Sopenharmony_ci 31638c2ecf20Sopenharmony_ci if (!found) { 31648c2ecf20Sopenharmony_ci dev_info(&b->dev, 31658c2ecf20Sopenharmony_ci "No busn resource found for root bus, will use [bus %02x-ff]\n", 31668c2ecf20Sopenharmony_ci bus); 31678c2ecf20Sopenharmony_ci pci_bus_insert_busn_res(b, bus, 255); 31688c2ecf20Sopenharmony_ci } 31698c2ecf20Sopenharmony_ci 31708c2ecf20Sopenharmony_ci max = pci_scan_child_bus(b); 31718c2ecf20Sopenharmony_ci 31728c2ecf20Sopenharmony_ci if (!found) 31738c2ecf20Sopenharmony_ci pci_bus_update_busn_res_end(b, max); 31748c2ecf20Sopenharmony_ci 31758c2ecf20Sopenharmony_ci return b; 31768c2ecf20Sopenharmony_ci} 31778c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_scan_root_bus); 31788c2ecf20Sopenharmony_ci 31798c2ecf20Sopenharmony_cistruct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, 31808c2ecf20Sopenharmony_ci void *sysdata) 31818c2ecf20Sopenharmony_ci{ 31828c2ecf20Sopenharmony_ci LIST_HEAD(resources); 31838c2ecf20Sopenharmony_ci struct pci_bus *b; 31848c2ecf20Sopenharmony_ci 31858c2ecf20Sopenharmony_ci pci_add_resource(&resources, &ioport_resource); 31868c2ecf20Sopenharmony_ci pci_add_resource(&resources, &iomem_resource); 31878c2ecf20Sopenharmony_ci pci_add_resource(&resources, &busn_resource); 31888c2ecf20Sopenharmony_ci b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources); 31898c2ecf20Sopenharmony_ci if (b) { 31908c2ecf20Sopenharmony_ci pci_scan_child_bus(b); 31918c2ecf20Sopenharmony_ci } else { 31928c2ecf20Sopenharmony_ci pci_free_resource_list(&resources); 31938c2ecf20Sopenharmony_ci } 31948c2ecf20Sopenharmony_ci return b; 31958c2ecf20Sopenharmony_ci} 31968c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_scan_bus); 31978c2ecf20Sopenharmony_ci 31988c2ecf20Sopenharmony_ci/** 31998c2ecf20Sopenharmony_ci * pci_rescan_bus_bridge_resize - Scan a PCI bus for devices 32008c2ecf20Sopenharmony_ci * @bridge: PCI bridge for the bus to scan 32018c2ecf20Sopenharmony_ci * 32028c2ecf20Sopenharmony_ci * Scan a PCI bus and child buses for new devices, add them, 32038c2ecf20Sopenharmony_ci * and enable them, resizing bridge mmio/io resource if necessary 32048c2ecf20Sopenharmony_ci * and possible. The caller must ensure the child devices are already 32058c2ecf20Sopenharmony_ci * removed for resizing to occur. 32068c2ecf20Sopenharmony_ci * 32078c2ecf20Sopenharmony_ci * Returns the max number of subordinate bus discovered. 32088c2ecf20Sopenharmony_ci */ 32098c2ecf20Sopenharmony_ciunsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge) 32108c2ecf20Sopenharmony_ci{ 32118c2ecf20Sopenharmony_ci unsigned int max; 32128c2ecf20Sopenharmony_ci struct pci_bus *bus = bridge->subordinate; 32138c2ecf20Sopenharmony_ci 32148c2ecf20Sopenharmony_ci max = pci_scan_child_bus(bus); 32158c2ecf20Sopenharmony_ci 32168c2ecf20Sopenharmony_ci pci_assign_unassigned_bridge_resources(bridge); 32178c2ecf20Sopenharmony_ci 32188c2ecf20Sopenharmony_ci pci_bus_add_devices(bus); 32198c2ecf20Sopenharmony_ci 32208c2ecf20Sopenharmony_ci return max; 32218c2ecf20Sopenharmony_ci} 32228c2ecf20Sopenharmony_ci 32238c2ecf20Sopenharmony_ci/** 32248c2ecf20Sopenharmony_ci * pci_rescan_bus - Scan a PCI bus for devices 32258c2ecf20Sopenharmony_ci * @bus: PCI bus to scan 32268c2ecf20Sopenharmony_ci * 32278c2ecf20Sopenharmony_ci * Scan a PCI bus and child buses for new devices, add them, 32288c2ecf20Sopenharmony_ci * and enable them. 32298c2ecf20Sopenharmony_ci * 32308c2ecf20Sopenharmony_ci * Returns the max number of subordinate bus discovered. 32318c2ecf20Sopenharmony_ci */ 32328c2ecf20Sopenharmony_ciunsigned int pci_rescan_bus(struct pci_bus *bus) 32338c2ecf20Sopenharmony_ci{ 32348c2ecf20Sopenharmony_ci unsigned int max; 32358c2ecf20Sopenharmony_ci 32368c2ecf20Sopenharmony_ci max = pci_scan_child_bus(bus); 32378c2ecf20Sopenharmony_ci pci_assign_unassigned_bus_resources(bus); 32388c2ecf20Sopenharmony_ci pci_bus_add_devices(bus); 32398c2ecf20Sopenharmony_ci 32408c2ecf20Sopenharmony_ci return max; 32418c2ecf20Sopenharmony_ci} 32428c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_rescan_bus); 32438c2ecf20Sopenharmony_ci 32448c2ecf20Sopenharmony_ci/* 32458c2ecf20Sopenharmony_ci * pci_rescan_bus(), pci_rescan_bus_bridge_resize() and PCI device removal 32468c2ecf20Sopenharmony_ci * routines should always be executed under this mutex. 32478c2ecf20Sopenharmony_ci */ 32488c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(pci_rescan_remove_lock); 32498c2ecf20Sopenharmony_ci 32508c2ecf20Sopenharmony_civoid pci_lock_rescan_remove(void) 32518c2ecf20Sopenharmony_ci{ 32528c2ecf20Sopenharmony_ci mutex_lock(&pci_rescan_remove_lock); 32538c2ecf20Sopenharmony_ci} 32548c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_lock_rescan_remove); 32558c2ecf20Sopenharmony_ci 32568c2ecf20Sopenharmony_civoid pci_unlock_rescan_remove(void) 32578c2ecf20Sopenharmony_ci{ 32588c2ecf20Sopenharmony_ci mutex_unlock(&pci_rescan_remove_lock); 32598c2ecf20Sopenharmony_ci} 32608c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_unlock_rescan_remove); 32618c2ecf20Sopenharmony_ci 32628c2ecf20Sopenharmony_cistatic int __init pci_sort_bf_cmp(const struct device *d_a, 32638c2ecf20Sopenharmony_ci const struct device *d_b) 32648c2ecf20Sopenharmony_ci{ 32658c2ecf20Sopenharmony_ci const struct pci_dev *a = to_pci_dev(d_a); 32668c2ecf20Sopenharmony_ci const struct pci_dev *b = to_pci_dev(d_b); 32678c2ecf20Sopenharmony_ci 32688c2ecf20Sopenharmony_ci if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1; 32698c2ecf20Sopenharmony_ci else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1; 32708c2ecf20Sopenharmony_ci 32718c2ecf20Sopenharmony_ci if (a->bus->number < b->bus->number) return -1; 32728c2ecf20Sopenharmony_ci else if (a->bus->number > b->bus->number) return 1; 32738c2ecf20Sopenharmony_ci 32748c2ecf20Sopenharmony_ci if (a->devfn < b->devfn) return -1; 32758c2ecf20Sopenharmony_ci else if (a->devfn > b->devfn) return 1; 32768c2ecf20Sopenharmony_ci 32778c2ecf20Sopenharmony_ci return 0; 32788c2ecf20Sopenharmony_ci} 32798c2ecf20Sopenharmony_ci 32808c2ecf20Sopenharmony_civoid __init pci_sort_breadthfirst(void) 32818c2ecf20Sopenharmony_ci{ 32828c2ecf20Sopenharmony_ci bus_sort_breadthfirst(&pci_bus_type, &pci_sort_bf_cmp); 32838c2ecf20Sopenharmony_ci} 32848c2ecf20Sopenharmony_ci 32858c2ecf20Sopenharmony_ciint pci_hp_add_bridge(struct pci_dev *dev) 32868c2ecf20Sopenharmony_ci{ 32878c2ecf20Sopenharmony_ci struct pci_bus *parent = dev->bus; 32888c2ecf20Sopenharmony_ci int busnr, start = parent->busn_res.start; 32898c2ecf20Sopenharmony_ci unsigned int available_buses = 0; 32908c2ecf20Sopenharmony_ci int end = parent->busn_res.end; 32918c2ecf20Sopenharmony_ci 32928c2ecf20Sopenharmony_ci for (busnr = start; busnr <= end; busnr++) { 32938c2ecf20Sopenharmony_ci if (!pci_find_bus(pci_domain_nr(parent), busnr)) 32948c2ecf20Sopenharmony_ci break; 32958c2ecf20Sopenharmony_ci } 32968c2ecf20Sopenharmony_ci if (busnr-- > end) { 32978c2ecf20Sopenharmony_ci pci_err(dev, "No bus number available for hot-added bridge\n"); 32988c2ecf20Sopenharmony_ci return -1; 32998c2ecf20Sopenharmony_ci } 33008c2ecf20Sopenharmony_ci 33018c2ecf20Sopenharmony_ci /* Scan bridges that are already configured */ 33028c2ecf20Sopenharmony_ci busnr = pci_scan_bridge(parent, dev, busnr, 0); 33038c2ecf20Sopenharmony_ci 33048c2ecf20Sopenharmony_ci /* 33058c2ecf20Sopenharmony_ci * Distribute the available bus numbers between hotplug-capable 33068c2ecf20Sopenharmony_ci * bridges to make extending the chain later possible. 33078c2ecf20Sopenharmony_ci */ 33088c2ecf20Sopenharmony_ci available_buses = end - busnr; 33098c2ecf20Sopenharmony_ci 33108c2ecf20Sopenharmony_ci /* Scan bridges that need to be reconfigured */ 33118c2ecf20Sopenharmony_ci pci_scan_bridge_extend(parent, dev, busnr, available_buses, 1); 33128c2ecf20Sopenharmony_ci 33138c2ecf20Sopenharmony_ci if (!dev->subordinate) 33148c2ecf20Sopenharmony_ci return -1; 33158c2ecf20Sopenharmony_ci 33168c2ecf20Sopenharmony_ci return 0; 33178c2ecf20Sopenharmony_ci} 33188c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_hp_add_bridge); 3319