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:
Sami Kerola 2011-07-24 17:35:43 +02:00
parent 7d8ee8dad5
commit ef71b8f112
5 changed files with 2102 additions and 2010 deletions

View File

@ -1,20 +1,20 @@
#ifndef HWCLOCK_CLOCK_H #ifndef HWCLOCK_CLOCK_H
#define HWCLOCK_CLOCK_H #define HWCLOCK_CLOCK_H
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> /* for errno, EPERM, EINVAL, ENOENT */
#include <time.h> #include <time.h>
#include "c.h" #include "c.h"
struct clock_ops { struct clock_ops {
char *interface_name; char *interface_name;
int (*get_permissions)(void); int (*get_permissions) (void);
int (*read_hardware_clock)(struct tm *tm); int (*read_hardware_clock) (struct tm * tm);
int (*set_hardware_clock)(const struct tm *tm); int (*set_hardware_clock) (const struct tm * tm);
int (*synchronize_to_clock_tick)(void); int (*synchronize_to_clock_tick) (void);
}; };
extern struct clock_ops *probe_for_cmos_clock(void); extern struct clock_ops *probe_for_cmos_clock(void);
@ -29,9 +29,9 @@ extern int debug;
extern int epoch_option; extern int epoch_option;
extern void outsyserr(char *msg, ...) extern void outsyserr(char *msg, ...)
#ifdef __GNUC__ #ifdef __GNUC__
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format(printf, 1, 2)));
#else #else
; ;
#endif #endif
extern double time_diff(struct timeval subtrahend, struct timeval subtractor); extern double time_diff(struct timeval subtrahend, struct timeval subtractor);
/* cmos.c */ /* cmos.c */
@ -50,4 +50,4 @@ extern void hwaudit_exit(int status);
# define hwclock_exit(_status) exit(_status) # define hwclock_exit(_status) exit(_status)
#endif #endif
#endif /* HWCLOCK_CLOCK_H */ #endif /* HWCLOCK_CLOCK_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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" #include "clock.h"
#ifdef __m68k__ #ifdef __m68k__
#include <unistd.h> /* for close() */ # include <unistd.h> /* for close() */
#include <fcntl.h> /* for O_RDONLY */ # include <fcntl.h> /* for O_RDONLY */
#include <sysexits.h> # include <sysexits.h>
#include <sys/ioctl.h> # include <sys/ioctl.h>
#include "nls.h" # include "nls.h"
#include "usleep.h" # include "usleep.h"
/* Get defines for KDGHWCLK and KDSHWCLK (m68k) */ /* 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 */ /* Even on m68k, if KDGHWCLK (antique) is not defined, don't build this */
@ -21,124 +23,126 @@
#if !defined(__m68k__) || !defined(KDGHWCLK) #if !defined(__m68k__) || !defined(KDGHWCLK)
struct clock_ops * struct clock_ops *probe_for_kd_clock()
probe_for_kd_clock() { {
return NULL; return NULL;
} }
#else /* __m68k__ && KDGHWCLK */ #else /* __m68k__ && KDGHWCLK */
static int con_fd = -1; /* opened by probe_for_kd_clock() */ /* Opened by probe_for_kd_clock(), and never closed. */
/* never closed */ static int con_fd = -1;
static char *con_fd_filename; /* usually "/dev/tty1" */ 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) */ if (debug)
struct hwclk_time start_time, nowtime; printf(_("Waiting in loop for time from KDGHWCLK to change\n"));
struct timeval begin, now;
if (debug) if (ioctl(con_fd, KDGHWCLK, &start_time) == -1) {
printf(_("Waiting in loop for time from KDGHWCLK to change\n")); outsyserr(_("KDGHWCLK ioctl to read time failed"));
return 3;
}
if (ioctl(con_fd, KDGHWCLK, &start_time) == -1) { /*
outsyserr(_("KDGHWCLK ioctl to read time failed")); * Wait for change. Should be within a second, but in case something
return 3; * 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 if (ioctl(con_fd, KDGHWCLK, &nowtime) == -1) {
* weird happens, we have a time limit (1.5s) on this loop to reduce the outsyserr(_
* impact of this failure. ("KDGHWCLK ioctl to read time failed in loop"));
*/ return 3;
gettimeofday(&begin, NULL); }
do { if (start_time.tm_sec != nowtime.tm_sec)
/* Added by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> break;
* "The culprit is the fast loop with KDGHWCLK ioctls. It seems gettimeofday(&now, NULL);
* the kernel gets confused by those on Amigas with A2000 RTCs if (time_diff(now, begin) > 1.5) {
* and simply hangs after some time. Inserting a sleep helps." fprintf(stderr,
*/ _("Timed out waiting for time change.\n"));
usleep(1); return 2;
}
} while (1);
if (ioctl(con_fd, KDGHWCLK, &nowtime) == -1) { return 0;
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;
} }
/*
* 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 if (ioctl(con_fd, KDGHWCLK, &t) == -1) {
read_hardware_clock_kd(struct tm *tm) { outsyserr(_("ioctl() failed to read time from %s"),
/*---------------------------------------------------------------------------- con_fd_filename);
Read the hardware clock and return the current time via <tm> hwclock_exit(EX_IOERR);
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 tm->tm_sec = t.sec;
console. tm->tm_min = t.min;
-----------------------------------------------------------------------------*/ tm->tm_hour = t.hour;
struct hwclk_time t; 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) { return 0;
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;
} }
/*
* 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 t.sec = new_broken_time->tm_sec;
set_hardware_clock_kd(const struct tm *new_broken_time) { t.min = new_broken_time->tm_min;
/*---------------------------------------------------------------------------- t.hour = new_broken_time->tm_hour;
Set the Hardware Clock to the time <new_broken_time>. Use ioctls to t.day = new_broken_time->tm_mday;
/dev/tty1 on what we assume is an m68k machine. 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. if (ioctl(con_fd, KDSHWCLK, &t) == -1) {
----------------------------------------------------------------------------*/ outsyserr(_("ioctl KDSHWCLK failed"));
struct hwclk_time t; hwclock_exit(1);
}
t.sec = new_broken_time->tm_sec; return 0;
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;
} }
static int static int get_permissions_kd(void)
get_permissions_kd(void) { {
return 0; return 0;
} }
static struct clock_ops kd = { static struct clock_ops kd = {
@ -150,8 +154,8 @@ static struct clock_ops kd = {
}; };
/* return &kd if KDGHWCLK works, NULL otherwise */ /* return &kd if KDGHWCLK works, NULL otherwise */
struct clock_ops * struct clock_ops *probe_for_kd_clock()
probe_for_kd_clock() { {
struct clock_ops *ret = NULL; struct clock_ops *ret = NULL;
struct hwclk_time t; struct hwclk_time t;
@ -176,4 +180,4 @@ probe_for_kd_clock() {
} }
return ret; return ret;
} }
#endif /* __m68k__ && KDGHWCLK */ #endif /* __m68k__ && KDGHWCLK */

