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/ua/ua_queue.c


File /code/strss7/drivers/ua/ua_queue.c



#ident "@(#) $Id: ua_queue.c,v 0.8.2.2 2003/04/03 19:51:46 brian Exp $"

static char const ident[] = "$Name:  $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:46 $";

#define __NO_VERSION__

#include <linux/config.h>
#include <linux/version.h>
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif

#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/cmn_err.h>

#include "../debug.h"

#include "ua.h"
#include "ua_data.h"

/*
 *  =========================================================================
 *
 *  Common M_CTL Porcessing
 *
 *  =========================================================================
 */
int ua_r_ctl(queue_t * q, mblk_t * mp)
{
	return (-EOPNOTSUPP);
}

int ua_w_ctl(queue_t * q, mblk_t * mp)
{
	return (-EOPNOTSUPP);
}

/*
 *  =========================================================================
 *
 *  Common M_FLUSH Porcessing
 *
 *  =========================================================================
 */
int ua_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);	/* flush all the way down */
			return (0);
		}
		*mp->b_rptr &= ~FLUSHW;
	}
	if (*mp->b_rptr & FLUSHR && !(mp->b_flags & MSGNOLOOP)) {
		if (*mp->b_rptr & FLUSHBAND)
			flushband(RD(q), mp->b_rptr[1], FLUSHALL);
		else
			flushq(RD(q), FLUSHALL);
		mp->b_flag |= MSGNOLOOP;
		if (RD(q)->q_next) {
			qreply(q, mp);	/* flush all the way up */
			return (0);
		}
	}
	freemsg(mp);
	return (0);
}

int ua_r_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);	/* flush all the way up */
			return (0);
		}
		*mp->b_rptr &= ~FLUSHW;
	}
	if (*mp->b_rptr & FLUSHR && !(mp->b_flags & MSGNOLOOP)) {
		if (*mp->b_rptr & FLUSHBAND)
			flushband(WR(q), mp->b_rptr[1], FLUSHALL);
		else
			flushq(WR(q), FLUSHALL);
		mp->b_flag |= MSGNOLOOP;
		if (WR(q)->q_next) {
			qreply(q, mp);	/* flush all the way down */
			return (0);
		}
	}
	freemsg(mp);
	return (0);
}

/*
 *  =========================================================================
 *
 *  Common QUEUE PUT and SRV routines
 *
 *  =========================================================================
 */
static inline int ua_recover(queue_t * q, mblk_t * mp, int err)
{
	switch (err) {
	case -EBUSY:
	case -EAGAIN:
	case -ENOMEM:
	case -ENOBUFS:
		putq(q, mp);
		return (0);
	}
	freemsg(mp);
	return (err);
}
static inline int ua_reservice(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);
}
static inline int ua_rd(queue_t * q, mblk_t * mp)
{
	pp_t *pp = (pp_t *) q->q_ptr;
	int type = mp->b_datap->db_type;
	if (!pp->ops->rd && q->q_next) {
		if (mp->b_datap->db_type < QPCTL && !canputnext(q))
			return (-EBUSY);
		putnext(q, mp);
		return (0);
	}
	if (M_DATA <= type && type <= M_STOPI && pp->ops && pp->ops->rd[type])
		return (*pp->ops->rd[type]);
	return (-EOPNOTSUPP);
}

INT ua_rput(queue_t * q, mblk_t * mp)
{
	if (mp->b_datap->db_type < QCTL || q->q_count)
		putq(q, mp);
	else {
		int err;
		if ((err = ua_rd(q, mp)))
			return (INT) (ua_recover(q, mp, err));
	}
	return (INT) (0);
}

INT ua_rsrv(queue_t * q, mblk_t * mp)
{
	mblk_t *mp;
	while ((mp = getq(q))) {
		int err;
		if (!(err = ua_rd(q, mp)))
			continue;
		if (mp->b_datap->db_type < QPCTL)
			return (INT) (ua_reservice(q, mp, err));
		freemsg(mp);
		return (INT) (err);
	}
	return (INT) (0);
}
static inline int ua_wr(queue_t * q, mblk_t * mp)
{
	pp_t *pp = (pp_t *) q->q_ptr;
	int type = mp->b_datap->db_type;
	if (!pp->ops->wr && q->q_next) {
		if (mp->b_datap->db_type < QPCTL && !canputnext(q))
			return (-EBUSY);
		putnext(q, mp);
		return (0);
	}
	if (M_DATA <= type && type <= M_STOPI && pp->ops && pp->ops->wr[type])
		return (*pp->ops->wr[type]);
	return (-EOPNOTSUPP);
}

INT ua_wput(queue_t * q, mblk_t * mp)
{
	if (mp->b_datap->db_type < QCTL || q->q_count)
		putq(q, mp);
	else {
		int err;
		if ((err = ua_wr(q, mp)))
			return (INT) (ua_recover(q, mp, err));
	}
	return (INT) (0);
}

INT ua_wsrv(queue_t * q, mblk_t * mp)
{
	mblk_t *mp;
	while ((mp = getq(q))) {
		int err;
		if (!(err = ua_wr(q, mp)))
			continue;
		if (mp->b_datap->db_type < QPCTL)
			return (INT) (ua_reservice(q, mp, err));
		freemsg(mp);
		return (INT) (err);
	}
	return (INT) (0);
}


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/ua/ua_queue.c

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

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