xref: /netbsd-src/sys/dev/rcons/rcons_kern.c (revision 454af1c0e885cbba6b59706391f770d646303f8c)
1 /*	$NetBSD: rcons_kern.c,v 1.22 2009/03/14 15:36:20 dsl Exp $ */
2 
3 /*
4  * Copyright (c) 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This software was developed by the Computer Systems Engineering group
8  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9  * contributed to Berkeley.
10  *
11  * All advertising materials mentioning features or use of this software
12  * must display the following acknowledgement:
13  *	This product includes software developed by the University of
14  *	California, Lawrence Berkeley Laboratory.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  *	@(#)rcons_kern.c	8.1 (Berkeley) 6/11/93
41  */
42 
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: rcons_kern.c,v 1.22 2009/03/14 15:36:20 dsl Exp $");
45 
46 #include <sys/param.h>
47 #include <sys/device.h>
48 #include <sys/kernel.h>
49 #include <sys/systm.h>
50 #include <sys/ioctl.h>
51 #include <sys/tty.h>
52 #include <sys/proc.h>
53 
54 #include <dev/rcons/raster.h>
55 #include <dev/rcons/rcons.h>
56 
57 static void rcons_belltmr(void *);
58 
59 static struct rconsole *mydevicep; /* XXX */
60 static void rcons_output(struct tty *);
61 
62 void
rcons_cnputc(int c)63 rcons_cnputc(int c)
64 {
65 	char buf[1];
66 	long attr;
67 
68 	/* Swap in kernel attribute */
69 	attr = mydevicep->rc_attr;
70 	mydevicep->rc_attr = mydevicep->rc_kern_attr;
71 
72 	if (c == '\n')
73 		rcons_puts(mydevicep, "\r\n", 2);
74 	else {
75 		buf[0] = c;
76 		rcons_puts(mydevicep, buf, 1);
77 	}
78 
79 	/* Swap out kernel attribute */
80 	mydevicep->rc_attr = attr;
81 }
82 
83 static void
rcons_output(struct tty * tp)84 rcons_output(struct tty *tp)
85 {
86 	int s, n;
87 	char buf[OBUFSIZ];
88 
89 	s = spltty();
90 	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) {
91 		splx(s);
92 		return;
93 	}
94 	tp->t_state |= TS_BUSY;
95 	splx(s);
96 	n = q_to_b(&tp->t_outq, buf, sizeof(buf));
97 	rcons_puts(mydevicep, buf, n);
98 
99 	s = spltty();
100 	tp->t_state &= ~TS_BUSY;
101 	/* Come back if there's more to do */
102 	if (ttypull(tp)) {
103 		tp->t_state |= TS_TIMEOUT;
104 		callout_schedule(&tp->t_rstrt_ch, 1);
105 	}
106 	splx(s);
107 }
108 
109 /* Ring the console bell */
110 void
rcons_bell(struct rconsole * rc)111 rcons_bell(struct rconsole *rc)
112 {
113 	int i, s;
114 
115 	if (rc->rc_bits & FB_VISBELL) {
116 		/* invert the screen twice */
117 		i = ((rc->rc_bits & FB_INVERT) == 0);
118 		rcons_invert(rc, i);
119 		rcons_invert(rc, i ^ 1);
120 	}
121 
122 	s = splhigh();
123 	if (rc->rc_belldepth++) {
124 		if (rc->rc_belldepth > 3)
125 			rc->rc_belldepth = 3;
126 		splx(s);
127 	} else {
128 		rc->rc_ringing = 1;
129 		splx(s);
130 		(*rc->rc_bell)(1);
131 		/* XXX Chris doesn't like the following divide */
132 		callout_reset(&rc->rc_belltmr_ch, hz / 10,
133 		    rcons_belltmr, rc);
134 	}
135 }
136 
137 /* Bell timer service routine */
138 static void
rcons_belltmr(void * p)139 rcons_belltmr(void *p)
140 {
141 	struct rconsole *rc = p;
142 	int s = splhigh(), i;
143 
144 	if (rc->rc_ringing) {
145 		rc->rc_ringing = 0;
146 		i = --rc->rc_belldepth;
147 		splx(s);
148 		(*rc->rc_bell)(0);
149 		if (i != 0)
150 			/* XXX Chris doesn't like the following divide */
151 			callout_reset(&rc->rc_belltmr_ch, hz / 30,
152 			    rcons_belltmr, rc);
153 	} else {
154 		rc->rc_ringing = 1;
155 		splx(s);
156 		(*rc->rc_bell)(1);
157 		callout_reset(&rc->rc_belltmr_ch, hz / 10,
158 		    rcons_belltmr, rc);
159 	}
160 }
161 
162 void
rcons_init(struct rconsole * rc,int clear)163 rcons_init(struct rconsole *rc, int clear)
164 {
165 	mydevicep = rc;
166 
167 	callout_init(&rc->rc_belltmr_ch, 0);
168 
169 	/* Initialize operations set, clear screen and turn cursor on */
170 	rcons_init_ops(rc);
171 	if (clear) {
172 		rc->rc_col = 0;
173 		rc->rc_row = 0;
174 		rcons_clear2eop(rc);
175 	}
176 	rcons_cursor(rc);
177 }
178 
179 void
rcons_ttyinit(struct tty * tp)180 rcons_ttyinit(struct tty *tp)
181 {
182 	/* XXX this should go away */
183 	struct rconsole *rc = mydevicep;
184 	struct winsize *ws;
185 
186 	if (rc == NULL)
187 		return;
188 
189 	/* Let the system know how big the console is */
190 	ws = &tp->t_winsize;
191 	ws->ws_row = rc->rc_maxrow;
192 	ws->ws_col = rc->rc_maxcol;
193 	ws->ws_xpixel = rc->rc_width;
194 	ws->ws_ypixel = rc->rc_height;
195 
196 	/* Initialization done; hook us up */
197 	tp->t_oproc = rcons_output;
198 	/*tp->t_stop = (void (*)()) nullop;*/
199 }
200