diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2012-07-18 16:06:20 -0400 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-07-18 16:06:20 -0400 |
| commit | 5f9dca96696ee88f9f2b33dd6fba5877270c559c (patch) | |
| tree | b30ddc5f4073304cfbb4ff38b6f6331deb799c78 /drivers/pci | |
| parent | d47557e4616904c9208e233b2a0e11662ba293b1 (diff) | |
| parent | fe6dacdb1a31957825c0876de7cdea4c356aca30 (diff) | |
Merge branch 'pci/nikhil-big-bar-fixes' into next
* pci/nikhil-big-bar-fixes:
PCI: reorder __pci_assign_resource() (no change)
PCI: fix truncation of resource size to 32 bits
Diffstat (limited to 'drivers/pci')
| -rw-r--r-- | drivers/pci/setup-res.c | 107 |
1 files changed, 54 insertions, 53 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 1a0e60e265ea..81b88bda7930 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
| @@ -145,33 +145,6 @@ void pci_disable_bridge_window(struct pci_dev *dev) | |||
| 145 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); | 145 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | ||
| 149 | int resno, resource_size_t size, resource_size_t align) | ||
| 150 | { | ||
| 151 | struct resource *res = dev->resource + resno; | ||
| 152 | resource_size_t min; | ||
| 153 | int ret; | ||
| 154 | |||
| 155 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; | ||
| 156 | |||
| 157 | /* First, try exact prefetching match.. */ | ||
| 158 | ret = pci_bus_alloc_resource(bus, res, size, align, min, | ||
| 159 | IORESOURCE_PREFETCH, | ||
| 160 | pcibios_align_resource, dev); | ||
| 161 | |||
| 162 | if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) { | ||
| 163 | /* | ||
| 164 | * That failed. | ||
| 165 | * | ||
| 166 | * But a prefetching area can handle a non-prefetching | ||
| 167 | * window (it will just not perform as well). | ||
| 168 | */ | ||
| 169 | ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, | ||
| 170 | pcibios_align_resource, dev); | ||
| 171 | } | ||
| 172 | return ret; | ||
| 173 | } | ||
| 174 | |||
| 175 | /* | 148 | /* |
| 176 | * Generic function that returns a value indicating that the device's | 149 | * Generic function that returns a value indicating that the device's |
| 177 | * original BIOS BAR address was not saved and so is not available for | 150 | * original BIOS BAR address was not saved and so is not available for |
| @@ -224,7 +197,35 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | |||
| 224 | return ret; | 197 | return ret; |
| 225 | } | 198 | } |
| 226 | 199 | ||
| 227 | static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resource_size_t min_align) | 200 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
| 201 | int resno, resource_size_t size, resource_size_t align) | ||
| 202 | { | ||
| 203 | struct resource *res = dev->resource + resno; | ||
| 204 | resource_size_t min; | ||
| 205 | int ret; | ||
| 206 | |||
| 207 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; | ||
| 208 | |||
| 209 | /* First, try exact prefetching match.. */ | ||
| 210 | ret = pci_bus_alloc_resource(bus, res, size, align, min, | ||
| 211 | IORESOURCE_PREFETCH, | ||
| 212 | pcibios_align_resource, dev); | ||
| 213 | |||
| 214 | if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) { | ||
| 215 | /* | ||
| 216 | * That failed. | ||
| 217 | * | ||
| 218 | * But a prefetching area can handle a non-prefetching | ||
| 219 | * window (it will just not perform as well). | ||
| 220 | */ | ||
| 221 | ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, | ||
| 222 | pcibios_align_resource, dev); | ||
| 223 | } | ||
| 224 | return ret; | ||
| 225 | } | ||
| 226 | |||
| 227 | static int _pci_assign_resource(struct pci_dev *dev, int resno, | ||
| 228 | resource_size_t size, resource_size_t min_align) | ||
| 228 | { | 229 | { |
| 229 | struct resource *res = dev->resource + resno; | 230 | struct resource *res = dev->resource + resno; |
| 230 | struct pci_bus *bus; | 231 | struct pci_bus *bus; |
| @@ -256,31 +257,6 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resour | |||
| 256 | return ret; | 257 | return ret; |
| 257 | } | 258 | } |
| 258 | 259 | ||
| 259 | int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize, | ||
| 260 | resource_size_t min_align) | ||
| 261 | { | ||
| 262 | struct resource *res = dev->resource + resno; | ||
| 263 | resource_size_t new_size; | ||
| 264 | int ret; | ||
| 265 | |||
| 266 | if (!res->parent) { | ||
| 267 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " | ||
| 268 | "\n", resno, res); | ||
| 269 | return -EINVAL; | ||
| 270 | } | ||
| 271 | |||
| 272 | /* already aligned with min_align */ | ||
| 273 | new_size = resource_size(res) + addsize; | ||
| 274 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | ||
| 275 | if (!ret) { | ||
| 276 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
| 277 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | ||
| 278 | if (resno < PCI_BRIDGE_RESOURCES) | ||
| 279 | pci_update_resource(dev, resno); | ||
| 280 | } | ||
| 281 | return ret; | ||
| 282 | } | ||
| 283 | |||
| 284 | int pci_assign_resource(struct pci_dev *dev, int resno) | 260 | int pci_assign_resource(struct pci_dev *dev, int resno) |
| 285 | { | 261 | { |
| 286 | struct resource *res = dev->resource + resno; | 262 | struct resource *res = dev->resource + resno; |
| @@ -316,6 +292,31 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
| 316 | return ret; | 292 | return ret; |
| 317 | } | 293 | } |
| 318 | 294 | ||
| 295 | int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize, | ||
| 296 | resource_size_t min_align) | ||
| 297 | { | ||
| 298 | struct resource *res = dev->resource + resno; | ||
| 299 | resource_size_t new_size; | ||
| 300 | int ret; | ||
| 301 | |||
| 302 | if (!res->parent) { | ||
| 303 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " | ||
| 304 | "\n", resno, res); | ||
| 305 | return -EINVAL; | ||
| 306 | } | ||
| 307 | |||
| 308 | /* already aligned with min_align */ | ||
| 309 | new_size = resource_size(res) + addsize; | ||
| 310 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | ||
| 311 | if (!ret) { | ||
| 312 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
| 313 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | ||
| 314 | if (resno < PCI_BRIDGE_RESOURCES) | ||
| 315 | pci_update_resource(dev, resno); | ||
| 316 | } | ||
| 317 | return ret; | ||
| 318 | } | ||
| 319 | |||
| 319 | int pci_enable_resources(struct pci_dev *dev, int mask) | 320 | int pci_enable_resources(struct pci_dev *dev, int mask) |
| 320 | { | 321 | { |
| 321 | u16 cmd, old_cmd; | 322 | u16 cmd, old_cmd; |
