]> git.ipfire.org Git - thirdparty/util-linux.git/blame_incremental - sys-utils/hwclock-rtc.c
sys-utils: cleanup license lines, add SPDX
[thirdparty/util-linux.git] / sys-utils / hwclock-rtc.c
... / ...
CommitLineData
1/*
2 * SPDX-License-Identifier: GPL-2.0-or-later
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * rtc.c - Use /dev/rtc for clock access
10 */
11#include <asm/ioctl.h>
12#include <errno.h>
13#include <linux/rtc.h>
14#include <linux/types.h>
15#include <fcntl.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <sys/ioctl.h>
19#include <sys/select.h>
20#include <sys/time.h>
21#include <time.h>
22#include <unistd.h>
23
24#include "monotonic.h"
25#include "strutils.h"
26#include "xalloc.h"
27#include "nls.h"
28
29#include "hwclock.h"
30
31#ifndef RTC_PARAM_GET
32struct rtc_param {
33 __u64 param;
34 union {
35 __u64 uvalue;
36 __s64 svalue;
37 __u64 ptr;
38 };
39 __u32 index;
40 __u32 __pad;
41};
42
43# define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param)
44# define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param)
45
46# define RTC_PARAM_FEATURES 0
47# define RTC_PARAM_CORRECTION 1
48# define RTC_PARAM_BACKUP_SWITCH_MODE 2
49#endif /* RTC_PARAM_GET */
50
51static const struct hwclock_param hwclock_params[] =
52{
53 { RTC_PARAM_FEATURES, "features", N_("supported features") },
54 { RTC_PARAM_CORRECTION, "correction", N_("time correction") },
55 { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", N_("backup switch mode") },
56 { }
57};
58
59const struct hwclock_param *get_hwclock_params(void)
60{
61 return hwclock_params;
62}
63
64/*
65 * /dev/rtc is conventionally chardev 10/135
66 * ia64 uses /dev/efirtc, chardev 10/136
67 * devfs (obsolete) used /dev/misc/... for miscdev
68 * new RTC framework + udev uses dynamic major and /dev/rtc0.../dev/rtcN
69 * ... so we need an overridable default
70 */
71
72/* default or user defined dev (by hwclock --rtc=<path>) */
73static const char *rtc_dev_name;
74static int rtc_dev_fd = -1;
75
76static void close_rtc(void)
77{
78 if (rtc_dev_fd != -1)
79 close(rtc_dev_fd);
80 rtc_dev_fd = -1;
81}
82
83static int open_rtc(const struct hwclock_control *ctl)
84{
85 static const char * const fls[] = {
86#ifdef __ia64__
87 "/dev/efirtc",
88 "/dev/misc/efirtc",
89#endif
90 "/dev/rtc0",
91 "/dev/rtc",
92 "/dev/misc/rtc"
93 };
94 size_t i;
95
96 if (rtc_dev_fd != -1)
97 return rtc_dev_fd;
98
99 /* --rtc option has been given */
100 if (ctl->rtc_dev_name) {
101 rtc_dev_name = ctl->rtc_dev_name;
102 rtc_dev_fd = open(rtc_dev_name, O_RDONLY);
103 } else {
104 for (i = 0; i < ARRAY_SIZE(fls); i++) {
105 if (ctl->verbose)
106 printf(_("Trying to open: %s\n"), fls[i]);
107 rtc_dev_fd = open(fls[i], O_RDONLY);
108
109 if (rtc_dev_fd < 0) {
110 if (errno == ENOENT || errno == ENODEV)
111 continue;
112 if (ctl->verbose)
113 warn(_("cannot open %s"), fls[i]);
114 }
115 rtc_dev_name = fls[i];
116 break;
117 }
118 if (rtc_dev_fd < 0)
119 rtc_dev_name = *fls; /* default for error messages */
120 }
121 if (rtc_dev_fd != -1)
122 atexit(close_rtc);
123 return rtc_dev_fd;
124}
125
126static int open_rtc_or_exit(const struct hwclock_control *ctl)
127{
128 int rtc_fd = open_rtc(ctl);
129
130 if (rtc_fd < 0) {
131 warn(_("cannot open rtc device"));
132 hwclock_exit(ctl, EXIT_FAILURE);
133 }
134 return rtc_fd;
135}
136
137static int do_rtc_read_ioctl(int rtc_fd, struct tm *tm)
138{
139 int rc = -1;
140 struct rtc_time rtc_tm = { 0 };
141
142 rc = ioctl(rtc_fd, RTC_RD_TIME, &rtc_tm);
143
144 if (rc == -1) {
145 warn(_("ioctl(RTC_RD_NAME) to %s to read the time failed"),
146 rtc_dev_name);
147 return -1;
148 }
149
150 /* kernel uses private struct tm definition to be self contained */
151 tm->tm_sec = rtc_tm.tm_sec;
152 tm->tm_min = rtc_tm.tm_min;
153 tm->tm_hour = rtc_tm.tm_hour;
154 tm->tm_mday = rtc_tm.tm_mday;
155 tm->tm_mon = rtc_tm.tm_mon;
156 tm->tm_year = rtc_tm.tm_year;
157 tm->tm_wday = rtc_tm.tm_wday;
158 tm->tm_yday = rtc_tm.tm_yday;
159 tm->tm_isdst = -1; /* don't know whether it's dst */
160 return 0;
161}
162
163/*
164 * Wait for the top of a clock tick by reading /dev/rtc in a busy loop
165 * until we see it. This function is used for rtc drivers without ioctl
166 * interrupts. This is typical on an Alpha, where the Hardware Clock
167 * interrupts are used by the kernel for the system clock, so aren't at
168 * the user's disposal.
169 */
170static int busywait_for_rtc_clock_tick(const struct hwclock_control *ctl,
171 const int rtc_fd)
172{
173 struct tm start_time = { 0 };
174 /* The time when we were called (and started waiting) */
175 struct tm nowtime = { 0 };
176 int rc;
177 struct timeval begin = { 0 }, now = { 0 };
178
179 if (ctl->verbose) {
180 printf("ioctl(%d, RTC_UIE_ON, 0): %s\n",
181 rtc_fd, strerror(errno));
182 printf(_("Waiting in loop for time from %s to change\n"),
183 rtc_dev_name);
184 }
185
186 if (do_rtc_read_ioctl(rtc_fd, &start_time))
187 return 1;
188
189 /*
190 * Wait for change. Should be within a second, but in case
191 * something weird happens, we have a time limit (1.5s) on this loop
192 * to reduce the impact of this failure.
193 */
194 gettime_monotonic(&begin);
195 do {
196 rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
197 if (rc || start_time.tm_sec != nowtime.tm_sec)
198 break;
199 gettime_monotonic(&now);
200 if (time_diff(now, begin) > 1.5) {
201 warnx(_("Timed out waiting for time change."));
202 return 1;
203 }
204 } while (1);
205
206 if (rc)
207 return 1;
208 return 0;
209}
210
211/*
212 * Same as synchronize_to_clock_tick(), but just for /dev/rtc.
213 */
214static int synchronize_to_clock_tick_rtc(const struct hwclock_control *ctl)
215{
216 int rtc_fd; /* File descriptor of /dev/rtc */
217 int ret = 1;
218
219 rtc_fd = open_rtc(ctl);
220 if (rtc_fd == -1) {
221 warn(_("cannot open rtc device"));
222 return ret;
223 }
224
225 /* Turn on update interrupts (one per second) */
226 int rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
227
228 if (rc != -1) {
229 /*
230 * Just reading rtc_fd fails on broken hardware: no
231 * update interrupt comes and a bootscript with a
232 * hwclock call hangs
233 */
234 fd_set rfds;
235 struct timeval tv;
236
237 /*
238 * Wait up to ten seconds for the next update
239 * interrupt
240 */
241 FD_ZERO(&rfds);
242 FD_SET(rtc_fd, &rfds);
243 tv.tv_sec = 10;
244 tv.tv_usec = 0;
245 rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
246 if (0 < rc)
247 ret = 0;
248 else if (rc == 0) {
249 warnx(_("select() to %s to wait for clock tick timed out"),
250 rtc_dev_name);
251 } else
252 warn(_("select() to %s to wait for clock tick failed"),
253 rtc_dev_name);
254 /* Turn off update interrupts */
255 rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
256 if (rc == -1)
257 warn(_("ioctl() to %s to turn off update interrupts failed"),
258 rtc_dev_name);
259 } else if (errno == ENOTTY || errno == EINVAL) {
260 /* rtc ioctl interrupts are unimplemented */
261 ret = busywait_for_rtc_clock_tick(ctl, rtc_fd);
262 } else
263 warn(_("ioctl(%d, RTC_UIE_ON, 0) to %s failed"),
264 rtc_fd, rtc_dev_name);
265 return ret;
266}
267
268static int read_hardware_clock_rtc(const struct hwclock_control *ctl,
269 struct tm *tm)
270{
271 int rtc_fd, rc;
272
273 rtc_fd = open_rtc_or_exit(ctl);
274
275 /* Read the RTC time/date, return answer via tm */
276 rc = do_rtc_read_ioctl(rtc_fd, tm);
277
278 return rc;
279}
280
281/*
282 * Set the Hardware Clock to the broken down time <new_broken_time>. Use
283 * ioctls to "rtc" device /dev/rtc.
284 */
285static int set_hardware_clock_rtc(const struct hwclock_control *ctl,
286 const struct tm *new_broken_time)
287{
288 int rc = -1;
289 int rtc_fd;
290 struct rtc_time rtc_tm = { 0 };
291
292 rtc_fd = open_rtc_or_exit(ctl);
293
294 /* kernel uses private struct tm definition to be self contained */
295 rtc_tm.tm_sec = new_broken_time->tm_sec;
296 rtc_tm.tm_min = new_broken_time->tm_min;
297 rtc_tm.tm_hour = new_broken_time->tm_hour;
298 rtc_tm.tm_mday = new_broken_time->tm_mday;
299 rtc_tm.tm_mon = new_broken_time->tm_mon;
300 rtc_tm.tm_year = new_broken_time->tm_year;
301 rtc_tm.tm_wday = new_broken_time->tm_wday;
302 rtc_tm.tm_yday = new_broken_time->tm_yday;
303 rtc_tm.tm_isdst = new_broken_time->tm_isdst;
304
305 rc = ioctl(rtc_fd, RTC_SET_TIME, &rtc_tm);
306
307 if (rc == -1) {
308 warn(_("ioctl(RTC_SET_TIME) to %s to set the time failed"),
309 rtc_dev_name);
310 hwclock_exit(ctl, EXIT_FAILURE);
311 }
312
313 if (ctl->verbose)
314 printf(_("ioctl(RTC_SET_TIME) was successful.\n"));
315
316 return 0;
317}
318
319static int get_permissions_rtc(void)
320{
321 return 0;
322}
323
324static const char *get_device_path(void)
325{
326 return rtc_dev_name;
327}
328
329static const struct clock_ops rtc_interface = {
330 N_("Using the rtc interface to the clock."),
331 get_permissions_rtc,
332 read_hardware_clock_rtc,
333 set_hardware_clock_rtc,
334 synchronize_to_clock_tick_rtc,
335 get_device_path,
336};
337
338/* return &rtc if /dev/rtc can be opened, NULL otherwise */
339const struct clock_ops *probe_for_rtc_clock(const struct hwclock_control *ctl)
340{
341 const int rtc_fd = open_rtc(ctl);
342
343 if (rtc_fd < 0)
344 return NULL;
345 return &rtc_interface;
346}
347
348#ifdef __alpha__
349/*
350 * Get the Hardware Clock epoch setting from the kernel.
351 */
352int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch_p)
353{
354 int rtc_fd;
355
356 rtc_fd = open_rtc(ctl);
357 if (rtc_fd < 0) {
358 warn(_("cannot open %s"), rtc_dev_name);
359 return 1;
360 }
361
362 if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
363 warn(_("ioctl(%d, RTC_EPOCH_READ, epoch_p) to %s failed"),
364 rtc_fd, rtc_dev_name);
365 return 1;
366 }
367
368 if (ctl->verbose)
369 printf(_("ioctl(%d, RTC_EPOCH_READ, epoch_p) to %s succeeded.\n"),
370 rtc_fd, rtc_dev_name);
371
372 return 0;
373}
374
375/*
376 * Set the Hardware Clock epoch in the kernel.
377 */
378int set_epoch_rtc(const struct hwclock_control *ctl)
379{
380 int rtc_fd;
381 unsigned long epoch;
382
383 errno = 0;
384 epoch = strtoul(ctl->epoch_option, NULL, 10);
385
386 /* There were no RTC clocks before 1900. */
387 if (errno || epoch < 1900 || epoch == ULONG_MAX) {
388 warnx(_("invalid epoch '%s'."), ctl->epoch_option);
389 return 1;
390 }
391
392 rtc_fd = open_rtc(ctl);
393 if (rtc_fd < 0) {
394 warn(_("cannot open %s"), rtc_dev_name);
395 return 1;
396 }
397
398 if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
399 warn(_("ioctl(%d, RTC_EPOCH_SET, %lu) to %s failed"),
400 rtc_fd, epoch, rtc_dev_name);
401 return 1;
402 }
403
404 if (ctl->verbose)
405 printf(_("ioctl(%d, RTC_EPOCH_SET, %lu) to %s succeeded.\n"),
406 rtc_fd, epoch, rtc_dev_name);
407
408 return 0;
409}
410#endif /* __alpha__ */
411
412
413
414static int resolve_rtc_param_alias(const char *alias, __u64 *value)
415{
416 const struct hwclock_param *param = &hwclock_params[0];
417
418 while (param->name) {
419 if (!strcmp(alias, param->name)) {
420 *value = param->id;
421 return 0;
422 }
423 param++;
424 }
425
426 return 1;
427}
428
429/* kernel uapi __u64 can be defined differently than uint64_t */
430static int strtoku64(const char *str, __u64 *num, int base)
431{
432 return ul_strtou64(str, (uint64_t *) &num, base);
433}
434
435/*
436 * Get the Hardware Clock parameter setting from the kernel.
437 */
438int get_param_rtc(const struct hwclock_control *ctl,
439 const char *name, uint64_t *id, uint64_t *value)
440{
441 int rtc_fd;
442 struct rtc_param param = { .param = 0 };
443
444 /* handle name */
445 if (resolve_rtc_param_alias(name, &param.param) != 0
446 && strtoku64(name, &param.param, 0) != 0) {
447 warnx(_("could not convert parameter name to number"));
448 return 1;
449 }
450
451 /* get parameter */
452 rtc_fd = open_rtc(ctl);
453 if (rtc_fd < 0) {
454 warn(_("cannot open %s"), rtc_dev_name);
455 return 1;
456 }
457
458 if (ioctl(rtc_fd, RTC_PARAM_GET, &param) == -1) {
459 warn(_("ioctl(%d, RTC_PARAM_GET, param) to %s failed"),
460 rtc_fd, rtc_dev_name);
461 return 1;
462 }
463
464 if (id)
465 *id = param.param;
466 if (value)
467 *value = param.uvalue;
468
469 if (ctl->verbose)
470 printf(_("ioctl(%d, RTC_PARAM_GET, param) to %s succeeded.\n"),
471 rtc_fd, rtc_dev_name);
472
473 return 0;
474}
475
476/*
477 * Set the Hardware Clock parameter in the kernel.
478 */
479int set_param_rtc(const struct hwclock_control *ctl, const char *opt0)
480{
481 int rtc_fd, rc = 1;
482 struct rtc_param param = { .param = 0 };
483 char *tok, *opt = xstrdup(opt0);
484
485 /* handle name */
486 tok = strtok(opt, "=");
487 if (resolve_rtc_param_alias(tok, &param.param) != 0
488 && strtoku64(tok, &param.param, 0) != 0) {
489 warnx(_("could not convert parameter name to number"));
490 goto done;
491 }
492
493 /* handle value */
494 tok = strtok(NULL, "=");
495 if (!tok) {
496 warnx(_("expected <param>=<value>"));
497 goto done;
498 }
499 if (strtoku64(tok, &param.uvalue, 0) != 0) {
500 warnx(_("could not convert parameter value to number"));
501 goto done;
502 }
503
504 /* set parameter */
505 rtc_fd = open_rtc(ctl);
506 if (rtc_fd < 0) {
507 warnx(_("cannot open %s"), rtc_dev_name);
508 return 1;
509 }
510
511 if (ioctl(rtc_fd, RTC_PARAM_SET, &param) == -1) {
512 warn(_("ioctl(%d, RTC_PARAM_SET, param) to %s failed"),
513 rtc_fd, rtc_dev_name);
514 goto done;
515 }
516
517 if (ctl->verbose)
518 printf(_("ioctl(%d, RTC_PARAM_SET, param) to %s succeeded.\n"),
519 rtc_fd, rtc_dev_name);
520
521 rc = 0;
522done:
523 free(opt);
524 return rc;
525}
526
527#ifndef RTC_VL_DATA_INVALID
528#define RTC_VL_DATA_INVALID 0x1
529#endif
530#ifndef RTC_VL_BACKUP_LOW
531#define RTC_VL_BACKUP_LOW 0x2
532#endif
533#ifndef RTC_VL_BACKUP_EMPTY
534#define RTC_VL_BACKUP_EMPTY 0x4
535#endif
536#ifndef RTC_VL_ACCURACY_LOW
537#define RTC_VL_ACCURACY_LOW 0x8
538#endif
539#ifndef RTC_VL_BACKUP_SWITCH
540#define RTC_VL_BACKUP_SWITCH 0x10
541#endif
542
543int rtc_vl_read(const struct hwclock_control *ctl)
544{
545 unsigned int vl;
546 int rtc_fd;
547 size_t i;
548 static const struct vl_bit {
549 unsigned int bit;
550 const char *desc;
551 } vl_bits[] = {
552 { RTC_VL_DATA_INVALID, N_("Voltage too low, RTC data is invalid") },
553 { RTC_VL_BACKUP_LOW, N_("Backup voltage is low") },
554 { RTC_VL_BACKUP_EMPTY, N_("Backup empty or not present") },
555 { RTC_VL_ACCURACY_LOW, N_("Voltage is low, RTC accuracy is reduced") },
556 { RTC_VL_BACKUP_SWITCH, N_("Backup switchover happened") },
557 };
558
559 rtc_fd = open_rtc(ctl);
560 if (rtc_fd < 0) {
561 warnx(_("cannot open %s"), rtc_dev_name);
562 return 1;
563 }
564
565 if (ioctl(rtc_fd, RTC_VL_READ, &vl) == -1) {
566 warn(_("ioctl(%d, RTC_VL_READ) on %s failed"),
567 rtc_fd, rtc_dev_name);
568 return 1;
569 }
570
571 if (ctl->verbose) {
572 printf(_("ioctl(%d, RTC_VL_READ) on %s returned 0x%x\n"),
573 rtc_fd, rtc_dev_name, vl);
574 }
575
576 for (i = 0; i < ARRAY_SIZE(vl_bits); ++i) {
577 const struct vl_bit *vlb = &vl_bits[i];
578
579 if (vl & vlb->bit) {
580 printf("0x%02x - %s\n", vlb->bit, vlb->desc);
581 vl &= ~vlb->bit;
582 }
583 }
584 if (vl)
585 printf("0x%02x - unknown bit(s)\n", vl);
586
587 return 0;
588}
589
590int rtc_vl_clear(const struct hwclock_control *ctl)
591{
592 int rtc_fd;
593
594 rtc_fd = open_rtc(ctl);
595 if (rtc_fd < 0) {
596 warnx(_("cannot open %s"), rtc_dev_name);
597 return 1;
598 }
599
600 if (ioctl(rtc_fd, RTC_VL_CLR) == -1) {
601 warn(_("ioctl(%d, RTC_VL_CLEAR) on %s failed"),
602 rtc_fd, rtc_dev_name);
603 return 1;
604 }
605
606 if (ctl->verbose)
607 printf(_("ioctl(%d, RTC_VL_CLEAR) on %s succeeded.\n"),
608 rtc_fd, rtc_dev_name);
609
610 return 0;
611}