diff options
Diffstat (limited to 'drivers/pci/setup-res.c')
-rw-r--r-- | drivers/pci/setup-res.c | 75 |
1 files changed, 36 insertions, 39 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index caed1ce6facd..b7c3a5ea1fca 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -166,11 +166,10 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | |||
166 | { | 166 | { |
167 | struct resource *root, *conflict; | 167 | struct resource *root, *conflict; |
168 | resource_size_t fw_addr, start, end; | 168 | resource_size_t fw_addr, start, end; |
169 | int ret = 0; | ||
170 | 169 | ||
171 | fw_addr = pcibios_retrieve_fw_addr(dev, resno); | 170 | fw_addr = pcibios_retrieve_fw_addr(dev, resno); |
172 | if (!fw_addr) | 171 | if (!fw_addr) |
173 | return 1; | 172 | return -ENOMEM; |
174 | 173 | ||
175 | start = res->start; | 174 | start = res->start; |
176 | end = res->end; | 175 | end = res->end; |
@@ -189,14 +188,13 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | |||
189 | resno, res); | 188 | resno, res); |
190 | conflict = request_resource_conflict(root, res); | 189 | conflict = request_resource_conflict(root, res); |
191 | if (conflict) { | 190 | if (conflict) { |
192 | dev_info(&dev->dev, | 191 | dev_info(&dev->dev, "BAR %d: %pR conflicts with %s %pR\n", |
193 | "BAR %d: %pR conflicts with %s %pR\n", resno, | 192 | resno, res, conflict->name, conflict); |
194 | res, conflict->name, conflict); | ||
195 | res->start = start; | 193 | res->start = start; |
196 | res->end = end; | 194 | res->end = end; |
197 | ret = 1; | 195 | return -EBUSY; |
198 | } | 196 | } |
199 | return ret; | 197 | return 0; |
200 | } | 198 | } |
201 | 199 | ||
202 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | 200 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
@@ -250,10 +248,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
250 | static int _pci_assign_resource(struct pci_dev *dev, int resno, | 248 | static int _pci_assign_resource(struct pci_dev *dev, int resno, |
251 | resource_size_t size, resource_size_t min_align) | 249 | resource_size_t size, resource_size_t min_align) |
252 | { | 250 | { |
253 | struct resource *res = dev->resource + resno; | ||
254 | struct pci_bus *bus; | 251 | struct pci_bus *bus; |
255 | int ret; | 252 | int ret; |
256 | char *type; | ||
257 | 253 | ||
258 | bus = dev->bus; | 254 | bus = dev->bus; |
259 | while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) { | 255 | while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) { |
@@ -262,21 +258,6 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, | |||
262 | bus = bus->parent; | 258 | bus = bus->parent; |
263 | } | 259 | } |
264 | 260 | ||
265 | if (ret) { | ||
266 | if (res->flags & IORESOURCE_MEM) | ||
267 | if (res->flags & IORESOURCE_PREFETCH) | ||
268 | type = "mem pref"; | ||
269 | else | ||
270 | type = "mem"; | ||
271 | else if (res->flags & IORESOURCE_IO) | ||
272 | type = "io"; | ||
273 | else | ||
274 | type = "unknown"; | ||
275 | dev_info(&dev->dev, | ||
276 | "BAR %d: can't assign %s (size %#llx)\n", | ||
277 | resno, type, (unsigned long long) resource_size(res)); | ||
278 | } | ||
279 | |||
280 | return ret; | 261 | return ret; |
281 | } | 262 | } |
282 | 263 | ||
@@ -302,17 +283,24 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
302 | * where firmware left it. That at least has a chance of | 283 | * where firmware left it. That at least has a chance of |
303 | * working, which is better than just leaving it disabled. | 284 | * working, which is better than just leaving it disabled. |
304 | */ | 285 | */ |
305 | if (ret < 0) | 286 | if (ret < 0) { |
287 | dev_info(&dev->dev, "BAR %d: no space for %pR\n", resno, res); | ||
306 | ret = pci_revert_fw_address(res, dev, resno, size); | 288 | ret = pci_revert_fw_address(res, dev, resno, size); |
289 | } | ||
307 | 290 | ||
308 | if (!ret) { | 291 | if (ret < 0) { |
309 | res->flags &= ~IORESOURCE_UNSET; | 292 | dev_info(&dev->dev, "BAR %d: failed to assign %pR\n", resno, |
310 | res->flags &= ~IORESOURCE_STARTALIGN; | 293 | res); |
311 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 294 | return ret; |
312 | if (resno < PCI_BRIDGE_RESOURCES) | ||
313 | pci_update_resource(dev, resno); | ||
314 | } | 295 | } |
315 | return ret; | 296 | |
297 | res->flags &= ~IORESOURCE_UNSET; | ||
298 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
299 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | ||
300 | if (resno < PCI_BRIDGE_RESOURCES) | ||
301 | pci_update_resource(dev, resno); | ||
302 | |||
303 | return 0; | ||
316 | } | 304 | } |
317 | EXPORT_SYMBOL(pci_assign_resource); | 305 | EXPORT_SYMBOL(pci_assign_resource); |
318 | 306 | ||
@@ -320,9 +308,11 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
320 | resource_size_t min_align) | 308 | resource_size_t min_align) |
321 | { | 309 | { |
322 | struct resource *res = dev->resource + resno; | 310 | struct resource *res = dev->resource + resno; |
311 | unsigned long flags; | ||
323 | resource_size_t new_size; | 312 | resource_size_t new_size; |
324 | int ret; | 313 | int ret; |
325 | 314 | ||
315 | flags = res->flags; | ||
326 | res->flags |= IORESOURCE_UNSET; | 316 | res->flags |= IORESOURCE_UNSET; |
327 | if (!res->parent) { | 317 | if (!res->parent) { |
328 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n", | 318 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n", |
@@ -333,14 +323,21 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
333 | /* already aligned with min_align */ | 323 | /* already aligned with min_align */ |
334 | new_size = resource_size(res) + addsize; | 324 | new_size = resource_size(res) + addsize; |
335 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | 325 | ret = _pci_assign_resource(dev, resno, new_size, min_align); |
336 | if (!ret) { | 326 | if (ret) { |
337 | res->flags &= ~IORESOURCE_UNSET; | 327 | res->flags = flags; |
338 | res->flags &= ~IORESOURCE_STARTALIGN; | 328 | dev_info(&dev->dev, "BAR %d: %pR (failed to expand by %#llx)\n", |
339 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | 329 | resno, res, (unsigned long long) addsize); |
340 | if (resno < PCI_BRIDGE_RESOURCES) | 330 | return ret; |
341 | pci_update_resource(dev, resno); | ||
342 | } | 331 | } |
343 | return ret; | 332 | |
333 | res->flags &= ~IORESOURCE_UNSET; | ||
334 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
335 | dev_info(&dev->dev, "BAR %d: reassigned %pR (expanded by %#llx)\n", | ||
336 | resno, res, (unsigned long long) addsize); | ||
337 | if (resno < PCI_BRIDGE_RESOURCES) | ||
338 | pci_update_resource(dev, resno); | ||
339 | |||
340 | return 0; | ||
344 | } | 341 | } |
345 | 342 | ||
346 | int pci_enable_resources(struct pci_dev *dev, int mask) | 343 | int pci_enable_resources(struct pci_dev *dev, int mask) |