^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Support routines for initializing a PCI subsystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Extruded from code written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Dave Rusling (david.rusling@reo.mts.dec.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * David Mosberger (davidm@cs.arizona.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * David Miller (davem@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Fixed for multiple PCI buses, 1999 Andrea Arcangeli <andrea@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Resource sorting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "pci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static void pci_std_update_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct pci_bus_region region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) bool disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u32 new, check, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (dev->is_virtfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Ignore resources for unimplemented BARs and unused resource slots
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * for 64 bit BARs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (!res->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (res->flags & IORESOURCE_UNSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Ignore non-moveable resources. This might be legacy resources for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * which no functional BAR register exists or another important
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * system resource we shouldn't move around.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (res->flags & IORESOURCE_PCI_FIXED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) pcibios_resource_to_bus(dev->bus, ®ion, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) new = region.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (res->flags & IORESOURCE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } else if (resno == PCI_ROM_RESOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mask = PCI_ROM_ADDRESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (resno < PCI_ROM_RESOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) reg = PCI_BASE_ADDRESS_0 + 4 * resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) } else if (resno == PCI_ROM_RESOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Apparently some Matrox devices have ROM BARs that read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * as zero when disabled, so don't update ROM BARs unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * they're enabled. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * https://lore.kernel.org/r/43147B3D.1030309@vc.cvut.cz/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!(res->flags & IORESOURCE_ROM_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) reg = dev->rom_base_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) new |= PCI_ROM_ADDRESS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * We can't update a 64-bit BAR atomically, so when possible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * disable decoding so that a half-updated BAR won't conflict
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * with another device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) pci_read_config_word(dev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pci_write_config_word(dev, PCI_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) cmd & ~PCI_COMMAND_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) pci_write_config_dword(dev, reg, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) pci_read_config_dword(dev, reg, &check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if ((new ^ check) & mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) resno, new, check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (res->flags & IORESOURCE_MEM_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) new = region.start >> 16 >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) pci_write_config_dword(dev, reg + 4, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) pci_read_config_dword(dev, reg + 4, &check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (check != new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pci_err(dev, "BAR %d: error updating (high %#08x != %#08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) resno, new, check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pci_write_config_word(dev, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) void pci_update_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (resno <= PCI_ROM_RESOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pci_std_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #ifdef CONFIG_PCI_IOV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pci_iov_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int pci_claim_resource(struct pci_dev *dev, int resource)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct resource *res = &dev->resource[resource];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct resource *root, *conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (res->flags & IORESOURCE_UNSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * If we have a shadow copy in RAM, the PCI device doesn't respond
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * to the shadow range, so we don't need to claim it, and upstream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * bridges don't need to route the range to the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (res->flags & IORESOURCE_ROM_SHADOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) root = pci_find_parent_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) conflict = request_resource_conflict(root, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (conflict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) resource, res, conflict->name, conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) EXPORT_SYMBOL(pci_claim_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) void pci_disable_bridge_window(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* MMIO Base/Limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Prefetchable MMIO Base/Limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * Generic function that returns a value indicating that the device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * original BIOS BAR address was not saved and so is not available for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * reinstatement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * Can be over-ridden by architecture specific code that implements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * reinstatement functionality rather than leaving it disabled when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * normal allocation attempts fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int resno, resource_size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct resource *root, *conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) resource_size_t fw_addr, start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) fw_addr = pcibios_retrieve_fw_addr(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (!fw_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) start = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) end = res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) res->start = fw_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) res->end = res->start + size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) res->flags &= ~IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) root = pci_find_parent_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (res->flags & IORESOURCE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) root = &ioport_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) root = &iomem_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) conflict = request_resource_conflict(root, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (conflict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) resno, res, conflict->name, conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) res->start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) res->end = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * We don't have to worry about legacy ISA devices, so nothing to do here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * This is marked as __weak because multiple architectures define it; it should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * eventually go away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) resource_size_t __weak pcibios_align_resource(void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) const struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) resource_size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) resource_size_t align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int resno, resource_size_t size, resource_size_t align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) resource_size_t min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * First, try exact prefetching match. Even if a 64-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * prefetchable bridge window is below 4GB, we can't put a 32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * prefetchable resource in it because pbus_size_mem() assumes a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * 64-bit window will contain no 32-bit resources. If we assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * things differently than they were sized, not everything will fit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = pci_bus_alloc_resource(bus, res, size, align, min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) pcibios_align_resource, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * If the prefetchable window is only 32 bits wide, we can put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * 64-bit prefetchable resources in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = pci_bus_alloc_resource(bus, res, size, align, min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) IORESOURCE_PREFETCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) pcibios_align_resource, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * If we didn't find a better match, we can put any memory resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * in a non-prefetchable window. If this resource is 32 bits and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * non-prefetchable, the first call already tried the only possibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * so we don't need to try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pcibios_align_resource, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int _pci_assign_resource(struct pci_dev *dev, int resno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) resource_size_t size, resource_size_t min_align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) bus = dev->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!bus->parent || !bus->self->transparent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) bus = bus->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int pci_assign_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) resource_size_t align, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (res->flags & IORESOURCE_PCI_FIXED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) align = pci_resource_alignment(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (!align) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ret = _pci_assign_resource(dev, resno, size, align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * If we failed to assign anything, let's try the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * where firmware left it. That at least has a chance of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * working, which is better than just leaving it disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ret = pci_revert_fw_address(res, dev, resno, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) res->flags &= ~IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) res->flags &= ~IORESOURCE_STARTALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (resno < PCI_BRIDGE_RESOURCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pci_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) EXPORT_SYMBOL(pci_assign_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) resource_size_t min_align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) resource_size_t new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (res->flags & IORESOURCE_PCI_FIXED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) flags = res->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!res->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* already aligned with min_align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) new_size = resource_size(res) + addsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = _pci_assign_resource(dev, resno, new_size, min_align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) res->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) resno, res, (unsigned long long) addsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) res->flags &= ~IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) res->flags &= ~IORESOURCE_STARTALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) resno, res, (unsigned long long) addsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (resno < PCI_BRIDGE_RESOURCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pci_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) void pci_release_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (!res->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) release_resource(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) res->end = resource_size(res) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) res->start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) EXPORT_SYMBOL(pci_release_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) int pci_resize_resource(struct pci_dev *dev, int resno, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct pci_host_bridge *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int old, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) u32 sizes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* Check if we must preserve the firmware's resource assignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) host = pci_find_host_bridge(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (host->preserve_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* Make sure the resource isn't assigned before resizing it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!(res->flags & IORESOURCE_UNSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pci_read_config_word(dev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (cmd & PCI_COMMAND_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) sizes = pci_rebar_get_possible_sizes(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (!sizes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (!(sizes & BIT(size)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) old = pci_rebar_get_current_size(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (old < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = pci_rebar_set_size(dev, resno, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* Check if the new config works by trying to assign everything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (dev->bus->self) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) goto error_resize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) error_resize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) pci_rebar_set_size(dev, resno, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) EXPORT_SYMBOL(pci_resize_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int pci_enable_resources(struct pci_dev *dev, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u16 cmd, old_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct resource *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) pci_read_config_word(dev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) old_cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) for (i = 0; i < PCI_NUM_RESOURCES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!(mask & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) r = &dev->resource[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if ((i == PCI_ROM_RESOURCE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) (!(r->flags & IORESOURCE_ROM_ENABLE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (r->flags & IORESOURCE_UNSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) i, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (!r->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) i, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (r->flags & IORESOURCE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) cmd |= PCI_COMMAND_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (r->flags & IORESOURCE_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) cmd |= PCI_COMMAND_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (cmd != old_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) pci_write_config_word(dev, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }