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

📄 ci_error.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Events 2-4 take place quite frequently.  The remaining events occur * extremely rarely.  Any scheme for port driver protection against extraneous * machine checks must take the frequencies of these events into account. * * To summarize, the only machine checks the CI port driver needs to guard * against are those that result from driver attempts to access inaccessible * local port registers.  Normally, all registers are of course fully * accessible.  Machine checks would be extremely common if this was not the * case.  However, a number of well-defined circumstances do exist under which * registers become inaccessible.  The most likely of these is loss of power, * either system-wide or just isolated to the bus on which the CI adapter * resides.  Certain CI hardware port types( CI750, CIBCI ) are also subject to * completely independent losses of power.  The adapters for these port types * are located within their own physically separate cabinets.  This makes them * vulnerable not only to separate losses of power but to becoming uncabled * from the busses on which they reside.  Either unfortunate circumstances * results in inaccessibility of most, but not all, local port registers.  The * registers of a sufficiently broken local port may also become inaccessible. * * The best most idealistic machine check protection strategy for the CI port * driver would be for it to always provide transparent protection against * machine checks during all register accesses.  Unfortunately, this is not * possible because the only protective mechanisms currently available are * expensive and are not transparent. * * The next best strategy is a defensive one: the CI port driver only protects * against machine checks on local CI ports known to have lost power, become * physically uncabled, or to have suffered a sufficient hardware failure.  In * other words, protective mechanisms are employed only for those local ports * determined to be at risk.  At all other times the driver makes no attempt to * protect against machine checks during register accesses. * * Implementation of this strategy is also unfortunately not possible.  This is * because for it to succeed the CI port driver would have to meet the * following two requirements: * * 1. It would have to be immediately notified when any of the events which *    could result in inaccessible local CI port registers occurs. * 2. It would have to immediately protect all subsequent register accesses on *    notification of local port machine check vulnerability. * * The first requirement can not be met because the driver is never notified of * system-wide or bus associated power loss.  Ironically ULTRIX crashes with a * machine check when such power loss occurs!  Furthermore, while the driver is * notified of independent CI port power loss, uncabling, and fatal errors * through interrupts; handling of such interrupts maybe temporarily blocked * postponing notification.  Such blockage is due to processor IPL level in * single processor environments and current unavailability of critical locks * in SMP environments.  The end result is the same, inability to immediately * notify the driver of local port machine check vulnerability on register * accesses. * * The second requirement for implementation of the next best strategy can also * not be met.  To meet it requires CI port driver determination of whether a * local CI port is currently vulnerable to machine checks prior to each * register access and to employ protective mechanisms only if it is.  Meeting * this requirement is much too costly given the frequency with which certain * register accesses are made. * * The machine check protection strategy actually employed by the CI port * driver is a realistic one and possesses the following two basic * characteristics: * * 1. It never attempts to protect against machine checks during register *    accesses that take place frequently( Events 2-4 above ). * 2. It considers a local port to always be at risk and protects against *    machine checks during all infrequent register accesses( Events 1,5-6 *    above ). * 3. The first checks it makes during interrupt processing are for uncabled *    or powerless local ports before allowing any subsequent register accesses *    by the current thread to occur. * * At first glance it may seem that this strategy is not all that rigorous, * and that better ones could be designed, and to some extent this is true. * However, this strategy is actually the best one available given the tools * which are currently provided by the Ultrix kernel. * * The basic tool employed for machine check protection is the BADADDR() macro. * This macro determines whether a specified byte, word, or longword address is * addressable and "returns" 1 if it is not.  It is used in the machine check * protection strategy to determine whether a register is accessible before * attempting to access it.  Therefore, the actual register accesses are never * themselves actually protected.   * * This mechanism is as defensive as it is possible to be without being * paranoid and without seriously affecting performance of mainline code paths. * It will serve until it is possible to transparently protect against machine * during all register accesses. *//* Libraries and Include Files. */#include		"../h/types.h"#include		"../h/param.h"#include		"../h/systm.h"#include		"../h/vmmac.h"#include		"../h/time.h"#include		"../h/ksched.h"#include		"../h/errlog.h"#include		"../h/smp_lock.h"#ifdef vax#include		"../machine/mtpr.h"#endif vax#include		"../../machine/common/cpuconf.h"#include		"../machine/cpu.h"#include		"../machine/pte.h"#include		"../io/xmi/xmireg.h"#include		"../io/scs/sca.h"#include		"../io/scs/scaparam.h"#include		"../io/scs/scamachmac.h"#include		"../io/ci/cippdsysap.h"#include		"../io/ci/cisysap.h"#include		"../io/msi/msisysap.h"#include		"../io/bi/bvpsysap.h"#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	SCSIB		lscs;extern	struct el_rec	*ealloc();extern	u_short		ci_severity;extern	u_short		ci_errlog;extern	u_long		ci_bhole_pfn;extern  scaaddr         scs_system_id;extern	CLSTAB		ci_cltab[ ES_FE + 1 ][ ESC_PPD + 1 ];extern	u_char		*ci_black_hole, scs_node_name[];extern	void		ci_dealloc_pkt(), ci_log_packet(), ci_unmap_port(),			ci_unmapped_isr(), cippd_stop();/*   Name:	ci_cleanup_port	- Clean up Local CI Port * *   Abstract:	This routine directs the second stage of local CI port clean *		up.  It is always invoked by forking to it. * *		Failed local CI ports are cleaned up in two stages.  The first *		stage 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.  This routine direct this second *		stage of port clean up and the constant environment necessary *		for its proper execution is provided by always forking to it. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	lpinfo.reason		-  Reason for port failure *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.cleanup	-   1 *	    fsmstatus.fkip	-   1 *	    fsmstatus.online	-   0 * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.fkip	-   0 * *   SMP:	The PCCB is locked to synchronize access.  PCCB locking is *		probably unnecessary because of lack of conflict for the PCCB *		due to single threading of port clean up and re-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 once their corresponding ports have been initialized. */voidci_cleanup_port( pccb )    register PCCB	*pccb;{    register GVPH	**lp, **ep, *cibp;    register u_long	code, pf_reason;    register u_long	save_ipl = Splscs();    /* The steps involved in the second stage of local port clean up include:     *     * 1. Locking the PCCB.     * 2. Removing and deallocating all packets logged to the local port     *    datagram and message buffer logout areas at time of failure.     * 3. Map the specific local port crash reason into a generic one.     * 4. Unlocking the PCCB.     * 5. Notifying the CI PPD of failure of the local port.     *     * CI ports logout all internalized queue entries to the appropriate area     * only when power failure is detected.  Both logout areas are scanned in     * their entirety and any packets found are deallocated( Step 3 ).  The     * logout areas are also re-initialized to GVPH_FREE( -1 ) to be able to     * differentiate logged packets from empty logout area slots on subsequent     * power failures.     *     * 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( Step 5 ).  Clean up of the last     * path triggers scheduling of port re-initialization by the CI PPD.  The     * PCCB lock is released( Step 4 ) prior to notifying the CI PPD of local     * port failure instead of after it as required by the SCA architecture.     */    Lock_pccb( pccb )    Pccb_fork_done( pccb, PANIC_PCCBFB )    for( lp = ( GVPH ** )pccb->Pqb.Dqe_logout,	 ep = ( GVPH ** )pccb->Pqb.Dqe_logout + ( 2 * CI_NLOG );	 lp < ep;	 ++lp ) {	if(( cibp = *lp ) != ( GVPH * )GVPH_FREE ) {	    ( void )ci_dealloc_pkt( cibp );	    *lp = ( GVPH * )GVPH_FREE;	}    }    if( Eseverity( pccb->lpinfo.reason ) == ES_FE ) {	pf_reason = PF_FATALERROR;    } else if( Ecode( pccb->lpinfo.reason ) == SE_POWER ||	       Ecode( pccb->lpinfo.reason ) == SE_POWERUP ) {	pf_reason = PF_POWER;    } else {	pf_reason = PF_PORTERROR;    }    Unlock_pccb( pccb )    ( void )cippd_stop( pccb, pf_reason );    ( void )splx( save_ipl );}/*   Name:	ci_console_log	- Log CI Events to Console Terminal * *   Abstract:	This routine logs CI events to the console terminal.  The event *		is always one of the following types: * *		PATH_EVENT	- Path specific event *		RPORT_EVENT	- Remote port specific event *		LPORT_EVENT	- Local port specific event * *		Explicit formatting information must be provided for each *		event.  This requires updating of the following tables each *		time a new event is defined: * *		1. The appropriate entry within the CI console logging table( *		   ci_cltab[][] ) must be updated to reflect the new maximum *		   code represented within the associated format table. * *		2. The associated format table itself( ci_cli[], ci_clw[], *		   ci_clre[], ci_cle[], ci_clse[], ci_clfe[], ci_clppdse[] ) *		   must be updated with both the class of variable information *		   and exact text to be displayed.  However, the appropriate *		   table should be updated with a NULL entry whenever the CI *		   port driver is specifically NOT to log a new event.  This *		   applies only to ci_clppdse[] when a new CI PPD severe error *		   event is to be specifically logged only by the CI PPD and *		   not by appropriate port drivers such as the CI port driver. * *		NOTE: Console logging of events is bypassed whenever the event *		      severity does not warrant console logging according to *		      the current CI severity level( ci_severity ).  Such *		      bypassing is overridden when the ECLAWAYS bit is set in *		      the event code indicating that the event is always to be *		      logged regardless of the current severity level. * *		NOTE: This routine does NOT log events arising external to the *		      CI port driver with the exception of those CI PPD severe *		      error events which are candidates for application of the *		      local port crash severity modifier( ESM_LPC ). * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   ci_cltab			- CI console logging table *   ci_severity		- CI console logging severity level *   cibp			- Address of CI port header( OPTIONAL ) *   event			- Event code *   event_type			- PATH_EVENT, LPORT_EVENT, RPORT_EVENT *   cpu			- CPU type code *   cpusw			- CPU switch structure *   pb				- Path Block pointer( OPTIONAL ) *   pccb			- Port Command and Control Block pointer *	pd.gvp.type.ci		-  CI specific PCCB fields *	    devattn.cicpurevlev	-   Out-of-revision CPU microcode logging info *	    devattn.cirevlev	-   Port microcode information *	    max_fn_level	-   Maximum functional microcode revision level *	    max_rom_level	-   Maximum PROM/self-test microcode rev level * *   Outputs: * *   IPL_SCS			- Interrupt processor level * *   SMP:	The PCCB is locked( EXTERNALLY ) to synchronize access and *		prevent premature PB deletion when a PB is provided. * *		PBs do NOT require locking when provided because only static *		fields are accessed.  SBs NEVER require locking. */voidci_console_log( pccb, pb, cibp, event, event_type )    register PCCB	*pccb;    register PB		*pb;    register GVPH	*cibp;    register u_long	event;    u_long		event_type;{    register u_long	fcode, severity = Eseverity( event ), data;    /* Events are logged according to their type and the class of variable     * information they display.  Console messages for path specific events(     * PATH_EVENT ) display the local and remote port station addresses and     * remote system name by default when the event is of severity level error(     * ES_E ) or severe error( ES_SE ).  Console messages for local port     * specific events( LPORT_EVENT ) display the local port station address by     * default when they are of severity level error( ES_E ) or higher.     * Console messages for remote port specific events( RPORT_EVENT ) do not     * display any information by default.     *          * The following classes of variable information currently exist:     *     * 1. Remote CI port station address.     * 2. Local CI port station address.     * 3. CI port parameter register( PPR ) only.     * 4. CI port registers.     * 5. BI registers.     * 6. CI packet fields.

⌨️ 快捷键说明

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