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/module.h


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


#ifndef __MODULE_HH__
#define __MODULE_HH__

#pragma interface

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

class moduls {
      private:
	static moduls *list;		
	moduls *next;			/* next in class list */
	moduls **prev;			/* prev in class list */

      public:
	struct module_info minfo;
	struct qinit rinit;
	struct qinit winit;
	struct streamtab info;

	dp *opens;			/* opened device list */
	lp *links;			/* linked device list */

	int cmajor;
	int nminor;

	inline void *operator new(size_t s) {
		void *addr = kmalloc(s, GFP_KERNEL);
		if (addr)
			 bzero(addr, s);
	};
	inline void operator delete(void *addr) {
		if (addr)
			kfree(addr);
	};
	moduls(const char *name, uint cmaj, uint nmin, uint min, uint max, uint hi,
	       uint lo):cmajor(cmaj), nminor(nmin) {
		minfo.mi_idnum = ('+' << 8 | cmaj);
		minfo.mi_idname = name;
		minfo.mi_minpsz = min;
		minfo.mi_maxpsz = max;
		minfo.mi_hiwat = hi;
		minfo.mi_lowat = lo;

		rinit.qi_putp = q_rput;
		rinit.qi_srvp = q_rsrv;
		rinit.qi_qopen = q_open;
		rinit.qi_qclose = q_close;
		rinit.qi_qadmin = NULL;
		rinit.qi_minfo = &minfo;
		rinit.qi_mstat = NULL;

		winit.qi_putp = q_rput;
		winit.qi_srvp = q_rsrv;
		winit.qi_qopen = NULL;
		winit.qi_qclose = NULL;
		winit.qi_qadmin = NULL;
		winit.qi_minfo = &minfo;
		winit.qi_mstat = NULL;

		info.st_rdinit = &rinit;
		info.st_wrinit = &winit;
		info.st_muxrinit = &rinit;
		info.st_muxwinit = &winit;

		if ((next = list))
			next->prev = &next;
		prev = &list;
	};
	~moduls(void) {
		if ((*prev = next))
			next->prev = prev;
		next = NULL;
		prev = NULL;
	};
	static inline int q_open(queue_t * q, dev_t * devp, int flag, int sflag, cred_t * crp) {
		moduls *m;
		int cmajor = getmajor(*devp);

		if (q->q_ptr != NULL)
			return (0);	/* already open */
		for (m = moduls::list; m && m->cmajor != cmajor; m = m->next);
		if (!m)
			return (EIO);
		return (m->open(q, devp, sflag, crp));
	};
	static inline int q_close(queue_t * q, int flag, cred_t * crp) {
		dp *dp = (class dp *) q->q_ptr;
		if (!dp)
			return (0);	/* alread closed */
		delete dp;
	};
	inline virtual int open(queue_t * q, dev_t * devp, int sflag, cred_t * crp) = 0;
	inline virtual dp *create_device(dp ** dpp, queue_t * q, int cmajor, int cminor) {
		return new dp(dpp, q, cmajor, cminor);
	};
};

class strmod:public moduls {
      public:
	strmod(const char *name, int cmaj, int nmin, uint min, uint max, uint hi, uint lo)
	:moduls(name, cmaj, nmin, min, max, hi, lo) {
		if (lis_register_strmod(&info, name) < 0)
			cmn_err(CE_NOTE, "LiS++: couldn't register mod!\n");
	};
	~strmod(void) {
		if (lis_unregister_strmod(&info) < 0)
			cmn_err(CE_NOTE, "LiS++: couldn't unregister mod!\n");
	};
	inline virtual int open(queue_t * q, dev_t * devp, int sflag, cred_t * crp) {
		dp *dp, **dpp;
		int cminor = getminor(*devp);
		if (sflag == DRVOPEN || !WR(q)->q_next)
			return (EIO);	/* must open as module */
		if (!cminor)
			sflag = CLONEOPEN;
		if (!(dpp = dp::slot(&opens, cminor, nminor, sflag)))
			return (ENXIO);
		if (!(dp = this->create_device(dpp, q, cmajor, cminor)))
			return (ENOMEM);
		*devp = makedevice(cmajor, cminor);
		return (0);
	};
};

class strdrv:public moduls {
      public:
	strdrv(const char *name, int cmaj, int nmin, uint min, uint max, uint hi, uint lo)
	:moduls(name, cmaj, nmin, min, max, hi, lo) {
		if (lis_register_strdev(cmaj, &info, nmin, name) < 0)
			cmn_err(CE_NOTE, "LiS++: couldn't register dev!\n");
	};
	~strdrv(void) {
		if (lis_unregister_strdev(cmajor) < 0)
			cmn_err(CE_NOTE, "LiS++: couldn't unregister dev!\n");
	};
	inline virtual int open(queue_t * q, dev_t * devp, int sflag, cred_t * crp) {
		dp *dp, **dpp;
		int cminor = getminor(*devp);
		if (sflag == MODOPEN || WR(q)->q_next)
			return (EIO);	/* must open as driver */
		if (!cminor)
			sflag = CLONEOPEN;
		if (!(dpp = dp::slot(&opens, cminor, nminor, sflag)))
			return (ENXIO);
		if (!(dp = this->create_device(dpp, q, cmajor, cminor)))
			return (ENOMEM);
		*devp = makedevice(cmajor, cminor);
		return (0);
	};
};

class strmux:public moduls {
      public:
	strmux(const char *name, int cmaj, int nmin, uint min, uint max, uint hi, uint lo)
	:moduls(name, cmaj, nmin, min, max, hi, lo), lmq(NULL) {
		if (lis_register_strdev(cmaj, &info, nmin, name) < 0)
			cmn_err(CE_NOTE, "LiS++: couldn't register mux!\n");
	};
	~strmux(void) {
		if (lis_unregister_strdev(cmajor) < 0)
			cmn_err(CE_NOTE, "LiS++: couldn't unregister mux!\n");
	};

	queue_t *lmq;			/* layer management queue */

	inline virtual int open(queue_t * q, dev_t * devp, int sflag, cred_t * crp) {
		dp *dp, **dpp;
		int cminor = getminor(*devp);

		if (sflag == MODOPEN || WR(q)->q_next)
			return (EIO);	/* must open as driver */
		if (!cminor && sflag != CLONEOPEN) {
			if (lmq)
				return (ENXIO);
			if (crp->cr_ruid != 0)
				return (EPERM);	/* neex r00t */
			lmq = q;
		}
		if (!(dpp = dp::slot(&opens, cminor, nminor, sflag)))
			return (ENXIO);
		if (!(dp = this->create_device(dpp, q, cmajor, cminor)))
			return (ENOMEM);
		*devp = makedevice(cmajor, cminor);
		return (0);
	};
};

#endif				/* __MODULE_HH__ */


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

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

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