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

📄 ci_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
 *   SMP:	No locks are required. */u_longci_get_port( pccb, cippdbp )    PCCB		*pccb;    GVPPPDH		*cippdbp;{    register GVPH	*cibp = Ppd_to_pd( cippdbp, pccb );    return( Get_pgrp( pccb, cibp ));}/*   Name:	ci_init_pb	- Initialize a Path Block * *   Abstract:	This function initializes the CI port specific portion of a *		Path Block and verifies the suitability of the remote port for *		path establishment.  The information for PB initialization is *		obtained from the ID response received from the target remote *		port.  This information also indicates whether the remote port *		is in a state( ENABLED or MAINTENANCE/ENABLED ) suitable for *		path establishment. * *		Reception of ID responses from target ports other than the *		local port automatically establish the port's connectivity. * *		NOTE: This is an optional PD function( Init_pb ) for use by the *		      CI PPD finite state machine.  The CI port driver provides *		      it because the driver has CI port specific information to *		      store and because remote CI ports may be in states *		      unsuitable for path establishment.  Other port drivers do *		      not have such needs and need not provide this function. *		      Those port drivers which do provide this function and *		      allow it to return failure status must log the failure *		      reason in a PD specific fashion.  However, only the very *		      first occurrence of failure on each path should be *		      logged.  Subsequent failures should not be logged until *		      after a success status is to be returned for the path. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   cippdbp			- Address of CI PPD header in ID packet *				   ( if it had such a header ) *   pb				- Path Block pointer *   pccb			- Port Command and Control Block pointer * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pb				- Path Block pointer *	pinfo.pd.gvp.type.ci	-  CI specific path information *	    port_fcn		-   Remote port function mask *	    port_fcn_ext	-   Remote port function extension *	    reset_port		-   Address of remote port's last resetter *	    rport_state		-   State of remote port *	    ucode_rev		-   Remote port microcode revision level *	pinfo.type.dual_path	-  Dual path remote port flag *	pinfo.type.hwtype	-  Hardware type of remote port *   pccb			- Port Command and Control Block pointer *	lpinfo.pd.gvp.type.ci	-  CI specific local port information *	    rpslogmap		-   Remote port state port logging bitmap *	pd.gvp.type.ci		-  CI specific PCCB fields *	    lpstatus		-   Local port status flags *		connectivity	-    Port connectivity established status flag * *   Return Values: * *   RET_SUCCESS		- PB successfully initialized *   RET_FAILURE		- Remote port is NOT in an acceptable state * *   SMP:	The PCCB is locked( EXTERNALLY ) as required by ci_log_packet() *		in case logging becomes necessary. * *		The PB is locked( EXTERNALLY ) postponing potential deletion *		and allowing exclusive access to PB contents. */u_longci_init_pb( pccb, pb, cippdbp )    PCCB		*pccb;    register PB		*pb;    register GVPPPDH	*cippdbp;{    register u_long	status = RET_SUCCESS;    register u_long	pktmult;    U_long( pb->pinfo.type ) = Idrec( cippdbp )->port_type;    U_long( pb->pinfo.Ucode_rev ) = Idrec( cippdbp )->ucode_rev;    pb->pinfo.Port_fcn = Idrec( cippdbp )->port_fcn;    pb->pinfo.Port_fcn_ext = Idrec( cippdbp )->port_fcn_ext;    pb->pinfo.Port_fcn_ext2 = Idrec( cippdbp )->port_fcn_ext2;    pb->pinfo.Rport_state = Idrec( cippdbp )->port_state;    pb->pinfo.Reset_port = Idrec( cippdbp )->reset_port;    if(( pktmult = (( pb->pinfo.Port_fcn_ext & PPR_IBUF_LEN ) >> 25 )) > 0 ) {       pktmult--;    }    if( pktmult > pccb->Pkt_mult ) {	pktmult = pccb->Pkt_mult;    }    pb->pinfo.path_pktmult = pktmult << 28;    if( Scaaddr_low( pccb->lpinfo.addr ) !=	Scaaddr_low( pb->pinfo.rport_addr )) {	pccb->Lpstatus.connectivity = 1;    }    if( pb->pinfo.Rport_state == PS_ENAB ||	 pb->pinfo.Rport_state == PS_ENAB_MAINT ) {	Clear_lpinfomap( Rpslogmap, Scaaddr_low( pb->pinfo.rport_addr ))    } else {	if( !Test_lpinfomap( Rpslogmap, Scaaddr_low( pb->pinfo.rport_addr ))) {	    Set_lpinfomap( Rpslogmap, Scaaddr_low( pb->pinfo.rport_addr ))	    ( void )ci_log_packet( pccb,				   pb,				   Ppd_to_pd( cippdbp, pccb ),				   RE_RPORT_STATE,				   RPORT_EVENT );	}	status = RET_FAILURE;    }    return( status );}/*   Name:	ci_inv_cache	- Invalidate CI Port's Translation Cache * *   Abstract:	This routine initiates invalidation of a specific local CI *		port's translation cache.  It is invoked by the CI PPD finite *		state machine only during the termination of established paths. * *		Translation cache invalidation is initiated by placing a INVTC *		command packet onto the highest priority port command queue *		and notifying the port when the queue was previously empty. * *		A CI port command packet is used to contain the command.  It is *		provided to this routine and is deallocated following command *		execution. * *		The port is crashed if the queue interlock can not be obtained. * *		NOTE: This is an optional PD routine( Inv_cache ) for use by *		      the CI PPD finite state machine.  The CI port driver *		      provides it because it oversee ports containing *		      translation caches requiring invalidation.  Other port *		      drivers do not have such needs and need not provide it. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   pb				- Path Block pointer *	pd.gvp.ci		-  CI specific PB fields *	    invtcpkt		-   Invalidate translation cache command packet *   pccb			- Port Command and Control Block pointer *   gvp_queue_retry		- SCA queuing failure retry count * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pb				- Path Block pointer *	pd.gvp.ci		-  CI specific PB fields *	    invtcpkt		-   NULL * *   SMP:	The PB is locked( EXTERNALLY ) postponing premature deletion *		and allowing exclusive access to PB contents. * *		Access to port command queues is by means of memory *		interlocking queuing instructions. * *              This routine requires the PCCB to be locked( EXTERNALLY ) *		because locks lower than the PCCB in the SCA locking hierarchy *              such as the PB may NOT be held without also holding the PCCB *              lock in case the port requires crashing. */voidci_inv_cache( pccb, pb, cippdbp )    register PCCB	*pccb;    PB			*pb;    GVPPPDH		*cippdbp;{    register GVPH	*cibp;    /* The steps involved in invalidating a local CI port's translation cache     * are as follows:     *     * 1. Retrieve the preallocated emergency invalidate translation cache     *    command packet associated with the failed path.     * 2. Format the generic Vaxport port header of the command packet.     * 3. Initiate invalidation of the local CI port's translation cache.     *     * The port is crashed if command execution can not be successfully     * initiated.     */    if(( cibp = pb->Invtcpkt )) {	pb->Invtcpkt = NULL;    } else {	panic( PANIC_NOTCPKT );    }    Format_gvph( pccb, cibp, INVTC, 0, DEALLOC_BUF )    Insqti_control( cibp, pccb )}/*   Name:	ci_notify_port	- Notify Port of CI PPD Continued Activity * *   Abstract:	This routine notifies the specified local CI port of CI PPD *		continued activity.  It is invoked on an ongoing basis by the *		CI PPD finite state machine.  It is also invoked during *		initialization of all local CI ports to initially engage local *		port maintenance timers, but only when such timers have been *		optionally enabled. * *		NOTE: This is an optional PD routine( Notify_port ) for use by *		      the CI PPD.  The CI port driver provides it because the *		      CI port requires continuous notification of CI PPD *		      activity.  Other ports do not have such needs and their *		      port drivers need not provide this routine and still *		      other port drivers may have such needs but utilize *		      different mechanisms to perform such notifications. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   ci_maint_timer		- CI port maintenance timer enable flag *   pccb			- Port Command and Control Block pointer * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    ciregptrs.pmcsr	-   Port status register pointer *	    ciregptrs.pmtcr	-   Port maintenance timer control reg pointer *	    lpstatus.mtimer	-   Maintenance timer is operational flag * *   SMP:	The PCCB is locked( EXTERNALLY ) allowing exclusive access to *		PCCB contents. */voidci_notify_port( pccb )    PCCB		*pccb;{    /* Notifying the specified local CI port of continuing CI PPD activity is     * required only when CI port maintenance timers have been optionally     * enabled.  When such enabling occurs, the maintenance timers on all CI     * ports must be written to periodically to notify the ports of continued     * functioning of host software.  Failure to write to a timer within a CI     * port specific sanity interval triggers transitioning of the     * corresponding port into the Uninitialized/Maintenance port state,     * generation of an interrupt, and crashing of the local port.     *     * The sanity interval for the CI750/CI780/CIBCI maintenance timer is 100     * seconds.  The interval for the CIBCA/CIXCA maintenance timer is     * variable.     *     * Management of the specified local CI port maintenance timer includes:     *     * 1. Reflecting any changes in software maintenance timer state by     *    disabling or enabling the specified local port maintenance timer as     *	  required.     * 2. Poking the specified local CI port maintenance timer if it is     *	  currently software enabled to prevent it from expiring.     */    if( ci_maint_timer ^ pccb->Lpstatus.mtimer ) {	DELAY( 1000 );	Lock_cidevice( pccb )	if(( pccb->Lpstatus.mtimer = ci_maint_timer )) {	    *pccb->Pmcsr &= ~PMCSR_MTD;	} else {	    *pccb->Pmcsr |= PMCSR_MTD;	}	Unlock_cidevice( pccb )	DELAY( 1000 );    }    if( pccb->Lpstatus.mtimer ) {	Lock_cidevice( pccb )	*pccb->Pmtcr = PMTCR_MTC;	Unlock_cidevice( pccb )        WBFLUSH    }}/*   Name:	ci_send_reqid	- Request Remote Port Identification * *   Abstract:	This function initiates a request for the identification of a *		specific remote port.  It is provided by the port driver for *		use by the CI PPD finite state machine during port polling for *		the maintenance of existing paths and the initiation of new *		ones.  It is also invoked by the CI port driver under special *		circumstances( See ci_rsp_handler()). * *		Execution of this function may also result in scheduling of the *		following asynchronous CI PPD notifications: * *		1. Completion of a request for remote port identification. *		2. Reception of information corresponding to the report port *		   whose identification was requested. * *		Neither notification requires scheduling every time this *		function is invoked.  Notification of the former through *		invocation of cippd_reqid_snt() occurs only when the caller *		requests deallocation of the packet used in satisfying the *		request( dispose == DEALLOC_BUF ).  Notification of the latter *		through invocation of cippd_receive() occurs only when a *		request is made for an existing remote port.  Some requests *		result in no asynchronous CI PPD notifications.  Others result *		in both possible notifications with no restrictions placed on *		the order in which they occur. * *		A request for identification is initiated by placing a REQID *		command packet onto the second highest priority port command *		queue and notifying the port when the queue was previously *		empty. * *		Either a CI port command packet or a CI port specific datagram *		buffer is used to contain the command.  Datagram buffers are *		used only when explicitly supplied to the function and are *		disposed of following command execution as specified.  Command *		packets are allocated by the function when datagram buffers are *		not provided.  They are always deallocated following command *		execution. * *		The port is crashed if the queue interlock can not be obtained. * *		NOTE: This is a mandatory PD function( Send_Reqid ) for use by *		      the CI PPD finite state machine.  Not all port drivers *		      issue port commands in order to obtain remote port *		      identifications like the CI port driver.  However, all *		      drivers must still supply this function for scheduling *		      purposes.  All port drivers must schedule CI PPD *		      reception of remote port identification information. *		      Those drivers like the CI port driver which have NOT *		      permanently disabled sanity checking on their local ports *		      must also schedule CI PPD notification of the completion *		      of their requests for remote port identifications.  How *		      each driver goes about performing each scheduling is *		      driver specific, but all notifications MUST be done *		      asynchronously.  They may NOT occur through immediate *		      call backs.  All drivers must also dispose of all port *		      specific datagram buffers optionally provided to this *		      function as specified. *		       *		NOTE: SCA port numbers are 6 bytes in size; however, maximum CI *		      and CI PPD port numbers only occupy 1 byte, the low-order *		      byte of a port station address.  Port numbers are passed *		      as 4 bytes entities back and forth between the CI PPD and *		      CI port driver. * *		NOTE: The requested identification information must always be *		      passed back to the CI PPD within a port specific datagram *		      buffer whenever the requested remote port is found to *		      exist.  The contents of this information is however

⌨️ 快捷键说明

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