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

📄 ci_init.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#include		"../io/gvp/gvpsysap.h"#include		"../io/uba/uqsysap.h"#include		"../io/sysap/sysap.h"#include		"../io/ci/cippdscs.h"#include		"../io/ci/ciscs.h"#include		"../io/msi/msiscs.h"#include		"../io/bi/bvpscs.h"#include		"../io/gvp/gvpscs.h"#include		"../io/uba/uqscs.h"#include		"../io/scs/scs.h"#include		"../io/gvp/gvp.h"#include		"../io/ci/cippd.h"#include		"../io/ci/ciport.h"#include		"../io/ci/ciadapter.h"/* External Variables and Routines. */extern	int		cpu;extern	SCSIB		lscs;extern	PDT		ci_pdt;extern	struct pte	Sysmap[];extern	CIISR		ci_isr[];extern	GVPBDDB		*gvp_bddb;extern	int		*ci_ucode;extern	struct lock_t	lk_scadb;extern	pccbq		scs_lport_db;extern	u_char		*ci_black_hole;extern	MRLTAB		ci7b_mrltable[], cibca_aa_mrltab[], cibca_ba_mrltab[],			cixcd_mrltable[], cikmf_mrltable[], cishc_mrltable[];extern	SCSH		*gvp_alloc_dg(), *gvp_alloc_msg();extern	u_long		*ci780_regoff[], *cibci_regoff[], *cibca_regoff[],			*cixcd_regoff[], *cikmf1_regoff[], *cikmf2_regoff[],			*cishc_regoff[];extern	u_short		ci_cippdburst, ci_cippdcontact, ci_first_port,			ci_max_reinits, ci_maint_intrvl, ci_maint_timer,			ci_ucode_type, cippd_max_port;extern	void		ci_crash_lport(), ci_dealloc_pkt(), ci_init_port(),			ci_log_dev_attn(), ci_log_initerr(), ci_notify_port(),			ci_unmap_port(), ci_unmapped_isr(), ci7b_disable(),			cibx_disable(), cishc_disable(),			cippd_start(), gvp_dealloc_dg(),			gvp_dealloc_msg();extern	u_long		ci_bhole_pfn, ci_crctable[], gvp_max_bds,			gvp_queue_retry, scs_dg_size, scs_msg_size,			ci_setup_port(), ci_test_port(), ci7b_load(),			ci7b_start(), cibca_aa_load(), cibx_start(),			gvp_initialize(), scs_initialize();/*   Name:	ci_init_port	- Initialize a Local CI Port * *   Abstract:	This routine directs the initialization of a local CI port.  It *		also oversees the port's initial initialization.  It is always *		invoked by forking to it. * *		The local port must be completely disabled whenever execution *		of this routine is scheduled including disablement of: * *		1. Port interrupts. *		2. Port boot/sanity timer. *		3. CI PPD finite state machine activity on the local port. * *		The local CI port must also be in the UNINITIALIZED port state. * *		This routine may also be scheduled to permanently shutdown *		local ports.  Such ports are always unmapped and marked broken *		in addition to having been disabled.  This distinguishes them *		from local ports to be initialized which are mapped and not *		marked broken. * *		NOTE: This is a mandatory PD function( Init_port ) for use by *		      the CI PPD. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   ci_cippdburst		- CI PPD port polling burst size *   ci_cippdcontact		- CI PPD port polling contact frequency *   ci_first_port		- Port number of first local CI port *   ci_maint_intrvl		- CI port maintenance timer interval *   ci_maint_timer             - CI port maintenance timer enable flag *   ci_max_reinits		- CI max number consecutive reinitializations *   pccb			- Port Command and Control Block pointer *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.cleanup	-   1 *	    fsmstatus.fkip	-   1 *	    fsmstatus.online	-   0 *   lk_scadb			- SCA database lock structure * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   ci_first_port		- Port number of first local CI port *   pccb			- Port Command and Control Block pinter *	lpinfo.addr		-  Local port station address *	lpinfo.nreinits		-  Number of local port re-initializations *	lpinfo.ppd.cippd	-  CI PPD specific local port information *	    max_port		-   Maximum hardware remote port number *	pd.gvp.pqb.type.ci	-  CI specific PQB fields *	    keepalive		-   Variable maintenance timer interval cell *	pd.gvp.type.ci		-  CI specific PCCB fields *	    devattn.cirevlev	-   Port microcode information *	    lbcrc		-   Loopback CRC *	    lbstatus		-   0 *	    lpstatus		-   Local port status flags *	        init		-    First time initialization status flag *		connectivity	-    0 *	    reinit_tries	-   Number consecutive re-initializations left *	ppd.cippd		-  CI PPD specific PCCB fields *	    burst		-   Port polling burst size *	    contact		-   Port polling contact frequency *	    fsmstatus.broken	-   Port is broken status flag *	    fsmstatus.cleanup	-   0 *	    fsmstatus.fkip	-   Fork operation in progress status flag * *   SMP:	The SCA database is locked for deletion of the PCCB following *		exhaustion of consecutive re-initialization attempts without a *		successful initial port initialization. * *		The PCCB is locked to synchronize access and as required by *		ci_log_dev_attn() in case event logging becomes necessary. *		PCCB locking 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.  PCCB addresses are always valid because these *		data structures are never deleted( except by this function on *		exhaustion of consecutive re-initialization attempts without a *		successful initial port initialization ). * *		Access to port queues is by means of memory interlocking *		queuing instructions. */voidci_init_port( pccb )    register PCCB	*pccb;{    register MRLTAB	*mrltab;    register gvpbq	*q, *qend;    register u_long	status;    register u_long 	save_ipl = Splscs();    /* The steps involved in port initialization are as follows:     *     *  1. The PCCB is locked.     *  2. Port clean up is marked completed.     *  3. The existence of port power is verified( non-broken ports only ).     *     *  - PORT RE-INITIALIZATION ONLY:     *  4. All port queues are flushed and all flushed packets are deallocated.     *  5. The local port maintenance timer interval, CI PPD port polling burst     *	   size, and CI PPD port polling contact frequency are reset.     *  6. Local port loopback is enabled and loopback status is cleared.     *     *  - ALL INITIALIZATIONS:     *  7. Presence of an operational port is verified.     *	8. All configuration register errors are cleared( CI750, CI780, CIBCI     *	   only ).     *  9. The CPU microcode revision level is verified( 11/750 only ).     * 10. An initial number of free datagrams and messages are allocated and     *	   and placed on the appropriate port queues.     * 11. Functional port microcode is loaded, read back, and verified( CI750,     *	   CI780, CIBCI, and CIBCA-AA only ).     * 12. Both port interrupts and the port itself are enabled.     * 13. The port is notified of free message and datagram buffer     *	   availability.     *     * - INITIAL PORT INITIALIZATION ONLY:     * 14. The local port number is retrieved and stored as the port number of     *	   the first local CI port encountered( when appropriate ).     * 15. The local port loopback datagram CRC is computed.     * 16. The maximum addressable port number is retrieved and verified.     * 17. Microcode revision levels( ram/functional and prom/self-test ) are     *	   verified.     *     *  - ALL INITIALIZATIONS:     * 18. The initialization of the local CI port is logged.     * 19. The local CI port maintenance timer is engaged provided CI port     *	   maintenance timers have been optionally enabled.     * 20. The PCCB is unlocked.     * 21. The CI PPD is notified of successful port initialization.     *     * Local ports can not be initialized when they are without power.  This     * presents no problems for those instances of power failure which involve     * the entire system.  It also poses no problems for local CIBCA/CIXCD     * ports which can not independently power failure.  Unfortunately,     * potential problems do exist for power failure of local CI750/CI780/CIBCI     * ports.  Such ports can power failure independently.  Worse yet, power     * loss and gain on such ports can be discrete events separated in time.     * This allows for the local port disablement and clean associated with the     * loss of port power to complete and local port initialization to commence     * before power is restored to the port.  It is also the reason why     * verification of port power occurs( Step 3 ) before proceeding further     * with port initialization, to insure that initialization is postponed     * while local ports are without power.  For a more extensive discussion of     * possible power failure recovery scenarios consult ci_crash_lport().     *     * All port queues are flushed immediately prior to port re-initialization(     * Step 4 ) to insure their pristine state.  Logically this action should     * occur as part of port clean up.  However, it is done immediately prior     * to port re-initialization in order to be able to meet the following     * requirements:     *     * 1. Port queues can not be flushed until all possibility of further     *	  packet queuing to them has ceased.     *     * 2. Port queue flushing must involve determination of whether or not the     *	  queues were left permanently locked by failure of the port( Discovery     *    of a locked queue or any failure to obtain a queue interlock during     *	  queue flushing results in zeroing of the offending queue and     *	  permanent loss of all packets residing on it ).     *     * Neither of these requirements can be easily met during port clean up.     * Nothing can prevent SYSAP or SCS motivated insertion of packets into     * port queues without seriously affecting performance until all paths     * associated with the failed port have been terminated.  This condition is     * not reached until the virtual end of port clean up.  Furthermore, until     * port re-initialization begins, multiple simultaneously active threads     * may exist to complicate the determination of queues left permanently     * locked by port failure.  It is only during re-initialization that a     * single thread with access to port queues exists, the thread responsible     * for the re-initialization itself.  Therefore, port queues are flushed     * during port re-initialization instead of during port clean up mainly     * because it is easier to meet these requirements and because it is just     * safer and more straight forward to do so.     *     * Local port maintenance timer interval, CI PPD port polling burst size,     * and CI PPD port polling contact frequency are all reset( Step 5 ) using     * configuration variables.  This allows their values to change following     * failure and re-initialization of a local port.  The values for CI PPD     * port polling burst size and contact frequency actually change much more     * frequently.  They are reset on a per local port basis following the     * completion of each CI PPD polling sweep( by ci_test_lpconn()).     *     * An error in Steps 7,9 or exhaustion of all consecutive port     * initialization attempts permanently aborts port initialization.  This is     * also the fate of ports marked broken.     *     * Errors in Steps 10-12 abort the current port initialization attempt.  A     * consecutive port initialization attempt is scheduled and the PCCB is     * unlocked.     *     * Retrieval of the maximum addressable port number( Step 16 ) is dependent     * upon the format of the CI port parameter register.  There are currently     * two possible formats easily distinguishable by means of the diagnostic     * information field.  One format implements this field while for the other     * it is always 0.  Failure to retrieve a valid maximum addressable port     * number crashes the local port and shuts it down permanently.     *     * Failure to verify the microcode revision level( Step 17 ) results either     * in logging of an appropriate warning message or crashing of the local     * port.  The former occurs when the revision level is known, just out of     * date.  The port is allowed to continue to function.  The latter occurs     * when the revision level is both unknown and does NOT exceed the known     * maximum level for the hardware port type.  The local port is permanently     * shut down.  No action is taken when an unknown level is found to exceed     * the known maximum revision level for the hardware port type.  It is just     * assumed that the port driver has not yet been updated to recognize a new     * maximum microcode revision level.     *     * Permanent abortion of port initialization proceeds as follows:     *     * 1. The port is left disabled and unmapped.     * 2. All associated resources are deallocated.     * 3. The local port is marked broken.     * 4. A console message is printed.     * 5. The PCCB is removed from the system-wide local port database.     * 6. The PCCB is unlocked.     * 7. The PCCB is deallocated( only when the initial port initialization     *    attempts fail ).     *     * The local port is marked broken( Step 3 ) only when it was previously     * NOT marked broken.  It is also unmapped at this time.  This situation     * exists only when all consecutive port initialization attempts have been     * exhausted.     *     * The PCCB is deallocated( Step 7 ) only when the initial port     * initialization attempts fails.  The SCA database is always locked prior     * to PCCB removal and unlocked following it.  In order to preserve the SCA     * locking hierarchy the PCCB lock is first released and then re-obtained     * after the SCA database is locked.  Cached PCCB addresses remain valid at     * this point because PCCBs are only deleted by this routine and such     * action has not yet occurred.     *      * NOTE: Broken local ports are unmapped at the time of their disablement.     *	     This is not the case for those local ports which are to be     *	     shutdown because they have exhausted their consecutive     *	     initialization attempts.  Such ports are explicitly unmapped by     *	     this routine during shutdown.     */    Lock_pccb( pccb )    Pccb_fork_done( pccb, PANIC_PCCBFB )    pccb->Fsmstatus.cleanup = 0;    if( !pccb->Fsmstatus.broken && !pccb->Lpstatus.power ) {	Unlock_pccb( pccb )        ( void )splx( save_ipl );	return;    } else if( !pccb->Lpstatus.init     &&		!pccb->Fsmstatus.broken &&		pccb->Reinit_tries == ci_max_reinits ) {	++pccb->lpinfo.nreinits;	for( q = &pccb->Pqb.cmdq0, qend = &pccb->Pqb.rspq; q <= qend; ++q ) {	    Flushq( pccb, q )	}	for( q = &pccb->Dfreeq, qend = &pccb->Mfreeq; q <= qend; ++q ) {	    Flushq( pccb, q )	}	pccb->Pqb.Keepalive = ( u_long )ci_maint_intrvl;	pccb->Burst = cippd_max_port;		/* poll all the nodes first */	pccb->Contact = ci_cippdcontact;	pccb->Lpstatus.connectivity = 0;	*( u_char * )&pccb->Lbstatus = 0;    }    if( !pccb->Fsmstatus.broken					      &&	 ( status = ci_setup_port( pccb )) == RET_SUCCESS	      &&	 ( pccb->Load_ucode == NULL ||	   ( status = ( *pccb->Load_ucode )( pccb )) == RET_SUCCESS ) &&	 ( status = ( *pccb->Start_port )( pccb )) == RET_SUCCESS ) {	status = 0;	if( pccb->Lpstatus.init ) {	    register u_long	ppr;	    Lock_cidevice( pccb )	    ppr = *pccb->Ppr;	    Unlock_cidevice( pccb )	    pccb->Lpstatus.init = 0;	    pccb->Devattn.cirevlev.ci_romlev = pccb->Rom_level;	    pccb->Devattn.cirevlev.ci_ramlev = pccb->Fn_level;

⌨️ 快捷键说明

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