| From 857fdc53a0a90c3ba7fcf5b1fb4c7a62ae03cf82 Mon Sep 17 00:00:00 2001 |
| From: Yinghai Lu <yinghai@kernel.org> |
| Date: Fri, 10 Jul 2009 09:36:20 -0700 |
| Subject: x86/pci: insert ioapic resource before assigning unassigned resources |
| |
| From: Yinghai Lu <yinghai@kernel.org> |
| |
| commit 857fdc53a0a90c3ba7fcf5b1fb4c7a62ae03cf82 upstream. |
| |
| Stephen reported that his DL585 G2 needed noapic after 2.6.22 (?) |
| |
| Dann bisected it down to: |
| commit 30a18d6c3f1e774de656ebd8ff219d53e2ba4029 |
| Date: Tue Feb 19 03:21:20 2008 -0800 |
| |
| x86: multi pci root bus with different io resource range, on |
| 64-bit |
| |
| It turns out that: |
| 1. that AMD-based systems have two HT chains. |
| 2. BIOS doesn't allocate resources for BAR 6 of devices under 8132 etc |
| 3. that multi-peer-root patch will try to split root resources to peer |
| root resources according to PCI conf of NB |
| 4. PCI core assigns unassigned resources, but they overlap with BARs |
| that are used by ioapic addr of io4 and 8132. |
| |
| The reason: at that point ioapic address are not inserted yet. Solution |
| is to insert ioapic resources into the tree a bit earlier. |
| |
| Reported-by: Stephen Frost <sfrost@snowman.net> |
| Reported-and-Tested-by: dann frazier <dannf@hp.com> |
| Signed-off-by: Yinghai Lu <yinghai@kernel.org> |
| Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/x86/include/asm/io_apic.h | 2 ++ |
| arch/x86/kernel/apic/io_apic.c | 14 +++----------- |
| arch/x86/pci/i386.c | 7 +++++++ |
| 3 files changed, 12 insertions(+), 11 deletions(-) |
| |
| --- a/arch/x86/include/asm/io_apic.h |
| +++ b/arch/x86/include/asm/io_apic.h |
| @@ -160,6 +160,7 @@ extern int io_apic_set_pci_routing(int i |
| |
| extern int (*ioapic_renumber_irq)(int ioapic, int irq); |
| extern void ioapic_init_mappings(void); |
| +extern void ioapic_insert_resources(void); |
| |
| #ifdef CONFIG_X86_64 |
| extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); |
| @@ -183,6 +184,7 @@ extern void ioapic_write_entry(int apic, |
| #define io_apic_assign_pci_irqs 0 |
| static const int timer_through_8259 = 0; |
| static inline void ioapic_init_mappings(void) { } |
| +static inline void ioapic_insert_resources(void) { } |
| |
| static inline void probe_nr_irqs_gsi(void) { } |
| #endif |
| --- a/arch/x86/kernel/apic/io_apic.c |
| +++ b/arch/x86/kernel/apic/io_apic.c |
| @@ -4182,28 +4182,20 @@ fake_ioapic_page: |
| } |
| } |
| |
| -static int __init ioapic_insert_resources(void) |
| +void __init ioapic_insert_resources(void) |
| { |
| int i; |
| struct resource *r = ioapic_resources; |
| |
| if (!r) { |
| - if (nr_ioapics > 0) { |
| + if (nr_ioapics > 0) |
| printk(KERN_ERR |
| "IO APIC resources couldn't be allocated.\n"); |
| - return -1; |
| - } |
| - return 0; |
| + return; |
| } |
| |
| for (i = 0; i < nr_ioapics; i++) { |
| insert_resource(&iomem_resource, r); |
| r++; |
| } |
| - |
| - return 0; |
| } |
| - |
| -/* Insert the IO APIC resources after PCI initialization has occured to handle |
| - * IO APICS that are mapped in on a BAR in PCI space. */ |
| -late_initcall(ioapic_insert_resources); |
| --- a/arch/x86/pci/i386.c |
| +++ b/arch/x86/pci/i386.c |
| @@ -35,6 +35,7 @@ |
| #include <asm/pat.h> |
| #include <asm/e820.h> |
| #include <asm/pci_x86.h> |
| +#include <asm/io_apic.h> |
| |
| |
| static int |
| @@ -230,6 +231,12 @@ void __init pcibios_resource_survey(void |
| pcibios_allocate_resources(1); |
| |
| e820_reserve_resources_late(); |
| + /* |
| + * Insert the IO APIC resources after PCI initialization has |
| + * occured to handle IO APICS that are mapped in on a BAR in |
| + * PCI space, but before trying to assign unassigned pci res. |
| + */ |
| + ioapic_insert_resources(); |
| } |
| |
| /** |