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