Module Name:    src
Committed By:   drochner
Date:           Tue Feb  2 16:18:29 UTC 2010

Modified Files:
        src/sys/dev/wscons: wsdisplay.c wsemulconf.c wsemulvar.h

Log Message:
add hooks to allow terminal emulations to be installed by LKMs
(these are not available in early bootstrap, so this is not an
option for the system's default emulation)


To generate a diff of this commit:
cvs rdiff -u -r1.128 -r1.129 src/sys/dev/wscons/wsdisplay.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/wscons/wsemulconf.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/wscons/wsemulvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/wscons/wsdisplay.c
diff -u src/sys/dev/wscons/wsdisplay.c:1.128 src/sys/dev/wscons/wsdisplay.c:1.129
--- src/sys/dev/wscons/wsdisplay.c:1.128	Thu Jan 28 22:36:19 2010
+++ src/sys/dev/wscons/wsdisplay.c	Tue Feb  2 16:18:29 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplay.c,v 1.128 2010/01/28 22:36:19 drochner Exp $ */
+/* $NetBSD: wsdisplay.c,v 1.129 2010/02/02 16:18:29 drochner 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.128 2010/01/28 22:36:19 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.129 2010/02/02 16:18:29 drochner Exp $");
 
 #include "opt_wsdisplay_compat.h"
 #include "opt_wsmsgattrs.h"
@@ -311,9 +311,11 @@
 		tty_detach(scr->scr_tty);
 		ttyfree(scr->scr_tty);
 	}
-	if (WSSCREEN_HAS_EMULATOR(scr))
+	if (WSSCREEN_HAS_EMULATOR(scr)) {
 		(*scr->scr_dconf->wsemul->detach)(scr->scr_dconf->wsemulcookie,
 						  &ccol, &crow);
+		wsemul_drop(scr->scr_dconf->wsemul);
+	}
 	free(scr->scr_dconf, M_DEVBUF);
 	free(scr, M_DEVBUF);
 }

Index: src/sys/dev/wscons/wsemulconf.c
diff -u src/sys/dev/wscons/wsemulconf.c:1.7 src/sys/dev/wscons/wsemulconf.c:1.8
--- src/sys/dev/wscons/wsemulconf.c:1.7	Sun Dec 11 12:24:12 2005
+++ src/sys/dev/wscons/wsemulconf.c	Tue Feb  2 16:18:29 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: wsemulconf.c,v 1.7 2005/12/11 12:24:12 christos Exp $ */
+/* $NetBSD: wsemulconf.c,v 1.8 2010/02/02 16:18:29 drochner Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -31,10 +31,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsemulconf.c,v 1.7 2005/12/11 12:24:12 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsemulconf.c,v 1.8 2010/02/02 16:18:29 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/malloc.h>
 
 #include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wsdisplayvar.h>
@@ -42,6 +43,13 @@
 #include <dev/wscons/wsemulvar.h>		/* pulls in opt_wsemul.h */
 #include <dev/wscons/wscons_callbacks.h>
 
+struct wsemulentry {
+	const struct wsemul_ops *ops;
+	int usecnt;
+	LIST_ENTRY(wsemulentry) next;
+};
+static LIST_HEAD(, wsemulentry) wsemuls = LIST_HEAD_INITIALIZER(&wsemuls);
+
 static const struct wsemul_ops *wsemul_conf[] = {
 #ifdef WSEMUL_SUN
 	&wsemul_sun_ops,
@@ -59,6 +67,7 @@
 wsemul_pick(const char *name)
 {
 	const struct wsemul_ops **ops;
+	struct wsemulentry *wep;
 
 	if (name == NULL) {
 		/* default */
@@ -69,9 +78,55 @@
 #endif
 	}
 
+	LIST_FOREACH(wep, &wsemuls, next)
+		if (!strcmp(name, wep->ops->name)) {
+			wep->usecnt++;
+			return wep->ops;
+		}
+
 	for (ops = &wsemul_conf[0]; *ops != NULL; ops++)
 		if (strcmp(name, (*ops)->name) == 0)
 			break;
 
 	return (*ops);
 }
+
+void
+wsemul_drop(const struct wsemul_ops *ops)
+{
+	struct wsemulentry *wep;
+
+	LIST_FOREACH(wep, &wsemuls, next)
+		if (ops == wep->ops) {
+			wep->usecnt--;
+			return;
+		}
+}
+
+int
+wsemul_add(const struct wsemul_ops *ops)
+{
+	struct wsemulentry *wep;
+
+	wep = malloc(sizeof (struct wsemulentry), M_DEVBUF, M_WAITOK);
+	wep->ops = ops;
+	wep->usecnt = 0;
+	LIST_INSERT_HEAD(&wsemuls, wep, next);
+	return 0;
+}
+
+int
+wsemul_remove(const struct wsemul_ops *ops)
+{
+	struct wsemulentry *wep;
+
+	LIST_FOREACH(wep, &wsemuls, next) {
+		if (ops == wep->ops) {
+			if (wep->usecnt)
+				return EBUSY;
+			LIST_REMOVE(wep, next);
+			return 0;
+		}
+	}
+	return ENOENT;
+}

Index: src/sys/dev/wscons/wsemulvar.h
diff -u src/sys/dev/wscons/wsemulvar.h:1.14 src/sys/dev/wscons/wsemulvar.h:1.15
--- src/sys/dev/wscons/wsemulvar.h:1.14	Tue Mar 25 00:49:20 2008
+++ src/sys/dev/wscons/wsemulvar.h	Tue Feb  2 16:18:29 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: wsemulvar.h,v 1.14 2008/03/25 00:49:20 cube Exp $ */
+/* $NetBSD: wsemulvar.h,v 1.15 2010/02/02 16:18:29 drochner Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -69,6 +69,9 @@
 #endif
 
 const struct wsemul_ops *wsemul_pick(const char *);
+void wsemul_drop(const struct wsemul_ops *);
+int wsemul_add(const struct wsemul_ops *);
+int wsemul_remove(const struct wsemul_ops *);
 
 /*
  * Callbacks from the emulation code to the display interface driver.

Reply via email to