setup-res.c revision 434aafc1aefb5eb6e8c8d15284c8f929be756521
1/* 2 * drivers/pci/setup-res.c 3 * 4 * Extruded from code written by 5 * Dave Rusling (david.rusling@reo.mts.dec.com) 6 * David Mosberger (davidm@cs.arizona.edu) 7 * David Miller (davem@redhat.com) 8 * 9 * Support routines for initializing a PCI subsystem. 10 */ 11 12/* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */ 13 14/* 15 * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru> 16 * Resource sorting 17 */ 18 19#include <linux/init.h> 20#include <linux/kernel.h> 21#include <linux/export.h> 22#include <linux/pci.h> 23#include <linux/errno.h> 24#include <linux/ioport.h> 25#include <linux/cache.h> 26#include <linux/slab.h> 27#include "pci.h" 28 29 30void pci_update_resource(struct pci_dev *dev, int resno) 31{ 32 struct pci_bus_region region; 33 bool disable; 34 u16 cmd; 35 u32 new, check, mask; 36 int reg; 37 enum pci_bar_type type; 38 struct resource *res = dev->resource + resno; 39 40 /* 41 * Ignore resources for unimplemented BARs and unused resource slots 42 * for 64 bit BARs. 43 */ 44 if (!res->flags) 45 return; 46 47 /* 48 * Ignore non-moveable resources. This might be legacy resources for 49 * which no functional BAR register exists or another important 50 * system resource we shouldn't move around. 51 */ 52 if (res->flags & IORESOURCE_PCI_FIXED) 53 return; 54 55 pcibios_resource_to_bus(dev->bus, ®ion, res); 56 57 new = region.start | (res->flags & PCI_REGION_FLAG_MASK); 58 if (res->flags & IORESOURCE_IO) 59 mask = (u32)PCI_BASE_ADDRESS_IO_MASK; 60 else 61 mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; 62 63 reg = pci_resource_bar(dev, resno, &type); 64 if (!reg) 65 return; 66 if (type != pci_bar_unknown) { 67 if (!(res->flags & IORESOURCE_ROM_ENABLE)) 68 return; 69 new |= PCI_ROM_ADDRESS_ENABLE; 70 } 71 72 /* 73 * We can't update a 64-bit BAR atomically, so when possible, 74 * disable decoding so that a half-updated BAR won't conflict 75 * with another device. 76 */ 77 disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on; 78 if (disable) { 79 pci_read_config_word(dev, PCI_COMMAND, &cmd); 80 pci_write_config_word(dev, PCI_COMMAND, 81 cmd & ~PCI_COMMAND_MEMORY); 82 } 83 84 pci_write_config_dword(dev, reg, new); 85 pci_read_config_dword(dev, reg, &check); 86 87 if ((new ^ check) & mask) { 88 dev_err(&dev->dev, "BAR %d: error updating (%#08x != %#08x)\n", 89 resno, new, check); 90 } 91 92 if (res->flags & IORESOURCE_MEM_64) { 93 new = region.start >> 16 >> 16; 94 pci_write_config_dword(dev, reg + 4, new); 95 pci_read_config_dword(dev, reg + 4, &check); 96 if (check != new) { 97 dev_err(&dev->dev, "BAR %d: error updating " 98 "(high %#08x != %#08x)\n", resno, new, check); 99 } 100 } 101 102 if (disable) 103 pci_write_config_word(dev, PCI_COMMAND, cmd); 104} 105 106int pci_claim_resource(struct pci_dev *dev, int resource) 107{ 108 struct resource *res = &dev->resource[resource]; 109 struct resource *root, *conflict; 110 111 root = pci_find_parent_resource(dev, res); 112 if (!root) { 113 dev_info(&dev->dev, "no compatible bridge window for %pR\n", 114 res); 115 return -EINVAL; 116 } 117 118 conflict = request_resource_conflict(root, res); 119 if (conflict) { 120 dev_info(&dev->dev, 121 "address space collision: %pR conflicts with %s %pR\n", 122 res, conflict->name, conflict); 123 return -EBUSY; 124 } 125 126 return 0; 127} 128EXPORT_SYMBOL(pci_claim_resource); 129 130void pci_disable_bridge_window(struct pci_dev *dev) 131{ 132 dev_info(&dev->dev, "disabling bridge mem windows\n"); 133 134 /* MMIO Base/Limit */ 135 pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); 136 137 /* Prefetchable MMIO Base/Limit */ 138 pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0); 139 pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); 140 pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); 141} 142 143/* 144 * Generic function that returns a value indicating that the device's 145 * original BIOS BAR address was not saved and so is not available for 146 * reinstatement. 147 * 148 * Can be over-ridden by architecture specific code that implements 149 * reinstatement functionality rather than leaving it disabled when 150 * normal allocation attempts fail. 151 */ 152resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx) 153{ 154 return 0; 155} 156 157static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, 158 int resno, resource_size_t size) 159{ 160 struct resource *root, *conflict; 161 resource_size_t fw_addr, start, end; 162 int ret = 0; 163 164 fw_addr = pcibios_retrieve_fw_addr(dev, resno); 165 if (!fw_addr) 166 return 1; 167 168 start = res->start; 169 end = res->end; 170 res->start = fw_addr; 171 res->end = res->start + size - 1; 172 173 root = pci_find_parent_resource(dev, res); 174 if (!root) { 175 if (res->flags & IORESOURCE_IO) 176 root = &ioport_resource; 177 else 178 root = &iomem_resource; 179 } 180 181 dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", 182 resno, res); 183 conflict = request_resource_conflict(root, res); 184 if (conflict) { 185 dev_info(&dev->dev, 186 "BAR %d: %pR conflicts with %s %pR\n", resno, 187 res, conflict->name, conflict); 188 res->start = start; 189 res->end = end; 190 ret = 1; 191 } 192 return ret; 193} 194 195static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, 196 int resno, resource_size_t size, resource_size_t align) 197{ 198 struct resource *res = dev->resource + resno; 199 resource_size_t min; 200 int ret; 201 202 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; 203 204 /* First, try exact prefetching match.. */ 205 ret = pci_bus_alloc_resource(bus, res, size, align, min, 206 IORESOURCE_PREFETCH, 207 pcibios_align_resource, dev); 208 209 if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) { 210 /* 211 * That failed. 212 * 213 * But a prefetching area can handle a non-prefetching 214 * window (it will just not perform as well). 215 */ 216 ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, 217 pcibios_align_resource, dev); 218 } 219 return ret; 220} 221 222static int _pci_assign_resource(struct pci_dev *dev, int resno, 223 resource_size_t size, resource_size_t min_align) 224{ 225 struct resource *res = dev->resource + resno; 226 struct pci_bus *bus; 227 int ret; 228 char *type; 229 230 bus = dev->bus; 231 while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) { 232 if (!bus->parent || !bus->self->transparent) 233 break; 234 bus = bus->parent; 235 } 236 237 if (ret) { 238 if (res->flags & IORESOURCE_MEM) 239 if (res->flags & IORESOURCE_PREFETCH) 240 type = "mem pref"; 241 else 242 type = "mem"; 243 else if (res->flags & IORESOURCE_IO) 244 type = "io"; 245 else 246 type = "unknown"; 247 dev_info(&dev->dev, 248 "BAR %d: can't assign %s (size %#llx)\n", 249 resno, type, (unsigned long long) resource_size(res)); 250 } 251 252 return ret; 253} 254 255int pci_assign_resource(struct pci_dev *dev, int resno) 256{ 257 struct resource *res = dev->resource + resno; 258 resource_size_t align, size; 259 int ret; 260 261 res->flags |= IORESOURCE_UNSET; 262 align = pci_resource_alignment(dev, res); 263 if (!align) { 264 dev_info(&dev->dev, "BAR %d: can't assign %pR " 265 "(bogus alignment)\n", resno, res); 266 return -EINVAL; 267 } 268 269 size = resource_size(res); 270 ret = _pci_assign_resource(dev, resno, size, align); 271 272 /* 273 * If we failed to assign anything, let's try the address 274 * where firmware left it. That at least has a chance of 275 * working, which is better than just leaving it disabled. 276 */ 277 if (ret < 0) 278 ret = pci_revert_fw_address(res, dev, resno, size); 279 280 if (!ret) { 281 res->flags &= ~IORESOURCE_UNSET; 282 res->flags &= ~IORESOURCE_STARTALIGN; 283 dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); 284 if (resno < PCI_BRIDGE_RESOURCES) 285 pci_update_resource(dev, resno); 286 } 287 return ret; 288} 289 290int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize, 291 resource_size_t min_align) 292{ 293 struct resource *res = dev->resource + resno; 294 resource_size_t new_size; 295 int ret; 296 297 res->flags |= IORESOURCE_UNSET; 298 if (!res->parent) { 299 dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " 300 "\n", resno, res); 301 return -EINVAL; 302 } 303 304 /* already aligned with min_align */ 305 new_size = resource_size(res) + addsize; 306 ret = _pci_assign_resource(dev, resno, new_size, min_align); 307 if (!ret) { 308 res->flags &= ~IORESOURCE_UNSET; 309 res->flags &= ~IORESOURCE_STARTALIGN; 310 dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); 311 if (resno < PCI_BRIDGE_RESOURCES) 312 pci_update_resource(dev, resno); 313 } 314 return ret; 315} 316 317int pci_enable_resources(struct pci_dev *dev, int mask) 318{ 319 u16 cmd, old_cmd; 320 int i; 321 struct resource *r; 322 323 pci_read_config_word(dev, PCI_COMMAND, &cmd); 324 old_cmd = cmd; 325 326 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 327 if (!(mask & (1 << i))) 328 continue; 329 330 r = &dev->resource[i]; 331 332 if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) 333 continue; 334 if ((i == PCI_ROM_RESOURCE) && 335 (!(r->flags & IORESOURCE_ROM_ENABLE))) 336 continue; 337 338 if (!r->parent) { 339 dev_err(&dev->dev, "device not available " 340 "(can't reserve %pR)\n", r); 341 return -EINVAL; 342 } 343 344 if (r->flags & IORESOURCE_IO) 345 cmd |= PCI_COMMAND_IO; 346 if (r->flags & IORESOURCE_MEM) 347 cmd |= PCI_COMMAND_MEMORY; 348 } 349 350 if (cmd != old_cmd) { 351 dev_info(&dev->dev, "enabling device (%04x -> %04x)\n", 352 old_cmd, cmd); 353 pci_write_config_word(dev, PCI_COMMAND, cmd); 354 } 355 return 0; 356} 357