⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 4 页
字号:
			break;		}		break;	}	case LMI_IOC_MAGIC:	{		if (count < size || s->i_state == LMI_UNATTACHED) {			ret = (-EINVAL);			break;		}		switch (nr) {		case _IOC_NR(LMI_IOCGOPTIONS):	/* lmi_option_t */			ret = lmi_iocgoptions(q, mp);			break;		case _IOC_NR(LMI_IOCSOPTIONS):	/* lmi_option_t */			ret = lmi_iocsoptions(q, mp);			break;		case _IOC_NR(LMI_IOCGCONFIG):	/* lmi_config_t */			ret = lmi_iocgconfig(q, mp);			break;		case _IOC_NR(LMI_IOCSCONFIG):	/* lmi_config_t */			ret = lmi_iocsconfig(q, mp);			break;		case _IOC_NR(LMI_IOCTCONFIG):	/* lmi_config_t */			ret = lmi_ioctconfig(q, mp);			break;		case _IOC_NR(LMI_IOCCCONFIG):	/* lmi_config_t */			ret = lmi_ioccconfig(q, mp);			break;		case _IOC_NR(LMI_IOCGSTATEM):	/* lmi_statem_t */			ret = lmi_iocgstatem(q, mp);			break;		case _IOC_NR(LMI_IOCCMRESET):	/* lmi_statem_t */			ret = lmi_ioccmreset(q, mp);			break;		case _IOC_NR(LMI_IOCGSTATSP):	/* lmi_sta_t */			ret = lmi_iocgstatsp(q, mp);			break;		case _IOC_NR(LMI_IOCSSTATSP):	/* lmi_sta_t */			ret = lmi_iocsstatsp(q, mp);			break;		case _IOC_NR(LMI_IOCGSTATS):	/* lmi_stats_t */			ret = lmi_iocgstats(q, mp);			break;		case _IOC_NR(LMI_IOCCSTATS):	/* lmi_stats_t */			ret = lmi_ioccstats(q, mp);			break;		case _IOC_NR(LMI_IOCGNOTIFY):	/* lmi_notify_t */			ret = lmi_iocgnotify(q, mp);			break;		case _IOC_NR(LMI_IOCSNOTIFY):	/* lmi_notify_t */			ret = lmi_iocsnotify(q, mp);			break;		case _IOC_NR(LMI_IOCCNOTIFY):	/* lmi_notify_t */			ret = lmi_ioccnotify(q, mp);			break;		default:			ptrace(("%s: %p: ERROR: Unsupported LMI ioctl %d\n", MOD_NAME, s, nr));			ret = -EOPNOTSUPP;			break;		}		break;	}	case SDL_IOC_MAGIC:	{		if (count < size || s->i_state == LMI_UNATTACHED) {			ret = (-EINVAL);			break;		}		switch (nr) {		case _IOC_NR(SDL_IOCGOPTIONS):	/* lmi_option_t */			ret = sdl_iocgoptions(q, mp);			break;		case _IOC_NR(SDL_IOCSOPTIONS):	/* lmi_option_t */			ret = sdl_iocsoptions(q, mp);			break;		case _IOC_NR(SDL_IOCGCONFIG):	/* sdl_config_t */			ret = sdl_iocgconfig(q, mp);			break;		case _IOC_NR(SDL_IOCSCONFIG):	/* sdl_config_t */			ret = sdl_iocsconfig(q, mp);			break;		case _IOC_NR(SDL_IOCTCONFIG):	/* sdl_config_t */			ret = sdl_ioctconfig(q, mp);			break;		case _IOC_NR(SDL_IOCCCONFIG):	/* sdl_config_t */			ret = sdl_ioccconfig(q, mp);			break;		case _IOC_NR(SDL_IOCGSTATEM):	/* sdl_statem_t */			ret = sdl_iocgstatem(q, mp);			break;		case _IOC_NR(SDL_IOCCMRESET):	/* sdl_statem_t */			ret = sdl_ioccmreset(q, mp);			break;		case _IOC_NR(SDL_IOCGSTATSP):	/* lmi_sta_t */			ret = sdl_iocgstatsp(q, mp);			break;		case _IOC_NR(SDL_IOCSSTATSP):	/* lmi_sta_t */			ret = sdl_iocsstatsp(q, mp);			break;		case _IOC_NR(SDL_IOCGSTATS):	/* sdl_stats_t */			ret = sdl_iocgstats(q, mp);			break;		case _IOC_NR(SDL_IOCCSTATS):	/* sdl_stats_t */			ret = sdl_ioccstats(q, mp);			break;		case _IOC_NR(SDL_IOCGNOTIFY):	/* sdl_notify_t */			ret = sdl_iocgnotify(q, mp);			break;		case _IOC_NR(SDL_IOCSNOTIFY):	/* sdl_notify_t */			ret = sdl_iocsnotify(q, mp);			break;		case _IOC_NR(SDL_IOCCNOTIFY):	/* sdl_notify_t */			ret = sdl_ioccnotify(q, mp);			break;		case _IOC_NR(SDL_IOCCDISCTX):	/* */			ret = sdl_ioccdisctx(q, mp);			break;		case _IOC_NR(SDL_IOCCCONNTX):	/* */			ret = sdl_ioccconntx(q, mp);			break;		default:			ptrace(("%s: ERROR: Unsupported SDL ioctl %d\n", MOD_NAME, nr));			ret = -EOPNOTSUPP;			break;		}		break;	}	default:		ret = (QR_PASSFLOW);		break;	}	if (ret > 0) {		return (ret);	} else 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 = -ret;		iocp->ioc_rval = -1;	}	qreply(q, mp);	return (QR_ABSORBED);}/* *  ----------------------------------------------------------------------- * *  M_PROTO, M_PCPROTO Handling * *  ----------------------------------------------------------------------- *//* *  Primitives from User to SDL. *  ----------------------------------- */STATIC intsdl_w_proto(queue_t *q, mblk_t *mp){	int rtn;	ulong prim;	struct sdl *s = SDL_PRIV(q);	ulong oldstate = s->i_state;	if ((prim = *(ulong *) mp->b_rptr) == SDL_BITS_FOR_TRANSMISSION_REQ) {		printd(("%s: %p: -> SDL_BITS_FOR_TRANSMISSION_REQ [%d]\n", MOD_NAME, s,			msgdsize(mp->b_cont)));		if ((rtn = sdl_bits_for_transmission_req(q, mp)) < 0)			s->i_state = oldstate;		return (rtn);	}	switch (prim) {	case SDL_BITS_FOR_TRANSMISSION_REQ:		printd(("%s: %p: -> SDL_BITS_FOR_TRANSMISSION_REQ [%d]\n", MOD_NAME, s,			msgdsize(mp->b_cont)));		rtn = sdl_bits_for_transmission_req(q, mp);		break;	case SDL_CONNECT_REQ:		printd(("%s: %p: -> SDL_CONNECT_REQ\n", MOD_NAME, s));		rtn = sdl_connect_req(q, mp);		break;	case SDL_DISCONNECT_REQ:		printd(("%s: %p: -> SDL_DISCONNECT_REQ\n", MOD_NAME, s));		rtn = sdl_disconnect_req(q, mp);		break;	case LMI_INFO_REQ:		printd(("%s: %p: -> LMI_INFO_REQ\n", MOD_NAME, s));		rtn = lmi_info_req(q, mp);		break;	case LMI_ATTACH_REQ:		printd(("%s: %p: -> LMI_ATTACH_REQ\n", MOD_NAME, s));		rtn = lmi_attach_req(q, mp);		break;	case LMI_DETACH_REQ:		printd(("%s: %p: -> LMI_DETACH_REQ\n", MOD_NAME, s));		rtn = lmi_detach_req(q, mp);		break;	case LMI_ENABLE_REQ:		printd(("%s: %p: -> LMI_ENABLE_REQ\n", MOD_NAME, s));		rtn = lmi_enable_req(q, mp);		break;	case LMI_DISABLE_REQ:		printd(("%s: %p: -> LMI_DISABLE_REQ\n", MOD_NAME, s));		rtn = lmi_disable_req(q, mp);		break;	case LMI_OPTMGMT_REQ:		printd(("%s: %p: -> LMI_OPTMGMT_REQ\n", MOD_NAME, s));		rtn = lmi_optmgmt_req(q, mp);		break;	default:		/* 		   discard anything we don't recognize */		swerr();		rtn = (-EOPNOTSUPP);		break;	}	if (rtn < 0)		s->i_state = oldstate;	return (rtn);}/* *  ------------------------------------------------------------------------- * *  M_DATA Handling * *  ------------------------------------------------------------------------- */STATIC INLINE intsdl_w_data(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	(void) s;	printd(("%s: %p: -> M_DATA [%d]\n", MOD_NAME, s, msgdsize(mp)));	return sdl_send_data(q, mp);}STATIC INLINE intsdl_r_data(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	(void) s;	printd(("%s: %p: M_DATA [%d] <-\n", MOD_NAME, s, msgdsize(mp)));	return sdl_recv_data(q, mp);}/* *  ========================================================================= * *  PUT and SRV * *  ========================================================================= */STATIC INLINE streamscall intsdl_w_prim(queue_t *q, mblk_t *mp){	/* 	   Fast Path */	if (mp->b_datap->db_type == M_DATA)		return sdl_w_data(q, mp);	switch (mp->b_datap->db_type) {	case M_DATA:		return sdl_w_data(q, mp);	case M_PROTO:	case M_PCPROTO:		return sdl_w_proto(q, mp);	case M_FLUSH:		return ss7_w_flush(q, mp);	case M_IOCTL:		return sdl_w_ioctl(q, mp);	}	return (QR_PASSALONG);}STATIC INLINE streamscall intsdl_r_prim(queue_t *q, mblk_t *mp){	/* 	   Fast Path */	if (mp->b_datap->db_type == M_DATA)		return sdl_r_data(q, mp);	switch (mp->b_datap->db_type) {	case M_DATA:		return sdl_r_data(q, mp);	case M_FLUSH:		return ss7_r_flush(q, mp);	}	return (QR_PASSALONG);}/* *  ======================================================================= * *  OPEN and CLOSE * *  ======================================================================= */STATIC streamscall intsdl_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){	MOD_INC_USE_COUNT;	/* keep module from unloading in our face */	if (q->q_ptr != NULL) {		MOD_DEC_USE_COUNT;		return (0);	/* already open */	}	if (sflag == MODOPEN || WR(q)->q_next != NULL) {		int cmajor = getmajor(*devp);		int cminor = getminor(*devp);		struct sdl *s;		/* 		   test for multiple push */		for (s = sdl_opens; s; s = s->next) {			if (s->u.dev.cmajor == cmajor && s->u.dev.cminor == cminor) {				MOD_DEC_USE_COUNT;				return (ENXIO);			}		}		if (!(sdl_alloc_priv(q, &sdl_opens, devp, crp))) {			MOD_DEC_USE_COUNT;			return (ENOMEM);		}		return (0);	}	MOD_DEC_USE_COUNT;	return (EIO);}STATIC streamscall intsdl_close(queue_t *q, int flag, cred_t *crp){	(void) flag;	(void) crp;	sdl_free_priv(q);	MOD_DEC_USE_COUNT;	return (0);}/* *  ======================================================================== * *  PRIVATE struct allocation, deallocation and cache * *  ======================================================================== */STATIC kmem_cache_t *sdl_priv_cachep = NULL;STATIC intsdl_init_caches(void){	if (!sdl_priv_cachep	    && !(sdl_priv_cachep =		 kmem_cache_create("sdl_priv_cachep", sizeof(struct sdl), 0, SLAB_HWCACHE_ALIGN,				   NULL, NULL))) {		cmn_err(CE_PANIC, "%s: Cannot allocate sdl_priv_cachep", __FUNCTION__);		return (-ENOMEM);	}	printd(("%s: Allocated/selected private structure cache\n", MOD_NAME));	return (0);}STATIC intsdl_term_caches(void){	if (sdl_priv_cachep) {		if (kmem_cache_destroy(sdl_priv_cachep)) {			cmn_err(CE_WARN, "%s: id not destroy sdl_priv_cachep.", __FUNCTION__);			return (-EBUSY);		} else			printd(("%s: destroyed sdl_priv_cachep\n", MOD_NAME));	}	return (0);}STATIC struct sdl *sdl_alloc_priv(queue_t *q, struct sdl **sp, dev_t *devp, cred_t *crp){	struct sdl *s;	if ((s = kmem_cache_alloc(sdl_priv_cachep, SLAB_ATOMIC))) {		printd(("%s: %p: allocated module private structure\n", MOD_NAME, s));		bzero(s, sizeof(*s));		sdl_get(s);	/* first get */		s->u.dev.cmajor = getmajor(*devp);		s->u.dev.cminor = getminor(*devp);		s->cred = *crp;		(s->oq = RD(q))->q_ptr = sdl_get(s);		(s->iq = WR(q))->q_ptr = sdl_get(s);		spin_lock_init(&s->qlock);	/* "sdl-queue-lock" */		s->o_prim = &sdl_r_prim;		s->i_prim = &sdl_w_prim;		s->o_wakeup = NULL;	// &sdl_rx_wakeup;		s->i_wakeup = NULL;	// &sdl_tx_wakeup;		s->i_state = LMI_DISABLED;		s->i_style = LMI_STYLE1;		s->i_version = 1;		spin_lock_init(&s->qlock);	/* "sdl-priv_lock" */		if ((s->next = *sp))			s->next->prev = &s->next;		s->prev = sp;		*sp = sdl_get(s);		printd(("%s: %p: linked module private structure\n", MOD_NAME, s));		s->timestamp = jiffies;		s->tickbytes = s->config.ifrate / HZ / 8;		s->bytecount = 0;		/* 		   configuration defaults */		s->option = lmi_default;		s->config = sdl_default;		printd(("%s: %p: setting module private structure defaults\n", MOD_NAME, s));	} else		ptrace(("%s: ERROR: Could not allocate module private structure\n", MOD_NAME));	return (s);}STATIC voidsdl_free_priv(queue_t *q){	struct sdl *s = SDL_PRIV(q);	psw_t flags;	ensure(s, return);	spin_lock_irqsave(&s->lock, flags);	{		ss7_unbufcall((str_t *) s);		sdl_timer_stop(s, tall);		if ((*(s->prev) = s->next))			s->next->prev = s->prev;		s->next = NULL;		s->prev = &s->next;		sdl_put(s);		s->oq->q_ptr = NULL;		flushq(s->oq, FLUSHALL);		s->oq = NULL;		sdl_put(s);		s->iq->q_ptr = NULL;		flushq(s->iq, FLUSHALL);		s->iq = NULL;		sdl_put(s);	}	spin_unlock_irqrestore(&s->lock, flags);	sdl_put(s);		/* final put */}STATIC struct sdl *sdl_get(struct sdl *s){	atomic_inc(&s->refcnt);	return (s);}STATIC voidsdl_put(struct sdl *s){	if (atomic_dec_and_test(&s->refcnt)) {		kmem_cache_free(sdl_priv_cachep, s);		printd(("%s: %p: freed sdl private structure\n", MOD_NAME, s));	}}/* *  ========================================================================= * *  Registration and initialization * *  ========================================================================= */#ifdef LINUX/* *  Linux Registration *  ------------------------------------------------------------------------- */unsigned short modid = MOD_ID;#ifndef module_paramMODULE_PARM(modid, "h");#elsemodule_param(modid, ushort, 0);#endifMODULE_PARM_DESC(modid, "Module ID for the SDL module. (0 for allocation.)");/* *  Linux Fast-STREAMS Registration *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */#ifdef LFSSTATIC struct fmodsw sdl_fmod = {	.f_name = MOD_NAME,	.f_str = &sdlinfo,	.f_flag = 0,	.f_kmod = THIS_MODULE,};STATIC intsdl_register_strmod(void){	int err;	if ((err = register_strmod(&sdl_fmod)) < 0)		return (err);	return (0);}STATIC intsdl_unregister_strmod(void){	int err;	if ((err = unregister_strmod(&sdl_fmod)) < 0)		return (err);	return (0);}#endif				/* LFS *//* *  Linux STREAMS Registration *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */#ifdef LISSTATIC intsdl_register_strmod(void){	int err;	if ((err = lis_register_strmod(&sdlinfo, MOD_NAME)) == LIS_NULL_MID)		return (-EIO);	return (0);}STATIC intsdl_unregister_strmod(void){	int err;	if ((err = lis_unregister_strmod(&sdlinfo)) < 0)		return (err);	return (0);}#endif				/* LIS */MODULE_STATIC int __initsdlinit(void){	int err;	cmn_err(CE_NOTE, MOD_BANNER);	/* banner message */	if ((err = sdl_init_caches())) {		cmn_err(CE_WARN, "%s: could not init caches, err = %d", MOD_NAME, err);		return (err);	}	if ((err = sdl_register_strmod())) {		cmn_err(CE_WARN, "%s: could not register module, err = %d", MOD_NAME, err);		sdl_term_caches();		return (err);	}	if (modid == 0)		modid = err;	return (0);}MODULE_STATIC void __exitsdlterminate(void){	int err;	if ((err = sdl_unregister_strmod()))		cmn_err(CE_WARN, "%s: could not unregister module", MOD_NAME);	if ((err = sdl_term_caches()))		cmn_err(CE_WARN, "%s: could not terminate caches", MOD_NAME);	return;}/* *  Linux Kernel Module Initialization *  ------------------------------------------------------------------------- */module_init(sdlinit);module_exit(sdlterminate);#endif				/* LINUX */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -