xref: /netbsd-src/sys/dev/wscons/wsemulconf.c (revision 1921d00aaf73418a4739ac211c4f97d21e2898e9)
1*1921d00aSdrochner /* $NetBSD: wsemulconf.c,v 1.8 2010/02/02 16:18:29 drochner Exp $ */
2b31e6386Sdrochner 
3b31e6386Sdrochner /*
4b31e6386Sdrochner  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
5b31e6386Sdrochner  *
6b31e6386Sdrochner  * Redistribution and use in source and binary forms, with or without
7b31e6386Sdrochner  * modification, are permitted provided that the following conditions
8b31e6386Sdrochner  * are met:
9b31e6386Sdrochner  * 1. Redistributions of source code must retain the above copyright
10b31e6386Sdrochner  *    notice, this list of conditions and the following disclaimer.
11b31e6386Sdrochner  * 2. Redistributions in binary form must reproduce the above copyright
12b31e6386Sdrochner  *    notice, this list of conditions and the following disclaimer in the
13b31e6386Sdrochner  *    documentation and/or other materials provided with the distribution.
14b31e6386Sdrochner  * 3. All advertising materials mentioning features or use of this software
15b31e6386Sdrochner  *    must display the following acknowledgement:
16b31e6386Sdrochner  *      This product includes software developed by Christopher G. Demetriou
17b31e6386Sdrochner  *	for the NetBSD Project.
18b31e6386Sdrochner  * 4. The name of the author may not be used to endorse or promote products
19b31e6386Sdrochner  *    derived from this software without specific prior written permission
20b31e6386Sdrochner  *
21b31e6386Sdrochner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22b31e6386Sdrochner  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23b31e6386Sdrochner  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24b31e6386Sdrochner  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25b31e6386Sdrochner  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26b31e6386Sdrochner  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27b31e6386Sdrochner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28b31e6386Sdrochner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29b31e6386Sdrochner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30b31e6386Sdrochner  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31b31e6386Sdrochner  */
32b31e6386Sdrochner 
33b32647d4Sdrochner #include <sys/cdefs.h>
34*1921d00aSdrochner __KERNEL_RCSID(0, "$NetBSD: wsemulconf.c,v 1.8 2010/02/02 16:18:29 drochner Exp $");
35b31e6386Sdrochner 
36b31e6386Sdrochner #include <sys/param.h>
37b31e6386Sdrochner #include <sys/systm.h>
38*1921d00aSdrochner #include <sys/malloc.h>
39b31e6386Sdrochner 
4092f81ea7Sjmmv #include <dev/wscons/wsconsio.h>
41b31e6386Sdrochner #include <dev/wscons/wsdisplayvar.h>
427560f4c5Sdrochner #include <dev/wscons/wsksymvar.h>
43085787ddSthorpej #include <dev/wscons/wsemulvar.h>		/* pulls in opt_wsemul.h */
44b31e6386Sdrochner #include <dev/wscons/wscons_callbacks.h>
45b31e6386Sdrochner 
46*1921d00aSdrochner struct wsemulentry {
47*1921d00aSdrochner 	const struct wsemul_ops *ops;
48*1921d00aSdrochner 	int usecnt;
49*1921d00aSdrochner 	LIST_ENTRY(wsemulentry) next;
50*1921d00aSdrochner };
51*1921d00aSdrochner static LIST_HEAD(, wsemulentry) wsemuls = LIST_HEAD_INITIALIZER(&wsemuls);
52*1921d00aSdrochner 
53b31e6386Sdrochner static const struct wsemul_ops *wsemul_conf[] = {
54b31e6386Sdrochner #ifdef WSEMUL_SUN
55b31e6386Sdrochner 	&wsemul_sun_ops,
56b31e6386Sdrochner #endif
577560f4c5Sdrochner #ifdef WSEMUL_VT100
587560f4c5Sdrochner 	&wsemul_vt100_ops,
597560f4c5Sdrochner #endif
60b31e6386Sdrochner #ifndef WSEMUL_NO_DUMB
61b31e6386Sdrochner 	&wsemul_dumb_ops,
62b31e6386Sdrochner #endif
63b31e6386Sdrochner 	NULL
64b31e6386Sdrochner };
65b31e6386Sdrochner 
66b31e6386Sdrochner const struct wsemul_ops *
wsemul_pick(const char * name)6782e5e6abSaugustss wsemul_pick(const char *name)
68b31e6386Sdrochner {
697560f4c5Sdrochner 	const struct wsemul_ops **ops;
70*1921d00aSdrochner 	struct wsemulentry *wep;
71b31e6386Sdrochner 
72b31e6386Sdrochner 	if (name == NULL) {
73b31e6386Sdrochner 		/* default */
74b31e6386Sdrochner #ifdef WSEMUL_DEFAULT
75b31e6386Sdrochner 		name = WSEMUL_DEFAULT;
76b31e6386Sdrochner #else
77b31e6386Sdrochner 		return (wsemul_conf[0]);
78b31e6386Sdrochner #endif
79b31e6386Sdrochner 	}
80b31e6386Sdrochner 
81*1921d00aSdrochner 	LIST_FOREACH(wep, &wsemuls, next)
82*1921d00aSdrochner 		if (!strcmp(name, wep->ops->name)) {
83*1921d00aSdrochner 			wep->usecnt++;
84*1921d00aSdrochner 			return wep->ops;
85*1921d00aSdrochner 		}
86*1921d00aSdrochner 
877560f4c5Sdrochner 	for (ops = &wsemul_conf[0]; *ops != NULL; ops++)
887560f4c5Sdrochner 		if (strcmp(name, (*ops)->name) == 0)
89b31e6386Sdrochner 			break;
90b31e6386Sdrochner 
917560f4c5Sdrochner 	return (*ops);
92b31e6386Sdrochner }
93*1921d00aSdrochner 
94*1921d00aSdrochner void
wsemul_drop(const struct wsemul_ops * ops)95*1921d00aSdrochner wsemul_drop(const struct wsemul_ops *ops)
96*1921d00aSdrochner {
97*1921d00aSdrochner 	struct wsemulentry *wep;
98*1921d00aSdrochner 
99*1921d00aSdrochner 	LIST_FOREACH(wep, &wsemuls, next)
100*1921d00aSdrochner 		if (ops == wep->ops) {
101*1921d00aSdrochner 			wep->usecnt--;
102*1921d00aSdrochner 			return;
103*1921d00aSdrochner 		}
104*1921d00aSdrochner }
105*1921d00aSdrochner 
106*1921d00aSdrochner int
wsemul_add(const struct wsemul_ops * ops)107*1921d00aSdrochner wsemul_add(const struct wsemul_ops *ops)
108*1921d00aSdrochner {
109*1921d00aSdrochner 	struct wsemulentry *wep;
110*1921d00aSdrochner 
111*1921d00aSdrochner 	wep = malloc(sizeof (struct wsemulentry), M_DEVBUF, M_WAITOK);
112*1921d00aSdrochner 	wep->ops = ops;
113*1921d00aSdrochner 	wep->usecnt = 0;
114*1921d00aSdrochner 	LIST_INSERT_HEAD(&wsemuls, wep, next);
115*1921d00aSdrochner 	return 0;
116*1921d00aSdrochner }
117*1921d00aSdrochner 
118*1921d00aSdrochner int
wsemul_remove(const struct wsemul_ops * ops)119*1921d00aSdrochner wsemul_remove(const struct wsemul_ops *ops)
120*1921d00aSdrochner {
121*1921d00aSdrochner 	struct wsemulentry *wep;
122*1921d00aSdrochner 
123*1921d00aSdrochner 	LIST_FOREACH(wep, &wsemuls, next) {
124*1921d00aSdrochner 		if (ops == wep->ops) {
125*1921d00aSdrochner 			if (wep->usecnt)
126*1921d00aSdrochner 				return EBUSY;
127*1921d00aSdrochner 			LIST_REMOVE(wep, next);
128*1921d00aSdrochner 			return 0;
129*1921d00aSdrochner 		}
130*1921d00aSdrochner 	}
131*1921d00aSdrochner 	return ENOENT;
132*1921d00aSdrochner }
133