From f0eca9626c6becb6fc56106b2e4287c6c784af3d Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Fri, 9 Sep 2005 00:57:14 +0200 Subject: [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: Greg KH Acked-by: Ivan Kokshaysky Signed-off-by: Linus Torvalds --- arch/i386/kernel/setup.c | 16 ++++++++-------- arch/x86_64/kernel/e820.c | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index fa0c69e..f3d8084 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1300,7 +1300,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat */ static void __init register_memory(void) { - unsigned long gapstart, gapsize; + unsigned long gapstart, gapsize, round; unsigned long long last; int i; @@ -1345,14 +1345,14 @@ static void __init register_memory(void) } /* - * Start allocating dynamic PCI memory a bit into the gap, - * aligned up to the nearest megabyte. - * - * Question: should we try to pad it up a bit (do something - * like " + (gapsize >> 3)" in there too?). We now have the - * technology. + * See how much we want to round up: start off with + * rounding to the next 1MB area. */ - 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", pci_mem_start, gapstart, gapsize); diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 116ac5f..bb0ae18 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -567,7 +567,7 @@ unsigned long pci_mem_start = 0xaeedbabe; */ __init void e820_setup_gap(void) { - unsigned long gapstart, gapsize; + unsigned long gapstart, gapsize, round; unsigned long last; int i; int found = 0; @@ -604,14 +604,14 @@ __init void e820_setup_gap(void) } /* - * Start allocating dynamic PCI memory a bit into the gap, - * aligned up to the nearest megabyte. - * - * Question: should we try to pad it up a bit (do something - * like " + (gapsize >> 3)" in there too?). We now have the - * technology. + * See how much we want to round up: start off with + * rounding to the next 1MB area. */ - 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", pci_mem_start, gapstart, gapsize); -- cgit v1.1