diff options
Diffstat (limited to 'kernel/time.c')
-rw-r--r-- | kernel/time.c | 173 |
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 | */ | ||
208 | void __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 | */ | ||
216 | int 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 */ | ||
346 | leave: 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 | |||
378 | asmlinkage long sys_adjtimex(struct timex __user *txc_p) | 205 | asmlinkage 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 */ |