patch-2.1.121 linux/arch/alpha/kernel/core_tsunami.c

Next file: linux/arch/alpha/kernel/entry.S
Previous file: linux/arch/alpha/kernel/core_t2.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c
@@ -6,6 +6,8 @@
  * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
  *
  */
+
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/types.h>
@@ -15,6 +17,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/system.h>
+#include <asm/pci.h>
 
 #define __EXTERN_INLINE inline
 #include <asm/io.h>
@@ -22,6 +25,7 @@
 #undef __EXTERN_INLINE
 
 #include "proto.h"
+#include "bios32.h"
 
 /*
  * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
@@ -33,10 +37,10 @@
  * BIOS32-style PCI interface:
  */
 
-#ifdef DEBUG 
-# define DBG(args)	printk args
+#ifdef DEBUG_CONFIG
+# define DBG_CFG(args)	printk args
 #else
-# define DBG(args)
+# define DBG_CFG(args)
 #endif
 
 #define DEBUG_MCHECK
@@ -50,7 +54,7 @@
 static volatile unsigned int TSUNAMI_mcheck_expected[NR_CPUS];
 static volatile unsigned int TSUNAMI_mcheck_taken[NR_CPUS];
 static unsigned int TSUNAMI_jd[NR_CPUS];
-
+int TSUNAMI_bootcpu;
 
 /*
  * Given a bus, device, and function number, compute resulting
@@ -87,249 +91,205 @@
  */
 
 static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
-	     unsigned char *type1)
+mk_conf_addr(u8 bus, u8 device_fn, u8 where, struct linux_hose_info *hose,
+	     unsigned long *pci_addr, unsigned char *type1)
 {
 	unsigned long addr;
 
-	DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
-	     "pci_addr=0x%p, type1=0x%p)\n",
-	     bus, device_fn, where, pci_addr, type1));
-
-	if (bus == 0) {
-		*type1 = 0;
-	} else {
-		/* Type 1 configuration cycle.  */
-		*type1 = 1;
-	}
-	addr = (bus << 16) | (device_fn << 8) | (where);
+	if (!pci_probe_enabled)
+		return -1;
+
+	DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
+		 "pci_addr=0x%p, type1=0x%p)\n",
+		 bus, device_fn, where, pci_addr, type1));
+
+        *type1 = (bus != 0);
+
+        if (hose->pci_first_busno == bus)
+		bus = 0;
+
+        addr = (bus << 16) | (device_fn << 8) | where;
+	addr |= hose->pci_config_space;
+		
 	*pci_addr = addr;
-	DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+	DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
 	return 0;
 }
 
 int 
-tsunami_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value)
+tsunami_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
+			       struct linux_hose_info *hose)
 {
 	unsigned long addr;
 	unsigned char type1;
 
-	*value = 0xff;
-	if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	*value = __kernel_ldbu(*(vucp)(addr+TSUNAMI_PCI0_CONF));
+	*value = __kernel_ldbu(*(vucp)addr);
 	return PCIBIOS_SUCCESSFUL;
 }
 
 int
-tsunami_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value)
+tsunami_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
+			       struct linux_hose_info *hose)
 {
 	unsigned long addr;
 	unsigned char type1;
 
-	*value = 0xffff;
-	if (where & 0x1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	*value = __kernel_ldwu(*(vusp)(addr+TSUNAMI_PCI0_CONF));
+	*value = __kernel_ldwu(*(vusp)addr);
 	return PCIBIOS_SUCCESSFUL;
 }
 
 int
-tsunami_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value)
+tsunami_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
+				struct linux_hose_info *hose)
 {
 	unsigned long addr;
 	unsigned char type1;
 
-	*value = 0xffffffff;
-	if (where & 0x3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	*value = *(vuip)(addr+TSUNAMI_PCI0_CONF);
+	*value = *(vuip)addr;
 	return PCIBIOS_SUCCESSFUL;
 }
 
 int 
-tsunami_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value)
+tsunami_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
+				struct linux_hose_info *hose)
 {
 	unsigned long addr;
 	unsigned char type1;
 
-	if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	__kernel_stb(value, *(vucp)(addr+TSUNAMI_PCI0_CONF));
+	__kernel_stb(value, *(vucp)addr);
 	return PCIBIOS_SUCCESSFUL;
 }
 
 int 
