Commit f0eca962 authored by Daniel Ritz's avatar Daniel Ritz Committed by Linus Torvalds

[PATCH] Update PCI IOMEM allocation start

This fixes the problem with "Averatec 6240 pcmcia_socket0: unable to
apply power", which was due to the CardBus IOMEM register region being
allocated at an address that was actually inside the RAM window that had
been reserved for video frame-buffers in an UMA setup.

The BIOS _should_ have marked that region reserved in the e820 memory
descriptor tables, but did not.

It is fixed by rounding up the default starting address of PCI memory
allocations, so that we leave a bigger gap after the final known memory
location.  The amount of rounding depends on how big the unused memory
gap is that we can allocate IOMEM from.

Based on example code by Linus.
Acked-by: default avatarGreg KH <greg@kroah.com>
Acked-by: default avatarIvan Kokshaysky <ink@jurassic.park.msu.ru>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 41d0ab2a
...@@ -1300,7 +1300,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat ...@@ -1300,7 +1300,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
*/ */
static void __init register_memory(void) static void __init register_memory(void)
{ {
unsigned long gapstart, gapsize; unsigned long gapstart, gapsize, round;
unsigned long long last; unsigned long long last;
int i; int i;
...@@ -1345,14 +1345,14 @@ static void __init register_memory(void) ...@@ -1345,14 +1345,14 @@ static void __init register_memory(void)
} }
/* /*
* Start allocating dynamic PCI memory a bit into the gap, * See how much we want to round up: start off with
* aligned up to the nearest megabyte. * rounding to the next 1MB area.
*
* Question: should we try to pad it up a bit (do something
* like " + (gapsize >> 3)" in there too?). We now have the
* technology.
*/ */
pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; round = 0x100000;
while ((gapsize >> 4) > round)
round += round;
/* Fun with two's complement */
pci_mem_start = (gapstart + round) & -round;
printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
pci_mem_start, gapstart, gapsize); pci_mem_start, gapstart, gapsize);
......
...@@ -567,7 +567,7 @@ unsigned long pci_mem_start = 0xaeedbabe; ...@@ -567,7 +567,7 @@ unsigned long pci_mem_start = 0xaeedbabe;
*/ */
__init void e820_setup_gap(void) __init void e820_setup_gap(void)
{ {
unsigned long gapstart, gapsize; unsigned long gapstart, gapsize, round;
unsigned long last; unsigned long last;
int i; int i;
int found = 0; int found = 0;
...@@ -604,14 +604,14 @@ __init void e820_setup_gap(void) ...@@ -604,14 +604,14 @@ __init void e820_setup_gap(void)
} }
/* /*
* Start allocating dynamic PCI memory a bit into the gap, * See how much we want to round up: start off with
* aligned up to the nearest megabyte. * rounding to the next 1MB area.
*
* Question: should we try to pad it up a bit (do something
* like " + (gapsize >> 3)" in there too?). We now have the
* technology.
*/ */
pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; round = 0x100000;
while ((gapsize >> 4) > round)
round += round;
/* Fun with two's complement */
pci_mem_start = (gapstart + round) & -round;
printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
pci_mem_start, gapstart, gapsize); pci_mem_start, gapstart, gapsize);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment