|
OpenSS7 SS7 for the Common Man |
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |
||||||||||||||||||||||||||
| Home | Overview | Status | News | Documentation | Resources | About | |||||||||||||||||||||
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);
}
|
|||||||||||||||||||||||||||
|
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
|
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |
|||||||||||||||||||||||||||