OpenSS7
SS7 for the
Common Man

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified:

Home Overview Status News Documentation Resources About
   
 Overview
 Status
 News
 Documentation
 Resources
 About

   
Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/str/queue.h


File /code/strss7/drivers/str/queue.h

#ifndef __QUEUE_H__
#define __QUEUE_H__

#pragma interface

#ident "@(#) $RCSfile: queue.h,v $ $Name:  $($Revision: 0.8.2.2 $) $Date: 2003/02/24 13:00:46 $"

class qp {
      protected:
	static int (qp::*r_ops[M_STOPI + 1]) (queue_t *, mblk_t *);
	static int (qp::*w_ops[M_STOPI + 1]) (queue_t *, mblk_t *);
	static inline int recov(queue_t * q, mblk_t * mp, int err) {
		switch (err) {
		case -EBUSY:
		case -EAGAIN:
		case -ENOMEM:
		case -ENOBUFS:
			putq(q, mp);
			return (0);
		}
	};
	static inline int resrv(queue_t * q, mblk_t * mp, int err) {
		if (mp->b_datap->db_type < QPCTL)
			switch (err) {
			case -EBUSY:
			case -EAGAIN:
			case -ENOMEM:
			case -ENOBUFS:
				putbq(q, mp);
				return (0);
			}
		freemsg(mp);
		return (err);
	};
	inline int m_r_op(queue_t * q, mblk_t * mp) {
		uint type = mp->b_datap->db_type;
		if (type <= M_STOPI && r_ops[type])
			return ((this->*r_ops[type]) (q, mp));
		if (q->q_next) {
			if (mp->b_datap->db_type < QPCTL && !canputnext(q))
				return (-EBUSY);
			putnext(q, mp);
			return (0);
		}
		return (-EOPNOTSUPP);
	};
	inline int m_w_op(queue_t * q, mblk_t * mp) {
		uint type = mp->b_datap->db_type;
		if (type <= M_STOPI && w_ops[type])
			return ((this->*w_ops[type]) (q, mp));
		if (q->q_next) {
			if (mp->b_datap->db_type < QPCTL && !canputnext(q))
				return (-EBUSY);
			putnext(q, mp);
			return (0);
		}
		return (-EOPNOTSUPP);
	};
      public:
	queue_t * rq;		
	queue_t *wq;			/* write queue */
      qp(queue_t * q):rq(RD(q)), wq(WR(q)) {
		rq->q_ptr = wq->q_ptr = this;
	};
	virtual ~ qp(void) {
		rq->q_ptr = wq->q_ptr = NULL;
	};
	inline void *operator new(size_t s) {
		void *addr;
		if ((addr = kmalloc(s, GFP_KERNEL)))
			bzero(addr, s);
		return (addr);
	};
	inline void *operator new(size_t s, void *addr) {
		bzero(addr, s);
		return (addr);
	};
	inline void operator delete(void *m) {
		kfree(m);
	};
	inline virtual int rput(queue_t * q, mblk_t * mp) {
		qp *qp;
		int err;
		if (mp->b_datap->db_type < QPCTL || q->q_count) {
			putq(q, mp);
			return (0);
		}
		if (!(qp = (class qp *) q->q_ptr))
			return (-EFAULT);
		if ((err = m_r_op(q, mp)))
			return (recov(q, mp, err));
		return (0);
	};
	inline virtual int rsrv(queue_t * q) {
		qp *qp;
		int err;
		mblk_t *mp;
		if (!(qp = (class qp *) q->q_ptr))
			return (-EFAULT);
		while ((mp = getq(q)))
			if ((err = m_r_op(q, mp)))
				return (resrv(q, mp, err));
		return (0);
	};
	inline virtual int wput(queue_t * q, mblk_t * mp) {
		qp *qp;
		int err;
		if (mp->b_datap->db_type < QPCTL || q->q_count) {
			putq(q, mp);
			return (0);
		}
		if (!(qp = (class qp *) q->q_ptr))
			return (-EFAULT);
		if ((err = m_w_op(q, mp)))
			return (recov(q, mp, err));
		return (0);
	};
	inline virtual int wsrv(queue_t * q) {
		qp *qp;
		int err;
		mblk_t *mp;
		if (!(qp = (class qp *) q->q_ptr))
			return (-EFAULT);
		while ((mp = getq(q)))
			if ((err = m_w_op(q, mp)))
				return (resrv(q, mp, err));
		return (0);
	};
	static inline int q_rput(queue_t * q, mblk_t * mp) {
		qp *qp;
		if (!(qp = (class qp *) (q->q_ptr)))
			return (-EFAULT);
		return (qp->rput(q, mp));
	};
	static inline int q_rsrv(queue_t * q) {
		qp *qp;
		if (!(qp = (class qp *) (q->q_ptr)))
			return (-EFAULT);
		return (qp->rsrv(q));
	};
	static inline int q_wput(queue_t * q, mblk_t * mp) {
		qp *qp;
		if (!(qp = (class qp *) (q->q_ptr)))
			return (-EFAULT);
		return (qp->wput(q, mp));
	};
	static inline int q_wsrv(queue_t * q) {
		qp *qp;
		if (!(qp = (class qp *) (q->q_ptr)))
			return (-EFAULT);
		return (qp->wsrv(q));
	};
	inline virtual int m_r_data(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_proto(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_break(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_ctl(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_delay(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_ioctl(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_passfp(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_rse(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_setopts(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_sig(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_copyin(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_copyout(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_error(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_flush(queue_t * q, mblk_t * mp) {
		if (*mp->b_rptr & FLUSHR) {
			if (*mp->b_rptr & FLUSHBAND)
				flushband(q, mp->b_rptr[1], FLUSHALL);
			else
				flushq(q, FLUSHALL);
			if (q->q_next) {
				putnext(q, mp);
				return (0);
			}
			*mp->b_rptr &= ~FLUSHR;
		}
		if (*mp->b_rptr & FLUSHW && !(mp->b_flag & MSGNOLOOP)) {
			if (*mp->b_rptr & FLUSHBAND)
				flushband(WR(q), mp->b_rptr[1], FLUSHALL);
			else
				flushq(WR(q), FLUSHALL);
			if (WR(q)->q_next) {
				mp->b_flag |= MSGNOLOOP;
				qreply(q, mp);
				return (0);
			}
		}
		freemsg(mp);
		return (0);
	};
	inline virtual int m_r_hangup(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_iocack(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_iocnak(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_iocdata(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_pcproto(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_pcrse(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_pcsig(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_read(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_stop(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_start(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_starti(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_r_stopi(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};

	inline virtual int m_w_data(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_proto(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_break(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_ctl(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_delay(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_ioctl(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_passfp(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_rse(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_setopts(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_sig(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_copyin(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_copyout(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_error(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_flush(queue_t * q, mblk_t * mp) {
		if (*mp->b_rptr & FLUSHW) {
			if (*mp->b_rptr & FLUSHBAND)
				flushband(q, mp->b_rptr[1], FLUSHALL);
			else
				flushq(q, FLUSHALL);
			if (q->q_next) {
				putnext(q, mp);
				return (0);
			}
			*mp->b_rptr &= ~FLUSHW;
		}
		if (*mp->b_rptr & FLUSHR && !(mp->b_flag & MSGNOLOOP)) {
			if (*mp->b_rptr & FLUSHBAND)
				flushband(RD(q), mp->b_rptr[1], FLUSHALL);
			else
				flushq(RD(q), FLUSHALL);
			if (RD(q)->q_next) {
				mp->b_flag |= MSGNOLOOP;
				qreply(q, mp);
				return (0);
			}
		}
		freemsg(mp);
		return (0);
	};
	inline virtual int m_w_hangup(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_iocack(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_iocnak(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_iocdata(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_pcproto(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_pcrse(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_pcsig(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_read(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_stop(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_start(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_starti(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
	inline virtual int m_w_stopi(queue_t * q, mblk_t * mp) {
		return (-EOPNOTSUPP);
	};
};

class dp:public qp {
      private:
	dp * next;			/* next device in moduls' opens list */
	dp **prev;			/* prev device in moduls' opens list */
      public:
	 dp(dp ** dpp, queue_t * _q, int cmaj, int cmin)
	:qp(_q), cmajor(cmaj), cminor(cmin) {
		if ((next = *dpp))
			next->prev = &next;
		prev = dpp;
	};
	virtual ~ dp(void) {
		if ((*prev = next))
			next->prev = prev;
	};

	int cmajor;			/* major device number */
	int cminor;			/* minor device number */

	static inline dp **slot(dp ** dpp, int &cminor, int nminor, int sflag) {
		if (!cminor && sflag == CLONEOPEN)
			cminor = 1;
		for (; *dpp && cminor <= nminor; dpp = &(*dpp)->next) {
			int dminor = (*dpp)->cminor;
			if (cminor < dminor)
				break;
			if (cminor == dminor) {
				if (sflag != CLONEOPEN)
					return (NULL);
				cminor++;
			}
		}
		if (cminor > nminor)
			return (NULL);
		return (dpp);
	};
};

class lp:public qp {
      private:
	lp * next;			/* next device in moduls' opens list */
	lp **prev;			/* prev device in moduls' opens list */
      public:
	 lp(lp ** lpp, queue_t * _q, queue_t * uq, int mid)
	:qp(_q), lmq(uq), muxid(mid) {
		if ((next = *lpp))
			next->prev = &next;
		prev = lpp;
	};
	virtual ~ lp(void) {
		if ((*prev = next))
			next->prev = prev;
	};

	static inline lp *find(lp ** lpp, int id) {
		if (!lpp)
			return (NULL);
		for (; *lpp && (*lpp)->muxid != id; lpp = &(*lpp)->next);
		return (*lpp);
	};

	int muxid;			/* multiplexor id */
	queue_t *lmq;			/* local management queue */
};

#ifndef INT
#define INT int
#endif

extern "C" {
	INT q_rput(queue_t * q, mblk_t * mp);
	INT q_rsrv(queue_t * q);
	INT q_wput(queue_t * q, mblk_t * mp);
	INT q_wsrv(queue_t * q);
}
#endif					/* __QUEUE_H__ */


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/str/queue.h

OpenSS7
SS7 for the
Common Man
Home Overview Status News Documentation Resources About

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified: