📄 x400p-ss7.c
字号:
return (-ENOBUFS);}#endif/* * LMI_INFO_ACK * ----------------------------------- */STATIC INLINE intlmi_info_ack(queue_t *q, struct xp *xp, caddr_t ppa_ptr, size_t ppa_len){ mblk_t *mp; lmi_info_ack_t *p; if ((mp = ss7_allocb(q, sizeof(*p) + ppa_len, BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_INFO_ACK; p->lmi_version = 1; p->lmi_state = xp->i_state; p->lmi_max_sdu = 0; /* FIXME: fill these out */ p->lmi_min_sdu = 0; /* FIXME: fill these out */ p->lmi_header_len = 0; p->lmi_ppa_style = LMI_STYLE2; bcopy(ppa_ptr, mp->b_wptr, ppa_len); mp->b_wptr += ppa_len; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * LMI_OK_ACK * ----------------------------------- */STATIC INLINE intlmi_ok_ack(queue_t *q, struct xp *xp, ulong state, long prim){ mblk_t *mp; lmi_ok_ack_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->lmi_primitive = LMI_OK_ACK; p->lmi_correct_primitive = prim; p->lmi_state = xp->i_state = state; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * LMI_ERROR_ACK * ----------------------------------- */STATIC INLINE intlmi_error_ack(queue_t *q, struct xp *xp, ulong state, long prim, ulong errno, ulong reason){ mblk_t *mp; lmi_error_ack_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->lmi_primitive = LMI_ERROR_ACK; p->lmi_errno = errno; p->lmi_reason = reason; p->lmi_error_primitive = prim; p->lmi_state = xp->i_state = state; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * LMI_ENABLE_CON * ----------------------------------- */STATIC INLINE intlmi_enable_con(queue_t *q, struct xp *xp){ mblk_t *mp; lmi_enable_con_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->lmi_primitive = LMI_ENABLE_CON; p->lmi_state = xp->i_state = LMI_ENABLED; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * LMI_DISABLE_CON * ----------------------------------- */STATIC INLINE intlmi_disable_con(queue_t *q, struct xp *xp){ mblk_t *mp; lmi_disable_con_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->lmi_primitive = LMI_DISABLE_CON; p->lmi_state = xp->i_state = LMI_DISABLED; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}#if 0/* * LMI_OPTMGMT_ACK * ----------------------------------- */STATIC INLINE intlmi_optmgmt_ack(queue_t *q, struct xp *xp, ulong flags, caddr_t opt_ptr, size_t opt_len){ mblk_t *mp; lmi_optmgmt_ack_t *p; if ((mp = ss7_allocb(q, sizeof(*p) + opt_len, BPRI_MED))) { mp->b_datap->db_type = M_PCPROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_OPTMGMT_ACK; p->lmi_opt_length = opt_len; p->lmi_opt_offset = opt_len ? sizeof(*p) : 0; p->lmi_mgmt_flags = flags; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * LMI_ERROR_IND * ----------------------------------- */STATIC INLINE intlmi_error_ind(queue_t *q, struct xp *xp, ulong errno, ulong reason){ mblk_t *mp; lmi_error_ind_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->lmi_primitive = LMI_ERROR_IND; p->lmi_errno = errno; p->lmi_reason = reason; p->lmi_state = xp->i_state; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS);}/* * LMI_STATS_IND * ----------------------------------- */STATIC INLINE intlmi_stats_ind(queue_t *q, struct xp *xp, ulong interval){ if (canputnext(xp->oq)) { mblk_t *mp; lmi_stats_ind_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_STATS_IND; p->lmi_interval = interval; p->lmi_timestamp = jiffies; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS); } rare(); return (-EBUSY);}/* * LMI_EVENT_IND * ----------------------------------- */STATIC INLINE intlmi_event_ind(queue_t *q, struct xp *xp, ulong oid, ulong level){ if (canputnext(xp->oq)) { mblk_t *mp; lmi_event_ind_t *p; if ((mp = ss7_allocb(q, sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PROTO; p = (typeof(p)) mp->b_wptr; mp->b_wptr += sizeof(*p); p->lmi_primitive = LMI_EVENT_IND; p->lmi_objectid = oid; p->lmi_timestamp = jiffies; p->lmi_severity = level; ss7_oput(xp->oq, mp); return (QR_DONE); } rare(); return (-ENOBUFS); } rare(); return (-EBUSY);}#endif/* * ========================================================================= * * PROTOCOL STATE MACHINE FUNCTIONS * * ========================================================================= *//* * ------------------------------------------------------------------------ * * Default Configuration * * ------------------------------------------------------------------------ */STATIC sdl_config_t sdl_default_e1_chan = { ifname:NULL, ifflags:0, iftype:SDL_TYPE_DS0, ifrate:64000, ifgtype:SDL_GTYPE_E1, ifgrate:2048000, ifmode:SDL_MODE_PEER, ifgmode:SDL_GMODE_NONE, ifgcrc:SDL_GCRC_CRC5, ifclock:SDL_CLOCK_SLAVE, ifcoding:SDL_CODING_HDB3, ifframing:SDL_FRAMING_CCS, ifblksize:8, ifleads:0, ifbpv:0, ifalarms:0, ifrxlevel:0, iftxlevel:0, ifsync:0, ifsyncsrc:{0, 0, 0, 0}};STATIC sdl_config_t sdl_default_t1_chan = { ifname:NULL, ifflags:0, iftype:SDL_TYPE_DS0, ifrate:64000, ifgtype:SDL_GTYPE_T1, ifgrate:1544000, ifmode:SDL_MODE_PEER, ifgmode:SDL_GMODE_NONE, ifgcrc:SDL_GCRC_CRC6, ifclock:SDL_CLOCK_SLAVE, ifcoding:SDL_CODING_AMI, ifframing:SDL_FRAMING_SF, ifblksize:8, ifleads:0, ifbpv:0, ifalarms:0, ifrxlevel:0, iftxlevel:0, ifsync:0, ifsyncsrc:{0, 0, 0, 0}};/* * ------------------------------------------------------------------------ * * Timers * * ------------------------------------------------------------------------ *//* * ======================================================================== * * Events from below * * ======================================================================== *//* * ========================================================================= * * EVENTS From Above * * ========================================================================= *//* * M_DATA * ----------------------------------- */STATIC intsdl_m_data(queue_t *q, mblk_t *mp){ struct xp *xp = XP_PRIV(q); struct sp *sp; struct ts *ts; int chan, slot; if (xp->i_state != LMI_ENABLED) goto eproto; if (!(sp = xp->sp)) goto efault; if (!(chan = xp->chan)) goto efault; if (xp->obj.sdl.config.ifgtype == SDL_GTYPE_E1) { if (chan < 1 || chan > 31) goto efault; slot = xp_e1_chan_map[chan]; } else { if (chan < 1 || chan > 24) goto efault; slot = xp_t1_chan_map[chan]; } if (!(ts = sp->slots[slot])) goto efault; if (ts->tx.buf.q_count > 64) goto ebusy; bufq_queue(&ts->tx.buf, mp); switch (xp->obj.sdl.config.iftype) { case SDL_TYPE_E1: if (++xp->chan > 31) xp->chan = 1; break; case SDL_TYPE_T1: if (++xp->chan > 24) xp->chan = 1; break; } return (QR_ABSORBED); ebusy: return (-EBUSY); efault: return m_error(q, xp, EFAULT); eproto: return m_error(q, xp, EPROTO);}/* * SDL_BITS_FOR_TRANSMISSION_REQ * ----------------------------------- * Non-preferred method. Normally one should just send M_DATA blocks. We * just strip off the redundant M_PROTO and put it on the queue. */STATIC intsdl_bits_for_transmission_req(queue_t *q, mblk_t *mp){ (void) q; (void) mp; return (QR_STRIP);}/* * SDL_CONNECT_REQ * ----------------------------------- */STATIC intsdl_connect_req(queue_t *q, mblk_t *mp){ struct xp *xp = XP_PRIV(q); psw_t flags; sdl_connect_req_t *p = (typeof(p)) mp->b_rptr; if (mp->b_wptr < mp->b_rptr + sizeof(*p)) goto eproto; if (xp->i_state != LMI_ENABLED) goto eproto; spin_lock_irqsave(&xp->lock, flags); { if (p->sdl_flags & SDL_RX_DIRECTION) { xp->obj.sdl.config.ifflags |= SDL_IF_RX_RUNNING; xp->obj.sdl.statem.rx_state = SDL_STATE_IN_SERVICE; ptrace(("%p: Enabling Rx\n", xp)); } if (p->sdl_flags & SDL_TX_DIRECTION) { xp->obj.sdl.config.ifflags |= SDL_IF_TX_RUNNING; xp->obj.sdl.statem.tx_state = SDL_STATE_IN_SERVICE; ptrace(("%p: Enabling Tx\n", xp)); } if ((xp->obj.sdl.config.ifflags & (SDL_IF_TX_RUNNING | SDL_IF_RX_RUNNING))) { ptrace(("%p: Marking interface up\n", xp)); xp->obj.sdl.config.ifflags |= SDL_IF_UP; } } spin_unlock_irqrestore(&xp->lock, flags); return (QR_DONE); eproto: return m_error(q, xp, EPROTO);}/* * SDL_DISCONNECT_REQ * ----------------------------------- */STATIC intsdl_disconnect_req(queue_t *q, mblk_t *mp){ struct xp *xp = XP_PRIV(q); psw_t flags; sdl_disconnect_req_t *p = (typeof(p)) mp->b_rptr; if (mp->b_wptr < mp->b_rptr + sizeof(*p)) goto eproto; if (xp->i_state != LMI_ENABLED) goto eproto; spin_lock_irqsave(&xp->lock, flags); { if (p->sdl_flags & SDL_RX_DIRECTION) { xp->obj.sdl.config.ifflags &= ~SDL_IF_RX_RUNNING; xp->obj.sdl.statem.rx_state = SDL_STATE_IDLE; ptrace(("%p: Disabling Rx\n", xp)); } if (p->sdl_flags & SDL_TX_DIRECTION) { xp->obj.sdl.config.ifflags &= ~SDL_IF_TX_RUNNING; xp->obj.sdl.statem.tx_state = SDL_STATE_IDLE; ptrace(("%p: Disabling Tx\n", xp)); } if (!(xp->obj.sdl.config.ifflags & (SDL_IF_TX_RUNNING | SDL_IF_RX_RUNNING))) { ptrace(("%p: Marking interface down\n", xp)); xp->obj.sdl.config.ifflags &= ~SDL_IF_UP; } } spin_unlock_irqrestore(&xp->lock, flags); return (QR_DONE); eproto: return m_error(q, xp, EPROTO);}/* * LMI_INFO_REQ * ----------------------------------- */STATIC intlmi_info_req(queue_t *q, mblk_t *mp){ struct xp *xp = XP_PRIV(q); switch (xp->i_state) { case LMI_ENABLED: case LMI_DISABLED: { struct sp *sp; struct cd *cd; if ((sp = xp->sp) && (cd = sp->cd)) { uint16_t ppa = (xp-> chan & 0xff) | ((sp->span & 0x0f) << 8) | ((cd->card & 0x0f) << 12); return lmi_info_ack(q, xp, (caddr_t) &ppa, sizeof(ppa)); } } } return lmi_info_ack(q, xp, NULL, 0);}/* * LMI_ATTACH_REQ * ----------------------------------- */STATIC intlmi_attach_req(queue_t *q, mblk_t *mp){ psw_t flags = 0; int err, card, span, chan, slot; struct cd *cd; struct sp *sp = NULL; uint16_t ppa; struct xp *xp = XP_PRIV(q); lmi_attach_req_t *p = ((typeof(p)) mp->b_rptr); if (mp->b_wptr - mp->b_rptr < sizeof(*p) + sizeof(ppa)) { ptrace(("%s: ERROR: primitive too small = %d bytes\n", DRV_NAME, mp->b_wptr - mp->b_rptr)); goto lmi_badprim; } if (xp->i_state != LMI_UNATTACHED) { ptrace(("%s: ERROR: interface out of state\n", DRV_NAME)); goto lmi_outstate; } xp->i_state = LMI_ATTACH_PENDING; ppa = *(typeof(ppa) *) (p + 1); /* check card */ card = (ppa >> 12) & 0x0f; for (cd = x400p_cards; cd && cd->card != card; cd = cd->next) ; if (!cd) { ptrace(("%s: ERROR: invalid card %d\n", DRV_NAME, card)); goto lmi_badppa; } /* check span */ span = (ppa >> 8) & 0x0f; if (span < 0 || span > X400_SPANS - 1) { ptrace(("%s: ERROR: invalid span %d\n", DRV_NAME, span)); goto lmi_badppa; } if (!(sp = cd->spans[span])) { ptrace(("%s: ERROR: unallocated span %d\n", DRV_NAME, span)); goto lmi_badppa; } if (sp->config.ifgtype != SDL_GTYPE_E1 && sp->config.ifgtype != SDL_GTYPE_T1) { swerr(); goto efault; } /* check chan */ chan = (ppa >> 0) & 0xff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -