📄 sl.c
字号:
if ( sl_ioc_lmiops[nr] ) return sl_ioc_lmiops[nr]((sl_t *)sl, cmd, arg); if ( (drv = sl->driver) ) return drv->ops.lmi.ioctl(sl, cmd, arg); return -ENXIO;}#ifndef abs#define abs(x) ((x)<0 ? -(x):(x))#endifstatic inline intsl_m_ioctl(queue_t *q, mblk_t *mp){ sl_t *sl = (sl_t *)q->q_ptr; struct iocblk *iocp = (struct iocblk *)mp->b_rptr; void *arg = mp->b_cont?mp->b_cont->b_rptr:NULL; int cmd = iocp->ioc_cmd, count = iocp->ioc_count; int ret = -EINVAL; if ( count >= _IOC_SIZE(cmd) ) { ret = sl_do_ioctl((lmi_t *)sl, cmd, arg); } if ( abs(ret) == ENXIO ) { if ( q->q_next ) { putnext(q, mp); return(0); } } if ( ret == 0 ) { mp->b_datap->db_type = M_IOCACK; iocp->ioc_error = 0; iocp->ioc_rval = 0; } else { mp->b_datap->db_type = M_IOCNAK; iocp->ioc_error = abs(ret); iocp->ioc_rval = -1; } qreply(q, mp); return(0);}/* * ======================================================================= * * M_PROTO, M_PCPROTO handling * * ======================================================================= */static inline intsl_m_proto(queue_t *q, mblk_t *mp){ int err = LMI_BADPRIM + EOPNOTSUPP; sl_t *sl = (sl_t *)q->q_ptr; int prim = *((sl_long *)mp->b_rptr); if ( SL_DSTR_FIRST <= prim && prim <= SL_DSTR_LAST ) { (*sl_lk_ops[prim - SL_DSTR_FIRST])(sl, mp); return(0); } if ( q->q_next ) { putnext(q, mp); return(0); } if ( LMI_DSTR_FIRST <= prim && prim <= LMI_DSTR_LAST ) { err = (*lmi_lmi_ops[prim - LMI_DSTR_FIRST])((lmi_t *)sl, mp); } return err;}static inline intsdt_m_proto(queue_t *q, mblk_t *mp){ int err = LMI_BADPRIM + EOPNOTSUPP; sl_t *sl = (sl_t *)q->q_ptr; long prim = *((sl_long *)mp->b_rptr); if ( SDT_USTR_FIRST <= prim && prim <= SDT_USTR_LAST ) { (*sl_sdt_ops[SDT_USTR_LAST - prim])(sl, mp); return(0); } if ( q->q_next ) { putnext(q, mp); return (0); } return err;}/* * ======================================================================= * * M_DATA handling * * ======================================================================= */static inline intsl_m_data(queue_t *q, mblk_t *mp){ sl_t *sl = (sl_t *)q->q_ptr; sl_lsc_pdu(sl, mp); return(0);}static inline intsdt_m_data(queue_t *q, mblk_t *mp){ sl_t *sl = (sl_t *)q->q_ptr; sdt_rc_signal_unit_ind(sl, mp); return(0);}/* * ------------------------------------------------------------------------- * * STREAMS PUTQ and SRVQ routines * * ------------------------------------------------------------------------- */void sl_wput(queue_t *q, mblk_t *mp){ int err = EOPNOTSUPP; if ( q->q_count && mp->b_datap->db_type < QPCTL ) { putq(q, mp); return; } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = sl_m_data(q, mp)) ) break; return; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sl_m_proto(q, mp)) ) break; return; case M_FLUSH: if ( *mp->b_rptr & FLUSHW ) { flushq(q, FLUSHALL); if ( q->q_next ) { putnext(q, mp); /* flush all the way down */ return; } *mp->b_rptr &= ~FLUSHW; } if ( *mp->b_rptr & FLUSHR ) { flushq(RD(q), FLUSHALL); qreply(q, mp); } else break; return; case M_IOCTL: if ( (err = sl_m_ioctl(q, mp)) ) break; return; } switch ( err&0xffff ) { case EAGAIN: putq(q, mp); return; case EOPNOTSUPP: if ( q->q_next ) { putnext(q, mp); return; } } freemsg(mp); /* don't even want to complain */ return;}void sl_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; } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = sl_m_data(q, mp)) ) break; continue; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sl_m_proto(q, mp)) ) break; continue; } switch ( err&0xffff ) { case EAGAIN: if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return; } break; case EOPNOTSUPP: if ( q->q_next ) { putnext(q, mp); return; } } freemsg(mp); }}static voidsl_rput(queue_t *q, mblk_t *mp){ int err = EOPNOTSUPP; if ( q->q_count && mp->b_datap->db_type < QPCTL ) { putq(q, mp); return; } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = sdt_m_data(q, mp)) ) break; return; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sdt_m_proto(q, mp)) ) break; return; } switch ( err&0xffff ) { case EAGAIN: putq(q, mp); return; case EOPNOTSUPP: putnext(q, mp); return; } freemsg(mp);}static voidsl_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; } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = sdt_m_data(q, mp)) ) break; continue; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sdt_m_proto(q, mp)) ) break; continue; } switch ( err&0xffff ) { case EAGAIN: if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return; } break; case EOPNOTSUPP: putnext(q, mp); return; } freemsg(mp); }}/* * ======================================================================= * * OPEN and CLOSE * * ======================================================================= */static lmi_driver_t *sl_drivers = NULL;static intsl_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){ int err; sl_t *sl; if ( q->q_ptr != NULL ) return (0); if ( (err = lmi_open(q, devp, flag, sflag, crp, sl_drivers, sizeof(sl_t))) ) return(err); sl = (sl_t *)q->q_ptr; sl->ucalls = &sl_mod_ucalls; if ( WR(q)->q_next ) sl->dcalls = &sl_mod_dcalls; else sl->dcalls = &sl_drv_dcalls; bufq_init(&sl->tb); bufq_init(&sl->rtb); return(0);}static intsl_close(queue_t *q, int flag, cred_t *crp){ int err; sl_t *sl = (sl_t *)q->q_ptr;// bufq_purge(&sl->tb); /* causes problems for some reason */// bufq_purge(&sl->rtb); /* causes problems for some reason */ err = lmi_close(q, flag, crp, (sl_ulong *)&sl->timers, SL_MAX_TIMERIDS, (sl_ulong *)&sl->bufids, SL_MAX_BUFCALLS); return(err);}/* * ======================================================================= * * DRIVER Registration (driver registering with us) * * ======================================================================= */intsl_register_driver(major_t cmajor, int nminor, char *name, lmi_ops_t *ops, sdt_dcalls_t *dcalls){ int ret; MOD_INC_USE_COUNT; if ( (ret = lmi_register_driver( &sl_drivers, cmajor, &sl_info, nminor, name, ops, dcalls, &sl_drv_ucalls)) < 0 ) { MOD_DEC_USE_COUNT; return(ret); } return(ret);}intsl_unregister_driver(major_t cmajor){ int err = lmi_unregister_driver(&sl_drivers, cmajor); if ( !err ) MOD_DEC_USE_COUNT; return (err);}/* * ======================================================================= * * LiS Module Initialization * * ======================================================================= */static int sl_initialized = 0;#ifndef LIS_REGISTEREDstatic inline void sl_init(void)#else__initfunc(void sl_init(void))#endif{ if ( sl_initialized ) return; sl_initialized = 1; printk(KERN_INFO SL_BANNER); /* console splash */#ifndef LIS_REGISTERED if ( !(sl_minfo.mi_idnum = lis_register_strmod(&sl_info, sl_minfo.mi_idname)) ) { cmn_err(CE_NOTE, "sl: couldn't register module\n"); }#endif#if 0 if ( sls_register_driver(SL_CMAJOR, SL_NMINOR, "sl", &sl_lmi_ops, &sl_drv_ops) ) { cmn_err(CE_NOTE: "sl: couldn't register as driver\n"); }#endif};#ifndef LIS_REGISTEREDstatic inline void sl_terminate(void)#else__initfunc(void sl_terminate(void))#endif{ if ( !sl_initialized ) return; sl_initialized = 0;#ifndef LIS_REGSITERED if (sl_minfo.mi_idnum) if ( (sl_minfo.mi_idnum = lis_unregister_strmod(&sl_info)) ) { cmn_err(CE_WARN, "sl: couldn't unregister module!\n"); }#endif};/* * ======================================================================= * * Kernel Module Initialization * * ======================================================================= */#ifdef MODULEint init_module(void){ (void)sl_debug; sl_init(); return(0);}void cleanup_module(void){ sl_terminate(); return;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -