xref: /csrg-svn/sys/news3400/iop/rs.c (revision 63308)
153887Smckusick /*
2*63308Sbostic  * Copyright (c) 1992, 1993
3*63308Sbostic  *	The Regents of the University of California.  All rights reserved.
453887Smckusick  *
553887Smckusick  * This code is derived from software contributed to Berkeley by
653887Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753887Smckusick  *
853887Smckusick  * %sccs.include.redist.c%
953887Smckusick  *
1053887Smckusick  * from: $Hdr: rs.c,v 4.300 91/06/09 06:43:03 root Rel41 $ SONY
1153887Smckusick  *
12*63308Sbostic  *	@(#)rs.c	8.1 (Berkeley) 06/11/93
1353887Smckusick  */
1453887Smckusick 
1553887Smckusick /*	rs.c	6.1	83/07/29	*/
1653887Smckusick 
1753887Smckusick #include "rs.h"
1853887Smckusick #if NRS > 0
1953887Smckusick /*
2053887Smckusick  * RS driver
2153887Smckusick  *
2253887Smckusick  */
2353887Smckusick #if NBK > 0
2453887Smckusick #include "bk.h"
2553887Smckusick #endif
2657183Sutashiro #include <sys/param.h>
2757183Sutashiro #include <sys/conf.h>
2857183Sutashiro #include <sys/proc.h>
2957183Sutashiro #include <sys/user.h>
3057183Sutashiro #include <sys/kernel.h>
3157183Sutashiro #include <sys/ioctl.h>
3257183Sutashiro #include <sys/tty.h>
3357183Sutashiro #include <sys/buf.h>
3457183Sutashiro #include <sys/malloc.h>
3553887Smckusick 
3653887Smckusick #ifdef CPU_SINGLE
3757183Sutashiro #include <news3400/hbdev/hbvar.h>
3853887Smckusick #else
3953887Smckusick #include "../iop/iopvar.h"
4053887Smckusick #endif
4153887Smckusick 
4257183Sutashiro #include <news3400/iop/rsreg.h>
4357183Sutashiro #include <news3400/sio/sccparam.h>
4453887Smckusick 
4553887Smckusick #define	RS_RXE	RXE
4653887Smckusick #define	RS_TXE	TXE
4753887Smckusick #define	RS_ON	(RXE|TXE|RTS|DTR)
4853887Smckusick #define	RS_OFF	TXE
4953887Smckusick #define	RS_RTS	RTS
5053887Smckusick #define	RS_DTR	DTR
5153887Smckusick #define	RS_CTS	CTS
5253887Smckusick #define	RS_DCD	DCD
5353887Smckusick #define	RS_DSR	DSR
5453887Smckusick #define	RS_RI	RI
5553887Smckusick #define	RS_BRK	XBREAK
5653887Smckusick 
5753887Smckusick #ifdef AUTO_ENABLE
5853887Smckusick #define	RS_AUTO_ENABLE	AUTO_ENABLE
5953887Smckusick #endif
6053887Smckusick 
6153887Smckusick #ifdef CPU_SINGLE
6253887Smckusick #define	iop_device	hb_device
6353887Smckusick #define	ii_unit		hi_unit
6453887Smckusick #define	ii_flags	hi_flags
6553887Smckusick #define	ii_alive	hi_alive
6653887Smckusick #endif
6753887Smckusick 
6853887Smckusick /*
6953887Smckusick  * Definition of the driver for the auto-configuration program.
7053887Smckusick  */
7153887Smckusick int rsprobe(), rsattach(), rsrint(), rsxint(), rssint();
7253887Smckusick struct iop_device *rsinfo[NRS];
7353887Smckusick 
7453887Smckusick #ifdef CPU_SINGLE
7553887Smckusick struct hb_driver rsdriver = { rsprobe, 0, rsattach, 0, 0, "rs", rsinfo };
7653887Smckusick #else
7753887Smckusick struct iop_driver rsdriver = { rsprobe, 0, rsattach, 0, "rs", rsinfo };
7853887Smckusick #endif
7953887Smckusick 
8053887Smckusick /*
8153887Smckusick  * Local variables for the driver
8253887Smckusick  */
8353887Smckusick 
8453887Smckusick struct	tty rs_tty[NRS*4];
8553887Smckusick char	rssoftCAR[NRS];
8653887Smckusick 
8753887Smckusick int	rs_flags[NRS*4];
8853887Smckusick int	rs_param[NRS*4];
8953887Smckusick char	rs_active[NRS*4];
9053887Smckusick char	rs_stopped[NRS*4];
9153887Smckusick 
9253887Smckusick int	rs_rate[NRS*4];
9353887Smckusick int	rs_average[NRS*4];
9453887Smckusick char	rs_timeout[NRS*4];
9553887Smckusick char	rs_watch;
9653887Smckusick 
9753887Smckusick #ifndef lint
9853887Smckusick int	nrs = NRS*4;			/* used by iostat */
9953887Smckusick #endif
10053887Smckusick 
10153887Smckusick extern	int tty00_is_console;
10253887Smckusick extern void rsstart();
10353887Smckusick extern void ttrstrt();
10453887Smckusick extern void rsctrl();
10553887Smckusick 
10653887Smckusick #define	RS_CARR(unit) (rssoftCAR[(unit) >> 2] & (1 << ((unit) & 03)))
10753887Smckusick #define	RS_FLAG(unit, flag) (rs_flags[unit] & (flag))
10853887Smckusick 
10953887Smckusick #define	RF_FLOWCTL	0x0010		/* use H/W flow control */
11053887Smckusick #define	RF_EXTCLK	0x0100		/* allow external clock */
11153887Smckusick #define	RF_NODELAY	0x1000		/* disable interrupt delay */
11253887Smckusick 
11353887Smckusick /*
11453887Smckusick  * Routine for configuration
11553887Smckusick  */
11653887Smckusick /*ARGSUSED*/
11753887Smckusick rsprobe(ii)
11853887Smckusick 	struct iop_device *ii;
11953887Smckusick {
12053887Smckusick 
12153887Smckusick 	return (rs_probe(ii));
12253887Smckusick }
12353887Smckusick 
12453887Smckusick /*
12553887Smckusick  * Routine called to attach a rs.
12653887Smckusick  */
rsattach(ii)12753887Smckusick rsattach(ii)
12853887Smckusick 	register struct iop_device *ii;
12953887Smckusick {
13053887Smckusick 	int i;
13153887Smckusick 
13253887Smckusick 	rssoftCAR[ii->ii_unit] = ii->ii_flags;
13353887Smckusick 	for (i = 0; i < 4; i++)
13453887Smckusick 		rs_flags[ii->ii_unit * 4 + i] =
13553887Smckusick 		    (ii->ii_flags >> i) & (RF_FLOWCTL|RF_EXTCLK|RF_NODELAY);
13653887Smckusick 	if (rs_watch == 0) {
13753887Smckusick 		rs_watchdog();
13853887Smckusick 		rs_watch = 1;
13953887Smckusick 	}
14053887Smckusick }
14153887Smckusick 
rs_watchdog()14253887Smckusick rs_watchdog()
14353887Smckusick {
14453887Smckusick 	register int unit, s;
14553887Smckusick 
14653887Smckusick 	for (unit = 0; unit < NRS*4; unit++) {
14753887Smckusick 		if (rs_active[unit] == 0)
14853887Smckusick 			continue;
14953887Smckusick 		s = spltty();
15053887Smckusick 		rs_average[unit] = (rs_average[unit] * 7 + rs_rate[unit]) >> 3;
15153887Smckusick 		rs_rate[unit] = 0;
15253887Smckusick 		(void) splx(s);
15353887Smckusick 	}
15453887Smckusick 	timeout(rs_watchdog, (caddr_t)0, hz / 10);
15553887Smckusick }
15653887Smckusick 
15753887Smckusick /*
15853887Smckusick  * Open a RS line. Turn on this rs if this is the first use of it.
15953887Smckusick  */
16053887Smckusick /*ARGSUSED*/
rsopen(dev,flag,mode,p)16153887Smckusick rsopen(dev, flag, mode, p)
16253887Smckusick 	dev_t dev;
16353887Smckusick 	int flag, mode;
16453887Smckusick 	struct proc *p;
16553887Smckusick {
16653887Smckusick 	register int unit;
16753887Smckusick 	register struct tty *tp;
16853887Smckusick 	register struct iop_device *ii;
16953887Smckusick 	int s;
17053887Smckusick 
17153887Smckusick 	unit = minor(dev);
17253887Smckusick 	if (unit >= NRS*4 || (ii = rsinfo[unit >> 2]) == 0 || ii->ii_alive == 0)
17353887Smckusick 		return (ENXIO);
17453887Smckusick 	if (rs_active[unit] == 0) {
17553887Smckusick 		if (rs_init(unit) < 0)
17653887Smckusick 			return (ENXIO);
17753887Smckusick 		rs_enable(unit);
17853887Smckusick 		rs_active[unit] = 1;
17953887Smckusick 	}
18053887Smckusick 	tp = &rs_tty[unit];
18153887Smckusick 	if (tp->t_state&TS_XCLUDE && curproc->p_ucred->cr_uid != 0)
18253887Smckusick 		return (EBUSY);
18353887Smckusick 	tp->t_addr = (caddr_t)0;
18453887Smckusick 	tp->t_oproc = rsstart;
18553887Smckusick #ifdef notyet /* KU:XXX */
18653887Smckusick 	tp->t_ctrlproc = rsctrl;
18753887Smckusick #endif
18853887Smckusick 	/*
18953887Smckusick 	 * If this is first open, initialze tty state to default.
19053887Smckusick 	 */
19153887Smckusick 	if ((tp->t_state & TS_ISOPEN) == 0) {
19253887Smckusick 		tp->t_state |= TS_WOPEN;
19353887Smckusick 		ttychars(tp);
19453887Smckusick 		if (tp->t_ispeed == 0) {
19553887Smckusick 			tp->t_iflag = TTYDEF_IFLAG;
19653887Smckusick 			tp->t_oflag = TTYDEF_OFLAG;
19753887Smckusick 			tp->t_cflag = TTYDEF_CFLAG;
19853887Smckusick 			tp->t_lflag = TTYDEF_LFLAG;
19953887Smckusick 			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
20053887Smckusick 		}
20153887Smckusick 		rsparam(tp, &tp->t_termios);
20253887Smckusick 		ttsetwater(tp);
20353887Smckusick 	}
20453887Smckusick 	/*
20553887Smckusick 	 * Wait receiver and status interrupt
20653887Smckusick 	 */
20753887Smckusick 	/*
20853887Smckusick 	 * Wait for carrier, then process line discipline specific open.
20953887Smckusick 	 */
21053887Smckusick 	rsmctl(dev, RS_ON, DMSET);
21153887Smckusick 	if (rs_param[unit] & DCD || RS_CARR(unit))
21253887Smckusick 		tp->t_state |= TS_CARR_ON;
21353887Smckusick 	s = spltty();		/* spl5 -> spltty, 90/02/28 sak */
21453887Smckusick 	while ((tp->t_state & TS_CARR_ON) == 0) {
21553887Smckusick 		tp->t_state |= TS_WOPEN;
21653887Smckusick 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
21753887Smckusick 	}
21853887Smckusick #ifdef notyet /* KU:XXX */
21953887Smckusick 	if (RS_FLAG(unit, RF_FLOWCTL)) {
22053887Smckusick 		tp->t_state |= TS_HFLWCTL;
22153887Smckusick 		rsmctl(dev, RS_AUTO_ENABLE, DMBIS);
22253887Smckusick 	} else {
22353887Smckusick 		tp->t_state &= ~TS_HFLWCTL;
22453887Smckusick 		rsmctl(dev, RS_AUTO_ENABLE, DMBIC);
22553887Smckusick 	}
22653887Smckusick #endif
22753887Smckusick 	(void) splx(s);
22853887Smckusick 	return ((*linesw[tp->t_line].l_open)(dev, tp));
22953887Smckusick }
23053887Smckusick 
23153887Smckusick /*
23253887Smckusick  * Close a RS line.
23353887Smckusick  */
23453887Smckusick /*ARGSUSED*/
rsclose(dev,flag)23553887Smckusick rsclose(dev, flag)
23653887Smckusick 	dev_t dev;
23753887Smckusick 	int flag;
23853887Smckusick {
23953887Smckusick 	register struct tty *tp;
24053887Smckusick 	register unit;
24153887Smckusick 
24253887Smckusick 	unit = minor(dev);
24353887Smckusick 	tp = &rs_tty[unit];
24453887Smckusick 	(*linesw[tp->t_line].l_close)(tp);
24553887Smckusick 	(void) rsmctl(unit, RS_BRK, DMBIC);
24653887Smckusick 	if (tp->t_cflag & HUPCL || (tp->t_state & TS_ISOPEN) == 0)
24753887Smckusick 		(void) rsmctl(unit, RS_OFF, DMSET);
24853887Smckusick 	ttyclose(tp);
24953887Smckusick 
25053887Smckusick 	if (RS_FLAG(unit, RF_FLOWCTL))
25153887Smckusick 		(void)rsmctl(unit, RS_RTS, DMBIC);
25253887Smckusick }
25353887Smckusick 
rsread(dev,uio,flag)25453887Smckusick rsread(dev, uio, flag)
25553887Smckusick 	dev_t dev;
25653887Smckusick 	struct uio *uio;
25753887Smckusick 	int flag;
25853887Smckusick {
25953887Smckusick 	register struct tty *tp;
26053887Smckusick 
26153887Smckusick 	tp = &rs_tty[minor(dev)];
26253887Smckusick 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
26353887Smckusick }
26453887Smckusick 
rswrite(dev,uio,flag)26553887Smckusick rswrite(dev, uio, flag)
26653887Smckusick 	dev_t dev;
26753887Smckusick 	struct uio *uio;
26853887Smckusick 	int flag;
26953887Smckusick {
27053887Smckusick 	register struct tty *tp;
27153887Smckusick 
27253887Smckusick 	tp = &rs_tty[minor(dev)];
27353887Smckusick 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
27453887Smckusick }
27553887Smckusick 
rsenable(unit)27653887Smckusick rsenable(unit)
27753887Smckusick 	int unit;
27853887Smckusick {
27953887Smckusick 
28053887Smckusick 	rs_timeout[unit] = 0;
28153887Smckusick 	rs_enable(unit);
28253887Smckusick }
28353887Smckusick 
28453887Smckusick /*
28553887Smckusick  * RS receiver interrupt.
28653887Smckusick  */
_rsrint(unit,buf,n)28753887Smckusick _rsrint(unit, buf, n)
28853887Smckusick 	register int unit;
28953887Smckusick 	register char *buf;
29053887Smckusick 	register int n;
29153887Smckusick {
29253887Smckusick 	register struct iop_device *ii;
29353887Smckusick 	register struct tty *tp;
29453887Smckusick 	register int (*rint)();
29553887Smckusick 
29653887Smckusick #ifdef notyet /* KU:XXX */
29753887Smckusick 	intrcnt[INTR_RS0 + unit]++;
29853887Smckusick #endif
29953887Smckusick 	ii = rsinfo[unit >> 2];
30053887Smckusick 	if (ii == 0 || ii->ii_alive == 0)
30153887Smckusick 		return;
30253887Smckusick 	tp = &rs_tty[unit];
30353887Smckusick 	if ((tp->t_state & TS_ISOPEN) == 0) {
30453887Smckusick 		wakeup((caddr_t)&tp->t_rawq);
30553887Smckusick 		goto enable;
30653887Smckusick 	}
30753887Smckusick 	/*
30853887Smckusick 	 * Loop fetching characters from the silo for this
30953887Smckusick 	 * rs until there are no more in the silo.
31053887Smckusick 	 */
31153887Smckusick 	rint = linesw[tp->t_line].l_rint;
31253887Smckusick 	while (--n >= 0) {
31353887Smckusick #if NBK > 0
31453887Smckusick 		if (tp->t_line == NETLDISC) {
31553887Smckusick 			c &= 0177;
31653887Smckusick 			BKINPUT(c, tp);
31753887Smckusick 		} else
31853887Smckusick #endif /* NBK > 0 */
31953887Smckusick 			(*rint)(*buf++, tp);
32053887Smckusick 	}
32153887Smckusick enable:
32253887Smckusick 	rs_rate[unit]++;
32353887Smckusick 	if (rs_average[unit] >= 10 && RS_FLAG(unit, RF_NODELAY) == 0) {
32453887Smckusick 		if (rs_timeout[unit] == 0) {
32553887Smckusick 			rs_timeout[unit] = 1;
32653887Smckusick 			timeout(rsenable, (caddr_t)unit, hz / 100);
32753887Smckusick 		}
32853887Smckusick 	} else
32953887Smckusick 		rs_enable(unit);
33053887Smckusick }
33153887Smckusick 
33253887Smckusick /*ARGSUSED*/
rsioctl(dev,cmd,data,flag)33353887Smckusick rsioctl(dev, cmd, data, flag)
33453887Smckusick 	dev_t dev;
33553887Smckusick 	caddr_t data;
33653887Smckusick {
33753887Smckusick 	register struct tty *tp;
33853887Smckusick 	register int unit = minor(dev);
33953887Smckusick 	int error;
34053887Smckusick 
34153887Smckusick 	tp = &rs_tty[unit];
34253887Smckusick 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
34353887Smckusick 	if (error >= 0)
34453887Smckusick 		return (error);
34553887Smckusick 	error = ttioctl(tp, cmd, data, flag);
34653887Smckusick 	if (error >= 0)
34753887Smckusick 		return (error);
34853887Smckusick 
34953887Smckusick 	switch (cmd) {
35053887Smckusick 
35153887Smckusick 	case TIOCSBRK:
35253887Smckusick 		(void) rsmctl(dev, RS_BRK, DMBIS);
35353887Smckusick 		break;
35453887Smckusick 
35553887Smckusick 	case TIOCCBRK:
35653887Smckusick 		(void) rsmctl(dev, RS_BRK, DMBIC);
35753887Smckusick 		break;
35853887Smckusick 
35953887Smckusick 	case TIOCSDTR:
36053887Smckusick 		(void) rsmctl(dev, RS_DTR|RS_RTS, DMBIS);
36153887Smckusick 		break;
36253887Smckusick 
36353887Smckusick 	case TIOCCDTR:
36453887Smckusick 		if (curproc->p_ucred->cr_uid &&
36553887Smckusick 		    curproc->p_session->s_ttyp != tp)
36653887Smckusick 			return (EACCES);
36753887Smckusick 		(void) rsmctl(dev, RS_DTR|RS_RTS, DMBIC);
36853887Smckusick 		break;
36953887Smckusick 
37053887Smckusick 	case TIOCMSET:
37153887Smckusick 		(void) rsmctl(dev, dmtors(*(int *)data), DMSET);
37253887Smckusick 		break;
37353887Smckusick 
37453887Smckusick 	case TIOCMBIS:
37553887Smckusick 		(void) rsmctl(dev, dmtors(*(int *)data), DMBIS);
37653887Smckusick 		break;
37753887Smckusick 
37853887Smckusick 	case TIOCMBIC:
37953887Smckusick 		(void) rsmctl(dev, dmtors(*(int *)data), DMBIC);
38053887Smckusick 		break;
38153887Smckusick 
38253887Smckusick 	case TIOCMGET:
38353887Smckusick 		*(int *)data = rstodm(rsmctl(dev, 0, DMGET));
38453887Smckusick 		break;
38553887Smckusick 
38653887Smckusick 	default:
38753887Smckusick 		return (ENOTTY);
38853887Smckusick 	}
38953887Smckusick 	return (0);
39053887Smckusick }
39153887Smckusick 
dmtors(bits)39253887Smckusick dmtors(bits)
39353887Smckusick 	register int bits;
39453887Smckusick {
39553887Smckusick 	register int b;
39653887Smckusick 
39753887Smckusick 	b = 0;
39853887Smckusick 	if (bits & DML_LE)  b |= RS_TXE|RS_RXE;
39953887Smckusick 	if (bits & DML_DTR) b |= RS_DTR;
40053887Smckusick 	if (bits & DML_RTS) b |= RS_RTS;
40153887Smckusick 	if (bits & DML_CTS) b |= RS_CTS;
40253887Smckusick 	if (bits & DML_CAR) b |= RS_DCD;
40353887Smckusick 	if (bits & DML_RNG) b |= RS_RI;
40453887Smckusick 	if (bits & DML_DSR) b |= RS_DSR;
40553887Smckusick #ifdef AUTO_ENABLE
40653887Smckusick 	if (bits & DML_USR) b |= RS_AUTO_ENABLE;
40753887Smckusick #endif /* AUTO_ENABLE */
40853887Smckusick 	return(b);
40953887Smckusick }
41053887Smckusick 
rstodm(bits)41153887Smckusick rstodm(bits)
41253887Smckusick 	register int bits;
41353887Smckusick {
41453887Smckusick 	register int b;
41553887Smckusick 
41653887Smckusick 	b = 0;
41753887Smckusick 	if (bits & (RS_TXE|RS_RXE)) b |= DML_LE;
41853887Smckusick 	if (bits & RS_DTR) b |= DML_DTR;
41953887Smckusick 	if (bits & RS_RTS) b |= DML_RTS;
42053887Smckusick 	if (bits & RS_CTS) b |= DML_CTS;
42153887Smckusick 	if (bits & RS_DCD) b |= DML_CAR;
42253887Smckusick 	if (bits & RS_RI)  b |= DML_RNG;
42353887Smckusick 	if (bits & RS_DSR) b |= DML_DSR;
42453887Smckusick #ifdef AUTO_ENABLE
42553887Smckusick 	if (bits & RS_AUTO_ENABLE) b |= DML_USR;
42653887Smckusick #endif
42753887Smckusick 	return(b);
42853887Smckusick }
42953887Smckusick 
43053887Smckusick /*
43153887Smckusick  * compat table
43253887Smckusick  */
43353887Smckusick struct speedtab rsspeedtab[] = {
43453887Smckusick 	0,	0,
43553887Smckusick 	50,	1,
43653887Smckusick 	75,	2,
43753887Smckusick 	110,	3,
43853887Smckusick 	134,	4,
43953887Smckusick 	150,	5,
44053887Smckusick 	200,	6,
44153887Smckusick 	300,	7,
44253887Smckusick 	600,	8,
44353887Smckusick 	1200,	9,
44453887Smckusick 	1800,	10,
44553887Smckusick 	2400,	11,
44653887Smckusick 	4800,	12,
44753887Smckusick 	9600,	13,
44853887Smckusick 	19200,	14,
44953887Smckusick 	38400,	15,
45053887Smckusick 	-1,	-1
45153887Smckusick };
45253887Smckusick 
45353887Smckusick /*
45453887Smckusick  * Set parameters from open or stty into the RS hardware
45553887Smckusick  * registers.
45653887Smckusick  */
rsparam(tp,t)45753887Smckusick rsparam(tp, t)
45853887Smckusick 	register struct tty *tp;
45953887Smckusick 	register struct termios *t;
46053887Smckusick {
46153887Smckusick 	register int param;
46253887Smckusick 	register int cflag = t->c_cflag;
46353887Smckusick 	int unit = minor(tp->t_dev);
46453887Smckusick 	int s;
46553887Smckusick 	int ospeed = ttspeedtab(t->c_ospeed, rsspeedtab);
46653887Smckusick 
46753887Smckusick 	/* check requested parameters */
46853887Smckusick 	if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
46953887Smckusick 	    (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6)
47053887Smckusick 		return (EINVAL);
47153887Smckusick 	/* and copy to tty */
47253887Smckusick 	tp->t_ispeed = t->c_ispeed;
47353887Smckusick 	tp->t_ospeed = t->c_ospeed;
47453887Smckusick 	tp->t_cflag = cflag;
47553887Smckusick 
47653887Smckusick 	/*
47753887Smckusick 	 * Block interrupts so parameters will be set
47853887Smckusick 	 * before the line interrupts.
47953887Smckusick 	 */
48053887Smckusick 	s = spltty();
48153887Smckusick 	if (tp->t_ospeed == 0) {
48253887Smckusick 		tp->t_cflag |= HUPCL;
48353887Smckusick 		(void) rsmctl(unit, RS_OFF, DMSET);
48453887Smckusick 		(void) splx(s);
48553887Smckusick 		return (0);
48653887Smckusick 	}
48753887Smckusick 
48853887Smckusick 	param = rs_get_param(unit) &
48953887Smckusick 		~(CHAR_SIZE|PARITY|EVEN|STOPBIT|BAUD_RATE|NOCHECK);
49053887Smckusick 	if ((cflag & CREAD) == 0)
49153887Smckusick 		param &= ~RXE;
49253887Smckusick 	if (cflag & CS6)
49353887Smckusick 		param |= C6BIT;
49453887Smckusick 	if (cflag & CS7)
49553887Smckusick 		param |= C7BIT;
49653887Smckusick 	if (cflag & PARENB)
49753887Smckusick 		param |= PARITY;
49853887Smckusick 	if ((cflag & PARODD) == 0)
49953887Smckusick 		param |= EVEN;
50053887Smckusick 	if ((tp->t_iflag & INPCK) == 0)
50153887Smckusick 		param |= NOCHECK;
50253887Smckusick 	if (cflag & CSTOPB)
50353887Smckusick 		param |= STOP2;
50453887Smckusick 	else
50553887Smckusick 		param |= STOP1;
50653887Smckusick 
50753887Smckusick 	rs_param[unit] = param | ospeed;
50853887Smckusick 
50953887Smckusick 	if (RS_FLAG(unit, RF_EXTCLK))
51053887Smckusick 		rs_param[unit] |= EXTCLK_ENABLE;
51153887Smckusick 	else
51253887Smckusick 		rs_param[unit] &= ~EXTCLK_ENABLE;
51353887Smckusick 	rs_set_param(unit, rs_param[unit]);
51453887Smckusick 	(void) splx(s);
51553887Smckusick 
51653887Smckusick 	return (0);
51753887Smckusick }
51853887Smckusick 
51953887Smckusick /*
52053887Smckusick  * RS transmitter interrupt.
52153887Smckusick  * Restart the idle line.
52253887Smckusick  */
_rsxint(unit,count)52353887Smckusick _rsxint(unit, count)
52453887Smckusick 	int unit;
52553887Smckusick 	int count;
52653887Smckusick {
52753887Smckusick 	register struct tty *tp;
52853887Smckusick 	register int s;
52953887Smckusick 
53053887Smckusick #ifdef notyet /* KU:XXX */
53153887Smckusick 	intrcnt[INTR_RS0 + unit]++;
53253887Smckusick #endif
53353887Smckusick 	rs_stopped[unit] = 0;
53453887Smckusick 	tp = &rs_tty[unit];
53553887Smckusick 	tp->t_state &= ~TS_BUSY;
53653887Smckusick 	s = spltty();
53753887Smckusick 	if (tp->t_state & TS_FLUSH)
53853887Smckusick 		tp->t_state &= ~TS_FLUSH;
53953887Smckusick 	else
54053887Smckusick 		ndflush(&tp->t_outq, count);
54153887Smckusick 	(void) splx(s);
54253887Smckusick 	if (tp->t_line)
54353887Smckusick 		(*linesw[tp->t_line].l_start)(tp);
54453887Smckusick 	else
54553887Smckusick 		rsstart(tp);
54653887Smckusick }
54753887Smckusick 
54853887Smckusick /*
54953887Smckusick  * Start (restart) transmission on the given RS line.
55053887Smckusick  */
55153887Smckusick void
rsstart(tp)55253887Smckusick rsstart(tp)
55353887Smckusick 	register struct tty *tp;
55453887Smckusick {
55553887Smckusick 	register int unit, nch;
55653887Smckusick 	int s;
55753887Smckusick 
55853887Smckusick 	unit = minor(tp->t_dev);
55953887Smckusick 
56053887Smckusick 	/*
56153887Smckusick 	 * Must hold interrupts in following code to prevent
56253887Smckusick 	 * state of the tp from changing.
56353887Smckusick 	 */
56453887Smckusick 	s = spltty();
56553887Smckusick 	/*
56653887Smckusick 	 * If it's currently active, or delaying, no need to do anything.
56753887Smckusick 	 */
56853887Smckusick 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
56953887Smckusick 		goto out;
57053887Smckusick 	/*
57153887Smckusick 	 * If ther are still characters in the IOP,
57253887Smckusick 	 * just reenable transmit.
57353887Smckusick 	 */
57453887Smckusick 	if (rs_stopped[unit]) {
57553887Smckusick 		rs_start(unit);
57653887Smckusick 		rs_stopped[unit] = 0;
57753887Smckusick 		goto out;
57853887Smckusick 	}
57953887Smckusick 	/*
58053887Smckusick 	 * If there are sleepers, and output has drained below low
58153887Smckusick 	 * water mark, wake up the sleepers.
58253887Smckusick 	 */
58353887Smckusick 	if (tp->t_outq.c_cc <= tp->t_lowat) {
58453887Smckusick 		if (tp->t_state & TS_ASLEEP) {
58553887Smckusick 			tp->t_state &= ~TS_ASLEEP;
58653887Smckusick 			wakeup((caddr_t)&tp->t_outq);
58753887Smckusick 		}
58853887Smckusick 		selwakeup(&tp->t_wsel);
58953887Smckusick 	}
59053887Smckusick 	/*
59153887Smckusick 	 * Now restart transmission unless the output queue is
59253887Smckusick 	 * empty.
59353887Smckusick 	 */
59453887Smckusick 	if (tp->t_outq.c_cc == 0)
59553887Smckusick 		goto out;
59653887Smckusick 	if (tp->t_flags & (RAW|LITOUT))
59753887Smckusick 		nch = ndqb(&tp->t_outq, 0);
59853887Smckusick 	else {
59953887Smckusick 		nch = ndqb(&tp->t_outq, 0200);
60053887Smckusick 		/*
60153887Smckusick 		 * If first thing on queue is a delay process it.
60253887Smckusick 		 */
60353887Smckusick 		if (nch == 0) {
60453887Smckusick 			nch = getc(&tp->t_outq);
60553887Smckusick 			timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
60653887Smckusick 			tp->t_state |= TS_TIMEOUT;
60753887Smckusick 			goto out;
60853887Smckusick 		}
60953887Smckusick 	}
61053887Smckusick 	/*
61153887Smckusick 	 * If characters to transmit, restart transmission.
61253887Smckusick 	 */
61353887Smckusick 	if (nch) {
61453887Smckusick 		tp->t_state |= TS_BUSY;
61553887Smckusick 		rs_output(unit, nch);
61653887Smckusick 	}
61753887Smckusick out:
61853887Smckusick 	(void) splx(s);
61953887Smckusick }
62053887Smckusick 
62153887Smckusick /*
62253887Smckusick  * Stop output on a line, e.g. for ^S/^Q or output flush.
62353887Smckusick  */
62453887Smckusick /*ARGSUSED*/
rsstop(tp,flag)62553887Smckusick rsstop(tp, flag)
62653887Smckusick 	register struct tty *tp;
62753887Smckusick {
62853887Smckusick 	register int unit, s;
62953887Smckusick 
63053887Smckusick 	unit = minor(tp->t_dev);
63153887Smckusick 	s = spltty();
63253887Smckusick 	if (tp->t_state & TS_BUSY) {
63353887Smckusick 		rs_stop(unit, 0);
63453887Smckusick 		rs_stopped[unit] = 1;
63553887Smckusick 		if ((tp->t_state & TS_TTSTOP) == 0) {
63653887Smckusick 			tp->t_state |= TS_FLUSH;
63753887Smckusick 			rs_stop(unit, 1);
63853887Smckusick 		}
63953887Smckusick 	}
64053887Smckusick 	(void) splx(s);
64153887Smckusick }
64253887Smckusick 
64353887Smckusick /*
64453887Smckusick  * RS modem control
64553887Smckusick  */
rsmctl(dev,bits,how)64653887Smckusick rsmctl(dev, bits, how)
64753887Smckusick 	dev_t dev;
64853887Smckusick 	int bits, how;
64953887Smckusick {
65053887Smckusick 	register int unit, mbits;
65153887Smckusick 	int s;
65253887Smckusick 
65353887Smckusick #ifdef AUTO_ENABLE
65453887Smckusick 	bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK|RS_AUTO_ENABLE);
65553887Smckusick #else
65653887Smckusick 	bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK);
65753887Smckusick #endif
65853887Smckusick 
65953887Smckusick 	unit = minor(dev);
66053887Smckusick 	s = spltty();		/* spl5 -> spltty, 90/02/28 sak */
66153887Smckusick 
66253887Smckusick 	mbits = rs_get_param(unit);
66353887Smckusick 	switch (how) {
66453887Smckusick 
66553887Smckusick 	case DMSET:
66653887Smckusick 		mbits = mbits & ~(RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK) | bits;
66753887Smckusick 		break;
66853887Smckusick 
66953887Smckusick 	case DMBIS:
67053887Smckusick 		mbits |= bits;
67153887Smckusick 		break;
67253887Smckusick 
67353887Smckusick 	case DMBIC:
67453887Smckusick 		mbits &= ~bits;
67553887Smckusick 		break;
67653887Smckusick 
67753887Smckusick 	case DMGET:
67853887Smckusick 		(void) splx(s);
67953887Smckusick 		return(mbits);
68053887Smckusick 	}
68153887Smckusick 	rs_param[unit] = mbits;
68253887Smckusick 	rs_set_param(unit, rs_param[unit]);
68353887Smckusick 
68453887Smckusick 	(void) splx(s);
68553887Smckusick 	return(mbits);
68653887Smckusick }
68753887Smckusick 
68853887Smckusick /*
68953887Smckusick  * Reset state of driver if IOP reset was necessary.
69053887Smckusick  * Reset the parameter and status, and
69153887Smckusick  * restart transmitters.
69253887Smckusick  */
rsreset()69353887Smckusick rsreset()
69453887Smckusick {
69553887Smckusick 	register int unit;
69653887Smckusick 	register struct tty *tp;
69753887Smckusick 	register struct iop_device *ii;
69853887Smckusick 
69953887Smckusick 	for (unit = 0; unit < NRS * 4; unit++) {
70053887Smckusick 		ii = rsinfo[unit >> 2];
70153887Smckusick 		if (ii == 0 || ii->ii_alive == 0)
70253887Smckusick 			continue;
70353887Smckusick 		printf(" rs%d", unit);
70453887Smckusick 		tp = &rs_tty[unit];
70553887Smckusick 		if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
70653887Smckusick 			rs_reset(unit);
70753887Smckusick 			rsparam(tp, &tp->t_termios);
70853887Smckusick 			(void) rsmctl(unit, RS_ON, DMSET);
70953887Smckusick 			tp->t_state &= ~TS_BUSY;
71053887Smckusick 			rsstart(tp);
71153887Smckusick 		}
71253887Smckusick 	}
71353887Smckusick }
71453887Smckusick 
71553887Smckusick /*
71653887Smckusick  * RS status interrupt
71753887Smckusick  */
_rssint(unit,stat)71853887Smckusick _rssint(unit, stat)
71953887Smckusick 	int unit;
72053887Smckusick 	int stat;
72153887Smckusick {
72253887Smckusick 	register struct tty *tp;
72353887Smckusick 
72453887Smckusick #ifdef notyet /* KU:XXX */
72553887Smckusick 	intrcnt[INTR_RS0 + unit]++;
72653887Smckusick #endif
72753887Smckusick 	tp = &rs_tty[unit];
72853887Smckusick 	if (stat & RS_DCD) {
72953887Smckusick 		rs_param[unit] |= RS_DCD;
73053887Smckusick 		(void)(*linesw[tp->t_line].l_modem)(tp, 1);
73153887Smckusick 	} else if (RS_CARR(unit) == 0 &&
73253887Smckusick 	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
73353887Smckusick 		rs_param[unit] &= ~(RS_DCD | RS_DTR);
73453887Smckusick 		rs_set_param(unit, rs_param[unit]);
73553887Smckusick 	}
73653887Smckusick 	if (stat & OVERRUN_ERROR) {
73753887Smckusick 		printf("rs%d: fifo overflow\n", unit);
73853887Smckusick 		rs_param[unit] &= ~OVERRUN_ERROR;
73953887Smckusick 		rs_set_param(unit, rs_param[unit]);
74053887Smckusick 	}
74153887Smckusick 	if (stat & RBREAK) {
74253887Smckusick 		rs_param[unit] &= ~RBREAK;
74353887Smckusick 		if (tp->t_state & TS_ISOPEN)
74453887Smckusick 			(*linesw[tp->t_line].l_rint)
74553887Smckusick 			    (tp->t_flags & RAW ? '\0' : tp->t_cc[VINTR], tp);
74653887Smckusick 	}
74753887Smckusick }
74853887Smckusick 
74953887Smckusick /*
75053887Smckusick  * RS control interrupt
75153887Smckusick  */
rscint(rs)75253887Smckusick rscint(rs)
75353887Smckusick 	int rs;
75453887Smckusick {
75553887Smckusick 
75653887Smckusick 	printf("rscint: %d\n", rs);
75753887Smckusick }
75853887Smckusick 
75953887Smckusick /*
76053887Smckusick  * RS H/W control
76153887Smckusick  */
76253887Smckusick void
rsctrl(tp,cmd,arg)76353887Smckusick rsctrl(tp, cmd, arg)
76453887Smckusick 	struct tty *tp;
76553887Smckusick 	int cmd;
76653887Smckusick 	int arg;
76753887Smckusick {
76853887Smckusick #ifdef notyet /* KU:XXX */
76953887Smckusick 	int unit = minor(tp->t_dev);
77053887Smckusick 
77153887Smckusick 	switch (cmd) {
77253887Smckusick 
77353887Smckusick 	case TC_HBLOCK:
77453887Smckusick 		if (RS_FLAG(unit, RF_FLOWCTL))
77553887Smckusick 			rsflowctl(unit, arg);
77653887Smckusick 		break;
77753887Smckusick 
77853887Smckusick 	default:
77953887Smckusick 		break;
78053887Smckusick 	}
78153887Smckusick 
78253887Smckusick 	return (0);
78353887Smckusick #endif
78453887Smckusick }
78553887Smckusick 
rsflowctl(unit,block)78653887Smckusick rsflowctl(unit, block)
78753887Smckusick 	int unit;
78853887Smckusick 	int block;
78953887Smckusick {
79053887Smckusick 	int s;
79153887Smckusick 
79253887Smckusick 	s = spltty();
79353887Smckusick 	if (block)
79453887Smckusick 		rs_param[unit] &= ~RS_RTS;
79553887Smckusick 	else
79653887Smckusick 		rs_param[unit] |= RS_RTS;
79753887Smckusick 	rs_set_param(unit, rs_param[unit]);
79853887Smckusick 	(void) splx(s);
79953887Smckusick }
80053887Smckusick 
80153887Smckusick /*
80253887Smckusick  * Machine dependent functions
80353887Smckusick  *
80453887Smckusick  *	rs_probe()
80553887Smckusick  *	rs_init()
80653887Smckusick  *	rsrint()
80753887Smckusick  *	rsxint()
80853887Smckusick  *	rssint()
80953887Smckusick  *	rs_enable()
81053887Smckusick  *	rs_output()
81153887Smckusick  *	rs_start()
81253887Smckusick  *	rs_stop()
81353887Smckusick  *	rs_reset()
81453887Smckusick  *	rs_get_param()
81553887Smckusick  *	rs_set_param()
81653887Smckusick  */
81753887Smckusick #ifdef CPU_SINGLE
81857183Sutashiro #include <news3400/hbdev/hbvar.h>
81957183Sutashiro #include <news3400/hbdev/rsreg.h>
82057183Sutashiro #include <news3400/sio/scc.h>
82153887Smckusick 
82253887Smckusick int	rslastcount[NRS*4];
82353887Smckusick int	scc_unit[] = { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 };
82453887Smckusick int	rs_unit[] = { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11 };
82553887Smckusick 
82653887Smckusick rs_probe(hi)
82753887Smckusick 	struct hb_device *hi;
82853887Smckusick {
82953887Smckusick 	register int i, cmax;
83053887Smckusick 
83153887Smckusick 	for (i = (hi->hi_unit << 2), cmax = 4; cmax > 0; cmax--, i++) {
83253887Smckusick 		if (i == 2 || i == 3)
83353887Smckusick 			continue;
83453887Smckusick 		if (scc_probe(scc_unit[i]))
83553887Smckusick 			continue;
83653887Smckusick 		return (0);
83753887Smckusick 	}
83853887Smckusick 	return (1);
83953887Smckusick }
84053887Smckusick 
rs_init(unit)84153887Smckusick rs_init(unit)
84253887Smckusick 	int unit;
84353887Smckusick {
84453887Smckusick 
84553887Smckusick 	if (scc_open(scc_unit[unit])) {
84653887Smckusick 		printf("rs_init: chan %d open failed.\n", scc_unit[unit]);
84753887Smckusick 		return (-1);
84853887Smckusick 	}
84953887Smckusick 	return (0);
85053887Smckusick }
85153887Smckusick 
rs_enable(unit)85253887Smckusick rs_enable(unit)
85353887Smckusick 	int unit;
85453887Smckusick {
85553887Smckusick 
85653887Smckusick 	scc_enable(scc_unit[unit]);
85753887Smckusick }
85853887Smckusick 
rsrint(scc,buf,cnt)85953887Smckusick rsrint(scc, buf, cnt)
86053887Smckusick 	int scc;
86153887Smckusick 	char *buf;
86253887Smckusick 	int cnt;
86353887Smckusick {
86453887Smckusick 
86553887Smckusick 	_rsrint(rs_unit[scc], buf, cnt);
86653887Smckusick }
86753887Smckusick 
rsxint(scc)86853887Smckusick rsxint(scc)
86953887Smckusick 	int scc;
87053887Smckusick {
87153887Smckusick 	int unit = rs_unit[scc];
87253887Smckusick 
87353887Smckusick 	_rsxint(unit, rslastcount[unit]);
87453887Smckusick }
87553887Smckusick 
rssint(scc,stat)87653887Smckusick rssint(scc, stat)
87753887Smckusick 	int scc;
87853887Smckusick 	int stat;
87953887Smckusick {
88053887Smckusick 
88153887Smckusick 	_rssint(rs_unit[scc], stat);
88253887Smckusick }
88353887Smckusick 
rs_start(unit)88453887Smckusick rs_start(unit)
88553887Smckusick 	int unit;
88653887Smckusick {
88753887Smckusick 
88853887Smckusick 	scc_start(scc_unit[unit]);
88953887Smckusick }
89053887Smckusick 
rs_output(unit,n)89153887Smckusick rs_output(unit, n)
89253887Smckusick 	int unit;
89353887Smckusick 	int n;
89453887Smckusick {
89553887Smckusick 
89653887Smckusick 	rslastcount[unit] =
89753887Smckusick 	    scc_write(scc_unit[unit], rs_tty[unit].t_outq.c_cf, n);
89853887Smckusick }
89953887Smckusick 
rs_stop(unit,flush)90053887Smckusick rs_stop(unit, flush)
90153887Smckusick 	int unit;
90253887Smckusick 	int flush;
90353887Smckusick {
90453887Smckusick 
90553887Smckusick 	if (flush)
90653887Smckusick 		scc_flush(scc_unit[unit]);
90753887Smckusick }
90853887Smckusick 
rs_reset(unit)90953887Smckusick rs_reset(unit)
91053887Smckusick 	int unit;
91153887Smckusick {
91253887Smckusick 
91353887Smckusick 	scc_reset(scc_unit[unit]);
91453887Smckusick }
91553887Smckusick 
rs_get_param(unit)91653887Smckusick rs_get_param(unit)
91753887Smckusick 	int unit;
91853887Smckusick {
91953887Smckusick 
92053887Smckusick 	return (scc_get_param(scc_unit[unit]));
92153887Smckusick }
92253887Smckusick 
rs_set_param(unit,param)92353887Smckusick rs_set_param(unit, param)
92453887Smckusick 	int unit;
92553887Smckusick 	int param;
92653887Smckusick {
92753887Smckusick 
92853887Smckusick 	scc_set_param(scc_unit[unit], param);
92953887Smckusick }
93053887Smckusick #endif /* CPU_SINGLE */
93153887Smckusick 
93253887Smckusick #ifdef IPC_MRX
93353887Smckusick #include "../ipc/newsipc.h"
93453887Smckusick #include "../mrx/h/scc.h"
93553887Smckusick #include "../mrx/h/cio.h"
93653887Smckusick 
93753887Smckusick int	port_rsrecv[NRS*4];
93853887Smckusick int	port_rsxmit[NRS*4];
93953887Smckusick int	port_rsstat[NRS*4];
94053887Smckusick int	port_rsctrl[NRS*4];
94153887Smckusick int	port_recv_iop[NRS*4];
94253887Smckusick int	port_xmit_iop[NRS*4];
94353887Smckusick int	port_ctrl_iop[NRS*4];
94453887Smckusick int	port_stat_iop[NRS*4];
94553887Smckusick 
94653887Smckusick /*
94753887Smckusick  *	minor No: 0 - 12 ----> SCC unit No : 0 - 9
94853887Smckusick  */
94953887Smckusick int	scc_unit[] = { 1, 0, -1, -1, 3, 2, 5, 4, 7, 6, 9, 8 };
95053887Smckusick 
95153887Smckusick rs_probe(ii)
95253887Smckusick 	struct iop_device *ii;
95353887Smckusick {
95453887Smckusick 	register int base = ii->ii_unit << 2;
95553887Smckusick 	register int i, j;
95653887Smckusick 	char buf[16];
95753887Smckusick 
95853887Smckusick #define	PT_CREATE(buf, name, unit, func, arg)	\
95953887Smckusick 	port_create(make_name(buf, name, unit), func, arg)
96053887Smckusick #define	OB_QUERY(buf, name, unit) \
96153887Smckusick 	object_query(make_name(buf, name, unit))
96253887Smckusick 	for (i = base; i < base+4; i++) {
96353887Smckusick 		if ((j = scc_unit[i]) < 0)
96453887Smckusick 			continue;
96553887Smckusick 		port_recv_iop[i] = OB_QUERY(buf, "scc_inputX", j);
96653887Smckusick 		if (port_recv_iop[i] <= 0)
96753887Smckusick 			return (0);
96853887Smckusick 		port_xmit_iop[i] = OB_QUERY(buf, "scc_outputX", j);
96953887Smckusick 		port_ctrl_iop[i] = OB_QUERY(buf, "scc_ctrlX", j);
97053887Smckusick 		port_stat_iop[i] = OB_QUERY(buf, "scc_statX", j);
97153887Smckusick 
97253887Smckusick 		port_rsrecv[i] = PT_CREATE(buf, "@rsrecvX", j, rsrint, i);
97353887Smckusick 		port_rsxmit[i] = PT_CREATE(buf, "@rsxmitX", j, rsxint, i);
97453887Smckusick 		port_rsctrl[i] = PT_CREATE(buf, "@rsctrlX", j, NULL, 0);
97553887Smckusick 		port_rsstat[i] = PT_CREATE(buf, "@rsstatX", j, rssint, i);
97653887Smckusick 	}
97753887Smckusick 	return (1);
97853887Smckusick }
97953887Smckusick 
rs_init(unit)98053887Smckusick rs_init(unit)
98153887Smckusick 	int unit;
98253887Smckusick {
98353887Smckusick 	int len;
98453887Smckusick 
98553887Smckusick 	msg_send(port_stat_iop[unit], port_rsstat[unit], NULL, 0, 0);
98653887Smckusick 	return (0);
98753887Smckusick }
98853887Smckusick 
rs_enable(unit)98953887Smckusick rs_enable(unit)
99053887Smckusick 	int unit;
99153887Smckusick {
99253887Smckusick 	int len;
99353887Smckusick 
99453887Smckusick 	len = MAX_CIO;
99553887Smckusick 	msg_send(port_recv_iop[unit], port_rsrecv[unit], &len, sizeof(len), 0);
99653887Smckusick }
99753887Smckusick 
rsrint(unit)99853887Smckusick rsrint(unit)
99953887Smckusick 	register int	unit;
100053887Smckusick {
100153887Smckusick 	char *addr;
100253887Smckusick 	int from, len;
100353887Smckusick 
100453887Smckusick 	msg_recv(port_rsrecv[unit], &from, &addr, &len, 0);
100553887Smckusick #ifdef mips
100653887Smckusick 	clean_dcache(addr, len + 8);
100753887Smckusick #endif
100853887Smckusick 	_rsrint(unit, addr, len);
100953887Smckusick }
101053887Smckusick 
rsxint(unit)101153887Smckusick rsxint(unit)
101253887Smckusick 	register int unit;
101353887Smckusick {
101453887Smckusick 	int from, *len;
101553887Smckusick 
101653887Smckusick 	msg_recv(port_rsxmit[unit], &from, &len, NULL, 0);
101753887Smckusick 	_rsxint(unit, *len);
101853887Smckusick }
101953887Smckusick 
rssint(unit)102053887Smckusick rssint(unit)
102153887Smckusick 	register int unit;
102253887Smckusick {
102353887Smckusick 	int from, *reply;
102453887Smckusick 
102553887Smckusick 	msg_recv(port_rsstat[unit], &from, &reply, NULL, 0);
102653887Smckusick 	_rssint(unit, *reply);
102753887Smckusick 	msg_send(from, port_rsstat[unit], NULL, 0, 0);
102853887Smckusick }
102953887Smckusick 
rs_start(unit)103053887Smckusick rs_start(unit)
103153887Smckusick 	int unit;
103253887Smckusick {
103353887Smckusick 	int func;
103453887Smckusick 
103553887Smckusick 	func = CIO_START;
103653887Smckusick 	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
103753887Smckusick }
103853887Smckusick 
rs_output(unit,n)103953887Smckusick rs_output(unit, n)
104053887Smckusick 	int unit;
104153887Smckusick 	int n;
104253887Smckusick {
104353887Smckusick 
104453887Smckusick 	msg_send(port_xmit_iop[unit], port_rsxmit[unit],
104555766Sbostic 	    rs_tty[unit].t_outq.c_cf, min(n, MAX_CIO), 0);
104653887Smckusick }
104753887Smckusick 
rs_stop(unit,flush)104853887Smckusick rs_stop(unit, flush)
104953887Smckusick 	int unit;
105053887Smckusick 	int flush;
105153887Smckusick {
105253887Smckusick 	int func;
105353887Smckusick 
105453887Smckusick 	func = flush ? CIO_FLUSH : CIO_STOP;
105553887Smckusick 	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
105653887Smckusick }
105753887Smckusick 
rs_reset(unit)105853887Smckusick rs_reset(unit)
105953887Smckusick 	int unit;
106053887Smckusick {
106153887Smckusick 	int func;
106253887Smckusick 
106353887Smckusick 	func = CIO_RESET;
106453887Smckusick 	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
106553887Smckusick }
106653887Smckusick 
rs_get_param(unit)106753887Smckusick rs_get_param(unit)
106853887Smckusick 	register int unit;
106953887Smckusick {
107053887Smckusick 	register int port;
107153887Smckusick 	struct scc_ctrl_req req;
107253887Smckusick 	int param, *reply;
107353887Smckusick 
107453887Smckusick 	port = port_rsctrl[unit];
107553887Smckusick 	req.scc_func = CIO_GETPARAMS;
107653887Smckusick 
107753887Smckusick 	/* message length 8 means 2 * sizeof(int) : func and status */
107853887Smckusick 	msg_send(port_ctrl_iop[unit], port, &req, 8, 0);
107953887Smckusick 	msg_recv(port, NULL, &reply, NULL, 0);
108053887Smckusick 
108153887Smckusick 	param = *reply;
108253887Smckusick 	msg_free(port);
108353887Smckusick 
108453887Smckusick 	return (param);
108553887Smckusick }
108653887Smckusick 
rs_set_param(unit,param)108753887Smckusick rs_set_param(unit, param)
108853887Smckusick 	register int unit;
108953887Smckusick 	int param;
109053887Smckusick {
109153887Smckusick 	struct scc_ctrl_req req;
109253887Smckusick 
109353887Smckusick 	req.scc_func = CIO_SETPARAMS;
109453887Smckusick 	req.scc_arg = param;
109553887Smckusick 
109653887Smckusick 	/* message length 8 means 2 * sizeof(int) : func and param */
109753887Smckusick 	msg_send(port_ctrl_iop[unit], 0, &req, 8, 0);
109853887Smckusick }
109953887Smckusick #endif /* IPC_MRX */
110053887Smckusick #endif /* NRS > 0 */
1101