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

📄 msi_lpmaint.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
     *     * Fork process synchronization( Step 4 ) is accomplished by means of the     * in-progress SIIBUF pointers.  These pointers are never NULL except     * during those rare circumstances when active fork processes must     * temporarily release their locks.  Therefore, the synchronization     * protocol just consists of releasing and re-obtaining all locks( PCCB,     * PCCB specific XFP and RFP ) until such time as both in-progress pointers     * are tested to be non-NULL.  The reason why such synchronization is     * necessary is discussed at greater length below.     *     * Flushing the transmit-in-progress circular queue( Step 5 ) does not     * disturb the SIIBUFs in the queue.  What occurs is deallocation of the     * MSI packets associated with each SIIBUF in the queue.  This allows     * recovery of their dynamically allocated memory.  Logically this action     * should occur during local port clean up.  It MUST be done at this time     * during the port disablement step because once the SII chip is reset(     * Step 5 ) the SII RAM buffer may NOT be accessed.  It is perfectly safe     * to flush the transmit-in-progress circular queue at this time even     * though it is not the logical moment to do so.  This is because once the     * local MSI port has been marked inactive( Step 7 ) no further attempt is     * made either to access the elements on this queue or to add new ones.     *     * Resetting the SII chip( Step 6 ) stops any operation in progress,     * disconnects the chip from the DSSI bus, returns all registers to their     * default values, and prevents all access to the SII RAM buffer.  Marking     * the local MSI port inactive( Step 7 ) disables all future processing by     * scheduled XFP, RFP and XFP_TIMER threads.  The end result of both these     * steps is to drive the local MSI port into a completely quiescent state     * allowing for full clean up and eventual local port re-initialization.     *     * Synchronization to active fork processes( Step 4 ) is important in a     * SMP environment for the following reason.  Occassions exist when an     * active fork process must temporarily release all locks including its     * specific fork process lock( RFP or XFP ).  Its expectations are to     * eventually re-obtain these locks and continue with its processing.  In a     * SMP environment lacking fork process synchronization releasing these     * locks allows another completely independent thread to obtain them and     * crash the local port.  Unfortunately, this almost always guarantees a     * machine check when the fork process re-obtains its locks and resumes     * processing.  This is because the fork process does not know the SII RAM     * buffer has been rendered inaccessible due to crashing of the local port     * and almost always attempts to access it anyway.  Fork process     * synchronization protects against such machine checks by forcing     * temporary postponement of local port crashing during those rare     * occassions when active fork processes must temporarily release their     * locks.     *     * 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 msi_clean_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 local MSI 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 consists solely of 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_pccb = 1;    } else {	unlock_pccb = 0;    }    if( pccb->Lpstatus.optlpcinfo ) {	if(( pb = cippd_get_pb( pccb,				( SCSH * )&pccb->Lpcinfo.pport_addr,				NO_BUF )) == NULL ) {	    pccb->Errlogopt.portnum = pccb->Lpcinfo.pport_addr;	}    } else {	pb = NULL;	pccb->Errlogopt.portnum = EL_UNDEF;    }    if( !pccb->Fsmstatus.cleanup ) {	Set_lpc_event( reason );    }    switch( Mask_esevmod( reason )) {	case SE_BUSERROR:	case SE_SWA:		case SE_IMODE:	case SE_TMODE:	    ( void )msi_log_devattn( pccb, reason, LOG_REGS );	    break;	case SE_NOPATH:		case SE_MFQE:		case SE_INVBNAME:	case SE_INVBSIZE:	    ( void )msi_log_packet( pccb,				    pb,				    NULL,				    (( pccb->Lpstatus.optlpcinfo )						? pccb->Lpcinfo.pkth : NULL ),				    (( pccb->Lpstatus.optlpcinfo )						? pccb->Lpcinfo.pktsize : 0 ),				    reason,				    LPORT_EVENT );	    break;	case SE_PPDSANITY:	default:	    ( void )panic( PANIC_UNKLPC );    }    if( msi_lpc_panic ) {	( void )panic( PANIC_REQLPC );    }    if( !pccb->Fsmstatus.cleanup ) {	pccb->Fsmstatus.cleanup = 1;	pccb->Fsmstatus.online = 0;	if( !Test_rfp_lock( pccb )) {	    Lock_rfp( pccb )	    unlock_rfp = 1;	} else {	    unlock_rfp = 0;	}	if( !Test_xfp_lock( pccb )) {	    Lock_xfp( pccb )	    unlock_xfp = 1;	} else {	    unlock_xfp = 0;	}	while( pccb->Xbusy == NULL || pccb->Rbusy == NULL ) {	    Unlock_xfp( pccb )	    Unlock_rfp( pccb )	    Unlock_pccb( pccb )	    Lock_pccb( pccb )	    Lock_rfp( pccb )	    Lock_xfp( pccb )	}	Xflush_xbusy( pccb )	( void )msi_disable( pccb );	if( unlock_xfp ) {	    Unlock_xfp( pccb )	}	if( unlock_rfp ) {	    Unlock_rfp( pccb )	}	pccb->lpinfo.reason = reason;	Pccb_fork( pccb, msi_clean_port, PANIC_PCCBFB )    }    if( unlock_pccb ) {	Unlock_pccb( pccb )    }}/*   Name:	msi_remote_rst	- Reset Remote Port and System * *   Abstract:	This function initiates resetting of a remote MSI port and *		system.  The remote system need NOT be known to be reset; *		however, the remote port must be in the appropriate maintenance *		state for it and the remote system to be reset. * *		Initiating resetting of a remote port and system is *		accomplished by initiating transmission of a MSI port specific *		RST packet to the target remote port.  A MSI port command *		packet is used to contain the reset request.  It is allocated *		by this function and deallocated following packet transmission. * *		Resetting of the remote port and system can optionally be *		forced; however, the port must in an appropriate maintenance *		state for this to occur. * *              NOTE: SCA port numbers are 6 bytes in size; however, maximum *                    MSI port numbers only occupy 1 byte. * *		NOTE: All attempts to transmit packets to the local ports own *		      station address are bypassed.  The SII chip is not *		      capable of either internal loopback or simultaneous *		      transmission and reception; and, no need exists to *		      provide this function in software. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   force			- If set, force maintenance reset *   pccb			- Port Command and Control Block pointer *   rport			- Station address of target remote port * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	pd.msi			-  MSI specific PCCB fields *	    comql		-   MSIB low priority command queue *	    lpstatus.xfork	-   1 *	    xforkb		-   Transmit Fork Process fork block * *   Return Values: * *   RET_SUCCESS		- Transmission successfully initiated *   RET_ALLOCFAIL		- Failed to allocate command packet *   RET_INVLPSTATE		- Local port in invalid state *   RET_NOPATH			- Invalid remote port station address * *   SMP:       The PCCB is locked allowing exclusive access to PCCB contents. *              PCCB addresses are always valid because these data structures *              are never deleted once their corresponding ports have been *		initialized. * *		The PCCB specific COMQL is locked allowing exclusive access to *		the corresponding low priority command queue */u_longmsi_remote_rst( pccb, rport, force )    register PCCB	*pccb;    scaaddr		*rport;    u_long		force;{    register MSIB	*msibp;    register u_long	status = RET_SUCCESS;    /* Only the Transmit Fork Process( XFP ) interfaces directly with the SII     * chip for the purpose of processing outgoing MSI packets.  All other     * driver routines must interface with the XFP.  Therefore the steps

⌨️ 快捷键说明

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