version 1.44.8.2, 2008/01/23 19:27:40 |
version 1.45, 2007/12/20 23:03:08 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
#include <sys/types.h> /* XXX to get __HAVE_TIMECOUNTER, remove |
|
after all ports are converted. */ |
|
#ifdef __HAVE_TIMECOUNTER |
|
|
/*- |
/*- |
*********************************************************************** |
*********************************************************************** |
Line 844 hardpps(struct timespec *tsp, /* time a |
|
Line 847 hardpps(struct timespec *tsp, /* time a |
|
} |
} |
#endif /* PPS_SYNC */ |
#endif /* PPS_SYNC */ |
#endif /* NTP */ |
#endif /* NTP */ |
|
#else /* !__HAVE_TIMECOUNTER */ |
|
/****************************************************************************** |
|
* * |
|
* Copyright (c) David L. Mills 1993, 1994 * |
|
* * |
|
* Permission to use, copy, modify, and distribute this software and its * |
|
* documentation for any purpose and without fee is hereby granted, provided * |
|
* that the above copyright notice appears in all copies and that both the * |
|
* copyright notice and this permission notice appear in supporting * |
|
* documentation, and that the name University of Delaware not be used in * |
|
* advertising or publicity pertaining to distribution of the software * |
|
* without specific, written prior permission. The University of Delaware * |
|
* makes no representations about the suitability this software for any * |
|
* purpose. It is provided "as is" without express or implied warranty. * |
|
* * |
|
******************************************************************************/ |
|
|
|
/* |
|
* Modification history kern_ntptime.c |
|
* |
|
* 24 Sep 94 David L. Mills |
|
* Tightened code at exits. |
|
* |
|
* 24 Mar 94 David L. Mills |
|
* Revised syscall interface to include new variables for PPS |
|
* time discipline. |
|
* |
|
* 14 Feb 94 David L. Mills |
|
* Added code for external clock |
|
* |
|
* 28 Nov 93 David L. Mills |
|
* Revised frequency scaling to conform with adjusted parameters |
|
* |
|
* 17 Sep 93 David L. Mills |
|
* Created file |
|
*/ |
|
/* |
|
* ntp_gettime(), ntp_adjtime() - precision time interface for SunOS |
|
* V4.1.1 and V4.1.3 |
|
* |
|
* These routines consitute the Network Time Protocol (NTP) interfaces |
|
* for user and daemon application programs. The ntp_gettime() routine |
|
* provides the time, maximum error (synch distance) and estimated error |
|
* (dispersion) to client user application programs. The ntp_adjtime() |
|
* routine is used by the NTP daemon to adjust the system clock to an |
|
* externally derived time. The time offset and related variables set by |
|
* this routine are used by hardclock() to adjust the phase and |
|
* frequency of the phase-lock loop which controls the system clock. |
|
*/ |
|
|
|
#include <sys/cdefs.h> |
|
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
|
#include "opt_ntp.h" |
|
#include "opt_compat_netbsd.h" |
|
|
|
#include <sys/param.h> |
|
#include <sys/resourcevar.h> |
|
#include <sys/systm.h> |
|
#include <sys/kernel.h> |
|
#include <sys/proc.h> |
|
#include <sys/sysctl.h> |
|
#include <sys/timex.h> |
|
#ifdef COMPAT_30 |
|
#include <compat/sys/timex.h> |
|
#endif |
|
#include <sys/vnode.h> |
|
#include <sys/kauth.h> |
|
|
|
#include <sys/mount.h> |
|
#include <sys/syscallargs.h> |
|
|
|
#include <sys/cpu.h> |
|
|
|
#ifdef NTP |
|
/* |
|
* The following variables are used by the hardclock() routine in the |
|
* kern_clock.c module and are described in that module. |
|
*/ |
|
extern int time_state; /* clock state */ |
|
extern int time_status; /* clock status bits */ |
|
extern long time_offset; /* time adjustment (us) */ |
|
extern long time_freq; /* frequency offset (scaled ppm) */ |
|
extern long time_maxerror; /* maximum error (us) */ |
|
extern long time_esterror; /* estimated error (us) */ |
|
extern long time_constant; /* pll time constant */ |
|
extern long time_precision; /* clock precision (us) */ |
|
extern long time_tolerance; /* frequency tolerance (scaled ppm) */ |
|
extern int time_adjusted; /* ntp might have changed the system time */ |
|
|
|
#ifdef PPS_SYNC |
|
/* |
|
* The following variables are used only if the PPS signal discipline |
|
* is configured in the kernel. |
|
*/ |
|
extern int pps_shift; /* interval duration (s) (shift) */ |
|
extern long pps_freq; /* pps frequency offset (scaled ppm) */ |
|
extern long pps_jitter; /* pps jitter (us) */ |
|
extern long pps_stabil; /* pps stability (scaled ppm) */ |
|
extern long pps_jitcnt; /* jitter limit exceeded */ |
|
extern long pps_calcnt; /* calibration intervals */ |
|
extern long pps_errcnt; /* calibration errors */ |
|
extern long pps_stbcnt; /* stability limit exceeded */ |
|
#endif /* PPS_SYNC */ |
|
|
|
/*ARGSUSED*/ |
|
/* |
|
* ntp_gettime() - NTP user application interface |
|
*/ |
|
void |
|
ntp_gettime(struct ntptimeval *ntvp) |
|
{ |
|
struct timeval atv; |
|
int s; |
|
|
|
memset(ntvp, 0, sizeof(struct ntptimeval)); |
|
|
|
s = splclock(); |
|
#ifdef EXT_CLOCK |
|
/* |
|
* The microtime() external clock routine returns a |
|
* status code. If less than zero, we declare an error |
|
* in the clock status word and return the kernel |
|
* (software) time variable. While there are other |
|
* places that call microtime(), this is the only place |
|
* that matters from an application point of view. |
|
*/ |
|
if (microtime(&atv) < 0) { |
|
time_status |= STA_CLOCKERR; |
|
ntvp->time = time; |
|
} else |
|
time_status &= ~STA_CLOCKERR; |
|
#else /* EXT_CLOCK */ |
|
microtime(&atv); |
|
#endif /* EXT_CLOCK */ |
|
ntvp->maxerror = time_maxerror; |
|
ntvp->esterror = time_esterror; |
|
(void) splx(s); |
|
TIMEVAL_TO_TIMESPEC(&atv, &ntvp->time); |
|
} |
|
|
|
|
|
/* ARGSUSED */ |
|
/* |
|
* ntp_adjtime() - NTP daemon application interface |
|
*/ |
|
int |
|
sys_ntp_adjtime(struct lwp *l, const struct sys_ntp_adjtime_args *uap, register_t *retval) |
|
{ |
|
/* { |
|
syscallarg(struct timex *) tp; |
|
} */ |
|
struct timex ntv; |
|
int error = 0; |
|
|
|
error = copyin((void *)SCARG(uap, tp), (void *)&ntv, sizeof(ntv)); |
|
if (error != 0) |
|
return (error); |
|
|
|
if (ntv.modes != 0 && (error = kauth_authorize_system(l->l_cred, |
|
KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_NTPADJTIME, NULL, |
|
NULL, NULL)) != 0) |
|
return (error); |
|
|
|
ntp_adjtime1(&ntv); |
|
|
|
error = copyout((void *)&ntv, (void *)SCARG(uap, tp), sizeof(ntv)); |
|
if (error == 0) |
|
*retval = ntp_timestatus(); |
|
|
|
return error; |
|
} |
|
|
|
void |
|
ntp_adjtime1(struct timex *ntv) |
|
{ |
|
int modes; |
|
int s; |
|
|
|
/* |
|
* Update selected clock variables. Note that there is no error |
|
* checking here on the assumption the superuser should know |
|
* what it is doing. |
|
*/ |
|
modes = ntv->modes; |
|
if (modes != 0) |
|
/* We need to save the system time during shutdown */ |
|
time_adjusted |= 2; |
|
s = splclock(); |
|
if (modes & MOD_FREQUENCY) |
|
#ifdef PPS_SYNC |
|
time_freq = ntv->freq - pps_freq; |
|
#else /* PPS_SYNC */ |
|
time_freq = ntv->freq; |
|
#endif /* PPS_SYNC */ |
|
if (modes & MOD_MAXERROR) |
|
time_maxerror = ntv->maxerror; |
|
if (modes & MOD_ESTERROR) |
|
time_esterror = ntv->esterror; |
|
if (modes & MOD_STATUS) { |
|
time_status &= STA_RONLY; |
|
time_status |= ntv->status & ~STA_RONLY; |
|
} |
|
if (modes & MOD_TIMECONST) |
|
time_constant = ntv->constant; |
|
if (modes & MOD_OFFSET) |
|
hardupdate(ntv->offset); |
|
|
|
/* |
|
* Retrieve all clock variables |
|
*/ |
|
if (time_offset < 0) |
|
ntv->offset = -(-time_offset >> SHIFT_UPDATE); |
|
else |
|
ntv->offset = time_offset >> SHIFT_UPDATE; |
|
#ifdef PPS_SYNC |
|
ntv->freq = time_freq + pps_freq; |
|
#else /* PPS_SYNC */ |
|
ntv->freq = time_freq; |
|
#endif /* PPS_SYNC */ |
|
ntv->maxerror = time_maxerror; |
|
ntv->esterror = time_esterror; |
|
ntv->status = time_status; |
|
ntv->constant = time_constant; |
|
ntv->precision = time_precision; |
|
ntv->tolerance = time_tolerance; |
|
#ifdef PPS_SYNC |
|
ntv->shift = pps_shift; |
|
ntv->ppsfreq = pps_freq; |
|
ntv->jitter = pps_jitter >> PPS_AVG; |
|
ntv->stabil = pps_stabil; |
|
ntv->calcnt = pps_calcnt; |
|
ntv->errcnt = pps_errcnt; |
|
ntv->jitcnt = pps_jitcnt; |
|
ntv->stbcnt = pps_stbcnt; |
|
#endif /* PPS_SYNC */ |
|
(void)splx(s); |
|
} |
|
#endif /* NTP */ |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
|
#ifdef NTP |
#ifdef NTP |
int |
int |