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