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