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

📄 sdl.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 4 页
字号:
		mp->b_wptr += sizeof(*p);		p->sdl_primitive = SDL_DISCONNECT_IND;		putnext(s->oq, mp);		return (QR_DONE);	}	rare();	return (-ENOBUFS);}#endif/* *  ========================================================================= * *  PROTOCOL STATE MACHINE FUNCTIONS * *  ========================================================================= *//* *  ------------------------------------------------------------------------- * *  Timers * *  ------------------------------------------------------------------------- */enum { tall, t9 };STATIC int sdl_t9_timeout(struct sdl *);STATIC void streamscallsdl_t9_expiry(caddr_t data){	ss7_do_timeout(data, "t9", "sdl", &((struct sdl *) data)->timers.t9,		       (int (*)(struct head *)) &sdl_t9_timeout, &sdl_t9_expiry);}STATIC voidsdl_stop_timer_t9(struct sdl *s){	ss7_stop_timer((struct head *) s, "t9", "sdl", &s->timers.t9);}STATIC voidsdl_start_timer_t9(struct sdl *s){	ss7_start_timer((struct head *) s, "t9", "sdl", &s->timers.t9, &sdl_t9_expiry,			s->timestamp - jiffies);};STATIC INLINE void__sdl_timer_stop(struct sdl *s, const uint t){	int single = 1;	switch (t) {	case tall:		single = 0;		/* 		   fall through */	case t9:		sdl_stop_timer_t9(s);		if (single)			break;		/* 		   fall through */		break;	default:		swerr();		break;	}}STATIC INLINE voidsdl_timer_stop(struct sdl *s, const uint t){	psw_t flags;	spin_lock_irqsave(&s->lock, flags);	{		__sdl_timer_stop(s, t);	}	spin_unlock_irqrestore(&s->lock, flags);}STATIC INLINE voidsdl_timer_start(struct sdl *s, const uint t){	psw_t flags;	spin_lock_irqsave(&s->lock, flags);	{		__sdl_timer_stop(s, t);		switch (t) {		case t9:			sdl_start_timer_t9(s);			break;		default:			swerr();			break;		}	}	spin_unlock_irqrestore(&s->lock, flags);}/* *  ------------------------------------------------------------------------- * *  State Machine * *  ------------------------------------------------------------------------- *//* *  ======================================================================== * *  EVENTS * *  ======================================================================== *//* *  ------------------------------------------------------------------------- * *  Timer Events * *  ------------------------------------------------------------------------- *//* *  T10 EXPIRY *  ----------------------------------- */STATIC intsdl_t9_timeout(struct sdl *s){	/* 	   wakeup the write queue */	qenable(s->iq);	return (QR_DONE);}/* *  ------------------------------------------------------------------------- * *  LM User -> LM Provider Primitives * *  ------------------------------------------------------------------------- *//* *  LMI_INFO_REQ: *  ----------------------------------- */STATIC intlmi_info_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	lmi_info_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	return lmi_info_ack(q, s);      emsgsize:	return lmi_error_ack(q, s, LMI_INFO_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_ATTACH_REQ: *  ----------------------------------- */STATIC intlmi_attach_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	lmi_attach_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_style != LMI_STYLE2)		goto eopnotsupp;	if (s->i_state != LMI_UNATTACHED)		goto outstate;	if (mp->b_wptr < mp->b_rptr + sizeof(*p) + 2)		goto badppa;	s->i_state = LMI_ATTACH_PENDING;	return lmi_ok_ack(q, s, LMI_ATTACH_REQ);      badppa:	ptrace(("%s: %p: PROTO: bad ppa (too short)\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_BADPPA, EMSGSIZE);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_OUTSTATE, EPROTO);      eopnotsupp:	ptrace(("%s: %p: PROTO: primitive not supported for style\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_NOTSUPP, EOPNOTSUPP);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_DETACH_REQ: *  ----------------------------------- */STATIC intlmi_detach_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	lmi_detach_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_style != LMI_STYLE2)		goto eopnotsupp;	if (s->i_state != LMI_DISABLED)		goto outstate;	s->i_state = LMI_DETACH_PENDING;	return lmi_ok_ack(q, s, LMI_DETACH_REQ);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DETACH_REQ, LMI_OUTSTATE, EPROTO);      eopnotsupp:	ptrace(("%s: %p: PROTO: primitive not supported for style\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DETACH_REQ, LMI_NOTSUPP, EOPNOTSUPP);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DETACH_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_ENABLE_REQ: *  ----------------------------------- */STATIC intlmi_enable_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	lmi_enable_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_state != LMI_DISABLED)		goto outstate;	s->i_state = LMI_ENABLE_PENDING;	return lmi_enable_con(q, s);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ENABLE_REQ, LMI_OUTSTATE, EPROTO);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ENABLE_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_DISABLE_REQ: *  ----------------------------------- */STATIC intlmi_disable_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	lmi_disable_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_state != LMI_ENABLED)		goto outstate;	s->i_state = LMI_DISABLE_PENDING;	return lmi_disable_con(q, s);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DISABLE_REQ, LMI_OUTSTATE, EPROTO);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DISABLE_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_OPTMGMT_REQ: *  ----------------------------------- */STATIC intlmi_optmgmt_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	lmi_optmgmt_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	goto eopnotsupp;      eopnotsupp:	ptrace(("%s: %p: PROTO: primitive not supported\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_OPTMGMT_REQ, LMI_NOTSUPP, EOPNOTSUPP);      emsgsize:	(void) s;	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_OPTMGMT_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  ------------------------------------------------------------------------- * *  SDL User -> SDL Provider Primitives * *  ------------------------------------------------------------------------- *//* *  M_DATA *  ----------------------------------- */STATIC intsdl_send_data(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	int size;	if (s->i_state != LMI_ENABLED)		goto outstate;	if (s->timestamp > jiffies) {		printd(("%s: %p: %s sleeping for %ld ms\n", MOD_NAME, s, __FUNCTION__,			s->timestamp - jiffies));		sdl_timer_start(s, t9);		return (-EAGAIN);	}	if (s->timestamp < jiffies) {		s->bytecount = 0;		s->timestamp = jiffies;		s->stats.tx_underruns++;	}	if (s->statem.tx_state != SDL_STATE_IDLE) {		size = msgdsize(mp);	} else {		/* 		   idle when transmitter shut down */		mblk_t *dp;		for (size = 0, dp = mp; dp; dp = dp->b_cont) {			if (dp->b_wptr > dp->b_rptr) {				int len = dp->b_wptr - dp->b_rptr;				size += len;				memset(dp->b_rptr, 0xff, len);			}		}	}	putnext(s->iq, mp);	s->stats.tx_octets += size;	s->bytecount += size;	ensure(s->tickbytes > 0, s->tickbytes = 1);	while (s->bytecount >= s->tickbytes) {		s->bytecount -= s->tickbytes;		s->timestamp++;	}	return (QR_ABSORBED);      outstate:	return (-EPROTO);	/* ignore */}/* *  SDL_BITS_FOR_TRANSMISSION_REQ *  ----------------------------------- *  This is the non-preferred way of sending data.  It is preferred that *  M_DATA blocks are used (above).  We just strip off the M_PROTO and requeue *  only the M_DATA blocks. */STATIC intsdl_bits_for_transmission_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	sdl_bits_for_transmission_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_state != LMI_ENABLED)		goto outstate;	if (!mp->b_cont || mp->b_cont->b_datap->db_type != M_DATA)		goto eproto;	trace();	return (QR_STRIP);      eproto:	ptrace(("%s: %p: ERROR: bad message\n", MOD_NAME, s));	return m_error(q, s, EPROTO);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return m_error(q, s, EPROTO);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return m_error(q, s, EPROTO);}/* *  SDL_CONNECT_REQ: *  ----------------------------------- */STATIC intsdl_connect_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	sdl_connect_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_state != LMI_ENABLED)		goto outstate;	s->statem.tx_state = SDL_STATE_IN_SERVICE;	s->statem.rx_state = SDL_STATE_IN_SERVICE;	return (QR_DONE);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return m_error(q, s, EPROTO);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return m_error(q, s, EPROTO);}/* *  SDL_DISCONNECT_REQ: *  ----------------------------------- */STATIC intsdl_disconnect_req(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	sdl_connect_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_state != LMI_ENABLED)		goto outstate;	s->statem.tx_state = SDL_STATE_IDLE;	s->statem.rx_state = SDL_STATE_IDLE;	return (QR_DONE);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return m_error(q, s, EPROTO);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return m_error(q, s, EPROTO);}/* *  ------------------------------------------------------------------------- * *  SDL-Provider -> SDL-User Primitives * *  ------------------------------------------------------------------------- *//* *  M_DATA *  ----------------------------------- */STATIC intsdl_recv_data(queue_t *q, mblk_t *mp){	struct sdl *s = SDL_PRIV(q);	int size;	if (s->i_state != LMI_ENABLED)		goto outstate;	if (s->statem.rx_state != SDL_STATE_IDLE) {		size = msgdsize(mp);	} else {		/* 		   idle when receiver shut down */		mblk_t *dp;		for (size = 0, dp = mp; dp; dp = dp->b_cont) {			if (dp->b_wptr > dp->b_rptr) {				int len = dp->b_wptr - dp->b_rptr;				size += len;				memset(dp->b_rptr, 0xff, len);			}		}	}	s->stats.rx_octets += size;	putnext(s->oq, mp);	return (QR_ABSORBED);      outstate:	return (QR_DONE);	/* ignore */}/* *  ========================================================================= * *  IO Controls * *  ========================================================================= * *  LM IO Controls * *  ------------------------------------------------------------------------- */STATIC intlmi_test_config(struct sdl *sdl, lmi_config_t * arg){	return (-EOPNOTSUPP);}STATIC intlmi_commit_config(struct sdl *sdl, lmi_config_t * arg){	return (-EOPNOTSUPP);}STATIC intlmi_iocgoptions(queue_t *q, mblk_t *mp){	if (mp->b_cont) {		struct sdl *s = SDL_PRIV(q);		int ret = 0;		psw_t flags;		lmi_option_t *arg = (typeof(arg)) mp->b_cont->b_rptr;		spin_lock_irqsave(&s->lock, flags);		{			*arg = s->option;		}		spin_unlock_irqrestore(&s->lock, flags);		return (ret);	}	rare();	return (-EINVAL);}STATIC intlmi_iocsoptions(queue_t *q, mblk_t *mp){	if (mp->b_cont) {		struct sdl *s = SDL_PRIV(q);		int ret = 0;		psw_t flags;		lmi_option_t *arg = (typeof(arg)) mp->b_cont->b_rptr;		spin_lock_irqsave(&s->lock, flags);		{			s->option = *arg;		}		spin_unlock_irqrestore(&s->lock, flags);		return (ret);	}	rare();	return (-EINVAL);}STATIC intlmi_iocgconfig(queue_t *q, mblk_t *mp){	if (mp->b_cont) {		struct sdl *s = SDL_PRIV(q);		psw_t flags;		lmi_config_t *arg = (typeof(arg)) mp->b_cont->b_rptr;		spin_lock_irqsave(&s->lock, flags);		{			arg->version = s->i_version;			arg->style = s->i_style;		}		spin_unlock_irqrestore(&s->lock, flags);

⌨️ 快捷键说明

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