Magellan Linux

Annotation of /alx-src/tags/kernel26-2.6.12-alx-r9/kernel/time.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 628 - (hide annotations) (download)
Wed Mar 4 10:48:58 2009 UTC (15 years, 3 months ago) by niro
Original Path: alx-src/trunk/kernel26-alx/linux/kernel/time.c
File MIME type: text/plain
File size: 16015 byte(s)
import linux sources based on 2.6.12-alx-r9:
 -using linux-2.6.12.6
 -using 2.6.12-ck6 patch set
 -using fbsplash-0.9.2-r3
 -using vesafb-tng-0.9-rc7
 -using squashfs-2.2
 -added cddvd-cmdfilter-drop.patch as ck dropped it
 -added via-epia-dri (cle266) patch
 -added zd1211-svn-32 wlan driver (http://zd1211.ath.cx/download/)
 -added debian patches to zd1211 for wep256 etc

1 niro 628 /*
2     * linux/kernel/time.c
3     *
4     * Copyright (C) 1991, 1992 Linus Torvalds
5     *
6     * This file contains the interface functions for the various
7     * time related system calls: time, stime, gettimeofday, settimeofday,
8     * adjtime
9     */
10     /*
11     * Modification history kernel/time.c
12     *
13     * 1993-09-02 Philip Gladstone
14     * Created file with time related functions from sched.c and adjtimex()
15     * 1993-10-08 Torsten Duwe
16     * adjtime interface update and CMOS clock write code
17     * 1995-08-13 Torsten Duwe
18     * kernel PLL updated to 1994-12-13 specs (rfc-1589)
19     * 1999-01-16 Ulrich Windl
20     * Introduced error checking for many cases in adjtimex().
21     * Updated NTP code according to technical memorandum Jan '96
22     * "A Kernel Model for Precision Timekeeping" by Dave Mills
23     * Allow time_constant larger than MAXTC(6) for NTP v4 (MAXTC == 10)
24     * (Even though the technical memorandum forbids it)
25     * 2004-07-14 Christoph Lameter
26     * Added getnstimeofday to allow the posix timer functions to return
27     * with nanosecond accuracy
28     */
29    
30     #include <linux/module.h>
31     #include <linux/timex.h>
32     #include <linux/errno.h>
33     #include <linux/smp_lock.h>
34     #include <linux/syscalls.h>
35     #include <linux/security.h>
36     #include <linux/fs.h>
37     #include <linux/module.h>
38    
39     #include <asm/uaccess.h>
40     #include <asm/unistd.h>
41    
42     /*
43     * The timezone where the local system is located. Used as a default by some
44     * programs who obtain this value by using gettimeofday.
45     */
46     struct timezone sys_tz;
47    
48     EXPORT_SYMBOL(sys_tz);
49    
50     #ifdef __ARCH_WANT_SYS_TIME
51    
52     /*
53     * sys_time() can be implemented in user-level using
54     * sys_gettimeofday(). Is this for backwards compatibility? If so,
55     * why not move it into the appropriate arch directory (for those
56     * architectures that need it).
57     */
58     asmlinkage long sys_time(time_t __user * tloc)
59     {
60     time_t i;
61     struct timeval tv;
62    
63     do_gettimeofday(&tv);
64     i = tv.tv_sec;
65    
66     if (tloc) {
67     if (put_user(i,tloc))
68     i = -EFAULT;
69     }
70     return i;
71     }
72    
73     /*
74     * sys_stime() can be implemented in user-level using
75     * sys_settimeofday(). Is this for backwards compatibility? If so,
76     * why not move it into the appropriate arch directory (for those
77     * architectures that need it).
78     */
79    
80     asmlinkage long sys_stime(time_t __user *tptr)
81     {
82     struct timespec tv;
83     int err;
84    
85     if (get_user(tv.tv_sec, tptr))
86     return -EFAULT;
87    
88     tv.tv_nsec = 0;
89    
90     err = security_settime(&tv, NULL);
91     if (err)
92     return err;
93    
94     do_settimeofday(&tv);
95     return 0;
96     }
97    
98     #endif /* __ARCH_WANT_SYS_TIME */
99    
100     asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __user *tz)
101     {
102     if (likely(tv != NULL)) {
103     struct timeval ktv;
104     do_gettimeofday(&ktv);
105     if (copy_to_user(tv, &ktv, sizeof(ktv)))
106     return -EFAULT;
107     }
108     if (unlikely(tz != NULL)) {
109     if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
110     return -EFAULT;
111     }
112     return 0;
113     }
114    
115     /*
116     * Adjust the time obtained from the CMOS to be UTC time instead of
117     * local time.
118     *
119     * This is ugly, but preferable to the alternatives. Otherwise we
120     * would either need to write a program to do it in /etc/rc (and risk
121     * confusion if the program gets run more than once; it would also be
122     * hard to make the program warp the clock precisely n hours) or
123     * compile in the timezone information into the kernel. Bad, bad....
124     *
125     * - TYT, 1992-01-01
126     *
127     * The best thing to do is to keep the CMOS clock in universal time (UTC)
128     * as real UNIX machines always do it. This avoids all headaches about
129     * daylight saving times and warping kernel clocks.
130     */
131     inline static void warp_clock(void)
132     {
133     write_seqlock_irq(&xtime_lock);
134     wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
135     xtime.tv_sec += sys_tz.tz_minuteswest * 60;
136     time_interpolator_reset();
137     write_sequnlock_irq(&xtime_lock);
138     clock_was_set();
139     }
140    
141     /*
142     * In case for some reason the CMOS clock has not already been running
143     * in UTC, but in some local time: The first time we set the timezone,
144     * we will warp the clock so that it is ticking UTC time instead of
145     * local time. Presumably, if someone is setting the timezone then we
146     * are running in an environment where the programs understand about
147     * timezones. This should be done at boot time in the /etc/rc script,
148     * as soon as possible, so that the clock can be set right. Otherwise,
149     * various programs will get confused when the clock gets warped.
150     */
151    
152     int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
153     {
154     static int firsttime = 1;
155     int error = 0;
156    
157     error = security_settime(tv, tz);
158     if (error)
159     return error;
160    
161     if (tz) {
162     /* SMP safe, global irq locking makes it work. */
163     sys_tz = *tz;
164     if (firsttime) {
165     firsttime = 0;
166     if (!tv)
167     warp_clock();
168     }
169     }
170     if (tv)
171     {
172     /* SMP safe, again the code in arch/foo/time.c should
173     * globally block out interrupts when it runs.
174     */
175     return do_settimeofday(tv);
176     }
177     return 0;
178     }
179    
180     asmlinkage long sys_settimeofday(struct timeval __user *tv,
181     struct timezone __user *tz)
182     {
183     struct timeval user_tv;
184     struct timespec new_ts;
185     struct timezone new_tz;
186    
187     if (tv) {
188     if (copy_from_user(&user_tv, tv, sizeof(*tv)))
189     return -EFAULT;
190     new_ts.tv_sec = user_tv.tv_sec;
191     new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
192     }
193     if (tz) {
194     if (copy_from_user(&new_tz, tz, sizeof(*tz)))
195     return -EFAULT;
196     }
197    
198     return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
199     }
200    
201     long pps_offset; /* pps time offset (us) */
202     long pps_jitter = MAXTIME; /* time dispersion (jitter) (us) */
203    
204     long pps_freq; /* frequency offset (scaled ppm) */
205     long pps_stabil = MAXFREQ; /* frequency dispersion (scaled ppm) */
206    
207     long pps_valid = PPS_VALID; /* pps signal watchdog counter */
208    
209     int pps_shift = PPS_SHIFT; /* interval duration (s) (shift) */
210    
211     long pps_jitcnt; /* jitter limit exceeded */
212     long pps_calcnt; /* calibration intervals */
213     long pps_errcnt; /* calibration errors */
214     long pps_stbcnt; /* stability limit exceeded */
215    
216     /* hook for a loadable hardpps kernel module */
217     void (*hardpps_ptr)(struct timeval *);
218    
219     /* we call this to notify the arch when the clock is being
220     * controlled. If no such arch routine, do nothing.
221     */
222     void __attribute__ ((weak)) notify_arch_cmos_timer(void)
223     {
224     return;
225     }
226    
227     /* adjtimex mainly allows reading (and writing, if superuser) of
228     * kernel time-keeping variables. used by xntpd.
229     */
230     int do_adjtimex(struct timex *txc)
231     {
232     long ltemp, mtemp, save_adjust;
233     int result;
234    
235     /* In order to modify anything, you gotta be super-user! */
236     if (txc->modes && !capable(CAP_SYS_TIME))
237     return -EPERM;
238    
239     /* Now we validate the data before disabling interrupts */
240    
241     if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
242     /* singleshot must not be used with any other mode bits */
243     if (txc->modes != ADJ_OFFSET_SINGLESHOT)
244     return -EINVAL;
245    
246     if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
247     /* adjustment Offset limited to +- .512 seconds */
248     if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
249     return -EINVAL;
250    
251     /* if the quartz is off by more than 10% something is VERY wrong ! */
252     if (txc->modes & ADJ_TICK)
253     if (txc->tick < 900000/USER_HZ ||
254     txc->tick > 1100000/USER_HZ)
255     return -EINVAL;
256    
257     write_seqlock_irq(&xtime_lock);
258     result = time_state; /* mostly `TIME_OK' */
259    
260     /* Save for later - semantics of adjtime is to return old value */
261     save_adjust = time_next_adjust ? time_next_adjust : time_adjust;
262    
263     #if 0 /* STA_CLOCKERR is never set yet */
264     time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
265     #endif
266     /* If there are input parameters, then process them */
267     if (txc->modes)
268     {
269     if (txc->modes & ADJ_STATUS) /* only set allowed bits */
270     time_status = (txc->status & ~STA_RONLY) |
271     (time_status & STA_RONLY);
272    
273     if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */
274     if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
275     result = -EINVAL;
276     goto leave;
277     }
278     time_freq = txc->freq - pps_freq;
279     }
280    
281     if (txc->modes & ADJ_MAXERROR) {
282     if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
283     result = -EINVAL;
284     goto leave;
285     }
286     time_maxerror = txc->maxerror;
287     }
288    
289     if (txc->modes & ADJ_ESTERROR) {
290     if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
291     result = -EINVAL;
292     goto leave;
293     }
294     time_esterror = txc->esterror;
295     }
296    
297     if (txc->modes & ADJ_TIMECONST) { /* p. 24 */
298     if (txc->constant < 0) { /* NTP v4 uses values > 6 */
299     result = -EINVAL;
300     goto leave;
301     }
302     time_constant = txc->constant;
303     }
304    
305     if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
306     if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
307     /* adjtime() is independent from ntp_adjtime() */
308     if ((time_next_adjust = txc->offset) == 0)
309     time_adjust = 0;
310     }
311     else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
312     ltemp = (time_status & (STA_PPSTIME | STA_PPSSIGNAL)) ==
313     (STA_PPSTIME | STA_PPSSIGNAL) ?
314     pps_offset : txc->offset;
315    
316     /*
317     * Scale the phase adjustment and
318     * clamp to the operating range.
319     */
320     if (ltemp > MAXPHASE)
321     time_offset = MAXPHASE << SHIFT_UPDATE;
322     else if (ltemp < -MAXPHASE)
323     time_offset = -(MAXPHASE << SHIFT_UPDATE);
324     else
325     time_offset = ltemp << SHIFT_UPDATE;
326    
327     /*
328     * Select whether the frequency is to be controlled
329     * and in which mode (PLL or FLL). Clamp to the operating
330     * range. Ugly multiply/divide should be replaced someday.
331     */
332    
333     if (time_status & STA_FREQHOLD || time_reftime == 0)
334     time_reftime = xtime.tv_sec;
335     mtemp = xtime.tv_sec - time_reftime;
336     time_reftime = xtime.tv_sec;
337     if (time_status & STA_FLL) {
338     if (mtemp >= MINSEC) {
339     ltemp = (time_offset / mtemp) << (SHIFT_USEC -
340     SHIFT_UPDATE);
341     if (ltemp < 0)
342     time_freq -= -ltemp >> SHIFT_KH;
343     else
344     time_freq += ltemp >> SHIFT_KH;
345     } else /* calibration interval too short (p. 12) */
346     result = TIME_ERROR;
347     } else { /* PLL mode */
348     if (mtemp < MAXSEC) {
349     ltemp *= mtemp;
350     if (ltemp < 0)
351     time_freq -= -ltemp >> (time_constant +
352     time_constant +
353     SHIFT_KF - SHIFT_USEC);
354     else
355     time_freq += ltemp >> (time_constant +
356     time_constant +
357     SHIFT_KF - SHIFT_USEC);
358     } else /* calibration interval too long (p. 12) */
359     result = TIME_ERROR;
360     }
361     if (time_freq > time_tolerance)
362     time_freq = time_tolerance;
363     else if (time_freq < -time_tolerance)
364     time_freq = -time_tolerance;
365     } /* STA_PLL || STA_PPSTIME */
366     } /* txc->modes & ADJ_OFFSET */
367     if (txc->modes & ADJ_TICK) {
368     tick_usec = txc->tick;
369     tick_nsec = TICK_USEC_TO_NSEC(tick_usec);
370     }
371     } /* txc->modes */
372     leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
373     || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0
374     && (time_status & STA_PPSSIGNAL) == 0)
375     /* p. 24, (b) */
376     || ((time_status & (STA_PPSTIME|STA_PPSJITTER))
377     == (STA_PPSTIME|STA_PPSJITTER))
378     /* p. 24, (c) */
379     || ((time_status & STA_PPSFREQ) != 0
380     && (time_status & (STA_PPSWANDER|STA_PPSERROR)) != 0))
381     /* p. 24, (d) */
382     result = TIME_ERROR;
383    
384     if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
385     txc->offset = save_adjust;
386     else {
387     if (time_offset < 0)
388     txc->offset = -(-time_offset >> SHIFT_UPDATE);
389     else
390     txc->offset = time_offset >> SHIFT_UPDATE;
391     }
392     txc->freq = time_freq + pps_freq;
393     txc->maxerror = time_maxerror;
394     txc->esterror = time_esterror;
395     txc->status = time_status;
396     txc->constant = time_constant;
397     txc->precision = time_precision;
398     txc->tolerance = time_tolerance;
399     txc->tick = tick_usec;
400     txc->ppsfreq = pps_freq;
401     txc->jitter = pps_jitter >> PPS_AVG;
402     txc->shift = pps_shift;
403     txc->stabil = pps_stabil;
404     txc->jitcnt = pps_jitcnt;
405     txc->calcnt = pps_calcnt;
406     txc->errcnt = pps_errcnt;
407     txc->stbcnt = pps_stbcnt;
408     write_sequnlock_irq(&xtime_lock);
409     do_gettimeofday(&txc->time);
410     notify_arch_cmos_timer();
411     return(result);
412     }
413    
414     asmlinkage long sys_adjtimex(struct timex __user *txc_p)
415     {
416     struct timex txc; /* Local copy of parameter */
417     int ret;
418    
419     /* Copy the user data space into the kernel copy
420     * structure. But bear in mind that the structures
421     * may change
422     */
423     if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
424     return -EFAULT;
425     ret = do_adjtimex(&txc);
426     return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
427     }
428    
429     inline struct timespec current_kernel_time(void)
430     {
431     struct timespec now;
432     unsigned long seq;
433    
434     do {
435     seq = read_seqbegin(&xtime_lock);
436    
437     now = xtime;
438     } while (read_seqretry(&xtime_lock, seq));
439    
440     return now;
441     }
442    
443     EXPORT_SYMBOL(current_kernel_time);
444    
445     /**
446     * current_fs_time - Return FS time
447     * @sb: Superblock.
448     *
449     * Return the current time truncated to the time granuality supported by
450     * the fs.
451     */
452     struct timespec current_fs_time(struct super_block *sb)
453     {
454     struct timespec now = current_kernel_time();
455     return timespec_trunc(now, sb->s_time_gran);
456     }
457     EXPORT_SYMBOL(current_fs_time);
458    
459     /**
460     * timespec_trunc - Truncate timespec to a granuality
461     * @t: Timespec
462     * @gran: Granuality in ns.
463     *
464     * Truncate a timespec to a granuality. gran must be smaller than a second.
465     * Always rounds down.
466     *
467     * This function should be only used for timestamps returned by
468     * current_kernel_time() or CURRENT_TIME, not with do_gettimeofday() because
469     * it doesn't handle the better resolution of the later.
470     */
471     struct timespec timespec_trunc(struct timespec t, unsigned gran)
472     {
473     /*
474     * Division is pretty slow so avoid it for common cases.
475     * Currently current_kernel_time() never returns better than
476     * jiffies resolution. Exploit that.
477     */
478     if (gran <= jiffies_to_usecs(1) * 1000) {
479     /* nothing */
480     } else if (gran == 1000000000) {
481     t.tv_nsec = 0;
482     } else {
483     t.tv_nsec -= t.tv_nsec % gran;
484     }
485     return t;
486     }
487     EXPORT_SYMBOL(timespec_trunc);
488    
489     #ifdef CONFIG_TIME_INTERPOLATION
490     void getnstimeofday (struct timespec *tv)
491     {
492     unsigned long seq,sec,nsec;
493    
494     do {
495     seq = read_seqbegin(&xtime_lock);
496     sec = xtime.tv_sec;
497     nsec = xtime.tv_nsec+time_interpolator_get_offset();
498     } while (unlikely(read_seqretry(&xtime_lock, seq)));
499    
500     while (unlikely(nsec >= NSEC_PER_SEC)) {
501     nsec -= NSEC_PER_SEC;
502     ++sec;
503     }
504     tv->tv_sec = sec;
505     tv->tv_nsec = nsec;
506     }
507     EXPORT_SYMBOL_GPL(getnstimeofday);
508    
509     int do_settimeofday (struct timespec *tv)
510     {
511     time_t wtm_sec, sec = tv->tv_sec;
512     long wtm_nsec, nsec = tv->tv_nsec;
513    
514     if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
515     return -EINVAL;
516    
517     write_seqlock_irq(&xtime_lock);
518     {
519     wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
520     wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
521    
522     set_normalized_timespec(&xtime, sec, nsec);
523     set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
524    
525     time_adjust = 0; /* stop active adjtime() */
526     time_status |= STA_UNSYNC;
527     time_maxerror = NTP_PHASE_LIMIT;
528     time_esterror = NTP_PHASE_LIMIT;
529     time_interpolator_reset();
530     }
531     write_sequnlock_irq(&xtime_lock);
532     clock_was_set();
533     return 0;
534     }
535    
536     void do_gettimeofday (struct timeval *tv)
537     {
538     unsigned long seq, nsec, usec, sec, offset;
539     do {
540     seq = read_seqbegin(&xtime_lock);
541     offset = time_interpolator_get_offset();
542     sec = xtime.tv_sec;
543     nsec = xtime.tv_nsec;
544     } while (unlikely(read_seqretry(&xtime_lock, seq)));
545    
546     usec = (nsec + offset) / 1000;
547    
548     while (unlikely(usec >= USEC_PER_SEC)) {
549     usec -= USEC_PER_SEC;
550     ++sec;
551     }
552    
553     tv->tv_sec = sec;
554     tv->tv_usec = usec;
555     }
556    
557     EXPORT_SYMBOL(do_gettimeofday);
558    
559    
560     #else
561     /*
562     * Simulate gettimeofday using do_gettimeofday which only allows a timeval
563     * and therefore only yields usec accuracy
564     */
565     void getnstimeofday(struct timespec *tv)
566     {
567     struct timeval x;
568    
569     do_gettimeofday(&x);
570     tv->tv_sec = x.tv_sec;
571     tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
572     }
573     #endif
574    
575     #if (BITS_PER_LONG < 64)
576     u64 get_jiffies_64(void)
577     {
578     unsigned long seq;
579     u64 ret;
580    
581     do {
582     seq = read_seqbegin(&xtime_lock);
583     ret = jiffies_64;
584     } while (read_seqretry(&xtime_lock, seq));
585     return ret;
586     }
587    
588     EXPORT_SYMBOL(get_jiffies_64);
589     #endif
590    
591     EXPORT_SYMBOL(jiffies);