This is a multi-part message in MIME format. --------------020304060207070105030801 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit There's some ugliness (which I'm unfortunately responsible for) in some of the x440 specific code. It's causing boot problems for us with certain configs. This patch remedies those problems. * There was an #ifdef'd call in setup_arch. It's been moved into subarch code where it belongs. * There were some ugly for loops that now are more readable. * The NUMA-specific summit code is now only compiled in & executed if CONFIG_NUMA. * The code checks that MAX_NUMNODES has a sane value before proceeding. Compiled and tested on 16 x440s, both NUMA & SMP. Cheers! -Matt --------------020304060207070105030801 Content-Type: text/plain; name="16way-x440_fix.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="16way-x440_fix.patch" diff -Nurp --exclude-from=/home/mcd/.dontdiff linux-2.6.0-test2-vanilla/arch/i386/kernel/setup.c linux-2.6.0-test2-16wayfix/arch/i386/kernel/setup.c 25-akpm/arch/i386/kernel/setup.c | 3 -- 25-akpm/arch/i386/kernel/summit.c | 30 ++++++++++++-------- 25-akpm/include/asm-i386/mach-summit/mach_mpparse.h | 8 +++++ 3 files changed, 27 insertions(+), 14 deletions(-) diff -puN arch/i386/kernel/setup.c~x440-fixes arch/i386/kernel/setup.c --- 25/arch/i386/kernel/setup.c~x440-fixes Fri Aug 8 16:48:09 2003 +++ 25-akpm/arch/i386/kernel/setup.c Fri Aug 8 16:48:09 2003 @@ -989,9 +989,6 @@ void __init setup_arch(char **cmdline_p) if (smp_found_config) get_smp_config(); #endif -#ifdef CONFIG_X86_SUMMIT - setup_summit(); -#endif register_memory(max_low_pfn); diff -puN arch/i386/kernel/summit.c~x440-fixes arch/i386/kernel/summit.c --- 25/arch/i386/kernel/summit.c~x440-fixes Fri Aug 8 16:48:09 2003 +++ 25-akpm/arch/i386/kernel/summit.c Fri Aug 8 16:48:09 2003 @@ -31,6 +31,7 @@ #include #include +#ifdef CONFIG_NUMA static void __init setup_pci_node_map_for_wpeg(int wpeg_num, struct rio_table_hdr *rth, struct scal_detail **scal_nodes, struct rio_detail **rio_nodes){ int twst_num = 0, node = 0, first_bus = 0; @@ -93,15 +94,21 @@ static void __init setup_pci_node_map_fo mp_bus_id_to_node[bus] = node; } -static void __init build_detail_arrays(struct rio_table_hdr *rth, +static int __init build_detail_arrays(struct rio_table_hdr *rth, struct scal_detail **sd, struct rio_detail **rd){ unsigned long ptr; int i, scal_detail_size, rio_detail_size; + if ((rth->num_scal_dev > MAX_NUMNODES) || + (rth->num_rio_dev > MAX_NUMNODES * 2)) { + printk("%s ERROR! MAX_NUMNODES incorrectly defined as %d!!!\n", __FUNCTION__, MAX_NUMNODES); + return 1; + } + switch (rth->version){ default: printk("%s: Bad Rio Grande Table Version: %d\n", __FUNCTION__, rth->version); - /* Fall through to default to version 2 spec */ + return 1; case 2: scal_detail_size = 11; rio_detail_size = 13; @@ -113,12 +120,13 @@ static void __init build_detail_arrays(s } ptr = (unsigned long)rth + 3; - for(i = 0; i < rth->num_scal_dev; i++) - sd[i] = (struct scal_detail *)(ptr + (scal_detail_size * i)); + for (i = 0; i < rth->num_scal_dev; i++, ptr += scal_detail_size) + sd[i] = (struct scal_detail *)ptr; + + for (i = 0; i < rth->num_rio_dev; i++, ptr += rio_detail_size) + rd[i] = (struct rio_detail *)ptr; - ptr += scal_detail_size * rth->num_scal_dev; - for(i = 0; i < rth->num_rio_dev; i++) - rd[i] = (struct rio_detail *)(ptr + (rio_detail_size * i)); + return 0; } void __init setup_summit(void) @@ -130,8 +138,6 @@ void __init setup_summit(void) unsigned short offset; int i; - memset(mp_bus_id_to_node, -1, sizeof(mp_bus_id_to_node)); - /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */ ptr = *(unsigned short *)phys_to_virt(0x40Eul); ptr = (unsigned long)phys_to_virt(ptr << 4); @@ -152,11 +158,13 @@ void __init setup_summit(void) return; } - /* Deal with the ugly version 2/3 pointer arithmetic */ - build_detail_arrays(rio_table_hdr, scal_devs, rio_devs); + /* Parse table. Non-zero return means bad table. */ + if (build_detail_arrays(rio_table_hdr, scal_devs, rio_devs)) + return; for(i = 0; i < rio_table_hdr->num_rio_dev; i++) if (is_WPEG(rio_devs[i]->type)) /* It's a Winnipeg, it's got PCI Busses */ setup_pci_node_map_for_wpeg(i, rio_table_hdr, scal_devs, rio_devs); } +#endif /* CONFIG_NUMA */ diff -puN include/asm-i386/mach-summit/mach_mpparse.h~x440-fixes include/asm-i386/mach-summit/mach_mpparse.h --- 25/include/asm-i386/mach-summit/mach_mpparse.h~x440-fixes Fri Aug 8 16:48:09 2003 +++ 25-akpm/include/asm-i386/mach-summit/mach_mpparse.h Fri Aug 8 16:48:09 2003 @@ -5,6 +5,12 @@ extern int use_cyclone; +#ifdef CONFIG_NUMA +extern void setup_summit(void); +#else /* !CONFIG_NUMA */ +#define setup_summit() {} +#endif /* CONFIG_NUMA */ + static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, struct mpc_config_translation *translation) { @@ -24,6 +30,7 @@ static inline int mps_oem_check(struct m || !strncmp(productid, "EXA", 3) || !strncmp(productid, "RUTHLESS SMP", 12))){ use_cyclone = 1; /*enable cyclone-timer*/ + setup_summit(); return 1; } return 0; @@ -36,6 +43,7 @@ static inline int acpi_madt_oem_check(ch (!strncmp(oem_table_id, "SERVIGIL", 8) || !strncmp(oem_table_id, "EXA", 3))){ use_cyclone = 1; /*enable cyclone-timer*/ + setup_summit(); return 1; } return 0; _