--- /dev/null
+/*******************************************************************************
+################################################################################
+# Copyright (c) [2017-2019] [Radisys] #
+# #
+# Licensed under the Apache License, Version 2.0 (the "License"); #
+# you may not use this file except in compliance with the License. #
+# You may obtain a copy of the License at #
+# #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+# #
+# Unless required by applicable law or agreed to in writing, software #
+# distributed under the License is distributed on an "AS IS" BASIS, #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+# See the License for the specific language governing permissions and #
+# limitations under the License. #
+################################################################################
+*******************************************************************************/
+\f
+/********************************************************************20**
+
+ Name: System Services -- Timing
+
+ Type: C source file
+
+ Desc: Source code for System Services related to timing.
+
+ File: ss_timer.c
+
+*********************************************************************21*/
+
+\f
+/* header include files (.h) */
+
+#include "envopt.h" /* environment options */
+#include "envdep.h" /* environment dependent */
+#include "envind.h" /* environment independent */
+
+#include "gen.h" /* general layer */
+#include "ssi.h" /* system services */
+
+#include "ss_err.h" /* errors */
+#include "ss_dep.h" /* implementation-specific */
+#include "ss_queue.h" /* queues */
+#include "ss_msg.h" /* messaging */
+#include "ss_mem.h" /* memory management interface */
+#include "ss_gen.h" /* general */
+#include "cm_mem.h" /* memory management */
+
+
+
+/* header/extern include files (.x) */
+
+#include "gen.x" /* general layer */
+#include "ssi.x" /* system services */
+
+#include "ss_dep.x" /* implementation-specific */
+#include "ss_queue.x" /* queues */
+#include "ss_task.x" /* tasking */
+#include "ss_timer.x" /* timers */
+#include "ss_strm.x" /* STREAMS */
+#include "ss_msg.x" /* messaging */
+#include "ss_mem.x" /* memory management interface */
+#include "ss_drvr.x" /* driver tasks */
+#ifdef SS_LOCKLESS_MEMORY
+#include "cm_llist.x"
+#include "cm_hash.x"
+#include "cm_mem_wl.x" /* common memory manager */
+#else
+#include "cm_mem.x" /* common memory manager */
+#endif /* SS_LOCKLESS_MEMORY */
+#include "ss_gen.x" /* general */
+
+
+/* Forward declarations */
+
+/* ss041.103 Declaration for STmrRegHndlr */
+/* ss015.301 Changed the timer activation function type as all timer activation
+ * functions are enclosed in a union.
+ */
+#ifndef SS_MULTIPLE_PROCS
+PRIVATE S16 STmrRegHndlr ARGS((
+ Ent ent,
+ Inst inst,
+ S16 period,
+ S16 units,
+ SsTmrActvFn ssTmrActvFn
+ ));
+/* ss015.301: Removed the timer handler prototypes guarded under SS_MT_TMR and
+ * handled mtFlag in existing timer handlers.
+ */
+#else /* SS_MULTIPLE_PROCS */
+PRIVATE S16 STmrRegHndlr ARGS((
+ ProcId proc,
+ Ent ent,
+ Inst inst,
+ S16 period,
+ S16 units,
+ SsTmrActvFn ssTmrActvFn
+ ));
+#endif /* SS_MULTIPLE_PROCS */
+
+/* ss041.103 Declaration for STmrDeregHndlr */
+#ifndef SS_MULTIPLE_PROCS
+PRIVATE S16 STmrDeregHndlr ARGS((
+ Ent ent,
+ Inst inst,
+ S16 period,
+ S16 units,
+ SsTmrActvFn ssTmrActvFn
+ ));
+/* ss015.301 Removed the timer handler prototypes guarded under SS_MT_TMR and
+ * handled mtFlag in existing timer handlers.
+ */
+#else /* SS_MULTIPLE_PROCS */
+PRIVATE S16 STmrDeregHndlr ARGS((
+ ProcId proc,
+ Ent ent,
+ Inst inst,
+ S16 period,
+ S16 units,
+ SsTmrActvFn ssTmrActvFn
+ ));
+#endif /* SS_MULTIPLE_PROCS */
+
+
+\f
+/* ss028.103 - Modification for SRegCfgTmr Support */
+/*
+*
+* Fun: Register Configurable Timer Task - timer
+*
+* Desc: This function is used to register a timer function for the
+* layer. The system services will periodically invoke the
+* function passed to it. The timer function will be used by the
+* layer to manage the layers internal protocol timers.
+*
+* Ret: ROK - ok
+* RFAILED - failed, general (optional)
+* ROUTRES - failed, out of resources (optional)
+*
+* Notes:
+*
+* File: ss_timer.c
+*
+*/
+/* ss029.103: addition: procId added and timer function type modified */
+#ifndef SS_MULTIPLE_PROCS
+#ifdef ANSI
+PUBLIC S16 SRegCfgTmr
+(
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+PFS16 tmrFnct /* timer function, typically SActvTmr */
+)
+#else
+PUBLIC S16 SRegCfgTmr(ent, inst, period, units, tmrFnct)
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+PFS16 tmrFnct; /* timer function, typically SActvTmr */
+#endif
+{
+ S16 ret;
+ /* ss015.301 - Enclosed all timer activation functions in a union. */
+ SsTmrActvFn ssTmrActvFn;
+ /* ss041.103 - Moved handling to STmrRegHndlr */
+
+ TRC1(SRegCfgTmr);
+
+ ssTmrActvFn.mtFlag = FALSE;
+ ssTmrActvFn.actvFnc.tmrActvFn = tmrFnct;
+ ret = STmrRegHndlr(ent, inst, period, units, ssTmrActvFn);
+
+ RETVALUE(ret);
+}
+
+#else /* SS_MULTIPLE_PROCS */
+
+#ifdef ANSI
+PUBLIC S16 SRegCfgTmr
+(
+ProcId proc, /* processor */
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+PAIFTMRS16 tmrFnct /* timer function, typically SActvTmr */
+)
+#else
+PUBLIC S16 SRegCfgTmr(proc, ent, inst, period, units, tmrFnct)
+ProcId proc; /* processor */
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+PAIFTMRS16 tmrFnct; /* timer function, typically SActvTmr */
+#endif
+
+{
+ S16 ret;
+ /* ss015.301 - Enclosed all timer activation functions in a union. */
+ SsTmrActvFn ssTmrActvFn;
+ /* ss041.103 - Moved handling to STmrRegHndlr */
+
+ TRC1(SRegCfgTmr);
+
+ ssTmrActvFn.mtFlag = FALSE;
+ ssTmrActvFn.actvFnc.tmrActvFn = tmrFnct;
+ ret = STmrRegHndlr(proc, ent, inst, period, units, ssTmrActvFn);
+
+ RETVALUE(ret);
+}
+
+#endif /* SS_MULTIPLE_PROCS */
+
+\f
+#ifndef SS_MULTIPLE_PROCS
+/* ss041.103 - New function for MT timer reg */
+#ifdef SS_MT_TMR
+/*
+*
+* Fun: Register Configurable Timer Task - timer
+*
+* Desc: This function is used to register a timer function for the
+* layer. The system services will periodically invoke the
+* function passed to it. The timer function will be used by the
+* layer to manage the layers internal protocol timers.
+*
+* Ret: ROK - ok
+* RFAILED - failed, general (optional)
+* ROUTRES - failed, out of resources (optional)
+*
+* Notes: By invoking this function, Ent and Inst are passed in the
+* timer activation function.
+*
+* File: ss_timer.c
+*
+*/
+#ifdef ANSI
+PUBLIC S16 SRegCfgTmrMt
+(
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+PAIFTMRS16 tmrFnctMt /* timer function, typically SActvTmr */
+)
+#else
+PUBLIC S16 SRegCfgTmrMt(ent, inst, period, units, tmrFnctMt)
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+PAIFTMRS16 tmrFnctMt; /* timer function, typically SActvTmr */
+#endif
+{
+ S16 ret;
+ /* ss015.301 - Enclosed all timer activation functions in a union. */
+ SsTmrActvFn ssTmrActvFn;
+
+ TRC1(SRegCfgTmrMt);
+
+ ssTmrActvFn.actvFnc.tmrActvFnMt = tmrFnctMt;
+ ssTmrActvFn.mtFlag = TRUE;
+ ret = STmrRegHndlr(ent, inst, period, units, ssTmrActvFn);
+
+ RETVALUE(ret);
+}
+#endif /* SS_MT_TMR */
+#endif /* not SS_MULTIPLE_PROCS */
+
+/* ss041.103 - Function for timer registration handling */
+/*
+*
+* Fun: Timer registration handler function
+*
+* Desc: This function is called by the timer registration interface
+* functions, and does the actual handling for timer
+* registration.
+*
+* Ret: ROK - ok
+* RFAILED - failed, general (optional)
+* ROUTRES - failed, out of resources (optional)
+*
+* Notes:
+*
+* File: ss_timer.c
+*
+*/
+
+/* ss015.301 Changed the timer activation function type as all timer activation
+ * functions are enclosed in a union.
+ */
+
+#ifndef SS_MULTIPLE_PROCS
+
+#ifdef ANSI
+PRIVATE S16 STmrRegHndlr
+(
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+SsTmrActvFn ssTmrActvFn /* timer function, typically SActvTmr */
+)
+#else
+PRIVATE S16 STmrRegHndlr(ent, inst, period, units, ssTmrActvFn)
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+SsTmrActvFn ssTmrActvFn; /* timer function, typically SActvTmr */
+#endif
+/* ss015.301: Removed the timer handler prototypes guarded
+ * under SS_MT_TMR and handled mtFlag in existing timer handlers.
+ */
+
+#else /* SS_MULTIPLE_PROCS */
+
+#ifdef ANSI
+PRIVATE S16 STmrRegHndlr
+(
+ProcId proc, /* processor */
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+SsTmrActvFn ssTmrActvFn /* timer function */
+)
+#else
+PRIVATE S16 STmrRegHndlr(proc, ent, inst, period, units, ssTmrActvFn)
+ProcId proc; /* processor */
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+SsTmrActvFn ssTmrActvFn; /* timer function */
+#endif
+
+#endif /* SS_MULTIPLE_PROCS */
+{
+#if (ERRCLASS & ERRCLS_INT_PAR)
+ U8 i;
+#endif
+ S16 ret;
+ SsTmrEntry *tmr;
+#ifdef SS_MULTIPLE_PROCS
+#if (ERRCLASS & ERRCLS_INT_PAR)
+ U16 procIdIdx;
+#endif /* ERRCLASS & ERRCLS_INT_PAR */
+#endif /* SS_MULTPLE_PROCS */
+
+ TRC1(STmrRegHndlr);
+
+#if (ERRCLASS & ERRCLS_INT_PAR)
+
+#ifdef SS_MULTIPLE_PROCS
+ if ((proc == SS_INV_PROCID) || (ent >= SS_MAX_ENT) || (inst >= SS_MAX_INST))
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS528, ERRZERO, "Invalid processor/entity/instance");
+ RETVALUE(RFAILED);
+ }
+#else /* SS_MULTIPLE_PROCS */
+ if (ent >= SS_MAX_ENT || inst >= SS_MAX_INST)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS529, ERRZERO, "Invalid entity/instance");
+ RETVALUE(RFAILED);
+ }
+#endif /* SS_MULTIPLE_PROCS */
+
+ /* check period */
+ if (period <= 0)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS530, ERRZERO, "Invalid period");
+ RETVALUE(RFAILED);
+ }
+
+ /* check period units*/
+ if ((units < 1) || (units > SS_TICKS_SEC))
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS531, ERRZERO, "Invalid period units");
+ RETVALUE(RFAILED);
+ }
+
+ if(ssTmrActvFn.mtFlag == TRUE)
+ {
+ /* ss015.301 Enclosed all timer activation functions in a union. */
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+ if (ssTmrActvFn.actvFnc.tmrActvFnMt == NULLP)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS532, ERRZERO, "Null pointer");
+ RETVALUE(RFAILED);
+ }
+#else
+ RETVALUE(RFAILED);
+#endif
+#else
+ RETVALUE(RFAILED);
+#endif
+ }
+ else
+ {
+ if (ssTmrActvFn.actvFnc.tmrActvFn == NULLP)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS532, ERRZERO, "Null pointer");
+ RETVALUE(RFAILED);
+ }
+ }
+
+#ifdef SS_MULTIPLE_PROCS
+ /* check if the procId has been registered with SSI */
+ procIdIdx = SGetProcIdIdx(proc);
+
+ if (procIdIdx == SS_INV_PROCID_IDX)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS533, ERRZERO,
+ "Could not find proc id index");
+ RETVALUE(RFAILED);
+ }
+#endif /* SS_MULTIPLE_PROCS */
+
+
+ /* check task ID */
+ /* lock TAPA task table */
+ SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
+ if (ret != ROK)
+ {
+ SSLOGERROR(ERRCLS_DEBUG, ESS534, ERRZERO,
+ "Could not lock TAPA task table");
+ RETVALUE(RFAILED);
+ }
+
+#ifdef SS_MULTIPLE_PROCS
+ if (osCp.tTskIds[procIdIdx][ent][inst] == SS_TSKNC)
+#else /* SS_MULTIPLE_PROCS */
+ if (osCp.tTskIds[ent][inst] == SS_TSKNC)
+#endif /* SS_MULTIPLE_PROCS */
+ {
+ if ( SS_RELEASE_SEMA(&osCp.tTskTblSem) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS535, ERRZERO,
+ "Could not release the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+ SSLOGERROR(ERRCLS_INT_PAR, ESS536, ERRZERO, "Unknown task");
+ RETVALUE(RFAILED);
+ }
+ if ( SS_RELEASE_SEMA(&osCp.tTskTblSem) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS537, ERRZERO,
+ "Could not release the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+
+#endif
+
+ /* lock the timer table */
+ ret = SLock(&osCp.tmrTblLock);
+ if (ret != ROK)
+ {
+
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS538, (ErrVal) ret,
+ "Could not lock timer table");
+#endif
+ RETVALUE(ret);
+ }
+
+
+ /* check if we've got room for another timer */
+ if (osCp.numTmrs == SS_MAX_TMRS)
+ {
+ if ( SUnlock(&osCp.tmrTblLock) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS539, ERRZERO,
+ "Could not unlock the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS540, ERRZERO, "Too many timers");
+#endif
+
+ RETVALUE(ROUTRES);
+ }
+
+#if (ERRCLASS & ERRCLS_INT_PAR)
+ /* check through the timer table for a matching timer entry */
+ for (i = 0; i < SS_MAX_TMRS; i++)
+ {
+ if ((osCp.tmrTbl[i].ownerEnt == ent)
+#ifdef SS_MULTIPLE_PROCS
+ && (osCp.tmrTbl[i].ownerProc == proc)
+#endif /* SS_MULTIPLE_PROCS */
+ && (osCp.tmrTbl[i].ownerInst == inst)
+ /* ss041.103 - Added mtFlag check */
+ /* ss015.301 Enclosed all timer activation functions in a union. */
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+ && (osCp.tmrTbl[i].ssTmrActvFn.mtFlag == ssTmrActvFn.mtFlag)
+ && ((ssTmrActvFn.mtFlag == FALSE
+ && osCp.tmrTbl[i].ssTmrActvFn.actvFnc.tmrActvFn == ssTmrActvFn.actvFnc.tmrActvFn)
+ || osCp.tmrTbl[i].ssTmrActvFn.actvFnc.tmrActvFnMt == ssTmrActvFn.actvFnc.tmrActvFnMt)
+#else
+ && (osCp.tmrTbl[i].ssTmrActvFn.actvFnc.tmrActvFn == ssTmrActvFn.actvFnc.tmrActvFn)
+#endif
+#else
+ && (osCp.tmrTbl[i].ssTmrActvFn.actvFnc.tmrActvFn == ssTmrActvFn.actvFnc.tmrActvFn)
+#endif
+ && (osCp.tmrTbl[i].interval == (U32) ((period * SS_TICKS_SEC) / units)))
+ {
+ /* is this timer in use ? (unexpired) */
+ if (osCp.tmrTbl[i].used == TRUE)
+ {
+ /* to prevent the same timer to be registered with SS UNLOCK and */
+ /* then RFAIL */
+ if (SUnlock(&osCp.tmrTblLock) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS541, ERRZERO, "Could not unlock the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+ RETVALUE(RFAILED);
+ }
+ }
+ }
+#endif
+
+ /* fill in the information we have into the timer entry */
+ tmr = &osCp.tmrTbl[osCp.nxtTmrEntry];
+ tmr->tmrId = osCp.nxtTmrEntry;
+#ifdef SS_MULTIPLE_PROCS
+ tmr->ownerProc = proc;
+#endif /* SS_MULTIPLE_PROCS */
+ tmr->ownerEnt = ent;
+ tmr->ownerInst = inst;
+ tmr->interval = (U32) ((period * SS_TICKS_SEC) / units);
+ tmr->ssTmrActvFn.mtFlag = ssTmrActvFn.mtFlag;
+
+ /* ss041.103 */
+ /* ss015.301 Enclosed all timer activation functions in a union. */
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+ if (ssTmrActvFn.mtFlag == TRUE)
+ {
+ tmr->ssTmrActvFn.actvFnc.tmrActvFnMt = ssTmrActvFn.actvFnc.tmrActvFnMt;
+ }
+ else
+#endif
+#endif
+ {
+ tmr->ssTmrActvFn.actvFnc.tmrActvFn = ssTmrActvFn.actvFnc.tmrActvFn;
+ }
+
+
+ /* ask the implementation to start the timer */
+ ret = ssdRegTmr(tmr);
+ if (ret != ROK)
+ {
+ tmr->tmrId = 0;
+#ifdef SS_MULTIPLE_PROCS
+ tmr->ownerProc = PROCNC;
+#endif /* SS_MULTIPLE_PROCS */
+ tmr->ownerEnt = ENTNC;
+ tmr->ownerInst = INSTNC;
+ tmr->interval = 0;
+ /* ss015.301 Enclosed all timer activation functions in a union. */
+ tmr->ssTmrActvFn.mtFlag = FALSE;
+ tmr->ssTmrActvFn.actvFnc.tmrActvFn = NULLP;
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+ tmr->ssTmrActvFn.actvFnc.tmrActvFnMt = NULLP;
+#endif
+#endif
+ }
+ else
+ {
+ tmr->used = TRUE;
+ osCp.nxtTmrEntry = tmr->nxt;
+ osCp.numTmrs++;
+ }
+
+
+ /* unlock the timer table */
+ if ( SUnlock(&osCp.tmrTblLock) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS542, ERRZERO,
+ "Could not unlock the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+
+ RETVALUE(ret);
+}
+
+
+\f
+/*
+*
+* Fun: SDeregCfgTmr
+*
+* Desc: This function is used to deregister a timer function.
+*
+* Ret: ROK - ok
+* RFAILED - failed, general (optional)
+*
+* Notes:
+*
+* File: ss_timer.c
+*
+*/
+/* ss029.103: addition: procId added and timer function type modified */
+#ifndef SS_MULTIPLE_PROCS
+
+#ifdef ANSI
+PUBLIC S16 SDeregCfgTmr
+(
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+PFS16 tmrFnct /* timer function */
+)
+#else
+PUBLIC S16 SDeregCfgTmr(ent, inst, period, units, tmrFnct)
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+PFS16 tmrFnct; /* timer function */
+#endif
+{
+ S16 ret;
+ /* ss015.301 Enclosed all timer activation functions in a union. */
+ SsTmrActvFn ssTmrActvFn;
+ /* ss041.103 - Moved handling to STmrDeregHndlr */
+
+ TRC1(SDeregCfgTmr);
+
+ ssTmrActvFn.mtFlag = FALSE;
+ ssTmrActvFn.actvFnc.tmrActvFn = tmrFnct;
+ ret = STmrDeregHndlr(ent, inst, period, units, ssTmrActvFn);
+
+ RETVALUE(ret);
+}
+
+#else /* SS_MULTIPLE_PROCS */
+
+#ifdef ANSI
+PUBLIC S16 SDeregCfgTmr
+(
+ProcId proc, /* processor */
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+PAIFTMRS16 tmrFnct /* timer function */
+)
+#else
+PUBLIC S16 SDeregCfgTmr(proc, ent, inst, period, units, tmrFnct)
+ProcId proc; /* processor */
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+PAIFTMRS16 tmrFnct; /* timer function */
+#endif
+{
+ S16 ret;
+ /* ss015.301 Enclosed all timer activation functions in a union. */
+ SsTmrActvFn ssTmrActvFn;
+
+ /* ss041.103 - Moved handling to STmrDeregHndlr */
+
+ TRC1(SDeregCfgTmr);
+
+ ssTmrActvFn.mtFlag = FALSE;
+ ssTmrActvFn.actvFnc.tmrActvFn = tmrFnct;
+ ret = STmrDeregHndlr(proc, ent, inst, period, units, ssTmrActvFn);
+
+ RETVALUE(ret);
+}
+
+#endif /* SS_MULTIPLE_PROCS */
+
+\f
+/* ss041.103 - Addition to support MT timer dereg */
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+/*
+*
+* Fun: SDeregCfgTmrMt
+*
+* Desc: This function is used to deregister an MT timer function.
+*
+* Ret: ROK - ok
+* RFAILED - failed, general (optional)
+*
+* Notes:
+*
+* File: ss_timer.c
+*
+*/
+#ifdef ANSI
+PUBLIC S16 SDeregCfgTmrMt
+(
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+PAIFTMRS16 tmrFnctMt /* timer function */
+)
+#else
+PUBLIC S16 SDeregCfgTmrMt(ent, inst, period, units, tmrFnctMt)
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+PAIFTMRS16 tmrFnctMt; /* timer function */
+#endif
+{
+ S16 ret;
+ /* ss015.301 Enclosed all timer activation functions in a union. */
+ SsTmrActvFn ssTmrActvFn;
+
+ TRC1(SDeregCfgTmrMt);
+
+ ssTmrActvFn.actvFnc.tmrActvFnMt = tmrFnctMt;
+ ssTmrActvFn.mtFlag = TRUE;
+
+ ret = STmrDeregHndlr(ent, inst, period, units, ssTmrActvFn);
+
+ RETVALUE(ret);
+}
+#endif /* SS_MT_TMR */
+#endif /* not SS_MULTIPLE_PROCS */
+
+
+/* ss041.103 - Addition of STmrDeregHndlr */
+/*
+*
+* Fun: STmrDeregHndlr
+*
+* Desc: This function is used to deregister a timer function.
+*
+* Ret: ROK - ok
+* RFAILED - failed, general (optional)
+*
+* Notes:
+*
+* File: ss_timer.c
+*
+*/
+/* ss029.103: addition: procId added and timer function type modified */
+
+/* ss015.301 Changed the timer activation function type as all timer activation
+ * functions are enclosed in a union.
+ */
+#ifndef SS_MULTIPLE_PROCS
+#ifdef ANSI
+PRIVATE S16 STmrDeregHndlr
+(
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+SsTmrActvFn ssTmrActvFn /* timer function */
+)
+#else
+/* ss017.301: Modified the prototype of STmrDeregHndlr for Non-ANSI
+ * compilation.
+ */
+PRIVATE S16 STmrDeregHndlr(ent, inst, period, units, ssTmrActvFn)
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+SsTmrActvFn ssTmrActvFn; /* timer function */
+#endif
+/* ss015.301: Removed the timer handler prototypes guarded under SS_MT_TMR
+ * and handled mtFlag in existing timer handlers.
+ */
+
+#else /* SS_MULTIPLE_PROCS */
+
+#ifdef ANSI
+PRIVATE S16 STmrDeregHndlr
+(
+ProcId proc, /* processor */
+Ent ent, /* entity */
+Inst inst, /* instance */
+S16 period, /* period */
+S16 units, /* period units */
+SsTmrActvFn ssTmrActvFn /* timer function */
+)
+#else
+PRIVATE S16 STmrDeregHndlr(proc, ent, inst, period, units, ssTmrActvFn)
+ProcId proc; /* processor */
+Ent ent; /* entity */
+Inst inst; /* instance */
+S16 period; /* period */
+S16 units; /* period units*/
+SsTmrActvFn ssTmrActvFn; /* timer function */
+#endif
+
+#endif /* SS_MULTIPLE_PROCS */
+{
+ S16 ret;
+ S16 idx;
+ SsTmrEntry *tmr;
+#ifdef SS_MULTIPLE_PROCS
+#if (ERRCLASS & ERRCLS_INT_PAR)
+ U16 procIdIdx;
+#endif /* ERRCLASS & ERRCLS_INT_PAR */
+#endif /* SS_MULTIPLE_PROCS */
+
+
+ TRC1(STmrDeregHndlr);
+
+
+#if (ERRCLASS & ERRCLS_INT_PAR)
+
+#ifdef SS_MULTIPLE_PROCS
+ if ((proc == SS_INV_PROCID) || (ent >= SS_MAX_ENT) || (inst >= SS_MAX_INST))
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS543, ERRZERO, "Invalid processor/entity/instance");
+ RETVALUE(RFAILED);
+ }
+
+#else /* SS_MULTIPLE_PROCS */
+ if (ent >= SS_MAX_ENT || inst >= SS_MAX_INST)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS544, ERRZERO, "Invalid entity/instance");
+ RETVALUE(RFAILED);
+ }
+#endif /* SS_MULTIPLE_PROCS */
+ /* check period */
+ if (period <= 0)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS545, ERRZERO, "Invalid period");
+ RETVALUE(RFAILED);
+ }
+
+ /* check period units */
+ if ((units < 1) || (units > SS_TICKS_SEC))
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS546, ERRZERO, "Invalid period units");
+ RETVALUE(RFAILED);
+ }
+
+ /* check timer function */
+ if(ssTmrActvFn.mtFlag == TRUE)
+ {
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+ if (ssTmrActvFn.actvFnc.tmrActvFnMt == NULLP)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS547, ERRZERO, "Null pointer");
+ RETVALUE(RFAILED);
+ }
+#else
+ RETVALUE(RFAILED);
+#endif
+#else
+ RETVALUE(RFAILED);
+#endif
+
+ }
+ else
+ {
+ if (ssTmrActvFn.actvFnc.tmrActvFn == NULLP)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS547, ERRZERO, "Null pointer");
+ RETVALUE(RFAILED);
+ }
+ }
+
+#ifdef SS_MULTIPLE_PROCS
+ /* check if the procId has been registered with SSI */
+ procIdIdx = SGetProcIdIdx(proc);
+
+ if (procIdIdx == SS_INV_PROCID_IDX)
+ {
+ SSLOGERROR(ERRCLS_INT_PAR, ESS548, ERRZERO,
+ "Could not find proc id index");
+ RETVALUE(RFAILED);
+ }
+#endif /* SS_MULTIPLE_PROCS */
+
+ /* check task ID */
+ /* lock TAPA task table */
+ SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
+ if (ret != ROK)
+ {
+ SSLOGERROR(ERRCLS_DEBUG, ESS549, ERRZERO,
+ "Could not lock TAPA task table");
+ RETVALUE(RFAILED);
+ }
+
+#ifdef SS_MULTIPLE_PROCS
+ if (osCp.tTskIds[procIdIdx][ent][inst] == SS_TSKNC)
+#else /* SS_MULTIPLE_PROCS */
+ if (osCp.tTskIds[ent][inst] == SS_TSKNC)
+#endif /* SS_MULTIPLE_PROCS */
+ {
+ if ( SS_RELEASE_SEMA(&osCp.tTskTblSem) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS550, ERRZERO,
+ "Could not release the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+ SSLOGERROR(ERRCLS_INT_PAR, ESS551, ERRZERO, "Unknown task");
+ RETVALUE(RFAILED);
+ }
+ if ( SS_RELEASE_SEMA(&osCp.tTskTblSem) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS552, ERRZERO,
+ "Could not release the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+
+#endif
+
+ /* lock the timer table */
+ ret = SLock(&osCp.tmrTblLock);
+ if (ret != ROK)
+ {
+
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS553, (ErrVal) ret,
+ "Could not lock timer table");
+#endif
+ RETVALUE(ret);
+ }
+
+
+ /* Note: Right now, we're using ent, inst and tmrActvFn to locate
+ * the timer,, this will change to using tmrId, some day.
+ */
+
+ /* locate the timer to delete in the timer table */
+ for (idx = 0; idx < SS_MAX_TMRS; idx++)
+ {
+ /* ss021.103 - Modification find timer by ent, inst, func, and period */
+ /* ss029.103: addition: multiple procId related changes */
+ if (osCp.tmrTbl[idx].ownerEnt == ent
+#ifdef SS_MULTIPLE_PROCS
+ && osCp.tmrTbl[idx].ownerProc == proc
+#endif /* SS_MULTIPLE_PROCS */
+ && osCp.tmrTbl[idx].ownerInst == inst
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+ /*
+ * ss015.301 - Modifed as timer activation functions
+ * enclosed in a union.
+ */
+ && osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == ssTmrActvFn.mtFlag
+ && ((ssTmrActvFn.mtFlag == FALSE
+ && osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn == ssTmrActvFn.actvFnc.tmrActvFn)
+ || osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt == ssTmrActvFn.actvFnc.tmrActvFnMt)
+#else
+ && osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn == ssTmrActvFn.actvFnc.tmrActvFn
+#endif
+#else
+ && osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn == ssTmrActvFn.actvFnc.tmrActvFn
+#endif
+ && osCp.tmrTbl[idx].interval == (U32) ((period * SS_TICKS_SEC) / units))
+ {
+ break;
+ }
+ }
+
+ if (idx == SS_MAX_TMRS)
+ {
+ if ( SUnlock(&osCp.tmrTblLock) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS554, ERRZERO,
+ "Could not unlock the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS555, ERRZERO, "Could not locate timer");
+#endif
+
+ RETVALUE(RFAILED);
+ }
+
+
+ /* ask the implementation to shut down this timer */
+ tmr = &osCp.tmrTbl[idx];
+ ret = ssdDeregTmr(tmr);
+ if (ret == ROK)
+ {
+ tmr->used = FALSE;
+ tmr->tmrId = 0;
+#ifdef SS_MULTIPLE_PROCS
+ tmr->ownerProc = PROCNC;
+#endif /* SS_MULTIPLE_PROCS */
+ tmr->ownerEnt = ENTNC;
+ tmr->ownerInst = INSTNC;
+ tmr->interval = 0;
+ /*
+ * ss015.301: Modifed as timer activation functions enclosed in a union.
+ */
+ tmr->ssTmrActvFn.mtFlag = FALSE;
+ tmr->ssTmrActvFn.actvFnc.tmrActvFn = NULLP;
+#ifndef SS_MULTIPLE_PROCS
+#ifdef SS_MT_TMR
+ tmr->ssTmrActvFn.actvFnc.tmrActvFnMt = NULLP;
+#endif
+#endif
+
+ tmr->nxt = osCp.nxtTmrEntry;
+ osCp.nxtTmrEntry = (SsIdx)idx;
+ osCp.numTmrs--;
+ }
+
+
+ /* unlock the timer table */
+ if ( SUnlock(&osCp.tmrTblLock) != ROK)
+ {
+#if (ERRCLASS & ERRCLS_DEBUG)
+ SSLOGERROR(ERRCLS_DEBUG, ESS556, ERRZERO,
+ "Could not unlock the semaphore");
+ RETVALUE(RFAILED);
+#endif
+ }
+
+
+ RETVALUE(ret);
+}
+
+/**********************************************************************
+ End of file
+**********************************************************************/