//------------------------------------------------------------------------------
static void timerCallback(tTimerHdl* pTimerHdl_p)
{
    UINT            index;
    tTimerHdl       orgTimerHdl;
    tHresTimerInfo* pTimerInfo;

    index = HDL_TO_IDX(*pTimerHdl_p);
    if (index >= TIMER_COUNT)
        return;      // invalid handle

    pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];

    orgTimerHdl = *pTimerHdl_p;

    if (pTimerInfo->pfnCallback != NULL)
    {
        pTimerInfo->pfnCallback(&pTimerInfo->eventArg);
    }

    if (orgTimerHdl != pTimerInfo->eventArg.timerHdl.handle)
        return;

    if (pTimerInfo->fContinuously)
    {
        edrv_restartTimer(pTimerHdl_p, HDL_TO_IDX(*pTimerHdl_p), pTimerInfo->period);
    }
    else
    {
        edrv_stopTimer(pTimerHdl_p, HDL_TO_IDX(*pTimerHdl_p));
    }
    return;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_deleteTimer(tTimerHdl* pTimerHdl_p)
{
    tOplkError          ret = kErrorOk;
    UINT                index;
    tHresTimerInfo*     pTimerInfo;

    if (pTimerHdl_p == NULL)
        return kErrorTimerInvalidHandle;

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        return ret;
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
            return kErrorTimerInvalidHandle;       // invalid handle

        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
        if (pTimerInfo->eventArg.timerHdl.handle != *pTimerHdl_p)
            return ret;     // invalid handle
    }

    edrv_stopTimer(pTimerHdl_p, HDL_TO_IDX(*pTimerHdl_p));

    *pTimerHdl_p = 0;
    pTimerInfo->eventArg.timerHdl.handle = 0;
    pTimerInfo->pfnCallback = NULL;

    return ret;
}
enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p)
{
	unsigned int uiIndex;
	tEplTimerHighReskTimerInfo *pTimerInfo;
	tEplTimerHdl OrgTimerHdl;
	enum hrtimer_restart Ret;

	BENCHMARK_MOD_24_SET(4);

	Ret = HRTIMER_NORESTART;
	pTimerInfo =
	    container_of(pTimer_p, tEplTimerHighReskTimerInfo, m_Timer);
	uiIndex = HDL_TO_IDX(pTimerInfo->m_EventArg.m_TimerHdl);
	if (uiIndex >= TIMER_COUNT) {	// invalid handle
		goto Exit;
	}

	/*
	 * We store the timer handle before calling the callback function
	 * as the timer can be modified inside it.
	 */
	OrgTimerHdl = pTimerInfo->m_EventArg.m_TimerHdl;

	if (pTimerInfo->m_pfnCallback != NULL) {
		pTimerInfo->m_pfnCallback(&pTimerInfo->m_EventArg);
	}

	if (pTimerInfo->m_fContinuously) {
		ktime_t Interval;
#ifdef PROVE_OVERRUN
		ktime_t Now;
		unsigned long Overruns;
#endif

		if (OrgTimerHdl != pTimerInfo->m_EventArg.m_TimerHdl) {
			/* modified timer has already been restarted */
			goto Exit;
		}
#ifdef PROVE_OVERRUN
		Now = ktime_get();
		Interval =
		    ktime_add_ns(ktime_set(0, 0), pTimerInfo->m_ullPeriod);
		Overruns = hrtimer_forward(pTimer_p, Now, Interval);
		if (Overruns > 1) {
			printk
			    ("EplTimerHighResk: Continuous timer (handle 0x%lX) had to skip %lu interval(s)!\n",
			     pTimerInfo->m_EventArg.m_TimerHdl, Overruns - 1);
		}
#else
		pTimer_p->expires = ktime_add_ns(pTimer_p->expires,
						 pTimerInfo->m_ullPeriod);
#endif

		Ret = HRTIMER_RESTART;
	}

      Exit:
	BENCHMARK_MOD_24_RESET(4);
	return Ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_deleteTimer(tTimerHdl* pTimerHdl_p)
{
    tOplkError              ret = kErrorOk;
    UINT                    index;
    tHresTimerInfo*         pTimerInfo;

    // check pointer to handle
    if(pTimerHdl_p == NULL)
        return kErrorTimerInvalidHandle;

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        return ret;
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {   // invalid handle
            return kErrorTimerInvalidHandle;
        }
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
        if (pTimerInfo->eventArg.timerHdl != *pTimerHdl_p)
        {   // invalid handle
            return ret;
        }
    }

    pTimerInfo->fContinue = FALSE;
    *pTimerHdl_p = 0;
    pTimerInfo->eventArg.timerHdl = 0;
    pTimerInfo->pfnCallback = NULL;

    return ret;
}
//------------------------------------------------------------------------------
static void timerDpc(PVOID pSystemParameter1_p,
                     PVOID pFunctionContext_p,
                     PVOID pSystemParameter2_p,
                     PVOID pSystemParameter3_p)
{
    tHresTimerInfo*   pTimerInfo = (tHresTimerInfo*)pFunctionContext_p;
    tTimerHdl         orgTimerHdl;
    UINT              index;

    UNREFERENCED_PARAMETER(pSystemParameter1_p);
    UNREFERENCED_PARAMETER(pSystemParameter2_p);
    UNREFERENCED_PARAMETER(pSystemParameter3_p);

    index = (UINT)HDL_TO_IDX(pTimerInfo->eventArg.timerHdl.handle);

    if (index >= TIMER_COUNT)
        return;      // invalid handle

    orgTimerHdl = pTimerInfo->eventArg.timerHdl.handle;

    if (pTimerInfo->pfnCallback != NULL)
        pTimerInfo->pfnCallback(&pTimerInfo->eventArg);

    if (orgTimerHdl != pTimerInfo->eventArg.timerHdl.handle)
    {
        /* modified timer has already been restarted */
        return;
    }

    if (pTimerInfo->fContinuously)
    {
        NdisSetTimerObject(pTimerInfo->timerObjHandle, pTimerInfo->dueTime, 0, pTimerInfo);
    }
}
//---------------------------------------------------------------------------------
static irqreturn_t timerCounterIsr(int irqNum_p, void* pDevInstData_p)
{
    irqreturn_t         ret = IRQ_HANDLED;
    UINT                index;
    tHresTimerInfo*     pTimerInfo = (tHresTimerInfo*)pDevInstData_p;
    UINT8               reg = 0;

    UNUSED_PARAMETER(irqNum_p);

    reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_ISR_OFFSET);
    if (reg == 0)
    {
        return IRQ_NONE;
    }

    // Acknowledge the Interrupt
    XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_ISR_OFFSET, reg);
    index = HDL_TO_IDX(pTimerInfo->eventArg.timerHdl.handle);

    if (index >= TIMER_COUNT)
    {
        // invalid handle
        return ret;
    }

    if (!(reg & (XTTCPSS_INTR_MATCH_1)) && !(reg & XTTCPSS_INTR_INTERVAL))
    {
        // unknown interrupt
        return ret;
    }

    if (!pTimerInfo->fContinuously)
    {
        // Disable the interrupt for this timer
        reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_IER_OFFSET);
        reg = 0;
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_IER_OFFSET, reg);

        // stop the timer
        reg = 0;
        reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET);
        reg |= XTTCPSS_CNT_CNTRL_DISABLE;
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET, reg);

        // Clear the Match counter
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_MATCH_1_OFFSET,
                          XTTCPSS_CLEAR);
    }

    if (pTimerInfo->pfnCallback != NULL)
    {
        // call the timer callback
        pTimerInfo->pfnCallback(&pTimerInfo->eventArg);
    }

    return ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_deleteTimer(tTimerHdl* pTimerHdl_p)
{
    tOplkError          ret = kErrorOk;
    UINT                index;
    tHresTimerInfo*     pTimerInfo;
    UINT8               reg;

    // check pointer to handle
    if (pTimerHdl_p == NULL)
    {
        return kErrorTimerInvalidHandle;
    }

    if (*pTimerHdl_p == 0)
    {
        // no timer created yet
        return ret;
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {
            // invalid handle
            return kErrorTimerInvalidHandle;
        }
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
        if (pTimerInfo->eventArg.timerHdl.handle != *pTimerHdl_p)
        {
            // invalid handle
            return ret;
        }
    }

    *pTimerHdl_p = 0;
    pTimerInfo->eventArg.timerHdl.handle = 0;
    pTimerInfo->pfnCallback = NULL;

    // Disable the interrupt for this timer
    reg = 0;
    XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_IER_OFFSET, reg);

    // Stop the timer
    reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET);
    reg = 0;
    reg |= (XTTCPSS_CNT_CNTRL_DISABLE | XTTCPSS_CNT_CNTRL_EN_WAVE);
    XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET, reg);

    return ret;
}
tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl * pTimerHdl_p)
{
	tEplKernel Ret = kEplSuccessful;
	unsigned int uiIndex;
	tEplTimerHighReskTimerInfo *pTimerInfo;

	// check pointer to handle
	if (pTimerHdl_p == NULL) {
		Ret = kEplTimerInvalidHandle;
		goto Exit;
	}

	if (*pTimerHdl_p == 0) {	// no timer created yet
		goto Exit;
	} else {
		uiIndex = HDL_TO_IDX(*pTimerHdl_p);
		if (uiIndex >= TIMER_COUNT) {	// invalid handle
			Ret = kEplTimerInvalidHandle;
			goto Exit;
		}
		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
		if (pTimerInfo->m_EventArg.m_TimerHdl != *pTimerHdl_p) {	// invalid handle
			goto Exit;
		}
	}

	*pTimerHdl_p = 0;
	pTimerInfo->m_EventArg.m_TimerHdl = 0;
	pTimerInfo->m_pfnCallback = NULL;

	/*
	 * Three return cases of hrtimer_try_to_cancel have to be tracked:
	 *  1 - timer has been removed
	 *  0 - timer was not active
	 *      We need not do anything. hrtimer timers just consist of
	 *      a hrtimer struct, which we might enqueue in the hrtimers
	 *      event list by calling hrtimer_start().
	 *      If a timer is not enqueued, it is not present in hrtimers.
	 * -1 - callback function is running
	 *      In this case we have to ensure that the timer is not
	 *      continuously restarted. This has been done by clearing
	 *      its handle.
	 */
	hrtimer_try_to_cancel(&pTimerInfo->m_Timer);

      Exit:
	return Ret;

}
//---------------------------------------------------------------------------
// Function:    EplTimerHighReskDeleteTimer()
//
// Description: deletes the timer with the specified handle. Afterward the
//              handle is set to zero.
//
// Parameters:  pTimerHdl_p     = pointer to timer handle
//
// Return:      tEplKernel      = error code
//
// State:       not tested
//---------------------------------------------------------------------------
tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl* pTimerHdl_p)
{
    tEplKernel                  Ret = kEplSuccessful;
    UINT                        uiIndex;
    tEplTimerHighReskTimerInfo* pTimerInfo;
    struct itimerspec           RelTime;

    EPL_DBGLVL_TIMERH_TRACE2("%s() Deleting timer:%lx\n", __func__, *pTimerHdl_p);

    // check pointer to handle
    if(pTimerHdl_p == NULL)
    {
        Ret = kEplTimerInvalidHandle;
        goto Exit;
    }

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        goto Exit;
    }
    else
    {
        uiIndex = HDL_TO_IDX(*pTimerHdl_p);
        if (uiIndex >= TIMER_COUNT)
        {   // invalid handle
            Ret = kEplTimerInvalidHandle;
            goto Exit;
        }
        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
        if (pTimerInfo->m_EventArg.m_TimerHdl != *pTimerHdl_p)
        {   // invalid handle
            goto Exit;
        }
    }

    // values of 0 disarms the timer
    RelTime.it_value.tv_sec = 0;
    RelTime.it_value.tv_nsec = 0;
    timer_settime(pTimerInfo->m_timer, 0, &RelTime, NULL);

    *pTimerHdl_p = 0;
    pTimerInfo->m_EventArg.m_TimerHdl = 0;
    pTimerInfo->m_pfnCallback = NULL;

Exit:
    return Ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_deleteTimer(tTimerHdl* pTimerHdl_p)
{
    tOplkError                  ret = kErrorOk;
    UINT                        index;
    tHresTimerInfo*             pTimerInfo;
    struct itimerspec           relTime;

    DEBUG_LVL_TIMERH_TRACE("%s() Deleting timer:%lx\n", __func__, *pTimerHdl_p);

    if (pTimerHdl_p == NULL)
        return kErrorTimerInvalidHandle;

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        return ret;
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {   // invalid handle
            return kErrorTimerInvalidHandle;
        }
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
        if (pTimerInfo->eventArg.timerHdl != *pTimerHdl_p)
        {   // invalid handle
            return ret;
        }
    }

    // values of 0 disarms the timer
    relTime.it_value.tv_sec = 0;
    relTime.it_value.tv_nsec = 0;
    timer_settime(pTimerInfo->timer, 0, &relTime, NULL);

    *pTimerHdl_p = 0;
    pTimerInfo->eventArg.timerHdl = 0;
    pTimerInfo->pfnCallback = NULL;

    return ret;
}
//---------------------------------------------------------------------------
// Function:    EplTimerHighReskDeleteTimer()
//
// Description: deletes the timer with the specified handle. Afterward the
//              handle is set to zero.
//
// Parameters:  pTimerHdl_p     = pointer to timer handle
//
// Return:      tEplKernel      = error code
//
// State:       not tested
//---------------------------------------------------------------------------
tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl* pTimerHdl_p)
{
    tEplKernel                  Ret = kEplSuccessful;
    unsigned int                uiIndex;
    tEplTimerHighReskTimerInfo* pTimerInfo;

    // check pointer to handle
    if(pTimerHdl_p == NULL)
    {
        Ret = kEplTimerInvalidHandle;
        goto Exit;
    }

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        goto Exit;
    }
    else
    {
        uiIndex = HDL_TO_IDX(*pTimerHdl_p);
        if (uiIndex >= TIMER_COUNT)
        {   // invalid handle
            Ret = kEplTimerInvalidHandle;
            goto Exit;
        }
        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
        if (pTimerInfo->m_EventArg.m_TimerHdl != *pTimerHdl_p)
        {   // invalid handle
            goto Exit;
        }
    }

    pTimerInfo->m_fContinuously = FALSE;
    *pTimerHdl_p = 0;
    pTimerInfo->m_EventArg.m_TimerHdl = 0;
    pTimerInfo->m_pfnCallback = NULL;

