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