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

📄 ci_isr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
     *		  whenever a local port executes a command with an invalid or     *		  unimplemented opcode field, invalid flags field, or non-zero     *		  status field.     *     *		- Aborted Local Port Command Encountered.  Packets with this     *		  status should never be encountered.  Only those port commands     *		  currently being processed by the port when it transitions     *		  into the disabled state can have this status.  However once     *		  a port enters the disabled state it either is in the process     *		  of being crashed or shortly will be, and all packets on all     *		  port queues are flushed during crashing of the port.     *     *		- All Other( Unknown ) Error Statuses.     *     * If a response does not contain any errors, or the error is only     * informational in nature, then the response is itself processed according     * to its port operation code.  Processing then continues with the next     * response on the port's response queue.  There is one exception to this     * rule: detection of a NOPATH status in a SNDLB packet.  The detection of     * this informational error forces deallocation of the packet instead of     * queuing it to the appropriate local port datagram free queue as would     * have automatically taken place had not the error occurred.  Deallocation     * of the packet is forced by explicit setting of the response bit within     * the flags field of the generic Vaxport driver header.     *     * Response processing terminates either when this queue is exhausted or a     * fatal error is detected triggering crashing of the port.  The port is     * also crashed if the queue interlock can not be obtained.     *     * Only cable statuses of open paths are ever updated.     */    do	{	Remqhi_rspq( pccb, cibp )	if( cibp == NULL ) {	    break;	}	cibp->opcode &= 0x3f;	if( cibp->status.failure ) {	    u_long		crash_lport = 0;	    register u_long	dispatch = 0, event = 0;	    Lock_pccb( pccb )	    if(( pb = cippd_get_pb( pccb, Pd_to_scs( cibp, pccb ), BUF ))) {		Lock_pb( pb )	    }	    switch((( cibp->status.type != T_OTHER )			? cibp->status.type			: ( T_OTHER + cibp->status.subtype ))) {		case T_OK:		    dispatch = 1;		    if( pb && pb->pinfo.state == PS_OPEN ) {			( void )ci_update_cable( pccb, pb, cibp, CABLE_GB );		    }		    break;		case T_VCC:		    break;		case T_INVBNAME:		    crash_lport = 1;		    event = SE_INVBNAME;		    break;		case T_INVBSIZE:		    crash_lport = 1;		    event = SE_INVBSIZE;		    break;		case T_ACCVIO:		    crash_lport = 1;		    event = SE_BACCVIO;		    break;		case T_NOPATH:		    if( cibp->opcode == IDREQ ) {			dispatch = 1;			if( Cselect( cibp ) != CS_AUTO ) {			    if( pb && pb->pinfo.state == PS_OPEN ) {				( void )ci_update_cable( pccb,							 pb,							 cibp,							 CABLE_GB );				if( pb->Pstatus.cable0 && pb->Pstatus.cable1 ){				    event = E_NOCABLES;				/* The response IDREQ packet is not re-used for				 * the transmission of a REQID over the other				 * cable.  Its processing must continue in case				 * it represents the REQID currently being				 * sanity checked.				 */				} else {				    register u_long	save_cable;				    save_cable = pccb->Poll_cable;				    if( Cselect( cibp ) == CS_CABLE0 ) {					pccb->Poll_cable = CS_CABLE1;				    } else {					pccb->Poll_cable = CS_CABLE0;				    }				    ( void )ci_send_reqid( pccb,							   NULL,						 	   Get_pgrp( pccb,cibp),							   DEALLOC_BUF );				    pccb->Poll_cable = save_cable;				}			    }			} else if( pb && pb->pinfo.state != PS_PATH_FAILURE ) {			    event = E_NOCABLES;			}		    } else if( cibp->opcode == LBSNT ) {			cibp->flags.rsp = 1;		    } else if( cibp->opcode == DGSNT   ||				cibp->opcode == RSTSNT ||				cibp->opcode == STRTSNT ) {			if( pb && pb->pinfo.state != PS_PATH_FAILURE ) {			    event = E_NOCABLES;			}		    } else if( pb ) {			pb->Fsmpstatus.path_closed = 1;			if( pb->pinfo.state != PS_PATH_FAILURE ) {			    event = E_NOCABLES;			}		    }		    break;		case T_BMSE:		    event = SE_BMSE;		    break;		case( T_OTHER + ST_PSVIO ):		    if( cibp->opcode == DGSNT   ||			 cibp->opcode == MSGSNT ||			 cibp->opcode == DATSNT ||			 cibp->opcode == DATREC ||			 cibp->opcode == LBSNT  ||			 cibp->opcode == LBREC ) {			crash_lport = 1;			event = SE_INVLPKTSIZE;		    } else {			event = SE_INVRPKTSIZE;			if( cibp->opcode != DGREC && pb ) {			    pb->Fsmpstatus.path_closed = 1;			}		    }		    break;		case( T_OTHER + ST_UPKT ):		    if( cibp->opcode != SNDRST && cibp->opcode != SNDSTRT ) {			event = SE_UNRECPKT;		    }		    break;		case( T_OTHER + ST_DPORT ):		    crash_lport = 1;		    event = SE_INVDPORT;		    break;		case( T_OTHER + ST_UCMD ):		    crash_lport = 1;		    event = SE_UNKCMD;		    break;		case( T_OTHER + ST_ABORT ):		    crash_lport = 1;		    event = SE_ABORTPKT;		    break;		case( T_OTHER + ST_INVPA ):		    crash_lport = 1;		    event = SE_INVPA;		    break;		case( T_OTHER + ST_INVSN ):		    crash_lport = 1;		    event = SE_INVSN;		    break;		case( T_OTHER + ST_IRESVCD ):		    crash_lport = 1;		    event = SE_IRESVCD;		    break;		case( T_OTHER + ST_IRESEQ ):		    crash_lport = 1;		    event = SE_IRESEQ;		    break;		case( T_OTHER + ST_DISCVCPKT ):		    crash_lport = 1;		    event = SE_DISCVCPKT;		    break;		case( T_OTHER + ST_INVDDL):		    crash_lport = 1;		    event = SE_INVDDL;		    break;		default:		    crash_lport = 1;		    event = SE_UNKSTATUS;		    break;	    }	    if( event ) {		if( crash_lport == 0 ) {		    ( void )ci_log_packet( pccb, pb, cibp, event, PATH_EVENT );		    ( void )cippd_crash_pb( pccb,					    pb,					    (( Eseverity( event ) == ES_E )						? E_PD : SE_PD ),					    0,					    NULL );		} else {		    ( void )ci_crash_lport( pccb,					    event,					    Pd_to_scs( cibp, pccb ));					    		}	    }	    if( pb ) {		Unlock_pb( pb )	    }	    Unlock_pccb( pccb )	    if( crash_lport ) {		return;	    }	    if( !cibp->flags.rsp ) {		if( cibp->opcode == IDREC ||		     cibp->opcode == IDREQ ||		     cibp->opcode == DGSNT ||		     cibp->opcode == DGREC ||		     cibp->opcode == LBSNT ||		     cibp->opcode == LBREC ||		     ( cibp->status.type == T_OTHER &&		       cibp->status.subtype == ST_UPKT )) {		    ( void )gvp_add_dg( pccb, Pd_to_scs( cibp, pccb ));		} else {		    ( void )gvp_add_msg( pccb, Pd_to_scs( cibp, pccb ));		}		continue;	    } else if( !dispatch ) {		( void )ci_dealloc_pkt( cibp );		continue;	    }	}	/* Responses with good or informational status are processed according	 * to their port operation codes as follows:	 *	 * Response		Processing	 *	 * Received/Transmitted	- SCS processes and disposes of response.	 *  Sequence Message	 *	 * Completed Block Data	- SCS is notified of block data transfer	 *  Transfer		  completion.	 *			- Port driver disposes of response.	 *	 * Received Datagram 	- SCS processes and disposes of datagram(	 *			  application datagrams only ).	 *			- CI PPD processes and disposes of datagram(	 *			  all other datagrams ).	 *	 * Invalidate		- Port driver disposes of response.	 *  Translation Cache	 *  Command	 * Transmitted Datagram	 * Reset Request	 * Start Request	 * Set Circuit Command	 *	 * Transmitted		- CI PPD is notified of request identification	 *  Identification	  command completion.	 *  Request		- Port driver disposes of response.	 *	 * Received		- The appropriate PB's cable status is updated(	 *  Identification	  open paths only ).	 *  Packet		- Log all crossed->uncrossed,	 *			  uncrossed->crossed, and bad->good cable	 *			  transitions( open paths only ).	 *			- CI PPD processes and disposes of response.	 *	 * Received		- The appropriate PCCB's loopback cable status	 *  Loopback Response	  is updated.         *			- Log all loopback bad->good transitions.	 *			- Port driver disposes of response.	 *	 * All other port	- The local port is crashed.	 *  operation codes	- Response processing is terminated.	 *         * Received sequenced messages, datagrams, and block data transfer         * completion packets are checked for and processed BEFORE dispatching         * on the operation code contained within the response.  Such special         * handling results in significantly improved performance.	 */	{	register SCSH		*scsbp = Pd_to_scs( cibp, pccb );	register GVPPPDH	*cippdbp = Pd_to_ppd( cibp, pccb );	if( cibp->opcode == MSGREC ) {	    ( void )scs_msg_rec( pccb, scsbp, Appl_size( cippdbp ));	    continue;	} else if( cibp->opcode == CNFREC || cibp->opcode == DATREC ) {	    ( void )scs_data_done( pccb, scsbp, &Cnfrec( cippdbp )->xctid );	} else if ( cibp->opcode == DGREC ) {	    if( cippdbp->mtype == SCSDG ) {

⌨️ 快捷键说明

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