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

📄 ci_lpmaint.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
 *		NOTE: The CI7B family of CI ports may report restoration of *		      port power without first reporting loss of it.  This *		      occurs when power loss is detected and signaled by the *		      port, but its restoration is noticed before the initial *		      interrupt is even received and processed.  In such cases *		      the appropriate interrupt service routine crashes the *		      local port with a reason code of SE_POWERUP, and *		      processing proceeds as it does for any other event. *		      Furthermore, the local port may always be immediately *		      re-initialized when the time comes to do so, because the *		      local port always has power unlike many instances when *		      the local port is crashed for power loss( *		      reason == SE_POWER ). * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   ci_lpc_panic		- CI local port crash panic flag *   ci_max_reinits		- CI max number consecutive reinitializations *   pccb			- Port Command and Control Block pointer *   reason			- Reason for crashing local CI port *   scsbp			- Address of SCS header in optional buffer * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	forkb			-  PCCB fork block *	lpinfo.reason		-  Reason for port failure *	pd.gvp.type.ci		-  CI specific PCCB fields *	    reinit_tries	-   Number consecutive re-initializations left *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.cleanup	-   1 *	    fsmstatus.fkip	-   1 *	    fsmstatus.online	-   0 * *   SMP:	The PCCB is locked INTERNALLY whenever it was not locked *		EXTERNALLY prior to routine invocation.  Locking the PCCB *		allows exclusive access to PCCB contents and prevents *		premature PB deletion.  PCCB addresses are always valid because *		these data structures are never deleted once their *		corresponding ports have been initialized. */voidci_crash_lport( pccb, reason, scsbp )    register PCCB	*pccb;    register u_long	reason;    SCSH		*scsbp;{    register PB		*pb;    register GVPH	*cibp;    u_long		port_state;    register u_long	log_regs = LOG_NOREGS, unlock = 0;    /* Crashing a local CI port consists of a number of distinct steps:     *     * 1. The crash request is pre-processed.     * 2. The local port is disabled.     * 3. The local port is cleaned up.     * 4. The local port is re-initialized.     *     * The first step is executed each time this routine is invoked.  It is the     * latter three steps which constitute crashing the port and are executed     * only once per port incarnation.  The major benefits of this single      * threading of port crashing are the assumptions made during port clean up     * and re-initialization which follow directly from it.  These assumptions     * greatly reduce code complexity and allow extension of the CI port driver     * to an SMP environment with a minimum of pain.  They are pointed out as     * they occur.     *     * Pre-processing of crash requests includes:     *     * 1. Locking the PCCB whenever it was not locked EXTERNALLY.     * 2. Retrieving the appropriate PB whenever an optional buffer was     *	  provided.     * 3. Applying the local port crash severity modifier( ESM_LPC ) to the     *    local port crash reason code.     * 4. Logging the crash request according to the provided crash reason.     * 5. Optionally panicing the system.     * 6. Deallocating the optional buffer.     *     * The local port crash severity modifier is applied( Step 3 ) ONLY if the     * local port is not already in the process of being crashed.       *     * Panicing of the system( Step 5 ) immediately terminates all further     * processing of the crash request.  Such panicing is OPTIONAL.  It is     * requested only when the CI configuration variable flag ci_lpc_panic is     * set.  This flag is set only when special debugging activity is required.     *     * Following pre-processing this routine ascertains whether or not the port     * has already been crashed but not yet re-initialized.  If this is indeed     * the case, as indicated by a PCCB clean up in progress status flag, then     * the current request is dismissed after the PCCB is unlocked( provided it     * was unlocked within this routine ).  Otherwise, actual crashing of the     * port commences with disablement of the local port including:     *     *  1. Setting the port clean up in progress flag to prohibit additional     *     crashings of the port until it has been re-initialized.     *  2. Taking the port offline.     *  3. Ascertaining the port state from the crash reason.  Note, it is only     *	   necessary to ascertain whether the port is currently enabled or not.     *  4. Disabling interrupts on the port( enabled ports only ).     *  5. Gracefully shutting down the port to abort all commands currently     *	   undergoing processing( enabled ports only ).     *  6. Disabling the port adapter in a hardware port type specific fashion.     *  7. Resetting bus specific register contents( CIBCI/CIBCA/CIXCD only ).     *  8. Disabling the port maintenance timer.     *     * Two additional actions are taken whenever the local port has lost power(     * CI750/CI780/CIBCI only ) or is marked broken and is to be permanently     * shutdown.  These two actions constitute unmapping of the local port.     *     *  9. Unmapping the adapter I/O space system PTEs to a black hole page to     *	   prevent stray machine checks.     * 10. Changing the interrupt service handler for the local port to a     *	   special routine( ci_unmapped_isr()) for fielding of all future     *	   interrupts while the adapter I/O space is unmapped.     *     * The first few steps of local port disablement( Steps 1-3 ) are executed     * by this routine.  The remaining steps( Steps 4-10 ) are accomplished     * through indirect invocation of the appropriate CI family specific     * local CI port disablement routine.     *     * At the time the decision is made to crash the port, the processor from     * which the port is crashed exists in one of two states distinguished     * mainly by whether the processor is at kernel mode or interrupt level.     * The existence of these two possible environments does not interfere with     * port disablement.  Unfortunately, the same is not necessary true for     * port clean up, a section of the port driver which is quite complicated     * in its own right.  Therefore, to avoid potential problems and to allow     * certain code simplifying assumptions to be made, port clean up has been     * structured into two stages, separated by both time and environment.     *     * The first stage of port clean up consists of those actions which should     * be performed immediately following port disablement and are insensitive     * to processor state.  The second stage consists of those activities which     * need not be performed immediately following port disablement and should     * be executed within a constant well-defined processor state.  The first     * stage of port clean up is directed by this routine which then schedules     * the second stage, directed by ci_cleanup_port(), through forking.  It is     * this act of forking which generates the constant environment necessary     * for the second stage of port clean up.     *     * The PCCB fork block is used to schedule the second stage of clean up.     * It should always be available because it is used only for port clean up     * and re-initialization, these activities are single threaded, and     * re-initialization always follows clean up.  Guaranteed availability     * of the PCCB fork block is one of the benefits of single threading of     * port clean up and re-initialization.     *     * The first stage of port clean up includes:     *     * 1. Scheduling clean up of the CI port through forking.     * 2. Unlocking the PCCB provided it was locked within this routine.     *     * Note that the first stage of port clean up currently does not contain     * any processor state insensitive actions which must be immediately     * performed following port disablement.  However, the structure exists to     * add them as it becomes necessary to do so.     *     * The second stage of port clean up includes:     *     * 1. Locking the PCCB.     * 2. Removing and deallocating all packets logged out to the datagram and     *    message buffer logout areas.  CI ports logout all internalized queue     *	  entries to the appropriate area only when power failure is detected.     * 3. Unlocking the PCCB.     * 4. Notifying the CI PPD of failure of the local port.     *     * The CI PPD completes the clean up of its portion of the local port     * including the failure and clean up all paths, both formative and fully     * established, originating at the port.  Clean up of the last path     * triggers scheduling of port re-initialization by the CI PPD.  Successful     * completion of port re-initialization marks the beginning of the next     * incarnation of the port and releases all restriction on crashing the     * port if further requests to do so are made.     */    if( !Test_pccb_lock( pccb )) {	Lock_pccb( pccb )	unlock = 1;    }    if( scsbp ) {	cibp =  Scs_to_pd( scsbp, pccb );	pb = cippd_get_pb( pccb, scsbp, BUF );    } else {	pb = NULL;	cibp = NULL;    }    if( !pccb->Fsmstatus.cleanup ) {	Set_lpc_event( reason );    }    switch( Mask_esevmod( reason )) {	case SE_POWER:		case SE_POWERUP:	case SE_ICMDQ0:	case SE_ICMDQ1:		case SE_ICMDQ2:		case SE_ICMDQ3:	case SE_IDFREEQ:	case SE_IMFREEQ:	case SE_RRSPQ:	case SE_RDFREEQ:	case SE_RMFREEQ:	case SE_MSE:	case SE_BIMSE:		case SE_DSE:		case SE_PARITY:	case SE_BIPARITY:	case SE_PORTERROR:	case SE_BIERROR:	case SE_MFQE:		case SE_SANITYTIMER:	case FE_NOCI:	case FE_BADMAXPORT:	case FE_PORTERROR:	    log_regs = LOG_REGS;	case FE_BADUCODE:	    ( void )ci_log_dev_attn( pccb, reason, log_regs );	    break;	case SE_PPDSANITY:	case SE_NOPATH:		case SE_INVLPKTSIZE:	case SE_INVBNAME:	case SE_INVBSIZE:	case SE_BACCVIO:	case SE_INVDPORT:	case SE_UNKCMD:		case SE_ABORTPKT:	case SE_UNKSTATUS:	case SE_UNKOPCODE:	case SE_INVOPCODE:	case SE_INVPA:		case SE_INVSN:		case SE_INVDDL:	case SE_IRESVCD:	case SE_IRESEQ:		case SE_DISCVCPKT:	    ( void )ci_log_packet( pccb, pb, cibp, reason, LPORT_EVENT );	    break;	default:	    ( void )panic( PANIC_UNKLPC );    }    if( ci_lpc_panic ) {	( void )panic( PANIC_REQLPC );    } else if( cibp ) {	( void )ci_dealloc_pkt( cibp );    }    if( !pccb->Fsmstatus.cleanup ) {	pccb->Fsmstatus.cleanup = 1;	pccb->Fsmstatus.online = 0;	pccb->Reinit_tries = ci_max_reinits;	switch( Mask_esevmod( reason )) {	    case SE_POWER:	 case SE_POWERUP:	case SE_MSE:	    case SE_BIMSE:	 case SE_DSE:		case SE_PARITY:	    case SE_BIPARITY:	 case SE_PORTERROR:	case SE_BIERROR:	    case SE_SANITYTIMER: case FE_NOCI:		case FE_PORTERROR:		port_state = PS_UNINIT;		break;	    default:		port_state = PS_ENAB;	}	( void )( *pccb->Disable_port )( pccb, port_state );	pccb->lpinfo.reason = reason;	Pccb_fork( pccb, ci_cleanup_port, PANIC_PCCBFB )    }    if( unlock ) {	Unlock_pccb( pccb )    }}/*   Name:	ci_remote_reset	- Reset Remote Port and System * *   Abstract:	This function initiates resetting of a remote CI port and

⌨️ 快捷键说明

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