tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[RFC] new APIs to use wskbd(4) input on non-wsdisplay tty devices



# tl;dr

I'd like to add new APIs to use wskbd(4) input on non-wsdisplay
tty devices, especially news68k that can use a putchar function
provided by firmware PROM as a kernel console device.

# Details

The news68k machines have various framebuffer options, but
most of them are not "dumb" framebuffer that can be handled
by raspos(9) but some of them have own processors (68000 etc.)
to handle various acceleration etc. so it's difficult to implement
framebuffer drivers.

To support "text only" framebuffer console, we can use putchar
functions provided by the firmware PROM.

However, to use getchar() functions we cannot use getchar
provided by PROM because it always stalls until any key is
pressed.

NetBSD/sun3 has the similar framework in sys/arch/sun3/dev/kd.c,
i.e. it uses a PROM function for putchar but use own keyboard
driver (sys/dev/sun/kbd.c) to handle kernel console.

I'd like to implement the similar framework on NetBSD/news68k.
news68k port already has wskbd driver (delived from newsmips port),
but currently a design of wskbd(9) assumes always it used with
wsdisplay(9) tty (i.e. ttyE?) device and there is no API to use
wskbd(9) input for other drivers than wsdisplay(9).

The attached patch provides new two APIs
- wskbd_consdev_kbdinput_register()
- wskbd_consdev_kbdinput_deregister()
to allow a kernel to use wskbd(9) for non-wsdisplay tty device.

Once "sc_consdev_kbdinput()" callback funtion is registered
via the wskbd_consdev_kbdinput_register() by the MD attachment,
MI wskbd(9) just puts the input data from wskbd(9) to the callback
fundtions, if NWSDISPLAY is not configured.

I think the change is minimum and it doesn't break any existing
ports that use wsdisplay(9) ttys, but I'd like to call for
comments about these implementation design.

Supporting non-serial console on news68k port has been in
my TODO list for ~20 years so I'd like to commit this
if there is no particular objection.

There is a video of NetBSD/news68k 9.3 with the similar patch:
 https://www.youtube.com/watch?v=kPOiHG20Ye8


Index: sys/dev/wscons/wskbd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.143
diff -u -p -d -r1.143 wskbd.c
--- sys/dev/wscons/wskbd.c	5 Feb 2019 10:04:49 -0000	1.143
+++ sys/dev/wscons/wskbd.c	6 Apr 2024 06:59:50 -0000
@@ -214,6 +214,9 @@ struct wskbd_softc {
 	/* optional table to translate scancodes in event mode */
 	int		sc_evtrans_len;
 	keysym_t	*sc_evtrans;
+
+	wskbd_consdev_kbdinput *sc_consdev_kbdinput;
+	device_t sc_consdev;
 };
 
 #define MOD_SHIFT_L		(1 << 0)
