📄 msi_isr.c
字号:
} break; case ID: Rcheck_id( pccb, Siibp, msibp, event ) if( Msibp ) { Rformat_msib( Siibp, Msibp ) Insert_msib( Msibp, rdoneq ) } break; case IDREQ: Rcheck_idreq( pccb, Siibp, msibp, event ) if( Msibp ) { Rqueue_id( pccb, Msibp, Siibp ) start_xfp = 1; } break; case RST: case STRT: break; case CNF: case RETDAT: event = SE_INVOPCODE; break; default: event = SE_UNKOPCODE; } } if( event ) { Rproc_error( pccb, Siibp, msibp, event, lpc, rdoneq ) event = 0; if( lpc ) { Unlock_rfp( pccb ) ( void )splx( save_ipl ); return; } } } else { if( Rinvalid_srcaddr( pccb, Siibp )) { Rlog_invsrcaddr( pccb, Siibp ) } } Rreset_cmdblk( Siibp ) if( rfree == NULL ) { rfree = siibp; } } /* */ if( rfree ) { if( rfree != ( siibp = pccb->Rbusy )) { Term_thread( siibp ) Thread_cmdblk( rfree, rfree ) if( *pccb->Msitlp == 0 ) { *pccb->Msitlp = (( SIIBUF * )rfree )->cmdblkaddr; } } else { *pccb->Msitlp = (( SIIBUF * )rfree )->cmdblkaddr; } } /* */ { register msibq *qaddr = &rdoneq; Unlock_rfp( pccb ) if( start_xfp ) { Xstart_xfp( pccb ) } for( msibp = qaddr->flink; msibp != qaddr; msibp = qaddr->flink ) { Remove_msib( Msibp ) Rfinish_receive( pccb, Msibp ) } } ( void )splx( save_ipl );}/* Name: msi_xfp - MSI Transmit Fork Process Routine * * Abstract: * * Inputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * pd.msi - MSI specific PCCB fields * lpstatus.xfork - 1 * * Outputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * pd.msi - MSI specific PCCB fields * comqh - MSIB high priority command queue * comql - MSIB low priority command queue * dfreeq - MSIB datagram free queue * lpcinfo - Optional local port crash information * pkth - Address of MSI packet * pktsize - Size of msi packet * pport_addr - Packet remote port station address * lpstatus.timer - Retry delay timer active flag * lpstatus.xfork - 0 * mfreeq - MSIB message free queue * perport - Per-DSSI port information * rpstatus.dip - Transmit delaying in progress flag * rpstatus.path - Path exists flag * xretrys - Current transmit retry attempt * xretryq - MSIB transmit retry queue * xretry_timer - Transmit retry timer( in 10 msecs ) * xseqno - Next transmit sequence number * siiregptrs - MSI register pointers * msidscr - DSSI control register * msiilp - Initiator list pointer register * xbusy - First transmit-in-progress SIIBUF pointer * xdmap - Transmit Fork Process DMapping Buffer Info * xfree - First free transmit SIIBUF pointer * * SMP: PCCB: Interlock Access * Prevent PB deletion * XFP: Interlock Access * Guarantee only one active XFP and XFP_TIMER threads * Prohibits Port Crashing * Prohibits VC closure except at behalf this routine * DFREEQ: Interlock Access * MFREEQ: Interlock Access * COMQH: Interlock Access * COMQL: Interlock Access */voidmsi_xfp( pccb ) register PCCB *pccb;{ msibq xmsg_doneq; register siibq *siibp, *xstart_xmt = NULL; register msibq *msibp; register MSI_PPORTINFO *dpi; u_long save_ipl;/* */ Xfp_started( pccb, save_ipl ) Init_queue( xmsg_doneq ) /* */ while(( Msibp = (( SIIBUF * )( siibp = pccb->Xbusy ))->save_msib )) { if( Siibp->cmdblk.status == ST_SUCCESS ) { if( *pccb->Msiilp != Siibp->cmdblkaddr ) { dpi = &pccb->Perport[ Siibp->cmdblk.dst ]; Xtransmit_done( pccb, Msibp, dpi, xmsg_doneq ) Xfree_siib( pccb, Siibp ) } else { break; } } else if( Xsii_busy( pccb )) { break; } else { /* Delay for awhile, if not we get bad status and cause duplicate packets to be resent. We should not have to do this, UGH SII. */ DELAY( 2 ); if( Siibp->cmdblk.status == ST_SUCCESS ) { continue; } else if( Xfalse_nack( pccb, Siibp )) { Siibp->cmdblk.status = ST_SUCCESS; continue; } else if( *pccb->Msiilp ) { *pccb->Msiilp = 0; dpi = &pccb->Perport[ Siibp->cmdblk.dst ]; if( Xignore_xmtfail( pccb, Siibp, dpi )) { Xdiscard_msib( pccb, Msibp ) Xfree_siib( pccb, Siibp ) } else { Xretry_xmt( pccb, siibp, msibp, dpi, xmsg_doneq ) } } if((( SIIBUF * )( siibp = pccb->Xbusy ))->save_msib ) { xstart_xmt = siibp; Xreset_xbusy( pccb, siibp ) } break; } } if( Siibp->save_msib == 0 || xstart_xmt ) { siibp = pccb->Xfree; Thread_cmdblk( siibp, siibp ) } /* */ while((( SIIBUF * )( siibp = pccb->Xfree ))->save_msib == 0 ) { Remove_comqh( pccb, msibp ) if( Msibp == NULL ) { Remove_comql( pccb, msibp ) if( Msibp == NULL ) { break; } } dpi = &pccb->Perport[ Msibp->Rport_addr ]; if( Rpstatus_dip( dpi )) { Xinsert_xretryq( dpi, Msibp ) } else if( Xabort_xmt( dpi, Msibp )) { Xdiscard_msib( pccb, Msibp ) } else { Xformat_siib( Siibp, Msibp ) if( Msibp->Ph.opcode == RETDAT ) { u_long event = 0; Xcheck_lretdat( pccb, Msibp, event ) if( event == 0 ) { ( void )bcopy( pccb->Xdmap.Saddr, Siibp->Xpkt.retdat.data, pccb->Xdmap.ssize ); if( Lp_msih( Msibp->Ph )) { Set_lp( Siibp->Xpkt.ph ) } Msibp->Framelength += U_short( pccb->Xdmap.ssize ); } else { Xretdat_error( pccb, msibp, event, xmsg_doneq ) Unlock_xfp( pccb ) ( void )splx( save_ipl ); return; } } if( Vc_msib( Msibp )) { Xset_xseqno( dpi, Siibp ) } Siibp->save_msib = Msibp; Xformat_cmdblk( pccb, Siibp, Msibp ) Xformat_xlink( Siibp, Msibp ) if( xstart_xmt == NULL ) { xstart_xmt = siibp; } pccb->Xfree = siibp->flink; } } /* */ if( xstart_xmt ) { Interrupt_enable( xstart_xmt ) siibp = pccb->Xfree; Term_thread( siibp ) siibp = siibp->blink; Interrupt_enable( Siibp ) if( *pccb->Msiilp == 0 ) { *pccb->Msiilp = (( SIIBUF * )xstart_xmt )->cmdblkaddr; *pccb->Msidscr = MSIDSCR_SOUT; } if( xstart_xmt != pccb->Xbusy ) { Thread_cmdblk( xstart_xmt, xstart_xmt ) } } /* */ Unlock_xfp( pccb ) while(( msibp = xmsg_doneq.flink ) != &xmsg_doneq ) { Remove_msib( Msibp ) ( void )scs_msg_snt( pccb, ( SCSH * )Msibp->Msg.text, ( Msibp->Framelength - MSG_OVHD )); } ( void )splx( save_ipl );}/* Name: msi_xfp_timer - MSI Transmit Fork Process Timer Routine * * Abstract: * * Inputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * pd.msi - MSI specific PCCB fields * lpstatus.timer - 1 * * Outputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * pd.msi - MSI specific PCCB fields * comqh - MSIB high priority command queue * lpstatus.timer - Retry delay timer status bit * lpstatus.xfork - Transmit Fork Process scheduled flag * perport - Per-DSSI port information * rpstatus.dip - Transmit delaying in progress flag * xretryq - MSIB transmit retry queue * xretry_timer - Transmit retry timer( in 10 msecs ) * xforkb - Transmit Fork Process fork block * * SMP: XFP: Interlock Access * Guarantee only one active XFP and XFP_TIMER threads * Prohibits Port Crashing * Prohibits VC closure except at behalf this routine * COMQH: Interlock Access * PCCB: Interlock Access */voidmsi_xfp_timer( pccb ) register PCCB *pccb;{ u_long save_ipl; register msibq *msibp; register MSI_PPORTINFO *ppi; register u_long portnum, reschedule = 0, start_xfp = 0; /* */ Xfp_timer_started( pccb, save_ipl ) for( portnum = 0; portnum < MSI_MAXNUM_PORT; ++portnum ) { ppi = &pccb->Perport[ portnum ]; if( Rpstatus_dip( ppi )) { if( --ppi->xretry_timer ) { reschedule = 1; } else { Clear_rpdip( ppi ) while(( msibp = ppi->xretryq.flink ) != &ppi->xretryq ) { Remove_msib( Msibp ) Insert_comqh( pccb, Msibp ) start_xfp = 1; } } } } if( reschedule ) { Xstart_xfp_timer( pccb ) } Unlock_xfp( pccb ) if( start_xfp ) { Xstart_xfp( pccb ) } ( void )splx( save_ipl );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -