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
|
#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 */
|
||||||
|
|
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"
|
#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 */
|
||||||
|
|
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 <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;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue