📄 slpmod.c
字号:
sl_set_i_state(sl, loc, SL_OUT_OF_SERVICE); return sl_out_of_service_ind(sl, loc, q, NULL, 0); outstate: return (0);}static intsl_data(queue_t *q, mblk_t *mp){ if (bcanputnext(q, mp->b_band)) { putnext(q, mp); return (0); } return (-EBUSY);}static intsl_proto(queue_t *q, mblk_t *mp){ struct sl *sl = SL_PRIV(q); struct lk *loc = SL_LOC_PRIV(sl, q); struct lk *rem = SL_REM_PRIV(sl, q); int rtn; if (mp->b_wptr < mp->b_rptr + sizeof(sl_ulong)) { freemsg(mp); return (0); } if (!sl_trylock(q)) return (-EDEADLK); loc->oldstate = loc->state; rem->oldstate = loc->state; switch (*(sl_ulong *) mp->b_rptr) { case LMI_INFO_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> LMI_INFO_REQ"); rtn = lmi_info_req(sl, loc, q, mp); break; case LMI_ATTACH_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> LMI_ATTACH_REQ"); rtn = lmi_attach_req(sl, loc, q, mp); break; case LMI_DETACH_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> LMI_DETACH_REQ"); rtn = lmi_detach_req(sl, loc, q, mp); break; case LMI_ENABLE_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> LMI_ENABLE_REQ"); rtn = lmi_enable_req(sl, loc, q, mp); break; case LMI_DISABLE_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> LMI_DISABLE_REQ"); rtn = lmi_disable_req(sl, loc, q, mp); break; case LMI_OPTMGMT_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> LMI_OPTMGMT_REQ"); rtn = lmi_optmgmt_req(sl, loc, q, mp); break; case SL_PDU_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_PDU_REQ"); rtn = sl_pdu_req(sl, loc, q, mp); break; case SL_EMERGENCY_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_EMERGENCY_REQ"); rtn = sl_emergency_req(sl, loc, q, mp); break; case SL_EMERGENCY_CEASES_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_EMERGENCY_CEASES_REQ"); rtn = sl_emergency_ceases_req(sl, loc, q, mp); break; case SL_START_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_START_REQ"); rtn = sl_start_req(sl, loc, q, mp); break; case SL_STOP_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_STOP_REQ"); rtn = sl_stop_req(sl, loc, q, mp); break; case SL_RETRIEVE_BSNT_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_RETRIEVE_BSNT_REQ"); rtn = sl_retrieve_bsnt_req(sl, loc, q, mp); break; case SL_RETRIEVAL_REQUEST_AND_FSNC_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_RETRIEVAL_REQUEST_AND_FSNC_REQ"); rtn = sl_retrieval_request_and_fsnc_req(sl, loc, q, mp); break; case SL_CLEAR_BUFFERS_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_CLEAR_BUFFERS_REQ"); rtn = sl_clear_buffers_req(sl, loc, q, mp); break; case SL_CLEAR_RTB_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_CLEAR_RTB_REQ"); rtn = sl_clear_rtb_req(sl, loc, q, mp); break; case SL_CONTINUE_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_CONTINUE_REQ"); rtn = sl_continue_req(sl, loc, q, mp); break; case SL_LOCAL_PROCESSOR_OUTAGE_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_LOCAL_PROCESSOR_OUTAGE_REQ"); rtn = sl_local_processor_outage_req(sl, loc, q, mp); break; case SL_RESUME_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_RESUME_REQ"); rtn = sl_resume_req(sl, loc, q, mp); break; case SL_CONGESTION_DISCARD_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_CONGESTION_DISCARD_REQ"); rtn = sl_congestion_discard_req(sl, loc, q, mp); break; case SL_CONGESTION_ACCEPT_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_CONGESTION_ACCEPT_REQ"); rtn = sl_congestion_accept_req(sl, loc, q, mp); break; case SL_NO_CONGESTION_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_NO_CONGESTION_REQ"); rtn = sl_no_congestion_req(sl, loc, q, mp); break; case SL_POWER_ON_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_POWER_ON_REQ"); rtn = sl_power_on_req(sl, loc, q, mp); break; case SL_OPTMGMT_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_OPTMGMT_REQ"); rtn = sl_optmgmt_req(sl, loc, q, mp); break; case SL_NOTIFY_REQ: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_NOTIFY_REQ"); rtn = sl_notify_req(sl, loc, q, mp); break; default: strlog(sl->mid, sl->sid, SLLOGRX, SL_TRACE, "-> SL_????_???"); rtn = sl_other_req(sl, loc, q, mp); break; } if (rtn != 0) { loc->state = loc->oldstate; rem->state = rem->oldstate; } sl_unlock(q); return (rtn);}static intsl_sig(queue_t *q, mblk_t *mp){ struct sl *sl = SL_PRIV(q); struct lk *loc = SL_LOC_PRIV(sl, q); struct lk *rem = SL_REM_PRIV(sl, q); int rtn; if (!sl_trylock(q)) return (-EDEADLK); if (!mi_timer_valid(mp)) return (0); loc->oldstate = loc->state; rem->oldstate = rem->state; switch (*(int *) mp->b_rptr) { case 1: strlog(sl->mid, sl->sid, SLLOGTO, SL_TRACE, "-> T1 TIMEOUT <-"); rtn = sl_t1_timeout(sl, loc, q); break; default: strlog(sl->mid, sl->sid, SLLOGTO, SL_TRACE, "-> ?? TIMEOUT <-"); rtn = 0; break; } if (rtn != 0) { loc->state = loc->oldstate; rem->state = rem->oldstate; } sl_unlock(q); return (rtn);}static intsl_ioctl(queue_t *q, mblk_t *mp){ mi_copy_done(q, mp, EINVAL); return (0);}static intsl_iocdata(queue_t *q, mblk_t *mp){ mi_copy_done(q, mp, EINVAL); return (0);}static intsl_flush(queue_t *q, mblk_t *mp){ if (mp->b_rptr[0] & FLUSHW) { if (mp->b_rptr[0] & FLUSHBAND) flushband(q, mp->b_rptr[1], FLUSHDATA); else flushq(q, FLUSHDATA); } /* pipemod style flush bit reversal */ switch (mp->b_rptr[0] & FLUSHRW) { case FLUSHW: mp->b_rptr[0] &= ~FLUSHW; mp->b_rptr[0] |= FLUSHR; break; case FLUSHR: mp->b_rptr[0] &= ~FLUSHR; mp->b_rptr[0] |= FLUSHW; break; } putnext(q, mp); return (0);}static intsl_other(queue_t *q, mblk_t *mp){ if (mp->b_datap->db_type >= QPCTL || bcanputnext(q, mp->b_band)) { putnext(q, mp); return (0); } return (-EBUSY);}static noinline fastcall intsl_msg_slow(queue_t *q, mblk_t *mp){ switch (mp->b_datap->db_type) { case M_DATA: return sl_data(q, mp); case M_PROTO: case M_PCPROTO: return sl_proto(q, mp); case M_SIG: case M_PCSIG: return sl_sig(q, mp); case M_IOCTL: return sl_ioctl(q, mp); case M_IOCDATA: return sl_iocdata(q, mp); case M_FLUSH: return sl_flush(q, mp); default: return sl_other(q, mp); }}static inline fastcall intsl_msg(queue_t *q, mblk_t *mp){ /* fastpath for data */ if (mp->b_datap->db_type == M_DATA) { if (bcanputnext(q, mp->b_band)) { putnext(q, mp); return (0); } return (-EBUSY); } if (mp->b_datap->db_type == M_PROTO) { if (mp->b_wptr >= mp->b_rptr + sizeof(sl_ulong)) { if (*(sl_ulong *) mp->b_rptr == SL_PDU_REQ) { if (bcanputnext(q, mp->b_band)) { *(sl_ulong *) mp->b_rptr = SL_PDU_IND; putnext(q, mp); return (0); } return (-EBUSY); } } } return sl_msg_slow(q, mp);}static streamscall __hot_in intsl_put(queue_t *q, mblk_t *mp){ if ((mp->b_datap->db_type < QPCTL && (q->q_first || (q->q_flag & QSVCBUSY))) || sl_msg(q, mp)) putq(q, mp); return (0);}static streamscall __hot_read intsl_srv(queue_t *q){ mblk_t *mp; while ((mp = getq(q))) { if (sl_msg(q, mp)) { putbq(q, mp); break; } } return (0);}static caddr_t sl_opens = NULL;static streamscall intsl_qopen(queue_t *q, dev_t *devp, int oflags, int sflag, cred_t *crp){ struct sl *sl; static int instance = 0; mblk_t *loc_tp, *rem_tp; int err; if (q->q_ptr) return (0); if (!(loc_tp = mi_timer_alloc(q, sizeof(int)))) return (ENOBUFS); *(int *) loc_tp->b_rptr = 1; if (!(rem_tp = mi_timer_alloc(WR(q), sizeof(int)))) { mi_timer_free(loc_tp); return (ENOBUFS); } *(int *) rem_tp->b_rptr = 1; if ((err = mi_open_comm(&sl_opens, sizeof(*sl), q, devp, oflags, sflag, crp))) { mi_timer_free(loc_tp); mi_timer_free(rem_tp); return (err); } sl = SL_PRIV(q); /* initialize sl structure */ sl->mid = q->q_qinfo->qi_minfo->mi_idnum; sl->sid = ++instance; sl->lock = SPIN_LOCK_UNLOCKED; sl->users = 0; sl->waitq = NULL; sl->rd.state.l_state = LMI_DISABLED; sl->rd.state.i_state = SL_POWER_OFF; sl->rd.state.i_flags = 0; sl->rd.oldstate.l_state = LMI_DISABLED; sl->rd.oldstate.i_state = SL_POWER_OFF; sl->rd.oldstate.i_flags = 0; sl->rd.t1 = loc_tp; sl->rd.other = &sl->wr; sl->rd.oq = RD(q); sl->wr.state.l_state = LMI_DISABLED; sl->wr.state.i_state = SL_POWER_OFF; sl->wr.state.i_flags = 0; sl->wr.oldstate.l_state = LMI_DISABLED; sl->wr.oldstate.i_state = SL_POWER_OFF; sl->wr.oldstate.i_flags = 0; sl->wr.t1 = rem_tp; sl->wr.other = &sl->rd; sl->wr.oq = WR(q); qprocson(q); return (0);}static streamscall intsl_qclose(queue_t *q, int oflags, cred_t *crp){ struct sl *sl = SL_PRIV(q); qprocsoff(q); mi_timer_free(XCHG(&sl->rd.t1, NULL)); mi_timer_free(XCHG(&sl->wr.t1, NULL)); mi_close_comm(&sl_opens, q); return (0);}static struct module_info sl_minfo = { .mi_idnum = MOD_ID, .mi_idname = MOD_NAME, .mi_minpsz = STRMINPSZ, .mi_maxpsz = STRMAXPSZ, .mi_hiwat = STRHIGH, .mi_lowat = STRLOW,};static struct module_stat sl_mstat __attribute__ ((aligned(SMP_CACHE_BYTES)));static struct qinit sl_rinit = { .qi_putp = sl_put, .qi_srvp = sl_srv, .qi_qopen = sl_qopen, .qi_qclose = sl_qclose, .qi_minfo = &sl_minfo, .qi_mstat = &sl_mstat,};static struct qinit sl_winit = { .qi_putp = sl_put, .qi_srvp = sl_srv, .qi_minfo = &sl_minfo, .qi_mstat = &sl_mstat,};static struct streamtab slpmodinfo = { .st_rdinit = &sl_rinit, .st_wrinit = &sl_winit,};static unsigned short modid = MOD_ID;#ifndef module_paramMODULE_PARM(modid, "h");#elsemodule_param(modid, ushort, 0);#endifMODULE_PARM_DESC(modid, "Module id for SLPMOD module. (0 for allocation.)");#ifdef LIS#define fmodsw _fmodsw#endifstatic struct fmodsw sl_fmod = { .f_name = MOD_NAME, .f_str = &slpmodinfo, .f_flag = D_MP, .f_kmod = THIS_MODULE,};static __init intslpmodinit(void){ int err; cmn_err(CE_NOTE, MOD_BANNER); if ((err = register_strmod(&sl_fmod)) < 0) { cmn_err(CE_WARN, "%s: could not regsiter module %d\n", MOD_NAME, (int) modid); return (err); } if (modid == 0) modid = err; return (0);}static __exit voidslpmodexit(void){ int err; if ((err = unregister_strmod(&sl_fmod)) < 0) { cmn_err(CE_WARN, "%s: could not unregister module, err = %d", MOD_NAME, err); return; } return;}module_init(slpmodinit);module_exit(slpmodexit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -