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


Reply via email to