📄 cippd_event.c
字号:
} if( pb ) { Lock_pb( pb ) if( type <= CNFE_STOP_REC && type != CNFE_SCSMSG_REC ) { ( void )cippd_dispatch( pccb, pb, type, cippdbp ); } else { ( void )cippd_crash_pb( pccb, pb, SE_BADPPDMTYPE, RECEIVE_BUF, Ppd_to_scs( cippdbp )); } Unlock_pb( pb ) } else { if( type > CNFE_STOP_REC || type == CNFE_SCSMSG_REC ) { pccb->Elogopt.port_num = port; ( void )cippd_log_path( pccb, NULL, cippdbp, RE_BADPPDMTYPE ); } ( void )( *pccb->Add_dg )( pccb, Ppd_to_scs( cippdbp )); } Unlock_pccb( pccb )}/* Name: cippd_reqid_snt - Identification Request Transmission Completed * * Abstract: This CI PPD event notification routine is asynchronously * invoked by port drivers following transmission of each * identification request. This occurs regardless of whether the * request had been initiated during polling or by the CI PPD * finite state machine during path establishment. Its purpose is * to determine whether the sanity check initiated during the * port's last polling interval has been satisfied. * * The local port sanity check crudely verifies the operational * status of the local port. During the last polling interval the * port number of the first remote port polled is saved. * Successful transmission of the request for this remote port's * identification must complete before the next timer interval or * the port is assumed to be broken and is crashed. * * NOTE: Some port drivers do NOT require sanity checks to be made * on their local ports. Such drivers set the * "nosanity_chk" finite state machine status bit in their * PCCBs as an appropriate indicator to the CI PPD. They * also NEVER bother to invoke this function following * transmission of an identification request. * * NOTE: SCA port numbers are 6 bytes in size; however, maximum * CI PPD port numbers only occupy 1 byte, the low-order * byte of a port station address. Port numbers are passed * as 4 bytes entities back and forth between the CI PPD and * its client port drivers. * * Inputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * ppd.cippd - CI PPD specific PCCB fields * fsmstatus - Finite State Machine status flags * nosanity_chk - Skip sanity checking flag * port - Port number of completed request * * Outputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * ppd.cippd - CI PPD specific PCCB fields * fsmstatus.sanity - Port polling ( sanity check ) in progress * * SMP: The PCCB is locked to synchronize access. PCCB addresses are * always valid because these data structures are never deleted * once their corresponding ports have been initialized. * * NO EXTERNAL locks may be held when this routine is invoked. */voidcippd_reqid_snt( pccb, port ) PCCB *pccb; u_long port;{ Lock_pccb( pccb ) if( pccb->Fsmstatus.sanity && pccb->Sanity_port == port ) { pccb->Fsmstatus.sanity = 0; } Unlock_pccb( pccb )}/* Name: cippd_start - Start CI PPD Activity on Local Port * * Abstract: This CI PPD event notification routine is asynchronously * invoked following local port initialization. It engages the CI * PPD finite state machine on the port by activating the CI PPD * interval timer routine. Once engaged this machine * automatically polls for remote systems and attempts to * establish CI PPD paths to those it discovers. * * There are two situations when this routine is invoked by a port * driver and they are identically handled. * * 1. During auto-configuration at system boot time following * successful initialization of a local port. * 2. Following the failure and successful re-initialization * of a local port. * * NOTE: Some port drivers NEVER require sanity checks to be made * on their local ports. Such drivers set the * "nosanity_chk" finite state machine status bit in their * PCCBs as an appropriate indicator prior to engaging the * CI PPD on their local ports. * * Inputs: * * IPL_SCS - Interrupt processor level * cippd_max_port - CI PPD maximum port to recognize * cippd_init_dgs - Number of CI PPD path establishment datagrams * cippd_itime - CI PPD port timer interval * pccb - Port Command and Control Block pointer * ppd.cippd - CI PPD specific PCCB fields * burst - Port polling burst size * contact - Port polling contact frequency * fsmstatus - Finite State Machine status flags * nosanity_chk - Skip sanity checking flag * online - 0 * * Outputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * lpinfo.ppd.cippd - CI PPD specific local port information * protocol - CI PPD protocol version level * ppd.cippd - CI PPD specific PCCB fields * form_pb - Formative PB queue( INITIALIZED ) * fsmstatus.online - 1 * fsmstatus.timer - 1 * next_port - Next port to poll * poll_cable - CI cable to use for polling * poll_due - Port polling interval timer * poll_interval - Current port polling interval * ppddgs - Num path establishment dgs left to allocate * timer_interval - Current CI timer interval * * SMP: The PCCB is locked to synchronize access. This is probably * unnecessary because of lack of conflict for the PCCB due to the * single threadedness of port clean up and 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. * * NO EXTERNAL locks may be held when this routine is invoked. */voidcippd_start( pccb ) register PCCB *pccb;{ /* The steps involved on starting the CI PPD on a local port are: * * 1. Lock the PCCB. * 2. Initialize the CI PPD specific PCCB fields controlling polling and * specifying the number of CI PPD datagrams left to allocate and add to * the specified local port datagram free queue. * 3. Schedule the first invocation of the CI PPD interval timer on the * local port. * 4. Unlock the PCCB. * * CI PPD datagrams added to the specified local port datagram free queue( * Step 2 ) are used for reception of solicited remote port identifications * and unsolicited START CI PPD datagrams. Actual buffer allocations are * performed prior to the initial polling for remote ports from the * specified local port( by cippd_poll()). * * Scheduling the first invocation of the CI PPD interval timer on a local * port is only necessary following the initial initialization of the port( * Step 3 ). Once activated the CI PPD interval timer is self maintaining * and remains permanently active on the local port. */ Lock_pccb( pccb ) pccb->Fsmstatus.online = 1; Init_queue( pccb->Form_pb ) pccb->Poll_due = 0; pccb->Next_port = 0; pccb->Poll_cable = FIRST_CABLE; pccb->Poll_interval = Pinterval( pccb ); pccb->Ppddgs = cippd_init_dgs; if( !pccb->Fsmstatus.timer ) { pccb->Fsmstatus.timer = 1; pccb->Timer_interval = cippd_itime; ( void )timeout( cippd_timer, ( u_char * )pccb, 0 ); } Unlock_pccb( pccb )}/* Name: cippd_stop - Stop CI PPD Activity on Local Port * * Abstract: This CI PPD event notification routine is asynchronously * invoked following disablement of a local port. It directs the * clean up the CI PPD portion of the failed port primarily by * directing the clean up all paths associated with the port, both * formative and established. * * Port re-initialization is triggered in one of two ways. It is * immediately initiated by this routine if there are no paths * associated with the failed port. Otherwise, clean up the last * associated path, formative or established, triggers it. * * NOTE: The appropriate port drivers are always responsible for * the removal and deallocation of all free datagram and * message buffers associated with failed local ports. The * CI PPD must never attempt to dispose of such buffers. * * Inputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * ppd.cippd - CI PPD specific PCCB fields * fsmstatus.cleanup - 1 * fsmstatus.fkip - 0 * fsmstatus.online - 0 * reason - Generic reason why the local port was crashed * * Outputs: * * IPL_SCS - Interrupt processor level * pccb - Port Command and Control Block pointer * forkb - PCCB fork block * ppd.cippd - CI PPD specific PCCB fields * fsmstatus.fkip - Fork operation in progress * fsmstatus.sanity - 0 * * SMP: The PCCB is locked to synchronize access and as required by * cippd_log_path() in case event logging becomes necessary. 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. Locking the PCCB also prevents premature PB deletion. * PCCB addresses are always valid because these data structures * are never deleted once their corresponding ports have been * initialized. * * PBs are locked to synchronize access and prevent premature * deletion. * * PB semaphores are incremented prior to scheduling asynchronous * clean up of both formative and established paths. Incrementing * the semaphore should guarantee PB validity when path clean up * commences. Actually, single threading of clean up should * sufficient for this purpose, but the PB semaphore is * incremented anyway as further protection and to detect errors * in error recovery logic. * * NO EXTERNAL locks may be held when this routine is invoked. */voidcippd_stop( pccb, reason ) register PCCB *pccb; u_long reason;{ register pbq *pb, *next_pb; register SB *sb; register long i; /* The steps involved in stopping CI PPD activity on a local port include: * * 1. Locking the PCCB. * 2. Cleaning up the CI PPD specific portion of the PCCB. * 3. Failing all formative paths associated with the local port. * 4. Failing all established paths associated with the local port. * 5. Unlocking the PCCB. * * * The failure of each formative path( Step 3 ) and each established path( * Step 4 ) is event logged. Local port re-initialization follows clean up * of the very last path associated with the failed port. It is initiated * directly by this routine if no paths are associated with the port at * time of failure. * * Failing paths associated with operational ports is a complex process. * It requires CI PPD finite state machine intervention to pre-process, * disable, and direct path clean up. Failing paths associated with failed * ports is not as complicated. No crash pre-processing must be done and * the port failure itself automatically disabled all associated paths. * Only path clean up is required and may be accomplished without CI PPD * intervention. However, synchronization to the path state interlock is * still required before path clean up commences. This maintains the * single threading necessary to prevent both multiple crashings of the * same path incarnation and multiple attempts to clean up the same path. * Such a need exists only in SMP environments where multiple CI PPD * threads may exist and interact. * * Synchronization to the path state interlock as a prelude to path clean * up proceeds as follows: * * The state of each path is checked. Another CI PPD thread is * assumed to have crashed the path and taken responsibility for * clean up if path state == PS_PATH_FAILURE. Otherwise, the * current thread assumes responsibility for cleaning up the path * by transitioning its state to PS_PATH_FAILURE. * * When this routine assumes responsibility for cleaning up a path, it * increments the appropriate PB semaphore and schedules asynchronous path * clean up through forking. Different routines are employed to clean up * formative and established paths. Using the semaphore in this fashion * should guarantee PB validity when path clean up commences. Actually, * single threading of clean up should be sufficient for this purpose, but * the semaphore is incremented anyway as further protection, and to detect * errors in error recovery logic. * * NOTE: The PB fork block is only used for path clean up. Therefore, it * should always be available because path clean up is single * threaded. * * NOTE: The PCCB fork block is only used for clean up and initialization * of the local port. Therefore, it should always be available * because port clean up and initialization are single threaded. */ Lock_pccb( pccb ) pccb->Fsmstatus.sanity = 0; if( pccb->lpinfo.Npaths == 0 && pccb->lpinfo.Nform_paths == 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -