diff options
Diffstat (limited to 'drivers/pci/setup-res.c')
-rw-r--r-- | drivers/pci/setup-res.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 5c060b152ce6..7eed671d5586 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -44,6 +44,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
44 | if (!res->flags) | 44 | if (!res->flags) |
45 | return; | 45 | return; |
46 | 46 | ||
47 | if (res->flags & IORESOURCE_UNSET) | ||
48 | return; | ||
49 | |||
47 | /* | 50 | /* |
48 | * Ignore non-moveable resources. This might be legacy resources for | 51 | * Ignore non-moveable resources. This might be legacy resources for |
49 | * which no functional BAR register exists or another important | 52 | * which no functional BAR register exists or another important |
@@ -101,11 +104,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
101 | 104 | ||
102 | if (disable) | 105 | if (disable) |
103 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 106 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
104 | |||
105 | res->flags &= ~IORESOURCE_UNSET; | ||
106 | dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n", | ||
107 | resno, res, (unsigned long long)region.start, | ||
108 | (unsigned long long)region.end); | ||
109 | } | 107 | } |
110 | 108 | ||
111 | int pci_claim_resource(struct pci_dev *dev, int resource) | 109 | int pci_claim_resource(struct pci_dev *dev, int resource) |
@@ -113,18 +111,23 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
113 | struct resource *res = &dev->resource[resource]; | 111 | struct resource *res = &dev->resource[resource]; |
114 | struct resource *root, *conflict; | 112 | struct resource *root, *conflict; |
115 | 113 | ||
114 | if (res->flags & IORESOURCE_UNSET) { | ||
115 | dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n", | ||
116 | resource, res); | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | |||
116 | root = pci_find_parent_resource(dev, res); | 120 | root = pci_find_parent_resource(dev, res); |
117 | if (!root) { | 121 | if (!root) { |
118 | dev_info(&dev->dev, "no compatible bridge window for %pR\n", | 122 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", |
119 | res); | 123 | resource, res); |
120 | return -EINVAL; | 124 | return -EINVAL; |
121 | } | 125 | } |
122 | 126 | ||
123 | conflict = request_resource_conflict(root, res); | 127 | conflict = request_resource_conflict(root, res); |
124 | if (conflict) { | 128 | if (conflict) { |
125 | dev_info(&dev->dev, | 129 | dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n", |
126 | "address space collision: %pR conflicts with %s %pR\n", | 130 | resource, res, conflict->name, conflict); |
127 | res, conflict->name, conflict); | ||
128 | return -EBUSY; | 131 | return -EBUSY; |
129 | } | 132 | } |
130 | 133 | ||
@@ -263,6 +266,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
263 | resource_size_t align, size; | 266 | resource_size_t align, size; |
264 | int ret; | 267 | int ret; |
265 | 268 | ||
269 | res->flags |= IORESOURCE_UNSET; | ||
266 | align = pci_resource_alignment(dev, res); | 270 | align = pci_resource_alignment(dev, res); |
267 | if (!align) { | 271 | if (!align) { |
268 | dev_info(&dev->dev, "BAR %d: can't assign %pR " | 272 | dev_info(&dev->dev, "BAR %d: can't assign %pR " |
@@ -282,6 +286,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
282 | ret = pci_revert_fw_address(res, dev, resno, size); | 286 | ret = pci_revert_fw_address(res, dev, resno, size); |
283 | 287 | ||
284 | if (!ret) { | 288 | if (!ret) { |
289 | res->flags &= ~IORESOURCE_UNSET; | ||
285 | res->flags &= ~IORESOURCE_STARTALIGN; | 290 | res->flags &= ~IORESOURCE_STARTALIGN; |
286 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 291 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); |
287 | if (resno < PCI_BRIDGE_RESOURCES) | 292 | if (resno < PCI_BRIDGE_RESOURCES) |
@@ -297,6 +302,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
297 | resource_size_t new_size; | 302 | resource_size_t new_size; |
298 | int ret; | 303 | int ret; |
299 | 304 | ||
305 | res->flags |= IORESOURCE_UNSET; | ||
300 | if (!res->parent) { | 306 | if (!res->parent) { |
301 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " | 307 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " |
302 | "\n", resno, res); | 308 | "\n", resno, res); |
@@ -307,6 +313,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
307 | new_size = resource_size(res) + addsize; | 313 | new_size = resource_size(res) + addsize; |
308 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | 314 | ret = _pci_assign_resource(dev, resno, new_size, min_align); |
309 | if (!ret) { | 315 | if (!ret) { |
316 | res->flags &= ~IORESOURCE_UNSET; | ||
310 | res->flags &= ~IORESOURCE_STARTALIGN; | 317 | res->flags &= ~IORESOURCE_STARTALIGN; |
311 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | 318 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); |
312 | if (resno < PCI_BRIDGE_RESOURCES) | 319 | if (resno < PCI_BRIDGE_RESOURCES) |
@@ -336,9 +343,15 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
336 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | 343 | (!(r->flags & IORESOURCE_ROM_ENABLE))) |
337 | continue; | 344 | continue; |
338 | 345 | ||
346 | if (r->flags & IORESOURCE_UNSET) { | ||
347 | dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n", | ||
348 | i, r); | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
339 | if (!r->parent) { | 352 | if (!r->parent) { |
340 | dev_err(&dev->dev, "device not available " | 353 | dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n", |
341 | "(can't reserve %pR)\n", r); | 354 | i, r); |
342 | return -EINVAL; | 355 | return -EINVAL; |
343 | } | 356 | } |
344 | 357 | ||