View File

@ -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 <unistd.h> /* for close() */
#include <fcntl.h> /* for O_RDONLY */ #include <fcntl.h> /* for O_RDONLY */
#include <errno.h> #include <errno.h>
@ -12,77 +14,83 @@
/* /*
* Get defines for rtc stuff. * Get defines for rtc stuff.
* *
* Getting the rtc defines is nontrivial. * Getting the rtc defines is nontrivial. The obvious way is by including
* The obvious way is by including <linux/mc146818rtc.h> * <linux/mc146818rtc.h> but that again includes <asm/io.h> which again
* but that again includes <asm/io.h> which again includes ... * includes ... and on sparc and alpha this gives compilation errors for
* and on sparc and alpha this gives compilation errors for * many kernel versions. So, we give the defines ourselves here. Moreover,
* many kernel versions. So, we give the defines ourselves here. * some Sparc person decided to be incompatible, and used a struct rtc_time
* Moreover, some Sparc person decided to be incompatible, and * different from that used in mc146818rtc.h.
* 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 * On Sparcs, there is a <asm/rtc.h> that defines different ioctls (that are
does not exist on other architectures. */ * required on my machine). However, this include file does not exist on
* other architectures.
*/
/* One might do: /* One might do:
#ifdef __sparc__ #ifdef __sparc__
#include <asm/rtc.h> # include <asm/rtc.h>
#endif #endif
*/ */
/* The following is roughly equivalent */ /* The following is roughly equivalent */
struct sparc_rtc_time struct sparc_rtc_time
{ {
int sec; /* Seconds (0-59) */ int sec; /* Seconds 0-59 */
int min; /* Minutes (0-59) */ int min; /* Minutes 0-59 */
int hour; /* Hour (0-23) */ int hour; /* Hour 0-23 */
int dow; /* Day of the week (1-7) */ int dow; /* Day of the week 1-7 */
int dom; /* Day of the month (1-31) */ int dom; /* Day of the month 1-31 */
int month; /* Month of year (1-12) */ int month; /* Month of year 1-12 */
int year; /* Year (0-99) */ int year; /* Year 0-99 */
}; };
#define RTCGET _IOR('p', 20, struct sparc_rtc_time) #define RTCGET _IOR('p', 20, struct sparc_rtc_time)
#define RTCSET _IOW('p', 21, struct sparc_rtc_time) #define RTCSET _IOW('p', 21, struct sparc_rtc_time)
/* non-sparc stuff */ /* non-sparc stuff */
#if 0 #if 0
#include <linux/version.h> # 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. */ * Check if the /dev/rtc interface is available in this version of the
#if LINUX_VERSION_CODE >= 131072 * system headers. 131072 is linux 2.0.0.
#include <linux/mc146818rtc.h> */
#endif # if LINUX_VERSION_CODE >= 131072
# include <linux/mc146818rtc.h>
# endif
#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 { struct linux_rtc_time {
int tm_sec; int tm_sec;
int tm_min; int tm_min;
int tm_hour; int tm_hour;
int tm_mday; int tm_mday;
int tm_mon; int tm_mon;
int tm_year; int tm_year;
int tm_wday; int tm_wday;
int tm_yday; int tm_yday;
int tm_isdst; int tm_isdst;
}; };
/* RTC_RD_TIME etc have this definition since 1.99.9 (pre2.0-9) */ /* RTC_RD_TIME etc have this definition since 1.99.9 (pre2.0-9) */
#ifndef RTC_RD_TIME #ifndef RTC_RD_TIME
#define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_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_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time)
#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */ # define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
#define RTC_UIE_OFF _IO('p', 0x04) /* Update int. enable off */ # 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 */
#endif #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 * ia64 uses /dev/efirtc, chardev 10/136
* devfs (obsolete) used /dev/misc/... for miscdev * devfs (obsolete) used /dev/misc/... for miscdev
* new RTC framework + udev uses dynamic major and /dev/rtc0.../dev/rtcN * 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 int rtc_dev_fd = -1;
static void static void close_rtc(void)
close_rtc(void) { {
if (rtc_dev_fd != -1) if (rtc_dev_fd != -1)
close(rtc_dev_fd); close(rtc_dev_fd);
rtc_dev_fd = -1; rtc_dev_fd = -1;
} }
static int static int open_rtc(void)
open_rtc(void) { {
char *fls[] = { char *fls[] = {
#ifdef __ia64__ #ifdef __ia64__
"/dev/efirtc", "/dev/efirtc",
@ -122,10 +130,11 @@ open_rtc(void) {
if (rtc_dev_name) if (rtc_dev_name)
rtc_dev_fd = open(rtc_dev_name, O_RDONLY); rtc_dev_fd = open(rtc_dev_name, O_RDONLY);
else { else {
for (p=fls; *p; ++p) { for (p = fls; *p; ++p) {
rtc_dev_fd = open(*p, O_RDONLY); 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; continue;
rtc_dev_name = *p; rtc_dev_name = *p;
break; break;
@ -139,8 +148,8 @@ open_rtc(void) {
return rtc_dev_fd; return rtc_dev_fd;
} }
static int static int open_rtc_or_exit(void)
open_rtc_or_exit(void) { {
int rtc_fd = open_rtc(); int rtc_fd = open_rtc();
if (rtc_fd < 0) { if (rtc_fd < 0) {
@ -150,8 +159,8 @@ open_rtc_or_exit(void) {
return rtc_fd; return rtc_fd;
} }
static int static int do_rtc_read_ioctl(int rtc_fd, struct tm *tm)
do_rtc_read_ioctl(int rtc_fd, struct tm *tm) { {
int rc = -1; int rc = -1;
char *ioctlname; char *ioctlname;
@ -169,7 +178,7 @@ do_rtc_read_ioctl(int rtc_fd, struct tm *tm) {
tm->tm_mon = stm.month - 1; tm->tm_mon = stm.month - 1;
tm->tm_year = stm.year - 1900; tm->tm_year = stm.year - 1900;
tm->tm_wday = stm.dow - 1; tm->tm_wday = stm.dow - 1;
tm->tm_yday = -1; /* day in the year */ tm->tm_yday = -1; /* day in the year */
} }
#endif #endif
if (rc == -1) { /* no sparc, or RTCGET failed */ if (rc == -1) { /* no sparc, or RTCGET failed */
@ -183,134 +192,153 @@ do_rtc_read_ioctl(int rtc_fd, struct tm *tm) {
return -1; 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; 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.
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; struct tm start_time;
/* The time when we were called (and started waiting) */ /* The time when we were called (and started waiting) */
struct tm nowtime; struct tm nowtime;
int rc; int rc;
struct timeval begin, now; struct timeval begin, now;
if (debug) if (debug)
printf(_("Waiting in loop for time from %s to change\n"), printf(_("Waiting in loop for time from %s to change\n"),
rtc_dev_name); rtc_dev_name);
rc = do_rtc_read_ioctl(rtc_fd, &start_time); rc = do_rtc_read_ioctl(rtc_fd, &start_time);
if (rc) if (rc)
return 1; 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 * Wait for change. Should be within a second, but in case
* impact of this failure. * something weird happens, we have a time limit (1.5s) on this loop
*/ * to reduce the impact of this failure.
gettimeofday(&begin, NULL); */
do { gettimeofday(&begin, NULL);
rc = do_rtc_read_ioctl(rtc_fd, &nowtime); do {
if (rc || start_time.tm_sec != nowtime.tm_sec) rc = do_rtc_read_ioctl(rtc_fd, &nowtime);
break; if (rc || start_time.tm_sec != nowtime.tm_sec)
gettimeofday(&now, NULL); break;
if (time_diff(now, begin) > 1.5) { gettimeofday(&now, NULL);
fprintf(stderr, _("Timed out waiting for time change.\n")); if (time_diff(now, begin) > 1.5) {
return 2; fprintf(stderr,
} _("Timed out waiting for time change.\n"));
} while(1); return 2;
}
} while (1);
if (rc) if (rc)
return 3; return 3;
return 0; return 0;
} }
static int /*
synchronize_to_clock_tick_rtc(void) { * Same as synchronize_to_clock_tick(), but just for /dev/rtc.
/*---------------------------------------------------------------------------- */
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 rtc_fd; /* File descriptor of /dev/rtc */
int ret; int ret;
rtc_fd = open_rtc(); rtc_fd = open_rtc();
if (rtc_fd == -1) { if (rtc_fd == -1) {
outsyserr(_("open() of %s failed"), rtc_dev_name); outsyserr(_("open() of %s failed"), rtc_dev_name);
ret = 1; ret = 1;
} else { } else {
int rc; /* Return code from ioctl */ int rc; /* Return code from ioctl */
/* Turn on update interrupts (one per second) */ /* Turn on update interrupts (one per second) */
#if defined(__alpha__) || defined(__sparc__) #if defined(__alpha__) || defined(__sparc__)
/* Not all alpha kernels reject RTC_UIE_ON, but probably they should. */ /*
rc = -1; * Not all alpha kernels reject RTC_UIE_ON, but probably
errno = EINVAL; * they should.
*/
rc = -1;
errno = EINVAL;
#else #else
rc = ioctl(rtc_fd, RTC_UIE_ON, 0); rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
#endif #endif
if (rc == -1 && (errno == ENOTTY || errno == EINVAL)) { 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 * This rtc device doesn't have interrupt functions.
kernel for the system clock, so aren't at the user's disposal. * This is typical on an Alpha, where the Hardware
*/ * Clock interrupts are used by the kernel for the
if (debug) * system clock, so aren't at the user's disposal.
printf(_("%s does not have interrupt functions. "), */
rtc_dev_name); if (debug)
ret = busywait_for_rtc_clock_tick(rtc_fd); printf(_
} else if (rc == 0) { ("%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 #ifdef Wait_until_update_interrupt
unsigned long dummy; unsigned long dummy;
/* this blocks until the next update interrupt */ /* this blocks until the next update interrupt */
rc = read(rtc_fd, &dummy, sizeof(dummy)); rc = read(rtc_fd, &dummy, sizeof(dummy));
ret = 1; ret = 1;
if (rc == -1) if (rc == -1)
outsyserr(_("read() to %s to wait for clock tick failed"), outsyserr(_
rtc_dev_name); ("read() to %s to wait for clock tick failed"),
else rtc_dev_name);
ret = 0; else
ret = 0;
#else #else
/* Just reading rtc_fd fails on broken hardware: no update /*
interrupt comes and a bootscript with a hwclock call hangs */ * Just reading rtc_fd fails on broken hardware: no
fd_set rfds; * update interrupt comes and a bootscript with a
struct timeval tv; * hwclock call hangs
*/
fd_set rfds;
struct timeval tv;
/* Wait up to five seconds for the next update interrupt */ /*
FD_ZERO(&rfds); * Wait up to five seconds for the next update
FD_SET(rtc_fd, &rfds); * interrupt
tv.tv_sec = 5; */
tv.tv_usec = 0; FD_ZERO(&rfds);
rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv); FD_SET(rtc_fd, &rfds);
ret = 1; tv.tv_sec = 5;
if (rc == -1) tv.tv_usec = 0;
outsyserr(_("select() to %s to wait for clock tick failed"), rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
rtc_dev_name); ret = 1;
else if (rc == 0) if (rc == -1)
fprintf(stderr, _("select() to %s to wait for clock tick timed out\n"), outsyserr(_
rtc_dev_name); ("select() to %s to wait for clock tick failed"),
else rtc_dev_name);
ret = 0; else if (rc == 0)
fprintf(stderr,
_
("select() to %s to wait for clock tick timed out\n"),
rtc_dev_name);
else
ret = 0;
#endif #endif
/* Turn off update interrupts */ /* Turn off update interrupts */
rc = ioctl(rtc_fd, RTC_UIE_OFF, 0); rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
if (rc == -1) if (rc == -1)
outsyserr(_("ioctl() to %s to turn off update interrupts failed"), outsyserr(_
rtc_dev_name); ("ioctl() to %s to turn off update interrupts failed"),
} else { rtc_dev_name);
outsyserr(_("ioctl() to %s to turn on update interrupts " } else {
"failed unexpectedly"), rtc_dev_name); outsyserr(_
ret = 1; ("ioctl() to %s to turn on update interrupts "
} "failed unexpectedly"), rtc_dev_name);
} ret = 1;
return ret; }
}
return ret;
} }
static int read_hardware_clock_rtc(struct tm *tm)
static int {
read_hardware_clock_rtc(struct tm *tm) {
int rtc_fd, rc; int rtc_fd, rc;
rtc_fd = open_rtc_or_exit(); rtc_fd = open_rtc_or_exit();
@ -321,13 +349,12 @@ read_hardware_clock_rtc(struct tm *tm) {
return rc; return rc;
} }
/*
static int * Set the Hardware Clock to the broken down time <new_broken_time>. Use
set_hardware_clock_rtc(const struct tm *new_broken_time) { * ioctls to "rtc" device /dev/rtc.
/*------------------------------------------------------------------------- */
Set the Hardware Clock to the broken down time <new_broken_time>. static int set_hardware_clock_rtc(const struct tm *new_broken_time)
Use ioctls to "rtc" device /dev/rtc. {
-------------------------------------------------------------------------*/
int rc = -1; int rc = -1;
int rtc_fd; int rtc_fd;
char *ioctlname; char *ioctlname;
@ -368,9 +395,8 @@ set_hardware_clock_rtc(const struct tm *new_broken_time) {
return 0; return 0;
} }
static int get_permissions_rtc(void)
static int {
get_permissions_rtc(void) {
return 0; return 0;
} }
@ -383,8 +409,8 @@ static struct clock_ops rtc = {
}; };
/* return &rtc if /dev/rtc can be opened, NULL otherwise */ /* return &rtc if /dev/rtc can be opened, NULL otherwise */
struct clock_ops * struct clock_ops *probe_for_rtc_clock()
probe_for_rtc_clock(){ {
int rtc_fd = open_rtc(); int rtc_fd = open_rtc();
if (rtc_fd >= 0) if (rtc_fd >= 0)
return &rtc; return &rtc;
@ -393,85 +419,91 @@ probe_for_rtc_clock(){
return NULL; 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 if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
get_epoch_rtc(unsigned long *epoch_p, int silent) { if (!silent)
/*---------------------------------------------------------------------------- outsyserr(_("ioctl(RTC_EPOCH_READ) to %s failed"),
Get the Hardware Clock epoch setting from the kernel. rtc_dev_name);
----------------------------------------------------------------------------*/ return 1;
int rtc_fd; }
rtc_fd = open_rtc(); if (debug)
if (rtc_fd < 0) { printf(_("we have read epoch %ld from %s "
if (!silent) { "with RTC_EPOCH_READ ioctl.\n"), *epoch_p,
if (errno == ENOENT) rtc_dev_name);
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_READ, epoch_p) == -1) { return 0;
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;
} }
/*
* 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 rtc_fd = open_rtc();
set_epoch_rtc(unsigned long epoch) { if (rtc_fd < 0) {
/*---------------------------------------------------------------------------- if (errno == ENOENT)
Set the Hardware Clock epoch in the kernel. fprintf(stderr,
----------------------------------------------------------------------------*/ _
int rtc_fd; ("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) { if (debug)
/* kernel would not accept this epoch value */ printf(_("setting epoch to %ld "
/* Hmm - bad habit, deciding not to do what the user asks "with RTC_EPOCH_SET ioctl to %s.\n"), epoch,
just because one believes that the kernel might not like it. */ rtc_dev_name);
fprintf(stderr, _("The epoch value may not be less than 1900. "
"You requested %ld\n"), epoch);
return 1;
}
rtc_fd = open_rtc(); if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
if (rtc_fd < 0) { if (errno == EINVAL)
if (errno == ENOENT) fprintf(stderr, _("The kernel device driver for %s "
fprintf(stderr, _("To manipulate the epoch value in the kernel, we must " "does not have the RTC_EPOCH_SET ioctl.\n"),
"access the Linux 'rtc' device driver via the device special " rtc_dev_name);
"file %s. This file does not exist on this system.\n"), else
rtc_dev_name); outsyserr(_("ioctl(RTC_EPOCH_SET) to %s failed"),
else rtc_dev_name);
outsyserr(_("Unable to open %s"), rtc_dev_name); return 1;
return 1; }
}
if (debug) return 0;
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;
} }