📄 scs_event.c
字号:
* * 1. The CB can not be retrieved. * 2. The connection is in an inappropriate state. */ if( scsbp->rconnid.index > ( lscs.max_conns - 1 )) { cbvte = NULL; event = SE_BADCONNID; } else { cbvte = Get_cbvte( scsbp->rconnid ); Lock_cbvte( cbvte ) cb = Get_cb( cbvte ); if( scsbp->rconnid.seq_num != cbvte->connid.seq_num ) { event = 0; ( void )( *pccb->Add_dg )( pccb, scsbp ); } else if( cb->cinfo.cstate == CS_OPEN && ( notify = cb->dg_event ) && cb->cinfo.dg_credit ) { register CSB *csb = &dg_csb; Event_counter( cb->cinfo.dgs_rec ) --cb->cinfo.dg_credit; csb = &dg_csb; Init_csb( csb, cb, scsbp, size ) Incr_cbvte_sem( cbvte ) Unlock_cbvte( cbvte ) ( void )( *notify )( csb ); Decr_cbvte_sem( cbvte ) return; } else if( cb->cinfo.cstate == CS_OPEN || cb->cinfo.cstate == CS_PATH_FAILURE || cb->cinfo.cstate == CS_DISCONN_SNT || cb->cinfo.cstate == CS_DISCONN_REC || cb->cinfo.cstate == CS_DISCONN_ACK || cb->cinfo.cstate == CS_DISCONN_MTCH ) { event = 0; Event_counter( cb->cinfo.dgs_discard ) ( void )( *cb->Add_dg )( pccb, scsbp ); } else { event = SE_BADCSTATE; } } if( cbvte ) { Unlock_cbvte( cbvte ) } if( event ) { register PB *pb; Lock_scadb() pb = ( *pccb->Get_pb )( pccb, scsbp, BUF ); ( void )( *pccb->Crash_path )( pccb, pb, event, RECEIVE_BUF, scsbp ); Unlock_scadb() }}/* Name: scs_msg_rec - Sequenced Message Received * * Abstract: This SCS event notification routine is asynchronously invoked * whenever a PD receives an application or SCS sequenced * message. The PD should not have notified SCS of the failure of * the path over which the sequenced message was received although * in a SMP environment this may prove unavoidable. * * SCS disposes of the received sequenced message in one of three * ways: * * 1. The SCS sequenced message is processed and disposed of by * SCS according to its message type. * 2. The application sequenced message is handed off to the * appropriate SYSAP through asynchronous invocation of the * connection's message event routine. * 3. The application sequenced message buffer is added to the * appropriate port's free message pool. * * Received application sequenced messages may contain extended * send credits. These credits may trigger notification of the * appropriate SYSAP of the availability of send credits on the * connection through asynchronous invocation of the connection's * control event routine. * * Inputs: * * IPL_SCS - Interrupt processor level * lscs - Local system permanent information * pccb - Port Command and Control Block pointer * lk_scadb - SCA database lock structure * scsbp - Address of SCS header in datagram buffer * scs_cbvtdb - CB vector table database pointer * size - Size of application data + SCS header * * Outputs: * * IPL_SCS - Interrupt processor level * cb - Connection Block pointer * cinfo.msgs_rec - Number of sequenced messages received * cinfo.rec_credit - Number of send credits held by remote SYSAP * cinfo.snd_credit - Number of send credits * cinfo.status.cwait - SYSAP waiting for send credits flag * * SMP: The SCA database is locked for PB retrieval. It also prevents * premature PB deletion as required by PD routines which crash * paths. * * The CB is locked to synchronize access and to prevent deletion. * It is indirectly locked through its CBVTE. Locking the CB also * prevents premature PB deletion as required by scs_init_cmsb(). * * The CBVTE semaphore is incremented prior to either SYSAP * reception of the received application sequenced message or * SYSAP notification of send credit availability. This prevents * any changes in connection state while call backs are in * progress. The semaphore is decremented after SYSAP reception * of the application sequenced message completes. * * PCCB addresses are always valid allowing access to static * fields because PCCBs are never deleted once SCS becomes aware * of their existence. * * NO EXTERNAL locks may be held when this routine is invoked. */voidscs_msg_rec( pccb, scsbp, size ) PCCB *pccb; register SCSH *scsbp; u_long size;{ u_long event; CSB msg_csb; CMSB credit_cmsb; register CB *cb; register CBVTE *cbvte; register void ( *notify )(), ( *credit )(); /* Invoke SCS to dispose of received non-application sequenced messages. * Otherwise, application sequence message reception notifications are * processed as follows: * * 1. Lock and retrieve the CB targeted by the received application * sequenced message. * 2. Validate the connection. * 3. Determine whether suitable conditions exist for reception and * disposal of the application sequenced message on the connection by * the corresponding SYSAP. * 4. Perform connection bookkeeping * 5. Increment the CBVTE semaphore. * 6. Unlock the CB. * 7. Notify the SYSAP of send credit availability on the connection if it * was waiting for them to become available and send credits were * extended across the connection piggy-backed on the received * application sequence message. * 8. Invoke the connection's message event routine to allow the * corresponding SYSAP to receive and dispose of the the application * sequenced message provided suitable conditions exist. * 9. Decrement the CBVTE semaphore. * * Incrementing the appropriate CBVTE semaphore protects the connection * against all changes in state for the duration of both SYSAP * notifications and while any call backs on the connection are in * progress. * * Failure to find suitable conditions for SYSAP disposal of the * application sequenced message( Step 3 ) may be due to: * * 1. Inappropriate connection state. * 2. Absence of a message event routine associated with the connection. * * Either condition aborts handing off the application sequence message to * the SYSAP for disposal. Instead, the message buffer is returned to the * appropriate port's message free pool provided the connection is in an * acceptable state. * * The path on which the sequenced message was received is crashed under * any of the following circumstances: * * 1. The CB can not be retrieved. * 2. A connection identification number mismatch exists( failure to * validate the connection ). * 3. The connection is in an inappropriate state. * 4. The remote SYSAP should not have possessed a send credit for * transmission of the application sequenced message. * * None of these circumstances are ever expected in a single processor * environment. This explains the drastic actions taken when they occur. * However, the occurrence of any of these circumstances can be expected in * a SMP environment, albeit with an extremely low frequency, whenever a * path fails. This is because no mechanisms exist to coordinate PD event * notifications of SCS as there are mechanisms to coordinate SCS * notifications of SYSAPs. This allows SCS receptions of application * sequenced messages to actually occur after PD notifications of path * failure even though PDs initiate the reception first. The actions taken * remain the same as in the single processor case even though they are * drastic and may well result in double crashing of the path. There is no * other alternative. */ if( scsbp->mtype != SCS_APPL_MSG ) { event = 0; cbvte = NULL; ( void )scs_receive( pccb, scsbp ); } else if( scsbp->rconnid.index > ( lscs.max_conns - 1 )) { cbvte = NULL; event = SE_BADCONNID; } else { cbvte = Get_cbvte( scsbp->rconnid ); Lock_cbvte( cbvte ) cb = Get_cb( cbvte ); if( scsbp->rconnid.seq_num != cbvte->connid.seq_num ) { event = SE_BADCONNID; } else if( cb->cinfo.cstate == CS_OPEN && ( notify = cb->msg_event )) { if( cb->cinfo.rec_credit-- ) { register CSB *csb = &msg_csb; if(( cb->cinfo.snd_credit += scsbp->credit ) && cb->cinfo.status.cwait ) { credit = cb->control; cb->cinfo.status.cwait = 0; ( void )scs_init_cmsb( CRE_CREDIT_AVAIL, ADR_SUCCESS, &credit_cmsb, cb, cb->pb, 0 ); } else { credit = NULL; } Event_counter( cb->cinfo.msgs_rec ) Init_csb( csb, cb, scsbp, size ) Incr_cbvte_sem( cbvte ) Unlock_cbvte( cbvte ) if( credit ) { ( void )( *credit )( CRE_CREDIT_AVAIL, &credit_cmsb ); } ( void )( *notify )( csb ); Decr_cbvte_sem( cbvte ) return; } else { cb->cinfo.rec_credit = 0; event = SE_NOCREDITS; } } else if( cb->cinfo.cstate == CS_OPEN || cb->cinfo.cstate == CS_DISCONN_SNT ) { event = 0; ( void )( *cb->Add_msg )( pccb, scsbp ); } else { event = SE_BADCSTATE; } } if( cbvte ) { Unlock_cbvte( cbvte ) } if( event ) { register PB *pb; Lock_scadb() pb = ( *pccb->Get_pb )( pccb, scsbp, BUF ); ( void )( *pccb->Crash_path )( pccb, pb, event, RECEIVE_BUF, scsbp ); Unlock_scadb() }}/* Name: scs_msg_snt - Application Sequenced Message Sent * * Abstract: This SCS event notification routine is asynchronously invoked * to dispose of certain specified application sequenced messages * following their transmission. The PD should not have notified * SCS of the failure of the path over which the application * sequenced message was transmitted although in a SMP environment * this may prove unavoidable. * * SCS disposes of the transmitted application sequenced message * in one of two ways: * * 1. The application sequenced message is deallocated. * 2. The application sequenced message buffer is converted into a * receive message buffer for the logical SCS connection by * adding it to the appropriate port's free message pool. * * Converting an application sequenced message buffer into a * receive message buffer may trigger the explicit extension of * send credits across the logical SCS connection. * * Inputs: * * IPL_SCS - Interrupt processor level * lscs - Local system permanent information * pccb - Port Command and Control Block pointer * lk_scadb - SCA database lock structure * scsbp - Address of SCS header in message buffer * scs_cbvtdb - CB vector table database pointer * size - Size of application data + SCS header * * Outputs: * * IPL_SCS - Interrupt processor level * * SMP: The SCA database is locked for PB retrieval. It also prevents * premature PB deletion as required by PD routines which crash * paths. * * The CB is locked to synchronize access and to prevent deletion. * It is indirectly locked through its CBVTE. Locking the CB also * prevents premature PB deletion as required by scs_init_cmsb() * and scs_dispose_msg(). * * PCCB addresses are always valid allowing access to static * fields because PCCBs are never deleted once SCS becomes aware * of their existence. * * NO EXTERNAL locks may be held when this routine is invoked. */voidscs_msg_snt( pccb, scsbp, size ) PCCB *pccb; register SCSH *scsbp; u_long size;{ register CB *cb; register PB *pb; register CBVTE *cbvte; register u_long event = 0; /* Application sequenced message transmission notifications are processed * as follows: * * 1. Lock and retrieve the CB targeted by the transmitted application * sequence message. * 2. Validate the connection. * 3. Dispose of the transmitted application sequenced message according * to the connection's current credit situation whenever the connection * is open. Otherwise, deallocate the transmitted application sequenced * message. * 4. Unlock the CB. * * The path over which the sequenced message was transmitted is crashed * under any of the following circumstances: * * 1. The CB can not be retrieved. * 2. A connection identification number mismatch exists. * * None of these circumstances are ever expected in a single processor * environment. This explains the drastic actions taken when they occur. * However, the occurrence of any of these circumstances can be expected in * a SMP environment, albeit with an extremely low frequency, whenever a * path fails. This is because no mechanisms exist to coordinate PD event * notifications of SCS as there are mechanisms to coordinate SCS * notifications of SYSAPs. This allows SCS disposal of transmitted * application sequenced messages to actually occur after PD notifications * of path failure even though PDs initiate message disposal first. The * actions taken remain the same as in the single processor case even * though they are drastic and may well result in double crashing of the * path. There is no other alternative. */ if( scsbp->sconnid.index > ( lscs.max_conns - 1 )) { cbvte = NULL; event = SE_BADCONNID; } else { cbvte = Get_cbvte( scsbp->sconnid ); Lock_cbvte( cbvte ) cb = Get_cb( cbvte ); if( scsbp->sconnid.seq_num != cbvte->connid.seq_num ) { event = SE_BADCONNID; } else if( cb->cinfo.cstate == CS_OPEN ) { ( void )scs_dispose_msg( cb, scsbp ); } else { ( void )( *cb->Dealloc_msg )( pccb, scsbp ); } } if( cbvte ) { Unlock_cbvte( cbvte ) } if( event ) { Lock_scadb() pb = ( *pccb->Get_pb )( pccb, scsbp, BUF ); ( void )( *pccb->Crash_path )( pccb, pb, event, DEALLOC_BUF, scsbp ); Unlock_scadb() }}/* Name: scs_new_path - New Path to System Discovered * * Abstract: This SCS event notification routine is asynchronously invoked * whenever the PD discovers a path to a previously unknown * system. It proceeds to notify all listening SYSAPs of the * existence of the new path through asynchronous invocations * of their connections' control event routines. * * SMP environments require the PB representing the path to the * new system to exist in some state for the duration of the SYSAP * notifications. The path itself can fail but the PB may NOT be * cleaned up until after this routine exits. The responsibility * for meeting this requirement is assigned to the PDs and the * choice of mechanism is also left up to the individual PDs. * * Inputs: * * IPL_SCS - Interrupt processor level * pb - Path Block pointer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -