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

📄 spm.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	case SDL_IOC_MAGIC:	{		if (count < size || PRIV(q)->state == LMI_UNATTACHED) {			ret = -EINVAL;			break;		}		switch (cmd) {		case SDL_IOCGOPTIONS:	/* lmi_option_t */			ret = sdl_iocgoptions(q, mp);			break;		case SDL_IOCSOPTIONS:	/* lmi_option_t */			ret = sdl_iocsoptions(q, mp);			break;		case SDL_IOCGCONFIG:	/* sdt_config_t */			ret = sdl_iocgconfig(q, mp);			break;		case SDL_IOCSCONFIG:	/* sdt_config_t */			ret = sdl_iocsconfig(q, mp);			break;		case SDL_IOCTCONFIG:	/* sdt_config_t */			ret = sdl_ioctconfig(q, mp);			break;		case SDL_IOCCCONFIG:	/* sdt_config_t */			ret = sdl_ioccconfig(q, mp);			break;		case SDL_IOCGSTATEM:	/* sdt_statem_t */			ret = sdl_iocgstatem(q, mp);			break;		case SDL_IOCCMRESET:	/* sdt_statem_t */			ret = sdl_ioccmreset(q, mp);			break;		case SDL_IOCGSTATSP:	/* lmi_sta_t */			ret = sdl_iocgstatsp(q, mp);			break;		case SDL_IOCSSTATSP:	/* lmi_sta_t */			ret = sdl_iocsstatsp(q, mp);			break;		case SDL_IOCGSTATS:	/* sdt_stats_t */			ret = sdl_iocgstats(q, mp);			break;		case SDL_IOCCSTATS:	/* sdt_stats_t */			ret = sdl_ioccstats(q, mp);			break;		case SDL_IOCGNOTIFY:	/* sdt_notify_t */			ret = sdl_iocgnotify(q, mp);			break;		case SDL_IOCSNOTIFY:	/* sdt_notify_t */			ret = sdl_iocsnotify(q, mp);			break;		case SDL_IOCCNOTIFY:	/* sdt_notify_t */			ret = sdl_ioccnotify(q, mp);			break;		default:			ret = -EOPNOTSUPP;			break;		}		ret = -EFAULT;		break;	}	default:		return (QR_PASSALONG);	}	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 *  ----------------------------------------------------------------------- */STATIC intspm_m_proto(queue_t *q, mblk_t *mp){	int rtn;	ulong prim;	spm_t *s = PRIV(q);	ulong oldstate = s->state;	if ((prim = *(ulong *) mp->b_rptr) == SDL_BITS_FOR_TRANSMISSION_REQ)		rtn = sdl_bits_for_transmission_req(q, mp);	else		switch (prim) {		case SDL_BITS_FOR_TRANSMISSION_REQ:			rtn = sdl_bits_for_transmission_req(q, mp);			break;		case SDL_CONNECT_REQ:			rtn = sdl_connect_req(q, mp);			break;		case SDL_DISCONNECT_REQ:			rtn = sdl_disconnect_req(q, mp);			break;		case LMI_INFO_REQ:			rtn = lmi_info_req(q, mp);			break;		case LMI_ATTACH_REQ:			rtn = lmi_attach_req(q, mp);			break;		case LMI_DETACH_REQ:			rtn = lmi_detach_req(q, mp);			break;		case LMI_ENABLE_REQ:			rtn = lmi_enable_req(q, mp);			break;		case LMI_DISABLE_REQ:			rtn = lmi_disable_req(q, mp);			break;		case LMI_OPTMGMT_REQ:			rtn = lmi_optmgmt_req(q, mp);			break;		default:			/* 			   pass along anything we don't recognize */			rtn = QR_PASSFLOW;			break;		}	if (rtn < 0)		s->state = oldstate;	return (rtn);}/* *  M_DATA Handling *  ------------------------------------------------------------------------- *  We need to throttle these to avoid locking up the processor.  The throttle *  is for 10 blocks every 10ms maximum which is precisely 64kbps. */STATIC void streamscallspm_w_timeout(caddr_t data){	queue_t *q = (queue_t *) data;	spm_t *s = PRIV(q);	if (!xchg(&s->wtim, 0))		return;	enableok(q);	qenable(q);	return;}STATIC void streamscallspm_r_timeout(caddr_t data){	queue_t *q = (queue_t *) data;	spm_t *s = PRIV(q);	if (!xchg(&s->rtim, 0))		return;	enableok(q);	qenable(q);	return;}STATIC INLINE intspm_w_data(queue_t *q, mblk_t *mp){	spm_t *s = PRIV(q);	if (s->wts == jiffies) {		if (s->wno++ >= 10) {			/* 			   come back in a tick */			s->wtim = timeout(&spm_w_timeout, (caddr_t) q, 1);			// printd(("spm: tx: blocking\n"));			return (QR_DISABLE);		}	} else {		s->wno = 1;		s->wts = jiffies;	}	return (QR_PASSFLOW);}STATIC INLINE intspm_r_data(queue_t *q, mblk_t *mp){	spm_t *s = PRIV(q);	if (s->rts == jiffies) {		if (s->rno++ >= 10) {			/* 			   come back in a tick */			s->rtim = timeout(&spm_r_timeout, (caddr_t) q, 1);			// printd(("spm: rx: blocking\n"));			return (QR_DISABLE);		}	} else {		s->rno = 1;		s->rts = jiffies;	}	return (QR_PASSFLOW);}/* *  M_RSE, M_PCRSE Handling *  ------------------------------------------------------------------------- */STATIC intspm_m_pcrse(queue_t *q, mblk_t *mp){	int rtn;	switch (*(ulong *) mp->b_rptr) {	default:		rtn = -EFAULT;		break;	}	return (rtn);}/* *  M_FLUSH Handling *  ------------------------------------------------------------------------- */STATIC INLINE intspm_m_flush(queue_t *q, mblk_t *mp, const uint8_t mflag){	if (*mp->b_rptr & mflag) {		if (*mp->b_rptr & FLUSHBAND)			flushband(q, mp->b_rptr[1], FLUSHALL);		else			flushq(q, FLUSHALL);	}	return (QR_LOOP);}STATIC intspm_w_flush(queue_t *q, mblk_t *mp){	return spm_m_flush(q, mp, FLUSHW);}STATIC intspm_r_flush(queue_t *q, mblk_t *mp){	return spm_m_flush(q, mp, FLUSHR);}/* *  ========================================================================= * *  PUT and SRV * *  ========================================================================= */STATIC INLINE streamscall intspm_r_prim(queue_t *q, mblk_t *mp){	/* 	   Fast Path */	if (mp->b_datap->db_type == M_DATA)		return spm_r_data(q, mp);	switch (mp->b_datap->db_type) {	case M_DATA:		return spm_r_data(q, mp);	case M_PROTO:	case M_PCPROTO:		return spm_m_proto(q, mp);	case M_RSE:	case M_PCRSE:		return spm_m_pcrse(q, mp);	case M_FLUSH:		return spm_r_flush(q, mp);	case M_IOCTL:		return spm_m_ioctl(q, mp);	}	return (QR_PASSFLOW);}STATIC INLINE streamscall intspm_w_prim(queue_t *q, mblk_t *mp){	/* 	   Fast Path */	if (mp->b_datap->db_type == M_DATA)		return spm_w_data(q, mp);	switch (mp->b_datap->db_type) {	case M_DATA:		return spm_w_data(q, mp);	case M_PROTO:	case M_PCPROTO:		return spm_m_proto(q, mp);	case M_RSE:	case M_PCRSE:		return spm_m_pcrse(q, mp);	case M_FLUSH:		return spm_w_flush(q, mp);	case M_IOCTL:		return spm_m_ioctl(q, mp);	}	return (QR_PASSFLOW);}STATIC streamscall voidspm_rx_wakeup(queue_t *q){}STATIC streamscall intspm_rput(queue_t *q, mblk_t *mp){	return (int) ss7_putq(q, mp, &spm_r_prim, &spm_rx_wakeup);}STATIC streamscall intspm_rsrv(queue_t *q){	return (int) ss7_srvq(q, &spm_r_prim, &spm_rx_wakeup);}STATIC streamscall voidspm_tx_wakeup(queue_t *q){}STATIC streamscall intspm_wput(queue_t *q, mblk_t *mp){	return (int) ss7_putq(q, mp, &spm_w_prim, &spm_tx_wakeup);}STATIC streamscall intspm_wsrv(queue_t *q){	return (int) ss7_srvq(q, &spm_w_prim, &spm_tx_wakeup);}/* *  ======================================================================= * *  OPEN and CLOSE * *  ======================================================================= */STATIC spm_t *spm_list = NULL;STATIC streamscall intspm_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){	int cmajor = getmajor(*devp);	int cminor = getminor(*devp);	spm_t *s, **sp = &spm_list;	(void) 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 == DRVOPEN || WR(q)->q_next == NULL) {		ptrace(("spm: ERROR: Can't open as driver\n"));		MOD_DEC_USE_COUNT;		return (EIO);	}	for (; *sp && (*sp)->cmajor < cmajor; sp = &(*sp)->next) ;	for (; *sp && (*sp)->cmajor == cmajor && (*sp)->cminor < cminor; sp = &(*sp)->next) ;	if (*sp && (*sp)->cmajor == cmajor && (*sp)->cminor == cminor) {		ptrace(("spm: ERROR: Multiple push\n"));		MOD_DEC_USE_COUNT;		return (ENXIO);	}	printd(("spm: Pushed module for char device %d:%d\n", cmajor, cminor));	if (!(s = spm_alloc_priv(q, sp, cmajor, cminor))) {		ptrace(("spm: ERROR: No cache memory\n"));		MOD_DEC_USE_COUNT;		return (ENOMEM);	}	return (0);}STATIC streamscall intspm_close(queue_t *q, int flag, cred_t *crp){	spm_t *s = PRIV(q);	(void) flag;	(void) crp;	(void) s;	printd(("spm: Popped module for char device %hu:%hu\n", (ushort) s->cmajor,		(ushort) s->cminor));	spm_free_priv(q);	MOD_DEC_USE_COUNT;	return (0);}/* *  ========================================================================= * *  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 SPM module. (0 for allocation.)");/* *  Linux Fast-STREAMS Registration *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */#ifdef LFSSTATIC struct fmodsw spm_fmod = {	.f_name = MOD_NAME,	.f_str = &spminfo,	.f_flag = 0,	.f_kmod = THIS_MODULE,};STATIC intspm_register_strmod(void){	int err;	if ((err = register_strmod(&spm_fmod)) < 0)		return (err);	return (0);}STATIC intspm_unregister_strmod(void){	int err;	if ((err = unregister_strmod(&spm_fmod)) < 0)		return (err);	return (0);}#endif				/* LFS *//* *  Linux STREAMS Registration *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */#ifdef LISSTATIC intspm_register_strmod(void){	int err;	if ((err = lis_register_strmod(&spminfo, MOD_NAME)) == LIS_NULL_MID)		return (-EIO);	return (0);}STATIC intspm_unregister_strmod(void){	int err;	if ((err = lis_unregister_strmod(&spminfo)) < 0)		return (err);	return (0);}#endif				/* LIS */MODULE_STATIC int __initspminit(void){	int err;	cmn_err(CE_NOTE, MOD_BANNER);	/* banner message */	if ((err = spm_init_caches())) {		cmn_err(CE_WARN, "%s: could not init caches, err = %d", MOD_NAME, err);		return (err);	}	if ((err = spm_register_strmod())) {		cmn_err(CE_WARN, "%s: could not register module, err = %d", MOD_NAME, err);		spm_term_caches();		return (err);	}	if (modid == 0)		modid = err;	return (0);}MODULE_STATIC void __exitspmterminate(void){	int err;	if ((err = spm_unregister_strmod()))		cmn_err(CE_WARN, "%s: could not unregister module", MOD_NAME);	if ((err = spm_term_caches()))		cmn_err(CE_WARN, "%s: could not terminate caches", MOD_NAME);	return;}/* *  Linux Kernel Module Initialization *  ------------------------------------------------------------------------- */module_init(spminit);module_exit(spmterminate);#endif				/* LINUX */

⌨️ 快捷键说明

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