📄 ci_error.c
字号:
* Abstract: This routine logs bad port numbers in CI packets. For a port * number within a packet to be considered bad it must exceed the * hardware maximum port number of the specified local port. * * NOTE: This is a mandatory PD routine( Log_badportnum ) for use * by the CI PPD. * * Inputs: * * IPL_SCS - Interrupt processor level * cippdbp - Address of CI PPD header * pccb - Port Command and Control Block pointer * * Outputs: * * IPL_SCS - Interrupt processor level * * SMP: The PCCB is locked( EXTERNALLY ) as required by * ci_log_packet(), the routine which performs the actual logging. */voidci_log_badport( pccb, cippdbp ) PCCB *pccb; GVPPPDH *cippdbp;{ ( void )ci_log_packet( pccb, NULL, Ppd_to_pd( cippdbp, pccb ), SE_BADPORTNUM, LPORT_EVENT );}/* Name: ci_log_dev_attn - Log CI Device Attention Events * * Abstract: This routine logs CI device attention events. Such events are * detected directly from a specific local CI port as opposed to * those events ascertained indirectly from a CI port packet. The * event is also optionally logged to the console. * * Nine classes of events are currently logged by this routine: * * 1. Software errors detected during port initialization. * 2. Software detected hardware problems. * 3. Software detected invalid hardware CI port types. * 4. Software detected local port failures. * 5. CPU or port microcode problems. * 6. Explicit hardware errors. * 7. Stray interrupts. * 8. Failures to obtain access to port queue memory interlocks. * 9. Local port initializations. * * Many of these events represent serious errors and are logged to * save relevant information before drastic steps are attempted to * resolve them. Others are less serious and are logged only to * give a warning or for informational purposes only. * * NOTE: Stray interrupts are specific interrupts processed by the * special routine ci_unmapped_isr(). This routine serves * as the interrupt service handler for local ports without * power or marked broken and permanently shutdown. Refer * to it for a more extensive explanation of what interrupts * are considered stray. * * NOTE: This routine does NOT log events arising external to the * CI port driver. It currently does NOT even log those CI * PPD events which are candidates for application of the * local port crash severity modifier( ESM_LPC ). * * Inputs: * * IPL_SCS - Interrupt processor level * event - Event code * cpu - CPU type code * cpusw - CPU switch structure * lscs - Local system permanent information * pccb - Port Command and Control Block pointer * pd.gvp.type.ci - CI specific PCCB fields * devattn.cicpurevlev - Out-of-revision CPU microcode information * devattn.cirevlev - Port microcode information * devattn.ciucode - Faulty microcode information * regs - LOG_REGS or LOG_NOREGS * * Outputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * lpinfo.nerrs - Number of errors on port * * SMP: The PCCB is locked( EXTERNALLY ) to synchronize access and as * required by ci_console_log(), the routine responsible for * logging events to the console terminal. */voidci_log_dev_attn( pccb, event, regs ) register PCCB *pccb; register u_long event; u_long regs;{ register u_long size; register u_char *celp; register struct el_rec *elp; register u_long severity = Eseverity( event ), data; /* The steps involved in logging device attention events include: * * 1. Logging the event to the console. * 2. Incrementing the counter of local port errors. * 3. Computing the size of the application portion of the event log * record. * 4. Allocating an event log record and initializing the record's sub id * packet fields. * 5. Initializing the portion of the record common to all CI events. * 6. Initializing the portion of the record reserved for register * contents. * 7. Moving any optional device attention information into the record. * 8. Validating the event log record. * * The ability of this routine to log the event is validated during console * logging( Step 1 ). A panic occurs whenever the CI port driver is not * prepared to log the reported event. * * Not all events increment the counter of errors which have occurred on * the specified local port( Step 2 ). Only those events with severity * level equal to or greater than error( ES_E ) increment the counter. * * This routine immediately terminates on failure to allocate an event log * record( Step 4 ). * * Not all device attention events request logging of device registers( * Step 6 ). Sufficient space is reserved within the event log record for * register contents only for those that do. Both CI port registers and * interconnect specific registers are logged when register logging is * requested. * * Accessibility of register locations are always checked prior to * accessing because the local port is itself suspect whenever this routine * is invoked and requested to log register contents. Accessibility to * each CI port register is explicitly tested before accessing while only * general accessibility to the interconnect registers, and not to each * separate one, is tested before accessing. Inability to access a * location implies unavailability of the port itself( ie - brain damage ) * and the specific access is bypassed. A more extensive explanation of * why and when register accesses require protection may be found at the * front of this module. * * The following types of mutually exclusive optional device attention * information may require logging( Step 7 ): * * 1. Microcode revision levels. * 2. CPU microcode revision levels. * 3. Information about improperly loaded functional microcode. * * Sufficient space is reserved within the event record for such optional * information only for those events which require its logging. Logging of * microcode revision levels is required by four events: I_LPORT_INIT, * I_LPORT_REINIT, FE_BADUCODE and W_UCODE_WARN. Logging of CPU microcode * revision levels is required by a single event: FE_CPU. Logging of * information about improperly loaded functional microcode is also * required only by a single event: E_UCODE_LOAD. * * NOTE: Requests for logging of register contents and requirements for * logging of optional device attention information are orthogonal. * In other words, an event may request register content logging and * require logging of optional information, or neither, or any * combination in between. * * NOTE: Fields reserved for registers which are either unused by local CI * ports of a specific hardware port type or are currently * inaccessible are initialized to EL_UNDEF. */ ( void )ci_console_log( pccb, NULL, NULL, event, LPORT_EVENT ); if( Eseverity( event ) >= ES_E ) { Event_counter( pccb->lpinfo.nerrs ) } if( ci_errlog > severity && !Test_cloverride( event ) && ci_errlog < SCA_ERRLOG3 ) { return; } size = sizeof( struct ci_common ); if( regs == LOG_REGS ) { size += sizeof( struct ci_regs ); switch( pccb->Interconnect ) { case ICT_SBICMI: break; case ICT_BI: size += sizeof( struct bi_regs ); break; case ICT_XMI: size += sizeof( struct cixmi_regs ); break; default: ( void )panic( PANIC_IC ); } } switch( Mask_esevmod( event )) { case I_LPORT_REINIT: case I_LPORT_INIT: case W_UCODE_WARN: case FE_BADUCODE: size += sizeof( struct ci_revlev ); break; case E_UCODE_LOAD: size += sizeof( struct ci_ucode ); break; case FE_CPU: size += sizeof( struct ci_cpurevlev ); break; } if(( elp = ealloc( size, EL_PRIHIGH )) == EL_FULL ) { return; } LSUBID( elp, ELCT_DCNTL, ELCI_ATTN, pccb->lpinfo.type.hwtype, Ctrl_from_name( pccb->lpinfo.name ), EL_UNDEF, event ) Elcicommon( elp )->ci_optfmask1 = 0; Elcicommon( elp )->ci_optfmask2 = 0; Elcicommon( elp )->ci_evpktver = CI_EVPKTVER; U_long( *Elcicommon( elp )->ci_lpname ) = pccb->lpinfo.name; Move_node( lscs.system.node_name, Elcicommon( elp )->ci_lname ) Move_scaaddr( lscs.system.sysid, *Elcicommon( elp )->ci_lsysid ) Move_scaaddr( pccb->lpinfo.addr, *Elcicommon( elp )->ci_lsaddr ) Elcicommon( elp )->ci_nerrs = pccb->lpinfo.nerrs; Elcicommon( elp )->ci_nreinits = pccb->lpinfo.nreinits; celp = ( u_char * )Elcidattn( elp ); if( regs == LOG_REGS ) { Elcicommon( elp )->ci_optfmask1 |= CI_REGS; switch( pccb->lpinfo.type.hwtype ) { case HPT_CI750: case HPT_CI780: case HPT_CIBCI: Elciciregs( celp )->ci_cnfr = Get_reg( pccb->Cnfr ); break; case HPT_CIBCA_AA: case HPT_CIBCA_BA: case HPT_CIXCD: case HPT_CIKMF: Elciciregs( celp )->ci_cnfr = EL_UNDEF; break; default: ( void )panic( PANIC_HPT ); } Lock_cidevice( pccb ) data = Get_reg( pccb->Pmcsr ); Unlock_cidevice( pccb ) Elciciregs( celp )->ci_pmcsr = data; Lock_cidevice( pccb ) data = Get_reg( pccb->Psr ); Unlock_cidevice( pccb ) Elciciregs( celp )->ci_psr = data; Lock_cidevice( pccb ) data = Get_reg( pccb->Pfar ); Unlock_cidevice( pccb ) Elciciregs( celp )->ci_pfaddr = data; Lock_cidevice( pccb ) data = Get_reg( pccb->Pesr ); Unlock_cidevice( pccb ) Elciciregs( celp )->ci_pesr = data; Lock_cidevice( pccb ) data = Get_reg( pccb->Ppr ); Unlock_cidevice( pccb ) Elciciregs( celp )->ci_ppr = data; celp += sizeof( struct ci_regs ); switch( pccb->Interconnect ) { case ICT_SBICMI: break; case ICT_BI: Elcicommon( elp )->ci_optfmask1 |= CI_BIREGS; Elcibiregs( celp )->bi_err_int = EL_UNDEF; if( !Bad_reg( pccb->Bityp )) { Elcibiregs( celp )->bi_typ = *pccb->Bityp; Elcibiregs( celp )->bi_ctrl = *pccb->Bictrl; Elcibiregs( celp )->bi_err = *pccb->Bierr; Elcibiregs( celp )->bi_int_dst = *pccb->Biint_dst; } else { Elcibiregs( celp )->bi_typ = EL_UNDEF; Elcibiregs( celp )->bi_ctrl = EL_UNDEF; Elcibiregs( celp )->bi_err = EL_UNDEF; Elcibiregs( celp )->bi_int_dst = EL_UNDEF; } celp += sizeof( struct bi_regs ); break; case ICT_XMI: Elcicommon( elp )->ci_optfmask1 |= CI_XMIREGS; Lock_cidevice( pccb ) if( !Bad_reg( pccb->Xdev )) { Unlock_cidevice( pccb ) Lock_cidevice( pccb ) data = *pccb->Xdev; Unlock_cidevice( pccb ) Elcixmiregs( celp )->xdev = data; Lock_cidevice( pccb ) data = *pccb->Xbe; Unlock_cidevice( pccb ) Elcixmiregs( celp )->xbe = data; Lock_cidevice( pccb ) data = *pccb->Xfadrl; Unlock_cidevice( pccb ) Elcixmiregs( celp )->xfadrl = data; Lock_cidevice( pccb ) data = *pccb->Xfadrh; Unlock_cidevice( pccb ) Elcixmiregs( celp )->xfadrh = data; if( pccb->lpinfo.type.hwtype == HPT_CIXCD ) { Lock_cidevice( pccb ) data = *pccb->Xcd_pidr; Unlock_cidevice( pccb ) Elcixmiregs( celp )->pidr = data; Lock_cidevice( pccb ) data = *pccb->Xcd_pvr; Unlock_cidevice( pccb ) Elcixmiregs( celp )->pvr = data; } else { Elcixmiregs( celp )->pidr = EL_UNDEF; Elcixmiregs( celp )->pvr = EL_UNDEF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -