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

📄 ci_init.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
 *   Return Values: * *   RET_SUCCESS		- Local port successfully prepared *   RET_FAILURE		- CI adapter is absent & can't be initialized *   				- Insufficient memory for port initialization * *   SMP:	The PCCB is locked( EXTERNALLY ) allowing unrestricted access. *		This is probably unnecessary because of lack of conflict for *		the PCCB due to the single threadedness of port clean up and *		initialization.  It is done anyway to guarantee unrestricted *		access and because the CI PPD interval timer may still be *		operational. * *		Access to port free queues is by means of memory interlocking *		queuing instructions. */u_longci_setup_port( pccb )    register PCCB	*pccb;{    register u_long	n;    register SCSH	*scsbp;    register gvpbq	*q, *qend;    register u_long	status = 0;    u_long		log_regs, sid = Sid;    /* The steps involved in preparing a CI port for initialization are as     * follows:     *     * 1. Presence of a local operational port is verified.     * 2. All configuration register errors are cleared( CI750, CI780, CIBCI     *	  only ).     * 3. The CPU microcode revision level is verified( 11/750 only ).     * 4. An initial number of free datagrams and messages, sufficient to fill     *	  the port's internal cache plus 1, are allocated and inserted into the     *    appropriate local port queues.     *     * Preparations for local port initialization are aborted on detection of     * any errors.  Errors in Steps 1,3 permanently abort port initialization.     * The fatal event is logged and the local port is taken permanently     * offline by marking it broken and unmapping it.  Errors in Step 4 abort     * only the current consecutive port initialization attempt.  The event is     * logged and all local port free queues are flushed with all flushed     * buffers being deallocated.     *     * VAX 11/750 CPU microcode revision levels must be checked prior to every     * attempt at CI750 port initialization( Step 3 ).  This is because 11/750     * writable control store is volatile and can be lost either on power     * failure or other very serious errors.     *     * Allocation of messages and datagrams and their insertion into     * appropriate local port free queues( Step 4 ) is bypassed whenever such     * buffers had been previously allocated.  This can only occur when     * preparation of the local port during a previous consecutive     * initialization succeeded although all subsequent attempts at starting of     * the port itself failed.     *     * NOTE: The port is not informed of the presence of free datagram and     *	     message buffers even though the queues have been previously empty.     *	     The port is disabled and therefore is in no condition to take     *	     notice.  The port is notified of free queue entry availability     *	     only after its successful enabling.     */    if( ci_test_port( pccb ) != RET_SUCCESS ) {	status = FE_NOCI;	log_regs = LOG_REGS;	pccb->Fsmstatus.broken = 1;    }#ifdef vax    else if( cpu == VAX_750 &&	 (( struct cpu750 * )&sid )->cp_urev < MIN_VAX750_REV ) {	status = FE_CPU;	log_regs = LOG_NOREGS;	pccb->Devattn.cicpurevlev.ci_hwtype = lscs.system.hwtype;	pccb->Devattn.cicpurevlev.ci_mincpurev = MIN_VAX750_REV;	pccb->Devattn.cicpurevlev.ci_currevlev				= (( struct cpu750 * )&sid )->cp_urev;	pccb->Fsmstatus.broken = 1;    }#endif vax    else if( pccb->Dfreeq.flink == NULL ) {	for( n = pccb->Dg_cache + 1; n; --n ) {	    if(( scsbp = gvp_alloc_dg( pccb )) == NULL ||	         insqti( Scs_to_pd( scsbp, pccb ), &pccb->Dfreeq, 0 ) > 0 ) {		if( scsbp ) {		    ( void )gvp_dealloc_dg( pccb, scsbp );		}		status = E_NOMEM;		log_regs = LOG_NOREGS;		break;	    }	}	if( status == 0 ) {	    for( n = pccb->Msg_cache + 1; n; --n ) {		if(( scsbp = gvp_alloc_msg( pccb )) == NULL ||		     insqti( Scs_to_pd( scsbp, pccb ), &pccb->Mfreeq, 0 ) > 0){		    if( scsbp ) {			( void )gvp_dealloc_msg( pccb, scsbp );		    }		    status = E_NOMEM;		    log_regs = LOG_NOREGS;		    break;		}	    }	}	if( status ) {	    for( q = &pccb->Dfreeq, qend = &pccb->Mfreeq; q <= qend; ++q ) {		Flushq( pccb, q )	    }	}    }    if( status == 0 ) {	status = RET_SUCCESS;    } else {	( void )ci_log_dev_attn( pccb, status, log_regs );	if( pccb->Fsmstatus.broken ) {	    ( void )ci_unmap_port( pccb );	}	status = RET_FAILURE;    }    return( status );}/*   Name:	ci_test_port	- Test Operational Status of Local CI Port * *   Abstract:	This function checks for the presence of a local CI port and *		clears all bus specific errors which require clearing if the *		port is both present and operational.  It is invoked only *		during local port initialization. * *		CI780/CIBCA/CIXCD local ports are always present though they *		may be broken.  CI750/CIBCI local ports may completely *		disappear if the condition triggering failure, clean up, and *		re-initialization was sufficiently severe.  The most likely *		cause of such a disappearence would be the powering down or *		uncabling of a CI750/CIBCI in its adjacent cabinet. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   cpu			- CPU type code *   cpusw			- CPU switch structure *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *          lpstatus.mapped     -   1 *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.broken	-   0 *	    fsmstatus.online	-   0 * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    ciregptrs.cnfr	-   Configuration register pointer * *   Return Values: * *   RET_SUCCESS		- Local port present and accessible *   RET_FAILURE		- Local port absent * *   SMP:	No locks are required.  PCCB addresses are always valid *		allowing access to static fields because these data structures *		are never deleted once their corresponding ports have been *		initialized( The PCCB is locked EXTERNALLY anyway ). */u_longci_test_port( pccb )    register PCCB	*pccb;{    register u_long	status = RET_SUCCESS;    /* The local CI port is declared absent in the following cases:     *     * 1. CIBCI/CIBCA/CIXCD failed its self-test.     * 2. CI750/CI780/CIBCI configuration register is unaccessible.     * 3. CIBCI/CIBCA/CIXCD bus specific device type register is unaccessible.     * 4. CI750/CIBCI port lacks power or has been uncabled in its separate     *    cabinet.     * 5. Verification of hardware port type fails.     *     * All errors are cleared from the CI750/CI780/CIBCI configuration.     * register( Step 2 ).  The CIBCA/CIXCD do not define such a register and     * so no clearing of errors is required.     *     * NOTE: There is never a need to clear errors in the BIIC/XMI error     *	     register because resetting of the node during port disablement     *	     accomplishes that task.     */    switch( pccb->lpinfo.type.hwtype ) {#ifdef vax	case HPT_CI750:	case HPT_CI780:	    if( Bad_reg( pccb->Cnfr )		  ||		 ( *pccb->Cnfr & CI780_CNF_NOCI ) ||		 ( *pccb->Cnfr & CI780_CNF_ADAP ) != NEX_CI ) {		status = RET_FAILURE;	    } else {		*pccb->Cnfr = *pccb->Cnfr;	    }	    break;#endif vax	case HPT_CIBCI:	    if( Bad_reg( pccb->Bityp )				      ||		 ( *pccb->Bictrl & BICTRL_BROKE )		      ||	         Bad_reg( pccb->Cnfr )				      ||		 ( *pccb->Cnfr & ( CIBCI_CNF_NOCI | CIBCI_CNF_DCLO )) ||		 ( *pccb->Bityp & BITYP_TYPE ) != BI_CIBCI ) {		status = RET_FAILURE;	    } else {		*pccb->Cnfr = *pccb->Cnfr;	    }	    break;	case HPT_CIBCA_AA:	case HPT_CIBCA_BA:	    if( Bad_reg( pccb->Bityp )			      ||		 ( *pccb->Bictrl & BICTRL_BROKE )	      ||		 ( *pccb->Bityp & BITYP_TYPE ) != BI_CIBCA    ||		 ( pccb->lpinfo.type.hwtype == HPT_CIBCA_AA &&			( *pccb->Bityp & CIBCA_DEV_BCABA ))   ||		 ( pccb->lpinfo.type.hwtype == HPT_CIBCA_BA &&			( *pccb->Bityp & CIBCA_DEV_BCABA ) == 0 )) {		status = RET_FAILURE;	    }	    break;	case HPT_CIXCD:	    Lock_cidevice( pccb )	    if( Bad_reg( pccb->Xdev )	  ||		 ( *pccb->Xbe & XMI_STF ) ||		 (( *pccb->Xdev & XMIDTYPE_TYPE ) != XMI_CIXCD )) {		status = RET_FAILURE;	    }	    Unlock_cidevice( pccb )	    break;	case HPT_CIKMF:	    if( Bad_reg( pccb->Xdev )	  ||		 ( *pccb->Xbe & XMI_STF ) ||		 (( *pccb->Xdev & XMIDTYPE_TYPE ) != XMI_CIKMF )) {		status = RET_FAILURE;	    }	    break;	default:	    ( void )panic( PANIC_HPT );    }    return( status );}/*   Name:	ci7b_load	- Load CI7B Family Functional Microcode * *   Abstract:	This function loads CI7B family functional microcode during *		local CI750/CI780/CIBCI port initialization. * *		NOTE: As presently implemented this function is not suitable *		      for use on hardware platforms requiring matching field *		      alignments and access types( ie- only longword aligned *		      entities may be longword accessed ).  This is due to how *		      each 6 byte CI7B family microcode word is currently *		      accessed during microcode loading and verification.  This *		      can be fixed but it is not worth it because CI7B family *		      ports will NOT be supported on non-VAX hardware *		      platforms. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   ci_ucode			- CI port functional microcode pointer *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *          lpstatus.mapped     -   1 *          lpstatus.onboard    -   0 *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.broken	-   0 *	    fsmstatus.online	-   0 * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    ciregptrs.madr	-   Maintenance address register pointer *	    ciregptrs.mdatr	-   Maintenance data register pointer *	    devattn.ciucode	-   Faulty microcode information * *   Return Values: * *   RET_SUCCESS		- Port microcode successfully loaded *   RET_FAILURE		- CI port microcode did not pass verification * *   SMP:	The PCCB is locked( EXTERNALLY ) to synchronize access.  This *		is probably unnecessary because of lack of conflict for the *		PCCB due to the single threadedness of port clean up and *		initialization.  It is done anyway to guarantee unrestricted *		access and because the CI PPD interval timer may still be *		active. */u_longci7b_load( pccb )    register PCCB	*pccb;{    register u_char	*ucode;    register u_long	csp, event, load_addr, status = RET_SUCCESS;    /* The port's writable control store is loaded with the in-core image of     * the CI7B functional microcode.  Proper loading is verified by reading     * the loaded microcode out of the port's writable control store and     * comparing it against the in-code microcode image.  Any comparison error     * aborts the current consecutive attempt at port initialization.  The     * event is logged and the port itself is disabled to flush out loaded     * microcode.     *     * A panic occurs whenever an attempt is made to load microcode into a     * local port with onboard functional microcode.     *     * NOTE: Where loading begins in the writable control store is dependent     *	     upon whether the port contains both PROM and RAM( CI750, CI780,     *	     and CIBCI ) or is RAM only.     */    if( pccb->Lpstatus.onboard ) {	( void )panic( PANIC_ONBOARD );    }    load_addr = ( Ci7b_allram( ci_ucode ) ? CI7B_ARAM_LOAD : CI7B_RAM_LOAD );    for( csp = load_addr, ucode = ( u_char * )ci_ucode;	 csp < C

⌨️ 快捷键说明

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