Exit:
    return Ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_deleteTimer(tTimerHdl* pTimerHdl_p)
{
    tOplkError          ret = kErrorOk;
    UINT                index;
    tHresTimerInfo*     pTimerInfo;
    HANDLE              hTimer;

    DEBUG_LVL_TIMERH_TRACE("%s() Deleting timer: %lx\n", __func__, *pTimerHdl_p);

    if (pTimerHdl_p == NULL)
        return kErrorTimerInvalidHandle;

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        return ret;
    }
    else
    {
        index = (UINT)HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {   // invalid handle
            return kErrorTimerInvalidHandle;
        }
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
        if (pTimerInfo->eventArg.timerHdl.handle != *pTimerHdl_p)
        {   // invalid handle
            return ret;
        }
    }

    pTimerInfo->pfnCallback = NULL;
    *pTimerHdl_p = 0;

    // Cancel timer
    hTimer = hresTimerInstance_l.aHandle[index + HRTIMER_HDL_TIMER0];
    CancelWaitableTimer(hTimer);
    return ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_exit(void)
{
    tHresTimerInfo*     pTimerInfo;
    tOplkError          ret = kErrorOk;
    UINT                index;

    for (index = 0; index < TIMER_COUNT; index++)
    {
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
        pTimerInfo->pfnCallback = NULL;

        ret = edrv_stopTimer(&pTimerInfo->eventArg.timerHdl.handle,
                             HDL_TO_IDX(pTimerInfo->eventArg.timerHdl.handle));
        if (ret != kErrorOk)
            break;

        pTimerInfo->eventArg.timerHdl.handle = 0;
    }

    // De-register the default timer callback
    ret = edrv_registerHresCallback(NULL);

    return ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p,
                                 ULONGLONG time_p,
                                 tTimerkCallback pfnCallback_p,
                                 ULONG argument_p,
                                 BOOL fContinue_p)
{
    tHresTimerInfo*     pTimerInfo;
    ULONGLONG           counter = 0;
    UINT                index;
    UINT8               reg;

    // check pointer to handle
    if (pTimerHdl_p == NULL)
    {
        return kErrorTimerInvalidHandle;
    }

    if (*pTimerHdl_p == 0)
    {
        // no timer created yet
        // search free timer info structure
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[0];
        for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++)
        {
            if (pTimerInfo->eventArg.timerHdl.handle == 0)
            {
                // free structure found
                break;
            }
        }
        if (index >= TIMER_COUNT)
        {
            // no free structure found
            return kErrorTimerNoTimerCreated;
        }

        pTimerInfo->eventArg.timerHdl.handle = HDL_INIT(index);
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {
            // invalid handle
            return kErrorTimerInvalidHandle;
        }

        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
    }

    // increment timer handle (if timer expires right after this statement,
    // the user would detect an unknown timer handle and discard it)
    pTimerInfo->eventArg.timerHdl.handle = HDL_INC(pTimerInfo->eventArg.timerHdl.handle);
    *pTimerHdl_p = pTimerInfo->eventArg.timerHdl.handle;

    // Adjust the Timeout if its to small
    if (fContinue_p != FALSE)
    {
        if (time_p < TIMER_MIN_VAL_CYCLE)
        {
            time_p = TIMER_MIN_VAL_CYCLE;
        }
    }
    else
    {
        if (time_p < TIMER_MIN_VAL_SINGLE)
        {
            time_p = TIMER_MIN_VAL_SINGLE;
        }
    }

    // Get the counter value from the timeout
    counter = (ULONGLONG)NSEC_TO_COUNT(time_p);
    if (counter > 0xFFFF)
    {
        return kErrorTimerNoTimerCreated;
    }

    pTimerInfo->eventArg.argument.value = argument_p;
    pTimerInfo->pfnCallback = pfnCallback_p;

    // disable the Timer
    reg = 0;
    reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET);
    reg |= XTTCPSS_CNT_CNTRL_DISABLE;
    XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET, reg);

    if (fContinue_p != FALSE)
    {
        pTimerInfo->fContinuously = fContinue_p;
        // Set the interval for continuous timer
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_INTR_VAL_OFFSET, (UINT16)counter);

        // Enable the interval interrupt
        reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_IER_OFFSET);
        reg = XTTCPSS_INTR_INTERVAL;
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_IER_OFFSET, reg);

        // Set specific values in Counter control reg
        reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET);
        reg |= (XTTCPSS_CNT_CNTRL_RST | XTTCPSS_CNT_CNTRL_INTERVAL);
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET, reg);
    }
    else
    {
        pTimerInfo->fContinuously = fContinue_p;
        // Set match counter for one-shot timer
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_MATCH_1_OFFSET, (UINT16)counter);
        // Enable the Match1 interrupt
        reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_IER_OFFSET);
        reg = XTTCPSS_INTR_MATCH_1;
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_IER_OFFSET, reg);

        // Set specific values in Counter control reg
        reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET);
        reg |= (XTTCPSS_CNT_CNTRL_MATCH | XTTCPSS_CNT_CNTRL_RST);
        XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET, reg);
    }

    // Re-enable the timer
    reg = XTTCPSS_READ_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET);
    reg &= ~XTTCPSS_CNT_CNTRL_DISABLE;
    XTTCPSS_WRITE_REG(pTimerInfo->index, XTTCPSS_CNT_CNTRL_OFFSET, reg);

    return kErrorOk;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p, ULONGLONG time_p,
                                 tTimerkCallback pfnCallback_p, ULONG argument_p,
                                 BOOL fContinue_p)
{
    tOplkError                  ret = kErrorOk;
    UINT                        index;
    tHresTimerInfo*             pTimerInfo;
    struct itimerspec           relTime;

    if (pTimerHdl_p == NULL)
    {
        DEBUG_LVL_ERROR_TRACE("%s() Invalid timer handle\n", __func__);
        return kErrorTimerInvalidHandle;
    }

    if (*pTimerHdl_p == 0)
    {   // no timer created yet, search free timer info structure
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[0];
        for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++)
        {
            if (pTimerInfo->eventArg.timerHdl == 0)
                break;      // free structure found
        }
        if (index >= TIMER_COUNT)
        {   // no free structure found
            DEBUG_LVL_ERROR_TRACE("%s() Invalid timer index:%d\n", __func__, index);
            return kErrorTimerNoTimerCreated;
        }
        pTimerInfo->eventArg.timerHdl = HDL_INIT(uiIndex);
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {   // invalid handle
            DEBUG_LVL_ERROR_TRACE("%s() Invalid timer index:%d\n", __func__, index);
            return kErrorTimerInvalidHandle;
        }
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
    }

    // increase too small time values
    if (fContinue_p != FALSE)
    {
        if (time_p < TIMER_MIN_VAL_CYCLE)
            time_p = TIMER_MIN_VAL_CYCLE;
    }
    else
    {
        if (time_p < TIMER_MIN_VAL_SINGLE)
            time_p = TIMER_MIN_VAL_SINGLE;
    }

    /* Increment timer handle (if timer expires right after this statement, the user
     * would detect an unknown timer handle and discard it) */
    pTimerInfo->eventArg.timerHdl = HDL_INC(pTimerInfo->eventArg.timerHdl);
    *pTimerHdl_p = pTimerInfo->eventArg.timerHdl;

    /* initialize timer info */
    pTimerInfo->eventArg.argument.value = argument_p;
    pTimerInfo->pfnCallback = pfnCallback_p;
    hrtimer_setCallback(pTimerInfo->timer, (void*)pTimerInfo->pfnCallback,
                        (void*)&pTimerInfo->eventArg);

    /*logMsg("set TCB: %p(%p)\n", (int)pTimerInfo->pfnCallback, (int)pTimerInfo->eventArg.argument.value, 0, 0, 0, 0);*/

    if (time_p >= 1000000000L)
    {
        relTime.it_value.tv_sec = (time_p / 1000000000L);
        relTime.it_value.tv_nsec = (time_p % 1000000000);
    }
    else
    {
        relTime.it_value.tv_sec = 0;
        relTime.it_value.tv_nsec = time_p;
    }

    if (fContinue_p)
    {
        relTime.it_interval.tv_nsec = relTime.it_value.tv_nsec;
        relTime.it_interval.tv_sec = relTime.it_value.tv_sec;
    }
    else
    {
        relTime.it_interval.tv_nsec = 0;
        relTime.it_interval.tv_sec = 0;
    }
#if 0
    DEBUG_LVL_TIMERH_TRACE("hrestimer_modifyTimer() timer=%lx ",
            pTimerInfo->eventArg.timerHdl);
    DEBUG_LVL_TIMERH_TRACE("        timeout=%ld:%ld/%ld:%ld\n",
           relTime.it_value.tv_sec, relTime.it_value.tv_nsec,
           relTime.it_interval.tv_sec, relTime.it_interval.tv_nsec);
#endif

    hrtimer_settime(pTimerInfo->timer, 0, &relTime, NULL);
    return ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p,
                                 ULONGLONG time_p,
                                 tTimerkCallback pfnCallback_p,
                                 ULONG argument_p,
                                 BOOL fContinue_p)
{
    tOplkError          ret = kErrorOk;
    BOOL                fRet;
    UINT                index;
    tHresTimerInfo*     pTimerInfo;
    HANDLE              hTimer;
    LARGE_INTEGER       dueTime;

    // check pointer to handle
    if (pTimerHdl_p == NULL)
    {
        DEBUG_LVL_ERROR_TRACE("%s() Invalid timer handle\n", __func__);
        return kErrorTimerInvalidHandle;
    }

    if (*pTimerHdl_p == 0)
    {   // no timer created yet -> search free timer info structure
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[0];
        for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++)
        {
            if (pTimerInfo->pfnCallback == NULL)
            {   // free structure found
                break;
            }
        }

        if (index >= TIMER_COUNT)
        {   // no free structure found
            DEBUG_LVL_ERROR_TRACE("%s() Invalid timer index: %d\n", __func__, index);
            return kErrorTimerNoTimerCreated;
        }
        pTimerInfo->eventArg.timerHdl.handle = HDL_INIT(index);
    }
    else
    {
        index = (UINT)HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {   // invalid handle
            DEBUG_LVL_ERROR_TRACE("%s() Invalid timer index: %d\n", __func__, index);
            return kErrorTimerInvalidHandle;
        }
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
    }

    // increment timer handle (if timer expires right after this statement,
    // the user would detect an unknown timer handle and discard it)
    pTimerInfo->eventArg.timerHdl.handle = HDL_INC(pTimerInfo->eventArg.timerHdl.handle);

    // calculate duetime [100 ns] (negative value = relative time)
    dueTime.QuadPart = (LONGLONG)time_p / -100LL;
    if (dueTime.QuadPart > -10000LL)
    {   // duetime is less than 1 ms
        dueTime.QuadPart = -10000LL;
    }

    if (fContinue_p != FALSE)
    {   // continuous timer
        pTimerInfo->dueTime = dueTime;
    }
    else
    {   // one-shot timer
        pTimerInfo->dueTime.QuadPart = 0LL;
    }

    pTimerInfo->eventArg.argument.value = argument_p;
    pTimerInfo->pfnCallback = pfnCallback_p;

    *pTimerHdl_p = pTimerInfo->eventArg.timerHdl.handle;

    // Configure timer
    hTimer = hresTimerInstance_l.aHandle[index + HRTIMER_HDL_TIMER0];
    fRet = SetWaitableTimer(hTimer, &dueTime, 0L, NULL, NULL, 0);
    if (!fRet)
    {
        DEBUG_LVL_ERROR_TRACE("SetWaitableTimer failed (%d)\n", GetLastError());
        return kErrorTimerNoTimerCreated;
    }

    return ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p, ULONGLONG time_p,
                                 tTimerkCallback pfnCallback_p, ULONG argument_p,
                                 BOOL fContinue_p)
{
    tOplkError              ret = kErrorOk;
    UINT                    index;
    tHresTimerInfo*         pTimerInfo;
    struct itimerspec       RelTime;

    // check pointer to handle
    if (pTimerHdl_p == NULL)
    {
        DEBUG_LVL_ERROR_TRACE("%s() Invalid timer handle\n", __func__);
        return kErrorTimerInvalidHandle;
    }

    if (*pTimerHdl_p == 0)
    {   // no timer created yet -> search free timer info structure
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[0];
        for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++)
        {
            if (pTimerInfo->eventArg.timerHdl == 0)
            {   // free structure found
                break;
            }
        }
        if (index >= TIMER_COUNT)
        {   // no free structure found
            DEBUG_LVL_ERROR_TRACE("%s() Invalid timer index:%d\n", __func__, index);
            return kErrorTimerNoTimerCreated;
        }
        pTimerInfo->eventArg.timerHdl = HDL_INIT(index);
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {   // invalid handle
            DEBUG_LVL_ERROR_TRACE("%s() Invalid timer index:%d\n", __func__, index);
            return kErrorTimerInvalidHandle;
        }
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
    }

    // increase too small time values
    if (fContinue_p != FALSE)
    {
        if (time_p < TIMER_MIN_VAL_CYCLE)
            time_p = TIMER_MIN_VAL_CYCLE;
    }
    else
    {
        if (time_p < TIMER_MIN_VAL_SINGLE)
            time_p = TIMER_MIN_VAL_SINGLE;
    }

    /* increment timer handle
     * (if timer expires right after this statement, the user
     * would detect an unknown timer handle and discard it) */
    pTimerInfo->eventArg.timerHdl = HDL_INC(pTimerInfo->eventArg.timerHdl);
    *pTimerHdl_p = pTimerInfo->eventArg.timerHdl;

    /* initialize timer info */
    pTimerInfo->eventArg.argument.value = argument_p;
    pTimerInfo->pfnCallback = pfnCallback_p;

    if (time_p >= 1000000000L)
    {
        RelTime.it_value.tv_sec = (time_p / 1000000000L);
        RelTime.it_value.tv_nsec = (time_p % 1000000000);
    }
    else
    {
        RelTime.it_value.tv_sec = 0;
        RelTime.it_value.tv_nsec = time_p;
    }

    if (fContinue_p)
    {
        RelTime.it_interval.tv_nsec = RelTime.it_value.tv_nsec;
        RelTime.it_interval.tv_sec = RelTime.it_value.tv_sec;
    }
    else
    {
        RelTime.it_interval.tv_nsec = 0;
        RelTime.it_interval.tv_sec = 0;
    }

    DEBUG_LVL_TIMERH_TRACE("%s() timer:%lx timeout=%ld:%ld\n", __func__,
                            pTimerInfo->eventArg.timerHdl,
                            RelTime.it_value.tv_sec, RelTime.it_value.tv_nsec);

    timer_settime(pTimerInfo->timer, 0, &RelTime, NULL);

    return ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p, ULONGLONG time_p,
                                 tTimerkCallback pfnCallback_p, ULONG argument_p,
                                 BOOL fContinue_p)
{
    tOplkError              ret = kErrorOk;
    UINT                    index;
    tHresTimerInfo*         pTimerInfo;

    DEBUG_LVL_TIMERH_TRACE("%s() pTimerHdl_p=%08x/%08x\n",
                            __func__, (unsigned int)pTimerHdl_p,(unsigned int)*pTimerHdl_p);

    if(pTimerHdl_p == NULL)
        return kErrorTimerInvalidHandle;

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        // search free timer info structure
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[0];
        for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++)
        {
            if (pTimerInfo->eventArg.timerHdl == 0)
            {   // free structure found
                break;
            }
        }
        if (index >= TIMER_COUNT)
        {   // no free structure found
            return kErrorTimerNoTimerCreated;
        }

        pTimerInfo->eventArg.timerHdl = HDL_INIT(index);
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
        {   // invalid handle
            return kErrorTimerInvalidHandle;
        }

        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
    }

    // increase too small time values
    if (fContinue_p != FALSE)
    {
        if (time_p < TIMER_MIN_VAL_CYCLE)
            time_p = TIMER_MIN_VAL_CYCLE;
    }
    else
    {
        if (time_p < TIMER_MIN_VAL_SINGLE)
            time_p = TIMER_MIN_VAL_SINGLE;
    }

    /* increment timer handle
     * (if timer expires right after this statement, the user
     * would detect an unknown timer handle and discard it) */
    pTimerInfo->eventArg.timerHdl = HDL_INC(pTimerInfo->eventArg.timerHdl);
    *pTimerHdl_p = pTimerInfo->eventArg.timerHdl;

    /* initialize timer info */
    pTimerInfo->eventArg.argument.value = argument_p;
    pTimerInfo->pfnCallback = pfnCallback_p;
    pTimerInfo->fContinue   = fContinue_p;
    pTimerInfo->time        = time_p;

    clock_gettime(CLOCK_MONOTONIC, &pTimerInfo->startTime);  // get current time
    sem_post(&pTimerInfo->syncSem); /* signal timer start to thread */

    return ret;
}
//---------------------------------------------------------------------------
// Function:    EplTimerHighReskModifyTimerNs()
//
// Description: modifies the timeout of the timer with the specified handle.
//              If the handle the pointer points to is zero, the timer must
//              be created first.
//              If it is not possible to stop the old timer,
//              this function always assures that the old timer does not
//              trigger the callback function with the same handle as the new
//              timer. That means the callback function must check the passed
//              handle with the one returned by this function. If these are
//              unequal, the call can be discarded.
//
// Parameters:  pTimerHdl_p     = pointer to timer handle
//              ullTimeNs_p     = relative timeout in [ns]
//              pfnCallback_p   = callback function, which is called mutual
//                                exclusive with the Edrv callback functions
//                                (Rx and Tx).
//              ulArgument_p    = user-specific argument
//              fContinuously_p = if TRUE, callback function will be called
//                                continuously;
//                                otherwise, it is a oneshot timer.
//
// Return:      tEplKernel      = error code
//---------------------------------------------------------------------------
tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl*     pTimerHdl_p,
                                    ULONGLONG           ullTimeNs_p,
                                    tEplTimerkCallback  pfnCallback_p,
                                    ULONG               ulArgument_p,
                                    BOOL                fContinuously_p)
{
    tEplKernel                   Ret;
    UINT                         uiIndex;
    tEplTimerHighReskTimerInfo*  pTimerInfo;

    /*
    EPL_DBGLVL_TIMERH_TRACE("%s() pTimerHdl_p=%08x/%08x\n",
      __func__, (unsigned int)pTimerHdl_p,(unsigned int)*pTimerHdl_p);
    */

    Ret = kEplSuccessful;

    // check pointer to handle
    if(pTimerHdl_p == NULL)
    {
        Ret = kEplTimerInvalidHandle;
        goto Exit;
    }

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        // search free timer info structure
        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
        for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++, pTimerInfo++)
        {
            if (pTimerInfo->m_EventArg.m_TimerHdl == 0)
            {   // free structure found
                break;
            }
        }
        if (uiIndex >= TIMER_COUNT)
        {   // no free structure found
            Ret = kEplTimerNoTimerCreated;
            goto Exit;
        }

        pTimerInfo->m_EventArg.m_TimerHdl = HDL_INIT(uiIndex);
    }
    else
    {
        uiIndex = HDL_TO_IDX(*pTimerHdl_p);
        if (uiIndex >= TIMER_COUNT)
        {   // invalid handle
            Ret = kEplTimerInvalidHandle;
            goto Exit;
        }

        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
    }

    // increase too small time values
    if (fContinuously_p != FALSE)
    {
        if (ullTimeNs_p < TIMER_MIN_VAL_CYCLE)
        {
            ullTimeNs_p = TIMER_MIN_VAL_CYCLE;
        }
    }
    else
    {
        if (ullTimeNs_p < TIMER_MIN_VAL_SINGLE)
        {
            ullTimeNs_p = TIMER_MIN_VAL_SINGLE;
        }
    }

    /*
     * increment timer handle
     * (if timer expires right after this statement, the user
     * would detect an unknown timer handle and discard it)
     */
    pTimerInfo->m_EventArg.m_TimerHdl = HDL_INC(pTimerInfo->m_EventArg.m_TimerHdl);
    *pTimerHdl_p = pTimerInfo->m_EventArg.m_TimerHdl;

    /* initialize timer info */
    pTimerInfo->m_EventArg.m_Arg.m_dwVal = ulArgument_p;
    pTimerInfo->m_pfnCallback      = pfnCallback_p;
    pTimerInfo->m_fContinuously    = fContinuously_p;
    pTimerInfo->m_ullTime          = ullTimeNs_p;

    clock_gettime(CLOCK_MONOTONIC, &pTimerInfo->m_startTime);  // get current time

    /* signal timer start to thread */
    sem_post(&pTimerInfo->m_syncSem);

Exit:
    return Ret;
}
tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
						unsigned long long ullTimeNs_p,
						tEplTimerkCallback
						pfnCallback_p,
						unsigned long ulArgument_p,
						BOOL fContinuously_p)
{
	tEplKernel Ret;
	unsigned int uiIndex;
	tEplTimerHighReskTimerInfo *pTimerInfo;
	ktime_t RelTime;

	Ret = kEplSuccessful;

	// check pointer to handle
	if (pTimerHdl_p == NULL) {
		Ret = kEplTimerInvalidHandle;
		goto Exit;
	}

	if (*pTimerHdl_p == 0) {	// no timer created yet

		// search free timer info structure
		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
		for (uiIndex = 0; uiIndex < TIMER_COUNT;
		     uiIndex++, pTimerInfo++) {
			if (pTimerInfo->m_EventArg.m_TimerHdl == 0) {	// free structure found
				break;
			}
		}
		if (uiIndex >= TIMER_COUNT) {	// no free structure found
			Ret = kEplTimerNoTimerCreated;
			goto Exit;
		}

		pTimerInfo->m_EventArg.m_TimerHdl = HDL_INIT(uiIndex);
	} else {
		uiIndex = HDL_TO_IDX(*pTimerHdl_p);
		if (uiIndex >= TIMER_COUNT) {	// invalid handle
			Ret = kEplTimerInvalidHandle;
			goto Exit;
		}

		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
	}

	/*
	 * increment timer handle
	 * (if timer expires right after this statement, the user
	 * would detect an unknown timer handle and discard it)
	 */
	pTimerInfo->m_EventArg.m_TimerHdl =
	    HDL_INC(pTimerInfo->m_EventArg.m_TimerHdl);
	*pTimerHdl_p = pTimerInfo->m_EventArg.m_TimerHdl;

	// reject too small time values
	if ((fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_CYCLE))
	    || (!fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_SINGLE))) {
		Ret = kEplTimerNoTimerCreated;
		goto Exit;
	}

	pTimerInfo->m_EventArg.m_ulArg = ulArgument_p;
	pTimerInfo->m_pfnCallback = pfnCallback_p;
	pTimerInfo->m_fContinuously = fContinuously_p;
	pTimerInfo->m_ullPeriod = ullTimeNs_p;

	/*
	 * HRTIMER_MODE_REL does not influence general handling of this timer.
	 * It only sets relative mode for this start operation.
	 * -> Expire time is calculated by: Now + RelTime
	 * hrtimer_start also skips pending timer events.
	 * The state HRTIMER_STATE_CALLBACK is ignored.
	 * We have to cope with that in our callback function.
	 */
	RelTime = ktime_add_ns(ktime_set(0, 0), ullTimeNs_p);
	hrtimer_start(&pTimerInfo->m_Timer, RelTime, HRTIMER_MODE_REL);

      Exit:
	return Ret;

}
//------------------------------------------------------------------------------
tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p,
                                 ULONGLONG time_p,
                                 tTimerkCallback pfnCallback_p,
                                 ULONG argument_p,
                                 BOOL fContinue_p)
{
    tOplkError          ret = kErrorOk;
    UINT                index;
    tHresTimerInfo*     pTimerInfo;

    if (pTimerHdl_p == NULL)
        return kErrorTimerInvalidHandle;

    if (*pTimerHdl_p == 0)
    {   // no timer created yet

        // search free timer info structure
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[0];
        for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++)
        {
            if (pTimerInfo->eventArg.timerHdl.handle == 0)
                break;      // free structure found
        }

        if (index >= TIMER_COUNT)
            return kErrorTimerNoTimerCreated;    // no free structure found

        pTimerInfo->eventArg.timerHdl.handle = HDL_INIT(index);
    }
    else
    {
        index = HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
            return kErrorTimerInvalidHandle;       // invalid handle

        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
    }

    /* increment timer handle
     * (if timer expires right after this statement, the user
     * would detect an unknown timer handle and discard it) */
    pTimerInfo->eventArg.timerHdl.handle = HDL_INC(pTimerInfo->eventArg.timerHdl.handle);
    *pTimerHdl_p = pTimerInfo->eventArg.timerHdl.handle;

    if (fContinue_p != FALSE)
    {
        if (time_p < TIMER_MIN_VAL_CYCLE)
            time_p = TIMER_MIN_VAL_CYCLE;
    }
    else
    {
        if (time_p < TIMER_MIN_VAL_SINGLE)
            time_p = TIMER_MIN_VAL_SINGLE;
    }

    pTimerInfo->eventArg.argument.value = argument_p;
    pTimerInfo->pfnCallback = pfnCallback_p;
    pTimerInfo->period = time_p;
    pTimerInfo->fContinuously = fContinue_p;

    // Register the default timer callback
    ret = edrv_registerHresCallback(timerCallback);
    if (ret != kErrorOk)
    {
        printk("Failed to register timer callback\n");
        return ret;
    }

    ret = edrv_startTimer(&pTimerInfo->eventArg.timerHdl.handle,
                          HDL_TO_IDX(pTimerInfo->eventArg.timerHdl.handle),
                          time_p);

    return ret;
}
//---------------------------------------------------------------------------
// Function:    EplTimerHighReskModifyTimerNs()
//
// Description: modifies the timeout of the timer with the specified handle.
//              If the handle the pointer points to is zero, the timer must
//              be created first.
//
// Parameters:  pTimerHdl_p     = pointer to timer handle
//              ullTimeNs_p     = relative timeout in [ns]
//              pfnCallback_p   = callback function, which is called mutual
//                                exclusive with the Edrv callback functions
//                                (Rx and Tx).
//              ulArgument_p    = user-specific argument
//              fContinuously_p = if TRUE, callback function will be called
//                                continuously;
//                                otherwise, it is a oneshot timer.
//
// Return:      tEplKernel      = error code
//---------------------------------------------------------------------------
tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl*     pTimerHdl_p,
                                    ULONGLONG           ullTimeNs_p,
                                    tEplTimerkCallback  pfnCallback_p,
                                    ULONG               ulArgument_p,
                                    BOOL                fContinuously_p)
{
    tEplKernel                   Ret;
    UINT                         uiIndex;
    tEplTimerHighReskTimerInfo*  pTimerInfo;
    struct itimerspec            RelTime;


    Ret = kEplSuccessful;

    // check pointer to handle
    if(pTimerHdl_p == NULL)
    {
        EPL_DBGLVL_ERROR_TRACE1("%s() Invalid timer handle\n", __func__);
        Ret = kEplTimerInvalidHandle;
        goto Exit;
    }

    if (*pTimerHdl_p == 0)
    {   // no timer created yet
        // search free timer info structure
        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
        for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++, pTimerInfo++)
        {
            if (pTimerInfo->m_EventArg.m_TimerHdl == 0)
            {   // free structure found
                break;
            }
        }
        if (uiIndex >= TIMER_COUNT)
        {   // no free structure found
            EPL_DBGLVL_ERROR_TRACE2("%s() Invalid timer index:%d\n", __func__, uiIndex);
            Ret = kEplTimerNoTimerCreated;
            goto Exit;
        }

        pTimerInfo->m_EventArg.m_TimerHdl = HDL_INIT(uiIndex);
    }
    else
    {
        uiIndex = HDL_TO_IDX(*pTimerHdl_p);
        if (uiIndex >= TIMER_COUNT)
        {   // invalid handle
            EPL_DBGLVL_ERROR_TRACE2("%s() Invalid timer index:%d\n", __func__, uiIndex);
            Ret = kEplTimerInvalidHandle;
            goto Exit;
        }

        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
    }

    // increase too small time values
    if (fContinuously_p != FALSE)
    {
        if (ullTimeNs_p < TIMER_MIN_VAL_CYCLE)
        {
            ullTimeNs_p = TIMER_MIN_VAL_CYCLE;
        }
    }
    else
    {
        if (ullTimeNs_p < TIMER_MIN_VAL_SINGLE)
        {
            ullTimeNs_p = TIMER_MIN_VAL_SINGLE;
        }
    }

    /*
     * increment timer handle
     * (if timer expires right after this statement, the user
     * would detect an unknown timer handle and discard it)
     */
    pTimerInfo->m_EventArg.m_TimerHdl = HDL_INC(pTimerInfo->m_EventArg.m_TimerHdl);
    *pTimerHdl_p = pTimerInfo->m_EventArg.m_TimerHdl;

    /* initialize timer info */
    pTimerInfo->m_EventArg.m_Arg.m_dwVal = ulArgument_p;
    pTimerInfo->m_pfnCallback      = pfnCallback_p;

    if (ullTimeNs_p >= 1000000000L)
    {
        RelTime.it_value.tv_sec = (ullTimeNs_p / 1000000000L);
        RelTime.it_value.tv_nsec = (ullTimeNs_p % 1000000000) ;
    }
    else
    {
        RelTime.it_value.tv_sec = 0;
        RelTime.it_value.tv_nsec = ullTimeNs_p;
    }

    if (fContinuously_p)
    {
        RelTime.it_interval.tv_nsec = RelTime.it_value.tv_nsec;
        RelTime.it_interval.tv_sec = RelTime.it_value.tv_sec;
    }
    else
    {
        RelTime.it_interval.tv_nsec = 0;
        RelTime.it_interval.tv_sec = 0;
    }

    /*
    EPL_DBGLVL_TIMERH_TRACE4("%s() timer:%lx timeout=%ld:%ld\n", __func__,
           pTimerInfo->m_EventArg.m_TimerHdl,
           RelTime.it_value.tv_sec, RelTime.it_value.tv_nsec);
           */

    timer_settime(pTimerInfo->m_timer, 0, &RelTime, NULL);

