<sys/socket.h>: turn off MSG_NOSIGNAL
[minix3.git] / drivers / readclock / forward.c
blob77eb77057cca55572b953a19f726c40884436a25
1 /*
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.
7 */
9 #include <minix/syslib.h>
10 #include <minix/drvlib.h>
11 #include <minix/sysutil.h>
12 #include <minix/log.h>
13 #include <minix/rs.h>
14 #include <minix/ds.h>
15 #include <minix/safecopies.h>
17 #include <sys/mman.h>
18 #include <sys/types.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <assert.h>
26 #include <time.h>
27 #include <lib.h>
29 #include "forward.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;
45 int
46 fwd_set_label(char *label)
48 target_label = label;
49 return OK;
52 int
53 fwd_init(void)
55 if (target_label == NULL) {
56 return EINVAL;
58 return OK;
61 static int
62 fwd_msg(int type, struct tm *t, int t_access, int flags)
64 int r;
65 message m;
66 endpoint_t ep;
67 cp_grant_id_t gid;
69 r = ds_retrieve_label_endpt(target_label, &ep);
70 if (r != 0) {
71 return -1;
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");
82 return -1;
85 m.m_lc_readclock_rtcdev.grant = gid;
86 m.m_lc_readclock_rtcdev.flags = flags;
88 r = _syscall(ep, type, &m);
89 cpf_revoke(gid);
90 if (r != RTCDEV_REPLY || m.m_readclock_lc_rtcdev.status != 0) {
91 log_warn(&log, "Call to '%s' failed.\n", target_label);
92 return -1;
95 return OK;
98 int
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);
111 fwd_pwr_off(void)
113 return fwd_msg(RTCDEV_PWR_OFF, NULL, 0, RTCDEV_NOFLAGS);
116 void
117 fwd_exit(void)
119 target_label = NULL;