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

📄 ci_isr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
		( void )scs_dg_rec( pccb, scsbp, Appl_size( cippdbp ));	    } else {		( void )cippd_receive( pccb,				       cippdbp,				       ( u_long )cippdbp->mtype );	    }	    continue;	} else {	    switch( cibp->opcode ) {		case DGSNT:		case RSTSNT:		case STRTSNT:		case CKTSET:		case TCINV:		    break;		case MSGSNT:		    ( void )scs_msg_snt( pccb, scsbp, Appl_size( cippdbp ));		    continue;		case IDREQ:		    ( void )cippd_reqid_snt( pccb, Get_pgrp( pccb, cibp ));		    break;		case IDREC:		    Lock_pccb( pccb )		    if(( pb = cippd_get_pb( pccb, scsbp, BUF ))) {			Lock_pb( pb )			/* Crash the path if the remote port is not in an			 * appropriate state.			 */			if( pb->pinfo.state == PS_OPEN ) {			    if( Idrec( cippdbp )->port_state != PS_ENAB &&				Idrec( cippdbp )->port_state != PS_ENAB_MAINT){				( void )ci_log_packet( pccb,						       pb,						       cibp,						       E_RPORTSTATE,						       PATH_EVENT );				( void )cippd_crash_pb( pccb,							pb,							E_PD,							0,							NULL );				Unlock_pb( pb )				Unlock_pccb( pccb )				( void )gvp_add_dg( pccb, scsbp );				continue;			    } else {				( void )ci_update_cable( pccb,							 pb,							 cibp,							 CABLE_CROSSED );				( void )ci_update_cable( pccb,							 pb,							 cibp,							 CABLE_BG );			    }			}			Unlock_pb( pb )		    }		    Unlock_pccb( pccb )		    ( void )cippd_receive( pccb, cippdbp, CNFE_ID_REC );		    continue;		case LBREC:		    Lock_pccb( pccb )		    ( void )ci_update_cable( pccb, NULL, cibp, CABLE_LB_BG );		    Unlock_pccb( pccb )		    break;		case MSGREC:	case CNFRET:	case DATREQ0:	case DATREQ2:		case CNTRD:	case LBSNT:	case MDATSNT:	case MDATREQ:		case MCNFREC:	case MDATREC:	case CNFREC:	case DATREC:		case DGREC:		    ( void )ci_crash_lport( pccb, SE_INVOPCODE, scsbp );		    return;		default:		    ( void )ci_crash_lport( pccb, SE_UNKOPCODE, scsbp );		    return;	    }	}	( void )ci_dealloc_pkt( cibp );	}    }	while( pccb->Pqb.rspq.flink );}/*   Name:	ci_unmapped_isr	- Unmapped CI Adapter Interrupt Service Routine * *   Abstract: * *   Inputs: * *   IPL_CI			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    lpstatus.mapped	-   0 *	    lpstatus.power	-   Port has power status flag *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.broken	-   Port is broken status flag *	    fsmstatus.online	-   0 * *   Outputs: * *   IPL_CI			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    lpstatus.power	-   Port has power status flag *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.broken	-   Port is broken status flag *	    fsmstatus.cleanup	-   Cleanup in progress status flag * *   SMP: */voidci_unmapped_isr( pccb )    register PCCB	*pccb;{    register u_long	cnfr, event, log_regs = LOG_REGS, save_ipl;    /* The steps involved in processing an interrupt from an unmapped local CI     * port are as follows:     *     * 1. IPL is synchronized to IPL_SCS.     * 2. The PCCB is locked.     * 3. The mapped state of the local port is verified.     * 4. The local port is mapped.     * 5. The interrupt is processed according to its nature.     * 6. The interrupt is logged.     * 7. The local port is disabled.     * 8. The PCCB is unlocked.     * 9. IPL is restored.     *     * The local port is always unmapped on entry into this routine; however it     * may be found to be mapped following locking of the PCCB( Step 2 ).     * There is only one way this can occur, if another thread were to process     * an interrupt notifying the port driver of power availability on the     * local port.  Such processing leaves the local port mapped because the     * severe error which caused the port to be unmapped in the first place(     * power loss ) has been alleviated.  It also removes any reason for     * continued execution of the current thread.   Either the power up     * interrupt processed by the other thread was originally designated for     * the current one, or the interrupt designated for the current thread was     * superseded by the power up interrupt processed by the other one.  In any     * event, there is no reason for the current thread to continue execution     * when it finds the local port mapped, and this is why the mapped state of     * the local port is verified( Step 3 ) after the PCCB is unlocked.     *     * This routine services interrupts only when the local port is temporarily     * without power or marked marked broken and permanently shutdown.  A panic     * is issued in any other circumstance.     *     * All interrupts on broken local ports are considered to be stray.     * Processing of these stray interrupts includes re-mapping of the local     * port adapter I/O space( Step 4 ).  This allows access to local port     * registers for the purpose of logging the interrupt( Step 6 ) and     * disabling the local port( Step 7 ).  Note that only the adapter I/O     * space is re-mapped.  The interrupt service handler for the local port is     * NOT restored to the routine appropriate for the local port hardware port     * type.  All interrupts on this local port continue to be serviced by this     * special routine.  Furthermore, this re-mapping is only temporary.  The     * local port is automatically returned to the unmapped state in which it     * was found at the beginning of interrupt processing during disablement of     * the local port( Step 7 ).     *     * Interrupts on local ports temporarily without power( CI750/CI780/CIBCI     * only ) may occur for many reasons.  In all cases the first action taken     * is to fully re-map the local port( Step 4 ).  This includes restoration     * of the appropriate routine as interrupt service handler for the local     * port.  Full re-mapping is done because the most likely reason for an     * interrupt from such a port is notification of restoration of port power.     * Such notification is the only interrupt reason which results in the     * local port left fully mapped at the conclusion of interrupt processing.     * As such, it is just more efficient to fully re-map local ports     * temporarily without power during processing of their interrupts.     *     * Note that full re-mapping of such local ports is not without its     * consequences.  Restoration of the normal routine as interrupt service     * handler forces subsequent interrupts to be processed by that routine,     * even if the current interrupt has not yet been fully deallt with.     * Fortunately, such sequences of events can only occur on those local      * ports subject to independent power loss which may function also in SMP     * environments( CIBCI only ).     * All routines which normally serve as interrupt service handlers for such     * local ports( cibci_isr()) have been modified to deal correctly with     * these situations when they occur.     *     * Once the local port has been re-mapped, the exact cause of the interrupt     * may be ascertained from cached contents of the bus specific     * configuration register.  Cached contents are employed      * 1. Port power up.     * 2. Port power down.     * 3. CI adapter not present( CI750/CIBCI only ).     *     * Any other interrupt is unexpected and is treated as a stray interrupt.     *     */    if( pccb == NULL ) {	return;    }    save_ipl = Splscs();    Lock_pccb( pccb )    if( pccb->Lpstatus.mapped ) {	Unlock_pccb( pccb )	( void )splx( save_ipl );	return;    }    if( pccb->Fsmstatus.broken ) {	( void )ci_map_port( pccb, MAP_REGS );	event = W_STRAY;    } else if( !pccb->Lpstatus.power ) {	if( ci_map_port( pccb, MAP_FULL ) == RET_SUCCESS ) {	    cnfr = *pccb->Cnfr;	    switch( pccb->lpinfo.type.hwtype ) {		case HPT_CI750:		case HPT_CI780:		    if( cnfr & CI780_CNF_PUP ) {			event = I_POWERUP;			pccb->Lpstatus.power = 1;		    } else if( cnfr & CI780_CNF_PDWN ) {			event = W_POWER;		    } else if( cnfr & CI780_CNF_NOCI ) {			event = FE_NOCI;			pccb->Fsmstatus.broken = 1;		    } else {			event = W_STRAY;		    }		    break;		case HPT_CIBCI:		    if( cnfr & CIBCI_CNF_PUP ) {			event = I_POWERUP;			pccb->Lpstatus.power = 1;		    } else if( cnfr & CIBCI_CNF_PDWN ) {			event = W_POWER;		    } else if( cnfr & ( CIBCI_CNF_NOCI | CIBCI_CNF_DCLO )) {			event = FE_NOCI;			pccb->Fsmstatus.broken = 1;		    } else {			event = W_STRAY;		    }		    break;		default:		    ( void )panic( PANIC_HPT );	    }	} else {	    event = FE_NOCI;	    pccb->Fsmstatus.broken = 1;	}	if(( pccb->Lpstatus.power || pccb->Fsmstatus.broken ) &&	     !pccb->Fsmstatus.cleanup ) {	    pccb->Fsmstatus.cleanup = 1;	    Pccb_fork(  pccb, ci_init_port, PANIC_PCCBFB );	}    } else {	( void )panic( PANIC_BADUNMAP );    }    ( void )ci_log_dev_attn( pccb, event, LOG_REGS );    ( void )( *pccb->Disable_port )( pccb, PS_UNINIT );    Unlock_pccb( pccb )    ( void )splx( save_ipl );}/*   Name:	ci780_isr	- CI750/CI780 Interrupt Service Routine * *   Abstract:	This routine is the primary interrupt service routine for CI750 *		and CI780 local ports.  It services all interrupts except: * *		1. When a local port adapter has lost power. *		2. When a local port is marked broken and permanently shutdown. * *		At such times the local port is unmapped and all interrupts are *		serviced instead by ci_unmapped_isr().   * *		CI750 adapters are located within their own physically separate *		cabinets.  They may lose power independently of the rest of the *		system.  They may also become uncabled from the CMI on which *		they nominally reside leading to their local ports being marked *		broken and permanently shutdown.  When either of these events *		occurs, much( but not all ) of adapter I/O space becomes *		unaccessible and any access attempt results in a machine check. *		It is as a protection against these extraneous machine checks *		that the local port is unmapped and interrupts re-directed to *		ci_unmapped_isr(). * *		CI780 adapters do NOT suffer from the same handicaps as CI750 *		adapters.  They are not located within their own physically *		separate cabinets and are not subject to extraneous machine *		checks.  There is no need to unmap a local CI780 port on loss *		of power.  However, such ports are unmapped anyway on loss of *		power because it is not worth distinguishing between two *		hardware port types( CI750 and CI780 ) which are otherwise so *		identical on the occurrence of an extremely rare condition that *		the remainder of the system normally panics on.  As for *		unmapping CI780 adapters whenever they are marked broken and *		are permanently shutdown, all local ports regardless of their *		hardware port types undergo such unmapping, and there is no *		reason to do anything different for CI780 local ports. *

⌨️ 快捷键说明

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