]> git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/hwclock-rtc.c
Merge branch 'mbsencode' of https://github.com/yontalcar/util-linux
[thirdparty/util-linux.git] / sys-utils / hwclock-rtc.c
1 /*
2 * rtc.c - Use /dev/rtc for clock access
3 */
4 #include <asm/ioctl.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/ioctl.h>
10 #include <sys/select.h>
11 #include <sys/time.h>
12 #include <time.h>
13 #include <unistd.h>
14
15 #include "nls.h"
16
17 #include "hwclock.h"
18
19 /*
20 * Get defines for rtc stuff.
21 *
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.
28 */
29
30 /*
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.
34 */
35 /* One might do:
36 #ifdef __sparc__
37 # include <asm/rtc.h>
38 #endif
39 */
40 #ifdef __sparc__
41 /* The following is roughly equivalent */
42 struct sparc_rtc_time
43 {
44 int sec; /* Seconds 0-59 */
45 int min; /* Minutes 0-59 */
46 int hour; /* Hour 0-23 */
47 int dow; /* Day of the week 1-7 */
48 int dom; /* Day of the month 1-31 */
49 int month; /* Month of year 1-12 */
50 int year; /* Year 0-99 */
51 };
52 #define RTCGET _IOR('p', 20, struct sparc_rtc_time)
53 #define RTCSET _IOW('p', 21, struct sparc_rtc_time)
54 #endif
55
56 /*
57 * struct rtc_time is present since 1.3.99.
58 * Earlier (since 1.3.89), a struct tm was used.
59 */
60 struct linux_rtc_time {
61 int tm_sec;
62 int tm_min;
63 int tm_hour;
64 int tm_mday;
65 int tm_mon;
66 int tm_year;
67 int tm_wday;
68 int tm_yday;
69 int tm_isdst;
70 };
71
72 /* RTC_RD_TIME etc have this definition since 1.99.9 (pre2.0-9) */
73 #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 */
78 #endif
79
80 /* RTC_EPOCH_READ and RTC_EPOCH_SET are present since 2.0.34 and 2.1.89 */
81 #ifndef RTC_EPOCH_READ
82 # define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
83 # define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
84 #endif
85
86 /*
87 * /dev/rtc is conventionally chardev 10/135
88 * ia64 uses /dev/efirtc, chardev 10/136
89 * devfs (obsolete) used /dev/misc/... for miscdev
90 * new RTC framework + udev uses dynamic major and /dev/rtc0.../dev/rtcN
91 * ... so we need an overridable default
92 */
93
94 /* default or user defined dev (by hwclock --rtc=<path>) */
95 static const char *rtc_dev_name;
96 static int rtc_dev_fd = -1;
97
98 static void close_rtc(void)
99 {
100 if (rtc_dev_fd != -1)
101 close(rtc_dev_fd);
102 rtc_dev_fd = -1;
103 }
104
105 static int open_rtc(const struct hwclock_control *ctl)
106 {
107 static const char *fls[] = {
108 #ifdef __ia64__
109 "/dev/efirtc",
110 "/dev/misc/efirtc",
111 #endif
112 "/dev/rtc0",
113 "/dev/rtc",
114 "/dev/misc/rtc"
115 };
116 size_t i;
117
118 if (rtc_dev_fd != -1)
119 return rtc_dev_fd;
120
121 /* --rtc option has been given */
122 if (ctl->rtc_dev_name) {
123 rtc_dev_name = ctl->rtc_dev_name;
124 rtc_dev_fd = open(rtc_dev_name, O_RDONLY);
125 } else {
126 for (i = 0; i < ARRAY_SIZE(fls); i++) {
127 if (ctl->debug)
128 printf(_("Trying to open: %s\n"), fls[i]);
129 rtc_dev_fd = open(fls[i], O_RDONLY);
130
131 if (rtc_dev_fd < 0
132 && (errno == ENOENT || errno == ENODEV))
133 continue;
134 rtc_dev_name = fls[i];
135 break;
136 }
137 if (rtc_dev_fd < 0)
138 rtc_dev_name = *fls; /* default for error messages */
139 }
140 if (rtc_dev_fd != -1)
141 atexit(close_rtc);
142 return rtc_dev_fd;
143 }
144
145 static int open_rtc_or_exit(const struct hwclock_control *ctl)
146 {
147 int rtc_fd = open_rtc(ctl);
148
149 if (rtc_fd < 0) {
150 warn(_("cannot open rtc device"));
151 hwclock_exit(ctl, EXIT_FAILURE);
152 }
153 return rtc_fd;
154 }
155
156 static int do_rtc_read_ioctl(int rtc_fd, struct tm *tm)
157 {
158 int rc = -1;
159 char *ioctlname;
160 #ifdef __sparc__
161 /* some but not all sparcs use a different ioctl and struct */
162 struct sparc_rtc_time stm;
163 #endif
164
165 ioctlname = "RTC_RD_TIME";
166 rc = ioctl(rtc_fd, RTC_RD_TIME, tm);
167
168 #ifdef __sparc__
169 if (rc == -1) { /* sparc sbus */
170 ioctlname = "RTCGET";
171 rc = ioctl(rtc_fd, RTCGET, &stm);
172 if (rc == 0) {
173 tm->tm_sec = stm.sec;
174 tm->tm_min = stm.min;
175 tm->tm_hour = stm.hour;
176 tm->tm_mday = stm.dom;
177 tm->tm_mon = stm.month - 1;
178 tm->tm_year = stm.year - 1900;
179 tm->tm_wday = stm.dow - 1;
180 tm->tm_yday = -1; /* day in the year */
181 }
182 }
183 #endif
184
185 if (rc == -1) {
186 warn(_("ioctl(%s) to %s to read the time failed"),
187 ioctlname, rtc_dev_name);
188 return -1;
189 }
190
191 tm->tm_isdst = -1; /* don't know whether it's dst */
192 return 0;
193 }
194
195 /*
196 * Wait for the top of a clock tick by reading /dev/rtc in a busy loop
197 * until we see it. This function is used for rtc drivers without ioctl
198 * interrupts. This is typical on an Alpha, where the Hardware Clock
199 * interrupts are used by the kernel for the system clock, so aren't at
200 * the user's disposal.
201 */
202 static int busywait_for_rtc_clock_tick(const struct hwclock_control *ctl,
203 const int rtc_fd)
204 {
205 struct tm start_time;
206 /* The time when we were called (and started waiting) */
207 struct tm nowtime;
208 int rc;
209 struct timeval begin, now;
210
211 if (ctl->debug) {
212 printf("ioctl(%d, RTC_UIE_ON, 0): %s\n",
213 rtc_fd, strerror(errno));
214 printf(_("Waiting in loop for time from %s to change\n"),
215 rtc_dev_name);
216 }
217
218 if (do_rtc_read_ioctl(rtc_fd, &start_time))
219 return 1;
220
221 /*
222 * Wait for change. Should be within a second, but in case
223 * something weird happens, we have a time limit (1.5s) on this loop
224 * to reduce the impact of this failure.
225 */
226 gettimeofday(&begin, NULL);
227 do {
228 rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
229 if (rc || start_time.tm_sec != nowtime.tm_sec)
230 break;
231 gettimeofday(&now, NULL);
232 if (time_diff(now, begin) > 1.5) {
233 warnx(_("Timed out waiting for time change."));
234 return 1;
235 }
236 } while (1);
237
238 if (rc)
239 return 1;
240 return 0;
241 }
242
243 /*
244 * Same as synchronize_to_clock_tick(), but just for /dev/rtc.
245 */
246 static int synchronize_to_clock_tick_rtc(const struct hwclock_control *ctl)
247 {
248 int rtc_fd; /* File descriptor of /dev/rtc */
249 int ret = 1;
250
251 rtc_fd = open_rtc(ctl);
252 if (rtc_fd == -1) {
253 warn(_("cannot open rtc device"));
254 return ret;
255 } else {
256 int rc; /* Return code from ioctl */
257 /* Turn on update interrupts (one per second) */
258 #if defined(__alpha__) || defined(__sparc__)
259 /*
260 * Not all alpha kernels reject RTC_UIE_ON, but probably
261 * they should.
262 */
263 rc = -1;
264 errno = EINVAL;
265 #else
266 rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
267 #endif
268 if (rc != -1) {
269 /*
270 * Just reading rtc_fd fails on broken hardware: no
271 * update interrupt comes and a bootscript with a
272 * hwclock call hangs
273 */
274 fd_set rfds;
275 struct timeval tv;
276
277 /*
278 * Wait up to ten seconds for the next update
279 * interrupt
280 */
281 FD_ZERO(&rfds);
282 FD_SET(rtc_fd, &rfds);
283 tv.tv_sec = 10;
284 tv.tv_usec = 0;
285 rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
286 if (0 < rc)
287 ret = 0;
288 else if (rc == 0) {
289 warnx(_("select() to %s to wait for clock tick timed out"),
290 rtc_dev_name);
291 } else
292 warn(_("select() to %s to wait for clock tick failed"),
293 rtc_dev_name);
294 /* Turn off update interrupts */
295 rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
296 if (rc == -1)
297 warn(_("ioctl() to %s to turn off update interrupts failed"),
298 rtc_dev_name);
299 } else if (errno == ENOTTY || errno == EINVAL) {
300 /* rtc ioctl interrupts are unimplemented */
301 ret = busywait_for_rtc_clock_tick(ctl, rtc_fd);
302 } else
303 warn(_("ioctl(%d, RTC_UIE_ON, 0) to %s failed"),
304 rtc_fd, rtc_dev_name);
305 }
306 return ret;
307 }
308
309 static int read_hardware_clock_rtc(const struct hwclock_control *ctl,
310 struct tm *tm)
311 {
312 int rtc_fd, rc;
313
314 rtc_fd = open_rtc_or_exit(ctl);
315
316 /* Read the RTC time/date, return answer via tm */
317 rc = do_rtc_read_ioctl(rtc_fd, tm);
318
319 return rc;
320 }
321
322 /*
323 * Set the Hardware Clock to the broken down time <new_broken_time>. Use
324 * ioctls to "rtc" device /dev/rtc.
325 */
326 static int set_hardware_clock_rtc(const struct hwclock_control *ctl,
327 const struct tm *new_broken_time)
328 {
329 int rc = -1;
330 int rtc_fd;
331 char *ioctlname;
332
333 rtc_fd = open_rtc_or_exit(ctl);
334
335 ioctlname = "RTC_SET_TIME";
336 rc = ioctl(rtc_fd, RTC_SET_TIME, new_broken_time);
337
338 #ifdef __sparc__
339 if (rc == -1) { /* sparc sbus */
340 struct sparc_rtc_time stm;
341
342 stm.sec = new_broken_time->tm_sec;
343 stm.min = new_broken_time->tm_min;
344 stm.hour = new_broken_time->tm_hour;
345 stm.dom = new_broken_time->tm_mday;
346 stm.month = new_broken_time->tm_mon + 1;
347 stm.year = new_broken_time->tm_year + 1900;
348 stm.dow = new_broken_time->tm_wday + 1;
349
350 ioctlname = "RTCSET";
351 rc = ioctl(rtc_fd, RTCSET, &stm);
352 }
353 #endif
354
355 if (rc == -1) {
356 warn(_("ioctl(%s) to %s to set the time failed"),
357 ioctlname, rtc_dev_name);
358 hwclock_exit(ctl, EXIT_FAILURE);
359 }
360
361 if (ctl->debug)
362 printf(_("ioctl(%s) was successful.\n"), ioctlname);
363
364 return 0;
365 }
366
367 static int get_permissions_rtc(void)
368 {
369 return 0;
370 }
371
372 static struct clock_ops rtc_interface = {
373 N_("Using the rtc interface to the clock."),
374 get_permissions_rtc,
375 read_hardware_clock_rtc,
376 set_hardware_clock_rtc,
377 synchronize_to_clock_tick_rtc,
378 };
379
380 /* return &rtc if /dev/rtc can be opened, NULL otherwise */
381 struct clock_ops *probe_for_rtc_clock(const struct hwclock_control *ctl)
382 {
383 const int rtc_fd = open_rtc(ctl);
384
385 if (rtc_fd < 0)
386 return NULL;
387 return &rtc_interface;
388 }
389
390 #ifdef __alpha__
391 /*
392 * Get the Hardware Clock epoch setting from the kernel.
393 */
394 int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch_p)
395 {
396 int rtc_fd;
397
398 rtc_fd = open_rtc(ctl);
399 if (rtc_fd < 0) {
400 warn(_("cannot open %s"), rtc_dev_name);
401 return 1;
402 }
403
404 if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
405 warn(_("ioctl(%d, RTC_EPOCH_READ, epoch_p) to %s failed"),
406 rtc_fd, rtc_dev_name);
407 return 1;
408 }
409
410 if (ctl->debug)
411 printf(_("ioctl(%d, RTC_EPOCH_READ, epoch_p) to %s succeeded.\n"),
412 rtc_fd, rtc_dev_name);
413
414 return 0;
415 }
416
417 /*
418 * Set the Hardware Clock epoch in the kernel.
419 */
420 int set_epoch_rtc(const struct hwclock_control *ctl)
421 {
422 int rtc_fd;
423 unsigned long epoch;
424
425 epoch = strtoul(ctl->epoch_option, NULL, 10);
426
427 /* There were no RTC clocks before 1900. */
428 if (epoch < 1900 || epoch == ULONG_MAX) {
429 warnx(_("invalid epoch '%s'."), ctl->epoch_option);
430 return 1;
431 }
432
433 rtc_fd = open_rtc(ctl);
434 if (rtc_fd < 0) {
435 warn(_("cannot open %s"), rtc_dev_name);
436 return 1;
437 }
438
439 if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
440 warn(_("ioctl(%d, RTC_EPOCH_SET, %lu) to %s failed"),
441 rtc_fd, epoch, rtc_dev_name);
442 return 1;
443 }
444
445 if (ctl->debug)
446 printf(_("ioctl(%d, RTC_EPOCH_SET, %lu) to %s succeeded.\n"),
447 rtc_fd, epoch, rtc_dev_name);
448
449 return 0;
450 }
451 #endif /* __alpha__ */