2 * Some real time clocks are embedded within other multi-function chips.
3 * Drivers for such chips will implement the RTCDEV protocol and the
4 * readclock driver will simply forward on the message to the driver.
5 * This keeps things simple for any other services that need to access
6 * the RTC as they only have to know / care about the readclock driver.
9 #include <minix/syslib.h>
10 #include <minix/drvlib.h>
11 #include <minix/sysutil.h>
12 #include <minix/log.h>
15 #include <minix/safecopies.h>
18 #include <sys/types.h>
30 #include "readclock.h"
32 static int fwd_msg(int type
, struct tm
*t
, int t_access
, int flags
);
34 static struct log log
= {
35 .name
= "readclock.fwd",
36 .log_level
= LEVEL_INFO
,
37 .log_func
= default_log
41 * Label of the driver that messages should be forwarded to.
43 static char *target_label
;
46 fwd_set_label(char *label
)
55 if (target_label
== NULL
) {
62 fwd_msg(int type
, struct tm
*t
, int t_access
, int flags
)
69 r
= ds_retrieve_label_endpt(target_label
, &ep
);
74 if (type
== RTCDEV_PWR_OFF
) {
75 /* RTCDEV_PWR_OFF messages don't contain any data/flags. */
76 return _syscall(ep
, RTCDEV_PWR_OFF
, &m
);
79 gid
= cpf_grant_direct(ep
, (vir_bytes
) t
, sizeof(struct tm
), t_access
);
80 if (!GRANT_VALID(gid
)) {
81 log_warn(&log
, "Could not create grant.\n");
85 m
.m_lc_readclock_rtcdev
.grant
= gid
;
86 m
.m_lc_readclock_rtcdev
.flags
= flags
;
88 r
= _syscall(ep
, type
, &m
);
90 if (r
!= RTCDEV_REPLY
|| m
.m_readclock_lc_rtcdev
.status
!= 0) {
91 log_warn(&log
, "Call to '%s' failed.\n", target_label
);
99 fwd_get_time(struct tm
*t
, int flags
)
101 return fwd_msg(RTCDEV_GET_TIME_G
, t
, CPF_WRITE
, flags
);
105 fwd_set_time(struct tm
*t
, int flags
)
107 return fwd_msg(RTCDEV_SET_TIME_G
, t
, CPF_READ
, flags
);
113 return fwd_msg(RTCDEV_PWR_OFF
, NULL
, 0, RTCDEV_NOFLAGS
);