📄 sl.c
字号:
printd(("%s: %p: SDT_DAEDT_TRANSMISSION_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}#endif/* * SDT_DAEDT_START_REQ * ----------------------------------- */STATIC INLINE intsdt_daedt_start_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_daedt_start_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_DAEDT_START_REQ; printd(("%s: %p: SDT_DAEDT_START_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * SDT_DAEDR_START_REQ * ----------------------------------- */STATIC INLINE intsdt_daedr_start_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_daedr_start_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_DAEDR_START_REQ; printd(("%s: %p: SDT_DAEDR_START_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * SDT_AERM_START_REQ * ----------------------------------- */STATIC INLINE intsdt_aerm_start_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_aerm_start_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_AERM_START_REQ; printd(("%s: %p: SDT_AERM_START_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * SDT_AERM_STOP_REQ * ----------------------------------- */STATIC INLINE intsdt_aerm_stop_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_aerm_stop_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_AERM_STOP_REQ; printd(("%s: %p: SDT_AERM_STOP_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * SDT_AERM_SET_TI_TO_TIN_REQ * ----------------------------------- */STATIC INLINE intsdt_aerm_set_ti_to_tin_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_aerm_set_ti_to_tin_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_AERM_SET_TI_TO_TIN_REQ; printd(("%s: %p: SDT_AERM_SET_TI_TO_TIN_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * SDT_AERM_SET_TI_TO_TIE_REQ * ----------------------------------- */STATIC INLINE intsdt_aerm_set_ti_to_tie_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_aerm_set_ti_to_tie_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_AERM_SET_TI_TO_TIE_REQ; printd(("%s: %p: SDT_AERM_SET_TI_TO_TIE_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * SDT_SUERM_START_REQ * ----------------------------------- */STATIC INLINE intsdt_suerm_start_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_suerm_start_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_SUERM_START_REQ; printd(("%s: %p: SDT_SUERM_START_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * SDT_SUERM_STOP_REQ * ----------------------------------- */STATIC INLINE intsdt_suerm_stop_req(queue_t *q, struct sl *sl){ mblk_t *mp; sdt_suerm_stop_req_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->sdt_primitive = SDT_SUERM_STOP_REQ; printd(("%s: %p: SDT_SUERM_STOP_REQ ->\n", MOD_NAME, sl)); putnext(sl->iq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * ========================================================================= * * PROTOCOL STATE MACHINE FUNCTIONS * * ========================================================================= *//* * ------------------------------------------------------------------------ * * Timers * * ------------------------------------------------------------------------ */enum { tall, t1, t2, t3, t4, t5, t6, t7 };SS7_DECLARE_TIMER(MOD_NAME, sl, t1, config);SS7_DECLARE_TIMER(MOD_NAME, sl, t2, config);SS7_DECLARE_TIMER(MOD_NAME, sl, t3, config);STATIC int sl_t4_timeout(struct sl *);STATIC void streamscallsl_t4_expiry(caddr_t data){ ss7_do_timeout(data, "t4", "sl", &((struct sl *) data)->timers.t4, (int (*)(struct head *)) &sl_t4_timeout, &sl_t4_expiry);}STATIC voidsl_stop_timer_t4(struct sl *sl){ ss7_stop_timer((struct head *) sl, "t4", "sl", &sl->timers.t4);}STATIC voidsl_start_timer_t4(struct sl *sl){ ss7_start_timer((struct head *) sl, "t4", "sl", &sl->timers.t4, &sl_t4_expiry, sl->statem.t4v);};SS7_DECLARE_TIMER(MOD_NAME, sl, t5, config);SS7_DECLARE_TIMER(MOD_NAME, sl, t6, config);SS7_DECLARE_TIMER(MOD_NAME, sl, t7, config);STATIC INLINE void__sl_timer_stop(struct sl *sl, const uint t){ int single = 1; switch (t) { case tall: single = 0; /* fall through */ case t1: sl_stop_timer_t1(sl); if (single) break; /* fall through */ case t2: sl_stop_timer_t2(sl); if (single) break; /* fall through */ case t3: sl_stop_timer_t3(sl); if (single) break; /* fall through */ case t4: sl_stop_timer_t4(sl); if (single) break; /* fall through */ case t5: sl_stop_timer_t5(sl); if (single) break; /* fall through */ case t6: sl_stop_timer_t6(sl); if (single) break; /* fall through */ case t7: sl_stop_timer_t7(sl); if (single) break; /* fall through */ break; default: swerr(); break; }}STATIC INLINE voidsl_timer_stop(struct sl *sl, const uint t){ psw_t flags; spin_lock_irqsave(&sl->lock, flags); { __sl_timer_stop(sl, t); } spin_unlock_irqrestore(&sl->lock, flags);}STATIC INLINE voidsl_timer_start(struct sl *sl, const uint t){ psw_t flags; spin_lock_irqsave(&sl->lock, flags); { __sl_timer_stop(sl, t); switch (t) { case t1: sl_start_timer_t1(sl); break; case t2: sl_start_timer_t2(sl); break; case t3: sl_start_timer_t3(sl); break; case t4: sl_start_timer_t4(sl); break; case t5: sl_start_timer_t5(sl); break; case t6: sl_start_timer_t6(sl); break; case t7: sl_start_timer_t7(sl); break; default: swerr(); break; } } spin_unlock_irqrestore(&sl->lock, flags);}/* * ------------------------------------------------------------------------- * * Duration Statistics * * ------------------------------------------------------------------------- */#if 0STATIC voidsl_is_stats(queue_t *q, struct sl *sl){ if (sl->stamp.sl_dur_unavail) sl->stats.sl_dur_unavail += jiffies - xchg(&sl->stamp.sl_dur_unavail, 0); if (sl->stamp.sl_dur_unavail_rpo) sl->stats.sl_dur_unavail_rpo += jiffies - xchg(&sl->stamp.sl_dur_unavail_rpo, 0); if (sl->stamp.sl_dur_unavail_failed) sl->stats.sl_dur_unavail_failed += jiffies - xchg(&sl->stamp.sl_dur_unavail_failed, 0); sl->stamp.sl_dur_in_service = jiffies;}STATIC voidsl_oos_stats(queue_t *q, struct sl *sl){ if (sl->stamp.sl_dur_in_service) sl->stats.sl_dur_in_service += jiffies - xchg(&sl->stamp.sl_dur_in_service, 0); if (sl->stamp.sl_dur_unavail_rpo) sl->stats.sl_dur_unavail_rpo += jiffies - xchg(&sl->stamp.sl_dur_unavail_rpo, 0); if (sl->stamp.sl_dur_unavail_failed) sl->stats.sl_dur_unavail_failed += jiffies - xchg(&sl->stamp.sl_dur_unavail_failed, 0); sl->stamp.sl_dur_unavail = jiffies;}STATIC voidsl_rpo_stats(queue_t *q, struct sl *sl){ if (sl->stamp.sl_dur_unavail_rpo) sl->stats.sl_dur_unavail_rpo += jiffies - xchg(&sl->stamp.sl_dur_unavail_rpo, 0);}STATIC voidsl_rpr_stats(queue_t *q, struct sl *sl){ if (sl->stamp.sl_dur_unavail_rpo) sl->stats.sl_dur_unavail_rpo += jiffies - xchg(&sl->stamp.sl_dur_unavail_rpo, 0);}#endif/* * ------------------------------------------------------------------------- * * SL State Machines * * ------------------------------------------------------------------------- */#define SN_OUTSIDE(lower,middle,upper) \ ( ( (lower) <= (upper) ) \ ? ( ( (middle) < (lower) ) || ( (middle) > (upper) ) ) \ : ( ( (middle) < (lower) ) && ( (middle) > (upper) ) ) \ )/* * ----------------------------------------------------------------------- * * STATE MACHINES:- The order of the state machine primitives below may seem * somewhat disorganized at first glance; however, they have been ordered by * dependency because they are all inline functions. You see, the L2 state * machine does not required multiple threading because there is never a * requirement to invoke the individual state machines concurrently. This * works out good for the driver, because a primitive action expands inline * to the necessary procedure, while the source still takes the appearance of * the SDL diagrams in the SS7 specification for inspection and debugging. * * ----------------------------------------------------------------------- */#define sl_cc_stop sl_cc_normalSTATIC INLINE voidsl_cc_normal(queue_t *q, struct sl *sl){ sl_timer_stop(sl, t5); sl->statem.cc_state = SL_STATE_IDLE;}STATIC INLINE voidsl_rc_stop(queue_t *q, struct sl *sl){ sl_cc_normal(q, sl); sl->statem.rc_state = SL_STATE_IDLE;}STATIC INLINE intsl_aerm_stop(queue_t *q, struct sl *sl){ return sdt_aerm_stop_req(q, sl);}STATIC INLINE intsl_iac_stop(queue_t *q, struct sl *sl){ int err; if (sl->statem.iac_state != SL_STATE_IDLE) { sl_timer_stop(sl, t3); sl_timer_stop(sl, t2); sl_timer_stop(sl, t4); if ((err = sl_aerm_stop(q, sl))) return (err); sl->statem.emergency = 0; sl->statem.iac_state = SL_STATE_IDLE; } return (QR_DONE);}STATIC streamscall void sl_tx_wakeup(queue_t *q);STATIC INLINE voidsl_daedt_transmitter_wakeup(queue_t *q, struct sl *sl){ if (sl->statem.txc_state == SL_STATE_SLEEPING) sl->statem.txc_state = SL_STATE_IN_SERVICE; sl_tx_wakeup(q);}STATIC INLINE voidsl_txc_send_sios(queue_t *q, struct sl *sl){ sl_timer_stop(sl, t7); if (sl->option.pvar == SS7_PVAR_ANSI_92) sl_timer_stop(sl, t6); sl->statem.lssu_available = 1; sl->statem.tx.sio = LSSU_SIOS; sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_poc_stop(queue_t *q, struct sl *sl){ sl->statem.poc_state = SL_STATE_IDLE;}STATIC INLINE intsl_suerm_stop(queue_t *q, struct sl *sl){ return sdt_suerm_stop_req(q, sl);}STATIC INLINE intsl_lsc_link_failure(queue_t *q, struct sl *sl, ulong reason){ int err; if (sl->statem.lsc_state != SL_STATE_OUT_OF_SERVICE) { if ((err = sl_out_of_service_ind(q, sl, reason))) return (err); sl->statem.failure_reason = reason; if ((err = sl_iac_stop(q, sl))) /* ok if not aligning */ return (err); sl_timer_stop(sl, t1); /* ok if not running */ if ((err = sl_suerm_stop(q, sl))) /* ok if not running */ return (err); sl_rc_stop(q, sl); sl_txc_send_sios(q, sl); sl_poc_stop(q, sl); /* ok if not ITUT */ sl->statem.emergency = 0; sl->statem.local_processor_outage = 0; sl->statem.remote_processor_outage = 0; /* ok if not ANSI */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -