From John Dyson - fix for bug in kern_physio where buffers would be
[unix-history] / sys / kern / kern_ntptime.c
CommitLineData
486e5ce2
GW
1/******************************************************************************
2 * *
3 * Copyright (c) David L. Mills 1993, 1994 *
4 * *
5 * Permission to use, copy, modify, and distribute this software and its *
6 * documentation for any purpose and without fee is hereby granted, provided *
7 * that the above copyright notice appears in all copies and that both the *
8 * copyright notice and this permission notice appear in supporting *
9 * documentation, and that the name University of Delaware not be used in *
10 * advertising or publicity pertaining to distribution of the software *
11 * without specific, written prior permission. The University of Delaware *
12 * makes no representations about the suitability this software for any *
13 * purpose. It is provided "as is" without express or implied warranty. *
14 * *
15 ******************************************************************************/
16
9e85cc83
GW
17/*
18 * $Id$
19 */
20
486e5ce2
GW
21/*
22 * Modification history kern_ntptime.c
23 *
24 * 14 Feb 94 David L. Mills
25 * Added code for external clock
26 *
27 * 28 Nov 93 David L. Mills
28 * Revised frequency scaling to conform with adjusted parameters
29 *
30 * 17 Sep 93 David L. Mills
31 * Created file
32 */
33/*
34 * ntp_gettime(), ntp_adjtime() - precision time interface
35 *
36 * These routines consitute the Network Time Protocol (NTP) interfaces
37 * for user and daemon application programs. The ntp_gettime() routine
38 * provides the time, maximum error (synch distance) and estimated error
39 * (dispersion) to client user application programs. The ntp_adjtime()
40 * routine is used by the NTP daemon to adjust the system clock to an
41 * externally derived time. The time offset and related variables set by
42 * this routine are used by hardclock() to adjust the phase and
43 * frequency of the phase-lock loop which controls the system clock.
44 */
9e85cc83
GW
45#include "param.h"
46#include "systm.h"
47#include "kernel.h"
48#include "timex.h"
49#include "proc.h"
486e5ce2 50
9e85cc83 51struct timex ntp_pll; /* has to be declared somewhere... */
486e5ce2 52
486e5ce2
GW
53
54/*
55 * ntp_gettime() - NTP user application interface
56 */
9e85cc83
GW
57
58struct ntp_gettime_args {
59 struct ntptimeval *tp;
60};
61
62int
63ntp_gettime(struct proc *p, struct ntp_gettime_args *uap, int *retval)
486e5ce2 64{
486e5ce2
GW
65 struct timeval atv;
66 struct ntptimeval ntv;
9e85cc83 67 int error = 0;
486e5ce2
GW
68 int s;
69
70 if (uap->tp) {
486e5ce2 71 s = splclock();
9e85cc83
GW
72 microtime(&ntv.time);
73 ntv.maxerror = ntp_pll.maxerror;
74 ntv.esterror = ntp_pll.esterror;
486e5ce2
GW
75 (void) splx(s);
76
9e85cc83 77 error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof (ntv));
486e5ce2 78 }
9e85cc83
GW
79 if (!error)
80 retval[0] = ntp_pll.status;
81 return error;
486e5ce2
GW
82}
83
9e85cc83
GW
84struct ntp_adjtime_args {
85 struct timex *tp;
86};
87
88extern void hardupdate(long);
89
486e5ce2
GW
90/*
91 * ntp_adjtime() - NTP daemon application interface
92 */
9e85cc83
GW
93int
94ntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap, int *retval) {
486e5ce2 95 struct timex ntv;
9e85cc83 96 int s, error;
486e5ce2 97
9e85cc83
GW
98 error = copyin((caddr_t)uap->tp, (caddr_t)&ntv, sizeof(ntv));
99 if (error)
100 return error;
486e5ce2
GW
101
102 /*
103 * Update selected clock variables - only the superuser can
104 * change anything. Note that there is no error checking here on
105 * the assumption the superuser should know what it is doing.
106 */
9e85cc83
GW
107 if(ntv.mode != 0 && !(error = suser(p->p_ucred, &p->p_acflag)))
108 return error ? error : EPERM;
486e5ce2
GW
109
110 s = splclock();
111 if (ntv.mode & ADJ_OFFSET)
112 hardupdate(ntv.offset);
113 if (ntv.mode & ADJ_FREQUENCY)
114#ifdef PPS_SYNC
9e85cc83 115 ntp_pll.frequency = ntv.frequency - ntp_pll.ybar;
486e5ce2 116#else /* PPS_SYNC */
9e85cc83 117 ntp_pll.frequency = ntv.frequency;
486e5ce2
GW
118#endif /* PPS_SYNC */
119 if (ntv.mode & ADJ_MAXERROR)
9e85cc83 120 ntp_pll.maxerror = ntv.maxerror;
486e5ce2 121 if (ntv.mode & ADJ_ESTERROR)
9e85cc83 122 ntp_pll.esterror = ntv.esterror;
486e5ce2 123 if (ntv.mode & ADJ_STATUS)
9e85cc83
GW
124 if (ntp_pll.status == TIME_OK || ntv.status == TIME_BAD)
125 ntp_pll.status = ntv.status;
486e5ce2 126 if (ntv.mode & ADJ_TIMECONST)
9e85cc83 127 ntp_pll.time_constant = ntv.time_constant;
486e5ce2
GW
128
129 /*
130 * Retrieve all clock variables
131 */
9e85cc83
GW
132 if (ntp_pll.offset < 0)
133 ntv.offset = -(-ntp_pll.offset >> SHIFT_UPDATE);
486e5ce2 134 else
9e85cc83 135 ntv.offset = ntp_pll.offset >> SHIFT_UPDATE;
486e5ce2 136#ifdef PPS_SYNC
9e85cc83 137 ntv.frequency = ntp_pll.frequency + ntp_pll.ybar;
486e5ce2 138#else /* PPS_SYNC */
9e85cc83 139 ntv.frequency = ntp_pll.frequency;
486e5ce2 140#endif /* PPS_SYNC */
9e85cc83
GW
141 ntv.maxerror = ntp_pll.maxerror;
142 ntv.esterror = ntp_pll.esterror;
143 ntv.status = ntp_pll.status;
144 ntv.time_constant = ntp_pll.time_constant;
145 ntv.precision = ntp_pll.precision;
146 ntv.tolerance = ntp_pll.tolerance;
486e5ce2 147#ifdef PPS_SYNC
9e85cc83
GW
148 ntv.ybar = ntp_pll.ybar;
149 ntv.disp = ntp_pll.disp;
150 ntv.shift = ntp_pll.shift;
151 ntv.calcnt = ntp_pll.calcnt;
152 ntv.jitcnt = ntp_pll.jitcnt;
153 ntv.discnt = ntp_pll.discnt;
486e5ce2
GW
154#endif /* PPS_SYNC */
155 (void)splx(s);
156
9e85cc83
GW
157 error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv));
158 retval[0] = ntp_pll.status;
159 return error;
486e5ce2 160}
9e85cc83 161