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

📄 cippd_event.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	Pccb_fork( pccb, pccb->Init_port, PPDPANIC_PCCBFB )    } else {	for( pb = pccb->Form_pb.flink, next_pb = Pb->flink;	     pb != &pccb->Form_pb;	     pb = next_pb, next_pb = Pb->flink ) {	    Lock_pb( Pb )	    if( Pb->pinfo.state != PS_PATH_FAILURE ) {		if( Pb->pinfo.state != PS_OPEN ) {		    Pb->pinfo.reason = reason;		    ( void )cippd_log_path( pccb, Pb, NULL, W_ABORT_PATH );		    Pb->pinfo.state = PS_PATH_FAILURE;		    Incr_pb_sem( Pb )		    Pb_fork( Pb, cippd_clean_fpb, PPDPANIC_PBFB )		} else {		    ( void )panic( PPDPANIC_PSTATE );		}	    }	    Unlock_pb( Pb )	}	for( i = ( CIPPD_MAXPATHS - 1 ); i >= 0; --i ) {	    if(( pb = pccb->Open_pb[ i ])) {		Lock_pb( Pb )		if( Pb->pinfo.state == PS_OPEN ) {		    Pb->pinfo.reason = reason;		    ( void )cippd_log_path( pccb, Pb, NULL, W_FAIL_PATH );		    Pb->pinfo.state = PS_PATH_FAILURE;		    Incr_pb_sem( Pb )		    Pb_fork( Pb, cippd_clean_pb, PPDPANIC_PBFB )		} else if( Pb->pinfo.state != PS_PATH_FAILURE ) {		    ( void )panic( PPDPANIC_PSTATE );		}		Unlock_pb( Pb )	    }	}    }    Unlock_pccb( pccb )}/*   Name:	cippd_poll	- Poll Remote Ports for their Identification * *   Abstract:	This routine polls all remote ports, both known and unknown, *		from a specific local port.  Through this process new systems *		are discovered and the state of CI PPD paths to known systems *		verified.  The polling process is itself sanity checked to *		verify the operational status of the local port. * *		Port Polling is accomplished by requesting remote port *		identifications.  Each time this routine is invoked the *		identification of a subset of all potentially existing remote *		ports accessible from the local port is requested.  It takes *		may take several routine invocations to sweep through all *		potentially accessible remote ports. * *		The number of ports polled during each invocation is a function *		of the maximum number of ports to poll, the polling burst size, *		and the next port to poll within the port's current sweep.  The *		first factor is governed by a dynamically adjustable parameter *		as is the second at the discretion of individual port drivers. * *		The state of established CI PPD paths is determined during each *		sweep by transmitted all identification requests over a *		specific physical cable.  This allows the state of this *		component of an established CI PPD path to be verified.  When *		the current sweep completes a new cable is chosen for the next *		sweep.   * *		This routine is also responsible for allocating and adding to *		the appropriate local port datagram free queue an initial *		number of free datagram buffers.  These buffers are used for *		the reception of remote port identifications solicited both by *		port polling and by the CI PPD finite state machine.  They are *		also used for reception of unsolicited START CI PPD datagrams *		from various remote systems. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   cippd_max_port		- CI PPD maximum port number to recognize *   cippd_penable		- CI PPD port polling enable flag *   pccb			- Port Command and Control Block pointer *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus		-   Finite State Machine status flags *		nosanity_chk	-    Skip sanity checking flag  *		online		-    1 *	    ppddgs		-   Num path establishment dgs left to allocate * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.sanity	-   Port polling ( sanity check ) in progress *	    next_port		-   Next port to poll *	    poll_cable		-   CI cable to use for polling *	    ppddgs		-   Num path establishment dgs left to allocate *	    sanity_port		-   Sanity check remote port * *   SMP:	The PCCB is locked( EXTERNALLY ) to synchronize access and to *		postpone crashing of the local port if it fails while polling *		is in progress. */voidcippd_poll( pccb )    register PCCB	*pccb;{    register SCSH	*scsbp;    register u_long	nports, max_port, ( *test )();;    /* Execute the following steps when port polling is currently enabled:     *     * 1. Allocate and add to the specific local port datagram free queue any     *	  CI PPD path establishment datagrams remaining to be allocated.     * 2. Continue the current polling sweep by requesting the identification     *	  of all remote ports to be polled during the current interval.     * 3. Enable a sanity check on local port functioning.     * 4. Optionally test the current connectivity status of the specified     *	  local port in a port specific fashion.     * 5. Arrange for the next sweep during the next polling interval.     *     * CI PPD path establishment datagrams are allocated and added to     * appropriate local port datagram free queues by this routine( Step 1 )     * contrary to normal expectations.  Logically, one would expect     * cippd_start(), the routine responsible for starting CI PPD activity on     * a specified local port, to allocate and add them.  It does not because     * such allocations can fail, and such failures within cippd_start() create     * unnecessairy complications.  It is much easier and more robust to     * perform the allocations within this routine, ancillary to port polling.     * Individual datagram allocation attempts can still fail; however, such     * failures can be ignored because many more opportunities exist to     * allocate all required CI PPD path establishment datagrams.     *     * The sanity check on local port functioning is enabled( Step 3 ) only if     * it has not been permanently disabled on the local port and at least one     * port was polled during the current polling interval.  This check     * operates by requiring the request for identification of the very first     * remote port polled to be transmitted before the next timer interval.     * Failure to do so leads the CI PPD to assume the existence of a     * questionable local port functional status and the local port is     * explicitly crashed by the CI PPD.     *     * The current connectivity status of the specified local port is     * optionally tested in a port specific fashion( Step 4 ) provided at least     * one port was polled during the current polling interval.  Such testing     * MUST occur prior to making arrangements for the next sweep during the     * next polling interval.  Connectivity testing is bypassed whenever the     * appropriate port driver has failed to establish a routine for testing     * local port connectivity.  Presumably it deems such testing of its local     * ports unnecessary.     *     * Arrangements are made for the next sweep during the next polling     * interval( Step 5 ) only when the current sweep completes.  This of     * course also requires at least one port to be polled during the current     * polling interval.  Arrangements for the next polling interval are not     * made by this routine but external to it by cippd_timer().     */    if( cippd_penable ) {	while( pccb->Ppddgs ) {	    if(( scsbp = ( *pccb->Alloc_dg )( pccb ))) {		( void )( *pccb->Add_dg )( pccb, scsbp );		--pccb->Ppddgs;	    } else {		break;	    }	}	pccb->Sanity_port = pccb->Next_port;	for( nports = pccb->Burst, max_port = Maxport( pccb );	     nports > 0 && pccb->Next_port <= max_port;	     --nports, ++pccb->Next_port ) {	    if(( *pccb->Send_reqid )( pccb,				      NULL,				      ( u_long )pccb->Next_port,				      DEALLOC_BUF ) == RET_ALLOCFAIL ) {		break;	    }	}	if( nports < pccb->Burst ) {	    if( !pccb->Fsmstatus.nosanity_chk ) {		pccb->Fsmstatus.sanity = 1;	    }	    if( pccb->Next_port > max_port ) {		if(( test = pccb->Test_lportconn )) {		    ( void )( *test )( pccb );		}		pccb->Next_port = 0;		if( ++pccb->Poll_cable > pccb->Max_cables ) {		    pccb->Poll_cable = FIRST_CABLE;		}	    }	}    }}/*   Name:	cippd_timer	- CI PPD Interval Timer Routine * *   Abstract:	This routine oversees all CI PPD timer related functions.  It *		is executed on a per port basis once every cippd_itime seconds *		where cippd_itime is a dynamically adjustable parameter. * *   Inputs: * *   IPL_SOFTCLOCK		- Interrupt processor level *   cippd_max_port		- CI PPD maximum port to recognize *   cippd_itime		- CI PPD port timer interval *   pccb			- Port Command and Control Block pointer * *   Outputs: * *   IPL_SOFTCLOCK		- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.timer	-   CI PPD interval timer activated status bit *	    poll_due		-   Port polling interval timer *	    poll_interval	-   Current port polling interval *	    timer_interval	-   Current CI timer interval *   pb				- Path Block pointer *	ppd.cippd		-  CI PPD specific PB fields *	    due_time		-   CI PPD traffic interval timer *	    fsmpstatus.timer	-   CI PPD traffic interval timer activated bit * *   SMP:	The PCCB is locked to synchronize access and as required by *		optional PD routines which notify local ports of continued CI *		PPD activity.  PCCB addresses are always valid because these *		data structures are never deleted once their corresponding *		ports have been initialized. * *		PBs are locked to synchronize access and for the declaration *		of CI PPD timeout configuration events when their traffic *		interval timers have expired. */voidcippd_timer( pccb )    register PCCB	*pccb;{    register pbq	*pb, *next_pb;    register u_long	save_ipl = Splscs(), ( *notify )();    /* Each timer interval the following sequence of actions occurs:     *     * 1. IPL is synchronized to IPL_SCS.     * 2. The PCCB is locked.     * 3. The local port is optionally notified, in a port specific fashion, of     *	  the continued activity of the CI PPD.     * 4. A sanity check on port functioning is performed.     * 5. The port's queue of formative PBs is scanned and CI PPD timeout     *	  configuration events declared on each path whose traffic interval     *    timer has expired.  Each PB is locked for the duration of its check.     * 6. The next round of port polling from the port is initiated provided     *	  the polling interval timer has expired.     * 7. The next timer wake up on the local port is scheduled.     * 8. The PCCB is unlocked.     * 9. IPL is restored.     *     * Steps 3-6 are immediately bypassed whenever the local port is found to     * not be currently online and functional.     *     * A sanity check on local port functioning( Step 4 ) consists of verifying     * transmission of an identification request to the first remote port     * polled during each polling interval.  The CI PPD assumes the port is     * broken, crashes the port, and aborts the remaining timer actions( Steps     * 5-6 ) if the targeted request is not successfully transmitted prior to     * expiration of the next timer interval.  Sanity checking may be     * permanently disabled on a per local port basis at the direction of the     * appropriate port driver.     *     * NOTE:	Port polling intervals( frequencies ) are computed as follows:     *     *		            ( polling burst size )     *		Interval =  ---------------------- * ( port contact frequency )     *			     ( number of ports )     *     * Number of ports a dynamically adjustable parameter.  Port contact     * frequency and Polling burst size vary on a per port basis( actually on     * an individual port driver basis ) and are also dynamically adjustable     * parameters at the discretion of individual port drivers.     *     * CI PPD interval timers are permanently active and completely self     * maintaining.  Therefore, the next timer wake up on the local port is     * scheduled regardless of whether the port is currently on or off line(     * Step 7 ).  The only time the next wake up is not scheduled is when the     * port is permanently broken and the appropriate port driver has taken it     * permanently offline.     */    Lock_pccb( pccb )    if( pccb->Fsmstatus.online ) {	if(( notify = pccb->Notify_port )) {	    ( void )( *notify )( pccb );	}	if( pccb->Fsmstatus.sanity ) {	    ( void )( *pccb->Crash_lport )( pccb, SE_PPDSANITY, NULL );	} else {	    for( pb = pccb->Form_pb.flink, next_pb = pb->flink;		 pb != &pccb->Form_pb;		 pb = next_pb, next_pb = pb->flink ) {		Lock_pb( Pb )		if( Pb->Fsmpstatus.timer &&		     ( Pb->Due_time -= pccb->Timer_interval ) < 0 ) {		    Pb->Fsmpstatus.timer = 0;		    ( void )cippd_dispatch( pccb, Pb, CNFE_TIMEOUT, NULL );		}		Unlock_pb( Pb )	    }	    if(( pccb->Poll_due -= pccb->Timer_interval ) < 0 ) {		( void )cippd_poll( pccb );		pccb->Poll_due = Pinterval( pccb );		pccb->Poll_interval = pccb->Poll_due;	    }	}    }    if( !pccb->Fsmstatus.broken ) {	pccb->Timer_interval = cippd_itime;	( void )timeout( cippd_timer, ( u_char * )pccb, ( hz * cippd_itime ));    } else {	pccb->Fsmstatus.timer = 0;    }    Unlock_pccb( pccb )    ( void )splx( save_ipl );}

⌨️ 快捷键说明

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