Hi,
Currently I am working on adding /dev/rtc. For now I can compile it and
use `settrans` to create a device file; I can confirm that ioctl() works
perfectly on the generated device file. I think it's a good chance to stop
and gather some suggestions and feedback, so I sent a series of RTC patches.
The next thing I'm going to do is implementing the rtc server code, i.e
rtc device driver. I have no experience of writing driver but I want to
give it a try. Any document that is recommended to read for implementing
rtc device driver?
Best,
Zhaoming
---
Makefile | 2 ++
hurd/pioctl.defs | 34 ++++++++++++++++++
rtc/Makefile | 19 ++++++++++
rtc/main.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++
rtc/mig-mutate.h | 0
rtc/pioctl-ops.c | 17 +++++++++
rtc/rtc.h | 21 +++++++++++
7 files changed, 187 insertions(+)
create mode 100644 hurd/pioctl.defs
create mode 100644 rtc/Makefile
create mode 100644 rtc/main.c
create mode 100644 rtc/mig-mutate.h
create mode 100644 rtc/pioctl-ops.c
create mode 100644 rtc/rtc.h
diff --git a/Makefile b/Makefile
index 4d848221..8133c9e9 100644
--- a/Makefile
+++ b/Makefile
@@ -69,6 +69,8 @@ ifeq ($(HAVE_LIBACPICA),yes)
prog-subdirs += acpi
endif
+prog-subdirs += rtc
+
# Other directories
other-subdirs = hurd doc config release include
diff --git a/hurd/pioctl.defs b/hurd/pioctl.defs
new file mode 100644
index 00000000..36fa8d3f
--- /dev/null
+++ b/hurd/pioctl.defs
@@ -0,0 +1,34 @@
+/* Definitions for /dev/rtc ioctls */
+
+/* Ioctl group 'p'; the subsystem is derived from calculations in
+ hurd/ioctls.defs. */
+subsystem pioctl 140000;
+
+#include <hurd/ioctl_types.defs>
+
+import "rtc.h";
+
+#ifdef PIOCTL_IMPORTS
+PIOCTL_IMPORTS
+#endif
+
+INTR_INTERFACE
+
+/* This is the arg for a struct rtc_time as specified by the
+ definition of _IOT_rtc_time in $(hurd)/rtc/rtc.h. */
+type rtc_time_t = struct[9] of int;
+
+/* TODO: adding other ioctl calls for /dev/rtc in mc146818rtc.h */
+skip; skip; skip; skip; /* 0 1 2 3 */
+skip; skip; skip; skip; /* 4 5 6 7 */
+skip; /* 8 */
+
+/* 9 RTC_RD_TIME */
+routine pioctl_rtc_rd_time (
+ reqport: io_t;
+ out time: rtc_time_t);
+
+/* 10 RTC_SET_TIME */
+routine pioctl_rtc_set_time (
+ reqport: io_t;
+ time: rtc_time_t);
diff --git a/rtc/Makefile b/rtc/Makefile
new file mode 100644
index 00000000..dd0e19d2
--- /dev/null
+++ b/rtc/Makefile
@@ -0,0 +1,19 @@
+dir := rtc
+makemode := server
+
+SRCS = main.c pioctl-ops.c
+MIGSRCS = pioctlServer.c
+
+OBJS = main.o pioctlServer.o pioctl-ops.o
+
+HURDLIBS = trivfs shouldbeinlibc ports
+
+target = rtc
+
+include ../Makeconf
+
+MIGCOMSFLAGS += -prefix rtc_
+mig-sheader-prefix = rtc_
+pioctl-MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
+
+rtc_pioctl_S.h pioctlServer.c: mig-mutate.h
diff --git a/rtc/main.c b/rtc/main.c
new file mode 100644
index 00000000..ae871e85
--- /dev/null
+++ b/rtc/main.c
@@ -0,0 +1,94 @@
+
+#include <version.h>
+
+#include <error.h>
+#include <argp.h>
+#include <nullauth.h>
+#include <hurd/trivfs.h>
+#include <hurd/ports.h>
+
+#include "rtc_pioctl_S.h"
+
+#include "rtc.h"
+
+const char *argp_program_version = STANDARD_HURD_VERSION (rtc);
+
+mach_port_t fsys_identity;
+
+struct trivfs_control *rtccntl;
+
+int trivfs_fstype = FSTYPE_DEV;
+int trivfs_fsid = 0;
+int trivfs_support_read = 0;
+int trivfs_support_write = 0;
+int trivfs_support_exec = 0;
+int trivfs_allow_open = O_READ | O_WRITE;
+
+static const struct argp_option options[] =
+{
+ {0}
+};
+
+/* TODO: adding option */
+static error_t
+parse_opt (int opt, char *arg, struct argp_state *state)
+{
+ return ARGP_ERR_UNKNOWN;
+}
+
+static const struct argp rtc_argp =
+{ options, parse_opt, 0, "RTC device" };
+
+int
+demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
+{
+ mig_routine_t routine;
+ if ((routine = rtc_pioctl_server_routine (inp)) ||
+ (routine = NULL, trivfs_demuxer (inp, outp)))
+ {
+ if (routine)
+ (*routine) (inp, outp);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ mach_port_t bootstrap;
+
+ mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE, &fsys_identity);
+
+ argp_parse (&rtc_argp, argc, argv, 0, 0, 0);
+
+ task_get_bootstrap_port (mach_task_self (), &bootstrap);
+ if (bootstrap == MACH_PORT_NULL)
+ error(1, 0, "Must be started as a translator");
+
+ /* Reply to our parent */
+ err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &rtccntl);
+ mach_port_deallocate (mach_task_self (), bootstrap);
+ if (err)
+ return -1;
+
+ /* Launch. */
+ ports_manage_port_operations_multithread (rtccntl->pi.bucket, demuxer,
+ 30 * 1000, 2 * 60 * 1000, 0);
+
+ return 0;
+}
+
+void
+trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st)
+{
+}
+
+error_t
+trivfs_goaway (struct trivfs_control *fsys, int flags)
+{
+ exit (0);
+}
diff --git a/rtc/mig-mutate.h b/rtc/mig-mutate.h
new file mode 100644
index 00000000..e69de29b
diff --git a/rtc/pioctl-ops.c b/rtc/pioctl-ops.c
new file mode 100644
index 00000000..02f4c65f
--- /dev/null
+++ b/rtc/pioctl-ops.c
@@ -0,0 +1,17 @@
+#include "rtc_pioctl_S.h"
+#include "rtc.h"
+#include <hurd/hurd_types.h>
+
+/* 9 RTC_RD_TIME -- Read RTC time*/
+kern_return_t
+rtc_S_pioctl_rtc_rd_time (io_t reqport, struct rtc_time * time)
+{
+ return KERN_SUCCESS;
+}
+
+/* 10 RTC_SET_TIME -- Set RTC time*/
+kern_return_t
+rtc_S_pioctl_rtc_set_time (io_t reqport, struct rtc_time time)
+{
+ return KERN_SUCCESS;
+}
diff --git a/rtc/rtc.h b/rtc/rtc.h
new file mode 100644
index 00000000..957b13a0
--- /dev/null
+++ b/rtc/rtc.h
@@ -0,0 +1,21 @@
+#ifndef _RTC_H
+#define _RTC_H 1
+
+#include <hurd/ioctl.h>
+
+struct rtc_time {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+typedef struct rtc_time rtc_time_t;
+
+#define _IOT_rtc_time _IOT(_IOTS(int),9,0,0,0,0)
+
+#endif /* rtc/rtc.h */
--
2.47.0