Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/wscons Add WSDISPLAY_MULTICONS option which allows w...



details:   https://anonhg.NetBSD.org/src/rev/15171f3e7083
branches:  trunk
changeset: 828539:15171f3e7083
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Dec 18 18:59:32 2017 +0000

description:
Add WSDISPLAY_MULTICONS option which allows wsdisplay to cooperate with
the console device being overridden. This allows for simultaneous console
output on fb and debug uart.

diffstat:

 sys/dev/wscons/files.wscons |    3 +-
 sys/dev/wscons/wsdisplay.c  |  102 ++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 95 insertions(+), 10 deletions(-)

diffs (246 lines):

diff -r bdd0ef0f8db6 -r 15171f3e7083 sys/dev/wscons/files.wscons
--- a/sys/dev/wscons/files.wscons       Mon Dec 18 18:58:00 2017 +0000
+++ b/sys/dev/wscons/files.wscons       Mon Dec 18 18:59:32 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.wscons,v 1.54 2017/08/30 00:39:27 jmcneill Exp $
+# $NetBSD: files.wscons,v 1.55 2017/12/18 18:59:32 jmcneill Exp $
 
 #
 # "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@@ -31,6 +31,7 @@
                                WSCONS_SUPPORT_ISO7FONTS
                                WSDISPLAY_SCROLLSUPPORT
                                WSKBD_EVENT_AUTOREPEAT
+                               WSDISPLAY_MULTICONS
 defparam opt_wsdisplay_compat.h        WSCOMPAT_USL_SYNCTIMEOUT
                                WSDISPLAY_DEFAULTSCREENS
 defparam opt_wsdisplay_compat.h WSDISPLAY_SCROLLBACK_LINES=100
diff -r bdd0ef0f8db6 -r 15171f3e7083 sys/dev/wscons/wsdisplay.c
--- a/sys/dev/wscons/wsdisplay.c        Mon Dec 18 18:58:00 2017 +0000
+++ b/sys/dev/wscons/wsdisplay.c        Mon Dec 18 18:59:32 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplay.c,v 1.143 2017/11/03 18:49:37 maya Exp $ */
+/* $NetBSD: wsdisplay.c,v 1.144 2017/12/18 18:59:32 jmcneill Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.143 2017/11/03 18:49:37 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.144 2017/12/18 18:59:32 jmcneill Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_wsdisplay_compat.h"
@@ -71,6 +71,9 @@
 
 #include "locators.h"
 
+/* Console device before replaced by wsdisplay */
+static struct consdev *wsdisplay_ocn;
+
 struct wsscreen_internal {
        const struct wsdisplay_emulops *emulops;
        void    *emulcookie;
@@ -99,6 +102,10 @@
        int scr_rawkbd;
 #endif
 
+#ifdef WSDISPLAY_MULTICONS
+       callout_t scr_getc_ch;
+#endif
+
        struct wsdisplay_softc *sc;
 
 #ifdef DIAGNOSTIC
@@ -234,14 +241,15 @@
 static struct wsdisplay_softc *wsdisplay_console_device;
 static struct wsscreen_internal wsdisplay_console_conf;
 
-static int wsdisplay_getc_dummy(dev_t);
+static int wsdisplay_getc(dev_t);
 static void wsdisplay_pollc(dev_t, int);
 
 static int wsdisplay_cons_pollmode;
+static int (*wsdisplay_cons_kbd_getc)(dev_t);
 static void (*wsdisplay_cons_kbd_pollc)(dev_t, int);
 
 static struct consdev wsdisplay_cons = {
-       NULL, NULL, wsdisplay_getc_dummy, wsdisplay_cnputc,
+       NULL, NULL, wsdisplay_getc, wsdisplay_cnputc,
        wsdisplay_pollc, NULL, NULL, NULL, NODEV, CN_NORMAL
 };
 
@@ -262,6 +270,27 @@
 
 int wsdisplay_clearonclose;
 
+#ifdef WSDISPLAY_MULTICONS
+static void
+wsscreen_getc_poll(void *priv)
+{
+       struct wsscreen *scr = priv;
+       int c;
+
+       if (wsdisplay_ocn && wsdisplay_ocn->cn_getc &&
+           WSSCREEN_HAS_EMULATOR(scr) && WSSCREEN_HAS_TTY(scr)) {
+               struct tty *tp = scr->scr_tty;
+               do {
+                       c = wsdisplay_ocn->cn_getc(wsdisplay_ocn->cn_dev);
+                       if (c != -1)
+                               (*tp->t_linesw->l_rint)((unsigned char)c, tp);
+               } while (c != -1);
+       }
+
+       callout_schedule(&scr->scr_getc_ch, mstohz(10));
+}
+#endif
+
 struct wsscreen *
 wsscreen_attach(struct wsdisplay_softc *sc, int console, const char *emul,
        const struct wsscreen_descr *type, void *cookie, int ccol,
@@ -315,6 +344,12 @@
 #ifdef WSDISPLAY_COMPAT_RAWKBD
        scr->scr_rawkbd = 0;
 #endif
+#ifdef WSDISPLAY_MULTICONS
+       callout_init(&scr->scr_getc_ch, 0);
+       callout_setfunc(&scr->scr_getc_ch, wsscreen_getc_poll, scr);
+       if (console)
+               callout_schedule(&scr->scr_getc_ch, mstohz(10));
+#endif
        return (scr);
 }
 
@@ -334,6 +369,8 @@
        }
        if (scr->scr_dconf->scrdata->capabilities & WSSCREEN_FREE)
                free(__UNCONST(scr->scr_dconf->scrdata), M_DEVBUF);
+       callout_halt(&scr->scr_getc_ch, NULL);
+       callout_destroy(&scr->scr_getc_ch);
        free(scr->scr_dconf, M_DEVBUF);
        free(scr, M_DEVBUF);
 }
@@ -884,6 +921,8 @@
                                                                  ccol, crow,
                                                                  defattr);
 
+       if (cn_tab != &wsdisplay_cons)
+               wsdisplay_ocn = cn_tab;
        cn_tab = &wsdisplay_cons;
        wsdisplay_console_initted = 2;
 }
@@ -910,6 +949,8 @@
                                                                  ccol, crow,
                                                                  defattr);
 
+       if (cn_tab != &wsdisplay_cons)
+               wsdisplay_ocn = cn_tab;
        cn_tab = &wsdisplay_cons;
        wsdisplay_console_initted = 1;
 }
@@ -919,7 +960,7 @@
 {
        KASSERT(wsdisplay_console_initted == 2);
 
-       cn_tab = NULL;
+       cn_tab = wsdisplay_ocn;
        wsdisplay_console_initted = 0;
 }
 
@@ -1631,6 +1672,14 @@
                KASSERT(WSSCREEN_HAS_EMULATOR(scr));
                (*scr->scr_dconf->wsemul->output)(scr->scr_dconf->wsemulcookie,
                                                  tbuf, n, 0);
+#ifdef WSDISPLAY_MULTICONS
+               if (scr->scr_dconf == &wsdisplay_console_conf &&
+                   wsdisplay_ocn && wsdisplay_ocn->cn_putc) {
+                       for (int i = 0; i < n; i++)
+                               wsdisplay_ocn->cn_putc(
+                                   wsdisplay_ocn->cn_dev, tbuf[i]);
+               }
+#endif
        }
        ndflush(&tp->t_outq, n);
 
@@ -1641,6 +1690,15 @@
                        KASSERT(WSSCREEN_HAS_EMULATOR(scr));
                        (*scr->scr_dconf->wsemul->output)
                            (scr->scr_dconf->wsemulcookie, tbuf, n, 0);
+
+#ifdef WSDISPLAY_MULTICONS
+                       if (scr->scr_dconf == &wsdisplay_console_conf &&
+                           wsdisplay_ocn && wsdisplay_ocn->cn_putc) {
+                               for (int i = 0; i < n; i++)
+                                       wsdisplay_ocn->cn_putc(
+                                           wsdisplay_ocn->cn_dev, tbuf[i]);
+                       }
+#endif
                }
                ndflush(&tp->t_outq, n);
        }
@@ -2229,11 +2287,31 @@
 
        dc = &wsdisplay_console_conf;
        (*dc->wsemul->output)(dc->wsemulcookie, &c, 1, 1);
+
+#ifdef WSDISPLAY_MULTICONS
+       if (wsdisplay_ocn && wsdisplay_ocn->cn_putc)
+               wsdisplay_ocn->cn_putc(wsdisplay_ocn->cn_dev, i);
+#endif
 }
 
 static int
-wsdisplay_getc_dummy(dev_t dev)
+wsdisplay_getc(dev_t dev)
 {
+       int c;
+
+       if (wsdisplay_cons_kbd_getc) {
+               c = wsdisplay_cons_kbd_getc(wsdisplay_cons.cn_dev);
+               if (c > 0)
+                       return c;
+       }
+
+#ifdef WSDISPLAY_MULTICONS
+       if (wsdisplay_ocn && wsdisplay_ocn->cn_getc) {
+               c = wsdisplay_ocn->cn_getc(wsdisplay_ocn->cn_dev);
+               if (c > 0)
+                       return c;
+       }
+#endif
        /* panic? */
        return (0);
 }
@@ -2253,21 +2331,27 @@
        /* notify to kbd drivers */
        if (wsdisplay_cons_kbd_pollc)
                (*wsdisplay_cons_kbd_pollc)(NODEV, on);
+
+#ifdef WSDISPLAY_MULTICONS
+       /* notify to old console driver */
+       if (wsdisplay_ocn && wsdisplay_ocn->cn_pollc)
+               wsdisplay_ocn->cn_pollc(wsdisplay_ocn->cn_dev, on);
+#endif
 }
 
 void
 wsdisplay_set_cons_kbd(int (*get)(dev_t), void (*poll)(dev_t, int),
        void (*bell)(dev_t, u_int, u_int, u_int))
 {
-       wsdisplay_cons.cn_getc = get;
        wsdisplay_cons.cn_bell = bell;
+       wsdisplay_cons_kbd_getc = get;
        wsdisplay_cons_kbd_pollc = poll;
 }
 
 void
 wsdisplay_unset_cons_kbd(void)
 {
-       wsdisplay_cons.cn_getc = wsdisplay_getc_dummy;
        wsdisplay_cons.cn_bell = NULL;
-       wsdisplay_cons_kbd_pollc = 0;
+       wsdisplay_cons_kbd_getc = NULL;
+       wsdisplay_cons_kbd_pollc = NULL;
 }



Home | Main Index | Thread Index | Old Index