/******************************************************************************
* 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
* 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
* ntp_gettime(), ntp_adjtime() - precision time interface
* 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.
struct timex ntp_pll
; /* has to be declared somewhere... */
* ntp_gettime() - NTP user application interface
struct ntp_gettime_args
{
ntp_gettime(struct proc
*p
, struct ntp_gettime_args
*uap
, int *retval
)
ntv
.maxerror
= ntp_pll
.maxerror
;
ntv
.esterror
= ntp_pll
.esterror
;
error
= copyout((caddr_t
)&ntv
, (caddr_t
)uap
->tp
, sizeof (ntv
));
retval
[0] = ntp_pll
.status
;
struct ntp_adjtime_args
{
extern void hardupdate(long);
* ntp_adjtime() - NTP daemon application interface
ntp_adjtime(struct proc
*p
, struct ntp_adjtime_args
*uap
, int *retval
) {
error
= copyin((caddr_t
)uap
->tp
, (caddr_t
)&ntv
, sizeof(ntv
));
* Update selected clock variables - only the superuser can
* change anything. Note that there is no error checking here on
* the assumption the superuser should know what it is doing.
if(ntv
.mode
!= 0 && !(error
= suser(p
->p_ucred
, &p
->p_acflag
)))
return error
? error
: EPERM
;
if (ntv
.mode
& ADJ_OFFSET
)
if (ntv
.mode
& ADJ_FREQUENCY
)
ntp_pll
.frequency
= ntv
.frequency
- ntp_pll
.ybar
;
ntp_pll
.frequency
= ntv
.frequency
;
if (ntv
.mode
& ADJ_MAXERROR
)
ntp_pll
.maxerror
= ntv
.maxerror
;
if (ntv
.mode
& ADJ_ESTERROR
)
ntp_pll
.esterror
= ntv
.esterror
;
if (ntv
.mode
& ADJ_STATUS
)
if (ntp_pll
.status
== TIME_OK
|| ntv
.status
== TIME_BAD
)
ntp_pll
.status
= ntv
.status
;
if (ntv
.mode
& ADJ_TIMECONST
)
ntp_pll
.time_constant
= ntv
.time_constant
;
* Retrieve all clock variables
ntv
.offset
= -(-ntp_pll
.offset
>> SHIFT_UPDATE
);
ntv
.offset
= ntp_pll
.offset
>> SHIFT_UPDATE
;
ntv
.frequency
= ntp_pll
.frequency
+ ntp_pll
.ybar
;
ntv
.frequency
= ntp_pll
.frequency
;
ntv
.maxerror
= ntp_pll
.maxerror
;
ntv
.esterror
= ntp_pll
.esterror
;
ntv
.status
= ntp_pll
.status
;
ntv
.time_constant
= ntp_pll
.time_constant
;
ntv
.precision
= ntp_pll
.precision
;
ntv
.tolerance
= ntp_pll
.tolerance
;
ntv
.shift
= ntp_pll
.shift
;
ntv
.calcnt
= ntp_pll
.calcnt
;
ntv
.jitcnt
= ntp_pll
.jitcnt
;
ntv
.discnt
= ntp_pll
.discnt
;
error
= copyout((caddr_t
)&ntv
, (caddr_t
)uap
->tp
, sizeof(ntv
));
retval
[0] = ntp_pll
.status
;