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/sigtran/ua_asp.c


File /code/strss7/drivers/sigtran/ua_asp.c



#ident "@(#) $RCSfile: ua_asp.c,v $ $Name:  $($Revision: 0.8.2.3 $) $Date: 2003/04/14 12:13:20 $"

static char const ident[] =
    "$RCSfile: ua_asp.c,v $ $Name:  $($Revision: 0.8.2.3 $) $Date: 2003/04/14 12:13:20 $";

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

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

#include "../debug.h"
#include "../bufq.h"

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

#define ASP_DESCRIP	"SIGTRAN ASP STREAMS MULTIPLEXING DRIVER."
#define ASP_COPYRIGHT	"Copyright (c) 1997-2002 OpenSS7 Corporation.  All Rights Reserved."
#define ASP_DEVICE	"Part of the OpenSS7 Stack for LiS STREAMS."
#define ASP_CONTACT	"Brian Bidulock <bidulock@openss7.org>"
#define ASP_LICENSE	"GPL"
#define ASP_BANNER	ASP_DESCRIP	"\n" \
			ASP_COPYRIGHT	"\n" \
			ASP_DEVICE	"\n" \
			ASP_CONTACT	"\n"

MODULE_AUTHOR(ASP_CONTACT);
MODULE_DESCRIPTION(ASP_DESCRIP);
MODULE_SUPPORTED_DEVICE(ASP_DEVICE);
#ifdef MODULE_LICENSE
MODULE_LICENSE(ASP_LICENSE);
#endif

#ifndef INT
#define INT void
#endif

/*
 *  =========================================================================
 *
 *  STREAMS Definitions
 *
 *  =========================================================================
 */

static int asp_open(queue_t *, dev_t *, int, int, cred_t *);
static int asp_close(queue_t *, int, cred_t *);

static struct module_info asp_m_minfo = {
	0,				/* Module ID number */
	"asp-lm",			/* Module name */
	0,				/* Min packet size accepted */
	INFPSZ,				/* Max packet size accepted */
	1,				/* Hi water mark */
	0				/* Lo water mark */
};

static INT asp_m_rput(queue_t *, mblk_t *);
static INT asp_m_rsrv(queue_t *);

static struct qinit asp_m_rinit {
	asp_m_rput,			/* Read put (msg from below) */
	asp_m_rsrv,			/* Read queue service */
	asp_open,			/* Each open */
	asp_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&asp_m_info,			/* Information */
	NULL				/* Statistics */
};

static INT asp_m_wput(queue_t *, mblk_t *);
static INT asp_m_wsrv(queue_t *);

static struct qinit asp_m_winit {
	asp_m_wput,			/* Read put (msg from below) */
	asp_m_wsrv,			/* Read queue service */
	asp_open,			/* Each open */
	asp_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&asp_m_info,			/* Information */
	NULL				/* Statistics */
};

static struct module_info asp_l_minfo = {
	0,				/* Module ID number */
	"asp-lm",			/* Module name */
	0,				/* Min packet size accepted */
	INFPSZ,				/* Max packet size accepted */
	1,				/* Hi water mark */
	0				/* Lo water mark */
};

static INT asp_l_rput(queue_t *, mblk_t *);
static INT asp_l_rsrv(queue_t *);

static struct qinit asp_l_rinit {
	asp_l_rput,			/* Read put (msg from below) */
	asp_l_rsrv,			/* Read queue service */
	asp_open,			/* Each open */
	asp_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&asp_l_info,			/* Information */
	NULL				/* Statistics */
};

static INT asp_l_wput(queue_t *, mblk_t *);
static INT asp_l_wsrv(queue_t *);

static struct qinit asp_l_winit {
	asp_l_wput,			/* Read put (msg from below) */
	asp_l_wsrv,			/* Read queue service */
	asp_open,			/* Each open */
	asp_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&asp_l_info,			/* Information */
	NULL				/* Statistics */
};

static struct streamtab asp_m_info = {
	&asp_m_rinit,			/* Upper read queue */
	&asp_m_winit,			/* Upper write queue */
	&asp_l_rinit,			/* Lower read queue */
	&asp_l_winit			/* Lower write queue */
};

/*
 *  =========================================================================
 *
 *  OUTPUT Events
 *
 *  =========================================================================
 */
/*
 *  =========================================================================
 *
 *  STATE Machines
 *
 *  =========================================================================
 */

int asp_aspup(asp_t * asp)
{
	gp_t *gp;
	for (gp = asp->gp; gp = gp->sp.next) {
		as_t *as = gp->sp.sp;
		switch (gp->state) {
		case ASP_INACTIVE:
			continue;
		case ASP_DOWN:
			if (!as->xpia_count++)
				as_up(as);
			as->xpdn_count--;
			gp->state = ASP_INACTIVE;
			continue;
		case ASP_ACTIVE:
			if (!--as->xpac_count)
				as_up(as);
			as->xpia_count++;
			gp->state = ASP_INACTIVE;
			continue;
		case ASP_WACK_ASPIA:
		case ASP_WACK_ASPAC:
		case ASP_WACK_HBEAT:
		}
	}
	return (0);
}

int asp_aspdn(asp_t * asp)
{
	gp_t *gp;
	for (gp = asp->gp; gp = gp->sp.next) {
		as_t *as = gp->sp.sp;
		switch (gp->state) {
		case ASP_DOWN:
			continue;
		case ASP_INACTIVE:
			if (!--as->xpia_count)
				as_down(as);
			++as->xpdn_count;
			gp->state = ASP_DOWN;
			continue;
		case ASP_WACK_ASPIA:
			if (gp->t_ack)
				untimeout(xcgh(&gp->t_ack, 0));
		case ASP_ACTIVE:
			if (!--as->xpac_count)
				as_down(as);
			++as->xpdn_count;
			gp->state = ASP_DOWN;
			continue;
		case ASP_WACK_ASPAC:
		case ASP_WACK_HBEAT:
		}
	}
	return (0);
}

int asp_ua_down(ua_t * ua, uint prot)
{
	int err;
	asp_t *asp;
	for (asp = ua->xp; asp; asp = asp->prot.next)
		if (asp->level & prot && (err = asp_down(asp)))
			return (err);
	return (0);
}

/*
 *  LM --> UA Primitives
 *  -----------------------------------
 */
static int asp_m_w_proto(queue_t * q, mblk_t * mp)
{
}
static int asp_m_w_pcproto(queue_t * q, mblk_t * mp)
{
}
static int asp_m_w_ioctl(queue_t * q, mblk_t * mp)
{
}
static int asp_m_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_PROTO:
		return asp_m_w_proto(q, mp);
	case M_PCPROTO:
		return asp_m_w_pcproto(q, mp);
	case M_IOCTL:
		return asp_m_w_ioctl(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}
static INT asp_m_wput(queue_t * q, mblk_t * mp)
{
	return ua_putq(q, mp, &asp_m_w_prim);
}
static INT asp_m_wsrv(queue_t * q)
{
	return ua_srvq(q, &asp_m_w_prim);
}

/*
 *  UA --> LM Primitives
 *  -----------------------------------
 */
static int asp_m_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (5);
}
static INT asp_m_rput(queue_t * q, mblk_t * mp)
{
	return ua_putq(q, mp, &asp_m_r_prim);
}
static INT asp_m_rsrv(queue_t * q)
{
	return ua_srvq(q, &asp_m_r_prim);
}

/*
 *  UA --> ASP Primitives
 *  -----------------------------------
 */
static int asp_l_w_proto(queue_t * q, mblk_t * mp)
{
}
static int asp_l_w_pcproto(queue_t * q, mblk_t * mp)
{
}
static int asp_l_w_data(queue_t * q, mblk_t * mp)
{
}
static int asp_l_w_ctl(queue_t * q, mblk_t * mp)
{
}
static int asp_l_w_error(queue_t * q, mblk_t * mp)
{
}
static int asp_l_w_hangup(queue_t * q, mblk_t * mp)
{
}
static int asp_l_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return asp_l_w_data(q, mp);
	case M_PROTO:
		return asp_l_w_proto(q, mp);
	case M_PCPROTO:
		return asp_l_w_pcproto(q, mp);
	case M_CTL:
		return asp_l_w_ctl(q, mp);
	case M_ERROR:
		return asp_l_w_error(q, mp);
	case M_HANGUP:
		return asl_l_w_hangup(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (5);
}
static INT asp_l_wput(queue_t * q, mblk_t * mp)
{
	return ua_putq(q, mp, &asp_l_w_prim);
}
static INT asp_l_wsrv(queue_t * q)
{
	return ua_srvq(q, &asp_l_w_prim);
}

/*
 *  ASP --> UA Primitives
 *  -----------------------------------
 */
static int asp_l_r_data(queue_t * q, mblk_t * mp)
{
}
static int asp_l_r_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b_rptr)) {
	case N_DATA_IND:
		return asp_data_ind(q, mp);
	case N_EXDATA_IND:
		return asp_exdata_ind(q, mp);
	case N_DATACK_IND:
		return asp_datac_ind(q, mp);
	case N_DISCON_IND:
		return asp_discon_ind(q, mp);
	case N_RESET_IND:
		return asp_reset_ind(q, mp);
	}
	return (-EOPNOTSUPP);
}
static int asp_l_r_pcproto(queue_t * q, mblk_t * mp)
{
}
static int asp_l_r_ctl(queue_t * q, mblk_t * mp)
{
}
static int asp_l_r_error(queue_t * q, mblk_t * mp)
{
}
static int asp_l_r_hangup(queue_t * q, mblk_t * mp)
{
}
static int asp_l_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return asp_l_r_data(q, mp);
	case M_PROTO:
		return asp_l_r_proto(q, mp);
	case M_PCPROTO:
		return asp_l_r_pcproto(q, mp);
	case M_CTL:
		return asp_l_r_ctl(q, mp);
	case M_ERROR:
		return asp_l_r_error(q, mp);
	case M_HANGUP:
		return asp_l_r_hangup(q, mp);
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}
static INT asp_l_rput(queue_t * q, mblk_t * mp)
{
	return ua_putq(q, mp, &asp_l_r_prim);
}
static INT asp_l_rsrv(queue_t * q)
{
	return ua_srvq(q, &asp_l_r_prim);
}

