13
20
* Get defines for rtc stuff.
15
* Getting the rtc defines is nontrivial.
16
* The obvious way is by including <linux/mc146818rtc.h>
17
* but that again includes <asm/io.h> which again includes ...
18
* and on sparc and alpha this gives compilation errors for
19
* many kernel versions. So, we give the defines ourselves here.
20
* Moreover, some Sparc person decided to be incompatible, and
21
* used a struct rtc_time different from that used in mc146818rtc.h.
22
* Getting the rtc defines is nontrivial. The obvious way is by including
23
* <linux/mc146818rtc.h> but that again includes <asm/io.h> which again
24
* includes ... and on sparc and alpha this gives compilation errors for
25
* many kernel versions. So, we give the defines ourselves here. Moreover,
26
* some Sparc person decided to be incompatible, and used a struct rtc_time
27
* different from that used in mc146818rtc.h.
24
/* On Sparcs, there is a <asm/rtc.h> that defines different ioctls
25
(that are required on my machine). However, this include file
26
does not exist on other architectures. */
31
* On Sparcs, there is a <asm/rtc.h> that defines different ioctls (that are
32
* required on my machine). However, this include file does not exist on
33
* other architectures.
32
40
/* The following is roughly equivalent */
33
41
struct sparc_rtc_time
35
int sec; /* Seconds (0-59) */
36
int min; /* Minutes (0-59) */
37
int hour; /* Hour (0-23) */
38
int dow; /* Day of the week (1-7) */
39
int dom; /* Day of the month (1-31) */
40
int month; /* Month of year (1-12) */
41
int year; /* Year (0-99) */
43
int sec; /* Seconds 0-59 */
44
int min; /* Minutes 0-59 */
45
int hour; /* Hour 0-23 */
46
int dow; /* Day of the week 1-7 */
47
int dom; /* Day of the month 1-31 */
48
int month; /* Month of year 1-12 */
49
int year; /* Year 0-99 */
44
52
#define RTCGET _IOR('p', 20, struct sparc_rtc_time)
45
53
#define RTCSET _IOW('p', 21, struct sparc_rtc_time)
48
55
/* non-sparc stuff */
50
#include <linux/version.h>
51
/* Check if the /dev/rtc interface is available in this version of
52
the system headers. 131072 is linux 2.0.0. */
53
#if LINUX_VERSION_CODE >= 131072
54
#include <linux/mc146818rtc.h>
57
# include <linux/version.h>
59
* Check if the /dev/rtc interface is available in this version of the
60
* system headers. 131072 is linux 2.0.0.
62
# if LINUX_VERSION_CODE >= 131072
63
# include <linux/mc146818rtc.h>
58
/* struct rtc_time is present since 1.3.99 */
59
/* Earlier (since 1.3.89), a struct tm was used. */
68
* struct rtc_time is present since 1.3.99.
69
* Earlier (since 1.3.89), a struct tm was used.
60
71
struct linux_rtc_time {
72
83
/* RTC_RD_TIME etc have this definition since 1.99.9 (pre2.0-9) */
73
84
#ifndef RTC_RD_TIME
74
#define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_time)
75
#define RTC_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time)
76
#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
77
#define RTC_UIE_OFF _IO('p', 0x04) /* Update int. enable off */
85
# define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_time)
86
# define RTC_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time)
87
# define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
88
# define RTC_UIE_OFF _IO('p', 0x04) /* Update int. enable off */
79
91
/* RTC_EPOCH_READ and RTC_EPOCH_SET are present since 2.0.34 and 2.1.89 */
80
92
#ifndef RTC_EPOCH_READ
81
#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
82
#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
93
# define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
94
# define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
85
/* /dev/rtc is conventionally chardev 10/135
98
* /dev/rtc is conventionally chardev 10/135
86
99
* ia64 uses /dev/efirtc, chardev 10/136
87
100
* devfs (obsolete) used /dev/misc/... for miscdev
88
101
* new RTC framework + udev uses dynamic major and /dev/rtc0.../dev/rtcN
177
191
rc = ioctl(rtc_fd, RTC_RD_TIME, tm);
181
fprintf(stderr, _("ioctl() to %s to read the time failed.\n"),
194
warn(_("ioctl(%s) to %s to read the time failed"),
195
ioctlname, rtc_dev_name);
186
tm->tm_isdst = -1; /* don't know whether it's dst */
191
busywait_for_rtc_clock_tick(const int rtc_fd) {
192
/*----------------------------------------------------------------------------
193
Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
195
-----------------------------------------------------------------------------*/
196
struct tm start_time;
197
/* The time when we were called (and started waiting) */
200
struct timeval begin, now;
203
printf(_("Waiting in loop for time from %s to change\n"),
206
rc = do_rtc_read_ioctl(rtc_fd, &start_time);
210
/* Wait for change. Should be within a second, but in case something
211
* weird happens, we have a time limit (1.5s) on this loop to reduce the
212
* impact of this failure.
214
gettimeofday(&begin, NULL);
216
rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
217
if (rc || start_time.tm_sec != nowtime.tm_sec)
219
gettimeofday(&now, NULL);
220
if (time_diff(now, begin) > 1.5) {
221
fprintf(stderr, _("Timed out waiting for time change.\n"));
232
synchronize_to_clock_tick_rtc(void) {
233
/*----------------------------------------------------------------------------
234
Same as synchronize_to_clock_tick(), but just for /dev/rtc.
235
-----------------------------------------------------------------------------*/
236
int rtc_fd; /* File descriptor of /dev/rtc */
241
outsyserr(_("open() of %s failed"), rtc_dev_name);
244
int rc; /* Return code from ioctl */
245
/* Turn on update interrupts (one per second) */
199
tm->tm_isdst = -1; /* don't know whether it's dst */
204
* Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
207
static int busywait_for_rtc_clock_tick(const int rtc_fd)
209
struct tm start_time;
210
/* The time when we were called (and started waiting) */
213
struct timeval begin, now;
216
printf(_("Waiting in loop for time from %s to change\n"),
219
rc = do_rtc_read_ioctl(rtc_fd, &start_time);
224
* Wait for change. Should be within a second, but in case
225
* something weird happens, we have a time limit (1.5s) on this loop
226
* to reduce the impact of this failure.
228
gettimeofday(&begin, NULL);
230
rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
231
if (rc || start_time.tm_sec != nowtime.tm_sec)
233
gettimeofday(&now, NULL);
234
if (time_diff(now, begin) > 1.5) {
235
warnx(_("Timed out waiting for time change."));
246
* Same as synchronize_to_clock_tick(), but just for /dev/rtc.
248
static int synchronize_to_clock_tick_rtc(void)
250
int rtc_fd; /* File descriptor of /dev/rtc */
255
warn(_("open() of %s failed"), rtc_dev_name);
258
int rc; /* Return code from ioctl */
259
/* Turn on update interrupts (one per second) */
246
260
#if defined(__alpha__) || defined(__sparc__)
247
/* Not all alpha kernels reject RTC_UIE_ON, but probably they should. */
262
* Not all alpha kernels reject RTC_UIE_ON, but probably
251
rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
268
rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
253
if (rc == -1 && (errno == ENOTTY || errno == EINVAL)) {
254
/* This rtc device doesn't have interrupt functions. This is typical
255
on an Alpha, where the Hardware Clock interrupts are used by the
256
kernel for the system clock, so aren't at the user's disposal.
259
printf(_("%s does not have interrupt functions. "),
261
ret = busywait_for_rtc_clock_tick(rtc_fd);
262
} else if (rc == 0) {
270
if (rc == -1 && (errno == ENOTTY || errno == EINVAL)) {
272
* This rtc device doesn't have interrupt functions.
273
* This is typical on an Alpha, where the Hardware
274
* Clock interrupts are used by the kernel for the
275
* system clock, so aren't at the user's disposal.
279
("%s does not have interrupt functions. "),
281
ret = busywait_for_rtc_clock_tick(rtc_fd);
282
} else if (rc == 0) {
263
283
#ifdef Wait_until_update_interrupt
266
/* this blocks until the next update interrupt */
267
rc = read(rtc_fd, &dummy, sizeof(dummy));
270
outsyserr(_("read() to %s to wait for clock tick failed"),
286
/* this blocks until the next update interrupt */
287
rc = read(rtc_fd, &dummy, sizeof(dummy));
291
("read() to %s to wait for clock tick failed"),
275
/* Just reading rtc_fd fails on broken hardware: no update
276
interrupt comes and a bootscript with a hwclock call hangs */
297
* Just reading rtc_fd fails on broken hardware: no
298
* update interrupt comes and a bootscript with a
280
/* Wait up to five seconds for the next update interrupt */
282
FD_SET(rtc_fd, &rfds);
285
rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
288
outsyserr(_("select() to %s to wait for clock tick failed"),
291
fprintf(stderr, _("select() to %s to wait for clock tick timed out\n"),
305
* Wait up to five seconds for the next update
309
FD_SET(rtc_fd, &rfds);
312
rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
316
("select() to %s to wait for clock tick failed"),
320
("select() to %s to wait for clock tick timed out"),
297
/* Turn off update interrupts */
298
rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
300
outsyserr(_("ioctl() to %s to turn off update interrupts failed"),
303
outsyserr(_("ioctl() to %s to turn on update interrupts "
304
"failed unexpectedly"), rtc_dev_name);
326
/* Turn off update interrupts */
327
rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
330
("ioctl() to %s to turn off update interrupts failed"),
334
("ioctl() to %s to turn on update interrupts "
335
"failed unexpectedly"), rtc_dev_name);
313
read_hardware_clock_rtc(struct tm *tm) {
342
static int read_hardware_clock_rtc(struct tm *tm)
316
346
rtc_fd = open_rtc_or_exit();
385
412
/* return &rtc if /dev/rtc can be opened, NULL otherwise */
387
probe_for_rtc_clock(){
413
struct clock_ops *probe_for_rtc_clock()
388
415
int rtc_fd = open_rtc();
392
outsyserr(_("Open of %s failed"), rtc_dev_name);
419
warn(_("Open of %s failed"), rtc_dev_name);
399
get_epoch_rtc(unsigned long *epoch_p, int silent) {
400
/*----------------------------------------------------------------------------
401
Get the Hardware Clock epoch setting from the kernel.
402
----------------------------------------------------------------------------*/
410
"To manipulate the epoch value in the kernel, we must "
411
"access the Linux 'rtc' device driver via the device special "
412
"file %s. This file does not exist on this system.\n"),
415
outsyserr(_("Unable to open %s"), rtc_dev_name);
420
if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
422
outsyserr(_("ioctl(RTC_EPOCH_READ) to %s failed"), rtc_dev_name);
427
printf(_("we have read epoch %ld from %s "
428
"with RTC_EPOCH_READ ioctl.\n"), *epoch_p, rtc_dev_name);
424
* Get the Hardware Clock epoch setting from the kernel.
426
int get_epoch_rtc(unsigned long *epoch_p, int silent)
435
("To manipulate the epoch value in the kernel, we must "
436
"access the Linux 'rtc' device driver via the device special "
437
"file %s. This file does not exist on this system."),
440
warn(_("Unable to open %s"), rtc_dev_name);
445
if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
447
warn(_("ioctl(RTC_EPOCH_READ) to %s failed"),
453
printf(_("we have read epoch %ld from %s "
454
"with RTC_EPOCH_READ ioctl.\n"), *epoch_p,
436
set_epoch_rtc(unsigned long epoch) {
437
/*----------------------------------------------------------------------------
438
Set the Hardware Clock epoch in the kernel.
439
----------------------------------------------------------------------------*/
443
/* kernel would not accept this epoch value */
444
/* Hmm - bad habit, deciding not to do what the user asks
445
just because one believes that the kernel might not like it. */
446
fprintf(stderr, _("The epoch value may not be less than 1900. "
447
"You requested %ld\n"), epoch);
454
fprintf(stderr, _("To manipulate the epoch value in the kernel, we must "
455
"access the Linux 'rtc' device driver via the device special "
456
"file %s. This file does not exist on this system.\n"),
459
outsyserr(_("Unable to open %s"), rtc_dev_name);
464
printf(_("setting epoch to %ld "
465
"with RTC_EPOCH_SET ioctl to %s.\n"), epoch, rtc_dev_name);
467
if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
469
fprintf(stderr, _("The kernel device driver for %s "
470
"does not have the RTC_EPOCH_SET ioctl.\n"), rtc_dev_name);
472
outsyserr(_("ioctl(RTC_EPOCH_SET) to %s failed"), rtc_dev_name);
461
* Set the Hardware Clock epoch in the kernel.
463
int set_epoch_rtc(unsigned long epoch)
468
/* kernel would not accept this epoch value
470
* Bad habit, deciding not to do what the user asks just
471
* because one believes that the kernel might not like it.
473
warnx(_("The epoch value may not be less than 1900. "
474
"You requested %ld"), epoch);
482
("To manipulate the epoch value in the kernel, we must "
483
"access the Linux 'rtc' device driver via the device special "
484
"file %s. This file does not exist on this system."),
487
warn(_("Unable to open %s"), rtc_dev_name);
492
printf(_("setting epoch to %ld "
493
"with RTC_EPOCH_SET ioctl to %s.\n"), epoch,
496
if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
498
warnx(_("The kernel device driver for %s "
499
"does not have the RTC_EPOCH_SET ioctl."),
502
warn(_("ioctl(RTC_EPOCH_SET) to %s failed"),