-tsunami_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value)
+tsunami_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
+				struct linux_hose_info *hose)
 {
 	unsigned long addr;
 	unsigned char type1;
 
-	if (where & 0x1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	__kernel_stw(value, *(vusp)(addr+TSUNAMI_PCI0_CONF));
+	__kernel_stw(value, *(vusp)addr);
 	return PCIBIOS_SUCCESSFUL;
 }
 
 int
-tsunami_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value)
+tsunami_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
+				 struct linux_hose_info *hose)
 {
 	unsigned long addr;
 	unsigned char type1;
 
-	if (where & 0x3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	*(vuip)(addr+TSUNAMI_PCI0_CONF) = value;
+	*(vuip)addr = value;
 	return PCIBIOS_SUCCESSFUL;
 }
 
-void __init
-tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
+static long
+tsunami_probe_read(volatile unsigned long *vaddr)
 {
-        unsigned long tsunami_err;
-	unsigned int i;
+	long dont_care, probe_result;
+	int cpu = smp_processor_id();
+	int s = swpipl(6);	/* Block everything but machine checks. */
+
+	TSUNAMI_mcheck_taken[cpu] = 0;
+	TSUNAMI_mcheck_expected[cpu] = 1;
+	dont_care = *vaddr;
+	draina();
+	TSUNAMI_mcheck_expected[cpu] = 0;
+	probe_result = !TSUNAMI_mcheck_taken[cpu];
+	TSUNAMI_mcheck_taken[cpu] = 0;
+	setipl(s);
 
-#if 0
-	printk("tsunami_init: CChip registers:\n");
-	printk("CSR_CSC 0x%lx\n", *(vulp)TSUNAMI_CSR_CSC);
-	printk("CSR_MTR 0x%lx\n", *(vulp)TSUNAMI_CSR_MTR);
-	printk("CSR_MISC 0x%lx\n", *(vulp)TSUNAMI_CSR_MISC);
-	printk("CSR_DIM0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM0);
-	printk("CSR_DIM1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM1);
-	printk("CSR_DIR0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR0);
-	printk("CSR_DIR1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR1);
-	printk("CSR_DRIR 0x%lx\n", *(vulp)TSUNAMI_CSR_DRIR);
-
-	printk("tsunami_init: DChip registers:\n");
-	printk("CSR_DSC 0x%lx\n", *(vulp)TSUNAMI_CSR_DSC);
-	printk("CSR_STR 0x%lx\n", *(vulp)TSUNAMI_CSR_STR);
-	printk("CSR_DREV 0x%lx\n", *(vulp)TSUNAMI_CSR_DREV);
-
-	printk("tsunami_init: PChip registers:\n");
-	printk("PCHIP0_WSBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA0);
-	printk("PCHIP0_WSBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA1);
-	printk("PCHIP0_WSBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA2);
-	printk("PCHIP0_WSBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA3);
-	printk("PCHIP0_WSM0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM0);
-	printk("PCHIP0_WSM1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM1);
-	printk("PCHIP0_WSM2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM2);
-	printk("PCHIP0_WSM3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM3);
-	printk("PCHIP0_TBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA0);
-	printk("PCHIP0_TBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA1);
-	printk("PCHIP0_TBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA2);
-	printk("PCHIP0_TBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA3);
-	printk("PCHIP0_PCTL 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PCTL);
-	printk("PCHIP0_PLAT 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PLAT);
-	printk("PCHIP0_PERROR 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERROR);
-	printk("PCHIP0_PERRMASK 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERRMASK);
-#endif
+	printk("dont_care == 0x%lx\n", dont_care);
+
+	return probe_result;
+}
 
-	for (i = 0; i < NR_CPUS; i++) {
-		TSUNAMI_mcheck_expected[i] = 0;
-		TSUNAMI_mcheck_taken[i] = 0;
+static long
+tsunami_probe_write(volatile unsigned long *vaddr)
+{
+	long true_contents, probe_result = 1;
+
+	TSUNAMI_cchip->misc.csr |= (1L << 28); /* clear NXM... */
+	true_contents = *vaddr;
+	*vaddr = 0;
+	draina();
+	if (TSUNAMI_cchip->misc.csr & (1L << 28)) {
+		int source = (TSUNAMI_cchip->misc.csr >> 29) & 7;
+		TSUNAMI_cchip->misc.csr |= (1L << 28); /* ...and unlock NXS. */
+		probe_result = 0;
+		printk("tsunami_probe_write: unit %d at 0x%016lx\n", source,
+		       (unsigned long)vaddr);
 	}
+	if (probe_result)
+		*vaddr = true_contents;
+	return probe_result;
+}
+#else
+#define tsunami_probe_read(ADDR) 1
+#endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
 
-#ifdef NOT_YET
-        /* 
-	 * Set up error reporting. Make sure CPU_PE is OFF in the mask.
-	 */
-	tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK;
-	tsunami_err &= ~20;   
-	*(vulp)TSUNAMI_PCHIP0_PERRMASK = tsunami_err;
-	mb();
-	tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK;
+#define FN __FUNCTION__
 
-	tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ;
-	tsunami_err |= 0x40;   /* master/target abort */
-	*(vulp)TSUNAMI_PCHIP0_PERROR = tsunami_err ;
-	mb() ;
-	tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ;
-#endif /* NOT_YET */
+static void __init
+tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
+		       unsigned long *mem_start)
+{
+	struct linux_hose_info *hose;
+	int i;
+
+	if (tsunami_probe_read(&pchip->pctl.csr) == 0)
+		return;
+
+	hose = (struct linux_hose_info *)*mem_start;
+	*mem_start = (unsigned long)(hose + 1);
+	memset(hose, 0, sizeof(*hose));
+
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+
+	hose->pci_io_space = TSUNAMI_IO(index);
+	hose->pci_mem_space = TSUNAMI_MEM(index);
+	hose->pci_config_space = TSUNAMI_CONF(index);
+	hose->pci_sparse_space = 0;
+	hose->pci_hose_index = index;
 
 	switch (alpha_use_srm_setup)
 	{
 	default:
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
-		/* Check window 0 for enabled and mapped to 0.  */
-		if (((*(vulp)TSUNAMI_PCHIP0_WSBA0 & 3) == 1)
-		    && (*(vulp)TSUNAMI_PCHIP0_TBA0 == 0)
-		    && ((*(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U) > 0x0ff00000U)) {
-			TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA0 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-			printk("tsunami_init: using Window 0 settings\n");
-			printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-			       *(vulp)TSUNAMI_PCHIP0_WSBA0,
-			       *(vulp)TSUNAMI_PCHIP0_WSM0,
-			       *(vulp)TSUNAMI_PCHIP0_TBA0);
-#endif
-			break;
-		}
-
-		/* Check window 1 for enabled and mapped to 0.  */
-		if (((*(vulp)TSUNAMI_PCHIP0_WSBA1 & 3) == 1)
-		    && (*(vulp)TSUNAMI_PCHIP0_TBA1 == 0)
-		    && ((*(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U) > 0x0ff00000U)) {
-			TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA1 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
+		for (i = 0; i < 4; ++i) {
+			if ((pchip->wsba[i].csr & 3) == 1
+			    && pchip->tba[i].csr == 0
+			    && (pchip->wsm[i].csr & 0xfff00000) > 0x0ff00000) {
+				TSUNAMI_DMA_WIN_BASE = pchip->wsba[i].csr & 0xfff00000;
+				TSUNAMI_DMA_WIN_SIZE = pchip->wsm[i].csr & 0xfff00000;
+				TSUNAMI_DMA_WIN_SIZE += 0x00100000;
 #if 1
-			printk("tsunami_init: using Window 1 settings\n");
-			printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-			       *(vulp)TSUNAMI_PCHIP0_WSBA1,
-			       *(vulp)TSUNAMI_PCHIP0_WSM1,
-			       *(vulp)TSUNAMI_PCHIP0_TBA1);
+				printk("%s: using Window %d settings\n", FN, i);
+				printk("%s: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+				       FN, pchip->wsba[i].csr, pchip->wsm[i].csr,
+				       pchip->tba[i].csr);
 #endif
-			break;
-		}
-
-		/* Check window 2 for enabled and mapped to 0.  */
-		if (((*(vulp)TSUNAMI_PCHIP0_WSBA2 & 3) == 1)
-		    && (*(vulp)TSUNAMI_PCHIP0_TBA2 == 0)
-		    && ((*(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U) > 0x0ff00000U)) {
-			TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA2 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-			printk("tsunami_init: using Window 2 settings\n");
-			printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-			       *(vulp)TSUNAMI_PCHIP0_WSBA2,
-			       *(vulp)TSUNAMI_PCHIP0_WSM2,
-			       *(vulp)TSUNAMI_PCHIP0_TBA2);
-#endif
-			break;
-		}
-
-		/* Check window 3 for enabled and mapped to 0.  */
-		if (((*(vulp)TSUNAMI_PCHIP0_WSBA3 & 3) == 1)
-		    && (*(vulp)TSUNAMI_PCHIP0_TBA3 == 0)
-		    && ((*(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U) > 0x0ff00000U)) {
-			TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA3 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U;
-			TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-			printk("tsunami_init: using Window 3 settings\n");
-			printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-			       *(vulp)TSUNAMI_PCHIP0_WSBA3,
-			       *(vulp)TSUNAMI_PCHIP0_WSM3,
-			       *(vulp)TSUNAMI_PCHIP0_TBA3);
-#endif
-			break;
+				goto found;
+			}
 		}
 
 		/* Otherwise, we must use our defaults.  */
@@ -345,28 +305,80 @@
 		 * Window 0 goes at 1 GB and is 1 GB large.
 		 */
 
-		*(vulp)TSUNAMI_PCHIP0_WSBA0
-			= 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
-		*(vulp)TSUNAMI_PCHIP0_WSM0
-			= (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL;
-		*(vulp)TSUNAMI_PCHIP0_TBA0 = 0UL;
-
-		*(vulp)TSUNAMI_PCHIP0_WSBA1 = 0UL;
-		*(vulp)TSUNAMI_PCHIP0_WSBA2 = 0UL;
-		*(vulp)TSUNAMI_PCHIP0_WSBA3 = 0UL;
+		pchip->wsba[0].csr = 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
+		pchip->wsm[0].csr = (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL;
+		pchip->tba[0].csr = 0;
+
+		pchip->wsba[1].csr = 0;
+		pchip->wsba[2].csr = 0;
+		pchip->wsba[3].csr = 0;
 		mb();
 	}
+found:;
+}
+
+void __init
+tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
+	extern asmlinkage void entInt(void);
+        unsigned long tmp;
+	
+	/* Ho hum.. init_arch is called before init_IRQ, but we need to be
+	   able to handle machine checks.  So install the handler now.  */
+	wrent(entInt, 0);
+
+	/* NXMs just don't matter to Tsunami--unless they make it
+	   choke completely. */
+	tmp = (unsigned long)(TSUNAMI_cchip - 1);
+	printk("%s: probing bogus address:  0x%016lx\n", FN, bogus_addr);
+	printk("\tprobe %s\n",
+	       tsunami_probe_write((unsigned long *)bogus_addr)
+	       ? "succeeded" : "failed");
+#endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
+
+#if 0
+	printk("%s: CChip registers:\n", FN);
+	printk("%s: CSR_CSC 0x%lx\n", FN, TSUNAMI_cchip->csc.csr);
+	printk("%s: CSR_MTR 0x%lx\n", FN, TSUNAMI_cchip.mtr.csr);
+	printk("%s: CSR_MISC 0x%lx\n", FN, TSUNAMI_cchip->misc.csr);
+	printk("%s: CSR_DIM0 0x%lx\n", FN, TSUNAMI_cchip->dim0.csr);
+	printk("%s: CSR_DIM1 0x%lx\n", FN, TSUNAMI_cchip->dim1.csr);
+	printk("%s: CSR_DIR0 0x%lx\n", FN, TSUNAMI_cchip->dir0.csr);
+	printk("%s: CSR_DIR1 0x%lx\n", FN, TSUNAMI_cchip->dir1.csr);
+	printk("%s: CSR_DRIR 0x%lx\n", FN, TSUNAMI_cchip->drir.csr);
+
+	printk("%s: DChip registers:\n");
+	printk("%s: CSR_DSC 0x%lx\n", FN, TSUNAMI_dchip->dsc.csr);
+	printk("%s: CSR_STR 0x%lx\n", FN, TSUNAMI_dchip->str.csr);
+	printk("%s: CSR_DREV 0x%lx\n", FN, TSUNAMI_dchip->drev.csr);
+#endif
+
+	/* Align memory to cache line; we'll be allocating from it.  */
+	*mem_start = (*mem_start | 31) + 1;
+
+	/* Find how many hoses we have, and initialize them.  */
+	tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start);
+	tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start);
+}
+
+static inline void
+tsunami_pci_clr_err_1(tsunami_pchip *pchip, int cpu)
+{
+	TSUNAMI_jd[cpu] = pchip->perror.csr;
+	DBG_MCK(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n",
+		 TSUNAMI_jd[cpu]));
+	pchip->perror.csr = 0x040;
+	mb();
+	TSUNAMI_jd[cpu] = pchip->perror.csr;
 }
 
 static int
 tsunami_pci_clr_err(void)
 {
-	unsigned int cpu = smp_processor_id();
-
-	TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR);
-	DBG(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n",TSUNAMI_jd[cpu]));
-	*((vulp)TSUNAMI_PCHIP0_PERROR) = 0x040; mb();
-	TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR);
+	int cpu = smp_processor_id();
+	tsunami_pci_clr_err_1(TSUNAMI_pchip0, cpu);
+	tsunami_pci_clr_err_1(TSUNAMI_pchip1, cpu);
 	return 0;
 }
 
@@ -374,13 +386,14 @@
 tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
 		      struct pt_regs * regs)
 {
-#if 1
+#if 0
         printk("TSUNAMI machine check ignored\n") ;
 #else
 	struct el_common *mchk_header;
 	struct el_TSUNAMI_sysdata_mcheck *mchk_sysdata;
 	unsigned int cpu = smp_processor_id();
 
+	mb();
 	mchk_header = (struct el_common *)la_ptr;
 
 	mchk_sysdata = (struct el_TSUNAMI_sysdata_mcheck *)
@@ -414,7 +427,7 @@
 	mb();
 	mb();  /* magic */
 	if (TSUNAMI_mcheck_expected[cpu]) {
-		DBG(("TSUNAMI machine check expected\n"));
+		DBG_MCK(("TSUNAMI machine check expected\n"));
 		TSUNAMI_mcheck_expected[cpu] = 0;
 		TSUNAMI_mcheck_taken[cpu] = 1;
 		mb();

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov