📄 m2pa_sdl.c
字号:
{ case __SID: switch ( cmd ) { default: ptrace(("Unknown IOCTL %x\n",cmd)); case I_STR: case I_LINK: case I_PLINK: case I_UNLINK: case I_PUNLINK: rare(); (void)lp; ret = -EINVAL; break; } ret = -EOPNOTSUPP; break; case SDL_IOC_MAGIC: if ( count >= size ) { switch ( cmd ) { case SDL_IOCGOPTIONS: ret = sdl_iocgoptions(q, cmd, arg); break; case SDL_IOCSOPTIONS: ret = sdl_iocsoptions(q, cmd, arg); break; case SDL_IOCGCONFIG: ret = sdl_iocgconfig (q, cmd, arg); break; case SDL_IOCSCONFIG: ret = sdl_iocsconfig (q, cmd, arg); break; default: case SDL_IOCTCONFIG: case SDL_IOCCCONFIG: case SDL_IOCGSTATEM: case SDL_IOCCMRESET: case SDL_IOCGSTATSP: case SDL_IOCSSTATSP: case SDL_IOCGSTATS: case SDL_IOCCSTATS: case SDL_IOCGNOTIFY: case SDL_IOCSNOTIFY: case SDL_IOCCNOTIFY: ret = -EOPNOTSUPP; break; } } else ret = -EINVAL; break; case DEV_IOC_MAGIC: if ( count >= size ) { switch ( cmd ) { case DEV_IOCSIFCLOCK: ret = dev_iocsifclock(q, cmd, arg); break; case DEV_IOCGIFCLOCK: ret = dev_iocgifclock(q, cmd, arg); break; case DEV_IOCCDISCTX: ret = dev_ioccdisctx (q, cmd, arg); break; case DEV_IOCCCONNTX: ret = dev_ioccconntx (q, cmd, arg); break; default: case DEV_IOCCIFRESET: case DEV_IOCGIFFLAGS: case DEV_IOCSIFFLAGS: case DEV_IOCGIFTYPE: case DEV_IOCSIFTYPE: case DEV_IOCGGRPTYPE: case DEV_IOCSGRPTYPE: case DEV_IOCGIFMODE: case DEV_IOCSIFMODE: case DEV_IOCGIFRATE: case DEV_IOCSIFRATE: case DEV_IOCGIFCODING: case DEV_IOCSIFCODING: case DEV_IOCGIFLEADS: case DEV_IOCSIFLEADS: 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 intm2pa_r_error(queue_t *q, mblk_t *mp){ putnext(q, mp); return(1);}/* * ------------------------------------------------------------------------- * * M_FLUSH Handling * * ------------------------------------------------------------------------- */static intm2pa_m_flush(queue_t *q, mblk_t *mp, const uint8_t mflag){ 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 intm2pa_w_flush(queue_t *q, mblk_t *mp){ return m2pa_m_flush(q, mp, FLUSHW);}static intm2pa_r_flush(queue_t *q, mblk_t *mp){ return m2pa_m_flush(q, mp, FLUSHR);}/* * ------------------------------------------------------------------------- * * Other messages (e.g. M_IOCACK) * * ------------------------------------------------------------------------- */static intm2pa_m_other(queue_t *q, mblk_t *mp){ rare(); 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 INTm2pa_wput(queue_t *q, mblk_t *mp){ int rtn; m2pa_t *m2 = (m2pa_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( m2, 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 = m2pa_w_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = m2pa_w_proto(q, mp); break; case M_FLUSH: rtn = m2pa_w_flush(q, mp); break; case M_IOCTL: rtn = m2pa_w_ioctl(q, mp); break; default: rtn = m2pa_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 INTm2pa_wsrv(queue_t *q){ int rtn; mblk_t *mp; m2pa_t *m2 = (m2pa_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( m2, return((INT)(-EFAULT)) ); while ( (mp = getq(q)) ) { switch ( mp->b_datap->db_type ) { case M_DATA: rtn = m2pa_w_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = m2pa_w_proto(q, mp); break; case M_FLUSH: rtn = m2pa_w_flush(q, mp); break; case M_IOCTL: rtn = m2pa_w_ioctl(q, mp); break; default: rtn = m2pa_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); } 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 INTm2pa_rput(queue_t *q, mblk_t *mp){ int rtn; m2pa_t *m2 = (m2pa_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( m2, 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 = m2pa_r_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = m2pa_r_proto(q, mp); break; case M_CTL: rtn = m2pa_r_ctl (q, mp); break; case M_ERROR: rtn = m2pa_r_error(q, mp); break; case M_FLUSH: rtn = m2pa_r_flush(q, mp); break; default: rtn = m2pa_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 INTm2pa_rsrv(queue_t *q){ int rtn; mblk_t *mp; m2pa_t *m2 = (m2pa_t *)q->q_ptr; ensure( q, return((INT)(-EFAULT)) ); ensure( m2, return((INT)(-EFAULT)) ); while ( (mp = getq(q)) ) { switch ( mp->b_datap->db_type ) { case M_DATA: rtn = m2pa_r_data (q, mp); break; case M_PROTO: case M_PCPROTO: rtn = m2pa_r_proto(q, mp); break; case M_CTL: rtn = m2pa_r_ctl (q, mp); break; case M_ERROR: rtn = m2pa_r_error(q, mp); break; case M_FLUSH: rtn = m2pa_r_flush(q, mp); break; default: rtn = m2pa_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); } 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 *m2pa_cachep = NULL;static voidm2pa_init_caches(void){ if ( !m2pa_cachep ) if ( !(m2pa_cachep = kmem_find_general_cachep(sizeof(m2pa_t))) ) if ( !(m2pa_cachep = kmem_cache_create( "m2pa_cachep", sizeof(m2pa_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL)) ) panic(__FUNCTION__ ":Cannot alloc m2pa_cachep.\n"); return;}static voidm2pa_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 m2pa_t *m2pa_alloc_priv(queue_t *q){ m2pa_t *m2; if ( (m2 = kmem_cache_alloc(m2pa_cachep, SLAB_ATOMIC)) ) { bzero(m2, sizeof(*m2)); RD(q)->q_ptr = WR(q)->q_ptr = m2; m2->rq = RD(q); m2->wq = WR(q); m2->version = M2PA_VERSION_DEFAULT; m2->fsnr = -1; m2->bsnr = -1; m2->fsnt = -1; m2->bsnt = -1; m2->bsna = -1; m2->state = LMI_DISABLED; } return(m2);}static voidm2pa_free_priv(queue_t *q){ m2pa_t *m2 = (m2pa_t *)q->q_ptr; untimeout(xchg(&m2->timer_rx_sib,0)); untimeout(xchg(&m2->timer_tx_sib,0)); kmem_cache_free(m2pa_cachep, m2); return;}/* * ========================================================================= * * OPEN and CLOSE * * ========================================================================= */static intm2pa_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 ( !(m2pa_alloc_priv(q)) ) return ENOMEM; return(0); } return EIO;}static intm2pa_close(queue_t *q, int flag, cred_t *crp){ (void)flag; (void)crp; m2pa_free_priv(q); return(0);}/* * ========================================================================= * * Lis Module Initialization * * ========================================================================= */voidm2pa_init(void){ int modnum; unless( m2pa_minfo.mi_idnum, return ); cmn_err(CE_NOTE, M2PA_BANNER); /* console splash */ m2pa_init_caches(); if ( !(modnum = lis_register_strmod(&m2pa_info, m2pa_minfo.mi_idname)) ) { m2pa_minfo.mi_idnum = 0; rare(); cmn_err(CE_NOTE, "m2pa: couldn't register as module\n"); return; } m2pa_minfo.mi_idnum = modnum; return;}voidm2pa_terminate(void){ ensure( m2pa_minfo.mi_idnum, return ); if ( (m2pa_minfo.mi_idnum = lis_unregister_strmod(&m2pa_info)) ) cmn_err(CE_WARN, "m2pa: couldn't unregister as module!\n"); m2pa_term_caches(); return;}/* * ========================================================================= * * Kernel Module Initialization * * ========================================================================= */int init_module(void){ m2pa_init(); return(0);}void cleanup_module(void){ m2pa_terminate(); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -