1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/mm.h>
28#include <linux/timex.h>
29#include <linux/smp_lock.h>
30
31#include <asm/uaccess.h>
32
33
34
35
36
37struct timezone sys_tz;
38
39
40
41extern rwlock_t xtime_lock;
42
43#if !defined(__alpha__) && !defined(__ia64__)
44
45
46
47
48
49
50
51
52
53asmlinkage long sys_time(int * tloc)
54{
55 struct timeval now;
56 int i;
57
58 do_gettimeofday(&now);
59 i = now.tv_sec;
60 if (tloc) {
61 if (put_user(i,tloc))
62 i = -EFAULT;
63 }
64 return i;
65}
66
67
68
69
70
71
72
73
74asmlinkage long sys_stime(int * tptr)
75{
76 int value;
77
78 if (!capable(CAP_SYS_TIME))
79 return -EPERM;
80 if (get_user(value, tptr))
81 return -EFAULT;
82 write_lock_irq(&xtime_lock);
83 vxtime_lock();
84 xtime.tv_sec = value;
85 xtime.tv_usec = 0;
86 vxtime_unlock();
87 time_adjust = 0;
88 time_status |= STA_UNSYNC;
89 time_maxerror = NTP_PHASE_LIMIT;
90 time_esterror = NTP_PHASE_LIMIT;
91 write_unlock_irq(&xtime_lock);
92 return 0;
93}
94
95#endif
96
97asmlinkage long sys_gettimeofday(struct timeval *tv, struct timezone *tz)
98{
99 if (tv) {
100 struct timeval ktv;
101 do_gettimeofday(&ktv);
102 if (copy_to_user(tv, &ktv, sizeof(ktv)))
103 return -EFAULT;
104 }
105 if (tz) {
106 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
107 return -EFAULT;
108 }
109 return 0;
110}
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128inline static void warp_clock(void)
129{
130 write_lock_irq(&xtime_lock);
131 vxtime_lock();
132 xtime.tv_sec += sys_tz.tz_minuteswest * 60;
133 vxtime_unlock();
134 write_unlock_irq(&xtime_lock);
135}
136
137
138
139
140
141
142
143
144
145
146
147
148int do_sys_settimeofday(struct timeval *tv, struct timezone *tz)
149{
150 static int firsttime = 1;
151
152 if (!capable(CAP_SYS_TIME))
153 return -EPERM;
154
155 if (tz) {
156
157 sys_tz = *tz;
158 if (firsttime) {
159 firsttime = 0;
160 if (!tv)
161 warp_clock();
162 }
163 }
164 if (tv)
165 {
166
167
168
169 do_settimeofday(tv);
170 }
171 return 0;
172}
173
174asmlinkage long sys_settimeofday(struct timeval *tv, struct timezone *tz)
175{
176 struct timeval new_tv;
177 struct timezone new_tz;
178
179 if (tv) {
180 if (copy_from_user(&new_tv, tv, sizeof(*tv)))
181 return -EFAULT;
182 }
183 if (tz) {
184 if (copy_from_user(&new_tz, tz, sizeof(*tz)))
185 return -EFAULT;
186 }
187
188 return do_sys_settimeofday(tv ? &new_tv : NULL, tz ? &new_tz : NULL);
189}
190
191long pps_offset;
192long pps_jitter = MAXTIME;
193
194long pps_freq;
195long pps_stabil = MAXFREQ;
196
197long pps_valid = PPS_VALID;
198
199int pps_shift = PPS_SHIFT;
200
201long pps_jitcnt;
202long pps_calcnt;
203long pps_errcnt;
204long pps_stbcnt;
205
206
207void (*hardpps_ptr)(struct timeval *);
208
209
210
211
212int do_adjtimex(struct timex *txc)
213{
214 long ltemp, mtemp, save_adjust;
215 int result;
216
217
218 if (txc->modes && !capable(CAP_SYS_TIME))
219 return -EPERM;
220
221
222
223 if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
224
225 if (txc->modes != ADJ_OFFSET_SINGLESHOT)
226 return -EINVAL;
227
228 if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
229
230 if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
231 return -EINVAL;
232
233
234 if (txc->modes & ADJ_TICK)
235 if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ)
236 return -EINVAL;
237
238 write_lock_irq(&xtime_lock);
239 result = time_state;
240
241
242 save_adjust = time_adjust;
243
244#if 0
245 time_status &= ~STA_CLOCKERR;
246#endif
247
248 if (txc->modes)
249 {
250 if (txc->modes & ADJ_STATUS)
251 time_status = (txc->status & ~STA_RONLY) |
252 (time_status & STA_RONLY);
253
254 if (txc->modes & ADJ_FREQUENCY) {
255 if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
256 result = -EINVAL;
257 goto leave;
258 }
259 time_freq = txc->freq - pps_freq;
260 }
261
262 if (txc->modes & ADJ_MAXERROR) {
263 if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
264 result = -EINVAL;
265 goto leave;
266 }
267 time_maxerror = txc->maxerror;
268 }
269
270 if (txc->modes & ADJ_ESTERROR) {
271 if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
272 result = -EINVAL;
273 goto leave;
274 }
275 time_esterror = txc->esterror;
276 }
277
278 if (txc->modes & ADJ_TIMECONST) {
279 if (txc->constant < 0) {
280 result = -EINVAL;
281 goto leave;
282 }
283 time_constant = txc->constant;
284 }
285
286 if (txc->modes & ADJ_OFFSET) {
287 if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
288
289 time_adjust = txc->offset;
290 }
291 else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
292 ltemp = (time_status & (STA_PPSTIME | STA_PPSSIGNAL)) ==
293 (STA_PPSTIME | STA_PPSSIGNAL) ?
294 pps_offset : txc->offset;
295
296
297
298
299
300 if (ltemp > MAXPHASE)
301 time_offset = MAXPHASE << SHIFT_UPDATE;
302 else if (ltemp < -MAXPHASE)
303 time_offset = -(MAXPHASE << SHIFT_UPDATE);
304 else
305 time_offset = ltemp << SHIFT_UPDATE;
306
307
308
309
310
311
312
313 if (time_status & STA_FREQHOLD || time_reftime == 0)
314 time_reftime = xtime.tv_sec;
315 mtemp = xtime.tv_sec - time_reftime;
316 time_reftime = xtime.tv_sec;
317 if (time_status & STA_FLL) {
318 if (mtemp >= MINSEC) {
319 ltemp = (time_offset / mtemp) << (SHIFT_USEC -
320 SHIFT_UPDATE);
321 if (ltemp < 0)
322 time_freq -= -ltemp >> SHIFT_KH;
323 else
324 time_freq += ltemp >> SHIFT_KH;
325 } else
326 result = TIME_ERROR;
327 } else {
328 if (mtemp < MAXSEC) {
329 ltemp *= mtemp;
330 if (ltemp < 0)
331 time_freq -= -ltemp >> (time_constant +
332 time_constant +
333 SHIFT_KF - SHIFT_USEC);
334 else
335 time_freq += ltemp >> (time_constant +
336 time_constant +
337 SHIFT_KF - SHIFT_USEC);
338 } else
339 result = TIME_ERROR;
340 }
341 if (time_freq > time_tolerance)
342 time_freq = time_tolerance;
343 else if (time_freq < -time_tolerance)
344 time_freq = -time_tolerance;
345 }
346 }
347 if (txc->modes & ADJ_TICK) {
348
349
350 if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ) {
351 result = -EINVAL;
352 goto leave;
353 }
354 tick = txc->tick;
355 }
356 }
357leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
358 || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0
359 && (time_status & STA_PPSSIGNAL) == 0)
360
361 || ((time_status & (STA_PPSTIME|STA_PPSJITTER))
362 == (STA_PPSTIME|STA_PPSJITTER))
363
364 || ((time_status & STA_PPSFREQ) != 0
365 && (time_status & (STA_PPSWANDER|STA_PPSERROR)) != 0))
366
367 result = TIME_ERROR;
368
369 if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
370 txc->offset = save_adjust;
371 else {
372 if (time_offset < 0)
373 txc->offset = -(-time_offset >> SHIFT_UPDATE);
374 else
375 txc->offset = time_offset >> SHIFT_UPDATE;
376 }
377 txc->freq = time_freq + pps_freq;
378 txc->maxerror = time_maxerror;
379 txc->esterror = time_esterror;
380 txc->status = time_status;
381 txc->constant = time_constant;
382 txc->precision = time_precision;
383 txc->tolerance = time_tolerance;
384 txc->tick = tick;
385 txc->ppsfreq = pps_freq;
386 txc->jitter = pps_jitter >> PPS_AVG;
387 txc->shift = pps_shift;
388 txc->stabil = pps_stabil;
389 txc->jitcnt = pps_jitcnt;
390 txc->calcnt = pps_calcnt;
391 txc->errcnt = pps_errcnt;
392 txc->stbcnt = pps_stbcnt;
393 write_unlock_irq(&xtime_lock);
394 do_gettimeofday(&txc->time);
395 return(result);
396}
397
398asmlinkage long sys_adjtimex(struct timex *txc_p)
399{
400 struct timex txc;
401 int ret;
402
403
404
405
406
407 if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
408 return -EFAULT;
409 ret = do_adjtimex(&txc);
410 return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
411}
412