@@ -420,6 +423,8 @@ wskbd_attach(device_t parent, device_t s
 	sc->sc_hotkeycookie = NULL;
 	sc->sc_evtrans_len = 0;
 	sc->sc_evtrans = NULL;
+	sc->sc_consdev_kbdinput = NULL;
+	sc->sc_consdev = NULL;
 
 #if NWSMUX > 0 || NWSDISPLAY > 0
 	sc->sc_base.me_ops = &wskbd_srcops;
@@ -664,9 +669,7 @@ void
 wskbd_input(device_t dev, u_int type, int value)
 {
 	struct wskbd_softc *sc = device_private(dev);
-#if NWSDISPLAY > 0
 	int num, i;
-#endif
 
 	if (sc->sc_repeating) {
 		sc->sc_repeating = 0;
@@ -706,6 +709,24 @@ wskbd_input(device_t dev, u_int type, in
 	}
 #endif
 
+#if NWSDISPLAY == 0
+	if (sc->sc_translating) {
+		keysym_t ks;
+
+		if (sc->sc_consdev_kbdinput) {
+			num = wskbd_translate(sc->id, type, value);
+			for (i = 0; i < num; i++) {
+				ks = sc->id->t_symbols[i];
+				if (KS_GROUP(ks) == KS_GROUP_Plain &&
+				    KS_VALUE(ks) <= 0x7f)
+					(*sc->sc_consdev_kbdinput)(
+					    sc->sc_consdev, KS_VALUE(ks));
+			}
+			return;
+		}
+	}
+#endif
+
 	wskbd_deliver_event(sc, type, value);
 
 #if defined(WSKBD_EVENT_AUTOREPEAT)
@@ -1683,6 +1704,36 @@ wskbd_hotkey_deregister(device_t self)
 	sc->sc_hotkeycookie = NULL;
 }
 
+device_t
+wskbd_consdev_kbdinput_register(device_t self, wskbd_consdev_kbdinput *kifn,
+    device_t cons_dv)
+{
+	struct wskbd_softc *sc = device_private(self);
+
+	if (sc == NULL)
+		return NULL;
+
+	if (kifn == NULL)
+		return NULL;
+
+	sc->sc_consdev_kbdinput = kifn;
+	sc->sc_consdev = cons_dv;
+	aprint_verbose_dev(self, "connecting to %s\n", device_xname(cons_dv));
+
+	return sc->sc_base.me_dv;
+}
+
+void
+wskbd_consdev_kbdinput_deregister(device_t self)
+{
+	struct wskbd_softc *sc = device_private(self);
+
+	KASSERT(sc != NULL);
+
+	sc->sc_consdev_kbdinput = NULL;
+	sc->sc_consdev = NULL;
+}
+
 static int
 wskbd_translate(struct wskbd_internal *id, u_int type, int value)
 {
Index: sys/dev/wscons/wskbdvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wskbdvar.h,v
retrieving revision 1.19
diff -u -p -d -r1.19 wskbdvar.h
--- sys/dev/wscons/wskbdvar.h	2 Sep 2012 21:14:56 -0000	1.19
+++ sys/dev/wscons/wskbdvar.h	6 Apr 2024 06:59:50 -0000
@@ -104,6 +104,14 @@ device_t wskbd_hotkey_register(device_t,
 void	 wskbd_hotkey_deregister(device_t);
 
 /*
+ * Callbacks from the keyboard driver to non-wscons console drivers.
+ */
+typedef void (wskbd_consdev_kbdinput)(device_t, int);
+device_t wskbd_consdev_kbdinput_register(device_t, wskbd_consdev_kbdinput *,
+    device_t);
+void wskbd_consdev_kbdinput_deregister(device_t);
+
+/*
  * set a translation table for scancodes in event mode
  * parameters are a pointer to the table and its length
  * pass length zero to turn translation off
Index: sys/arch/news68k/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/news68k/conf/GENERIC,v
retrieving revision 1.133
diff -u -p -d -r1.133 GENERIC
--- sys/arch/news68k/conf/GENERIC	26 Apr 2019 21:40:31 -0000	1.133
+++ sys/arch/news68k/conf/GENERIC	6 Apr 2024 06:59:50 -0000
@@ -202,7 +202,7 @@ ss*	at scsibus? target ? lun ?		# SCSI s
 uk*	at scsibus? target ? lun ?		# unknown SCSI devices
 
 # PROM console support
-#romcons0 at mainbus0
+romcons0 at mainbus0
 
 #
 # accept filters
Index: sys/arch/news68k/conf/INSTALL
===================================================================
RCS file: /cvsroot/src/sys/arch/news68k/conf/INSTALL,v
retrieving revision 1.65.4.1
diff -u -p -d -r1.65.4.1 INSTALL
--- sys/arch/news68k/conf/INSTALL	10 Feb 2020 18:28:33 -0000	1.65.4.1
+++ sys/arch/news68k/conf/INSTALL	6 Apr 2024 06:59:50 -0000
@@ -134,7 +134,7 @@ st*	at scsibus? target ? lun ?		# SCSI t
 cd*	at scsibus? target ? lun ?		# SCSI CD-ROMs
 
 # PROM console support
-#romcons0 at mainbus0
+romcons0 at mainbus0
 
 # Misc.
 pseudo-device	bpfilter		# Berkeley Packet Filter
Index: sys/arch/news68k/news68k/romcons.c
===================================================================
RCS file: /cvsroot/src/sys/arch/news68k/news68k/romcons.c,v
retrieving revision 1.3
diff -u -p -d -r1.3 romcons.c
--- sys/arch/news68k/news68k/romcons.c	25 Jul 2014 08:10:34 -0000	1.3
+++ sys/arch/news68k/news68k/romcons.c	6 Apr 2024 06:59:50 -0000
@@ -37,6 +37,8 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: romcons.c,v 1.3 2014/07/25 08:10:34 dholland Exp $");
 
+#include "wskbd.h"
+
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/device.h>
@@ -47,6 +49,9 @@ __KERNEL_RCSID(0, "$NetBSD: romcons.c,v 
 #include <sys/kauth.h>
 
 #include <dev/cons.h>
+#if NWSKBD > 0
+#include <dev/wscons/wskbdvar.h>
+#endif
 
 #include <machine/autoconf.h>
 #include <machine/romcall.h>
@@ -59,6 +64,8 @@ struct romcons_softc {
 	struct callout sc_poll_ch;
 	int sc_flags;
 #define	CONS_POLL	1
+
+	device_t sc_kbdinput_dv;
 };
 
 #define	BURSTLEN	128	/* max number of bytes to write in one chunk */
@@ -79,7 +86,10 @@ dev_type_ioctl(romcons_ioctl);
 dev_type_tty(romcons_tty);
 dev_type_poll(romcons_poll);
 
-void romcons_kbdinput(int);
+#if NWSKBD > 0
+static void romcons_attach_deferred(device_t);
+static void romcons_kbdinput(device_t, int);
+#endif
 
 const struct cdevsw romcons_cdevsw = {
 	.d_open = romcons_open,
@@ -129,8 +139,35 @@ romcons_attach(device_t parent, device_t
 	aprint_normal("\n");
 
 	callout_init(&sc->sc_poll_ch, 0);
+
+#if NWSKBD > 0
+	config_defer(self, romcons_attach_deferred);
+#endif
 }
 
+#if NWSKBD > 0
+static void
+romcons_attach_deferred(device_t self)
+{
+	struct romcons_softc *sc;
+	device_t wskbd_dev;
+
+	sc = device_private(self);
+	KASSERT(sc != NULL);
+
+	/* XXX assume only one keyboard at wskbd0 */
+	wskbd_dev = device_lookup(&wskbd_cd, 0);
+	if (wskbd_dev == NULL) {
+		aprint_error_dev(self, "no wskbd0 is attached\n");
+		return;
+	}
+
+	/* attach wskbd hook for tty(4) of userland processes */
+	sc->sc_kbdinput_dv =
+	    wskbd_consdev_kbdinput_register(wskbd_dev, romcons_kbdinput, self);
+}
+#endif
+
 static void romcons_start(struct tty *);
 static int romcons_param(struct tty *, struct termios *);
 static void romcons_pollin(void *);
@@ -294,17 +331,19 @@ romcons_pollin(void *aux)
 	callout_reset(&sc->sc_poll_ch, 1, romcons_pollin, sc);
 }
 
-void
-romcons_kbdinput(int ks)
+#if NWSKBD > 0
+static void
+romcons_kbdinput(device_t self, int ks)
 {
-	struct romcons_softc *sc;
+	struct romcons_softc *sc = device_private(self);
 	struct tty *tp;
 
-	sc = device_lookup_private(&romcons_cd, 0);
+	KASSERT(sc != NULL);
 	tp = sc->sc_tty;
 	if (tp && (tp->t_state & TS_ISOPEN))
 		(*tp->t_linesw->l_rint)(ks, tp);
 }
+#endif
 
 void
 romcons_cnprobe(struct consdev *cd)


---

Thanks,
---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index