📄 m2pa_sdt.c
字号:
return m2pa_w_proto(q, mp);}static inline int m2pa_r_pcproto(queue_t *q, mblk_t *mp){ return m2pa_r_proto(q, mp);}/* * ------------------------------------------------------------------------- * * M_CTL Handling * * ------------------------------------------------------------------------- */static inline int m2pa_w_ctl(queue_t *q, mblk_t *mp){ (void)q; (void)mp; return(-EOPNOTSUPP);}static inline int m2pa_r_ctl(queue_t *q, mblk_t *mp){ (void)q; (void)mp; return(-EOPNOTSUPP);}/* * ------------------------------------------------------------------------- * * M_IOCTL Handling * * ------------------------------------------------------------------------- */static inline int m2pa_w_ioctl(queue_t *q, mblk_t *mp){ int ret; struct iocblk *iocp = (struct iocblk *)mp->b_rptr; int cmd = iocp->ioc_cmd; void *arg = mp->b_cont?mp->b_cont->b_rptr:NULL; int type = _IOC_TYPE(cmd); int nr = _IOC_NR(cmd); int size = _IOC_SIZE(cmd); switch ( type ) { case __SID: switch ( cmd ) { case I_LINK: case I_PLINK: case I_UNLINK: case I_PUNLINK: { struct linkblk *lp = (struct linkblk *)arg; (void)lp; } default: case I_FDINSERT: ret = -EINVAL; } break; case M2PA_IOC_MAGIC: if ( iocp->ioc_count >= size ) { if ( 0 <= nr && nr < sizeof(m2pa_ioctl)/sizeof(void *) ) { if ( m2pa_ioctl[nr] ) ret = (*m2pa_ioctl[nr])(q, cmd, arg); else ret = -EOPNOTSUPP; } } else return = -EINVAL; break; default: if ( q->q_next ) { putnext(q, mp); return(0); } ret = -EOPNOTSUPP; } } mp->b_datap->db_type = ret ? M_IOCNAK : M_IOCACK; iocp->ioc_error = -ret; iocp->ioc_rval = ret ? -1 : 0; qrepy(q, mp); return(0);}/* * ------------------------------------------------------------------------- * * M_FLUSH Handling * * ------------------------------------------------------------------------- */static inline void m2pa_w_flush(queue_t *q, mblk_t *mp){ if ( *mp->b_rptr & M_FLUSHW ) { flushq(q, FLUSHALL ); if ( q-q_next ) { putnext(q, mp); return; } *mp->b_rptr &= ~FLUSHW; } if ( *mp->b_rptr & FLUSHR ) { flushq(RD(q), FLUSHALL); qreply(q, mp); return; } if ( q->q_next ) { putnext(q, mp); return; }}/* * ------------------------------------------------------------------------- * * M_ERROR Handling * * ------------------------------------------------------------------------- */static inline void m2pa_r_error(queue_t *q, mblk_t *mp){ m2pa_t *m2 = (m2pa_t *)q->q_ptr; m2->zapped = 1; if ( q->q_next ) { putnext(q, mp); return; }}/* * ========================================================================= * * STREAMS QUEUE PUT and QUEUE SERVICE routines * * ========================================================================= * * READ QUEUE PUT and SRV routines * * ------------------------------------------------------------------------- * * M2PA RPUT - Message from below. * * If the message is a priority message we attempt to process it immediately. * If the message is a non-priority message, but there are no messages on the * queue yet, we attempt to process it immediately. If the message is not * supported, we pass it down-queue if possible. If the message cannot be * processed immediately we place it on the queue. */static INTm2pa_rput(queue_t *q, mblk_t *mp){ int err = -EOPNOTSUPP; if ( mp->b_datap->db_type < QPCTL && q->q_count ) { putq(q, mp); /* * NOTE:- after placing messages on the queue here, I should * check if placing the message on the queue crosses a band * threshold for congestion accept and congestion discard. * When crossing congestion accept, I should sent busy to the * peer and notify MTP3. When crossing congestion discard I * should notify MTP3. */ return(0); } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = m2pa_r_data(q, mp)) ) break; return(0); case M_PROTO: if ( (err = m2pa_r_proto(q, mp)) ) break; return(0); case M_PCPROTO: if ( (err = m2pa_r_pcproto(q, mp)) ) break; return(0); case M_CTL: if ( (err = m2pa_r_ctl(q, mp)) ) break; return(0); case M_ERROR: m2pa_r_error(q, mp); return(0); } switch ( err ) { case -EAGAIN: putq(q, mp); return(0); case -EOPNOTSUPP: if ( q->q_next ) { putnext(q, mp); return(0); } } freemsg(mp); return(err);}/* * M2PA RSRV - Queued message from below. * * If the message is a priority message we attempt to process it immediately * and without flow control. If the message is a non-priority message and * the next queue is flow controlled, we put the message back on the queue * and wait. If we cannot process a priority message immediately we cannot * place it back on the queue and discard it. We requeue non-priority * messages which cannot be processed immediately. Unrecognized messages are * passed down-queue. */static INTm2pa_rsrv(queue_t *q){ mblk_t *mp; int err = -EOPNOTSUPP; while ( (mp = getq(q)) ) { if ( mp->b_datap->db_type < QPCTL && !canputnext(q) ) { putbq(q, mp); return(0); } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = m2pa_r_data(q, mp)) ) break; goto rsrv_continue; case M_PROTO: if ( (err = m2pa_r_proto(q, mp)) ) break; goto rsrv_continue; case M_PCPROTO: if ( (err = m2pa_r_pcproto(q, mp)) ) break; goto rsrv_continue; case M_CTL: if ( (err = m2pa_r_ctl(q, mp)) ) break; goto rsrv_continue; } switch ( err ) { case -EAGAIN: if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return(0); } case -EOPNOTSUPP: if ( q->q_next ) { putnext(q, mp); goto rsrv_continue; } break; } freemsg(mp);rsrv_continue: /* * NOTE:- I have removed and processed a message from the * receive queue, so I should check for receive congestion * abatement. If receive congestion has abated below the * accept threshold, I should signal MTP that there is no * longer any receive congestion. */ continue; } return(0);}/* * ------------------------------------------------------------------------- * * WRITE QUEUE PUT and SRV routines * * ------------------------------------------------------------------------- * * M2PA WPUT - Message from above. * * If the message is priority message we attempt to process it immediately. * If the message is non-priority message, but there are no messages on the * queue yet, we attempt to process it immediately. If the message is not * supported, we pass it down-queue if possible. If the message cannot be * processed immediately, we place it on the queue. */static INTm2pa_wput(queue_t *q, mblk_t *mp){ mblk_t *mp; int err = -EOPNOTSUPP; if ( q->q_count && mp->b_datap->db_type < QPCTL ) { putq(q, mp); /* * NOTE:- after placing messages on the queue here, I should * check for transmit congestion. I should check if placing * the message on the queue crosses a band threshold for * congestion onset and abatement. When crossing congestion * thresholds, I should notify MTP3. */ return(0); } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = m2pa_w_data(q, mp)) ) break; return(0); case M_PROTO: if ( (err = m2pa_w_proto(q, mp)) ) break; return(0); case M_PCPROTO: if ( (err = m2pa_w_pcproto(q, mp)) ) break; return(0); case M_CTL: if ( (err = m2pa_w_ctl(q, mp)) ) break; return(0); case M_IOCTL: if ( (err = m2pa_w_ioctl(q, mp)) ) break; return(0); case M_FLUSH: m2pa_w_flush(q, mp); return(0); } switch ( err ) { case -EAGAIN: if ( mp->b_datap->db_type < QPCTL ) { putq(q, mp); return(0); } case -EOPNOTSUPP: if ( q->q_next ) { putnext(q, mp); return(0); } } freemsg(mp); return(err);}/* * M2PA WSRV = Queued message from above. * * If the message is a priority message we attempt to process it immediately * and without flow control. If the message is a non-priority message and * the next queue is flow controlled, we put the message back on the queue * and wait. If we cannot process a priority message immediately we cannot * place it back on the queue, we discard it. We requeue non-priority * messages which cannot be processed immediately. Unrecognized messages are * passed down-queue. */static INTm2pa_wsrv(queue_t *q){ int err = -EOPNOTSUPP; mblk_t *mp; while ( (mp = getq(q)) ) { if ( q->q_next && mp->b_datap->db_type < QPCTL && !canputnext(q)) { putbq(q, mp); return(0); } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = m2pa_w_data(q, mp)) ) break; goto wsrv_continue; case M_PROTO: if ( (err = m2pa_w_proto(q, mp)) ) break; goto wsrv_continue; case M_PCPROTO: if ( (err = m2pa_w_pcproto(q, mp)) ) break; goto wsrv_continue; case M_CTL: if ( (err = m2pa_w_ctl(q, mp)) ) break; goto wsrv_continue; } switch ( err ) { case -EAGAIN: if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return(0); } case -EOPNOTSUPP: if ( q->q_next ) { putnext(q, mp); goto wsrv_continue; } } freemsg(mp);wsrv_continue: /* * NOTE:- I have removed a message from the queue, so I * should check for band congestion abatement for the data * band to see if transmit congestion has abated. If it has, * I should notify MTP3 of transmit abatement. */ continue; } return(0);}/* * ========================================================================= * * OPEN and CLOSE * * ========================================================================= *//* * Private structure allocation and deallocation. * * We use Linux hardware aligned cache here for speedy access to information * contained in the private data structure. */kmem_cache_t *m2pa_cachep = NULL;static m2pa_t *m2pa_alloc_priv(queue_t *q){ m2pa_t *m2pa; if ( (m2pa = kmem_cache_alloc(m2pa_cachep)) ) { bzero(m2pa, sizeof(*m2pa)); RD(q)->q_ptr = WR(q)->q_tpr = m2pa; m2pa->rq = RD(q); m2pa->wq = WR(q); } return(m2pa);}static voidm2pa_free_priv(queue_t *q){ m2pa_t *m2 = (m2pa_t *)q->q_ptr; kmem_cache_free(m2pa_cachep, m2pa); return;}static voidm2pa_init_priv(void){ if ( !(m2pa_cachep = kmem_find_general_cachep(sizeof(m2pa_t))) ) { /* allocate a new cachep */ } return;}/* * ------------------------------------------------------------------------- * * OPEN - Each open * * ------------------------------------------------------------------------- */static intm2pa_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){ (void)crp; if ( q->q_ptr != NULL ) return(0); /* * FIXME: we have to open this as a driver, not a module */ if ( sflag == MODOPEN || WR(q)->q_next != NULL ) { /* * FIXME: check to make sure that the module we are being * pushed over is compatible (i.e. it is the right kind of * transport module. */ if ( !(m2pa = kmem_cache_alloc(m2pa_m2pa_cachep, SLAB_HWCACHE_ALIGN)) ) return ENOMEM; RD(q)->q_ptr = WR(q)->q_ptr = m2pa; m2pa->rq = RD(q); m2pa->wq = WR(q); /* * TODO: more structure initialization */ return(0); } return EIO;}/* * ------------------------------------------------------------------------- * * CLOSE - Last close * * ------------------------------------------------------------------------- */static intm2pa_close(queue_t *q, int flag, cred_t *crp){ m2pa_t *m2pa = (m2pa_t *)q->q_ptr; (void)flag; (void)crp; /* * TODO: make sure everything is deallocated */ kmem_cache_free(m2pa_m2pa_cachep, m2pa); return(0);}/* * ========================================================================= * * LiS MODULE INITIALIZATION * * ========================================================================= */static int m2pa_initialized = 0;#ifndef LIS_REGISTEREDstatic inline void m2pa_init(void)#else__initfunc(void m2pa_init(void))#endif{ if ( m2pa_initialized ) return; m2pa_initialized = 1; cmn_err(CE_NOTE, M2PA_BANNER); /* console splash */#ifndef LIS_REGISTERED if ( !(m2pa_minfo.mi_idnum = lis_register_strmod(&m2pa_info, m2pa_minfo.mi_idname)) ) { cmn_err(CE_NOTE, "m2pa: couldn't register as module\n"); m2pa_minfo.mi_idnum = 0; }#endif}#ifndef LIS_REGISTEREDstatic inline void m2pa_terminate(void)#else__initfunc(void m2pa_terminate(void))#endif{ if ( !m2pa_initialized ) return; m2pa_initialized = 0;#ifndef LIS_REGISTERED if ( m2pa_minfo.mi_idnum ) if ( (sdt_minfo.mi_idnum = lis_unregister_strmod(&m2pa_info)) ) { cmn_err(CE_WARN, "sdt: couldn't unregister as module!\n"); }#endif};/* * ========================================================================= * * LINUX KERNEL MODULE INITIALIZATION * * ========================================================================= */#ifdef MODULEint init_module(void){ m2pa_init(); return(0);}void cleanup_module(void){ m2pa_terminate(); return;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -