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