예제 #1
0
void
sctp_update_dce(sctp_t *sctp)
{
	sctp_faddr_t	*fp;
	sctp_stack_t	*sctps = sctp->sctp_sctps;
	iulp_t		uinfo;
	ip_stack_t	*ipst = sctps->sctps_netstack->netstack_ip;
	uint_t		ifindex;

	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
		bzero(&uinfo, sizeof (uinfo));
		/*
		 * Only record the PMTU for this faddr if we actually have
		 * done discovery. This prevents initialized default from
		 * clobbering any real info that IP may have.
		 */
		if (fp->pmtu_discovered) {
			if (fp->isv4) {
				uinfo.iulp_mtu = fp->sfa_pmss +
				    sctp->sctp_hdr_len;
			} else {
				uinfo.iulp_mtu = fp->sfa_pmss +
				    sctp->sctp_hdr6_len;
			}
		}
		if (sctps->sctps_rtt_updates != 0 &&
		    fp->rtt_updates >= sctps->sctps_rtt_updates) {
			/*
			 * dce_update_uinfo() merges these values with the
			 * old values.
			 */
			uinfo.iulp_rtt = TICK_TO_MSEC(fp->srtt);
			uinfo.iulp_rtt_sd = TICK_TO_MSEC(fp->rttvar);
			fp->rtt_updates = 0;
		}
		ifindex = 0;
		if (IN6_IS_ADDR_LINKSCOPE(&fp->faddr)) {
			/*
			 * If we are going to create a DCE we'd better have
			 * an ifindex
			 */
			if (fp->ixa->ixa_nce != NULL) {
				ifindex = fp->ixa->ixa_nce->nce_common->
				    ncec_ill->ill_phyint->phyint_ifindex;
			} else {
				continue;
			}
		}

		(void) dce_update_uinfo(&fp->faddr, ifindex, &uinfo, ipst);
	}
}
예제 #2
0
//------------------------------------------------------------------------------
//
//  Function: OEMGetTickCount
//
//  This returns the number of milliseconds that have elapsed since Windows
//  CE was started. If the system timer period is 1ms the function simply
//  returns the value of CurMSec. If the system timer period is greater then
//  1 ms, the HiRes offset is added to the value of CurMSec.
//
UINT32
OEMGetTickCount(
    )
{
    UINT64 baseCounts;
    UINT32 offset;

    // This code adjusts the accuracy of the returned value to the nearest
    // MSec when the system tick exceeds 1 ms. The following code checks if
    // a system timer interrupt occurred between reading the CurMSec value
    // and the call to fetch the HiResTicksSinceSysTick. If so, the value of
    // CurMSec and Offset is re-read, with the certainty that a system timer
    // interrupt will not occur again.
    do
        {
        baseCounts = g_oalTimerContext.curCounts;
        offset = OALTimerGetCount() - g_oalTimerContext.base;
        }
    while (baseCounts != g_oalTimerContext.curCounts);


   //  Update CurMSec (kernel uses both CurMSec and GetTickCount() at different places) and return msec tick count
    CurMSec = (UINT32)TICK_TO_MSEC(baseCounts + offset);

    return CurMSec;

}
예제 #3
0
//------------------------------------------------------------------------------
//
//  Function:  OALGetTickCount
//
//  This function returns number of 1 ms ticks which elapsed since system boot
//  or reset (absolute value isn't important). The counter can overflow but
//  overflow period should not be shorter then approx 30 seconds. Function
//  is used in  system boot so it must work before interrupt subsystem
//  is active.
//
UINT32
OALGetTickCount(
    )
{
    UINT64 tickCount = OALTimerGetReg(&g_pTimerRegs->TCRR);
    //  Returns number of 1 msec ticks
    return (UINT32) TICK_TO_MSEC(tickCount);
}
예제 #4
0
/*
 * Poll for an input event.
 *
 * timo is measured in ticks
 */
int
t_kspoll(TIUSER *tiptr, int timo, int waitflg, int *events)
{
	file_t		*fp;
	vnode_t		*vp;
	klwp_t		*lwp = ttolwp(curthread);
	clock_t		timout;	/* milliseconds */
	int		error;
	u_char 		pri;
	int 		pflag;
	rval_t		rval;

	fp = tiptr->fp;
	vp = fp->f_vnode;

	if (events == NULL || ((waitflg & READWAIT) == 0))
		return (EINVAL);

	/* Convert from ticks to milliseconds */
	if (timo < 0)
		timout = -1;
	else
		timout = TICK_TO_MSEC(timo);

	/*
	 * Indicate that the lwp is not to be stopped while doing
	 * this network traffic.  This is to avoid deadlock while
	 * debugging a process via /proc.
	 */
	if (lwp != NULL)
		lwp->lwp_nostop++;

	if (waitflg & NOINTR)
		pflag = MSG_ANY | MSG_HOLDSIG;
	else
		pflag = MSG_ANY;
	pri = 0;
	error = kstrgetmsg(vp, NULL, NULL, &pri, &pflag, timout, &rval);

	if (lwp != NULL)
		lwp->lwp_nostop--;

	/* Set the return *events. */
	if (error != 0) {
		if (error == ETIME) {
			*events = 0;
			error = 0;
		}
		return (error);
	}
	*events = 1;
	return (0);
}
예제 #5
0
/*
 * Send failure event. Message is expected to have message header still
 * in place, data follows in subsequent mblk's.
 */
static void
sctp_sendfail(sctp_t *sctp, mblk_t *msghdr, uint16_t flags, int error)
{
	struct sctp_send_failed *sfp;
	mblk_t *mp;
	sctp_msg_hdr_t *smh;

	/* Allocate a mblk for the notification header */
	if ((mp = allocb(sizeof (*sfp), BPRI_MED)) == NULL) {
		/* give up */
		freemsg(msghdr);
		return;
	}

	smh = (sctp_msg_hdr_t *)msghdr->b_rptr;
	sfp = (struct sctp_send_failed *)mp->b_rptr;
	sfp->ssf_type = SCTP_SEND_FAILED;
	sfp->ssf_flags = flags;
	sfp->ssf_length = smh->smh_msglen + sizeof (*sfp);
	sfp->ssf_error = error;
	sfp->ssf_assoc_id = 0;

	bzero(&sfp->ssf_info, sizeof (sfp->ssf_info));
	sfp->ssf_info.sinfo_stream = smh->smh_sid;
	sfp->ssf_info.sinfo_flags = smh->smh_flags;
	sfp->ssf_info.sinfo_ppid = smh->smh_ppid;
	sfp->ssf_info.sinfo_context = smh->smh_context;
	sfp->ssf_info.sinfo_timetolive = TICK_TO_MSEC(smh->smh_ttl);

	mp->b_wptr = (uchar_t *)(sfp + 1);
	mp->b_cont = msghdr->b_cont;

	freeb(msghdr);

	sctp_notify(sctp, mp, sfp->ssf_length);

}
예제 #6
0
static uint_t
ntwdt_cyclic_softint(caddr_t arg)
{
	/*LINTED E_BAD_PTR_CAST_ALIGN*/
	ntwdt_state_t *ntwdt_ptr = (ntwdt_state_t *)arg;
	ntwdt_runstate_t *ntwdt_state;

	ntwdt_state = ntwdt_ptr->ntwdt_run_state;

	mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);

	if ((ntwdt_state->ntwdt_watchdog_flags & NTWDT_FLAG_SKIP_CYCLIC) != 0) {
		ntwdt_state->ntwdt_watchdog_flags &= ~NTWDT_FLAG_SKIP_CYCLIC;
		goto end;
	}

	if ((ntwdt_state->ntwdt_timer_running == 0) ||
	    (ntwdt_ptr->ntwdt_cycl_id == CYCLIC_NONE) ||
	    (ntwdt_state->ntwdt_watchdog_enabled == 0)) {
		goto end;
	}

	NTWDT_DBG(NTWDT_DBG_IOCTL, ("cyclic_softint: %d"
	    "ddi_get_lbolt64(): %d\n", ntwdt_state->ntwdt_watchdog_timeout,
	    (int)TICK_TO_MSEC(ddi_get_lbolt64())));

	/*
	 * Decrement the virtual watchdog timer and check if it has expired.
	 */
	ntwdt_state->ntwdt_time_remaining -= NTWDT_DECREMENT_INTERVAL;

	if (ntwdt_state->ntwdt_time_remaining == 0) {
		cmn_err(CE_WARN, "application-watchdog expired");
		ntwdt_state->ntwdt_watchdog_expired = 1;

		if (ntwdt_state->ntwdt_reset_enabled != 0) {
			/*
			 * The user wants to reset the system.
			 */
			mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);

			NTWDT_DBG(NTWDT_DBG_NTWDT, ("recovery being done"));
			ntwdt_enforce_timeout();
		} else {
			NTWDT_DBG(NTWDT_DBG_NTWDT, ("no recovery being done"));
			ntwdt_state->ntwdt_watchdog_enabled = 0;
		}

		/*
		 * Schedule Callout to stop the cyclic.
		 */
		(void) timeout(ntwdt_stop_timer_lock, ntwdt_ptr, 0);
	} else {
		_NOTE(EMPTY)
		NTWDT_DBG(NTWDT_DBG_NTWDT, ("time remaining in AWDT: %d secs",
		    (int)TICK_TO_MSEC(ntwdt_state->ntwdt_time_remaining)));
	}

end:
	mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
	return (DDI_INTR_CLAIMED);
}
예제 #7
0
/*ARGSUSED*/
static int
ntwdt_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
	int *rvalp)
{
	int instance = getminor(dev);
	int retval = 0;
	ntwdt_state_t *ntwdt_ptr = NULL;
	ntwdt_runstate_t *ntwdt_state;
	lom_dogstate_t lom_dogstate;
	lom_dogctl_t lom_dogctl;
	uint32_t lom_dogtime;

	if ((ntwdt_ptr = getstate(instance)) == NULL) {
		return (ENXIO);
	}

	ntwdt_state = ntwdt_ptr->ntwdt_run_state;

	switch (cmd) {
	case LOMIOCDOGSTATE:
		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);
		lom_dogstate.reset_enable = ntwdt_state->ntwdt_reset_enabled;
		lom_dogstate.dog_enable = ntwdt_state->ntwdt_watchdog_enabled;
		lom_dogstate.dog_timeout = ntwdt_state->ntwdt_watchdog_timeout;
		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);

		if (ddi_copyout((caddr_t)&lom_dogstate, (caddr_t)arg,
		    sizeof (lom_dogstate_t), mode) != 0) {
			retval = EFAULT;
		}
		break;

	case LOMIOCDOGCTL:
		if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogctl,
		    sizeof (lom_dogctl_t), mode) != 0) {
			retval = EFAULT;
			break;
		}

		NTWDT_DBG(NTWDT_DBG_IOCTL, ("reset_enable: %d, and dog_enable: "
		    "%d, watchdog_timeout %d", lom_dogctl.reset_enable,
		    lom_dogctl.dog_enable,
		    ntwdt_state->ntwdt_watchdog_timeout));
		/*
		 * ignore request to enable reset while disabling watchdog.
		 */
		if (!lom_dogctl.dog_enable && lom_dogctl.reset_enable) {
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("invalid combination of "
			    "reset_enable: %d, and dog_enable: %d",
			    lom_dogctl.reset_enable,
			    lom_dogctl.dog_enable));
			retval = EINVAL;
			break;
		}

		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);

		if (ntwdt_state->ntwdt_watchdog_timeout == 0) {
			/*
			 * the LOMIOCDOGTIME has never been used to setup
			 * a valid timeout.
			 */
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("timeout has not been set"
			    "watchdog_timeout: %d",
			    ntwdt_state->ntwdt_watchdog_timeout));
			retval = EINVAL;
			goto end;
		}

		/*
		 * Store the user specified state in the softstate.
		 */
		ntwdt_state->ntwdt_reset_enabled = lom_dogctl.reset_enable;
		ntwdt_state->ntwdt_watchdog_enabled = lom_dogctl.dog_enable;

		if (ntwdt_state->ntwdt_watchdog_enabled != 0) {
			/*
			 * The user wants to enable the watchdog.
			 * Arm the watchdog and start the cyclic.
			 */
			ntwdt_arm_watchdog(ntwdt_state);

			if (ntwdt_state->ntwdt_timer_running == 0) {
				ntwdt_start_timer(ntwdt_ptr);
			}

			NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is enabled"));
		} else {
			/*
			 * The user wants to disable the watchdog.
			 */
			if (ntwdt_state->ntwdt_timer_running != 0) {
				ntwdt_stop_timer(ntwdt_ptr);
			}
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is disabled"));
		}

		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
		break;

	case LOMIOCDOGTIME:
		if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogtime,
		    sizeof (uint32_t), mode) != 0) {
			retval = EFAULT;
			break;
		}

		NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set timeout: %d",
		    lom_dogtime));

		/*
		 * Ensure specified timeout is valid.
		 */
		if ((lom_dogtime == 0) ||
		    (lom_dogtime > (uint32_t)NTWDT_MAX_TIMEOUT)) {
			retval = EINVAL;
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set invalid "
			    "timeout: %d", (int)TICK_TO_MSEC(lom_dogtime)));
			break;
		}

		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);

		ntwdt_state->ntwdt_watchdog_timeout = lom_dogtime;

		/*
		 * If awdt is currently running, re-arm it with the
		 * newly-specified timeout value.
		 */
		if (ntwdt_state->ntwdt_timer_running != 0) {
			ntwdt_arm_watchdog(ntwdt_state);
		}
		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
		break;

	case LOMIOCDOGPAT:
		/*
		 * Allow user to pat the watchdog timer.
		 */
		NTWDT_DBG(NTWDT_DBG_IOCTL, ("DOGPAT is invoked"));
		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);

		/*
		 * If awdt is not enabled or underlying cyclic is not
		 * running, exit.
		 */
		if (!(ntwdt_state->ntwdt_watchdog_enabled &&
		    ntwdt_state->ntwdt_timer_running)) {
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("PAT: AWDT not enabled"));
			goto end;
		}

		if (ntwdt_state->ntwdt_watchdog_expired == 0) {
			/*
			 * re-arm the awdt.
			 */
			ntwdt_arm_watchdog(ntwdt_state);
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT patted, "
			    "remainning seconds: %d",
			    ntwdt_state->ntwdt_time_remaining));
		}

		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
		break;

	default:
		retval = EINVAL;
		break;
	}
	return (retval);
end:
	mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
	return (retval);
}
예제 #8
0
//------------------------------------------------------------------------------
//
//  Function: OALTimerIntrHandler
//
//  This function implement timer interrupt handler. It is called from common
//  ARM interrupt handler.
//
UINT32 OALTimerIntrHandler()
{
    UINT32 count;
    INT32 period, delta;
    UINT32 sysIntr = SYSINTR_NOP;



    // allow bsp to process timer interrupt first
    sysIntr = OALTickTimerIntr();
    if (sysIntr != SYSINTR_NOP) return sysIntr;

    // Clear interrupt
    OALTimerSetReg(&g_pTimerRegs->TISR, GPTIMER_TIER_MATCH);

    // How far from interrupt we are?
    count = OALTimerGetCount();
    delta = count - g_oalTimerContext.match;
    

    // If delta is negative, timer fired for some reason
    // To be safe, reprogram the timer for minimum delta
    if (delta < 0)
    {
        delta = 0;
        goto cleanUp;
    }

#ifdef OAL_ILTIMING
    if (g_oalILT.active)
    {
        g_oalILT.isrTime1 = delta;
    }        
#endif

    // Find how long period was
    period = count - g_oalTimerContext.base;
    g_oalTimerContext.curCounts += period;    
    g_oalTimerContext.base += period;

    // Calculate actual CurMSec
    CurMSec = (UINT32) TICK_TO_MSEC(g_oalTimerContext.curCounts);

    OALLED(LED_IDX_TIMER, CurMSec >> 10);

    // Reschedule?
    delta = dwReschedTime - CurMSec;
    if (delta <= 0)
        {
        sysIntr = SYSINTR_RESCHED;
        delta = g_oalTimerContext.maxPeriodMSec;
        }

cleanUp:
    // Set new period
    UpdatePeriod(delta);

#ifdef OAL_ILTIMING
    if (g_oalILT.active) {
        if (--g_oalILT.counter == 0) {
            sysIntr = SYSINTR_TIMING;
            g_oalILT.counter = g_oalILT.counterSet;
            g_oalILT.isrTime2 = 0;
        }
    }
#endif

    return sysIntr;
}