patch-2.4.19 linux-2.4.19/arch/ia64/sn/io/sn2/bte_error.c

Next file: linux-2.4.19/arch/ia64/sn/io/sn2/ml_SN_intr.c
Previous file: linux-2.4.19/arch/ia64/sn/io/sn1/pcibr.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/ia64/sn/io/sn2/bte_error.c linux-2.4.19/arch/ia64/sn/io/sn2/bte_error.c
@@ -0,0 +1,190 @@
+/* $Id: bte_error.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/smp.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/ioerror.h>
+#include <asm/sn/sn2/shubio.h>
+#include <asm/sn/bte.h>
+
+/************************************************************************
+ *									*
+ * 			 BTE ERROR RECOVERY				*
+ *									*
+ * Given a BTE error, the node causing the error must do the following: *
+ *    a) Clear all crbs relating to that BTE				*
+ *		1) Read CRBA value for crb in question			*
+ *		2) Mark CRB as VALID, store local physical 		*
+ *		   address known to be good in the address field	*
+ *		   (bte_notification_targ is a known good local		*
+ *		    address).						*
+ *		3) Write CRBA						*
+ *		4) Using ICCR, FLUSH the CRB, and wait for it to 	*
+ *		   complete.						*
+ *		... BTE BUSY bit should now be clear (or at least 	*
+ *		    should be after ALL CRBs associated with the 	*
+ *		    transfer are complete.				*
+ *									*
+ *    b) Re-enable BTE							*
+ *		1) Write IMEM with BTE Enable + XXX bits
+ *		2) Write IECLR with BTE clear bits
+ *		3) Clear IIDSR INT_SENT bits.
+ *									*
+ ************************************************************************/
+
+#ifdef BTE_ERROR
+// This routine is not called.  Yet.  It may be someday.  It probably
+// *should* be someday.  Until then, ifdef it out.
+bte_result_t
+bte_error_handler(bte_handle_t *bh)
+/*
+ * Function: 	bte_error_handler
+ * Purpose:	Process a BTE error after a transfer has failed.
+ * Parameters:	bh - bte handle of bte that failed.
+ * Returns:	The BTE error type.
+ * Notes:
+ */
+{
+    devfs_handle_t	hub_v;
+    hubinfo_t		hinfo;
+    int			il;
+    hubreg_t		iidsr, imem, ieclr;
+    hubreg_t		bte_status;
+
+    bh->bh_bte->bte_error_count++;
+
+    /* 
+     * Process any CRB logs - we know that the bte_context contains
+     * the BTE completion status, but to avoid a race with error
+     * processing, we force a call to pick up any CRB errors pending. 
+     * After this call, we know that we have any CRB errors related to 
+     * this BTE transfer in the context.
+     */
+    hub_v = cnodeid_to_vertex(bh->bh_bte->bte_cnode);
+    hubinfo_get(hub_v, &hinfo);
+    (void)hubiio_crb_error_handler(hub_v, hinfo);
+
+    /* Be sure BTE is stopped */
+
+    (void)BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_CTRL);
+
+    /*	
+     * Now clear up the rest of the error - be sure to hold crblock 
+     * to avoid race with other cpu on this node.
+     */
+    imem = REMOTE_HUB_L(hinfo->h_nasid, IIO_IMEM);
+    ieclr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IECLR);
+    if (bh->bh_bte->bte_num == 0) {
+	imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD;
+	ieclr|= IECLR_BTE0;
+    } else {
+	imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD;
+	ieclr|= IECLR_BTE1;
+    }
+
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IMEM, imem);
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, ieclr);
+
+    iidsr  = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR);
+    iidsr &= ~IIO_IIDSR_SENT_MASK;
+    iidsr |= IIO_IIDSR_ENB_MASK;
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, iidsr);
+    mutex_spinunlock(&hinfo->h_crblock, il);
+
+    bte_status = BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_STAT);
+    BTE_STORE(bh->bh_bte->bte_base, BTEOFF_STAT, bte_status & ~IBLS_BUSY);
+    ASSERT(!BTE_IS_BUSY(BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_STAT)));
+
+    switch(bh->bh_error) {
+    case IIO_ICRB_ECODE_PERR:
+	return(BTEFAIL_POISON);
+    case IIO_ICRB_ECODE_WERR:
+	return(BTEFAIL_PROT);
+    case IIO_ICRB_ECODE_AERR:
+	return(BTEFAIL_ACCESS);
+    case IIO_ICRB_ECODE_TOUT:
+	return(BTEFAIL_TOUT);
+    case IIO_ICRB_ECODE_XTERR:
+	return(BTEFAIL_ERROR);
+    case IIO_ICRB_ECODE_DERR:
+	return(BTEFAIL_DIR);
+    case IIO_ICRB_ECODE_PWERR:
+    case IIO_ICRB_ECODE_PRERR:
+	/* NO BREAK */
+    default:
+	printk("BTE failure (%d) unexpected\n", 
+		bh->bh_error);
+	return(BTEFAIL_ERROR);
+    }
+}
+#endif // BTE_ERROR
+
+void
+bte_crb_error_handler(devfs_handle_t hub_v, int btenum, 
+		      int crbnum, ioerror_t *ioe)
+/*
+ * Function: 	bte_crb_error_handler
+ * Purpose:	Process a CRB for a specific HUB/BTE
+ * Parameters:	hub_v	- vertex of hub in HW graph
+ *		btenum	- bte number on hub (0 == a, 1 == b)
+ *		crbnum	- crb number being processed
+ * Notes: 
+ *	This routine assumes serialization at a higher level. A CRB 
+ *	should not be processed more than once. The error recovery 
+ *	follows the following sequence - if you change this, be real
+ *	sure about what you are doing. 
+ *
+ */
+{
+        hubinfo_t	hinfo;
+	icrba_t		crba; 
+	icrbb_t		crbb; 
+	nasid_t		n;
+
+	hubinfo_get(hub_v, &hinfo);
+
+
+	n = hinfo->h_nasid;
+	
+	/* Step 1 */
+	crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum));
+	crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum));
+
+
+	/* Zero error and error code to prevent error_dump complaining
+	 * about these CRBs. 
+	 */
+	crbb.b_error=0;
+	crbb.b_ecode=0;
+
+	/* Step 2 */
+	REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval);
+	/* Step 3 */
+	REMOTE_HUB_S(n, IIO_ICCR, 
+		     IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum);
+	while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING)
+	    ;
+}
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)