📄 sdl.c
字号:
static void dev_daedr_recvd_frame_ind(sdl_t *sdl, mblk_t *mp){ sdl_daedr_recvd_frame(sdl, mp); /* FIXME */}static void dev_daedr_compr_frame_ind(sdl_t *sdl, mblk_t *mp){ int count = ((int *)mp->b_rptr)[1]; assert(mp->b_datap->db_ref); freemsg(mp); /* FIXME */ sdl_daedr_compr_frame(sdl, count);}static void dev_daedr_error_frame_ind(sdl_t *sdl, mblk_t *mp){ assert(mp->b_datap->db_ref); freemsg(mp); /* FIXME */ sdl_daedr_error_frame(sdl);}static void dev_daedr_loss_of_sync_ind(sdl_t *sdl, mblk_t *mp){ assert(mp->b_datap->db_ref); freemsg(mp); /* FIXME */ sdl_daedr_loss_of_sync(sdl);}static void dev_daedr_N_octets_ind(sdl_t *sdl, mblk_t *mp){ assert(mp->b_datap->db_ref); freemsg(mp); /* FIXME */ sdl_daedr_N_octets(sdl);}static void dev_daedt_tx_request_ind(sdl_t *sdl, mblk_t *mp){ assert(mp->b_datap->db_ref); freemsg(mp); /* FIXME */ sdl_daedt_tx_request(sdl);}static void (*sdl_dev_ops[])(sdl_t *, mblk_t *) ={ dev_daedr_recvd_frame_ind, /* DEV_DAEDR_RECEIVED_FRAME_IND */ dev_daedr_compr_frame_ind, /* DEV_DAEDR_COMPRESSED_FRAME_IND */ dev_daedr_error_frame_ind, /* DEV_DAEDR_ERROR_FRAME_IND */ dev_daedr_loss_of_sync_ind, /* DEV_DAEDR_LOSS_OF_SYNC_IND */ dev_daedr_N_octets_ind, /* DEV_DAEDR_N_OCTETS_IND */ dev_daedt_tx_request_ind /* DEV_DAEDT_TX_REQUEST_IND */};/* * ======================================================================= * * M_IOCTL handling * * ======================================================================= */static intsdl_do_ioctl(lmi_t *sdl, int cmd, void *arg){ int nr = _IOC_NR(cmd); lmi_driver_t *drv; if ( _IOC_TYPE(cmd) == SDL_IOC_MAGIC ) if ( SDL_IOC_FIRST <= nr && nr <= SDL_IOC_LAST ) if ( sdl_ioc_lmiops[nr] ) return sdl_ioc_lmiops[nr]((sdl_t *)sdl, cmd, arg); if ( (drv = sdl->driver) ) return drv->ops.lmi.ioctl(sdl, cmd, arg); rare(); return -ENXIO;}#ifndef abs#define abs(x) ((x)<0 ? -(x):(x))#endifstatic inline intsdl_m_ioctl(queue_t *q, mblk_t *mp){ sdl_t *sdl = (sdl_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, size = iocp->ioc_count; int ret = -EINVAL; if ( size >= _IOC_SIZE(cmd) ) ret = sdl_do_ioctl((lmi_t *)sdl, cmd, arg); if ( abs(ret) == ENXIO ) { rare(); if ( WR(q)->q_next ) { rare(); putnext(q, mp); return(0); } } 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 = abs(ret); iocp->ioc_rval = -1; } qreply(q, mp); return(0);}/* * ======================================================================= * * M_PROTO, M_PCPROTO handling * * ======================================================================= */static inline intsdl_m_proto(queue_t *q, mblk_t *mp){ int err = LMI_BADPRIM + EOPNOTSUPP; sdl_t *sdl = (sdl_t *)q->q_ptr; int prim = *((lmi_long *)mp->b_rptr);// ptrace(("primitive = %d\n", prim)); if ( SDL_DSTR_FIRST <= prim && prim <= SDL_DSTR_LAST ) {// ptrace(("sdl_sdt_ops offset = %d\n", (int)(prim - SDL_DSTR_FIRST))); (*sdl_sdt_ops[prim - SDL_DSTR_FIRST])(sdl, mp); return(0); } seldom(); if ( WR(q)->q_next ) { rare(); putnext(q, mp); return (0); } if ( LMI_DSTR_FIRST <= prim && prim <= LMI_DSTR_LAST ) if ( !(err = lmi_lmi_ops[prim - LMI_DSTR_FIRST]((lmi_t *)sdl, mp)) ) return(0); ptrace(("Error return = %d\n", err)); return err;}static inline intdev_m_proto(queue_t *q, mblk_t *mp){ int err = LMI_BADPRIM + EOPNOTSUPP;// sdl_t *sdl = (sdl_t *)q->q_ptr;// long prim = *((lmi_long *)mp->b_rptr);// FIXME: for device which want to send mblks...// if ( DEV_USTR_FIRST <= prim && prim <= DEV_USTR_LAST )// {// (*sdl_dev_ops[DEV_USTR_LAST - prim])(sdl, mp);// return(0);// } if ( RD(q)->q_next ) { putnext(q, mp); return(0); } return err;}/* * ======================================================================= * * M_DATA handling * * ======================================================================= */static inline intsdl_m_data(queue_t *q, mblk_t *mp){ sdl_t *sdl = (sdl_t *)q->q_ptr; sdl->dcalls->xmit(sdl, mp); return(0);}static inline intdev_m_data(queue_t *q, mblk_t *mp){// sdl_t *sdl = (sdl_t *)q->q_ptr; putnext(q, mp);// sdl->ucalls->daedr_received_bits(sdl, mp); /* loop */ return(0);}/* * -------------------------------------------- * * STREAMS QUEUE PUT and QUEUE SERVICE routines * * -------------------------------------------- */static voidsdl_wput(queue_t *q, mblk_t *mp){ int err= EOPNOTSUPP; if ( q->q_count && mp->b_datap->db_type < QPCTL ) { seldom(); 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: /* should be sent band 1 */ case M_PCPROTO: if ( (err = sdl_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 = sdl_m_ioctl(q, mp)) ) { seldom(); break; } return; } switch ( err&0xffff ) { case EAGAIN: seldom(); putq(q, mp); return; case EOPNOTSUPP: rare(); if ( q->q_next ) { rare(); putnext(q, mp); return; } } rare(); assert(mp->b_datap->db_ref); freemsg(mp); /* don't even want to complain... */}static voidsdl_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) ) { seldom(); 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; default: err = EOPNOTSUPP; } switch ( err&0xffff ) { case EAGAIN: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return; } rare(); break; case EOPNOTSUPP: rare(); if ( q->q_next ) { rare(); putnext(q, mp); return; } } rare(); assert(mp->b_datap->db_ref); freemsg(mp); }}static voidsdl_rput(queue_t *q, mblk_t *mp){ int err = EOPNOTSUPP; if ( q->q_count && mp->b_datap->db_type < QPCTL ) { seldom(); putq(q, mp); return; } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = dev_m_data(q, mp)) ) { seldom(); break; } return; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = dev_m_proto(q, mp)) ) { seldom(); break; } return; } switch ( err&0xffff ) { case EAGAIN: rare(); putq(q, mp); return; case EOPNOTSUPP: rare(); putnext(q, mp); return; } rare(); assert(mp->b_datap->db_ref); freemsg(mp);}#define SDL_SUPQ_MAXLEN 20static voidsdl_rsrv(queue_t *q){ mblk_t *mp; int err= EOPNOTSUPP; while ( (mp = getq(q)) ) { if ( mp->b_datap->db_type < QPCTL && !canputnext(q) ) { seldom(); putbq(q, mp); return; } switch ( mp->b_datap->db_type ) { case M_DATA: if ( (err = dev_m_data(q, mp)) ) { seldom(); break; } continue; case M_CTL: case M_PROTO: case M_PCPROTO: if ( (err = dev_m_proto(q, mp)) ) { seldom(); break; } continue; default: err = EOPNOTSUPP; } switch ( err&0xffff ) { case EAGAIN: seldom(); if ( mp->b_datap->db_type < QPCTL ) { putbq(q, mp); return; } rare(); break; case EOPNOTSUPP: seldom(); putnext(q, mp); return; } rare(); assert(mp->b_datap->db_ref); freemsg(mp); }}/* * ======================================================================= * * SDT Driver Implemenation * * ======================================================================= */static lmi_driver_t *sdl_drivers = NULL;static struct lmi *sdl_drv_attach(dev_t dev){ lmi_t *sdl; MOD_INC_USE_COUNT; if ( !(sdl = lmi_drv_attach(dev, sdl_drivers, sizeof(sdl_t))) ) MOD_DEC_USE_COUNT; return sdl;}static intsdl_drv_open(struct lmi *sdl){ int err; if ( !sdl ) return ENXIO; if ( !(err = lmi_drv_open(sdl->device)) ) { sdl->device->module = sdl; sdl->device->ucalls = sdl->driver->ucalls; sdl->dcalls = &sdl_drv_dcalls; } return (err);}static intsdl_drv_close(struct lmi *sdl){ int err; sdl_t *p = (sdl_t *)sdl; if ( !(err = lmi_drv_close(sdl, (sdl_ulong *)NULL, SDL_MAX_TIMERIDS, (sdl_ulong *)&p->bufids, SDL_MAX_BUFCALLS)) ) MOD_DEC_USE_COUNT; return(err);}/* these are for registration with SDT as a driver */static struct lmi_ops sdl_lmi_ops = { { sdl_drv_attach, /* dev.attach */ sdl_drv_open, /* dev.open */ sdl_drv_close /* dev.close */ }, { lmi_info, /* lmi.info */ lmi_attach, /* lmi.attach */ lmi_detach, /* lmi.detach */ lmi_enable, /* lmi.enable */ lmi_disable, /* lmi.disable */ sdl_do_ioctl /* lmi.ioctl */ }};/* * ======================================================================= * * OPEN and CLOSE * * ======================================================================= */static intsdl_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){ int err; sdl_t *sdl; if ( q->q_ptr != NULL ) return (0); if ( (err = lmi_open(q, devp, flag, sflag, crp, sdl_drivers, sizeof(sdl_t))) ) return(err); sdl = (sdl_t *)q->q_ptr; sdl->ucalls = &sdl_mod_ucalls; if ( WR(q)->q_next ) sdl->dcalls = &sdl_mod_dcalls; else sdl->dcalls = &sdl_drv_dcalls; return(0);}static intsdl_close(queue_t *q, int flag, cred_t *crp){ int err; sdl_t *sdl = (sdl_t *)q->q_ptr; err = lmi_close(q, flag, crp, (sdl_ulong *)&sdl->timers, SDL_MAX_TIMERIDS, (sdl_ulong *)&sdl->bufids, SDL_MAX_BUFCALLS); return(err);}/* * ======================================================================= * * DRIVER Registration (driver registering with us) * * ======================================================================= */intsdl_register_driver(major_t cmajor, int nminor, char *name, lmi_ops_t *ops, dev_dcalls_t *dcalls){ int err; MOD_INC_USE_COUNT; err = lmi_register_driver( &sdl_drivers, cmajor, &sdl_info, nminor, name, ops, dcalls, &sdl_dev_ucalls ); if ( err < 0 ) MOD_DEC_USE_COUNT; return(err);}intsdl_unregister_driver(major_t cmajor){ int err = lmi_unregister_driver(&sdl_drivers, cmajor); if ( !err ) MOD_DEC_USE_COUNT; return (err);}/* * ======================================================================= * * LiS Module Initialization * * ======================================================================= */static int sdl_initialized = 0;#ifndef LIS_REGISTEREDstatic inline void sdl_init(void)#else__initfunc(void sdl_init(void))#endif{ if ( sdl_initialized ) return; sdl_initialized = 1; printk(KERN_INFO SDL_BANNER); /* console splash */#if 0#ifndef LIS_REGISTERED if ( !(sdl_minfo.mi_idnum = lis_register_strmod(&sdl_info, sdl_minfo.mi_idname)) ) { cmn_err(CE_NOTE, "sdl: couldn't register as module\n"); }#endif if ( sdt_register_driver(SDL_CMAJOR, SDL_NMINOR, "sdl", &sdl_lmi_ops, &sdl_drv_ops) ) { cmn_err(CE_NOTE, "sdl: couldn't register as driver\n"); }#else (void)sdl_lmi_ops; (void)sdl_drv_ops; (void)sdl_dev_ops;#endif};#ifndef LIS_REGISTEREDstatic inline void sdl_terminate(void)#else__initfunc(void sdl_terminate(void))#endif{ if ( !sdl_initialized ) return; sdl_initialized = 0;#if 0#ifndef LIS_REGSITERED if (sdl_minfo.mi_idnum) if ( (sdl_minfo.mi_idnum = lis_unregister_strmod(&sdl_info)) ) { cmn_err(CE_WARN, "sdl: couldn't unregister as module!\n"); }#endif if ( sdt_unregister_driver(SDL_CMAJOR) ) { cmn_err(CE_WARN, "sdl: couldn't unregister as driver!\n"); }#endif};/* * ======================================================================= * * Kernel Module Initialization * * ======================================================================= */#ifdef MODULEint init_module(void){ (void)sdl_debug; sdl_init(); return(0);}void cleanup_module(void){ sdl_terminate(); return;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -