diff options
Diffstat (limited to 'clockB/kd.c')
-rw-r--r-- | clockB/kd.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/clockB/kd.c b/clockB/kd.c new file mode 100644 index 000000000..68287cb54 --- /dev/null +++ b/clockB/kd.c @@ -0,0 +1,219 @@ +/************************************************************************** + + This is a component of the hwclock program. + + This file contains the code for accessing the hardware clock via + the KDHWCLK facility of M68k machines. + +****************************************************************************/ + +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "hwclock.h" + + + +#if defined(KDGHWCLK) +const bool got_kdghwclk = TRUE; +static const int kdghwclk_ioctl = KDGHWCLK; +static const int kdshwclk_ioctl = KDSHWCLK; +#else +const bool got_kdghwclk = FALSE; +static const int kdghwclk_ioctl; /* Never used; just to make compile work */ +struct hwclk_time {int sec;}; + /* Never used; just to make compile work */ +#endif + + +void +synchronize_to_clock_tick_KD(int *retcode_p) { +/*---------------------------------------------------------------------------- + Wait for the top of a clock tick by calling KDGHWCLK in a busy loop until + we see it. +-----------------------------------------------------------------------------*/ + int con_fd; + + if (debug) + printf("Waiting in loop for time from KDGHWCLK to change\n"); + + con_fd = open("/dev/tty1", O_RDONLY); + if (con_fd < 0) { + fprintf(stderr, "%s: open() failed to open /dev/tty1, errno = %s (%d).\n", + MYNAME, strerror(errno), errno); + *retcode_p = 1; + } else { + int rc; /* return code from ioctl() */ + int i; /* local loop index */ + /* The time when we were called (and started waiting) */ + struct hwclk_time start_time, nowtime; + + rc = ioctl(con_fd, kdghwclk_ioctl, &start_time); + if (rc == -1) { + fprintf(stderr, "%s: KDGHWCLK to read time failed, " + "errno = %s (%d).\n", MYNAME, strerror(errno), errno); + *retcode_p = 3; + } + + for (i = 0; + (rc = ioctl(con_fd, kdghwclk_ioctl, &nowtime)) != -1 + && start_time.sec == nowtime.sec && i < 1000000; + i++); + if (i >= 1000000) { + fprintf(stderr, "%s: Timed out waiting for time change.\n", MYNAME); + *retcode_p = 2; + } else if (rc == -1) { + fprintf(stderr, "%s: KDGHWCLK to read time failed, " + "errno = %s (%d).\n", MYNAME, strerror(errno), errno); + *retcode_p = 3; + } else *retcode_p = 0; + close(con_fd); + } +} + + + +void +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. + + Note that we don't use /dev/console here. That might be a serial + console. +-----------------------------------------------------------------------------*/ +#ifdef KDGHWCLK + int con_fd; + struct hwclk_time t; + + con_fd = open("/dev/tty1", O_RDONLY); + if (con_fd < 0) { + fprintf(stderr, "%s: open() failed to open /dev/tty1, errno = %s (%d).\n", + MYNAME, strerror(errno), errno); + exit(5); + } else { + int rc; /* return code from ioctl() */ + + rc = ioctl(con_fd, kdghwclk_ioctl, &t); + if (rc == -1) { + fprintf(stderr, "%s: ioctl() failed to read time from /dev/tty1, " + "errno = %s (%d).\n", + MYNAME, strerror(errno), errno); + exit(5); + } + close(con_fd); + } + + 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 */ +#else + /* This routine should never be invoked. It is here just to make the + program compile. + */ +#endif +} + + + +void +set_hardware_clock_kd(const struct tm new_broken_time, + const bool testing) { +/*---------------------------------------------------------------------------- + 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. +----------------------------------------------------------------------------*/ +#ifdef KDGHWCLK + int con_fd; /* File descriptor of /dev/tty1 */ + struct hwclk_time t; + + con_fd = open("/dev/tty1", O_RDONLY); + if (con_fd < 0) { + fprintf(stderr, "%s: Error opening /dev/tty1. Errno: %s (%d)\n", + MYNAME, strerror(errno), errno); + exit(1); + } else { + int rc; /* locally used return code */ + + 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 (testing) + printf("Not setting Hardware Clock because running in test mode.\n"); + else { + rc = ioctl(con_fd, kdshwclk_ioctl, &t ); + if (rc < 0) { + fprintf(stderr, "%s: ioctl() to open /dev/tty1 failed. " + "Errno: %s (%d)\n", + MYNAME, strerror(errno), errno); + exit(1); + } + } + close(con_fd); + } +#else + /* This function should never be invoked. It is here just to make the + program compile. + */ +#endif +} + + + +void +see_if_kdghwclk_works(bool * const kdghwclk_works_p) { +/*---------------------------------------------------------------------------- + Find out if we are capable of accessing the Hardware Clock via the + KDHWCLK facility (ioctl to /dev/tty1). +-----------------------------------------------------------------------------*/ + if (got_kdghwclk) { + int con_fd; + struct hwclk_time t; + + con_fd = open("/dev/tty1", O_RDONLY); + if (con_fd >= 0) { + if (ioctl( con_fd, kdghwclk_ioctl, &t ) >= 0) + *kdghwclk_works_p = TRUE; + else { + if (errno == EINVAL) { + /* KDGHWCLK not implemented in this kernel... */ + *kdghwclk_works_p = FALSE; + if (debug) + printf(MYNAME "was built with KDGHWCLK capability, but the " + "ioctl does not exist in the kernel. The ioctl (to " + "/dev/tty1) failed with errno EINVAL.\n"); + } else { + *kdghwclk_works_p = FALSE; + fprintf(stderr, + "%s: KDGHWCLK ioctl failed, errno = %s (%d).\n", + MYNAME, strerror(errno), errno); + } + } + } else { + *kdghwclk_works_p = FALSE; + fprintf(stderr, + "%s: Can't open /dev/tty1. open() errno = %s (%d).\n", + MYNAME, strerror(errno), errno); + } + close(con_fd); + } else *kdghwclk_works_p = FALSE; +} + + + |