📄 ci_isr.c
字号:
* Inputs: * * IPL_CI - Interrupt processor level * pccb - Port Command and Control Block pointer * lpinfo.type.hwtype - HPT_CI750 or HPT_CI780 * pd.gvp.type.ci - CI specific PCCB fields * lpstatus.mapped - 1 * lpstatus.power - 1 * ppd.cippd - CI PPD specific PCCB fields * fsmstatus.broken - 0 * * Outputs: * * IPL_CI - Interrupt processor level * pccb - Port Command and Control Block pointer * pd.gvp.type.ci - CI specific PCCB fields * ciregptrs.cnfr - Configuration register pointer * ciregptrs.psrcr - Port status release control reg pointer * lpstatus.power - Port has power status flag * ppd.cippd - CI PPD specific PCCB fields * fsmstatus.broken - Port is broken status flag * * SMP: No locks are required even though the PCCB may be manipulated. * Locks are never required for normal( ie - non-error ) interrupt * processing for the following reasons: * * 1. No changes to interlocked structures are made. * 2. PCCB references are only to static fields. * 3. Port registers either indicate no errors at time of * access or can not change until released. * * Locks are also not required during error processing because * CI750 and CI780 local ports are NEVER present in SMP * environments. */voidci780_isr( pccb ) register PCCB *pccb;{ register u_long save_ipl, cnfr, psr, lpcrash; /* The steps involved in processing an interrupt are as follows: * * 1. IPL is synchronized to IPL_SCS. * 2. The port configuration and status registers are checked for errors. * 3. Responses on the port response queue are processed after releasing * the port status register. * 4. IPL is restored. * * CI750/CI780 port configuration register errors include: * * 1. SBI faults( CI780 only ). * 2. Corrected read datas( CRDs ). * 3. Port power up. * 4. Port power down. * 5. CI adapter not present( CI750 only ). * 6. Memory system errors( NXM, UCE, and RLTO on CI750; CXTERR, CXTMO, and * RDS on CI780 ). * 7. Adapter port parity errors( CI750 only ). * 8. Miscellaneous errors( PFD and any undefined errors; TDCLO, TACLO, * and CTO on CI750; TDEAD, and TFAIL on CI780 ). * * CI750/CI780 port status register errors include: * * 1. Internal hardware failures( reported as parity errors ). * 2. Sanity time expiration. * 3. Data structure error. * 4. Message free queue empty. * 5. Miscellaneous errors( MISC on CI750 or undefined errors ). * * SBI faults( CI780 ) are totally ignored because they are processed * elsewhere. CRDs are cleared and then ignored because they are just * informational. Processing of the interrupt then proceeds as if the * error had never occurred. The existence of any other error forces * bypassing of response processing and triggers crashing, clean up, and * re-initialization of the local port. * * Port power down and CI adapter absent( CI750 only ) are special cases. * Both trigger crashing, disablement, and clean up of the affected local * port. Both result in scheduling of local port initialization. However, * while local port initialization is postponed while port power is * unavailable, no attempt is made to initialize absent local ports. They * are just shutdown and left permanently offline. A more detailed * description of possible power failure recovery scenarios may be obtained * by consulting ci_crash_lport(). * * There is one special port status register miscellaneous error which * requires further explanation. Broken link modules( L0100 ) may result * in link module acceptance of all packets transmitted on the CI. * Needless to say this can cause havoc especially when the module begins * to ACK/NACK packets not really addressed to it causing ACK/NACK packet * collisions and a great deal of confusion. CI port microcode has been * upgraded( hopefully ) to compare packet destination with local node * addresses and to signal mismatches by means of a special code in the * PESR. Action taken by the CI port driver on discovery of this condition * includes crashing the port, marking it broken, and taking it permanently * offline. * * NOTE: Port power up unlike port power down is not a special case. It is * treated the same as any other fatal port error, triggering * crashing, disablement, clean up, and initialization of the * affected local port. */ save_ipl = Splscs(); if( *pccb->Cnfr & ~CI780_CNF_ADAP ) { if((( cnfr = *pccb->Cnfr ) & CI780_CNF_ERRS ) == 0 ) { *pccb->Cnfr = cnfr; } else { if( cnfr & CI780_CNF_PUP ) { pccb->Lpstatus.power = 1; lpcrash = SE_POWERUP; } else if( cnfr & CI780_CNF_PDWN ) { pccb->Lpstatus.power = 0; lpcrash = SE_POWER; } else if( cnfr & CI780_CNF_NOCI ) { pccb->Fsmstatus.broken = 1; lpcrash = FE_NOCI; } else if ( cnfr & CI780_CNF_MSE ) { lpcrash = SE_MSE; } else if( cnfr & CI780_CNF_CBPE ) { lpcrash = SE_PARITY; } else { lpcrash = SE_PORTERROR; } ( void )ci_crash_lport( pccb, lpcrash, NULL ); ( void )splx( save_ipl ); return; } } if(( *pccb->Psr & ~PSR_RQA ) == 0 ) { *pccb->Psrcr = PSRCR_PSRC; ( void )ci_rsp_handler( pccb ); } else { if(( psr = *pccb->Psr ) & CI7B_PS_MTE ) { lpcrash = SE_PARITY; } else if( psr & PSR_SE ) { lpcrash = SE_SANITYTIMER; } else if( psr & PSR_DSE ) { lpcrash = SE_DSE; } else if( psr & PSR_MFQE ) { lpcrash = SE_MFQE; } else { lpcrash = FE_PORTERROR; if(( psr & PSR_MISC ) && Pesr_misc( *pccb->Pesr ) == PESR_BRKLINK){ pccb->Fsmstatus.broken = 1; } } ( void )ci_crash_lport( pccb, lpcrash, NULL ); } ( void )splx( save_ipl );}/* Name: cibci_isr - CIBCI Interrupt Service Routine * * Abstract: This routine is the primary interrupt service routine for the * CIBCI local port. It services all interrupts except: * * 1. When a local port adapter has lost power. * 2. When a local port is marked broken and permanently shutdown. * * At such times the local port is unmapped and all interrupts are * serviced instead by ci_unmapped_isr(). * * CIBCI adapters are located within their own physically separate * cabinets. They may lose power independently of the rest of the * system. They may also become uncabled from the BI on which * they nominally reside leading to their local ports being marked * broken and permanently shutdown. When either of these events * occurs, much( but not all ) of adapter I/O space becomes * unaccessible and any access attempt results in a machine check. * It is as a protection against these extraneous machine checks * that CIBCI local ports are unmapped and interrupts re-directed * to ci_unmapped_isr(). * * Inputs: * * IPL_CI - Interrupt processor level * pccb - Port Command and Control Block pointer * lpinfo.type.hwtype - HPT_CIBCI * pd.gvp.type.ci - CI specific PCCB fields * lpstatus.mapped - 1 * lpstatus.power - 1 * ppd.cippd - CI PPD specific PCCB fields * fsmstatus.broken - 0 * * Outputs: * * IPL_CI - Interrupt processor level * pccb - Port Command and Control Block pointer * pd.gvp.type.ci - CI specific PCCB fields * ciregptrs.psrcr - Port status release control reg pointer * lpstatus.power - Port has power status flag * ppd.cippd - CI PPD specific PCCB fields * fsmstatus.broken - Port is broken status flag * * SMP: The PCCB is locked to synchronize access both to itself and to * adapter register contents but only during error processing. * PCCB addresses are always valid because these data structures * are never deleted once their corresponding ports have been * initialized. * * No locks are required for normal( ie - non-error ) interrupt * processing for the following reasons: * * 1. No changes to interlocked structures are made. * 2. PCCB references are only to static fields. * 3. Port registers either indicate no errors at time of * access or can not change until released. */voidcibci_isr( pccb ) register PCCB *pccb;{ register u_long save_ipl, ber, cnfr, psr, lpcrash; /* The steps involved in servicing CIBCI interrupts are as follows: * * 1. IPL is synchronized to IPL_SCS. * 2. The BI control and status, port configuration, and port status * registers are checked for errors. * 3. Responses on the port response queue are processed after releasing * the port status register. * 4. IPL is restored. * * CIBCI port configuration register errors include: * * 1. Port power up. * 2. Port power down. * 3. CI adapter not present( NOCI and DCLO ). * 4. Parity errors( CPPE, BAPE, and BIPE ). * 5. Miscellaneous errors( BBE; or undefined errors ). * * CIBCI hard BI errors reported within the BI error register include: * * 1. BI memory system errors( IVE, RDS, RTO, STO, BTO, NEX, and ICE ) * 2. Parity errors( MPE, CEP, and SPE ). * 3. Miscellaneous errors( MTCE, CTE, ISE, TDF; or undefined errors ). * * CIBCI port status register errors include: * * 1. Parity errors( reported within PMCSR ). * 2. Sanity time expiration. * 3. Data structure error. * 4. Message free queue empty. * 5. Miscellaneous errors( MISC; or undefined errors ). * * BI soft errors including CRDs are totally ignored. Processing of the * interrupt proceeds as if they had never occurred. The existence of any * other error forces bypassing of response processing and triggers * crashing, clean up, and re-initialization of the local port. The PCCB * is locked while any and all errors are being processed. * * Port power down and CI adapter absent are special cases. Both trigger * crashing, disablement, and clean up of the affected local port. Both * result in scheduling of local port initialization. However, while local * port initialization is postponed while port power is unavailable, no * attempt is made to initialize absent local ports. They are just * shutdown and left permanently offline. A more detailed description of * possible power failure recovery scenarios may be obtained by consulting * ci_crash_lport(). * * There is one special port status register miscellaneous error which * requires further explanation. Broken link modules( L0100 ) may result * in link module acceptance of all packets transmitted on the CI. * Needless to say this can cause havoc especially when the module begins * to ACK/NACK packets not really addressed to it causing ACK/NACK packet * collisions and a great deal of confusion. CI port microcode has been * upgraded( hopefully ) to compare packet destination with local node * addresses and to signal mismatches by means of a special code in the * PESR. Action taken by the CI port driver on discovery of this condition * includes crashing the port, marking it broken, and taking it permanently * offline. * * NOTE: Consult the beginning of this module for a more in-depth * discussion on the processing of interrupts, especially interrupts * to report errors, in SMP environments. * * NOTE: Port power up unlike port power down is not a special case. It is * treated the same as any other fatal port error, triggering * crashing, disablement, clean up, and initialization of the * affected local port. * * NOTE: The local port may be found to be unmapped following locking of * the PCCB on initial discovery of an error. The only way in which * such unmapping could have occurred is during interrupt processing * by another thread. This other thread must have processed either * the adapter reported error which triggered creation of the current * thread or another more serious error. This allows the current * thread to just be terminated as either the reason for its creation * has already been satisfactorily dealt with or no longer exists. */ save_ipl = Splscs(); if(( *pccb->Bictrl & BICTRL_HES ) || ( *pccb->Cnfr & CIBCI_CNF_ERRS ) || ( *pccb->Psr & CI7B_PS_ERRS )) { Lock_pccb( pccb ) if( !pccb->Lpstatus.mapped ) { Unlock_pccb( pccb ) ( void )splx( save_ipl ); return; } if(( cnfr = *pccb->Cnfr ) & CIBCI_CNF_ERRS ) { if( cnfr & CIBCI_CNF_PUP ) { pccb->Lpstatus.power = 1; lpcrash = SE_POWERUP; } el
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -