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); } }
//------------------------------------------------------------------------------ // // 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; }
//------------------------------------------------------------------------------ // // 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); }
/* * 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); }
/* * 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); }
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); }
/*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); }
//------------------------------------------------------------------------------ // // 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; }