xref: /original-bsd/sys/luna68k/dev/bmc.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1992 OMRON Corporation.
3  * Copyright (c) 1992 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * OMRON Corporation.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)bmc.c	7.8 (Berkeley) 06/08/93
12  */
13 
14 #include "bmc.h"
15 #if NBMC > 0
16 
17 #include <sys/param.h>
18 #include <sys/systm.h>
19 #include <sys/ioctl.h>
20 #include <sys/proc.h>
21 #include <sys/tty.h>
22 #include <sys/conf.h>
23 #include <sys/file.h>
24 #include <sys/uio.h>
25 #include <sys/kernel.h>
26 #include <sys/syslog.h>
27 #include <machine/stinger.h>
28 #include <luna68k/dev/device.h>
29 #include <luna68k/dev/sioreg.h>
30 #include <luna68k/dev/siovar.h>
31 #include <luna68k/luna68k/cons.h>
32 
33 extern	struct sio_portc *sio_port_assign();
34 
35 int     bmcprobe();
36 int     bmcopen();
37 void    bmcstart();
38 int     bmcparam();
39 int     bmcintr();
40 
41 struct	driver bmcdriver = {
42 	bmcprobe, "bmc",
43 };
44 
45 struct	bmc_softc {
46 	struct sio_portc *sc_pc;
47 	int	sc_mask;
48 };
49 
50 struct	bmc_softc bmc_softc[NBMC];
51 
52 struct	tty bmc_tty[NBMC];
53 
54 int	bmc_active;
55 int	bmcconsole = -1;
56 int	bmcdefaultrate = B9600;				/* speed of console line is fixed */
57 int	bmcmajor = 13;
58 
59 #define	bmcunit(x)		minor(x)
60 
61 extern	struct tty *constty;
62 
63 /*
64  *  key-code decoding
65  */
66 
67 struct bmc_keymap {
68 	int	km_type;
69 	int	km_code[2];
70 };
71 
72 #define KC_CHAR		0x000000FF
73 #define KC_TYPE		0x0000FF00
74 #define	KC_CODE		0x00000000
75 #define	KC_SHIFT	0x00000100
76 #define	KC_IGNORE	0x0000FF00
77 
78 #define KS_SHIFT	0
79 #define KS_CTRL		1
80 #define KS_META		2
81 
82 struct bmc_keymap bmc_keymap[] = {
83 	KC_IGNORE,	0,		0,		/*   0 [0x00]	      */
84 	KC_IGNORE,	0,		0,		/*   1 [0x01]	      */
85 	KC_IGNORE,	0,		0,		/*   2 [0x02]	      */
86 	KC_IGNORE,	0,		0,		/*   3 [0x03]	      */
87 	KC_IGNORE,	0,		0,		/*   4 [0x04]	      */
88 	KC_IGNORE,	0,		0,		/*   5 [0x05]	      */
89 	KC_IGNORE,	0,		0,		/*   6 [0x06]	      */
90 	KC_IGNORE,	0,		0,		/*   7 [0x07]	      */
91 	KC_IGNORE,	0,		0,		/*   8 [0x08]	      */
92 	KC_CODE,	0x09,		0x09,		/*   9 [0x09]	TAB   */
93 	KC_SHIFT,	KS_CTRL,	KS_CTRL,	/*  10 [0x0A]	CTRL  */
94 	KC_IGNORE,	0,		0,		/*  11 [0x0B]	      */
95 	KC_SHIFT,	KS_SHIFT,	KS_SHIFT,	/*  12 [0x0C]	SHIFT */
96 	KC_SHIFT,	KS_SHIFT,	KS_SHIFT,	/*  13 [0x0D]	SHIFT */
97 	KC_IGNORE,	0,		0,		/*  14 [0x0E]	      */
98 	KC_SHIFT,	KS_META,	KS_META,	/*  15 [0x0F]	META  */
99 	KC_CODE,	0x1B,		0x1B,		/*  16 [0x10]	ESC   */
100 	KC_CODE,	0x08,		0x08,		/*  17 [0x11]	BS    */
101 	KC_CODE,	0x0D,		0x0D,		/*  18 [0x12]	CR    */
102 	KC_IGNORE,	0,		0,		/*  19 [0x13]	      */
103 	KC_CODE,	0x20,		0x20,		/*  20 [0x14]	SP    */
104 	KC_CODE,	0x7F,		0x7F,		/*  21 [0x15]	DEL   */
105 	KC_IGNORE,	0,		0,		/*  22 [0x16]	      */
106 	KC_IGNORE,	0,		0,		/*  23 [0x17]	      */
107 	KC_IGNORE,	0,		0,		/*  24 [0x18]	      */
108 	KC_IGNORE,	0,		0,		/*  25 [0x19]	      */
109 	KC_IGNORE,	0,		0,		/*  26 [0x1A]	      */
110 	KC_IGNORE,	0,		0,		/*  27 [0x1B]	      */
111 	KC_IGNORE,	0,		0,		/*  28 [0x1C]	      */
112 	KC_IGNORE,	0,		0,		/*  29 [0x1D]	      */
113 	KC_IGNORE,	0,		0,		/*  30 [0x1E]	      */
114 	KC_IGNORE,	0,		0,		/*  31 [0x1F]	      */
115 	KC_IGNORE,	0,		0,		/*  32 [0x20]	      */
116 	KC_IGNORE,	0,		0,		/*  33 [0x21]	      */
117 	KC_CODE,	0x31,		0x21,		/*  34 [0x22]	 1    */
118 	KC_CODE,	0x32,		0x22,		/*  35 [0x23]	 2    */
119 	KC_CODE,	0x33,		0x23,		/*  36 [0x24]	 3    */
120 	KC_CODE,	0x34,		0x24,		/*  37 [0x25]	 4    */
121 	KC_CODE,	0x35,		0x25,		/*  38 [0x26]	 5    */
122 	KC_CODE,	0x36,		0x26,		/*  39 [0x27]	 6    */
123 	KC_CODE,	0x37,		0x27,		/*  40 [0x28]	 7    */
124 	KC_CODE,	0x38,		0x28,		/*  41 [0x29]	 8    */
125 	KC_CODE,	0x39,		0x29,		/*  42 [0x2A]	 9    */
126 	KC_CODE,	0x30,		0x30,		/*  43 [0x2B]	 0    */
127 	KC_CODE,	0x2D,		0x3D,		/*  44 [0x2C]	 -    */
128 	KC_CODE,	0x5E,		0x7E,		/*  45 [0x2D]	 ^    */
129 	KC_CODE,	0x5C,		0x7C,		/*  46 [0x2E]	 \    */
130 	KC_IGNORE,	0,		0,		/*  47 [0x2F]	      */
131 	KC_IGNORE,	0,		0,		/*  48 [0x30]	      */
132 	KC_IGNORE,	0,		0,		/*  49 [0x31]	      */
133 	KC_CODE,	0x71,		0x51,		/*  50 [0x32]	 q    */
134 	KC_CODE,	0x77,		0x57,		/*  51 [0x33]	 w    */
135 	KC_CODE,	0x65,		0x45,		/*  52 [0x34]	 e    */
136 	KC_CODE,	0x72,		0x52,		/*  53 [0x35]	 r    */
137 	KC_CODE,	0x74,		0x54,		/*  54 [0x36]	 t    */
138 	KC_CODE,	0x79,		0x59,		/*  55 [0x37]	 y    */
139 	KC_CODE,	0x75,		0x55,		/*  56 [0x38]	 u    */
140 	KC_CODE,	0x69,		0x49,		/*  57 [0x39]	 i    */
141 	KC_CODE,	0x6F,		0x4F,		/*  58 [0x3A]	 o    */
142 	KC_CODE,	0x70,		0x50,		/*  59 [0x3B]	 p    */
143 	KC_CODE,	0x40,		0x60,		/*  60 [0x3C]	 @    */
144 	KC_CODE,	0x5B,		0x7B,		/*  61 [0x3D]	 [    */
145 	KC_IGNORE,	0,		0,		/*  62 [0x3E]	      */
146 	KC_IGNORE,	0,		0,		/*  63 [0x3F]	      */
147 	KC_IGNORE,	0,		0,		/*  64 [0x40]	      */
148 	KC_IGNORE,	0,		0,		/*  65 [0x41]	      */
149 	KC_CODE,	0x61,		0x41,		/*  66 [0x42]	 a    */
150 	KC_CODE,	0x73,		0x53,		/*  67 [0x43]	 s    */
151 	KC_CODE,	0x64,		0x44,		/*  68 [0x44]	 d    */
152 	KC_CODE,	0x66,		0x46,		/*  69 [0x45]	 f    */
153 	KC_CODE,	0x67,		0x47,		/*  70 [0x46]	 g    */
154 	KC_CODE,	0x68,		0x48,		/*  71 [0x47]	 h    */
155 	KC_CODE,	0x6A,		0x4A,		/*  72 [0x48]	 j    */
156 	KC_CODE,	0x6B,		0x4B,		/*  73 [0x49]	 k    */
157 	KC_CODE,	0x6C,		0x4C,		/*  74 [0x4A]	 l    */
158 	KC_CODE,	0x3B,		0x2B,		/*  75 [0x4B]	 ;    */
159 	KC_CODE,	0x3A,		0x2A,		/*  76 [0x4C]	 :    */
160 	KC_CODE,	0x5D,		0x7D,		/*  77 [0x4D]	 ]    */
161 	KC_IGNORE,	0,		0,		/*  78 [0x4E]	      */
162 	KC_IGNORE,	0,		0,		/*  79 [0x4F]	      */
163 	KC_IGNORE,	0,		0,		/*  80 [0x50]	      */
164 	KC_IGNORE,	0,		0,		/*  81 [0x51]	      */
165 	KC_CODE,	0x7A,		0x5A,		/*  82 [0x52]	 z    */
166 	KC_CODE,	0x78,		0x58,		/*  83 [0x53]	 x    */
167 	KC_CODE,	0x63,		0x43,		/*  84 [0x54]	 c    */
168 	KC_CODE,	0x76,		0x56,		/*  85 [0x55]	 v    */
169 	KC_CODE,	0x62,		0x42,		/*  86 [0x56]	 b    */
170 	KC_CODE,	0x6E,		0x4E,		/*  87 [0x57]	 n    */
171 	KC_CODE,	0x6D,		0x4D,		/*  88 [0x58]	 m    */
172 	KC_CODE,	0x2C,		0x3C,		/*  89 [0x59]	 ,    */
173 	KC_CODE,	0x2E,		0x3E,		/*  90 [0x5A]	 .    */
174 	KC_CODE,	0x2F,		0x3F,		/*  91 [0x5B]	 /    */
175 	KC_CODE,	0x5F,		0x5F,		/*  92 [0x5C]	 _    */
176 	KC_IGNORE,	0,		0,		/*  93 [0x5D]	      */
177 	KC_IGNORE,	0,		0,		/*  94 [0x5E]	      */
178 	KC_IGNORE,	0,		0,		/*  95 [0x5F]	      */
179 	KC_IGNORE,	0,		0,		/*  96 [0x60]	      */
180 	KC_IGNORE,	0,		0,		/*  97 [0x61]	      */
181 	KC_IGNORE,	0,		0,		/*  98 [0x62]	      */
182 	KC_IGNORE,	0,		0,		/*  99 [0x63]	      */
183 	KC_IGNORE,	0,		0,		/* 100 [0x64]	      */
184 	KC_IGNORE,	0,		0,		/* 101 [0x65]	      */
185 	KC_IGNORE,	0,		0,		/* 102 [0x66]	      */
186 	KC_IGNORE,	0,		0,		/* 103 [0x67]	      */
187 	KC_IGNORE,	0,		0,		/* 104 [0x68]	      */
188 	KC_IGNORE,	0,		0,		/* 105 [0x69]	      */
189 	KC_IGNORE,	0,		0,		/* 106 [0x6A]	      */
190 	KC_IGNORE,	0,		0,		/* 107 [0x6B]	      */
191 	KC_IGNORE,	0,		0,		/* 108 [0x6C]	      */
192 	KC_IGNORE,	0,		0,		/* 109 [0x6D]	      */
193 	KC_IGNORE,	0,		0,		/* 110 [0x6E]	      */
194 	KC_IGNORE,	0,		0,		/* 111 [0x6F]	      */
195 	KC_IGNORE,	0,		0,		/* 112 [0x70]	      */
196 	KC_IGNORE,	0,		0,		/* 113 [0x71]	      */
197 	KC_IGNORE,	0,		0,		/* 114 [0x72]	      */
198 	KC_IGNORE,	0,		0,		/* 115 [0x73]	      */
199 	KC_IGNORE,	0,		0,		/* 116 [0x74]	      */
200 	KC_IGNORE,	0,		0,		/* 117 [0x75]	      */
201 	KC_IGNORE,	0,		0,		/* 118 [0x76]	      */
202 	KC_IGNORE,	0,		0,		/* 119 [0x77]	      */
203 	KC_IGNORE,	0,		0,		/* 120 [0x78]	      */
204 	KC_IGNORE,	0,		0,		/* 121 [0x79]	      */
205 	KC_IGNORE,	0,		0,		/* 122 [0x7A]	      */
206 	KC_IGNORE,	0,		0,		/* 123 [0x7B]	      */
207 	KC_IGNORE,	0,		0,		/* 124 [0x7C]	      */
208 	KC_IGNORE,	0,		0,		/* 125 [0x7D]	      */
209 	KC_IGNORE,	0,		0,		/* 126 [0x7E]	      */
210 	KC_IGNORE,	0,		0,		/* 127 [0x7F]	      */
211 };
212 
213 int	shift_flag = 0;
214 int	ctrl_flag  = 0;
215 int	meta_flag  = 0;
216 
217 bmc_decode(code)
218 	register u_char code;
219 {
220 	register unsigned int c, updown;
221 
222 	if (code & 0x80)
223 		updown = 1;
224 	else
225 		updown = 0;
226 
227 	code &= 0x7F;
228 
229 	c = bmc_keymap[code].km_type;
230 
231 	switch(c) {
232 
233 	case KC_CODE:
234 		if (updown)
235 			c = KC_IGNORE;
236 		break;
237 
238 	case KC_SHIFT:
239 		switch(bmc_keymap[code].km_code[0]) {
240 		case KS_SHIFT:
241 			shift_flag = 1 - updown;
242 			break;
243 
244 		case KS_CTRL:
245 			ctrl_flag  = 1 - updown;
246 			break;
247 
248 		case KS_META:
249 			meta_flag  = 1 - updown;
250 			break;
251 		}
252 		break;
253 
254 	default:
255 		break;
256 	}
257 
258 	c |= bmc_keymap[code].km_code[shift_flag];
259 
260 	if (bmc_keymap[code].km_type == KC_CODE) {
261 		if (meta_flag)
262 			c |= 0x0080;
263 		if (ctrl_flag)
264 			c &= 0xFF1F;
265 	}
266 
267 	return(c);
268 }
269 
270 
271 /*
272  *  probe routine
273  */
274 
275 bmcprobe(hd)
276 	register struct hp_device *hd;
277 {
278 	int unit = hd->hp_unit;
279 	register struct bmc_softc *sc = &bmc_softc[unit];
280 	register struct sio_portc *pc;
281 
282 	if (sc->sc_pc != 0) {
283 		pc = sc->sc_pc;
284 		printf("bmc%d: port %d, address 0x%x, intr 0x%x (console)\n",
285 		       pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr);
286 		return(1);
287 	}
288 
289 	/*
290 	 * Check out bitmap Interface board
291 	 */
292 
293 	if (KernInter.plane == 0) {
294 		return(0);
295 	}
296 
297 	/* locate the major number */
298 	for (bmcmajor = 0; bmcmajor < nchrdev; bmcmajor++)
299 		if (cdevsw[bmcmajor].d_open == bmcopen)
300 			break;
301 
302 	sc->sc_pc = pc = sio_port_assign(BMC_PORT, bmcmajor, unit, bmcintr);
303 
304 	printf("bmc%d: port %d, address 0x%x, intr 0x%x\n",
305 	       pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr);
306 
307 	bmdinit();
308 
309 	bmc_active |= 1 << unit;
310 	return(1);
311 }
312 
313 /*
314  *  entry routines
315  */
316 
317 /* ARGSUSED */
318 #ifdef __STDC__
319 bmcopen(dev_t dev, int flag, int mode, struct proc *p)
320 #else
321 bmcopen(dev, flag, mode, p)
322 	dev_t dev;
323 	int flag, mode;
324 	struct proc *p;
325 #endif
326 {
327 	register struct tty *tp;
328 	register int unit;
329 	int error = 0;
330 
331 	unit = bmcunit(dev);
332 
333 	if (unit >= NBMC)
334 		return (ENXIO);
335 	if ((bmc_active & (1 << unit)) == 0)
336 		return (ENXIO);
337 
338 	tp = &bmc_tty[unit];
339 	tp->t_oproc = bmcstart;
340 	tp->t_param = bmcparam;
341 	tp->t_dev = dev;
342 	if ((tp->t_state & TS_ISOPEN) == 0) {
343 		tp->t_state |= TS_WOPEN;
344 		ttychars(tp);
345 		if (tp->t_ispeed == 0) {
346 			tp->t_iflag = TTYDEF_IFLAG;
347 			tp->t_oflag = TTYDEF_OFLAG;
348 			tp->t_cflag = TTYDEF_CFLAG;
349 /*			tp->t_cflag = (CREAD | CS8 | HUPCL);	*/
350 			tp->t_lflag = TTYDEF_LFLAG;
351 			tp->t_ispeed = tp->t_ospeed = bmcdefaultrate;
352 		}
353 		bmcparam(tp, &tp->t_termios);
354 		ttsetwater(tp);
355 	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
356 		return (EBUSY);
357 	tp->t_state |= TS_CARR_ON;
358 	(void) spltty();
359 	while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
360 	       (tp->t_state & TS_CARR_ON) == 0) {
361 		tp->t_state |= TS_WOPEN;
362 		if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
363 		    ttopen, 0))
364 			break;
365 	}
366 	(void) spl0();
367 	if (error == 0)
368 		error = (*linesw[tp->t_line].l_open)(dev, tp);
369 
370 	return (error);
371 }
372 
373 /*ARGSUSED*/
374 bmcclose(dev, flag, mode, p)
375 	dev_t dev;
376 	int flag, mode;
377 	struct proc *p;
378 {
379 	register struct tty *tp;
380 	register int unit;
381 
382 	unit = bmcunit(dev);
383 	tp = &bmc_tty[unit];
384 	(*linesw[tp->t_line].l_close)(tp, flag);
385 	ttyclose(tp);
386 	return (0);
387 }
388 
389 bmcread(dev, uio, flag)
390 	dev_t dev;
391 	struct uio *uio;
392 {
393 	register struct tty *tp = &bmc_tty[bmcunit(dev)];
394 
395 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
396 }
397 
398 bmcwrite(dev, uio, flag)
399 	dev_t dev;
400 	struct uio *uio;
401 {
402 	register int unit = bmcunit(dev);
403 	register struct tty *tp = &bmc_tty[unit];
404 
405 	if ((unit == bmcconsole) && constty &&
406 	    (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
407 		tp = constty;
408 
409 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
410 }
411 
412 /*
413  * Stop output on a line.
414  */
415 /*ARGSUSED*/
416 bmcstop(tp, flag)
417 	register struct tty *tp;
418 {
419 	register int s;
420 
421 	s = spltty();
422 	if (tp->t_state & TS_BUSY) {
423 		if ((tp->t_state&TS_TTSTOP)==0)
424 			tp->t_state |= TS_FLUSH;
425 	}
426 	splx(s);
427 }
428 
429 bmcioctl(dev, cmd, data, flag, p)
430 	dev_t dev;
431 	int cmd;
432 	caddr_t data;
433 	int flag;
434 	struct proc *p;
435 {
436 	register struct tty *tp;
437 	register int unit = bmcunit(dev);
438 	register int error;
439 
440 	tp = &bmc_tty[unit];
441 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
442 	if (error >= 0)
443 		return (error);
444 	error = ttioctl(tp, cmd, data, flag);
445 	if (error >= 0)
446 		return (error);
447 
448 	switch (cmd) {
449 	default:
450 		return (ENOTTY);
451 	}
452 	return (0);
453 }
454 
455 /*
456  *
457  */
458 void
459 bmcstart(tp)
460 	register struct tty *tp;
461 {
462 	int unit = bmcunit(tp->t_dev);
463 	register struct bmc_softc *sc = &bmc_softc[unit];
464 	register int cc, s;
465 	int hiwat = 0;
466 
467 	s = spltty();
468 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
469 		splx(s);
470 		return;
471 	}
472 	tp->t_state |= TS_BUSY;
473 	cc = tp->t_outq.c_cc;
474 	if (cc <= tp->t_lowat) {
475 		if (tp->t_state & TS_ASLEEP) {
476 			tp->t_state &= ~TS_ASLEEP;
477 			wakeup((caddr_t)&tp->t_outq);
478 		}
479 		selwakeup(&tp->t_wsel);
480 	}
481 	/*
482 	 * Limit the amount of output we do in one burst
483 	 * to prevent hogging the CPU.
484 	 */
485 	while (--cc >= 0) {
486 		register int c;
487 
488 		c = getc(&tp->t_outq);
489 		/*
490 		 * iteputchar() may take a long time and we don't want to
491 		 * block all interrupts for long periods of time.  Since
492 		 * there is no need to stay at high priority while outputing
493 		 * the character (since we don't have to worry about
494 		 * interrupts), we don't.  We just need to make sure that
495 		 * we don't reenter iteputchar, which is guarenteed by the
496 		 * earlier setting of TS_BUSY.
497 		 */
498 		splx(s);
499 		bmdputc(c & sc->sc_mask);
500 		spltty();
501 	}
502 	tp->t_state &= ~TS_BUSY;
503 	splx(s);
504 }
505 
506 bmcparam(tp, t)
507 	register struct tty *tp;
508 	register struct termios *t;
509 {
510 	int unit = bmcunit(tp->t_dev);
511 	register struct bmc_softc *sc = &bmc_softc[unit];
512 	register int cflag = t->c_cflag;
513 
514         /* and copy to tty */
515         tp->t_ispeed = t->c_ispeed;
516         tp->t_ospeed = t->c_ospeed;
517         tp->t_cflag = cflag;
518 
519 	/*
520 	 * change line speed
521 	 */
522 
523 	switch (cflag&CSIZE) {
524 	case CS5:
525 		sc->sc_mask = 0x1F ; break;
526 	case CS6:
527 		sc->sc_mask = 0x3F ; break;
528 	case CS7:
529 		sc->sc_mask = 0x7F ; break;
530 	case CS8:
531 		sc->sc_mask = 0xFF ; break;
532 	}
533 
534 	/*
535 	 * parity
536 	 */
537 
538 	/*
539 	 * stop bit
540 	 */
541 
542 	return (0);
543 }
544 
545 
546 /*
547  *  interrupt handling
548  */
549 
550 bmcintr(unit)
551 	register int unit;
552 {
553 	register struct siodevice *sio = bmc_softc[unit].sc_pc->pc_addr;
554 	register struct tty *tp;
555 	register u_char code;
556 	register int c;
557 	int s, rr;
558 
559 	tp = &bmc_tty[unit];
560 	rr = siogetreg(sio);
561 
562 	if (rr & RR_RXRDY) {
563 		code = sio->sio_data;
564 		c = bmc_decode(code);
565 		if (c & KC_TYPE)			/* skip special codes */
566 			return;
567 		code = (c & KC_CHAR);
568 		if ((tp->t_state & TS_ISOPEN) != 0)
569 			(*linesw[tp->t_line].l_rint)(code, tp);
570 	}
571 
572 	if (rr & RR_TXRDY) {
573 		sio->sio_cmd = WR0_RSTPEND;
574 	}
575 }
576 
577 /*
578  * Following are all routines needed for SIO to act as console
579  */
580 
581 bmccnprobe(cp)
582 	register struct consdev *cp;
583 {
584 
585 	if ((KernInter.dipsw & KIFF_DIPSW_NOBM) || (KernInter.plane == 0)) {
586 		cp->cn_pri = CN_DEAD;
587 		return;
588 	}
589 
590 	/* locate the major number */
591 	for (bmcmajor = 0; bmcmajor < nchrdev; bmcmajor++)
592 		if (cdevsw[bmcmajor].d_open == bmcopen)
593 			break;
594 
595 	/* initialize required fields */
596 	cp->cn_dev = makedev(bmcmajor, 0);
597 	cp->cn_tp  = &bmc_tty[0];
598 	cp->cn_pri = CN_INTERNAL;
599 }
600 
601 bmccninit(cp)
602 	struct consdev *cp;
603 {
604 	int unit = bmcunit(cp->cn_dev);
605 	register struct bmc_softc *sc = &bmc_softc[0];
606 
607 	sioinit((struct siodevice *) SIO_HARDADDR, bmcdefaultrate);
608 
609 	bmdinit();
610 
611 	/* port assign */
612 	sc->sc_pc = sio_port_assign(BMC_PORT, bmcmajor, 0, bmcintr);
613 
614 	bmcconsole = unit;
615 	bmc_active |= 1 << unit;
616 }
617 
618 bmccngetc(dev)
619 	dev_t dev;
620 {
621 	struct bmc_softc *sc = &bmc_softc[bmcunit(dev)];
622 	struct sio_portc *pc = sc->sc_pc;
623 	register int c;
624 	register u_char code;
625 
626 	do {
627 		code = sio_imgetc(pc->pc_addr);
628 	} while ((c = bmc_decode(code)) & KC_TYPE);
629 
630 	return(c);
631 }
632 
633 bmccnputc(dev, c)
634 	dev_t dev;
635 	int c;
636 {
637 	struct bmc_softc *sc = &bmc_softc[bmcunit(dev)];
638 	struct sio_portc *pc = sc->sc_pc;
639 
640 	bmdputc(c);
641 }
642 #endif
643