diff options
author | Yinghai Lu <yinghai@kernel.org> | 2010-01-22 04:02:23 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-02-22 19:17:21 -0500 |
commit | d65245c3297ac63abc51a976d92f45f2195d2854 (patch) | |
tree | 97dbc9a714ef03810609f2d5faca1f56fd872547 /drivers/pci | |
parent | cd81e1ea1a4cda94aa5f3e942301cf0da497c262 (diff) |
PCI: don't shrink bridge resources
When clearing leaf bridge resources, trying to get a big enough one, we
could shrink the bridge if there is no resource under it. Confirm
against the old resource side to make sure we're increasing the
allocation.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/setup-bus.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7e87ea8f3200..f560814c557c 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -382,7 +382,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
382 | { | 382 | { |
383 | struct pci_dev *dev; | 383 | struct pci_dev *dev; |
384 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); | 384 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); |
385 | unsigned long size = 0, size1 = 0; | 385 | unsigned long size = 0, size1 = 0, old_size; |
386 | 386 | ||
387 | if (!b_res) | 387 | if (!b_res) |
388 | return; | 388 | return; |
@@ -407,12 +407,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
407 | } | 407 | } |
408 | if (size < min_size) | 408 | if (size < min_size) |
409 | size = min_size; | 409 | size = min_size; |
410 | old_size = resource_size(b_res); | ||
411 | if (old_size == 1) | ||
412 | old_size = 0; | ||
410 | /* To be fixed in 2.5: we should have sort of HAVE_ISA | 413 | /* To be fixed in 2.5: we should have sort of HAVE_ISA |
411 | flag in the struct pci_bus. */ | 414 | flag in the struct pci_bus. */ |
412 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | 415 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) |
413 | size = (size & 0xff) + ((size & ~0xffUL) << 2); | 416 | size = (size & 0xff) + ((size & ~0xffUL) << 2); |
414 | #endif | 417 | #endif |
415 | size = ALIGN(size + size1, 4096); | 418 | size = ALIGN(size + size1, 4096); |
419 | if (size < old_size) | ||
420 | size = old_size; | ||
416 | if (!size) { | 421 | if (!size) { |
417 | if (b_res->start || b_res->end) | 422 | if (b_res->start || b_res->end) |
418 | dev_info(&bus->self->dev, "disabling bridge window " | 423 | dev_info(&bus->self->dev, "disabling bridge window " |
@@ -433,7 +438,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
433 | unsigned long type, resource_size_t min_size) | 438 | unsigned long type, resource_size_t min_size) |
434 | { | 439 | { |
435 | struct pci_dev *dev; | 440 | struct pci_dev *dev; |
436 | resource_size_t min_align, align, size; | 441 | resource_size_t min_align, align, size, old_size; |
437 | resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ | 442 | resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ |
438 | int order, max_order; | 443 | int order, max_order; |
439 | struct resource *b_res = find_free_bus_resource(bus, type); | 444 | struct resource *b_res = find_free_bus_resource(bus, type); |
@@ -483,6 +488,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
483 | } | 488 | } |
484 | if (size < min_size) | 489 | if (size < min_size) |
485 | size = min_size; | 490 | size = min_size; |
491 | old_size = resource_size(b_res); | ||
492 | if (old_size == 1) | ||
493 | old_size = 0; | ||
494 | if (size < old_size) | ||
495 | size = old_size; | ||
486 | 496 | ||
487 | align = 0; | 497 | align = 0; |
488 | min_align = 0; | 498 | min_align = 0; |