hwclock: coding style clean up
Despide amount of the change this change should be harmless. Everything is about indendation, comment restructuring etc not code changes. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
7d8ee8dad5
commit
ef71b8f112
|
@ -1,20 +1,20 @@
|
|||
#ifndef HWCLOCK_CLOCK_H
|
||||
#define HWCLOCK_CLOCK_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h> /* for errno, EPERM, EINVAL, ENOENT */
|
||||
#include <time.h>
|
||||
|
||||
#include "c.h"
|
||||
|
||||
struct clock_ops {
|
||||
char *interface_name;
|
||||
int (*get_permissions)(void);
|
||||
int (*read_hardware_clock)(struct tm *tm);
|
||||
int (*set_hardware_clock)(const struct tm *tm);
|
||||
int (*synchronize_to_clock_tick)(void);
|
||||
int (*get_permissions) (void);
|
||||
int (*read_hardware_clock) (struct tm * tm);
|
||||
int (*set_hardware_clock) (const struct tm * tm);
|
||||
int (*synchronize_to_clock_tick) (void);
|
||||
};
|
||||
|
||||
extern struct clock_ops *probe_for_cmos_clock(void);
|
||||
|
@ -29,9 +29,9 @@ extern int debug;
|
|||
extern int epoch_option;
|
||||
extern void outsyserr(char *msg, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
__attribute__ ((format(printf, 1, 2)));
|
||||
#else
|
||||
;
|
||||
;
|
||||
#endif
|
||||
extern double time_diff(struct timeval subtrahend, struct timeval subtractor);
|
||||
/* cmos.c */
|
||||
|
@ -50,4 +50,4 @@ extern void hwaudit_exit(int status);
|
|||
# define hwclock_exit(_status) exit(_status)
|
||||
#endif
|
||||
|
||||
#endif /* HWCLOCK_CLOCK_H */
|
||||
#endif /* HWCLOCK_CLOCK_H */
|
||||
|
|
943
hwclock/cmos.c
943
hwclock/cmos.c
File diff suppressed because it is too large
Load Diff
2409
hwclock/hwclock.c
2409
hwclock/hwclock.c
File diff suppressed because it is too large
Load Diff
218
hwclock/kd.c
218
hwclock/kd.c
|
@ -1,19 +1,21 @@
|
|||
/* kd.c - KDGHWCLK stuff, possibly m68k only - deprecated */
|
||||
/*
|
||||
* kd.c - KDGHWCLK stuff, possibly m68k only, likely to be deprecated
|
||||
*/
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
#ifdef __m68k__
|
||||
|
||||
#include <unistd.h> /* for close() */
|
||||
#include <fcntl.h> /* for O_RDONLY */
|
||||
#include <sysexits.h>
|
||||
#include <sys/ioctl.h>
|
||||
# include <unistd.h> /* for close() */
|
||||
# include <fcntl.h> /* for O_RDONLY */
|
||||
# include <sysexits.h>
|
||||
# include <sys/ioctl.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "usleep.h"
|
||||
# include "nls.h"
|
||||
# include "usleep.h"
|
||||
|
||||
/* Get defines for KDGHWCLK and KDSHWCLK (m68k) */
|
||||
#include <linux/kd.h>
|
||||
# include <linux/kd.h>
|
||||
|
||||
/* Even on m68k, if KDGHWCLK (antique) is not defined, don't build this */
|
||||
|
||||
|
@ -21,124 +23,126 @@
|
|||
|
||||
#if !defined(__m68k__) || !defined(KDGHWCLK)
|
||||
|
||||
struct clock_ops *
|
||||
probe_for_kd_clock() {
|
||||
struct clock_ops *probe_for_kd_clock()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* __m68k__ && KDGHWCLK */
|
||||
#else /* __m68k__ && KDGHWCLK */
|
||||
|
||||
static int con_fd = -1; /* opened by probe_for_kd_clock() */
|
||||
/* never closed */
|
||||
/* Opened by probe_for_kd_clock(), and never closed. */
|
||||
static int con_fd = -1;
|
||||
static char *con_fd_filename; /* usually "/dev/tty1" */
|
||||
|
||||
static int
|
||||
synchronize_to_clock_tick_kd(void) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Wait for the top of a clock tick by calling KDGHWCLK in a busy loop until
|
||||
we see it.
|
||||
-----------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Wait for the top of a clock tick by calling KDGHWCLK in a busy loop until
|
||||
* we see it.
|
||||
*/
|
||||
static int synchronize_to_clock_tick_kd(void)
|
||||
{
|
||||
/* The time when we were called (and started waiting) */
|
||||
struct hwclk_time start_time, nowtime;
|
||||
struct timeval begin, now;
|
||||
|
||||
/* The time when we were called (and started waiting) */
|
||||
struct hwclk_time start_time, nowtime;
|
||||
struct timeval begin, now;
|
||||
if (debug)
|
||||
printf(_("Waiting in loop for time from KDGHWCLK to change\n"));
|
||||
|
||||
if (debug)
|
||||
printf(_("Waiting in loop for time from KDGHWCLK to change\n"));
|
||||
if (ioctl(con_fd, KDGHWCLK, &start_time) == -1) {
|
||||
outsyserr(_("KDGHWCLK ioctl to read time failed"));
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (ioctl(con_fd, KDGHWCLK, &start_time) == -1) {
|
||||
outsyserr(_("KDGHWCLK ioctl to read time failed"));
|
||||
return 3;
|
||||
}
|
||||
/*
|
||||
* Wait for change. Should be within a second, but in case something
|
||||
* weird happens, we have a time limit (1.5s) on this loop to reduce
|
||||
* the impact of this failure.
|
||||
*/
|
||||
gettimeofday(&begin, NULL);
|
||||
do {
|
||||
/*
|
||||
* Added by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
|
||||
*
|
||||
* "The culprit is the fast loop with KDGHWCLK ioctls. It
|
||||
* seems the kernel gets confused by those on Amigas with
|
||||
* A2000 RTCs and simply hangs after some time. Inserting a
|
||||
* sleep helps."
|
||||
*/
|
||||
usleep(1);
|
||||
|
||||
/* Wait for change. Should be within a second, but in case something
|
||||
* weird happens, we have a time limit (1.5s) on this loop to reduce the
|
||||
* impact of this failure.
|
||||
*/
|
||||
gettimeofday(&begin, NULL);
|
||||
do {
|
||||
/* Added by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
|
||||
* "The culprit is the fast loop with KDGHWCLK ioctls. It seems
|
||||
* the kernel gets confused by those on Amigas with A2000 RTCs
|
||||
* and simply hangs after some time. Inserting a sleep helps."
|
||||
*/
|
||||
usleep(1);
|
||||
if (ioctl(con_fd, KDGHWCLK, &nowtime) == -1) {
|
||||
outsyserr(_
|
||||
("KDGHWCLK ioctl to read time failed in loop"));
|
||||
return 3;
|
||||
}
|
||||
if (start_time.tm_sec != nowtime.tm_sec)
|
||||
break;
|
||||
gettimeofday(&now, NULL);
|
||||
if (time_diff(now, begin) > 1.5) {
|
||||
fprintf(stderr,
|
||||
_("Timed out waiting for time change.\n"));
|
||||
return 2;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
if (ioctl(con_fd, KDGHWCLK, &nowtime) == -1) {
|
||||
outsyserr(_("KDGHWCLK ioctl to read time failed in loop"));
|
||||
return 3;
|
||||
}
|
||||
if (start_time.tm_sec != nowtime.tm_sec)
|
||||
break;
|
||||
gettimeofday(&now, NULL);
|
||||
if (time_diff(now, begin) > 1.5) {
|
||||
fprintf(stderr, _("Timed out waiting for time change.\n"));
|
||||
return 2;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the hardware clock and return the current time via <tm> argument.
|
||||
* Use ioctls to /dev/tty1 on what we assume is an m68k machine.
|
||||
*
|
||||
* Note that we don't use /dev/console here. That might be a serial console.
|
||||
*/
|
||||
static int read_hardware_clock_kd(struct tm *tm)
|
||||
{
|
||||
struct hwclk_time t;
|
||||
|
||||
static int
|
||||
read_hardware_clock_kd(struct tm *tm) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Read the hardware clock and return the current time via <tm>
|
||||
argument. Use ioctls to /dev/tty1 on what we assume is an m68k
|
||||
machine.
|
||||
if (ioctl(con_fd, KDGHWCLK, &t) == -1) {
|
||||
outsyserr(_("ioctl() failed to read time from %s"),
|
||||
con_fd_filename);
|
||||
hwclock_exit(EX_IOERR);
|
||||
}
|
||||
|
||||
Note that we don't use /dev/console here. That might be a serial
|
||||
console.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct hwclk_time t;
|
||||
tm->tm_sec = t.sec;
|
||||
tm->tm_min = t.min;
|
||||
tm->tm_hour = t.hour;
|
||||
tm->tm_mday = t.day;
|
||||
tm->tm_mon = t.mon;
|
||||
tm->tm_year = t.year;
|
||||
tm->tm_wday = t.wday;
|
||||
tm->tm_isdst = -1; /* Don't know if it's Daylight Savings Time */
|
||||
|
||||
if (ioctl(con_fd, KDGHWCLK, &t) == -1) {
|
||||
outsyserr(_("ioctl() failed to read time from %s"), con_fd_filename);
|
||||
hwclock_exit(EX_IOERR);
|
||||
}
|
||||
|
||||
tm->tm_sec = t.sec;
|
||||
tm->tm_min = t.min;
|
||||
tm->tm_hour = t.hour;
|
||||
tm->tm_mday = t.day;
|
||||
tm->tm_mon = t.mon;
|
||||
tm->tm_year = t.year;
|
||||
tm->tm_wday = t.wday;
|
||||
tm->tm_isdst = -1; /* Don't know if it's Daylight Savings Time */
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the Hardware Clock to the time <new_broken_time>. Use ioctls to
|
||||
* /dev/tty1 on what we assume is an m68k machine.
|
||||
*
|
||||
* Note that we don't use /dev/console here. That might be a serial console.
|
||||
*/
|
||||
static int set_hardware_clock_kd(const struct tm *new_broken_time)
|
||||
{
|
||||
struct hwclk_time t;
|
||||
|
||||
static int
|
||||
set_hardware_clock_kd(const struct tm *new_broken_time) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Set the Hardware Clock to the time <new_broken_time>. Use ioctls to
|
||||
/dev/tty1 on what we assume is an m68k machine.
|
||||
t.sec = new_broken_time->tm_sec;
|
||||
t.min = new_broken_time->tm_min;
|
||||
t.hour = new_broken_time->tm_hour;
|
||||
t.day = new_broken_time->tm_mday;
|
||||
t.mon = new_broken_time->tm_mon;
|
||||
t.year = new_broken_time->tm_year;
|
||||
t.wday = new_broken_time->tm_wday;
|
||||
|
||||
Note that we don't use /dev/console here. That might be a serial console.
|
||||
----------------------------------------------------------------------------*/
|
||||
struct hwclk_time t;
|
||||
|
||||
t.sec = new_broken_time->tm_sec;
|
||||
t.min = new_broken_time->tm_min;
|
||||
t.hour = new_broken_time->tm_hour;
|
||||
t.day = new_broken_time->tm_mday;
|
||||
t.mon = new_broken_time->tm_mon;
|
||||
t.year = new_broken_time->tm_year;
|
||||
t.wday = new_broken_time->tm_wday;
|
||||
|
||||
if (ioctl(con_fd, KDSHWCLK, &t ) == -1) {
|
||||
outsyserr(_("ioctl KDSHWCLK failed"));
|
||||
hwclock_exit(1);
|
||||
}
|
||||
return 0;
|
||||
if (ioctl(con_fd, KDSHWCLK, &t) == -1) {
|
||||
outsyserr(_("ioctl KDSHWCLK failed"));
|
||||
hwclock_exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_permissions_kd(void) {
|
||||
return 0;
|
||||
static int get_permissions_kd(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_ops kd = {
|
||||
|
@ -150,8 +154,8 @@ static struct clock_ops kd = {
|
|||
};
|
||||
|
||||
/* return &kd if KDGHWCLK works, NULL otherwise */
|
||||
struct clock_ops *
|
||||
probe_for_kd_clock() {
|
||||
struct clock_ops *probe_for_kd_clock()
|
||||
{
|
||||
struct clock_ops *ret = NULL;
|
||||
struct hwclk_time t;
|
||||
|
||||
|
@ -176,4 +180,4 @@ probe_for_kd_clock() {
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* __m68k__ && KDGHWCLK */
|
||||
#endif /* __m68k__ && KDGHWCLK */
|
||||
|
|
526
hwclock/rtc.c
526
hwclock/rtc.c
|
@ -1,4 +1,6 @@
|
|||
/* rtc.c - Use /dev/rtc for clock access */
|
||||
/*
|
||||
* rtc.c - Use /dev/rtc for clock access
|
||||
*/
|
||||
#include <unistd.h> /* for close() */
|
||||
#include <fcntl.h> /* for O_RDONLY */
|
||||
#include <errno.h>
|
||||
|
@ -12,77 +14,83 @@
|
|||
/*
|
||||
* Get defines for rtc stuff.
|
||||
*
|
||||
* Getting the rtc defines is nontrivial.
|
||||
* The obvious way is by including <linux/mc146818rtc.h>
|
||||
* but that again includes <asm/io.h> which again includes ...
|
||||
* and on sparc and alpha this gives compilation errors for
|
||||
* many kernel versions. So, we give the defines ourselves here.
|
||||
* Moreover, some Sparc person decided to be incompatible, and
|
||||
* used a struct rtc_time different from that used in mc146818rtc.h.
|
||||
* Getting the rtc defines is nontrivial. The obvious way is by including
|
||||
* <linux/mc146818rtc.h> but that again includes <asm/io.h> which again
|
||||
* includes ... and on sparc and alpha this gives compilation errors for
|
||||
* many kernel versions. So, we give the defines ourselves here. Moreover,
|
||||
* some Sparc person decided to be incompatible, and used a struct rtc_time
|
||||
* different from that used in mc146818rtc.h.
|
||||
*/
|
||||
|
||||
/* On Sparcs, there is a <asm/rtc.h> that defines different ioctls
|
||||
(that are required on my machine). However, this include file
|
||||
does not exist on other architectures. */
|
||||
/*
|
||||
* On Sparcs, there is a <asm/rtc.h> that defines different ioctls (that are
|
||||
* required on my machine). However, this include file does not exist on
|
||||
* other architectures.
|
||||
*/
|
||||
/* One might do:
|
||||
#ifdef __sparc__
|
||||
#include <asm/rtc.h>
|
||||
# include <asm/rtc.h>
|
||||
#endif
|
||||
*/
|
||||
/* The following is roughly equivalent */
|
||||
struct sparc_rtc_time
|
||||
{
|
||||
int sec; /* Seconds (0-59) */
|
||||
int min; /* Minutes (0-59) */
|
||||
int hour; /* Hour (0-23) */
|
||||
int dow; /* Day of the week (1-7) */
|
||||
int dom; /* Day of the month (1-31) */
|
||||
int month; /* Month of year (1-12) */
|
||||
int year; /* Year (0-99) */
|
||||
int sec; /* Seconds 0-59 */
|
||||
int min; /* Minutes 0-59 */
|
||||
int hour; /* Hour 0-23 */
|
||||
int dow; /* Day of the week 1-7 */
|
||||
int dom; /* Day of the month 1-31 */
|
||||
int month; /* Month of year 1-12 */
|
||||
int year; /* Year 0-99 */
|
||||
};
|
||||
|
||||
#define RTCGET _IOR('p', 20, struct sparc_rtc_time)
|
||||
#define RTCSET _IOW('p', 21, struct sparc_rtc_time)
|
||||
|
||||
|
||||
/* non-sparc stuff */
|
||||
#if 0
|
||||
#include <linux/version.h>
|
||||
/* Check if the /dev/rtc interface is available in this version of
|
||||
the system headers. 131072 is linux 2.0.0. */
|
||||
#if LINUX_VERSION_CODE >= 131072
|
||||
#include <linux/mc146818rtc.h>
|
||||
#endif
|
||||
# include <linux/version.h>
|
||||
/*
|
||||
* Check if the /dev/rtc interface is available in this version of the
|
||||
* system headers. 131072 is linux 2.0.0.
|
||||
*/
|
||||
# if LINUX_VERSION_CODE >= 131072
|
||||
# include <linux/mc146818rtc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* struct rtc_time is present since 1.3.99 */
|
||||
/* Earlier (since 1.3.89), a struct tm was used. */
|
||||
/*
|
||||
* struct rtc_time is present since 1.3.99.
|
||||
* Earlier (since 1.3.89), a struct tm was used.
|
||||
*/
|
||||
struct linux_rtc_time {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
};
|
||||
|
||||
/* RTC_RD_TIME etc have this definition since 1.99.9 (pre2.0-9) */
|
||||
#ifndef RTC_RD_TIME
|
||||
#define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_time)
|
||||
#define RTC_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time)
|
||||
#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
|
||||
#define RTC_UIE_OFF _IO('p', 0x04) /* Update int. enable off */
|
||||
#endif
|
||||
/* RTC_EPOCH_READ and RTC_EPOCH_SET are present since 2.0.34 and 2.1.89 */
|
||||
#ifndef RTC_EPOCH_READ
|
||||
#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
|
||||
#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
|
||||
# define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_time)
|
||||
# define RTC_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time)
|
||||
# define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
|
||||
# define RTC_UIE_OFF _IO('p', 0x04) /* Update int. enable off */
|
||||
#endif
|
||||
|
||||
/* /dev/rtc is conventionally chardev 10/135
|
||||
/* RTC_EPOCH_READ and RTC_EPOCH_SET are present since 2.0.34 and 2.1.89 */
|
||||
#ifndef RTC_EPOCH_READ
|
||||
# define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
|
||||
# define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* /dev/rtc is conventionally chardev 10/135
|
||||
* ia64 uses /dev/efirtc, chardev 10/136
|
||||
* devfs (obsolete) used /dev/misc/... for miscdev
|
||||
* new RTC framework + udev uses dynamic major and /dev/rtc0.../dev/rtcN
|
||||
|
@ -94,15 +102,15 @@ char *rtc_dev_name;
|
|||
|
||||
static int rtc_dev_fd = -1;
|
||||
|
||||
static void
|
||||
close_rtc(void) {
|
||||
static void close_rtc(void)
|
||||
{
|
||||
if (rtc_dev_fd != -1)
|
||||
close(rtc_dev_fd);
|
||||
rtc_dev_fd = -1;
|
||||
}
|
||||
|
||||
static int
|
||||
open_rtc(void) {
|
||||
static int open_rtc(void)
|
||||
{
|
||||
char *fls[] = {
|
||||
#ifdef __ia64__
|
||||
"/dev/efirtc",
|
||||
|
@ -122,10 +130,11 @@ open_rtc(void) {
|
|||
if (rtc_dev_name)
|
||||
rtc_dev_fd = open(rtc_dev_name, O_RDONLY);
|
||||
else {
|
||||
for (p=fls; *p; ++p) {
|
||||
for (p = fls; *p; ++p) {
|
||||
rtc_dev_fd = open(*p, O_RDONLY);
|
||||
|
||||
if (rtc_dev_fd < 0 && (errno == ENOENT || errno == ENODEV))
|
||||
if (rtc_dev_fd < 0
|
||||
&& (errno == ENOENT || errno == ENODEV))
|
||||
continue;
|
||||
rtc_dev_name = *p;
|
||||
break;
|
||||
|
@ -139,8 +148,8 @@ open_rtc(void) {
|
|||
return rtc_dev_fd;
|
||||
}
|
||||
|
||||
static int
|
||||
open_rtc_or_exit(void) {
|
||||
static int open_rtc_or_exit(void)
|
||||
{
|
||||
int rtc_fd = open_rtc();
|
||||
|
||||
if (rtc_fd < 0) {
|
||||
|
@ -150,8 +159,8 @@ open_rtc_or_exit(void) {
|
|||
return rtc_fd;
|
||||
}
|
||||
|
||||
static int
|
||||
do_rtc_read_ioctl(int rtc_fd, struct tm *tm) {
|
||||
static int do_rtc_read_ioctl(int rtc_fd, struct tm *tm)
|
||||
{
|
||||
int rc = -1;
|
||||
char *ioctlname;
|
||||
|
||||
|
@ -169,7 +178,7 @@ do_rtc_read_ioctl(int rtc_fd, struct tm *tm) {
|
|||
tm->tm_mon = stm.month - 1;
|
||||
tm->tm_year = stm.year - 1900;
|
||||
tm->tm_wday = stm.dow - 1;
|
||||
tm->tm_yday = -1; /* day in the year */
|
||||
tm->tm_yday = -1; /* day in the year */
|
||||
}
|
||||
#endif
|
||||
if (rc == -1) { /* no sparc, or RTCGET failed */
|
||||
|
@ -183,134 +192,153 @@ do_rtc_read_ioctl(int rtc_fd, struct tm *tm) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
tm->tm_isdst = -1; /* don't know whether it's dst */
|
||||
tm->tm_isdst = -1; /* don't know whether it's dst */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
busywait_for_rtc_clock_tick(const int rtc_fd) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
|
||||
we see it.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct tm start_time;
|
||||
/* The time when we were called (and started waiting) */
|
||||
struct tm nowtime;
|
||||
int rc;
|
||||
struct timeval begin, now;
|
||||
/*
|
||||
* Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
|
||||
* we see it.
|
||||
*/
|
||||
static int busywait_for_rtc_clock_tick(const int rtc_fd)
|
||||
{
|
||||
struct tm start_time;
|
||||
/* The time when we were called (and started waiting) */
|
||||
struct tm nowtime;
|
||||
int rc;
|
||||
struct timeval begin, now;
|
||||
|
||||
if (debug)
|
||||
printf(_("Waiting in loop for time from %s to change\n"),
|
||||
rtc_dev_name);
|
||||
if (debug)
|
||||
printf(_("Waiting in loop for time from %s to change\n"),
|
||||
rtc_dev_name);
|
||||
|
||||
rc = do_rtc_read_ioctl(rtc_fd, &start_time);
|
||||
if (rc)
|
||||
return 1;
|
||||
rc = do_rtc_read_ioctl(rtc_fd, &start_time);
|
||||
if (rc)
|
||||
return 1;
|
||||
|
||||
/* Wait for change. Should be within a second, but in case something
|
||||
* weird happens, we have a time limit (1.5s) on this loop to reduce the
|
||||
* impact of this failure.
|
||||
*/
|
||||
gettimeofday(&begin, NULL);
|
||||
do {
|
||||
rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
|
||||
if (rc || start_time.tm_sec != nowtime.tm_sec)
|
||||
break;
|
||||
gettimeofday(&now, NULL);
|
||||
if (time_diff(now, begin) > 1.5) {
|
||||
fprintf(stderr, _("Timed out waiting for time change.\n"));
|
||||
return 2;
|
||||
}
|
||||
} while(1);
|
||||
/*
|
||||
* Wait for change. Should be within a second, but in case
|
||||
* something weird happens, we have a time limit (1.5s) on this loop
|
||||
* to reduce the impact of this failure.
|
||||
*/
|
||||
gettimeofday(&begin, NULL);
|
||||
do {
|
||||
rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
|
||||
if (rc || start_time.tm_sec != nowtime.tm_sec)
|
||||
break;
|
||||
gettimeofday(&now, NULL);
|
||||
if (time_diff(now, begin) > 1.5) {
|
||||
fprintf(stderr,
|
||||
_("Timed out waiting for time change.\n"));
|
||||
return 2;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
if (rc)
|
||||
return 3;
|
||||
return 0;
|
||||
if (rc)
|
||||
return 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
synchronize_to_clock_tick_rtc(void) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Same as synchronize_to_clock_tick(), but just for /dev/rtc.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int rtc_fd; /* File descriptor of /dev/rtc */
|
||||
int ret;
|
||||
/*
|
||||
* Same as synchronize_to_clock_tick(), but just for /dev/rtc.
|
||||
*/
|
||||
static int synchronize_to_clock_tick_rtc(void)
|
||||
{
|
||||
int rtc_fd; /* File descriptor of /dev/rtc */
|
||||
int ret;
|
||||
|
||||
rtc_fd = open_rtc();
|
||||
if (rtc_fd == -1) {
|
||||
outsyserr(_("open() of %s failed"), rtc_dev_name);
|
||||
ret = 1;
|
||||
} else {
|
||||
int rc; /* Return code from ioctl */
|
||||
/* Turn on update interrupts (one per second) */
|
||||
rtc_fd = open_rtc();
|
||||
if (rtc_fd == -1) {
|
||||
outsyserr(_("open() of %s failed"), rtc_dev_name);
|
||||
ret = 1;
|
||||
} else {
|
||||
int rc; /* Return code from ioctl */
|
||||
/* Turn on update interrupts (one per second) */
|
||||
#if defined(__alpha__) || defined(__sparc__)
|
||||
/* Not all alpha kernels reject RTC_UIE_ON, but probably they should. */
|
||||
rc = -1;
|
||||
errno = EINVAL;
|
||||
/*
|
||||
* Not all alpha kernels reject RTC_UIE_ON, but probably
|
||||
* they should.
|
||||
*/
|
||||
rc = -1;
|
||||
errno = EINVAL;
|
||||
#else
|
||||
rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
|
||||
rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
|
||||
#endif
|
||||
if (rc == -1 && (errno == ENOTTY || errno == EINVAL)) {
|
||||
/* This rtc device doesn't have interrupt functions. This is typical
|
||||
on an Alpha, where the Hardware Clock interrupts are used by the
|
||||
kernel for the system clock, so aren't at the user's disposal.
|
||||
*/
|
||||
if (debug)
|
||||
printf(_("%s does not have interrupt functions. "),
|
||||
rtc_dev_name);
|
||||
ret = busywait_for_rtc_clock_tick(rtc_fd);
|
||||
} else if (rc == 0) {
|
||||
if (rc == -1 && (errno == ENOTTY || errno == EINVAL)) {
|
||||
/*
|
||||
* This rtc device doesn't have interrupt functions.
|
||||
* This is typical on an Alpha, where the Hardware
|
||||
* Clock interrupts are used by the kernel for the
|
||||
* system clock, so aren't at the user's disposal.
|
||||
*/
|
||||
if (debug)
|
||||
printf(_
|
||||
("%s does not have interrupt functions. "),
|
||||
rtc_dev_name);
|
||||
ret = busywait_for_rtc_clock_tick(rtc_fd);
|
||||
} else if (rc == 0) {
|
||||
#ifdef Wait_until_update_interrupt
|
||||
unsigned long dummy;
|
||||
unsigned long dummy;
|
||||
|
||||
/* this blocks until the next update interrupt */
|
||||
rc = read(rtc_fd, &dummy, sizeof(dummy));
|
||||
ret = 1;
|
||||
if (rc == -1)
|
||||
outsyserr(_("read() to %s to wait for clock tick failed"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
ret = 0;
|
||||
/* this blocks until the next update interrupt */
|
||||
rc = read(rtc_fd, &dummy, sizeof(dummy));
|
||||
ret = 1;
|
||||
if (rc == -1)
|
||||
outsyserr(_
|
||||
("read() to %s to wait for clock tick failed"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
ret = 0;
|
||||
#else
|
||||
/* Just reading rtc_fd fails on broken hardware: no update
|
||||
interrupt comes and a bootscript with a hwclock call hangs */
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
/*
|
||||
* Just reading rtc_fd fails on broken hardware: no
|
||||
* update interrupt comes and a bootscript with a
|
||||
* hwclock call hangs
|
||||
*/
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
/* Wait up to five seconds for the next update interrupt */
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(rtc_fd, &rfds);
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
|
||||
ret = 1;
|
||||
if (rc == -1)
|
||||
outsyserr(_("select() to %s to wait for clock tick failed"),
|
||||
rtc_dev_name);
|
||||
else if (rc == 0)
|
||||
fprintf(stderr, _("select() to %s to wait for clock tick timed out\n"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
ret = 0;
|
||||
/*
|
||||
* Wait up to five seconds for the next update
|
||||
* interrupt
|
||||
*/
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(rtc_fd, &rfds);
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
|
||||
ret = 1;
|
||||
if (rc == -1)
|
||||
outsyserr(_
|
||||
("select() to %s to wait for clock tick failed"),
|
||||
rtc_dev_name);
|
||||
else if (rc == 0)
|
||||
fprintf(stderr,
|
||||
_
|
||||
("select() to %s to wait for clock tick timed out\n"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
ret = 0;
|
||||
#endif
|
||||
|
||||
/* Turn off update interrupts */
|
||||
rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
|
||||
if (rc == -1)
|
||||
outsyserr(_("ioctl() to %s to turn off update interrupts failed"),
|
||||
rtc_dev_name);
|
||||
} else {
|
||||
outsyserr(_("ioctl() to %s to turn on update interrupts "
|
||||
"failed unexpectedly"), rtc_dev_name);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
/* Turn off update interrupts */
|
||||
rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
|
||||
if (rc == -1)
|
||||
outsyserr(_
|
||||
("ioctl() to %s to turn off update interrupts failed"),
|
||||
rtc_dev_name);
|
||||
} else {
|
||||
outsyserr(_
|
||||
("ioctl() to %s to turn on update interrupts "
|
||||
"failed unexpectedly"), rtc_dev_name);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_hardware_clock_rtc(struct tm *tm) {
|
||||
static int read_hardware_clock_rtc(struct tm *tm)
|
||||
{
|
||||
int rtc_fd, rc;
|
||||
|
||||
rtc_fd = open_rtc_or_exit();
|
||||
|
@ -321,13 +349,12 @@ read_hardware_clock_rtc(struct tm *tm) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
set_hardware_clock_rtc(const struct tm *new_broken_time) {
|
||||
/*-------------------------------------------------------------------------
|
||||
Set the Hardware Clock to the broken down time <new_broken_time>.
|
||||
Use ioctls to "rtc" device /dev/rtc.
|
||||
-------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Set the Hardware Clock to the broken down time <new_broken_time>. Use
|
||||
* ioctls to "rtc" device /dev/rtc.
|
||||
*/
|
||||
static int set_hardware_clock_rtc(const struct tm *new_broken_time)
|
||||
{
|
||||
int rc = -1;
|
||||
int rtc_fd;
|
||||
char *ioctlname;
|
||||
|
@ -368,9 +395,8 @@ set_hardware_clock_rtc(const struct tm *new_broken_time) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_permissions_rtc(void) {
|
||||
static int get_permissions_rtc(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -383,8 +409,8 @@ static struct clock_ops rtc = {
|
|||
};
|
||||
|
||||
/* return &rtc if /dev/rtc can be opened, NULL otherwise */
|
||||
struct clock_ops *
|
||||
probe_for_rtc_clock(){
|
||||
struct clock_ops *probe_for_rtc_clock()
|
||||
{
|
||||
int rtc_fd = open_rtc();
|
||||
if (rtc_fd >= 0)
|
||||
return &rtc;
|
||||
|
@ -393,85 +419,91 @@ probe_for_rtc_clock(){
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Hardware Clock epoch setting from the kernel.
|
||||
*/
|
||||
int get_epoch_rtc(unsigned long *epoch_p, int silent)
|
||||
{
|
||||
int rtc_fd;
|
||||
|
||||
rtc_fd = open_rtc();
|
||||
if (rtc_fd < 0) {
|
||||
if (!silent) {
|
||||
if (errno == ENOENT)
|
||||
fprintf(stderr,
|
||||
_
|
||||
("To manipulate the epoch value in the kernel, we must "
|
||||
"access the Linux 'rtc' device driver via the device special "
|
||||
"file %s. This file does not exist on this system.\n"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
outsyserr(_("Unable to open %s"), rtc_dev_name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
get_epoch_rtc(unsigned long *epoch_p, int silent) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Get the Hardware Clock epoch setting from the kernel.
|
||||
----------------------------------------------------------------------------*/
|
||||
int rtc_fd;
|
||||
if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
|
||||
if (!silent)
|
||||
outsyserr(_("ioctl(RTC_EPOCH_READ) to %s failed"),
|
||||
rtc_dev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rtc_fd = open_rtc();
|
||||
if (rtc_fd < 0) {
|
||||
if (!silent) {
|
||||
if (errno == ENOENT)
|
||||
fprintf(stderr, _(
|
||||
"To manipulate the epoch value in the kernel, we must "
|
||||
"access the Linux 'rtc' device driver via the device special "
|
||||
"file %s. This file does not exist on this system.\n"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
outsyserr(_("Unable to open %s"), rtc_dev_name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (debug)
|
||||
printf(_("we have read epoch %ld from %s "
|
||||
"with RTC_EPOCH_READ ioctl.\n"), *epoch_p,
|
||||
rtc_dev_name);
|
||||
|
||||
if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
|
||||
if (!silent)
|
||||
outsyserr(_("ioctl(RTC_EPOCH_READ) to %s failed"), rtc_dev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
printf(_("we have read epoch %ld from %s "
|
||||
"with RTC_EPOCH_READ ioctl.\n"), *epoch_p, rtc_dev_name);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the Hardware Clock epoch in the kernel.
|
||||
*/
|
||||
int set_epoch_rtc(unsigned long epoch)
|
||||
{
|
||||
int rtc_fd;
|
||||
|
||||
if (epoch < 1900) {
|
||||
/* kernel would not accept this epoch value
|
||||
*
|
||||
* Bad habit, deciding not to do what the user asks just
|
||||
* because one believes that the kernel might not like it.
|
||||
*/
|
||||
fprintf(stderr, _("The epoch value may not be less than 1900. "
|
||||
"You requested %ld\n"), epoch);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
set_epoch_rtc(unsigned long epoch) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Set the Hardware Clock epoch in the kernel.
|
||||
----------------------------------------------------------------------------*/
|
||||
int rtc_fd;
|
||||
rtc_fd = open_rtc();
|
||||
if (rtc_fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
fprintf(stderr,
|
||||
_
|
||||
("To manipulate the epoch value in the kernel, we must "
|
||||
"access the Linux 'rtc' device driver via the device special "
|
||||
"file %s. This file does not exist on this system.\n"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
outsyserr(_("Unable to open %s"), rtc_dev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (epoch < 1900) {
|
||||
/* kernel would not accept this epoch value */
|
||||
/* Hmm - bad habit, deciding not to do what the user asks
|
||||
just because one believes that the kernel might not like it. */
|
||||
fprintf(stderr, _("The epoch value may not be less than 1900. "
|
||||
"You requested %ld\n"), epoch);
|
||||
return 1;
|
||||
}
|
||||
if (debug)
|
||||
printf(_("setting epoch to %ld "
|
||||
"with RTC_EPOCH_SET ioctl to %s.\n"), epoch,
|
||||
rtc_dev_name);
|
||||
|
||||
rtc_fd = open_rtc();
|
||||
if (rtc_fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
fprintf(stderr, _("To manipulate the epoch value in the kernel, we must "
|
||||
"access the Linux 'rtc' device driver via the device special "
|
||||
"file %s. This file does not exist on this system.\n"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
outsyserr(_("Unable to open %s"), rtc_dev_name);
|
||||
return 1;
|
||||
}
|
||||
if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
|
||||
if (errno == EINVAL)
|
||||
fprintf(stderr, _("The kernel device driver for %s "
|
||||
"does not have the RTC_EPOCH_SET ioctl.\n"),
|
||||
rtc_dev_name);
|
||||
else
|
||||
outsyserr(_("ioctl(RTC_EPOCH_SET) to %s failed"),
|
||||
rtc_dev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
printf(_("setting epoch to %ld "
|
||||
"with RTC_EPOCH_SET ioctl to %s.\n"), epoch, rtc_dev_name);
|
||||
|
||||
if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
|
||||
if (errno == EINVAL)
|
||||
fprintf(stderr, _("The kernel device driver for %s "
|
||||
"does not have the RTC_EPOCH_SET ioctl.\n"), rtc_dev_name);
|
||||
else
|
||||
outsyserr(_("ioctl(RTC_EPOCH_SET) to %s failed"), rtc_dev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue