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