📄 sdt.c
字号:
int err = LMI_BADPRIM + EOPNOTSUPP; sdt_t *sdt = (sdt_t *)q->q_ptr; long prim = *((sdt_long *)mp->b_rptr); if ( SDL_USTR_FIRST <= prim && prim <= SDL_USTR_LAST ) { (*sdt_sdl_ops[SDL_USTR_LAST - prim])(sdt, mp); return(0); } if ( q->q_next ) { putnext(q, mp); return (0); } return err;}/* * ======================================================================= * * M_DATA handling * * ======================================================================= */static inline intsdt_m_data(queue_t *q, mblk_t *mp){ sdt_t *sdt = (sdt_t *)q->q_ptr; sdt->dcalls->daedt_xmit(sdt, mp); return(0);}static inline intsdl_m_data(queue_t *q, mblk_t *mp){ sdt_t *sdt = (sdt_t *)q->q_ptr; sdt_daedr_received_bits(sdt, mp);// sdt->ucalls->rc_signal_unit(sdt, mp); return(0);}/* * -------------------------------------------- * * STREAMS QUEUE PUT and QUEUE SERVICE routines * * -------------------------------------------- *//* * We only want M_DATA on the queue so that the driver can read from the * queue and backenable to the Signalling Link write queue. When can attempt * to deliver to the driver in the service routine for push devices but it * is better to take the pull approach. None of the protocol messages take * any time here anyway. */static voidsdt_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 = sdt_m_data(q, mp)) ) { seldom(); break; } return; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sdt_m_proto(q, mp)) ) { seldom(); 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 = sdt_m_ioctl(q, mp)) ) { seldom(); break; } return; } switch ( err&0xffff ) { case EAGAIN: seldom(); putq(q, mp); return; case EOPNOTSUPP: if ( q->q_next ) { rare(); putnext(q, mp); return; } default: rare(); break; } assert(mp->b_datap->db_ref); freemsg(mp); /* don't even want to complain... */ return;}static voidsdt_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 = sdt_m_data(q, mp)) ) { seldom(); break; } continue; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sdt_m_proto(q, mp)) ) { seldom(); break; } continue; } switch ( err&0xffff ) { case EAGAIN: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return; } rare(); break; case EOPNOTSUPP: if ( q->q_next ) { rare(); putnext(q, mp); return; } default: rare(); break; } assert(mp->b_datap->db_ref); freemsg(mp); /* don't even want to complain... */ }}static voidsdt_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 = sdl_m_data(q, mp)) ) { seldom(); break; } return; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sdl_m_proto(q, mp)) ) { seldom(); break; } return; } switch ( err&0xffff ) { case EAGAIN: seldom(); putq(q, mp); return; case EOPNOTSUPP: rare(); putnext(q, mp); return; default: rare(); break; } assert(mp->b_datap->db_ref); freemsg(mp);}static voidsdt_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 = sdl_m_data(q, mp)) ) { seldom(); break; } continue; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = sdl_m_proto(q, mp)) ) { seldom(); break; } continue; } switch ( err&0xffff ) { case EAGAIN: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return; } rare(); break; case EOPNOTSUPP: rare(); putnext(q, mp); return; default: rare(); break; } assert(mp->b_datap->db_ref); freemsg(mp); }}/* * ======================================================================= * * SL Driver Implemenation * * ======================================================================= */static lmi_driver_t *sdt_drivers = NULL;static struct lmi *sdt_drv_attach(dev_t dev){ lmi_t *sdt; MOD_INC_USE_COUNT; if ( !(sdt = lmi_drv_attach(dev, sdt_drivers, sizeof(sdt_t))) ) MOD_DEC_USE_COUNT; return sdt;}static intsdt_drv_open(struct lmi *sdt){ int err; if ( !sdt ) return ENXIO; if ( !(err = lmi_drv_open(sdt)) ) { sdt->device->module = sdt; sdt->device->ucalls = sdt->driver->ucalls; sdt->dcalls = &sdt_drv_dcalls; } return (err);}static intsdt_drv_close(struct lmi *sdt){ int err; sdt_t *p = (sdt_t *)sdt; if ( !(err = lmi_drv_close(sdt, (sdt_ulong *)NULL, SDT_MAX_TIMERIDS, (sdt_ulong *)&p->bufids, SDT_MAX_BUFCALLS)) ) MOD_DEC_USE_COUNT; return(err);}/* these are for registration with SL as a driver */static struct lmi_ops sdt_lmi_ops = { { sdt_drv_attach, /* dev.attach */ sdt_drv_open, /* dev.open */ sdt_drv_close /* dev.close */ }, { lmi_info, /* lmi.info */ lmi_attach, /* lmi.attach */ lmi_detach, /* lmi.detach */ lmi_enable, /* lmi.enable */ lmi_disable, /* lmi.disable */ sdt_do_ioctl /* lmi.ioctl */ }};/* * ======================================================================= * * OPEN and CLOSE * * ======================================================================= */static intsdt_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){ int err; sdt_t *sdt; if ( q->q_ptr != NULL ) return(0); if ( (err = lmi_open(q, devp, flag, sflag, crp, sdt_drivers, sizeof(sdt_t))) ) return(err); sdt = (sdt_t *)q->q_ptr; sdt->ucalls = &sdt_mod_ucalls; if ( WR(q)->q_next ) sdt->dcalls = &sdt_mod_dcalls; else sdt->dcalls = &sdt_drv_dcalls; return(0);}static intsdt_close(queue_t *q, int flag, cred_t *crp){ int err; sdt_t *sdt = (sdt_t *)q->q_ptr; err = lmi_close(q, flag, crp, (sdt_ulong *)&sdt->timers, SDT_MAX_TIMERIDS, (sdt_ulong *)&sdt->bufids, SDT_MAX_BUFCALLS); return(err);}/* * ======================================================================= * * DRIVER Registration (driver registering with us) * * ======================================================================= */intsdt_register_driver(major_t cmajor, int nminor, char *name, lmi_ops_t *ops, sdl_dcalls_t *dcalls){ int ret; MOD_INC_USE_COUNT; if ( (ret = lmi_register_driver(&sdt_drivers, cmajor, &sdt_info, nminor, name, ops, dcalls, &sdt_drv_ucalls)) < 0 ) { MOD_DEC_USE_COUNT; return(ret); } return(ret);}intsdt_unregister_driver(major_t cmajor){ int err = lmi_unregister_driver(&sdt_drivers, cmajor); if ( !err ) MOD_DEC_USE_COUNT; return (err);}/* * ======================================================================= * * LiS Module Initialization * * ======================================================================= */static int sdt_initialized = 0;#ifndef LIS_REGISTEREDstatic inline void sdt_init(void)#else__initfunc(void sdt_init(void))#endif{ if ( sdt_initialized ) return; sdt_initialized = 1; printk(KERN_INFO SDT_BANNER); /* console splash */#ifndef LIS_REGISTERED if ( !(sdt_minfo.mi_idnum = lis_register_strmod(&sdt_info, sdt_minfo.mi_idname)) ) cmn_err(CE_NOTE, "sdt: couldn't register as module\n");#endif#if 0 if ( sl_register_driver(SDT_CMAJOR, SDT_NMINOR, "sdt", &sdt_lmi_ops, &sdt_drv_ops) ) { cmn_err(CE_NOTE, "sdt: couldn't register as driver\n"); }#else (void)sdt_lmi_ops; (void)sdt_drv_ops;#endif};#ifndef LIS_REGISTEREDstatic inline void sdt_terminate(void)#else__initfunc(void sdt_terminate(void))#endif{ if ( !sdt_initialized ) return; sdt_initialized = 0;#ifndef LIS_REGISTERED if (sdt_minfo.mi_idnum) if ( (sdt_minfo.mi_idnum = lis_unregister_strmod(&sdt_info)) ) cmn_err(CE_WARN, "sdt: couldn't unregister as module!\n");#endif#if 0 if ( sl_unregister_driver(SDT_CMAJOR) ) { cmn_err(CE_WARN, "sdt: couldn't unregister as driver!\n"); }#endif};/* * ======================================================================= * * Kernel Module Initialization * * ======================================================================= */#ifdef MODULEint init_module(void){ (void)sdt_debug; sdt_init(); return(0);}void cleanup_module(void){ sdt_terminate(); return;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -