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

📄 bvp_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)bvp_subr.c	4.5	(ULTRIX)	11/13/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1987 - 1989 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* *   Modification History * *   13-Nov-1990	Pete Keilty *	Change all instances of PF_ERROR to PF_PORTERROR because of a *	fix to SCS resource deallocation. * *   25-Sep-1990	JAW *	initial wait value of zero is incorrect for routine bvp_wait_prt.   *	According to the spec, -1 is the proper (non-legal) value.  Also *	found some missing "{}" in loop in the same routine. *	 *   19-Sep-1989	Pete Keilty *	Added pccb to macro Pd_to_ppd. * *   23-Aug-1989	Pete Keilty *	Change wbflush() to macro define in scamachmac.h WBFLUSH. * *   25-May-1989	Pete Keilty *	Add wbflush() for mips cpu's ISIS. *	Add Splscs() to reinit & cleanup routines, fork no longer raises ipl. * *   05-Mar-1989	Todd M. Katz		TMK0003 *	1. Include header file ../vaxmsi/msisysap.h. *	2. Use the ../machine link to refer to machine specific header files. * *   19-Aug-1988	Todd M. Katz		TMK0002 *	1. Change all instances of PF_FATALERROR -> PF_ERROR as no current *	   instance of crashing the local port is fatal. *	2. SCA event codes have been completed revised.  All former BVP SSP *	   local port crash codes are now defined as severe error events.  The *	   local port crash attribute itself is applied by bvp_crash_lport(). *	3. Currently bvp_proc_rsp() incorrectly crashes the path when it *	   encounters a packet with an unknown status.  Change it so that it *	   crashes the local port with a reason code of SE_UNKSTATUS. * *   02-Jun-1988	Ricky S. Palmer *	Removed inclusion of header file ../vaxmsi/msisysap.h * *   09-Jan-1988	Todd M. Katz		TMK0001 *	Included new header files ../vaxscs/scaparam.h, ../vaxmsi/msisysap.h, *	and ../vaxmsi/msiscs.h. * *   21-Dec-87		map *	Added missing {} in wait_prt() routine.  Caused port initialization *	to fail if Self-test not done. *//*	Include files */#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/buf.h"#include "../h/conf.h"#include "../h/dir.h"#include "../h/kmalloc.h"#include "../h/user.h"#include "../h/map.h"#include "../h/vm.h"#include "../h/vmmac.h"#include "../h/dk.h"#include "../h/cmap.h"#include "../h/uio.h"#include "../h/ioctl.h"#include "../h/fs.h"#include "../machine/cpu.h"#include "../machine/scb.h"#include "../io/uba/ubareg.h"#include "../io/uba/ubavar.h"#ifdef vax#include "../machine/mtpr.h"#endif vax#include "../io/bi/bireg.h"#include "../io/bi/buareg.h"#include "../io/bi/bvpreg.h"#include "../io/bi/bvpport.h"#include "../io/bi/bdareg.h"#include	"../h/errlog.h"#include	"../h/ksched.h"#include	"../io/scs/sca.h"#include	"../io/scs/scaparam.h"#include	"../io/scs/scamachmac.h"#include	"../io/ci/cippdsysap.h"#include	"../io/ci/cisysap.h"#include	"../io/msi/msisysap.h"#include	"../io/bi/bvpsysap.h"#include	"../io/gvp/gvpsysap.h"#include	"../io/uba/uqsysap.h"#include	"../io/sysap/sysap.h"#include	"../io/ci/cippdscs.h"#include	"../io/ci/ciscs.h"#include	"../io/msi/msiscs.h"#include	"../io/bi/bvpscs.h"#include	"../io/gvp/gvpscs.h"#include	"../io/uba/uqscs.h"#include	"../io/scs/scs.h"#include	"../io/gvp/gvp.h"#include	"../io/bi/bvpppd.h"/*	Data definitions */u_long		bvp_wait_prt();void		bvp_cleanup(), bvp_disable();extern	u_long	gvp_queue_retry;extern	struct	bidata	bidata[];extern	int	hz;/* 	Port Info Block */extern	struct bvp_port_info bvp_port_info[];/* BVP switch structure */extern	struct bvp_sw bvp_sw[];extern	int    nbvptypes;/*	BVP command table */extern	struct 	bvp_cmd	bvp_cmd[];#define DELAYONE 5/**//* * * *	Name:		bvp_init_port *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */short	bvp_init_port( pccb )PCCB		*pccb;{GVPPQB		*pqb;GVPPQB		*phys_pqb;struct bvpregs	*bvrg;u_long		ps;int		count;	if( bvp_wait_prt(pccb) != RET_SUCCESS) {		return(RET_FAILURE);	/* Port is dead			*/	}	pqb = &pccb->Pqb;	/* Get pointer to PQB			*/	phys_pqb = (GVPPQB *)svtophy(pqb); /* Physical address of PQB	*/	bvrg = (struct bvpregs *)Pccb.port_regs; /* Get addr of port regs *//* *	Issue Port Init command */	bvrg->bvp_pc = BVP_PC_OWN | 		       ((u_long)phys_pqb & 0xffffff00) |		       BVP_CMD_PINIT; /* Write Port Init Instruction	*/	WBFLUSH	count = 0;	while ( count < DELAYONE ) {	/* Wait for at most 1 second	*/		if ( (bvrg->bvp_pc & BVP_PC_OWN) == 0 ) 			break;		DELAY(200000)		count = count + 1;	}	if ( count == DELAYONE ) {		return( RET_FAILURE );  /* Init Failed	*/	}	ps = bvrg->bvp_ps;	if ( (ps & BVP_PS_PST) != BVP_PSTATE_INIT ) {		return( RET_FAILURE );	}	bvrg->bvp_ps = ps & ~BVP_PS_OWN; /* Clear ownership bit		*/	WBFLUSH	return( RET_SUCCESS );	 /* and return success			*/}/**//* * * *	Name:		bvp_wait_prt *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */u_long	bvp_wait_prt(pccb)PCCB	*pccb;{struct	bvpregs		*bvrg;u_long			prog_count = -1;u_long			bvp_status;int			count;	bvrg = Pccb.port_regs;	/* Get address of Port Registers	  */	for(;;) {	    for(;;) {		if( (bvrg->bvp_ps & BVP_PS_STD) == 0) { /* Self test not done */			if (prog_count != bvrg->bvp_pd) { /* Any progress ? */				prog_count = bvrg->bvp_pd; /* Yes - update */				DELAY(1000000)	/* Delay 1 second	*/			}			else {				bvp_crash_lport( pccb, 						 SE_NOPATH, 						 (SCSH *)NULL ); /* No - we died  */				return( RET_FAILURE );			}		}		else			break;	    }	    bvp_status = bvrg->bvp_ps;	/* Get copy of status register	  */	    bvrg->bvp_ps = bvp_status & ~BVP_PS_OWN;	    WBFLUSH	    switch( bvp_status & BVP_PS_PST ) {	    case BVP_PSTATE_STOP:		bvrg->bvp_pc = BVP_PC_OWN | BVP_CMD_RESTART;		WBFLUSH		DELAY(1000000)	/* Delay 1 second	*/		for(;;) {		    if( (bvrg->bvp_pc & BVP_PC_OWN) != 0 ) { /* Cmd not complete */			prog_count = bvrg->bvp_pd;	/* Reset counter	*/			DELAY(1000000)	/* Delay 1 second	*/			if (prog_count != bvrg->bvp_pd) { /* Any progress ? */				prog_count = bvrg->bvp_pd; /* Yes - update */			}			else {				bvp_crash_lport( pccb, 						 SE_NOPATH, 						 (SCSH *)NULL ); /* No - we died  */				return( RET_FAILURE );			}		    }		    else			break;		}		bvp_status = bvrg->bvp_ps;  /* Get copy of status register */		bvrg->bvp_ps = bvp_status & ~BVP_PS_OWN;		WBFLUSH		if ( (bvp_status & BVP_PS_PST) != BVP_PSTATE_UNDF ) {			return( RET_FAILURE );		}		return( RET_SUCCESS );		break;	    case BVP_PSTATE_UNDF:		if ( (BVP_PS_OWN | BVP_PS_XSTP | BVP_PS_ACC | BVP_PS_STD ) ==		bvp_status ) 		/* All o.k. ?		  */		    return ( RET_SUCCESS );	/* Yes indeed		  */		if ( BVP_PS_ACC & bvp_status )	/* No - Can we at least communicate */		    return ( RET_SUCCESS );	/* Yes find out what we can */		return( RET_FAILURE );		/* Port is dead in the water */		break;	    case BVP_PSTATE_ENAB:		return( RET_SUCCESS );		break;	    default:		break;	    }	}}/**//* * * *	Name:		bvp_proc_rsp *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */void	bvp_proc_rsp(pccb)PCCB	*pccb;{register GVPH	*bvpbp;SCSH		*tmpscs;u_long		port_crash = 0;u_long		path_crash = 0; /* Remove and process each packet on the local port's response queue until * either the queue is exhausted or the local port is crashed. */    do	{	Remqhi_rspq( pccb, bvpbp )	if ( bvpbp == ( GVPH * )NULL )	    break;	if( bvpbp->status.failure ) {	    switch((( bvpbp->status.type != T_OTHER )			? bvpbp->status.type			: ( T_OTHER + bvpbp->status.subtype ))) {		/* Unknown Local Port Command.		 *		 * This status is generated whenever the local port executes a		 * command with an invalid  opcode field.		 *		 * The local port is crashed and the current packet is disposed		 * of.  Any packets remaining within the local port's response		 * queue are flushed during crashing of the port.		 */		case ( T_OTHER + ST_URCMD ):		    port_crash = SE_UNKCMD;		    break;		/* Unimplemented Port Command.		 *		 * This status is generated whenever the local port executes a		 * command with an unimplemented  opcode field.		 *		 * The local port is crashed and the current packet is 		 * disposed of. Any packets remaining within the local port's		 * response queue are flushed during crashing of the port.		 */		case ( T_OTHER + ST_UICMD ):		    port_crash = SE_UNKCMD;		    break;		/* Invalid FLAGS or STATUS field		 *		 * This status is generated whenever the local port executes a		 * command with an invalid  flags or non-zero status field.		 *		 * The local port is crashed and the current packet is 		 * disposed of. Any packets remaining within the local port's		 * response queue are flushed during crashing of the port.		 */		case ( T_OTHER + ST_IVLP ):		    port_crash = SE_UNKCMD;		    break;		/* All Other Error Statuses.		 *		 * The local port is crashed and the current packet is disposed		 * of.  Any packets remaining within the local port's response		 * queue are flushed during crashing of the port.		 */		default:		    port_crash = SE_UNKSTATUS;		    break;		}	    /* Crash the local port.  Crashing the local port immediately	     *  terminates all response processing.	     */	       ( void )bvp_crash_lport( pccb,					port_crash,					Pd_to_scs( bvpbp, pccb ));		return;	}	/* Process the current packet according to its port operation code.	 *	 * Received sequenced messages are checked for and processed BEFORE	 * dispatching on the operation code contained within the packet.  Such 	 * special handling results in significantly improved performance.	 *	 * Received messages are always processed and disposed of by SCS.	 */	if ( bvpbp->opcode == MSGREC ) {	    if( (Lpinfo.bvp_type == BI_AIE) ||		(Lpinfo.bvp_type == BI_AIE_TK) ||		(Lpinfo.bvp_type == BI_AIE_TK70)) {		tmpscs = Pd_to_scs( bvpbp, pccb ); 	    }	    ( void )scs_msg_rec( pccb,				 Pd_to_scs( bvpbp, pccb ),				 ( Pd_to_ppd( bvpbp, pccb )->length - 2 ));	    continue;	    }	switch( bvpbp->opcode ) {	    /* Transmitted sequenced messages are always processed and 	     * disposed of by SCS.	     */	    case MSGSNT:		( void )scs_msg_snt( pccb,				     Pd_to_scs( bvpbp, pccb ),				     ( Pd_to_ppd( bvpbp, pccb )->length - 2 ));		continue;	    /* Received datagrams are processed and disposed of by SCS if they	     * contain application datagrams.  If they are not application	     * datagrams then the port is sick and the path is crashed.	     */	    case DGREC: {		register GVPPPDH		*bvpppdbp;		if (( bvpppdbp = Pd_to_ppd( bvpbp, pccb ))->mtype == SCSDG )		    ( void )scs_dg_rec( pccb,					Pd_to_scs( bvpbp, pccb ),					bvpppdbp->length - 2 );		else {		    ( void )bvp_crash_lport( pccb,					    SE_INVOPCODE,					    Pd_to_scs( bvpbp, pccb ));		    return;		}		continue;		}	    /* Crash the local port for all other known port operation codes.	     * Crashing the local port immediately terminates all response	     * processing.	     */	    case DGSNT:		( void )bvp_crash_lport( pccb,					SE_INVOPCODE,					Pd_to_scs( bvpbp, pccb ));		return;	    /* Crash the local port for all unknown port operation codes.	     * Crashing the local port immediately terminates all response	     * processing.	     */	    default:		( void )bvp_crash_lport( pccb,					SE_UNKOPCODE,					Pd_to_scs( bvpbp, pccb ));		return;	    }    }	while( pccb->Pqb.rspq.flink != ( gvpbq * )NULL );}/**//* * * *	Name:		bvp_qtrans *	 *	Abstract:	Queue transition handler *			 *	Inputs: * *	pccb		- Pointer to PCCB for the port *	mask		- Number representing queue that transitioned *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */void	bvp_qtrans( pccb, queno )

⌨️ 快捷键说明

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