linux/drivers/pci/setup-res.c
<<
>>
Prefs
   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/kernel.h>
  20#include <linux/export.h>
  21#include <linux/pci.h>
  22#include <linux/errno.h>
  23#include <linux/ioport.h>
  24#include <linux/cache.h>
  25#include <linux/slab.h>
  26#include "pci.h"
  27
  28
  29void pci_update_resource(struct pci_dev *dev, int resno)
  30{
  31        struct pci_bus_region region;
  32        bool disable;
  33        u16 cmd;
  34        u32 new, check, mask;
  35        int reg;
  36        enum pci_bar_type type;
  37        struct resource *res = dev->resource + resno;
  38
  39        if (dev->is_virtfn) {
  40                dev_warn(&dev->dev, "can't update VF BAR%d\n", resno);
  41                return;
  42        }
  43
  44        /*
  45         * Ignore resources for unimplemented BARs and unused resource slots
  46         * for 64 bit BARs.
  47         */
  48        if (!res->flags)
  49                return;
  50
  51        if (res->flags & IORESOURCE_UNSET)
  52                return;
  53
  54        /*
  55         * Ignore non-moveable resources.  This might be legacy resources for
  56         * which no functional BAR register exists or another important
  57         * system resource we shouldn't move around.
  58         */
  59        if (res->flags & IORESOURCE_PCI_FIXED)
  60                return;
  61
  62        pcibios_resource_to_bus(dev->bus, &region, res);
  63
  64        new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
  65        if (res->flags & IORESOURCE_IO)
  66                mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
  67        else
  68                mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
  69
  70        reg = pci_resource_bar(dev, resno, &type);
  71        if (!reg)
  72                return;
  73        if (type != pci_bar_unknown) {
  74                if (!(res->flags & IORESOURCE_ROM_ENABLE))
  75                        return;
  76                new |= PCI_ROM_ADDRESS_ENABLE;
  77        }
  78
  79        /*
  80         * We can't update a 64-bit BAR atomically, so when possible,
  81         * disable decoding so that a half-updated BAR won't conflict
  82         * with another device.
  83         */
  84        disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
  85        if (disable) {
  86                pci_read_config_word(dev, PCI_COMMAND, &cmd);
  87                pci_write_config_word(dev, PCI_COMMAND,
  88                                      cmd & ~PCI_COMMAND_MEMORY);
  89        }
  90
  91        pci_write_config_dword(dev, reg, new);
  92        pci_read_config_dword(dev, reg, &check);
  93
  94        if ((new ^ check) & mask) {
  95                dev_err(&dev->dev, "BAR %d: error updating (%#08x != %#08x)\n",
  96                        resno, new, check);
  97        }
  98
  99        if (res->flags & IORESOURCE_MEM_64) {
 100                new = region.start >> 16 >> 16;
 101                pci_write_config_dword(dev, reg + 4, new);
 102                pci_read_config_dword(dev, reg + 4, &check);
 103                if (check != new) {
 104                        dev_err(&dev->dev, "BAR %d: error updating (high %#08x != %#08x)\n",
 105                                resno, new, check);
 106                }
 107        }
 108
 109        if (disable)
 110                pci_write_config_word(dev, PCI_COMMAND, cmd);
 111}
 112
 113int pci_claim_resource(struct pci_dev *dev, int resource)
 114{
 115        struct resource *res = &dev->resource[resource];
 116        struct resource *root, *conflict;
 117
 118        if (res->flags & IORESOURCE_UNSET) {
 119                dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n",
 120                         resource, res);
 121                return -EINVAL;
 122        }
 123
 124        root = pci_find_parent_resource(dev, res);
 125        if (!root) {
 126                dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
 127                         resource, res);
 128                res->flags |= IORESOURCE_UNSET;
 129                return -EINVAL;
 130        }
 131
 132        conflict = request_resource_conflict(root, res);
 133        if (conflict) {
 134                dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
 135                         resource, res, conflict->name, conflict);
 136                res->flags |= IORESOURCE_UNSET;
 137                return -EBUSY;
 138        }
 139
 140        return 0;
 141}
 142EXPORT_SYMBOL(pci_claim_resource);
 143
 144void pci_disable_bridge_window(struct pci_dev *dev)
 145{
 146        dev_info(&dev->dev, "disabling bridge mem windows\n");
 147
 148        /* MMIO Base/Limit */
 149        pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
 150
 151        /* Prefetchable MMIO Base/Limit */
 152        pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
 153        pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
 154        pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
 155}
 156
 157/*
 158 * Generic function that returns a value indicating that the device's
 159 * original BIOS BAR address was not saved and so is not available for
 160 * reinstatement.
 161 *
 162 * Can be over-ridden by architecture specific code that implements
 163 * reinstatement functionality rather than leaving it disabled when
 164 * normal allocation attempts fail.
 165 */
 166resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
 167{
 168        return 0;
 169}
 170
 171static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
 172                int resno, resource_size_t size)
 173{
 174        struct resource *root, *conflict;
 175        resource_size_t fw_addr, start, end;
 176
 177        fw_addr = pcibios_retrieve_fw_addr(dev, resno);
 178        if (!fw_addr)
 179                return -ENOMEM;
 180
 181        start = res->start;
 182        end = res->end;
 183        res->start = fw_addr;
 184        res->end = res->start + size - 1;
 185        res->flags &= ~IORESOURCE_UNSET;
 186
 187        root = pci_find_parent_resource(dev, res);
 188        if (!root) {
 189                if (res->flags & IORESOURCE_IO)
 190                        root = &ioport_resource;
 191                else
 192                        root = &iomem_resource;
 193        }
 194
 195        dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n",
 196                 resno, res);
 197        conflict = request_resource_conflict(root, res);
 198        if (conflict) {
 199                dev_info(&dev->dev, "BAR %d: %pR conflicts with %s %pR\n",
 200                         resno, res, conflict->name, conflict);
 201                res->start = start;
 202                res->end = end;
 203                res->flags |= IORESOURCE_UNSET;
 204                return -EBUSY;
 205        }
 206        return 0;
 207}
 208
 209static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 210                int resno, resource_size_t size, resource_size_t align)
 211{
 212        struct resource *res = dev->resource + resno;
 213        resource_size_t min;
 214        int ret;
 215
 216        min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
 217
 218        /*
 219         * First, try exact prefetching match.  Even if a 64-bit
 220         * prefetchable bridge window is below 4GB, we can't put a 32-bit
 221         * prefetchable resource in it because pbus_size_mem() assumes a
 222         * 64-bit window will contain no 32-bit resources.  If we assign
 223         * things differently than they were sized, not everything will fit.
 224         */
 225        ret = pci_bus_alloc_resource(bus, res, size, align, min,
 226                                     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
 227                                     pcibios_align_resource, dev);
 228        if (ret == 0)
 229                return 0;
 230
 231        /*
 232         * If the prefetchable window is only 32 bits wide, we can put
 233         * 64-bit prefetchable resources in it.
 234         */
 235        if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
 236             (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
 237                ret = pci_bus_alloc_resource(bus, res, size, align, min,
 238                                             IORESOURCE_PREFETCH,
 239                                             pcibios_align_resource, dev);
 240                if (ret == 0)
 241                        return 0;
 242        }
 243
 244        /*
 245         * If we didn't find a better match, we can put any memory resource
 246         * in a non-prefetchable window.  If this resource is 32 bits and
 247         * non-prefetchable, the first call already tried the only possibility
 248         * so we don't need to try again.
 249         */
 250        if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
 251                ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
 252                                             pcibios_align_resource, dev);
 253
 254        return ret;
 255}
 256
 257static int _pci_assign_resource(struct pci_dev *dev, int resno,
 258                                resource_size_t size, resource_size_t min_align)
 259{
 260        struct pci_bus *bus;
 261        int ret;
 262
 263        bus = dev->bus;
 264        while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
 265                if (!bus->parent || !bus->self->transparent)
 266                        break;
 267                bus = bus->parent;
 268        }
 269
 270        return ret;
 271}
 272
 273int pci_assign_resource(struct pci_dev *dev, int resno)
 274{
 275        struct resource *res = dev->resource + resno;
 276        resource_size_t align, size;
 277        int ret;
 278
 279        if (res->flags & IORESOURCE_PCI_FIXED)
 280                return 0;
 281
 282        res->flags |= IORESOURCE_UNSET;
 283        align = pci_resource_alignment(dev, res);
 284        if (!align) {
 285                dev_info(&dev->dev, "BAR %d: can't assign %pR (bogus alignment)\n",
 286                         resno, res);
 287                return -EINVAL;
 288        }
 289
 290        size = resource_size(res);
 291        ret = _pci_assign_resource(dev, resno, size, align);
 292
 293        /*
 294         * If we failed to assign anything, let's try the address
 295         * where firmware left it.  That at least has a chance of
 296         * working, which is better than just leaving it disabled.
 297         */
 298        if (ret < 0) {
 299                dev_info(&dev->dev, "BAR %d: no space for %pR\n", resno, res);
 300                ret = pci_revert_fw_address(res, dev, resno, size);
 301        }
 302
 303        if (ret < 0) {
 304                dev_info(&dev->dev, "BAR %d: failed to assign %pR\n", resno,
 305                         res);
 306                return ret;
 307        }
 308
 309        res->flags &= ~IORESOURCE_UNSET;
 310        res->flags &= ~IORESOURCE_STARTALIGN;
 311        dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
 312        if (resno < PCI_BRIDGE_RESOURCES)
 313                pci_update_resource(dev, resno);
 314
 315        return 0;
 316}
 317EXPORT_SYMBOL(pci_assign_resource);
 318
 319int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
 320                        resource_size_t min_align)
 321{
 322        struct resource *res = dev->resource + resno;
 323        unsigned long flags;
 324        resource_size_t new_size;
 325        int ret;
 326
 327        if (res->flags & IORESOURCE_PCI_FIXED)
 328                return 0;
 329
 330        flags = res->flags;
 331        res->flags |= IORESOURCE_UNSET;
 332        if (!res->parent) {
 333                dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n",
 334                         resno, res);
 335                return -EINVAL;
 336        }
 337
 338        /* already aligned with min_align */
 339        new_size = resource_size(res) + addsize;
 340        ret = _pci_assign_resource(dev, resno, new_size, min_align);
 341        if (ret) {
 342                res->flags = flags;
 343                dev_info(&dev->dev, "BAR %d: %pR (failed to expand by %#llx)\n",
 344                         resno, res, (unsigned long long) addsize);
 345                return ret;
 346        }
 347
 348        res->flags &= ~IORESOURCE_UNSET;
 349        res->flags &= ~IORESOURCE_STARTALIGN;
 350        dev_info(&dev->dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
 351                 resno, res, (unsigned long long) addsize);
 352        if (resno < PCI_BRIDGE_RESOURCES)
 353                pci_update_resource(dev, resno);
 354
 355        return 0;
 356}
 357
 358int pci_enable_resources(struct pci_dev *dev, int mask)
 359{
 360        u16 cmd, old_cmd;
 361        int i;
 362        struct resource *r;
 363
 364        pci_read_config_word(dev, PCI_COMMAND, &cmd);
 365        old_cmd = cmd;
 366
 367        for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 368                if (!(mask & (1 << i)))
 369                        continue;
 370
 371                r = &dev->resource[i];
 372
 373                if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
 374                        continue;
 375                if ((i == PCI_ROM_RESOURCE) &&
 376                                (!(r->flags & IORESOURCE_ROM_ENABLE)))
 377                        continue;
 378
 379                if (r->flags & IORESOURCE_UNSET) {
 380                        dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n",
 381                                i, r);
 382                        return -EINVAL;
 383                }
 384
 385                if (!r->parent) {
 386                        dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n",
 387                                i, r);
 388                        return -EINVAL;
 389                }
 390
 391                if (r->flags & IORESOURCE_IO)
 392                        cmd |= PCI_COMMAND_IO;
 393                if (r->flags & IORESOURCE_MEM)
 394                        cmd |= PCI_COMMAND_MEMORY;
 395        }
 396
 397        if (cmd != old_cmd) {
 398                dev_info(&dev->dev, "enabling device (%04x -> %04x)\n",
 399                         old_cmd, cmd);
 400                pci_write_config_word(dev, PCI_COMMAND, cmd);
 401        }
 402        return 0;
 403}
 404