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

📄 sl_mux.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 2 页
字号:
		*x++ = (tlen << 4) & 0xf0;		for (i = 0; i < tlen; i++)			*x++ = tbyte;		mp->b_wptr = x;		__printd(("mtp: Sent SLTM\n"));		qreply(q, mp);	}	ls->sltm_timer = timeout(&failed_sltm, (caddr_t) q, 4 * HZ);	/* T1T */}STATIC inthandle_message(queue_t *q, mblk_t *mp){	struct ls *ls = (struct ls *) q->q_ptr;	unsigned char *x = mp->b_rptr;	uint sio, dpc, opc, sls, h0, h1, b;	int i;	__printd(("mtp: M_DATA: "));	for (i = 0; i < mp->b_wptr - mp->b_rptr; i++)		__printd(("%02x ", x[i] & 0x0ff));	__printd(("\n"));	sio = *x++;	if ((sio & 0xf) == 1 || (sio & 0xf) == 2) {		ptrace(("Got Test Message\n"));		b = *x++ & 0x00ff;		dpc = ((b << 0) & 0xff);		b = *x++ & 0x00ff;		dpc |= ((b << 8) & 0x3f00);		opc = ((b >> 6) & 0x03);		b = *x++ & 0x00ff;		opc |= ((b << 2) & 0x3fc);		b = *x++ & 0x00ff;		opc |= ((b << 10) & 0x3c00);		sls = (b >> 4) & 0x0f;		b = *x++ & 0x00ff;		h0 = b & 0x0f;		h1 = b >> 4;		if (h0 == 1 && h1 == 1) {			mblk_t *dp;			__printd(("mtp: Got SLTM\n"));			if ((dp = copymsg(mp))) {				x = dp->b_rptr;				h1 = 2;				x++;				*x++ = opc;				*x++ = ((opc >> 8) & 0x3f) | (dpc << 6);				*x++ = (dpc >> 2);				*x++ = ((dpc >> 10) & 0x0f) | (sls << 4);				*x++ = h0 | (h1 << 4);				/* 				   send back */				__printd(("mtp: Sent SLTA\n"));				qreply(q, dp);				freemsg(mp);				return (1);			}		} else if (h0 == 1 && h1 == 2) {			__printd(("mtp: Got SLTA\n"));			if (ls->sltm_timer)				untimeout(ls->sltm_timer);			ls->sltm_failures = 0;			ls->sltm_timer = timeout(&send_sltm, (caddr_t) q, 2 * 60 * HZ);	/* T2T */		}	}	return (0);}/* *  ========================================================================= * *  STREAMS Message Handling * *  ========================================================================= *//* *  ------------------------------------------------------------------------- * *  M_DATA Handling * *  ------------------------------------------------------------------------- */STATIC intsl_r_data(queue_t *q, mblk_t *mp){	if (handle_message(q, mp))		return (QR_ABSORBED);	return (QR_PASSFLOW);}/* *  ------------------------------------------------------------------------- * *  M_PROTO, M_PCPROTO Handling * *  ------------------------------------------------------------------------- */STATIC intsl_r_proto(queue_t *q, mblk_t *mp){	struct ls *ls = (struct ls *) q->q_ptr;	ptrace(("Got M_PROTO = %ld\n", *(long *) mp->b_rptr));	switch (*(long *) mp->b_rptr) {	case SL_OUT_OF_SERVICE_IND:		__printd(("mtp: Got SL_OUT_OF_SERVICE_IND\n"));		if (ls->sltm_timer)			untimeout(xchg(&ls->sltm_timer, 0));		if (ls->recovery_timer)			untimeout(xchg(&ls->recovery_timer, 0));		if (!ls->recovery_attempts)			restart_link((caddr_t) q);		else			ls->recovery_timer = timeout(&restart_link, (caddr_t) q, 1 * HZ);	/* T17 												 */		return (QR_DONE);	case SL_PDU_IND:		__printd(("mtp: Got SL_PDU_IND\n"));		if (handle_message(q, mp->b_cont))			return (QR_TRIMMED);		break;	case SL_IN_SERVICE_IND:		__printd(("mtp: Got SL_IN_SERVICE_IND\n"));		ls->recovery_attempts = 0;		send_sltm((caddr_t) q);		return (QR_DONE);	}	return (QR_PASSFLOW);}/* *  ------------------------------------------------------------------------- * *  M_IOCTL Handling * *  ------------------------------------------------------------------------- */STATIC intsl_w_ioctl(queue_t *q, mblk_t *mp){	struct sl *sl = SL_PRIV(q);	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 type = _IOC_TYPE(cmd), nr = _IOC_NR(cmd), size = _IOC_SIZE(cmd);	int ret = 0;	(void) sl;	(void) size;	(void) count;	switch (type) {	case _IOC_TYPE(__SID):	{		psw_t flags;		struct ls *ls, **lpp;		struct linkblk *lb = (struct linkblk *) arg;		if (lb == NULL) {			swerr();			ret = -EINVAL;			break;		}		switch (nr) {		case _IOC_NR(I_PLINK):			ptrace(("%s: %p: I_PLINK\n", DRV_NAME, sl));			if (iocp->ioc_cr->cr_uid != 0) {				ptrace(("%s: %p: ERROR: Non-root attempt to I_PLINK\n", DRV_NAME,					sl));				ret = -EPERM;				break;			}		case _IOC_NR(I_LINK):			ptrace(("%s: %p: I_LINK\n", DRV_NAME, sl));			MOD_INC_USE_COUNT;	/* keep module from unloading */			spin_lock_irqsave(&master.lock, flags);			{				/* place in list in ascending index order */				for (lpp = &master.ls.list;				     *lpp && (*lpp)->u.mux.index < lb->l_index;				     lpp = &(*lpp)->next) ;				if ((ls = slm_alloc_ls(lb->l_qbot, lpp, lb->l_index, iocp->ioc_cr))) {					spin_unlock_irqrestore(&master.lock, flags);					break;				}				MOD_DEC_USE_COUNT;				ret = -ENOMEM;			}			spin_unlock_irqrestore(&master.lock, flags);			break;		case _IOC_NR(I_PUNLINK):			ptrace(("%s: %p: I_PUNLINK\n", DRV_NAME, sl));			if (iocp->ioc_cr->cr_uid != 0) {				ptrace(("%s: %p: ERROR: Non-root attempt to I_PUNLINK\n", DRV_NAME,					sl));				ret = -EPERM;				break;			}		case _IOC_NR(I_UNLINK):			ptrace(("%s: %p: I_UNLINK\n", DRV_NAME, sl));			spin_lock_irqsave(&master.lock, flags);			{				for (ls = master.ls.list; ls; ls = ls->next)					if (ls->u.mux.index == lb->l_index)						break;				if (ls == NULL) {					ret = -EINVAL;					ptrace(("%s: %p: ERROR: Couldn't find I_UNLINK muxid %u\n",						DRV_NAME, sl, lb->l_index));					spin_unlock_irqrestore(&master.lock, flags);					break;				}				slm_free_ls(ls->iq);				MOD_DEC_USE_COUNT;			}			spin_unlock_irqrestore(&master.lock, flags);			break;		default:		case _IOC_NR(I_STR):			ptrace(("%s: %p: ERROR: Unsupported STREAMS ioctl %c, %d\n", DRV_NAME, sl,				(char) type, nr));			ret = -EOPNOTSUPP;			break;		}		break;	}	default:		ptrace(("%s: %p: ERROR: Unsupported ioctl %c, %d\n", DRV_NAME, sl, (char) type,			nr));		ret = -EOPNOTSUPP;		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);}/* *  ------------------------------------------------------------------------- * *  Message Handling * *  ------------------------------------------------------------------------- *//* *  UPPER MUX Queues *  ----------------------------------- */STATIC streamscall intsl_r_prim(queue_t *q, mblk_t *mp){	switch (mp->b_datap->db_type) {	case M_FLUSH:		return ss7_r_flush(q, mp);	default:		return (QR_PASSFLOW);	}}STATIC streamscall intsl_w_prim(queue_t *q, mblk_t *mp){	switch (mp->b_datap->db_type) {	case M_IOCTL:		return sl_w_ioctl(q, mp);	case M_FLUSH:		return ss7_w_flush(q, mp);	default:		return (QR_PASSFLOW);	}}/* *  LOWER MUX Queues *  ----------------------------------- */STATIC streamscall intls_r_prim(queue_t *q, mblk_t *mp){	switch (mp->b_datap->db_type) {	case M_DATA:		return sl_r_data(q, mp);	case M_PROTO:	case M_PCPROTO:		return sl_r_proto(q, mp);	case M_FLUSH:		return ss7_r_flush(q, mp);	default:		return (QR_PASSFLOW);	}}STATIC streamscall intls_w_prim(queue_t *q, mblk_t *mp){	switch (mp->b_datap->db_type) {	case M_FLUSH:		return ss7_w_flush(q, mp);	default:		return (QR_PASSFLOW);	}}/* *  ========================================================================= * *  OPEN and CLOSE * *  ========================================================================= */STATIC major_t slm_majors[CMAJORS] = { CMAJOR_0, };/* *  OPEN *  ------------------------------------------------------------------------- */STATIC streamscall intsl_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp){	psw_t flags;	int mindex = 0;	major_t cmajor = getmajor(*devp);	minor_t cminor = getminor(*devp);	struct sl *sl, **spp;	MOD_INC_USE_COUNT;	if (q->q_ptr != NULL) {		MOD_DEC_USE_COUNT;		return (0);	/* already open */	}	if (sflag == MODOPEN || WR(q)->q_next) {		ptrace(("%s: ERROR: cannot push as module\n", DRV_NAME));		MOD_DEC_USE_COUNT;		return (EIO);	}	if (cmajor != CMAJOR_0 || cminor > 0) {		MOD_DEC_USE_COUNT;		return (ENXIO);	}	/* allocate a new device */	cminor = 1;	spin_lock_irqsave(&master.lock, flags);	for (spp = &master.sl.list; *spp; spp = &(*spp)->next) {		major_t dmajor = (*spp)->u.dev.cmajor;		if (cmajor != dmajor)			break;		if (cmajor == dmajor) {			minor_t dminor = (*spp)->u.dev.cminor;			if (cminor < dminor)				break;			if (cminor > dminor)				continue;			if (cminor == dminor) {				if (++cminor >= NMINORS) {					if (++mindex >= CMAJORS || !(cmajor = slm_majors[mindex]))						break;					cminor = 0;				}				continue;			}		}	}	if (mindex >= CMAJORS || !cmajor) {		ptrace(("%s: ERROR: no device numbers available\n", DRV_NAME));		spin_unlock_irqrestore(&master.lock, flags);		MOD_DEC_USE_COUNT;		return (ENXIO);	}	printd(("%s: opened character device %hu:%hu\n", DRV_NAME, cmajor, cminor));	*devp = makedevice(cmajor, cminor);	if (!(sl = slm_alloc_sl(q, spp, cmajor, cminor, crp))) {		ptrace(("%s: ERROR: no memory\n", DRV_NAME));		spin_unlock_irqrestore(&master.lock, flags);		MOD_DEC_USE_COUNT;		return (ENOMEM);	}	spin_unlock_irqrestore(&master.lock, flags);	return (0);}/* *  CLOSE *  ------------------------------------------------------------------------- */STATIC streamscall intsl_close(queue_t *q, int sflag, cred_t *crp){	struct sl *sl = SL_PRIV(q);	psw_t flags;	(void) sl;	printd(("%s: %p: closing character device %hu:%hu\n", DRV_NAME, sl, sl->u.dev.cmajor,		sl->u.dev.cminor));	spin_lock_irqsave(&master.lock, flags);	{		slm_free_sl(q);	}	spin_unlock_irqrestore(&master.lock, flags);	MOD_DEC_USE_COUNT;	return (0);}/* *  ========================================================================= * *  Registration and initialization * *  ========================================================================= */#ifdef LINUX/* *  Linux Registration *  ------------------------------------------------------------------------- */unsigned short modid = DRV_ID;#ifndef module_paramMODULE_PARM(modid, "h");#elsemodule_param(modid, ushort, 0);#endifMODULE_PARM_DESC(modid, "Module ID for the SDL-MUX driver. (0 for allocation.)");major_t major = CMAJOR_0;#ifndef module_paramMODULE_PARM(major, "h");#elsemodule_param(major, uint, 0);#endifMODULE_PARM_DESC(major, "Device number for the SDL-MUX driver. (0 for allocation.)");/* *  Linux Fast-STREAMS Registration *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */#ifdef LFSSTATIC struct cdevsw slm_cdev = {	.d_name = DRV_NAME,	.d_str = &sl_muxinfo,	.d_flag = 0,	.d_fop = NULL,	.d_mode = S_IFCHR,	.d_kmod = THIS_MODULE,};STATIC intslm_register_strdev(major_t major){	int err;	if ((err = register_strdev(&slm_cdev, major)) < 0)		return (err);	return (0);}STATIC intslm_unregister_strdev(major_t major){	int err;	if ((err = unregister_strdev(&slm_cdev, major)) < 0)		return (err);	return (0);}#endif				/* LFS *//* *  Linux STREAMS Registration *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */#ifdef LISSTATIC intslm_register_strdev(major_t major){	int err;	if ((err = lis_register_strdev(major, &sl_muxinfo, UNITS, DRV_NAME)) < 0)		return (err);	return (0);}STATIC intslm_unregister_strdev(major_t major){	int err;	if ((err = lis_unregister_strdev(major)) < 0)		return (err);	return (0);}#endif				/* LIS */MODULE_STATIC void __exitsl_muxterminate(void){	int err, mindex;	for (mindex = CMAJORS - 1; mindex >= 0; mindex--) {		if (slm_majors[mindex]) {			if ((err = slm_unregister_strdev(slm_majors[mindex])))				cmn_err(CE_PANIC, "%s: cannot unregister major %d", DRV_NAME,					slm_majors[mindex]);			if (mindex)				slm_majors[mindex] = 0;		}	}	if ((err = slm_term_caches()))		cmn_err(CE_WARN, "%s: could not terminate caches", DRV_NAME);	return;}MODULE_STATIC int __initsl_muxinit(void){	int err, mindex = 0;	cmn_err(CE_NOTE, DRV_BANNER);	/* console splash */	if ((err = slm_init_caches())) {		cmn_err(CE_WARN, "%s: could not init caches, err = %d", DRV_NAME, err);		sl_muxterminate();		return (err);	}	for (mindex = 0; mindex < CMAJORS; mindex++) {		if ((err = slm_register_strdev(slm_majors[mindex])) < 0) {			if (mindex) {				cmn_err(CE_WARN, "%s: could not register major %d", DRV_NAME,					slm_majors[mindex]);				continue;			} else {				cmn_err(CE_WARN, "%s: could not register driver, err = %d",					DRV_NAME, err);				sl_muxterminate();				return (err);			}		}		if (slm_majors[mindex] == 0)			slm_majors[mindex] = err;#if 0		LIS_DEVFLAGS(slm_majors[mindex]) |= LIS_MODFLG_CLONE;#endif		if (major == 0)			major = slm_majors[0];	}	return (0);}/* *  Linux Kernel Module Initialization *  ------------------------------------------------------------------------- */module_init(sl_muxinit);module_exit(sl_muxterminate);#endif				/* LINUX */

⌨️ 快捷键说明

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