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

📄 ci_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
     * 1. Allocating a full size CI port specific datagram buffer for use as a     *	  port command packet.     * 2. Formatting the SNDLB specific portion of the command packet.     * 3. Formatting the generic Vaxport header.     * 4. Initiating port command execution.     *     * Port command execution( Step 4 ) leads to loopback datagram transmission     * over the CI to the local port itself.  The local port is used as the     * target for the loopback datagram because it is the only port guaranteed     * to be present.  The loopback packet is transmitted over the current     * polling cable instead of allowing the port to choose the physical cable     * for transmission. The port is always crashed whenever loopback datagram     * transmission can not be successfully initiated.     *     * Successful reception of the loopback datagram( LBREC ) successfully     * completes the connectivity test on the current cable.  Local port     * loopback cable status is updated and any bad->good loopback cable     * transitions are logged.  The connectivity test on the current cable is     * also completed by either failure to transmit the loopback datagram or     * failure to successfully receive the loopback datagram.  Such failure is     * noted the next time this routine is invoked( Phase 1 ) to test the     * connectivity status of the target cable.     *     * Prior to testing local port connectivity, the CI PPD port polling burst     * size and contact frequency for the local port are reset from CI     * configuration variables.     */    pccb->Contact = ci_cippdcontact;    pccb->Burst = ci_cippdburst;    ( void )ci_update_cable( pccb, NULL, NULL, CABLE_LB_GB );    if( pccb->Lpstatus.connectivity ) {	if(( npaths = pccb->lpinfo.Nform_paths + pccb->lpinfo.Npaths ) <= 1 &&	     ( npaths == 0 ||	       cippd_get_pb( pccb, ( SCSH * )&pccb->lpinfo.addr, NO_BUF ))) {	    pccb->Lpstatus.connectivity = 0;	    pccb->Lbstatus.cable0_test = 0;	    pccb->Lbstatus.cable1_test = 0;	    skip_test = 0;	} else if( pccb->Poll_cable == FIRST_CABLE ) {	    if( pccb->Lbstatus.cable0_prev || !pccb->Lbstatus.cable0_test ) {		skip_test = 0;	    } else {		skip_test = 1;	    }	} else if( pccb->Lbstatus.cable1_prev || !pccb->Lbstatus.cable1_test ){	    skip_test = 0;	} else {	    skip_test = 1;	}	if( skip_test ) {	    return;	}    }    if(( scsbp = gvp_alloc_dg( pccb ))) {	cibp = Scs_to_pd( scsbp, pccb );	bp = Sndlb( Pd_to_ppd( cibp, pccb ));	bp->lblength = LBDSIZE;	( void )bcopy( pccb->Lbdata, bp->lbdata, LBDSIZE );	( void )bcopy(( u_char * )&pccb->Lbcrc, bp->crc, sizeof( u_long ));	Format_gvph( pccb, cibp, SNDLB, 		     Scaaddr_low( pccb->lpinfo.addr ), RECEIVE_BUF )	if(( Cselect( cibp ) = pccb->Poll_cable ) == FIRST_CABLE ) {	    pccb->Lbstatus.cable0_curr = 1;	    pccb->Lbstatus.cable0_test = 1;	} else {	    pccb->Lbstatus.cable1_curr = 1;	    pccb->Lbstatus.cable1_test = 1;	}	Insqti_maintenance( cibp, pccb )    }}/*   Name:	ci_update_ptype	- Update Hardware Port Type of Remote Port * *   Abstract:	This routine updates the remote port's hardware port type as *		necessary.  It is required because CI750, CI780, and CIBCI CI *		ports all identify themselves as CI780 CI ports to requests for *		identification. * *		This routine is invoked by the CI PPD finite state machine *		after it has received both an identification packet and a *		START/STACK CI PPD datagram.  It is only at this time that *		sufficient information is available for correctly specifying *		the remote port's hardware port type. * *		NOTE: This is an optional PD routine( Update_ptype ) for use by *		      the CI PPD finite state machine.  The CI port driver *		      provides it because it is unable to easily distinguish *		      between certain CI ports until a certain point in the *		      path establishment process.  Other port drivers do not *		      have such needs and need not provide this routine. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   pb				- Path Block pointer * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pb				- Path Block pointer *	pinfo.type.hwtype	-  Remote hardware port type * *   SMP:	The PB is locked( EXTERNALLY ) postponing potential PB deletion *		and allowing exclusive access to PB contents. */voidci_update_ptype( pb )    PB			*pb;{    if( pb->pinfo.type.hwtype == HPT_CI780 ) {	if( bcmp(( char *)&pb->sb->sinfo.hwtype, "V750", 4 ) == 0 ) {	    pb->pinfo.type.hwtype = HPT_CI750;	} else if(( bcmp(( char *)&pb->sb->sinfo.hwtype, "V780", 4 ) != 0 ) &&		  ( bcmp(( char *)&pb->sb->sinfo.hwtype, "8600", 4 ) != 0 )) {	    pb->pinfo.type.hwtype = HPT_CIBCI;	}    }}/*   Name:	ci_alloc_pkt	- Allocate CI Port Command Packet * *   Abstract:	This function allocates a CI port specific command packet from *		dynamic kernel memory.  Such packets must always be directed to *		the local port response queue following command execution. *		They must never be directed to the appropriate local port free *		queue. * *		NOTE: The CI specific PCCB field pkt_size must contain the size *		      of the largest CI port command to always be directed to *		      the local port response queue following command *		      execution.  Currently this is the SETCKT port command. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    pkt_size		-   Size of port command packet * *   Outputs: * *   IPL_SCS			- Interrupt processor level * *   Return Values: * *   Address of generic Vaxport header in buffer on success *   Otherwise NULL * *   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. */GVPH *ci_alloc_pkt( pccb )    PCCB		*pccb;{    register GVPH	*cibp;    KM_ALLOC( cibp, GVPH *, pccb->Pkt_size, KM_SCABUF, KM_NOWAIT|KM_WIRED )    if( cibp ) {	U_long( cibp->size ) = ( u_long )(( DYN_CICMD << 16 ) |					   pccb->Pkt_size );	Dm_msg_dg( cibp, pccb->Pkt_size )    }    return( cibp );}/*   Name:	ci_dealloc_pkt	- Deallocate CI Port Command Packet * *   Abstract:	This routine deallocates a CI port specific command packet to *		dynamic kernel memory. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   cibp			- Address of generic Vaxport header * *   Outputs:	 * *   IPL_SCS			- Interrupt processor level * *   SMP:	No locks are required. */voidci_dealloc_pkt( cibp )    GVPH	*cibp;{    KM_FREE(( char * )cibp, KM_SCABUF )}/*   Name:	ci_update_cable	- Update Cable Status of Path Block * *   Abstract:	This routine checks for the specified cable transition.  The *		following types of transitions may be checked for: * *		1. Cable transitions from good to bad. *		2. Cable transitions from bad to good. *		3. Cables transition from crossed to uncrossed or uncrossed to *		   crossed. *		4. Loopback cable transitions from good to bad. *		5. Loopback cable transitions from bad to good. * *		Occurrence of a cable transition triggers logging of the event. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   cibp			- Address of generic Vaxport header( OPTIONAL ) *   pb				- Address of Path Block( OPTIONAL ) *   pccb			- Port Command and Control Block pointer *   type			- CABLE_BG, CABLE_GB, CABLE_CROSSED, *				   CABLE_LB_BG, or CABLE_LB_GB * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pb				- Path Block pointer *	pd.gvp.type.ci		-  CI specific PB fields *	    pstatus		-   Path status flag bits *		cable0		-    Cable0 status flag *		cable1		-    Cable1 status flag *		cables_crossed	-    Cables crossed flag *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    lbstatus		-   Loopback status flags *		cable0_curr	-    Cable 0 current status flags *		cable0_prev	-    Cable 0 previous status flags *		cable1_curr	-    Cable 1 current status flags *		cable1_prev	-    Cable 1 previous status flags * *   SMP:       The PCCB is locked( EXTERNALLY ) in case the occurrence of a *		cable transition requires its logging. * *		The PB is locked( EXTERNALLY ), whenever one is provided, *		postponing potential deletion and allowing exclusive access to *		PB contents. */voidci_update_cable( pccb, pb, cibp, type )    PCCB		*pccb;    PB			*pb;    GVPH		*cibp;    u_long		type;{    register LBRECH	*lb;    register u_long	event = 0;    /* The following types of transition checks update the cables status of     * appropriate PBs utilizing information found within CI port packets:     *     * 1. CABLE_GB	- Cable transitions from cable good to cable bad.     * 2. CABLE_BG	- Cable transitions from cable bad to cable good.     * 3. CABLE_CROSSED	- Cable transitions from cables crossed to cables     *			  uncrossed or from cables uncrossed to cables crossed.     *     * Determination of whether loopback cables have transitioned from good to     * bad( CABLE_LB_GB ) updates the loopback cable status of appropriate     * PCCBs and does NOT utilize CI port packets but only PCCB information.     *     * The last type of cable transition checking, whether loopback cables have     * transitioned from bad to good, utilizes CI port packets but only when     * such packets are provided.  Otherwise, only PCCB information is used in     * such determinations together with the additional assumption that the     * appropriate loopback cable status are now good.  The loopback cable     * statuses of appropriate PCCBs are always updated.     */    switch( type ) {	case CABLE_GB:	    if( Cable0_status( cibp ) != CABLE_ACK ) {		if( !pb->Pstatus.cable0 ) {		    event = W_CABLE0_GB;		    pb->Pstatus.cable0 = 1;		}	    } else if( !pb->Pstatus.cable1 ) {		event = W_CABLE1_GB;		pb->Pstatus.cable1 = 1;	    }	    break;	case CABLE_BG:	    if( Receive_cable( cibp ) == CS_CABLE0 ) {		if( pb->Pstatus.cable0 ) {		    event = I_CABLE0_BG;		    pb->Pstatus.cable0 = 0;		}	    } else if( pb->Pstatus.cable1 ) {		event = I_CABLE1_BG;		pb->Pstatus.cable1 = 0;	    }	    break;	case CABLE_CROSSED:	    if( Send_cable( cibp ) == Receive_cable( cibp )) {		if( pb->Pstatus.cables_crossed ) {		    event = I_CABLES_CU;		    pb->Pstatus.cables_crossed = 0;		}	    } else if( !pb->Pstatus.cables_crossed ) {		event = W_CABLES_UC;		pb->Pstatus.cables_crossed = 1;	    }	    break;	case CABLE_LB_GB:	    if( pccb->Poll_cable == FIRST_CABLE ) {		if( !pccb->Lbstatus.cable0_prev && pccb->Lbstatus.cable0_curr){		    event = W_CABLE0_LBGB;		}		pccb->Lbstatus.cable0_prev = pccb->Lbstatus.cable0_curr;	    } else {		if( !pccb->Lbstatus.cable1_prev && pccb->Lbstatus.cable1_curr){		    event = W_CABLE1_LBGB;		}		pccb->Lbstatus.cable1_prev = pccb->Lbstatus.cable1_curr;	    }	    break;	case CABLE_LB_BG:	    lb = Lbrec( Pd_to_ppd( cibp, pccb ));	    if( Comp_loopback( pccb, lb )) {		if( Cselect( cibp ) == CS_CABLE0 ) {		    pccb->Lbstatus.cable0_curr = 0;		    if( pccb->Lbstatus.cable0_prev ) {			event = I_CABLE0_LBBG;		    }		} else {		    pccb->Lbstatus.cable1_curr = 0;		    if( pccb->Lbstatus.cable1_prev ) {			event = I_CABLE1_LBBG;		    }		}	    }	    break;	default:	    ( void )panic( PANIC_CABLE );    }    if( event ) {	( void )ci_log_packet( pccb, pb, NULL, event, RPORT_EVENT );    }}

⌨️ 快捷键说明

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