Exit:
    return Ret;
}
//------------------------------------------------------------------------------
tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p,
                                 ULONGLONG time_p,
                                 tTimerkCallback pfnCallback_p,
                                 ULONG argument_p,
                                 BOOL fContinue_p)
{
    UINT              index;
    tHresTimerInfo*   pTimerInfo;
    LONGLONG          relTime;

    if (pTimerHdl_p == NULL)
        return kErrorTimerInvalidHandle;

    if (*pTimerHdl_p == 0)
    {
        // search free timer info structure
        pTimerInfo = &hresTimerInstance_l.aTimerInfo[0];
        for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++)
        {
            if (pTimerInfo->eventArg.timerHdl.handle == 0)
                break;
        }

        if (index >= TIMER_COUNT)
            return kErrorTimerNoTimerCreated;

        pTimerInfo->eventArg.timerHdl.handle = HDL_INIT(index);
    }
    else
    {
        index = (UINT)HDL_TO_IDX(*pTimerHdl_p);
        if (index >= TIMER_COUNT)
            return kErrorTimerInvalidHandle;

        pTimerInfo = &hresTimerInstance_l.aTimerInfo[index];
    }

    /* increment timer handle
     * (if timer expires right after this statement, the user
     * would detect an unknown timer handle and discard it) */
    pTimerInfo->eventArg.timerHdl.handle = HDL_INC(pTimerInfo->eventArg.timerHdl.handle);
    *pTimerHdl_p = pTimerInfo->eventArg.timerHdl.handle;

    // increase too small time values
    if (fContinue_p != FALSE)
    {
        if (time_p < TIMER_MIN_VAL_CYCLE)
            time_p = TIMER_MIN_VAL_CYCLE;
    }
    else
    {
        if (time_p < TIMER_MIN_VAL_SINGLE)
            time_p = TIMER_MIN_VAL_SINGLE;
    }

    pTimerInfo->eventArg.argument.value = argument_p;
    pTimerInfo->pfnCallback = pfnCallback_p;
    pTimerInfo->fContinuously = fContinue_p;

    relTime = time_p / 100LL;
    if (relTime < 0)
    {
        // Negative value is not allowed
        return kErrorTimerNoTimerCreated;
    }

    pTimerInfo->dueTime.QuadPart = -(relTime);
    NdisSetTimerObject(pTimerInfo->timerObjHandle, pTimerInfo->dueTime, 0, pTimerInfo);

    return kErrorOk;
}