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 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 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 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 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 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 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