xref: /original-bsd/sys/news3400/iop/rs.c (revision 3a296e00)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: rs.c,v 4.300 91/06/09 06:43:03 root Rel41 $ SONY
11  *
12  *	@(#)rs.c	7.2 (Berkeley) 07/28/92
13  */
14 
15 /*	rs.c	6.1	83/07/29	*/
16 
17 #include "rs.h"
18 #if NRS > 0
19 /*
20  * RS driver
21  *
22  */
23 #include "../include/fix_machine_type.h"
24 
25 #if NBK > 0
26 #include "bk.h"
27 #endif
28 #include "param.h"
29 #include "conf.h"
30 #include "proc.h"
31 #include "user.h"
32 #include "kernel.h"
33 #include "ioctl.h"
34 #include "tty.h"
35 #include "buf.h"
36 #include "malloc.h"
37 
38 #ifdef CPU_SINGLE
39 #include "../hbdev/hbvar.h"
40 #else
41 #include "../iop/iopvar.h"
42 #endif
43 
44 #include "../iop/rsreg.h"
45 #include "../sio/sccparam.h"
46 
47 #define	RS_RXE	RXE
48 #define	RS_TXE	TXE
49 #define	RS_ON	(RXE|TXE|RTS|DTR)
50 #define	RS_OFF	TXE
51 #define	RS_RTS	RTS
52 #define	RS_DTR	DTR
53 #define	RS_CTS	CTS
54 #define	RS_DCD	DCD
55 #define	RS_DSR	DSR
56 #define	RS_RI	RI
57 #define	RS_BRK	XBREAK
58 
59 #ifdef AUTO_ENABLE
60 #define	RS_AUTO_ENABLE	AUTO_ENABLE
61 #endif
62 
63 #ifdef CPU_SINGLE
64 #define	iop_device	hb_device
65 #define	ii_unit		hi_unit
66 #define	ii_flags	hi_flags
67 #define	ii_alive	hi_alive
68 #endif
69 
70 /*
71  * Definition of the driver for the auto-configuration program.
72  */
73 int rsprobe(), rsattach(), rsrint(), rsxint(), rssint();
74 struct iop_device *rsinfo[NRS];
75 
76 #ifdef CPU_SINGLE
77 struct hb_driver rsdriver = { rsprobe, 0, rsattach, 0, 0, "rs", rsinfo };
78 #else
79 struct iop_driver rsdriver = { rsprobe, 0, rsattach, 0, "rs", rsinfo };
80 #endif
81 
82 /*
83  * Local variables for the driver
84  */
85 
86 struct	tty rs_tty[NRS*4];
87 char	rssoftCAR[NRS];
88 
89 int	rs_flags[NRS*4];
90 int	rs_param[NRS*4];
91 char	rs_active[NRS*4];
92 char	rs_stopped[NRS*4];
93 
94 int	rs_rate[NRS*4];
95 int	rs_average[NRS*4];
96 char	rs_timeout[NRS*4];
97 char	rs_watch;
98 
99 #ifndef lint
100 int	nrs = NRS*4;			/* used by iostat */
101 #endif
102 
103 extern	int tty00_is_console;
104 extern void rsstart();
105 extern void ttrstrt();
106 extern void rsctrl();
107 
108 #define	RS_CARR(unit) (rssoftCAR[(unit) >> 2] & (1 << ((unit) & 03)))
109 #define	RS_FLAG(unit, flag) (rs_flags[unit] & (flag))
110 
111 #define	RF_FLOWCTL	0x0010		/* use H/W flow control */
112 #define	RF_EXTCLK	0x0100		/* allow external clock */
113 #define	RF_NODELAY	0x1000		/* disable interrupt delay */
114 
115 /*
116  * Routine for configuration
117  */
118 /*ARGSUSED*/
119 rsprobe(ii)
120 	struct iop_device *ii;
121 {
122 
123 	return (rs_probe(ii));
124 }
125 
126 /*
127  * Routine called to attach a rs.
128  */
129 rsattach(ii)
130 	register struct iop_device *ii;
131 {
132 	int i;
133 
134 	rssoftCAR[ii->ii_unit] = ii->ii_flags;
135 	for (i = 0; i < 4; i++)
136 		rs_flags[ii->ii_unit * 4 + i] =
137 		    (ii->ii_flags >> i) & (RF_FLOWCTL|RF_EXTCLK|RF_NODELAY);
138 	if (rs_watch == 0) {
139 		rs_watchdog();
140 		rs_watch = 1;
141 	}
142 }
143 
144 rs_watchdog()
145 {
146 	register int unit, s;
147 
148 	for (unit = 0; unit < NRS*4; unit++) {
149 		if (rs_active[unit] == 0)
150 			continue;
151 		s = spltty();
152 		rs_average[unit] = (rs_average[unit] * 7 + rs_rate[unit]) >> 3;
153 		rs_rate[unit] = 0;
154 		(void) splx(s);
155 	}
156 	timeout(rs_watchdog, (caddr_t)0, hz / 10);
157 }
158 
159 /*
160  * Open a RS line. Turn on this rs if this is the first use of it.
161  */
162 /*ARGSUSED*/
163 rsopen(dev, flag, mode, p)
164 	dev_t dev;
165 	int flag, mode;
166 	struct proc *p;
167 {
168 	register int unit;
169 	register struct tty *tp;
170 	register struct iop_device *ii;
171 	int s;
172 
173 	unit = minor(dev);
174 	if (unit >= NRS*4 || (ii = rsinfo[unit >> 2]) == 0 || ii->ii_alive == 0)
175 		return (ENXIO);
176 	if (rs_active[unit] == 0) {
177 		if (rs_init(unit) < 0)
178 			return (ENXIO);
179 		rs_enable(unit);
180 		rs_active[unit] = 1;
181 	}
182 	tp = &rs_tty[unit];
183 	if (tp->t_state&TS_XCLUDE && curproc->p_ucred->cr_uid != 0)
184 		return (EBUSY);
185 	tp->t_addr = (caddr_t)0;
186 	tp->t_oproc = rsstart;
187 #ifdef notyet /* KU:XXX */
188 	tp->t_ctrlproc = rsctrl;
189 #endif
190 	/*
191 	 * If this is first open, initialze tty state to default.
192 	 */
193 	if ((tp->t_state & TS_ISOPEN) == 0) {
194 		tp->t_state |= TS_WOPEN;
195 		ttychars(tp);
196 		if (tp->t_ispeed == 0) {
197 			tp->t_iflag = TTYDEF_IFLAG;
198 			tp->t_oflag = TTYDEF_OFLAG;
199 			tp->t_cflag = TTYDEF_CFLAG;
200 			tp->t_lflag = TTYDEF_LFLAG;
201 			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
202 		}
203 		rsparam(tp, &tp->t_termios);
204 		ttsetwater(tp);
205 	}
206 	/*
207 	 * Wait receiver and status interrupt
208 	 */
209 	/*
210 	 * Wait for carrier, then process line discipline specific open.
211 	 */
212 	rsmctl(dev, RS_ON, DMSET);
213 	if (rs_param[unit] & DCD || RS_CARR(unit))
214 		tp->t_state |= TS_CARR_ON;
215 	s = spltty();		/* spl5 -> spltty, 90/02/28 sak */
216 	while ((tp->t_state & TS_CARR_ON) == 0) {
217 		tp->t_state |= TS_WOPEN;
218 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
219 	}
220 #ifdef notyet /* KU:XXX */
221 	if (RS_FLAG(unit, RF_FLOWCTL)) {
222 		tp->t_state |= TS_HFLWCTL;
223 		rsmctl(dev, RS_AUTO_ENABLE, DMBIS);
224 	} else {
225 		tp->t_state &= ~TS_HFLWCTL;
226 		rsmctl(dev, RS_AUTO_ENABLE, DMBIC);
227 	}
228 #endif
229 	(void) splx(s);
230 	return ((*linesw[tp->t_line].l_open)(dev, tp));
231 }
232 
233 /*
234  * Close a RS line.
235  */
236 /*ARGSUSED*/
237 rsclose(dev, flag)
238 	dev_t dev;
239 	int flag;
240 {
241 	register struct tty *tp;
242 	register unit;
243 
244 	unit = minor(dev);
245 	tp = &rs_tty[unit];
246 	(*linesw[tp->t_line].l_close)(tp);
247 	(void) rsmctl(unit, RS_BRK, DMBIC);
248 	if (tp->t_cflag & HUPCL || (tp->t_state & TS_ISOPEN) == 0)
249 		(void) rsmctl(unit, RS_OFF, DMSET);
250 	ttyclose(tp);
251 
252 	if (RS_FLAG(unit, RF_FLOWCTL))
253 		(void)rsmctl(unit, RS_RTS, DMBIC);
254 }
255 
256 rsread(dev, uio, flag)
257 	dev_t dev;
258 	struct uio *uio;
259 	int flag;
260 {
261 	register struct tty *tp;
262 
263 	tp = &rs_tty[minor(dev)];
264 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
265 }
266 
267 rswrite(dev, uio, flag)
268 	dev_t dev;
269 	struct uio *uio;
270 	int flag;
271 {
272 	register struct tty *tp;
273 
274 	tp = &rs_tty[minor(dev)];
275 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
276 }
277 
278 rsenable(unit)
279 	int unit;
280 {
281 
282 	rs_timeout[unit] = 0;
283 	rs_enable(unit);
284 }
285 
286 /*
287  * RS receiver interrupt.
288  */
289 _rsrint(unit, buf, n)
290 	register int unit;
291 	register char *buf;
292 	register int n;
293 {
294 	register struct iop_device *ii;
295 	register struct tty *tp;
296 	register int (*rint)();
297 
298 #ifdef notyet /* KU:XXX */
299 	intrcnt[INTR_RS0 + unit]++;
300 #endif
301 	ii = rsinfo[unit >> 2];
302 	if (ii == 0 || ii->ii_alive == 0)
303 		return;
304 	tp = &rs_tty[unit];
305 	if ((tp->t_state & TS_ISOPEN) == 0) {
306 		wakeup((caddr_t)&tp->t_rawq);
307 		goto enable;
308 	}
309 	/*
310 	 * Loop fetching characters from the silo for this
311 	 * rs until there are no more in the silo.
312 	 */
313 	rint = linesw[tp->t_line].l_rint;
314 	while (--n >= 0) {
315 #if NBK > 0
316 		if (tp->t_line == NETLDISC) {
317 			c &= 0177;
318 			BKINPUT(c, tp);
319 		} else
320 #endif /* NBK > 0 */
321 			(*rint)(*buf++, tp);
322 	}
323 enable:
324 	rs_rate[unit]++;
325 	if (rs_average[unit] >= 10 && RS_FLAG(unit, RF_NODELAY) == 0) {
326 		if (rs_timeout[unit] == 0) {
327 			rs_timeout[unit] = 1;
328 			timeout(rsenable, (caddr_t)unit, hz / 100);
329 		}
330 	} else
331 		rs_enable(unit);
332 }
333 
334 /*ARGSUSED*/
335 rsioctl(dev, cmd, data, flag)
336 	dev_t dev;
337 	caddr_t data;
338 {
339 	register struct tty *tp;
340 	register int unit = minor(dev);
341 	int error;
342 
343 	tp = &rs_tty[unit];
344 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
345 	if (error >= 0)
346 		return (error);
347 	error = ttioctl(tp, cmd, data, flag);
348 	if (error >= 0)
349 		return (error);
350 
351 	switch (cmd) {
352 
353 	case TIOCSBRK:
354 		(void) rsmctl(dev, RS_BRK, DMBIS);
355 		break;
356 
357 	case TIOCCBRK:
358 		(void) rsmctl(dev, RS_BRK, DMBIC);
359 		break;
360 
361 	case TIOCSDTR:
362 		(void) rsmctl(dev, RS_DTR|RS_RTS, DMBIS);
363 		break;
364 
365 	case TIOCCDTR:
366 		if (curproc->p_ucred->cr_uid &&
367 		    curproc->p_session->s_ttyp != tp)
368 			return (EACCES);
369 		(void) rsmctl(dev, RS_DTR|RS_RTS, DMBIC);
370 		break;
371 
372 	case TIOCMSET:
373 		(void) rsmctl(dev, dmtors(*(int *)data), DMSET);
374 		break;
375 
376 	case TIOCMBIS:
377 		(void) rsmctl(dev, dmtors(*(int *)data), DMBIS);
378 		break;
379 
380 	case TIOCMBIC:
381 		(void) rsmctl(dev, dmtors(*(int *)data), DMBIC);
382 		break;
383 
384 	case TIOCMGET:
385 		*(int *)data = rstodm(rsmctl(dev, 0, DMGET));
386 		break;
387 
388 	default:
389 		return (ENOTTY);
390 	}
391 	return (0);
392 }
393 
394 dmtors(bits)
395 	register int bits;
396 {
397 	register int b;
398 
399 	b = 0;
400 	if (bits & DML_LE)  b |= RS_TXE|RS_RXE;
401 	if (bits & DML_DTR) b |= RS_DTR;
402 	if (bits & DML_RTS) b |= RS_RTS;
403 	if (bits & DML_CTS) b |= RS_CTS;
404 	if (bits & DML_CAR) b |= RS_DCD;
405 	if (bits & DML_RNG) b |= RS_RI;
406 	if (bits & DML_DSR) b |= RS_DSR;
407 #ifdef AUTO_ENABLE
408 	if (bits & DML_USR) b |= RS_AUTO_ENABLE;
409 #endif /* AUTO_ENABLE */
410 	return(b);
411 }
412 
413 rstodm(bits)
414 	register int bits;
415 {
416 	register int b;
417 
418 	b = 0;
419 	if (bits & (RS_TXE|RS_RXE)) b |= DML_LE;
420 	if (bits & RS_DTR) b |= DML_DTR;
421 	if (bits & RS_RTS) b |= DML_RTS;
422 	if (bits & RS_CTS) b |= DML_CTS;
423 	if (bits & RS_DCD) b |= DML_CAR;
424 	if (bits & RS_RI)  b |= DML_RNG;
425 	if (bits & RS_DSR) b |= DML_DSR;
426 #ifdef AUTO_ENABLE
427 	if (bits & RS_AUTO_ENABLE) b |= DML_USR;
428 #endif
429 	return(b);
430 }
431 
432 /*
433  * compat table
434  */
435 struct speedtab rsspeedtab[] = {
436 	0,	0,
437 	50,	1,
438 	75,	2,
439 	110,	3,
440 	134,	4,
441 	150,	5,
442 	200,	6,
443 	300,	7,
444 	600,	8,
445 	1200,	9,
446 	1800,	10,
447 	2400,	11,
448 	4800,	12,
449 	9600,	13,
450 	19200,	14,
451 	38400,	15,
452 	-1,	-1
453 };
454 
455 /*
456  * Set parameters from open or stty into the RS hardware
457  * registers.
458  */
459 rsparam(tp, t)
460 	register struct tty *tp;
461 	register struct termios *t;
462 {
463 	register int param;
464 	register int cflag = t->c_cflag;
465 	int unit = minor(tp->t_dev);
466 	int s;
467 	int ospeed = ttspeedtab(t->c_ospeed, rsspeedtab);
468 
469 	/* check requested parameters */
470 	if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
471 	    (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6)
472 		return (EINVAL);
473 	/* and copy to tty */
474 	tp->t_ispeed = t->c_ispeed;
475 	tp->t_ospeed = t->c_ospeed;
476 	tp->t_cflag = cflag;
477 
478 	/*
479 	 * Block interrupts so parameters will be set
480 	 * before the line interrupts.
481 	 */
482 	s = spltty();
483 	if (tp->t_ospeed == 0) {
484 		tp->t_cflag |= HUPCL;
485 		(void) rsmctl(unit, RS_OFF, DMSET);
486 		(void) splx(s);
487 		return (0);
488 	}
489 
490 	param = rs_get_param(unit) &
491 		~(CHAR_SIZE|PARITY|EVEN|STOPBIT|BAUD_RATE|NOCHECK);
492 	if ((cflag & CREAD) == 0)
493 		param &= ~RXE;
494 	if (cflag & CS6)
495 		param |= C6BIT;
496 	if (cflag & CS7)
497 		param |= C7BIT;
498 	if (cflag & PARENB)
499 		param |= PARITY;
500 	if ((cflag & PARODD) == 0)
501 		param |= EVEN;
502 	if ((tp->t_iflag & INPCK) == 0)
503 		param |= NOCHECK;
504 	if (cflag & CSTOPB)
505 		param |= STOP2;
506 	else
507 		param |= STOP1;
508 
509 	rs_param[unit] = param | ospeed;
510 
511 	if (RS_FLAG(unit, RF_EXTCLK))
512 		rs_param[unit] |= EXTCLK_ENABLE;
513 	else
514 		rs_param[unit] &= ~EXTCLK_ENABLE;
515 	rs_set_param(unit, rs_param[unit]);
516 	(void) splx(s);
517 
518 	return (0);
519 }
520 
521 /*
522  * RS transmitter interrupt.
523  * Restart the idle line.
524  */
525 _rsxint(unit, count)
526 	int unit;
527 	int count;
528 {
529 	register struct tty *tp;
530 	register int s;
531 
532 #ifdef notyet /* KU:XXX */
533 	intrcnt[INTR_RS0 + unit]++;
534 #endif
535 	rs_stopped[unit] = 0;
536 	tp = &rs_tty[unit];
537 	tp->t_state &= ~TS_BUSY;
538 	s = spltty();
539 	if (tp->t_state & TS_FLUSH)
540 		tp->t_state &= ~TS_FLUSH;
541 	else
542 		ndflush(&tp->t_outq, count);
543 	(void) splx(s);
544 	if (tp->t_line)
545 		(*linesw[tp->t_line].l_start)(tp);
546 	else
547 		rsstart(tp);
548 }
549 
550 /*
551  * Start (restart) transmission on the given RS line.
552  */
553 void
554 rsstart(tp)
555 	register struct tty *tp;
556 {
557 	register int unit, nch;
558 	int s;
559 
560 	unit = minor(tp->t_dev);
561 
562 	/*
563 	 * Must hold interrupts in following code to prevent
564 	 * state of the tp from changing.
565 	 */
566 	s = spltty();
567 	/*
568 	 * If it's currently active, or delaying, no need to do anything.
569 	 */
570 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
571 		goto out;
572 	/*
573 	 * If ther are still characters in the IOP,
574 	 * just reenable transmit.
575 	 */
576 	if (rs_stopped[unit]) {
577 		rs_start(unit);
578 		rs_stopped[unit] = 0;
579 		goto out;
580 	}
581 	/*
582 	 * If there are sleepers, and output has drained below low
583 	 * water mark, wake up the sleepers.
584 	 */
585 	if (tp->t_outq.c_cc <= tp->t_lowat) {
586 		if (tp->t_state & TS_ASLEEP) {
587 			tp->t_state &= ~TS_ASLEEP;
588 			wakeup((caddr_t)&tp->t_outq);
589 		}
590 		selwakeup(&tp->t_wsel);
591 	}
592 	/*
593 	 * Now restart transmission unless the output queue is
594 	 * empty.
595 	 */
596 	if (tp->t_outq.c_cc == 0)
597 		goto out;
598 	if (tp->t_flags & (RAW|LITOUT))
599 		nch = ndqb(&tp->t_outq, 0);
600 	else {
601 		nch = ndqb(&tp->t_outq, 0200);
602 		/*
603 		 * If first thing on queue is a delay process it.
604 		 */
605 		if (nch == 0) {
606 			nch = getc(&tp->t_outq);
607 			timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
608 			tp->t_state |= TS_TIMEOUT;
609 			goto out;
610 		}
611 	}
612 	/*
613 	 * If characters to transmit, restart transmission.
614 	 */
615 	if (nch) {
616 		tp->t_state |= TS_BUSY;
617 		rs_output(unit, nch);
618 	}
619 out:
620 	(void) splx(s);
621 }
622 
623 /*
624  * Stop output on a line, e.g. for ^S/^Q or output flush.
625  */
626 /*ARGSUSED*/
627 rsstop(tp, flag)
628 	register struct tty *tp;
629 {
630 	register int unit, s;
631 
632 	unit = minor(tp->t_dev);
633 	s = spltty();
634 	if (tp->t_state & TS_BUSY) {
635 		rs_stop(unit, 0);
636 		rs_stopped[unit] = 1;
637 		if ((tp->t_state & TS_TTSTOP) == 0) {
638 			tp->t_state |= TS_FLUSH;
639 			rs_stop(unit, 1);
640 		}
641 	}
642 	(void) splx(s);
643 }
644 
645 /*
646  * RS modem control
647  */
648 rsmctl(dev, bits, how)
649 	dev_t dev;
650 	int bits, how;
651 {
652 	register int unit, mbits;
653 	int s;
654 
655 #ifdef AUTO_ENABLE
656 	bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK|RS_AUTO_ENABLE);
657 #else
658 	bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK);
659 #endif
660 
661 	unit = minor(dev);
662 	s = spltty();		/* spl5 -> spltty, 90/02/28 sak */
663 
664 	mbits = rs_get_param(unit);
665 	switch (how) {
666 
667 	case DMSET:
668 		mbits = mbits & ~(RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK) | bits;
669 		break;
670 
671 	case DMBIS:
672 		mbits |= bits;
673 		break;
674 
675 	case DMBIC:
676 		mbits &= ~bits;
677 		break;
678 
679 	case DMGET:
680 		(void) splx(s);
681 		return(mbits);
682 	}
683 	rs_param[unit] = mbits;
684 	rs_set_param(unit, rs_param[unit]);
685 
686 	(void) splx(s);
687 	return(mbits);
688 }
689 
690 /*
691  * Reset state of driver if IOP reset was necessary.
692  * Reset the parameter and status, and
693  * restart transmitters.
694  */
695 rsreset()
696 {
697 	register int unit;
698 	register struct tty *tp;
699 	register struct iop_device *ii;
700 
701 	for (unit = 0; unit < NRS * 4; unit++) {
702 		ii = rsinfo[unit >> 2];
703 		if (ii == 0 || ii->ii_alive == 0)
704 			continue;
705 		printf(" rs%d", unit);
706 		tp = &rs_tty[unit];
707 		if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
708 			rs_reset(unit);
709 			rsparam(tp, &tp->t_termios);
710 			(void) rsmctl(unit, RS_ON, DMSET);
711 			tp->t_state &= ~TS_BUSY;
712 			rsstart(tp);
713 		}
714 	}
715 }
716 
717 /*
718  * RS status interrupt
719  */
720 _rssint(unit, stat)
721 	int unit;
722 	int stat;
723 {
724 	register struct tty *tp;
725 
726 #ifdef notyet /* KU:XXX */
727 	intrcnt[INTR_RS0 + unit]++;
728 #endif
729 	tp = &rs_tty[unit];
730 	if (stat & RS_DCD) {
731 		rs_param[unit] |= RS_DCD;
732 		(void)(*linesw[tp->t_line].l_modem)(tp, 1);
733 	} else if (RS_CARR(unit) == 0 &&
734 	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
735 		rs_param[unit] &= ~(RS_DCD | RS_DTR);
736 		rs_set_param(unit, rs_param[unit]);
737 	}
738 	if (stat & OVERRUN_ERROR) {
739 		printf("rs%d: fifo overflow\n", unit);
740 		rs_param[unit] &= ~OVERRUN_ERROR;
741 		rs_set_param(unit, rs_param[unit]);
742 	}
743 	if (stat & RBREAK) {
744 		rs_param[unit] &= ~RBREAK;
745 		if (tp->t_state & TS_ISOPEN)
746 			(*linesw[tp->t_line].l_rint)
747 			    (tp->t_flags & RAW ? '\0' : tp->t_cc[VINTR], tp);
748 	}
749 }
750 
751 /*
752  * RS control interrupt
753  */
754 rscint(rs)
755 	int rs;
756 {
757 
758 	printf("rscint: %d\n", rs);
759 }
760 
761 /*
762  * RS H/W control
763  */
764 void
765 rsctrl(tp, cmd, arg)
766 	struct tty *tp;
767 	int cmd;
768 	int arg;
769 {
770 #ifdef notyet /* KU:XXX */
771 	int unit = minor(tp->t_dev);
772 
773 	switch (cmd) {
774 
775 	case TC_HBLOCK:
776 		if (RS_FLAG(unit, RF_FLOWCTL))
777 			rsflowctl(unit, arg);
778 		break;
779 
780 	default:
781 		break;
782 	}
783 
784 	return (0);
785 #endif
786 }
787 
788 rsflowctl(unit, block)
789 	int unit;
790 	int block;
791 {
792 	int s;
793 
794 	s = spltty();
795 	if (block)
796 		rs_param[unit] &= ~RS_RTS;
797 	else
798 		rs_param[unit] |= RS_RTS;
799 	rs_set_param(unit, rs_param[unit]);
800 	(void) splx(s);
801 }
802 
803 /*
804  * Machine dependent functions
805  *
806  *	rs_probe()
807  *	rs_init()
808  *	rsrint()
809  *	rsxint()
810  *	rssint()
811  *	rs_enable()
812  *	rs_output()
813  *	rs_start()
814  *	rs_stop()
815  *	rs_reset()
816  *	rs_get_param()
817  *	rs_set_param()
818  */
819 #ifdef CPU_SINGLE
820 #include "../hbdev/hbvar.h"
821 #include "../hbdev/rsreg.h"
822 #include "../sio/scc.h"
823 
824 int	rslastcount[NRS*4];
825 int	scc_unit[] = { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 };
826 int	rs_unit[] = { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11 };
827 
828 rs_probe(hi)
829 	struct hb_device *hi;
830 {
831 	register int i, cmax;
832 
833 	for (i = (hi->hi_unit << 2), cmax = 4; cmax > 0; cmax--, i++) {
834 		if (i == 2 || i == 3)
835 			continue;
836 		if (scc_probe(scc_unit[i]))
837 			continue;
838 		return (0);
839 	}
840 	return (1);
841 }
842 
843 rs_init(unit)
844 	int unit;
845 {
846 
847 	if (scc_open(scc_unit[unit])) {
848 		printf("rs_init: chan %d open failed.\n", scc_unit[unit]);
849 		return (-1);
850 	}
851 	return (0);
852 }
853 
854 rs_enable(unit)
855 	int unit;
856 {
857 
858 	scc_enable(scc_unit[unit]);
859 }
860 
861 rsrint(scc, buf, cnt)
862 	int scc;
863 	char *buf;
864 	int cnt;
865 {
866 
867 	_rsrint(rs_unit[scc], buf, cnt);
868 }
869 
870 rsxint(scc)
871 	int scc;
872 {
873 	int unit = rs_unit[scc];
874 
875 	_rsxint(unit, rslastcount[unit]);
876 }
877 
878 rssint(scc, stat)
879 	int scc;
880 	int stat;
881 {
882 
883 	_rssint(rs_unit[scc], stat);
884 }
885 
886 rs_start(unit)
887 	int unit;
888 {
889 
890 	scc_start(scc_unit[unit]);
891 }
892 
893 rs_output(unit, n)
894 	int unit;
895 	int n;
896 {
897 
898 	rslastcount[unit] =
899 	    scc_write(scc_unit[unit], rs_tty[unit].t_outq.c_cf, n);
900 }
901 
902 rs_stop(unit, flush)
903 	int unit;
904 	int flush;
905 {
906 
907 	if (flush)
908 		scc_flush(scc_unit[unit]);
909 }
910 
911 rs_reset(unit)
912 	int unit;
913 {
914 
915 	scc_reset(scc_unit[unit]);
916 }
917 
918 rs_get_param(unit)
919 	int unit;
920 {
921 
922 	return (scc_get_param(scc_unit[unit]));
923 }
924 
925 rs_set_param(unit, param)
926 	int unit;
927 	int param;
928 {
929 
930 	scc_set_param(scc_unit[unit], param);
931 }
932 #endif /* CPU_SINGLE */
933 
934 #ifdef IPC_MRX
935 #include "../ipc/newsipc.h"
936 #include "../mrx/h/scc.h"
937 #include "../mrx/h/cio.h"
938 
939 int	port_rsrecv[NRS*4];
940 int	port_rsxmit[NRS*4];
941 int	port_rsstat[NRS*4];
942 int	port_rsctrl[NRS*4];
943 int	port_recv_iop[NRS*4];
944 int	port_xmit_iop[NRS*4];
945 int	port_ctrl_iop[NRS*4];
946 int	port_stat_iop[NRS*4];
947 
948 /*
949  *	minor No: 0 - 12 ----> SCC unit No : 0 - 9
950  */
951 int	scc_unit[] = { 1, 0, -1, -1, 3, 2, 5, 4, 7, 6, 9, 8 };
952 
953 rs_probe(ii)
954 	struct iop_device *ii;
955 {
956 	register int base = ii->ii_unit << 2;
957 	register int i, j;
958 	char buf[16];
959 
960 #define	PT_CREATE(buf, name, unit, func, arg)	\
961 	port_create(make_name(buf, name, unit), func, arg)
962 #define	OB_QUERY(buf, name, unit) \
963 	object_query(make_name(buf, name, unit))
964 	for (i = base; i < base+4; i++) {
965 		if ((j = scc_unit[i]) < 0)
966 			continue;
967 		port_recv_iop[i] = OB_QUERY(buf, "scc_inputX", j);
968 		if (port_recv_iop[i] <= 0)
969 			return (0);
970 		port_xmit_iop[i] = OB_QUERY(buf, "scc_outputX", j);
971 		port_ctrl_iop[i] = OB_QUERY(buf, "scc_ctrlX", j);
972 		port_stat_iop[i] = OB_QUERY(buf, "scc_statX", j);
973 
974 		port_rsrecv[i] = PT_CREATE(buf, "@rsrecvX", j, rsrint, i);
975 		port_rsxmit[i] = PT_CREATE(buf, "@rsxmitX", j, rsxint, i);
976 		port_rsctrl[i] = PT_CREATE(buf, "@rsctrlX", j, NULL, 0);
977 		port_rsstat[i] = PT_CREATE(buf, "@rsstatX", j, rssint, i);
978 	}
979 	return (1);
980 }
981 
982 rs_init(unit)
983 	int unit;
984 {
985 	int len;
986 
987 	msg_send(port_stat_iop[unit], port_rsstat[unit], NULL, 0, 0);
988 	return (0);
989 }
990 
991 rs_enable(unit)
992 	int unit;
993 {
994 	int len;
995 
996 	len = MAX_CIO;
997 	msg_send(port_recv_iop[unit], port_rsrecv[unit], &len, sizeof(len), 0);
998 }
999 
1000 rsrint(unit)
1001 	register int	unit;
1002 {
1003 	char *addr;
1004 	int from, len;
1005 
1006 	msg_recv(port_rsrecv[unit], &from, &addr, &len, 0);
1007 #ifdef mips
1008 	clean_dcache(addr, len + 8);
1009 #endif
1010 	_rsrint(unit, addr, len);
1011 }
1012 
1013 rsxint(unit)
1014 	register int unit;
1015 {
1016 	int from, *len;
1017 
1018 	msg_recv(port_rsxmit[unit], &from, &len, NULL, 0);
1019 	_rsxint(unit, *len);
1020 }
1021 
1022 rssint(unit)
1023 	register int unit;
1024 {
1025 	int from, *reply;
1026 
1027 	msg_recv(port_rsstat[unit], &from, &reply, NULL, 0);
1028 	_rssint(unit, *reply);
1029 	msg_send(from, port_rsstat[unit], NULL, 0, 0);
1030 }
1031 
1032 rs_start(unit)
1033 	int unit;
1034 {
1035 	int func;
1036 
1037 	func = CIO_START;
1038 	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
1039 }
1040 
1041 rs_output(unit, n)
1042 	int unit;
1043 	int n;
1044 {
1045 
1046 	msg_send(port_xmit_iop[unit], port_rsxmit[unit],
1047 	    rs_tty[unit].t_outq.c_cf, min(n, MAX_CIO), 0);
1048 }
1049 
1050 rs_stop(unit, flush)
1051 	int unit;
1052 	int flush;
1053 {
1054 	int func;
1055 
1056 	func = flush ? CIO_FLUSH : CIO_STOP;
1057 	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
1058 }
1059 
1060 rs_reset(unit)
1061 	int unit;
1062 {
1063 	int func;
1064 
1065 	func = CIO_RESET;
1066 	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
1067 }
1068 
1069 rs_get_param(unit)
1070 	register int unit;
1071 {
1072 	register int port;
1073 	struct scc_ctrl_req req;
1074 	int param, *reply;
1075 
1076 	port = port_rsctrl[unit];
1077 	req.scc_func = CIO_GETPARAMS;
1078 
1079 	/* message length 8 means 2 * sizeof(int) : func and status */
1080 	msg_send(port_ctrl_iop[unit], port, &req, 8, 0);
1081 	msg_recv(port, NULL, &reply, NULL, 0);
1082 
1083 	param = *reply;
1084 	msg_free(port);
1085 
1086 	return (param);
1087 }
1088 
1089 rs_set_param(unit, param)
1090 	register int unit;
1091 	int param;
1092 {
1093 	struct scc_ctrl_req req;
1094 
1095 	req.scc_func = CIO_SETPARAMS;
1096 	req.scc_arg = param;
1097 
1098 	/* message length 8 means 2 * sizeof(int) : func and param */
1099 	msg_send(port_ctrl_iop[unit], 0, &req, 8, 0);
1100 }
1101 #endif /* IPC_MRX */
1102 #endif /* NRS > 0 */
1103