/*
 *  =========================================================================
 *
 *  OPEN and CLOSE
 *
 *  =========================================================================
 */
static ua_t *asp_opens_list = NULL;

static asp_open(queue_t * q, dev_t * devp, int flag, int sflag, cred_t * crp)
{
	int cmajor = getmajor(*devp);
	int cminor = getminor(*devp);
	dp_t *dp, **dpp;
	if (sflag == MODOPEN || WR(q)->q_next) {
		ptrace(("Can't open as module\n"));
		return (EIO);
	}
	if (cmajor == ASP_CMAJOR && cminor == 1 && crp->cr_uid != 0) {
		ptrace(("Non-root priviledge user attempting to open control stream\n"));
		return (EPERM);
	}
	if (q->q_ptr != NULL) {
		ptrace(("Device already open\n"));
		return (0);
	}
	if (cmajor == ASP_CMAJOR && cminor == 0) {
		ptrace(("Clone minor opened\n"));
		sflag = CLONEOPEN;
	}
	if (sflag == CLONEOPEN) {
		ptrace(("Clone open in effect\n"));
		cmajor = ASP_CMAJOR;
		cminor = 2;
	}
	for (dpp = &asp_opens_list; *dpp; dpp = &(*dpp)->next) {
		ushort dmajor = getmajor(*devp);
		if (cmajor < dmajor)
			break;
		if (cmajor == dmajor) {
			ushort dminor = getminor(*devp);
			if (cminor < dminor)
				break;
			if (cminor == dminor) {
				if (slfag == CLONEOPEN) {
					if (++cminor > ASP_NMINOR) {
						if (++cmajor > ASP_CMAJOR + (ASP_NMINOR - 1))
							break;
						cminor = 0;
					}
					continue;
				}
				ptrace(("Requested device in use\n"));
				return (EIO);
			}
		}
	}
	if (cmajor > ASP_CMAJOR + (ASP_NMAJOR - 1)) {
		ptrace(("No devices available\n"));
		return (ENXIO);
	}
	*devp = makedevice(cmajor, cminor);
	if (!(dp = kmem_cache_alloc(ua_pp_cachep, SLAB_ATOMIC))) {
		ptrace(("Cannot allocate cache entry for device\n"));
		return (ENOMEM);
	}
	bzero(dp, sizeof(dp_t));
	if ((dp->next = *dpp))
		dp->next->prev = &dp->next;
	dp->prev = dpp;
	*dpp = dp;
	dp->id.dev = *devp;
	dp->rq = RD(q);
	dp->wq = WR(q);
	dp->mq = RD(q);
	dp->rq->q_ptr = dp;
	dp->wq->q_ptr = dp;
	return (0);
}
static int asp_close(queue_t * q, int flag, cred_t * crp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	if ((*(dp->prev) = dp->next))
		dp->next->prev = dp->prev;
	dp->prev = NULL;
	dp->next = NULL;
	if (dp->bid)
		unbufcall(dp->bid);
	dp->rq->q_ptr = NULL;
	dp->wq->q_ptr = NULL;
	fixme(("Make sure that we are not referenced...\n"));
	kmem_cache_free(ua_pp_cachep, dp);
	return (0);
}

/*
 *  =========================================================================
 *
 *  LiS Module Initialization
 *
 *  =========================================================================
 */
int asp_init(void)
{
	int cmajor;
	if (!asp_u_minfo.mi_idnum) {
		if ((cmajor = lis_register_strdev(SGP_CMAJOR, &sgp_info, SGP_NMINOR,
						  asp_u_minfo.mi_idname)) < 0) {
			asp_u_minfo.mi_idnum = 0;
			rare();
			cmn_err(CE_NOTE, "asp: couldn't register driver\n");
			return;
		}
		asp_u_minfo.mi_idnum = cmajor;
	}
	return (0);
}
void asp_terminate(void)
{
	if (asp_u_minfo.mi_idnum) {
		if ((asp_u_minfo.mi_idnum = lis_unregister_strdev(asp_u_minfo.mi_idnum))) {
			asp_u_minfo.mi_idnum = 0;
			rare();
			cmn_err(CE_WARN, "asp: couldn't unregister driver\n");
		}
	}
}

/*
 *  =========================================================================
 *
 *  Kernel Module Initialization
 *
 *  =========================================================================
 */
int init_module(void)
{
	int err;
	asp_init();
	return (0);
}
void cleanup_module(void)
{
	asp_terminate();
	return;
}


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

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

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