1 /* kd.c - KDGHWCLK stuff, possibly m68k only */
2 #include <unistd.h> /* for close() */
3 #include <fcntl.h> /* for O_RDONLY */
6 #include "../defines.h" /* for HAVE_nanosleep */
10 static int con_fd
= -1; /* opened by probe_for_kd_clock() */
13 /* Get defines for KDGHWCLK and KDSHWCLK (m68k) */
16 #define KDGHWCLK 0x4B50 /* get hardware clock */
17 #define KDSHWCLK 0x4B51 /* set hardware clock */
19 unsigned sec
; /* 0..59 */
20 unsigned min
; /* 0..59 */
21 unsigned hour
; /* 0..23 */
22 unsigned day
; /* 1..31 */
23 unsigned mon
; /* 0..11 */
24 unsigned year
; /* 70... */
25 int wday
; /* 0..6, 0 is Sunday, -1 means unknown/don't set */
30 synchronize_to_clock_tick_kd(void) {
31 /*----------------------------------------------------------------------------
32 Wait for the top of a clock tick by calling KDGHWCLK in a busy loop until
34 -----------------------------------------------------------------------------*/
37 /* The time when we were called (and started waiting) */
38 struct hwclk_time start_time
, nowtime
;
41 printf(_("Waiting in loop for time from KDGHWCLK to change\n"));
43 if (ioctl(con_fd
, KDGHWCLK
, &start_time
) == -1) {
44 outsyserr(_("KDGHWCLK ioctl to read time failed"));
50 /* Added by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
51 /* "The culprit is the fast loop with KDGHWCLK ioctls. It seems
52 the kernel gets confused by those on Amigas with A2000 RTCs
53 and simply hangs after some time. Inserting a nanosleep helps." */
54 /* Christian T. Steigies: 1 instead of 1000000 is still sufficient
55 to keep the machine from freezing. */
58 struct timespec sleep
= { 0, 1 };
59 nanosleep( &sleep
, NULL
);
65 fprintf(stderr
, _("Timed out waiting for time change.\n"));
68 if (ioctl(con_fd
, KDGHWCLK
, &nowtime
) == -1) {
69 outsyserr(_("KDGHWCLK ioctl to read time failed in loop"));
72 } while (start_time
.sec
== nowtime
.sec
);
79 read_hardware_clock_kd(struct tm
*tm
) {
80 /*----------------------------------------------------------------------------
81 Read the hardware clock and return the current time via <tm>
82 argument. Use ioctls to /dev/tty1 on what we assume is an m68k
85 Note that we don't use /dev/console here. That might be a serial
87 -----------------------------------------------------------------------------*/
90 if (ioctl(con_fd
, KDGHWCLK
, &t
) == -1) {
91 outsyserr(_("ioctl() failed to read time from /dev/tty1"));
100 tm
->tm_year
= t
.year
;
101 tm
->tm_wday
= t
.wday
;
102 tm
->tm_isdst
= -1; /* Don't know if it's Daylight Savings Time */
109 set_hardware_clock_kd(const struct tm
*new_broken_time
) {
110 /*----------------------------------------------------------------------------
111 Set the Hardware Clock to the time <new_broken_time>. Use ioctls to
112 /dev/tty1 on what we assume is an m68k machine.
114 Note that we don't use /dev/console here. That might be a serial console.
115 ----------------------------------------------------------------------------*/
118 t
.sec
= new_broken_time
->tm_sec
;
119 t
.min
= new_broken_time
->tm_min
;
120 t
.hour
= new_broken_time
->tm_hour
;
121 t
.day
= new_broken_time
->tm_mday
;
122 t
.mon
= new_broken_time
->tm_mon
;
123 t
.year
= new_broken_time
->tm_year
;
124 t
.wday
= new_broken_time
->tm_wday
;
126 if (ioctl(con_fd
, KDSHWCLK
, &t
) == -1) {
127 outsyserr(_("ioctl() to open /dev/tty1 failed"));
134 get_permissions_kd(void) {
138 static struct clock_ops kd
= {
139 "KDGHWCLK interface to m68k clock",
141 read_hardware_clock_kd
,
142 set_hardware_clock_kd
,
143 synchronize_to_clock_tick_kd
,
146 /* return &kd if KDGHWCLK works, NULL otherwise */
148 probe_for_kd_clock() {
149 struct clock_ops
*ret
= NULL
;
153 con_fd
= open("/dev/tty1", O_RDONLY
);
155 if (ioctl( con_fd
, KDGHWCLK
, &t
) == -1) {
157 outsyserr(_("KDGHWCLK ioctl failed"));
161 /* probably KDGHWCLK exists on m68k only */
163 outsyserr(_("Can't open /dev/tty1"));