]> git.ipfire.org Git - thirdparty/util-linux.git/blame - sys-utils/hwclock-rtc.c
hwclock: drop ancient sparc special cases
[thirdparty/util-linux.git] / sys-utils / hwclock-rtc.c
CommitLineData
ef71b8f1 1/*
68a2ade7
KZ
2 * SPDX-License-Identifier: GPL-2.0-or-later
3 *
ef71b8f1
SK
4 * rtc.c - Use /dev/rtc for clock access
5 */
998f392a 6#include <asm/ioctl.h>
5213517f 7#include <errno.h>
998f392a
SK
8#include <fcntl.h>
9#include <stdio.h>
10#include <stdlib.h>
7eda085c 11#include <sys/ioctl.h>
998f392a
SK
12#include <sys/select.h>
13#include <sys/time.h>
14#include <time.h>
15#include <unistd.h>
7eda085c 16
f78a9021 17#include "monotonic.h"
511a5126
KZ
18#include "strutils.h"
19#include "xalloc.h"
7eda085c
KZ
20#include "nls.h"
21
c7f75390
KZ
22#include "hwclock.h"
23
7eda085c
KZ
24/*
25 * Get defines for rtc stuff.
26 *
ef71b8f1
SK
27 * Getting the rtc defines is nontrivial. The obvious way is by including
28 * <linux/mc146818rtc.h> but that again includes <asm/io.h> which again
29 * includes ... and on sparc and alpha this gives compilation errors for
30 * many kernel versions. So, we give the defines ourselves here. Moreover,
31 * some Sparc person decided to be incompatible, and used a struct rtc_time
32 * different from that used in mc146818rtc.h.
7eda085c
KZ
33 */
34
ef71b8f1
SK
35/*
36 * struct rtc_time is present since 1.3.99.
37 * Earlier (since 1.3.89), a struct tm was used.
38 */
7eda085c 39struct linux_rtc_time {
ef71b8f1
SK
40 int tm_sec;
41 int tm_min;
42 int tm_hour;
43 int tm_mday;
44 int tm_mon;
45 int tm_year;
46 int tm_wday;
47 int tm_yday;
48 int tm_isdst;
7eda085c
KZ
49};
50
51/* RTC_RD_TIME etc have this definition since 1.99.9 (pre2.0-9) */
52#ifndef RTC_RD_TIME
ef71b8f1
SK
53# define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_time)
54# define RTC_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time)
55# define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
56# define RTC_UIE_OFF _IO('p', 0x04) /* Update int. enable off */
7eda085c 57#endif
ef71b8f1 58
7eda085c
KZ
59/* RTC_EPOCH_READ and RTC_EPOCH_SET are present since 2.0.34 and 2.1.89 */
60#ifndef RTC_EPOCH_READ
ef71b8f1
SK
61# define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
62# define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
7eda085c
KZ
63#endif
64
511a5126
KZ
65#ifndef RTC_PARAM_GET
66struct rtc_param {
67 uint64_t param;
68 union {
69 uint64_t uvalue;
70 int64_t svalue;
71 uint64_t ptr;
72 };
73 uint32_t index;
74 uint32_t __pad;
75};
76
77# define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param)
78# define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param)
79
80# define RTC_PARAM_FEATURES 0
81# define RTC_PARAM_CORRECTION 1
82# define RTC_PARAM_BACKUP_SWITCH_MODE 2
83#endif /* RTC_PARAM_GET */
84
63d81834
KZ
85static const struct hwclock_param hwclock_params[] =
86{
87 { RTC_PARAM_FEATURES, "features", N_("supported features") },
88 { RTC_PARAM_CORRECTION, "correction", N_("time correction") },
89 { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", N_("backup switch mode") },
90 { }
91};
92
93const struct hwclock_param *get_hwclock_params(void)
94{
95 return hwclock_params;
96}
97
ef71b8f1
SK
98/*
99 * /dev/rtc is conventionally chardev 10/135
88681c5f
KZ
100 * ia64 uses /dev/efirtc, chardev 10/136
101 * devfs (obsolete) used /dev/misc/... for miscdev
102 * new RTC framework + udev uses dynamic major and /dev/rtc0.../dev/rtcN
103 * ... so we need an overridable default
104 */
7eda085c 105
88681c5f 106/* default or user defined dev (by hwclock --rtc=<path>) */
067b6028 107static const char *rtc_dev_name;
27f9db17
KZ
108static int rtc_dev_fd = -1;
109
ef71b8f1
SK
110static void close_rtc(void)
111{
27f9db17
KZ
112 if (rtc_dev_fd != -1)
113 close(rtc_dev_fd);
114 rtc_dev_fd = -1;
115}
116
336f7c5f 117static int open_rtc(const struct hwclock_control *ctl)
ef71b8f1 118{
e08dddbc 119 static const char * const fls[] = {
88681c5f
KZ
120#ifdef __ia64__
121 "/dev/efirtc",
122 "/dev/misc/efirtc",
123#endif
88681c5f 124 "/dev/rtc0",
1811900a 125 "/dev/rtc",
067b6028 126 "/dev/misc/rtc"
88681c5f 127 };
067b6028 128 size_t i;
5d1f6bae 129
27f9db17
KZ
130 if (rtc_dev_fd != -1)
131 return rtc_dev_fd;
132
5d1f6bae 133 /* --rtc option has been given */
336f7c5f
SK
134 if (ctl->rtc_dev_name) {
135 rtc_dev_name = ctl->rtc_dev_name;
27f9db17 136 rtc_dev_fd = open(rtc_dev_name, O_RDONLY);
336f7c5f 137 } else {
067b6028 138 for (i = 0; i < ARRAY_SIZE(fls); i++) {
de4568f7 139 if (ctl->verbose)
067b6028
SK
140 printf(_("Trying to open: %s\n"), fls[i]);
141 rtc_dev_fd = open(fls[i], O_RDONLY);
27f9db17 142
b3fc2a3c
KZ
143 if (rtc_dev_fd < 0) {
144 if (errno == ENOENT || errno == ENODEV)
145 continue;
146 if (ctl->verbose)
147 warn(_("cannot open %s"), fls[i]);
148 }
067b6028 149 rtc_dev_name = fls[i];
27f9db17
KZ
150 break;
151 }
152 if (rtc_dev_fd < 0)
153 rtc_dev_name = *fls; /* default for error messages */
5d1f6bae 154 }
926ffe74 155 if (rtc_dev_fd != -1)
27f9db17
KZ
156 atexit(close_rtc);
157 return rtc_dev_fd;
63cccae4
KZ
158}
159
336f7c5f 160static int open_rtc_or_exit(const struct hwclock_control *ctl)
ef71b8f1 161{
336f7c5f 162 int rtc_fd = open_rtc(ctl);
63cccae4
KZ
163
164 if (rtc_fd < 0) {
067b6028 165 warn(_("cannot open rtc device"));
c47a8f2a 166 hwclock_exit(ctl, EXIT_FAILURE);
364cda48
KZ
167 }
168 return rtc_fd;
169}
170
ef71b8f1
SK
171static int do_rtc_read_ioctl(int rtc_fd, struct tm *tm)
172{
364cda48 173 int rc = -1;
fc35f2db 174
fc35f2db 175 rc = ioctl(rtc_fd, RTC_RD_TIME, tm);
364cda48 176
364cda48 177 if (rc == -1) {
bed96b1c
TW
178 warn(_("ioctl(RTC_RD_NAME) to %s to read the time failed"),
179 rtc_dev_name);
cdedde03 180 return -1;
364cda48
KZ
181 }
182
ef71b8f1 183 tm->tm_isdst = -1; /* don't know whether it's dst */
364cda48
KZ
184 return 0;
185}
7eda085c 186
ef71b8f1 187/*
0411a57e
WP
188 * Wait for the top of a clock tick by reading /dev/rtc in a busy loop
189 * until we see it. This function is used for rtc drivers without ioctl
190 * interrupts. This is typical on an Alpha, where the Hardware Clock
191 * interrupts are used by the kernel for the system clock, so aren't at
192 * the user's disposal.
ef71b8f1 193 */
336f7c5f
SK
194static int busywait_for_rtc_clock_tick(const struct hwclock_control *ctl,
195 const int rtc_fd)
ef71b8f1
SK
196{
197 struct tm start_time;
198 /* The time when we were called (and started waiting) */
199 struct tm nowtime;
200 int rc;
cf8c1917 201 struct timeval begin = { 0 }, now = { 0 };
ef71b8f1 202
de4568f7 203 if (ctl->verbose) {
0411a57e
WP
204 printf("ioctl(%d, RTC_UIE_ON, 0): %s\n",
205 rtc_fd, strerror(errno));
ef71b8f1
SK
206 printf(_("Waiting in loop for time from %s to change\n"),
207 rtc_dev_name);
0411a57e 208 }
ef71b8f1 209
4a6f658c
WP
210 if (do_rtc_read_ioctl(rtc_fd, &start_time))
211 return 1;
ef71b8f1
SK
212
213 /*
214 * Wait for change. Should be within a second, but in case
215 * something weird happens, we have a time limit (1.5s) on this loop
216 * to reduce the impact of this failure.
217 */
f78a9021 218 gettime_monotonic(&begin);
ef71b8f1
SK
219 do {
220 rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
221 if (rc || start_time.tm_sec != nowtime.tm_sec)
222 break;
f78a9021 223 gettime_monotonic(&now);
ef71b8f1 224 if (time_diff(now, begin) > 1.5) {
111c05d3 225 warnx(_("Timed out waiting for time change."));
4a6f658c 226 return 1;
ef71b8f1
SK
227 }
228 } while (1);
229
230 if (rc)
4a6f658c
WP
231 return 1;
232 return 0;
7eda085c
KZ
233}
234
ef71b8f1
SK
235/*
236 * Same as synchronize_to_clock_tick(), but just for /dev/rtc.
237 */
336f7c5f 238static int synchronize_to_clock_tick_rtc(const struct hwclock_control *ctl)
ef71b8f1
SK
239{
240 int rtc_fd; /* File descriptor of /dev/rtc */
4bfd519e 241 int ret = 1;
ef71b8f1 242
336f7c5f 243 rtc_fd = open_rtc(ctl);
ef71b8f1 244 if (rtc_fd == -1) {
067b6028 245 warn(_("cannot open rtc device"));
4bfd519e 246 return ret;
042f62df
RP
247 }
248
249 /* Turn on update interrupts (one per second) */
250 int rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
251
252 if (rc != -1) {
253 /*
254 * Just reading rtc_fd fails on broken hardware: no
255 * update interrupt comes and a bootscript with a
256 * hwclock call hangs
257 */
258 fd_set rfds;
259 struct timeval tv;
260
261 /*
262 * Wait up to ten seconds for the next update
263 * interrupt
264 */
265 FD_ZERO(&rfds);
266 FD_SET(rtc_fd, &rfds);
267 tv.tv_sec = 10;
268 tv.tv_usec = 0;
269 rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
270 if (0 < rc)
271 ret = 0;
272 else if (rc == 0) {
273 warnx(_("select() to %s to wait for clock tick timed out"),
274 rtc_dev_name);
275 } else
276 warn(_("select() to %s to wait for clock tick failed"),
277 rtc_dev_name);
278 /* Turn off update interrupts */
279 rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
280 if (rc == -1)
281 warn(_("ioctl() to %s to turn off update interrupts failed"),
282 rtc_dev_name);
c8650db3
ŁS
283 } else if (errno == ENOTTY || errno == EINVAL) {
284 /* rtc ioctl interrupts are unimplemented */
285 ret = busywait_for_rtc_clock_tick(ctl, rtc_fd);
286 } else
287 warn(_("ioctl(%d, RTC_UIE_ON, 0) to %s failed"),
288 rtc_fd, rtc_dev_name);
ef71b8f1 289 return ret;
7eda085c
KZ
290}
291
336f7c5f
SK
292static int read_hardware_clock_rtc(const struct hwclock_control *ctl,
293 struct tm *tm)
ef71b8f1 294{
55a4a75c 295 int rtc_fd, rc;
7eda085c 296
336f7c5f 297 rtc_fd = open_rtc_or_exit(ctl);
7eda085c 298
364cda48 299 /* Read the RTC time/date, return answer via tm */
55a4a75c 300 rc = do_rtc_read_ioctl(rtc_fd, tm);
7eda085c 301
55a4a75c 302 return rc;
7eda085c
KZ
303}
304
ef71b8f1
SK
305/*
306 * Set the Hardware Clock to the broken down time <new_broken_time>. Use
307 * ioctls to "rtc" device /dev/rtc.
308 */
336f7c5f
SK
309static int set_hardware_clock_rtc(const struct hwclock_control *ctl,
310 const struct tm *new_broken_time)
ef71b8f1 311{
364cda48
KZ
312 int rc = -1;
313 int rtc_fd;
364cda48 314
336f7c5f 315 rtc_fd = open_rtc_or_exit(ctl);
63cccae4 316
fc35f2db
SK
317 rc = ioctl(rtc_fd, RTC_SET_TIME, new_broken_time);
318
364cda48 319 if (rc == -1) {
bed96b1c
TW
320 warn(_("ioctl(RTC_SET_TIME) to %s to set the time failed"),
321 rtc_dev_name);
c47a8f2a 322 hwclock_exit(ctl, EXIT_FAILURE);
364cda48
KZ
323 }
324
de4568f7 325 if (ctl->verbose)
bed96b1c 326 printf(_("ioctl(RTC_SET_TIME) was successful.\n"));
364cda48 327
364cda48 328 return 0;
7eda085c
KZ
329}
330
ef71b8f1
SK
331static int get_permissions_rtc(void)
332{
7eda085c
KZ
333 return 0;
334}
335
df4f1a66
KZ
336static const char *get_device_path(void)
337{
338 return rtc_dev_name;
339}
340
e08dddbc 341static const struct clock_ops rtc_interface = {
8f729d60 342 N_("Using the rtc interface to the clock."),
7eda085c
KZ
343 get_permissions_rtc,
344 read_hardware_clock_rtc,
345 set_hardware_clock_rtc,
346 synchronize_to_clock_tick_rtc,
df4f1a66 347 get_device_path,
7eda085c
KZ
348};
349
350/* return &rtc if /dev/rtc can be opened, NULL otherwise */
e08dddbc 351const struct clock_ops *probe_for_rtc_clock(const struct hwclock_control *ctl)
ef71b8f1 352{
bd078689
SK
353 const int rtc_fd = open_rtc(ctl);
354
355 if (rtc_fd < 0)
356 return NULL;
357 return &rtc_interface;
7eda085c
KZ
358}
359
bd078689 360#ifdef __alpha__
ef71b8f1
SK
361/*
362 * Get the Hardware Clock epoch setting from the kernel.
363 */
af68bd01 364int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch_p)
ef71b8f1
SK
365{
366 int rtc_fd;
367
336f7c5f 368 rtc_fd = open_rtc(ctl);
ef71b8f1 369 if (rtc_fd < 0) {
cbc36f79 370 warn(_("cannot open %s"), rtc_dev_name);
ef71b8f1
SK
371 return 1;
372 }
373
374 if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
f613c3c2
WP
375 warn(_("ioctl(%d, RTC_EPOCH_READ, epoch_p) to %s failed"),
376 rtc_fd, rtc_dev_name);
ef71b8f1
SK
377 return 1;
378 }
7eda085c 379
de4568f7 380 if (ctl->verbose)
f613c3c2
WP
381 printf(_("ioctl(%d, RTC_EPOCH_READ, epoch_p) to %s succeeded.\n"),
382 rtc_fd, rtc_dev_name);
7eda085c 383
ef71b8f1 384 return 0;
7eda085c
KZ
385}
386
ef71b8f1
SK
387/*
388 * Set the Hardware Clock epoch in the kernel.
389 */
336f7c5f 390int set_epoch_rtc(const struct hwclock_control *ctl)
ef71b8f1
SK
391{
392 int rtc_fd;
f7599b4f 393 unsigned long epoch;
ef71b8f1 394
9bf8088f 395 errno = 0;
f7599b4f
WP
396 epoch = strtoul(ctl->epoch_option, NULL, 10);
397
398 /* There were no RTC clocks before 1900. */
9bf8088f 399 if (errno || epoch < 1900 || epoch == ULONG_MAX) {
f7599b4f 400 warnx(_("invalid epoch '%s'."), ctl->epoch_option);
ef71b8f1
SK
401 return 1;
402 }
403
336f7c5f 404 rtc_fd = open_rtc(ctl);
ef71b8f1 405 if (rtc_fd < 0) {
cbc36f79 406 warn(_("cannot open %s"), rtc_dev_name);
ef71b8f1
SK
407 return 1;
408 }
7eda085c 409
f7599b4f 410 if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
f613c3c2
WP
411 warn(_("ioctl(%d, RTC_EPOCH_SET, %lu) to %s failed"),
412 rtc_fd, epoch, rtc_dev_name);
ef71b8f1
SK
413 return 1;
414 }
7eda085c 415
de4568f7 416 if (ctl->verbose)
f613c3c2
WP
417 printf(_("ioctl(%d, RTC_EPOCH_SET, %lu) to %s succeeded.\n"),
418 rtc_fd, epoch, rtc_dev_name);
419
ef71b8f1 420 return 0;
7eda085c 421}
bd078689 422#endif /* __alpha__ */
6097b12d 423
63d81834
KZ
424
425
6097b12d
BK
426static int resolve_rtc_param_alias(const char *alias, uint64_t *value)
427{
428 const struct hwclock_param *param = &hwclock_params[0];
429
430 while (param->name) {
431 if (!strcmp(alias, param->name)) {
432 *value = param->id;
433 return 0;
434 }
435 param++;
436 }
437
438 return 1;
439}
440
441/*
442 * Get the Hardware Clock parameter setting from the kernel.
443 */
511a5126
KZ
444int get_param_rtc(const struct hwclock_control *ctl,
445 const char *name, uint64_t *id, uint64_t *value)
6097b12d
BK
446{
447 int rtc_fd;
511a5126 448 struct rtc_param param = { .param = 0 };
6097b12d
BK
449
450 /* handle name */
511a5126
KZ
451 if (resolve_rtc_param_alias(name, &param.param) != 0
452 && ul_strtou64(name, &param.param, 0) != 0) {
453 warnx(_("could not convert parameter name to number"));
454 return 1;
6097b12d
BK
455 }
456
457 /* get parameter */
458 rtc_fd = open_rtc(ctl);
459 if (rtc_fd < 0) {
460 warn(_("cannot open %s"), rtc_dev_name);
461 return 1;
462 }
463
511a5126 464 if (ioctl(rtc_fd, RTC_PARAM_GET, &param) == -1) {
6097b12d
BK
465 warn(_("ioctl(%d, RTC_PARAM_GET, param) to %s failed"),
466 rtc_fd, rtc_dev_name);
467 return 1;
468 }
469
511a5126
KZ
470 if (id)
471 *id = param.param;
47577bb5 472 if (value)
511a5126
KZ
473 *value = param.uvalue;
474
6097b12d
BK
475 if (ctl->verbose)
476 printf(_("ioctl(%d, RTC_PARAM_GET, param) to %s succeeded.\n"),
477 rtc_fd, rtc_dev_name);
478
479 return 0;
480}
b22b78b1
BK
481
482/*
483 * Set the Hardware Clock parameter in the kernel.
484 */
511a5126 485int set_param_rtc(const struct hwclock_control *ctl, const char *opt0)
b22b78b1 486{
511a5126
KZ
487 int rtc_fd, rc = 1;
488 struct rtc_param param = { .param = 0 };
489 char *tok, *opt = xstrdup(opt0);
b22b78b1
BK
490
491 /* handle name */
511a5126
KZ
492 tok = strtok(opt, "=");
493 if (resolve_rtc_param_alias(tok, &param.param) != 0
494 && ul_strtou64(tok, &param.param, 0) != 0) {
495 warnx(_("could not convert parameter name to number"));
496 goto done;
b22b78b1
BK
497 }
498
499 /* handle value */
500 tok = strtok(NULL, "=");
501 if (!tok) {
502 warnx(_("expected <param>=<value>"));
511a5126 503 goto done;
b22b78b1 504 }
511a5126 505 if (ul_strtou64(tok, &param.uvalue, 0) != 0) {
b22b78b1 506 warnx(_("could not convert parameter value to number"));
511a5126 507 goto done;
b22b78b1
BK
508 }
509
510 /* set parameter */
511 rtc_fd = open_rtc(ctl);
512 if (rtc_fd < 0) {
513 warnx(_("cannot open %s"), rtc_dev_name);
514 return 1;
515 }
516
517 if (ioctl(rtc_fd, RTC_PARAM_SET, &param) == -1) {
518 warn(_("ioctl(%d, RTC_PARAM_SET, param) to %s failed"),
519 rtc_fd, rtc_dev_name);
511a5126 520 goto done;
b22b78b1
BK
521 }
522
523 if (ctl->verbose)
524 printf(_("ioctl(%d, RTC_PARAM_SET, param) to %s succeeded.\n"),
525 rtc_fd, rtc_dev_name);
526
511a5126
KZ
527 rc = 0;
528done:
529 free(opt);
530 return rc;
b22b78b1 531}