⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shuberror.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    icrbe.icrbe_context,	    icrbe.icrbe_toutvld,	    icrbe.icrbe_ctxtvld);}/* * hubiio_crb_error_handler * *	This routine gets invoked when a hub gets an error  *	interrupt. So, the routine is running in interrupt context *	at error interrupt level. * Action: *	It's responsible for identifying ALL the CRBs that are marked *	with error, and process them.  *	 * 	If you find the CRB that's marked with error, map this to the *	reason it caused error, and invoke appropriate error handler. * *	XXX Be aware of the information in the context register. * * NOTE: *	Use REMOTE_HUB_* macro instead of LOCAL_HUB_* so that the interrupt *	handler can be run on any node. (not necessarily the node  *	corresponding to the hub that encountered error). */inthubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo){	cnodeid_t	cnode;	nasid_t		nasid;	ii_icrb0_a_u_t		icrba;		/* II CRB Register A */	ii_icrb0_b_u_t		icrbb;		/* II CRB Register B */	ii_icrb0_c_u_t		icrbc;		/* II CRB Register C */	ii_icrb0_d_u_t		icrbd;		/* II CRB Register D */	ii_icrb0_e_u_t		icrbe;		/* II CRB Register D */	int		i;	int		num_errors = 0;	/* Num of errors handled */	ioerror_t	ioerror;	int		rc;	nasid = hinfo->h_nasid;	cnode = NASID_TO_COMPACT_NODEID(nasid);	/*	 * XXX - Add locking for any recovery actions	 */	/*	 * Scan through all CRBs in the Hub, and handle the errors	 * in any of the CRBs marked.	 */	for (i = 0; i < IIO_NUM_CRBS; i++) {		/* Check this crb entry to see if it is in error. */		icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i));		if (icrbb.b_mark == 0) {			continue;		}		icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i));		IOERROR_INIT(&ioerror);		/* read other CRB error registers. */		icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i));		icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i));		icrbe.ii_icrb0_e_regval = REMOTE_HUB_L(nasid, IIO_ICRB_E(i));		IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);		/* Check if this error is due to BTE operation,		* and handle it separately.		*/		if (icrbd.d_bteop ||			((icrbb.b_initiator == IIO_ICRB_INIT_BTE0 ||			icrbb.b_initiator == IIO_ICRB_INIT_BTE1) &&			(icrbb.b_imsgtype == IIO_ICRB_IMSGT_BTE ||			icrbb.b_imsgtype == IIO_ICRB_IMSGT_SN1NET))){			int bte_num;			if (icrbd.d_bteop)				bte_num = icrbc.c_btenum;			else /* b_initiator bit 2 gives BTE number */				bte_num = (icrbb.b_initiator & 0x4) >> 2;			hubiio_crb_free(hinfo, i);			bte_crb_error_handler(hub_v, bte_num,					      i, &ioerror,					      icrbd.d_bteop);			num_errors++;			continue;		}		/*		 * XXX		 * Assuming the only other error that would reach here is		 * crosstalk errors. 		 * If CRB times out on a message from Xtalk, it changes 		 * the message type to CRB. 		 *		 * If we get here due to other errors (SN0net/CRB)		 * what's the action ?		 */		/*		 * Pick out the useful fields in CRB, and		 * tuck them away into ioerror structure.		 */		IOERROR_SETVALUE(&ioerror,xtalkaddr,icrba.a_addr << IIO_ICRB_ADDR_SHFT);		IOERROR_SETVALUE(&ioerror,widgetnum,icrba.a_sidn);		if (icrba.a_iow){			/*			 * XXX We shouldn't really have BRIDGE-specific code			 * here, but alas....			 *			 * The BRIDGE (or XBRIDGE) sets the upper bit of TNUM			 * to indicate a WRITE operation.  It sets the next			 * bit to indicate an INTERRUPT operation.  The bottom			 * 3 bits of TNUM indicate which device was responsible.			 */			IOERROR_SETVALUE(&ioerror,widgetdev,					 TNUM_TO_WIDGET_DEV(icrba.a_tnum));			/*			* The encoding of TNUM (see comments above) is			* different for PIC. So we'll save TNUM here and			* deal with the differences later when we can			* determine if we're using a Bridge or the PIC.			*			* XXX:  We may be able to remove saving the widgetdev			* above and just sort it out of TNUM later.			*/			IOERROR_SETVALUE(&ioerror, tnum, icrba.a_tnum);		}		if (icrbb.b_error) {		    /*		     * CRB 'i' has some error. Identify the type of error,		     * and try to handle it.		     *		     */		    switch(icrbb.b_ecode) {			case IIO_ICRB_ECODE_PERR:			case IIO_ICRB_ECODE_WERR:			case IIO_ICRB_ECODE_AERR:			case IIO_ICRB_ECODE_PWERR:			case IIO_ICRB_ECODE_TOUT:			case IIO_ICRB_ECODE_XTERR:			    printk("Shub II CRB %d: error %s on hub cnodeid: %d",				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);			    /*			     * Any sort of write error is mostly due			     * bad programming (Note it's not a timeout.)			     * So, invoke hub_iio_error_handler with			     * appropriate information.			     */			    IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);			    /* Go through the error bit lookup phase */			    if (error_state_set(hub_v, ERROR_STATE_LOOKUP) ==				    ERROR_RETURN_CODE_CANNOT_SET_STATE)				return(IOERROR_UNHANDLED);			    rc = hub_ioerror_handler(				    hub_v,				    DMA_WRITE_ERROR,				    MODE_DEVERROR,				    &ioerror);			    if (rc == IOERROR_HANDLED) {				rc = hub_ioerror_handler(					hub_v,					DMA_WRITE_ERROR,					MODE_DEVREENABLE,					&ioerror);			    }else {				printk("Unable to handle %s on hub %d",					hubiio_crb_errors[icrbb.b_ecode],					cnode);				/* panic; */			    }			    /* Go to Next error */			    print_crb_fields(i, icrba, icrbb, icrbc,				    icrbd, icrbe);			    hubiio_crb_free(hinfo, i);			    continue;			case IIO_ICRB_ECODE_PRERR:			case IIO_ICRB_ECODE_DERR:			    printk("Shub II CRB %d: error %s on hub : %d",				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);			    /* panic */			default:			    printk("Shub II CRB error (code : %d) on hub : %d",				    icrbb.b_ecode, cnode);			    /* panic */		    }		} 		/*		 * Error is not indicated via the errcode field		 * Check other error indications in this register.		 */		if (icrbb.b_xerr) {		    printk("Shub II CRB %d: Xtalk Packet with error bit set to hub %d",			    i, cnode);		    /* panic */		}		if (icrbb.b_lnetuce) {		    printk("Shub II CRB %d: Uncorrectable data error detected on data "			    " from NUMAlink to node %d",			    i, cnode);		    /* panic */		}		print_crb_fields(i, icrba, icrbb, icrbc, icrbd, icrbe);		if (icrbb.b_error) {		/* 		 * CRB 'i' has some error. Identify the type of error,		 * and try to handle it.		 */		switch(icrbb.b_ecode) {		case IIO_ICRB_ECODE_PERR:		case IIO_ICRB_ECODE_WERR:		case IIO_ICRB_ECODE_AERR:		case IIO_ICRB_ECODE_PWERR:			printk("%s on hub cnodeid: %d",				hubiio_crb_errors[icrbb.b_ecode], cnode);			/*			 * Any sort of write error is mostly due			 * bad programming (Note it's not a timeout.)			 * So, invoke hub_iio_error_handler with			 * appropriate information.			 */			IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);			rc = hub_ioerror_handler(					hub_v, 					DMA_WRITE_ERROR, 					MODE_DEVERROR, 					&ioerror);                        if (rc == IOERROR_HANDLED) {                                rc = hub_ioerror_handler(                                        hub_v,                                        DMA_WRITE_ERROR,                                        MODE_DEVREENABLE,                                        &ioerror);                                ASSERT(rc == IOERROR_HANDLED);                        }else {				panic("Unable to handle %s on hub %d",					hubiio_crb_errors[icrbb.b_ecode],					cnode);				/*NOTREACHED*/			}			/* Go to Next error */			hubiio_crb_free(hinfo, i);			continue;		case IIO_ICRB_ECODE_PRERR:                case IIO_ICRB_ECODE_TOUT:                case IIO_ICRB_ECODE_XTERR:		case IIO_ICRB_ECODE_DERR:			panic("Fatal %s on hub : %d",				hubiio_crb_errors[icrbb.b_ecode], cnode);			/*NOTREACHED*/				default:			panic("Fatal error (code : %d) on hub : %d",				icrbb.b_ecode, cnode);			/*NOTREACHED*/		}		} 	/* if (icrbb.b_error) */			/*		 * Error is not indicated via the errcode field 		 * Check other error indications in this register.		 */				if (icrbb.b_xerr) {			panic("Xtalk Packet with error bit set to hub %d",				cnode);			/*NOTREACHED*/		}		if (icrbb.b_lnetuce) {			panic("Uncorrectable data error detected on data "				" from Craylink to node %d",				cnode);			/*NOTREACHED*/		}	}	return	num_errors;}/* * hubii_check_widget_disabled * *	Check if PIO access to the specified widget is disabled due *	to any II errors that are currently set. * *	The specific error bits checked are: *		IPRBx register: SPUR_RD (51) *				SPUR_WR (50) *				RD_TO (49) *				ERROR (48) * *		WSTAT register: CRAZY (32) */inthubii_check_widget_disabled(nasid_t nasid, int wnum){	iprb_t		iprb;	ii_wstat_u_t	wstat;	iprb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB(wnum));	if (iprb.iprb_regval & (IIO_PRB_SPUR_RD | IIO_PRB_SPUR_WR |		IIO_PRB_RD_TO | IIO_PRB_ERROR)) {#ifdef DEBUG	    printk(KERN_WARNING "II error, IPRB%x=0x%lx\n", wnum, iprb.iprb_regval);#endif	    return(1);	}	wstat.ii_wstat_regval = REMOTE_HUB_L(nasid, IIO_WSTAT);	if (wstat.ii_wstat_regval & IIO_WSTAT_ECRAZY) {#ifdef DEBUG	    printk(KERN_WARNING "II error, WSTAT=0x%lx\n", wstat.ii_wstat_regval);#endif	    return(1);	}	return(0);}/*ARGSUSED*//* * hubii_prb_handler *      Handle the error reported in the PRB for wiget number wnum. *      This typically happens on a PIO write error. *      There is nothing much we can do in this interrupt context for *      PIO write errors. For e.g. QL scsi controller has the *      habit of flaking out on PIO writes. *      Print a message and try to continue for now *      Cleanup involes freeing the PRB register */static voidhubii_prb_handler(vertex_hdl_t hub_v, hubinfo_t hinfo, int wnum){        nasid_t         nasid;        nasid = hinfo->h_nasid;        /*         * Clear error bit by writing to IECLR register.         */        REMOTE_HUB_S(nasid, IIO_IECLR, (1 << wnum));        /*         * PIO Write to Widget 'i' got into an error.         * Invoke hubiio_error_handler with this information.         */        printk( "Hub nasid %d got a PIO Write error from widget %d, "				"cleaning up and continuing", nasid, wnum);        /*         * XXX         * It may be necessary to adjust IO PRB counter         * to account for any lost credits.         */}inthubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo){        int             wnum;        nasid_t         nasid;        int             num_errors = 0;        iprb_t          iprb;        nasid = hinfo->h_nasid;        /*         * Check if IPRB0 has any error first.         */        iprb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB(0));        if (iprb.iprb_error) {                num_errors++;                hubii_prb_handler(hub_v, hinfo, 0);        }        /*         * Look through PRBs 8 - F to see if any of them has error bit set.         * If true, invoke hub iio error handler for this widget.         */        for (wnum = HUB_WIDGET_ID_MIN; wnum <= HUB_WIDGET_ID_MAX; wnum++) {                iprb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB(wnum));                if (!iprb.iprb_error)                        continue;                num_errors++;                hubii_prb_handler(hub_v, hinfo, wnum);        }        return num_errors;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -