From 577cf09bc5aed36b40a3dcaf3842e8c35b6a8dcc Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 17 Jul 2024 13:00:39 +0200 Subject: [PATCH] rtc: factor out RTC_Linux_ReadTime_AfterInterrupt We have code to read time after an RTC's UIE interrupt, which we currently use as part of maintaining the correction file. In a later commit, we will need the same functionality for using the RTC as reference clock, so export the function and give it a descriptive name appropriate for a globally visible function. --- rtc_linux.c | 52 +++++++++++++++++++++++++++++++--------------------- rtc_linux.h | 2 ++ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/rtc_linux.c b/rtc_linux.c index 4de11b0..4c98cb9 100644 --- a/rtc_linux.c +++ b/rtc_linux.c @@ -785,43 +785,53 @@ RTC_Linux_CheckInterrupt(int fd) return (data & RTC_UF) == RTC_UF; } +time_t +RTC_Linux_ReadTime_AfterInterrupt(int fd, int utc, struct timespec *sys_time_cooked) +{ + int status; + struct rtc_time rtc_raw; + + /* Read RTC time, sandwiched between two polls of the system clock + so we can bound any error. */ + + SCH_GetLastEventTime(sys_time_cooked, NULL, NULL); + + status = ioctl(fd, RTC_RD_TIME, &rtc_raw); + if (status < 0) { + LOG(LOGS_ERR, "Could not read time from %s : %s", CNF_GetRtcDevice(), strerror(errno)); + return -1; + } + + /* Convert RTC time into a struct timespec */ + return t_from_rtc(&rtc_raw, utc); +} + static void read_from_device(int fd_, int event, void *any) { int status; struct timespec sys_time; - struct rtc_time rtc_raw; time_t rtc_t; int error = 0; status = RTC_Linux_CheckInterrupt(fd); - if (status < 0) { - SCH_RemoveFileHandler(fd); - RTC_Linux_SwitchInterrupt(fd, 0); /* Likely to raise error too, but just to be sure... */ - close(fd); - fd = -1; - return; + if (status == -1) { + SCH_RemoveFileHandler(fd); + RTC_Linux_SwitchInterrupt(fd, 0); /* Likely to raise error too, but just to be sure... */ + close(fd); + fd = -1; + return; } else if (status == 0) { - return; + /* Wait for the next interrupt, this one may be bogus */ + return; } - SCH_GetLastEventTime(&sys_time, NULL, NULL); - - status = ioctl(fd, RTC_RD_TIME, &rtc_raw); - if (status < 0) { - LOG(LOGS_ERR, "Could not read time from %s : %s", CNF_GetRtcDevice(), strerror(errno)); + rtc_t = RTC_Linux_ReadTime_AfterInterrupt(fd, rtc_on_utc, &sys_time); + if (rtc_t == (time_t)-1) { error = 1; goto turn_off_interrupt; } - /* Convert RTC time into a struct timespec */ - rtc_t = t_from_rtc(&rtc_raw, rtc_on_utc); - - if (rtc_t == (time_t)(-1)) { - error = 1; - goto turn_off_interrupt; - } - process_reading(rtc_t, &sys_time); if (n_samples < 4) { diff --git a/rtc_linux.h b/rtc_linux.h index 1f67ba8..350fd50 100644 --- a/rtc_linux.h +++ b/rtc_linux.h @@ -44,5 +44,7 @@ extern void RTC_Linux_CycleLogFile(void); extern int RTC_Linux_SwitchInterrupt(int fd, int on_off); extern int RTC_Linux_CheckInterrupt(int fd); +extern time_t RTC_Linux_ReadTime_AfterInterrupt(int fd, int utc, + struct timespec *sys_time_cooked); #endif /* _GOT_RTC_LINUX_H */