Commit | Line | Data |
---|---|---|
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 | 51 | struct 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 | |
58 | struct ntp_gettime_args { | |
59 | struct ntptimeval *tp; | |
60 | }; | |
61 | ||
62 | int | |
63 | ntp_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 |
84 | struct ntp_adjtime_args { |
85 | struct timex *tp; | |
86 | }; | |
87 | ||
88 | extern void hardupdate(long); | |
89 | ||
486e5ce2 GW |
90 | /* |
91 | * ntp_adjtime() - NTP daemon application interface | |
92 | */ | |
9e85cc83 GW |
93 | int |
94 | ntp_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 |