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