aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time.c')
-rw-r--r--kernel/time.c173
1 files changed, 0 insertions, 173 deletions
diff --git a/kernel/time.c b/kernel/time.c
index 5bd489747643..0e017bff4c19 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -202,179 +202,6 @@ asmlinkage long sys_settimeofday(struct timeval __user *tv,
202 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL); 202 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
203} 203}
204 204
205/* we call this to notify the arch when the clock is being
206 * controlled. If no such arch routine, do nothing.
207 */
208void __attribute__ ((weak)) notify_arch_cmos_timer(void)
209{
210 return;
211}
212
213/* adjtimex mainly allows reading (and writing, if superuser) of
214 * kernel time-keeping variables. used by xntpd.
215 */
216int do_adjtimex(struct timex *txc)
217{
218 long ltemp, mtemp, save_adjust;
219 int result;
220
221 /* In order to modify anything, you gotta be super-user! */
222 if (txc->modes && !capable(CAP_SYS_TIME))
223 return -EPERM;
224
225 /* Now we validate the data before disabling interrupts */
226
227 if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
228 /* singleshot must not be used with any other mode bits */
229 if (txc->modes != ADJ_OFFSET_SINGLESHOT)
230 return -EINVAL;
231
232 if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
233 /* adjustment Offset limited to +- .512 seconds */
234 if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
235 return -EINVAL;
236
237 /* if the quartz is off by more than 10% something is VERY wrong ! */
238 if (txc->modes & ADJ_TICK)
239 if (txc->tick < 900000/USER_HZ ||
240 txc->tick > 1100000/USER_HZ)
241 return -EINVAL;
242
243 write_seqlock_irq(&xtime_lock);
244 result = time_state; /* mostly `TIME_OK' */
245
246 /* Save for later - semantics of adjtime is to return old value */
247 save_adjust = time_next_adjust ? time_next_adjust : time_adjust;
248
249#if 0 /* STA_CLOCKERR is never set yet */
250 time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
251#endif
252 /* If there are input parameters, then process them */
253 if (txc->modes)
254 {
255 if (txc->modes & ADJ_STATUS) /* only set allowed bits */
256 time_status = (txc->status & ~STA_RONLY) |
257 (time_status & STA_RONLY);
258
259 if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */
260 if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
261 result = -EINVAL;
262 goto leave;
263 }
264 time_freq = txc->freq;
265 }
266
267 if (txc->modes & ADJ_MAXERROR) {
268 if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
269 result = -EINVAL;
270 goto leave;
271 }
272 time_maxerror = txc->maxerror;
273 }
274
275 if (txc->modes & ADJ_ESTERROR) {
276 if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
277 result = -EINVAL;
278 goto leave;
279 }
280 time_esterror = txc->esterror;
281 }
282
283 if (txc->modes & ADJ_TIMECONST) { /* p. 24 */
284 if (txc->constant < 0) { /* NTP v4 uses values > 6 */
285 result = -EINVAL;
286 goto leave;
287 }
288 time_constant = txc->constant;
289 }
290
291 if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
292 if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
293 /* adjtime() is independent from ntp_adjtime() */
294 if ((time_next_adjust = txc->offset) == 0)
295 time_adjust = 0;
296 }
297 else if (time_status & STA_PLL) {
298 ltemp = txc->offset;
299
300 /*
301 * Scale the phase adjustment and
302 * clamp to the operating range.
303 */
304 if (ltemp > MAXPHASE)
305 time_offset = MAXPHASE << SHIFT_UPDATE;
306 else if (ltemp < -MAXPHASE)
307 time_offset = -(MAXPHASE << SHIFT_UPDATE);
308 else
309 time_offset = ltemp << SHIFT_UPDATE;
310
311 /*
312 * Select whether the frequency is to be controlled
313 * and in which mode (PLL or FLL). Clamp to the operating
314 * range. Ugly multiply/divide should be replaced someday.
315 */
316
317 if (time_status & STA_FREQHOLD || time_reftime == 0)
318 time_reftime = xtime.tv_sec;
319 mtemp = xtime.tv_sec - time_reftime;
320 time_reftime = xtime.tv_sec;
321 if (time_status & STA_FLL) {
322 if (mtemp >= MINSEC) {
323 ltemp = (time_offset / mtemp) << (SHIFT_USEC -
324 SHIFT_UPDATE);
325 time_freq += shift_right(ltemp, SHIFT_KH);
326 } else /* calibration interval too short (p. 12) */
327 result = TIME_ERROR;
328 } else { /* PLL mode */
329 if (mtemp < MAXSEC) {
330 ltemp *= mtemp;
331 time_freq += shift_right(ltemp,(time_constant +
332 time_constant +
333 SHIFT_KF - SHIFT_USEC));
334 } else /* calibration interval too long (p. 12) */
335 result = TIME_ERROR;
336 }
337 time_freq = min(time_freq, time_tolerance);
338 time_freq = max(time_freq, -time_tolerance);
339 } /* STA_PLL */
340 } /* txc->modes & ADJ_OFFSET */
341 if (txc->modes & ADJ_TICK) {
342 tick_usec = txc->tick;
343 tick_nsec = TICK_USEC_TO_NSEC(tick_usec);
344 }
345 } /* txc->modes */
346leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
347 result = TIME_ERROR;
348
349 if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
350 txc->offset = save_adjust;
351 else {
352 txc->offset = shift_right(time_offset, SHIFT_UPDATE);
353 }
354 txc->freq = time_freq;
355 txc->maxerror = time_maxerror;
356 txc->esterror = time_esterror;
357 txc->status = time_status;
358 txc->constant = time_constant;
359 txc->precision = time_precision;
360 txc->tolerance = time_tolerance;
361 txc->tick = tick_usec;
362
363 /* PPS is not implemented, so these are zero */
364 txc->ppsfreq = 0;
365 txc->jitter = 0;
366 txc->shift = 0;
367 txc->stabil = 0;
368 txc->jitcnt = 0;
369 txc->calcnt = 0;
370 txc->errcnt = 0;
371 txc->stbcnt = 0;
372 write_sequnlock_irq(&xtime_lock);
373 do_gettimeofday(&txc->time);
374 notify_arch_cmos_timer();
375 return(result);
376}
377
378asmlinkage long sys_adjtimex(struct timex __user *txc_p) 205asmlinkage long sys_adjtimex(struct timex __user *txc_p)
379{ 206{
380 struct timex txc; /* Local copy of parameter */ 207 struct timex txc; /* Local copy of parameter */