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