📄 sdl_sctp.c
字号:
case DEV_IOCCIFLEADS: ret = -EOPNOTSUPP; break; } } else ret = -EINVAL; break; default: if ( q->q_next ) { putnext(q, mp); return(1); } ret = -EOPNOTSUPP; break; } if ( ret >= 0 ) { mp->b_datap->db_type = M_IOCACK; iocp->ioc_error = 0; iocp->ioc_rval = 0; } else { seldom(); mp->b_datap->db_type = M_IOCNAK; iocp->ioc_error = -ret; iocp->ioc_rval = -1; } qreply(q, mp); return(1);}/* * ------------------------------------------------------------------------- * * M_ERROR Handling * * ------------------------------------------------------------------------- */static intsdl_r_error(queue_t *q, mblk_t *mp){ ensure( q, return(-EFAULT) ); ensure( mp, return(-EFAULT) ); putnext(q, mp); return(1);}/* * ------------------------------------------------------------------------- * * M_FLUSH Handling * * ------------------------------------------------------------------------- */static intsdl_m_flush(queue_t *q, mblk_t *mp, const uint8_t mflag){ ensure( q, return(-EFAULT) ); ensure( mp, return(-EFAULT) ); if ( *mp->b_rptr & mflag ) { if ( *mp->b_rptr & FLUSHBAND ) flushband(q, mp->b_rptr[1], FLUSHALL); else flushq(q, FLUSHALL); } putnext(q, mp); return(1);}static intsdl_w_flush(queue_t *q, mblk_t *mp){ ensure( q, return(-EFAULT) ); ensure( mp, return(-EFAULT) ); return sdl_m_flush(q, mp, FLUSHW);}static intsdl_r_flush(queue_t *q, mblk_t *mp){ ensure( q, return(-EFAULT) ); ensure( mp, return(-EFAULT) ); return sdl_m_flush(q, mp, FLUSHR);}/* * ------------------------------------------------------------------------- * * Other messages (e.g. M_IOCACK) * * ------------------------------------------------------------------------- */static intsdl_m_other(queue_t *q, mblk_t *mp){ rare(); ensure( q, return(-EFAULT) ); ensure( mp, return(-EFAULT) ); if ( mp->b_datap->db_type >= QPCTL || bcanputnext(q, mp->b_band) ) { putnext(q, mp); return(1); } else return(-EBUSY);}/* * ========================================================================= * * PUT and SRV * * ========================================================================= *//* * SDL Write Put and Service */static INTsdl_wput(queue_t *q, mblk_t *mp){ int rtn; sdl_t *sp; ensure( q, return((INT)(-EFAULT)) ); sp = (sdl_t *)q->q_ptr; ensure( sp, return((INT)(-EFAULT)) ); ensure( mp, return((INT)(-EFAULT)) ); if ( mp->b_datap->db_type < QPCTL && q->q_count ) { seldom(); putq(q, mp); return(INT)(0); } switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sdl_w_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = sdl_w_proto(q, mp); break; case M_FLUSH: rtn = sdl_w_flush(q, mp); break; case M_IOCTL: rtn = sdl_w_ioctl(q, mp); break; default: rtn = sdl_m_other(q, mp); break; } switch ( rtn ) { case 0: assert(mp->b_datap->db_ref); freemsg(mp); case 1: break; case 2: assert(mp->b_datap->db_ref); freeb(mp); break; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); putq(q, mp); return(INT)(0); default: rare(); ptrace(("Error = %d\n", rtn)); assert(mp->b_datap->db_ref); freemsg(mp); return(INT)(rtn); } return(INT)(0);}static INTsdl_wsrv(queue_t *q){ int rtn; mblk_t *mp; sdl_t *sp; ensure( q, return((INT)(-EFAULT)) ); sp = (sdl_t *)q->q_ptr; ensure( sp, return((INT)(-EFAULT)) ); while ( (mp = getq(q)) ) { switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sdl_w_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = sdl_w_proto(q, mp); break; case M_FLUSH: rtn = sdl_w_flush(q, mp); break; case M_IOCTL: rtn = sdl_w_ioctl(q, mp); break; default: rtn = sdl_m_other(q, mp); break; } switch ( rtn ) { case 0: assert(mp->b_datap->db_ref); freemsg(mp); case 1: continue; case 2: assert(mp->b_datap->db_ref); freeb(mp); continue; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return(INT)(0); } __ptrace(("This should never happen!\n")); if ( mp->b_datap->db_type == M_PCPROTO ) { mp->b_datap->db_type = M_PROTO; putq(q, mp); return(INT)(0); } default: rare(); ptrace(("Error = %d\n", rtn)); assert(mp->b_datap->db_ref); freemsg(mp); continue; } } return(INT)(0);}/* * SCTP Read Put and Service */static INTsdl_rput(queue_t *q, mblk_t *mp){ int rtn; sdl_t *sp; ensure( q, return((INT)(-EFAULT)) ); sp = (sdl_t *)q->q_ptr; ensure( sp, return((INT)(-EFAULT)) ); ensure( mp, return((INT)(-EFAULT)) ); if ( mp->b_datap->db_type < QPCTL && q->q_count ) { seldom(); putq(q, mp); return(INT)(0); } switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sdl_r_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = sdl_r_proto(q, mp); break;// case M_CTL: rtn = sdl_r_ctl (q, mp); break; case M_ERROR: rtn = sdl_r_error(q, mp); break; case M_FLUSH: rtn = sdl_r_flush(q, mp); break; default: rtn = sdl_m_other(q, mp); break; } switch ( rtn ) { case 0: assert(mp->b_datap->db_ref); freemsg(mp); case 1: break; case 2: assert(mp->b_datap->db_ref); freeb(mp); break; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); putq(q, mp); return(INT)(0); default: rare(); ptrace(("Error = %d\n", rtn)); assert(mp->b_datap->db_ref); freemsg(mp); return(INT)(rtn); } return(INT)(0);}static INTsdl_rsrv(queue_t *q){ int rtn; mblk_t *mp; sdl_t *sp; ensure( q, return((INT)(-EFAULT)) ); sp = (sdl_t *)q->q_ptr; ensure( sp, return((INT)(-EFAULT)) ); while ( (mp = getq(q)) ) { switch ( mp->b_datap->db_type ) { case M_DATA: rtn = sdl_r_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = sdl_r_proto(q, mp); break;// case M_CTL: rtn = sdl_r_ctl (q, mp); break; case M_ERROR: rtn = sdl_r_error(q, mp); break; case M_FLUSH: rtn = sdl_r_flush(q, mp); break; default: rtn = sdl_m_other(q, mp); break; } switch ( rtn ) { case 0: assert(mp->b_datap->db_ref); freemsg(mp); case 1: continue; case 2: assert(mp->b_datap->db_ref); freeb(mp); continue; case -ENOBUFS: /* should set up bufcall */ case -EBUSY: case -EAGAIN: case -ENOMEM: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return(INT)(0); } __ptrace(("This should never happen!\n")); if ( mp->b_datap->db_type == M_PCPROTO ) { mp->b_datap->db_type = M_PROTO; putq(q, mp); return(INT)(0); } default: rare(); ptrace(("Error = %d\n", rtn)); assert(mp->b_datap->db_ref); freemsg(mp); continue; } } return(INT)(0);}/* * ========================================================================= * * Private Structure allocation, deallocation and cache * * ========================================================================= */kmem_cache_t *sdl_cachep = NULL;static voidsdl_init_caches(void){ if ( !sdl_cachep ) if ( !(sdl_cachep = kmem_find_general_cachep(sizeof(sdl_t))) ) if ( !(sdl_cachep = kmem_cache_create( "sdl_cachep", sizeof(sdl_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL)) ) panic(__FUNCTION__ ":Cannot alloc sdl_cachep.\n"); return;}static voidsdl_term_caches(void){ /* * We could try to shrink the caches byt that was a very bad idea * last time I tried (crashed kernel) so I won't do it here. */}static sdl_t *sdl_alloc_priv(queue_t *q){ sdl_t *sp; ensure( q, return(NULL) ); if ( (sp = kmem_cache_alloc(sdl_cachep, SLAB_ATOMIC)) ) { bzero(sp, sizeof(*sp)); RD(q)->q_ptr = WR(q)->q_ptr = sp; sp->rq = RD(q); sp->wq = WR(q); sp->state = LMI_DISABLED; } return(sp);}static voidsdl_free_priv(queue_t *q){ sdl_t *sp; ensure( q, return ); sp = (sdl_t *)q->q_ptr; ensure( sp, return ); untimeout(xchg(&sp->timer_tick,0)); freemsg(xchg(&sp->rx_buf,NULL)); freemsg(xchg(&sp->tx_buf,NULL)); kmem_cache_free(sdl_cachep, sp); return;}/* * ========================================================================= * * OPEN and CLOSE * * ========================================================================= */static intsdl_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){ (void)crp; /* for now */ if ( q->q_ptr != NULL ) /* already open */ return(0); if ( sflag == MODOPEN || WR(q)->q_next != NULL ) {// fixme(("Check module we are being pushed over.\n")); if ( !(sdl_alloc_priv(q)) ) return ENOMEM; return(0); } return EIO;}static intsdl_close(queue_t *q, int flag, cred_t *crp){ (void)flag; (void)crp; sdl_free_priv(q); return(0);}/* * ========================================================================= * * Lis Module Initialization * * ========================================================================= */voidsdl_init(void){ int modnum; unless( sdl_minfo.mi_idnum, return ); cmn_err(CE_NOTE, SDL_BANNER); /* console splash */ sdl_init_caches(); if ( !(modnum = lis_register_strmod(&sdl_info, sdl_minfo.mi_idname)) ) { sdl_minfo.mi_idnum = 0; rare(); cmn_err(CE_NOTE, "sdl: couldn't register as module\n"); return; } sdl_minfo.mi_idnum = modnum; return;}voidsdl_terminate(void){ ensure( sdl_minfo.mi_idnum, return ); if ( (sdl_minfo.mi_idnum = lis_unregister_strmod(&sdl_info)) ) cmn_err(CE_WARN, "sdl: couldn't unregister as module!\n"); sdl_term_caches(); return;}/* * ========================================================================= * * Kernel Module Initialization * * ========================================================================= */int init_module(void){ sdl_init(); return(0);}void cleanup_module(void){ sdl_terminate(); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -