xref: /original-bsd/sys/vax/uba/dmf.c (revision dcaa9859)
1 /*	dmf.c	4.7	82/08/22	*/
2 
3 #include "dmf.h"
4 #if NDMF > 0
5 /*
6  * DMF32 driver
7  *
8  * TODO:
9  *	test with modem
10  *	load as much as possible into silo
11  *	get correct numbers for receive silo parameter timeout
12  *	use auto XON/XOFF
13  *	test reset code
14  *	test with more than one unit
15  *	optimize for efficient DMA and dynamically
16  *	  decide between silo and DMA mode
17  */
18 #include "bk.h"
19 #include "../h/param.h"
20 #include "../h/conf.h"
21 #include "../h/dir.h"
22 #include "../h/user.h"
23 #include "../h/tty.h"
24 #include "../h/map.h"
25 #include "../h/pte.h"
26 #include "../h/buf.h"
27 #include "../h/vm.h"
28 #include "../h/ubareg.h"
29 #include "../h/ubavar.h"
30 #include "../h/bk.h"
31 #include "../h/clist.h"
32 #include "../h/file.h"
33 #include "../h/uio.h"
34 
35 /*
36  * Definition of the driver for the auto-configuration program.
37  */
38 int	dmfprobe(), dmfattach(), dmfrint(), dmfxint();
39 struct	uba_device *dmfinfo[NDMF];
40 u_short	dmfstd[] = { 0 };
41 struct	uba_driver dmfdriver =
42 	{ dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo };
43 
44 /*
45  * In this driver, "dmf" (unqualified) refers to the async portion
46  * of the dmf32, "dmfc" to the combo portion, "dmfs" to the sync
47  * portion, "dmfl" to the lp portion, and "dmfd" to the dr portion.
48  */
49 struct dmfdevice
50 {
51 	short	dmfccsr0;		/* combo csr 0 */
52 	short	dmfccsr1;		/* combo csr 1 */
53 	short	dmfs[4];
54 	short	dmfcsr;			/* control-status register */
55 	short	dmflpr;			/* line parameter register */
56 	short	dmfrbuf;		/* receiver buffer (ro) */
57 	union {
58 		u_short	dmfirw;		/* indirect register word */
59 		u_char	dmfirc[2];	/*    "         "    bytes */
60 	} dmfun;
61 	short	dmfl[2];
62 	short	dmfd[4];
63 };
64 
65 #define	dmfrsp	dmfrbuf		/* receive silo parameter register (wo) */
66 #define	dmftbuf	dmfun.dmfirc[0]	/* transmit buffer */
67 #define	dmftsc	dmfun.dmfirc[0]	/* transmit silo count */
68 #define	dmfrms	dmfun.dmfirc[1]	/* receive modem status */
69 #define	dmflcr	dmfun.dmfirc[0]	/* line control register */
70 #define	dmftms	dmfun.dmfirc[1]	/* transmit modem status */
71 #define	dmftba	dmfun.dmfirw	/* transmit buffer address */
72 #define	dmftcc	dmfun.dmfirw	/* transmit character count */
73 
74 /* bits in dmfcsr */
75 #define	DMF_TI	0100000		/* transmit interrupt */
76 #define	DMF_TIE	0040000		/* transmit interrupt enable */
77 #define	DMF_NXM	0020000		/* non-existant memory */
78 #define	DMF_LIN	0003400		/* transmit line number */
79 #define	DMF_RI	0000200		/* receiver interrupt */
80 #define	DMF_RIE	0000100		/* receiver interrupt enable */
81 #define	DMF_CLR	0000040		/* master reset */
82 #define	DMF_IAD	0000037		/* indirect address register */
83 
84 #define	DMFIR_TBUF	000	/* select tbuf indirect register */
85 #define	DMFIR_LCR	010	/* select lcr indirect register */
86 #define	DMFIR_TBA	020	/* select tba indirect register */
87 #define	DMFIR_TCC	030	/* select tcc indirect register */
88 
89 /* bits in dmflpr */
90 #define	BITS6	(01<<3)
91 #define	BITS7	(02<<3)
92 #define	BITS8	(03<<3)
93 #define	TWOSB	0200
94 #define	PENABLE	040
95 /* DEC manuals incorrectly say this bit causes generation of even parity. */
96 #define	OPAR	0100
97 
98 #define	DMF_IE	(DMF_TIE|DMF_RIE)
99 
100 #define	DMF_SILOCNT	32		/* size of DMF output silo (per line) */
101 
102 /* bits in dmfrbuf */
103 #define	DMF_DSC		0004000		/* data set change */
104 #define	DMF_PE		0010000		/* parity error */
105 #define	DMF_FE		0020000		/* framing error */
106 #define	DMF_DO		0040000		/* data overrun */
107 
108 /* bits in dmfrms */
109 #define	DMF_USRR	0004		/* user modem signal (pin 25) */
110 #define	DMF_SR		0010		/* secondary receive */
111 #define	DMF_CTS		0020		/* clear to send */
112 #define	DMF_CAR		0040		/* carrier detect */
113 #define	DMF_RNG		0100		/* ring */
114 #define	DMF_DSR		0200		/* data set ready */
115 
116 /* bits in dmftms */
117 #define	DMF_USRW	0001		/* user modem signal (pin 18) */
118 #define	DMF_DTR		0002		/* data terminal ready */
119 #define	DMF_RATE	0004		/* data signal rate select */
120 #define	DMF_ST		0010		/* secondary transmit */
121 #define	DMF_RTS		0020		/* request to send */
122 #define	DMF_BRK		0040		/* pseudo break bit */
123 #define	DMF_PREEMPT	0200		/* preempt output */
124 
125 /* flags for modem control */
126 #define	DMF_ON	(DMF_DTR|DMF_RTS)
127 #define	DMF_OFF	0
128 
129 /* bits in dmflcr */
130 #define	DMF_MIE		0040		/* modem interrupt enable */
131 #define	DMF_FLUSH	0020		/* flush transmit silo */
132 #define	DMF_RBRK	0010		/* real break bit */
133 #define	DMF_RE		0004		/* receive enable */
134 #define	DMF_AUTOX	0002		/* auto XON/XOFF */
135 #define	DMF_TE		0001		/* transmit enable */
136 
137 #define	DMFLCR_ENA	(DMF_MIE|DMF_RE|DMF_TE)
138 
139 /* bits in dm lsr, copied from dh.c */
140 #define	DML_USR		0001000		/* usr modem sig, not a real DM bit */
141 #define	DML_DSR		0000400		/* data set ready, not a real DM bit */
142 #define	DML_RNG		0000200		/* ring */
143 #define	DML_CAR		0000100		/* carrier detect */
144 #define	DML_CTS		0000040		/* clear to send */
145 #define	DML_SR		0000020		/* secondary receive */
146 #define	DML_ST		0000010		/* secondary transmit */
147 #define	DML_RTS		0000004		/* request to send */
148 #define	DML_DTR		0000002		/* data terminal ready */
149 #define	DML_LE		0000001		/* line enable */
150 
151 /*
152  * Local variables for the driver
153  */
154 char	dmf_speeds[] =
155 	{ 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 };
156 
157 struct	tty dmf_tty[NDMF*8];
158 char	dmfsoftCAR[NDMF];
159 int	ndmf = NDMF*8;
160 int	dmfact;				/* mask of active dmf's */
161 int	dmfstart(), ttrstrt();
162 
163 #ifdef DMFDMA
164 /*
165  * The clist space is mapped by the driver onto each UNIBUS.
166  * The UBACVT macro converts a clist space address for unibus uban
167  * into an i/o space address for the DMA routine.
168  */
169 int	dmf_ubinfo[MAXNUBA];		/* info about allocated unibus map */
170 static int cbase[MAXNUBA];		/* base address in unibus map */
171 #define	UBACVT(x, uban)		(cbase[uban] + ((x)-(char *)cfree))
172 #endif
173 
174 /*
175  * Routine for configuration to set dmf interrupt.
176  */
177 /*ARGSUSED*/
178 dmfprobe(reg, ctlr)
179 	caddr_t reg;
180 	int ctlr;
181 {
182 	register int br, cvec;		/* these are ``value-result'' */
183 	register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg;
184 
185 #ifdef lint
186 	br = 0; cvec = br; br = cvec;
187 #endif
188 	br = 0x15;
189 	cvec = (uba_hd[numuba].uh_lastiv -= 4*8);
190 	dmfaddr->dmfccsr0 = cvec >> 2;
191 	/* NEED TO SAVE IT SOMEWHERE FOR OTHER DEVICES */
192 	return (sizeof (struct dmfdevice));
193 }
194 
195 /*
196  * Routine called to attach a dmf.
197  */
198 dmfattach(ui)
199 	struct uba_device *ui;
200 {
201 
202 	dmfsoftCAR[ui->ui_unit] = ui->ui_flags;
203 }
204 
205 
206 /*
207  * Open a DMF32 line, mapping the clist onto the uba if this
208  * is the first dmf on this uba.  Turn on this dmf if this is
209  * the first use of it.
210  */
211 /*ARGSUSED*/
212 dmfopen(dev, flag)
213 	dev_t dev;
214 {
215 	register struct tty *tp;
216 	register int unit, dmf;
217 	register struct dmfdevice *addr;
218 	register struct uba_device *ui;
219 	int s;
220 
221 	unit = minor(dev);
222 	dmf = unit >> 3;
223 	if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0) {
224 		u.u_error = ENXIO;
225 		return;
226 	}
227 	tp = &dmf_tty[unit];
228 	if (tp->t_state&TS_XCLUDE && u.u_uid!=0) {
229 		u.u_error = EBUSY;
230 		return;
231 	}
232 	addr = (struct dmfdevice *)ui->ui_addr;
233 	tp->t_addr = (caddr_t)addr;
234 	tp->t_oproc = dmfstart;
235 	tp->t_state |= TS_WOPEN;
236 	/*
237 	 * While setting up state for this uba and this dmf,
238 	 * block uba resets which can clear the state.
239 	 */
240 	s = spl5();
241 #ifdef DMFDMA
242 	if (dmf_ubinfo[ui->ui_ubanum] == 0) {
243 		dmf_ubinfo[ui->ui_ubanum] =
244 		    uballoc(ui->ui_ubanum, (caddr_t)cfree,
245 			nclist*sizeof(struct cblock), 0);
246 		cbase[ui->ui_ubanum] = dmf_ubinfo[ui->ui_ubanum]&0x3ffff;
247 	}
248 #endif
249 	if ((dmfact&(1<<dmf)) == 0) {
250 		addr->dmfcsr |= DMF_IE;
251 		dmfact |= (1<<dmf);
252 		addr->dmfrsp = 1;	/* DON'T KNOW WHAT TO SET IT TO YET */
253 	}
254 	splx(s);
255 	/*
256 	 * If this is first open, initialze tty state to default.
257 	 */
258 	if ((tp->t_state&TS_ISOPEN) == 0) {
259 		ttychars(tp);
260 		if (tp->t_ispeed == 0) {
261 			tp->t_ispeed = B300;
262 			tp->t_ospeed = B300;
263 			tp->t_flags = ODDP|EVENP|ECHO;
264 		}
265 		dmfparam(unit);
266 	}
267 	/*
268 	 * Wait for carrier, then process line discipline specific open.
269 	 */
270 	if ((dmfmctl(dev, DMF_ON, DMSET) & (DMF_CAR<<8)) ||
271 	    (dmfsoftCAR[dmf] & (1<<(unit&07))))
272 		tp->t_state |= TS_CARR_ON;
273 	s = spl5();
274 	while ((tp->t_state & TS_CARR_ON) == 0) {
275 		tp->t_state |= TS_WOPEN;
276 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
277 	}
278 	splx(s);
279 	(*linesw[tp->t_line].l_open)(dev, tp);
280 }
281 
282 /*
283  * Close a DMF32 line.
284  */
285 /*ARGSUSED*/
286 dmfclose(dev, flag)
287 	dev_t dev;
288 	int flag;
289 {
290 	register struct tty *tp;
291 	register unit;
292 
293 	unit = minor(dev);
294 	tp = &dmf_tty[unit];
295 	(*linesw[tp->t_line].l_close)(tp);
296 	dmfmctl(unit, DMF_BRK, DMBIC);
297 	if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0)
298 		dmfmctl(unit, DMF_OFF, DMSET);
299 	ttyclose(tp);
300 }
301 
302 dmfread(dev, uio)
303 	dev_t dev;
304 	struct uio *uio;
305 {
306 	register struct tty *tp;
307 
308 	tp = &dmf_tty[minor(dev)];
309 	return ((*linesw[tp->t_line].l_read)(tp, uio));
310 }
311 
312 dmfwrite(dev, uio)
313 	dev_t dev;
314 	struct uio *uio;
315 {
316 	register struct tty *tp;
317 
318 	tp = &dmf_tty[minor(dev)];
319 	(*linesw[tp->t_line].l_write)(tp, uio);
320 }
321 
322 /*
323  * DMF32 receiver interrupt.
324  */
325 dmfrint(dmf)
326 	int dmf;
327 {
328 	register struct tty *tp;
329 	register c;
330 	register struct dmfdevice *addr;
331 	register struct tty *tp0;
332 	register struct uba_device *ui;
333 	int overrun = 0;
334 
335 	ui = dmfinfo[dmf];
336 	if (ui == 0 || ui->ui_alive == 0)
337 		return;
338 	addr = (struct dmfdevice *)ui->ui_addr;
339 	tp0 = &dmf_tty[dmf<<3];
340 	/*
341 	 * Loop fetching characters from the silo for this
342 	 * dmf until there are no more in the silo.
343 	 */
344 	while ((c = addr->dmfrbuf) < 0) {
345 		tp = tp0 + ((c>>8)&07);
346 		if (c & DMF_DSC) {
347 			addr->dmfcsr = DMF_IE | DMFIR_TBUF | ((c>>8)&07);
348 			if (addr->dmfrms & DMF_CAR) {
349 				if ((tp->t_state & TS_CARR_ON) == 0) {
350 					wakeup((caddr_t)&tp->t_rawq);
351 					tp->t_state |= TS_CARR_ON;
352 				}
353 			} else {
354 				if (tp->t_state & TS_CARR_ON) {
355 					gsignal(tp->t_pgrp, SIGHUP);
356 					gsignal(tp->t_pgrp, SIGCONT);
357 					addr->dmfcsr = DMF_IE | DMFIR_LCR |
358 						((c>>8)&07);
359 					addr->dmftms = 0;
360 					flushtty(tp, FREAD|FWRITE);
361 				}
362 				tp->t_state &= ~TS_CARR_ON;
363 			}
364 			continue;
365 		}
366 		if ((tp->t_state&TS_ISOPEN)==0) {
367 			wakeup((caddr_t)tp);
368 			continue;
369 		}
370 		if (c & DMF_PE)
371 			if ((tp->t_flags&(EVENP|ODDP))==EVENP
372 			 || (tp->t_flags&(EVENP|ODDP))==ODDP )
373 				continue;
374 		if ((c & DMF_DO) && overrun == 0) {
375 			printf("dmf%d: silo overflow\n", dmf);
376 			overrun = 1;
377 		}
378 		if (c & DMF_FE)
379 			/*
380 			 * At framing error (break) generate
381 			 * a null (in raw mode, for getty), or a
382 			 * interrupt (in cooked/cbreak mode).
383 			 */
384 			if (tp->t_flags&RAW)
385 				c = 0;
386 			else
387 				c = tun.t_intrc;
388 #if NBK > 0
389 		if (tp->t_line == NETLDISC) {
390 			c &= 0177;
391 			BKINPUT(c, tp);
392 		} else
393 #endif
394 			(*linesw[tp->t_line].l_rint)(c, tp);
395 	}
396 }
397 
398 /*
399  * Ioctl for DMF32.
400  */
401 /*ARGSUSED*/
402 dmfioctl(dev, cmd, data, flag)
403 	dev_t dev;
404 	caddr_t data;
405 {
406 	register struct tty *tp;
407 	register int unit = minor(dev);
408 	register int dmf = unit >> 3;
409 	register struct device *dmfaddr;
410 
411 	tp = &dmf_tty[unit];
412 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
413 	if (cmd == 0)
414 		return;
415 	if (ttioctl(tp, cmd, data, flag)) {
416 		if (cmd == TIOCSETP || cmd == TIOCSETN)
417 			dmfparam(unit);
418 	} else switch(cmd) {
419 
420 	case TIOCSBRK:
421 		dmfmctl(dev, DMF_BRK, DMBIS);
422 		break;
423 
424 	case TIOCCBRK:
425 		dmfmctl(dev, DMF_BRK, DMBIC);
426 		break;
427 
428 	case TIOCSDTR:
429 		dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS);
430 		break;
431 
432 	case TIOCCDTR:
433 		dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC);
434 		break;
435 
436 	case TIOCMSET:
437 		dmfmctl(dev, dmtodmf(*(int *)data), DMSET);
438 		break;
439 
440 	case TIOCMBIS:
441 		dmfmctl(dev, dmtodmf(*(int *)data), DMBIS);
442 		break;
443 
444 	case TIOCMBIC:
445 		dmfmctl(dev, dmtodmf(*(int *)data), DMBIC);
446 		break;
447 
448 	case TIOCMGET:
449 		*(int *)data = dmftodm(dmfmctl(dev, 0, DMGET));
450 		break;
451 
452 	default:
453 		u.u_error = ENOTTY;
454 	}
455 }
456 
457 dmtodmf(bits)
458 	register int bits;
459 {
460 	register int b;
461 
462 	b = bits & 012;
463 	if (bits & DML_ST) b |= DMF_RATE;
464 	if (bits & DML_RTS) b |= DMF_RTS;
465 	if (bits & DML_USR) b |= DMF_USRW;
466 	return(b);
467 }
468 
469 dmftodm(bits)
470 	register int bits;
471 {
472 	register int b;
473 
474 	b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE;
475 	if (bits & DMF_USRR) b |= DML_USR;
476 	if (bits & DMF_RTS) b |= DML_RTS;
477 	return(b);
478 }
479 
480 
481 /*
482  * Set parameters from open or stty into the DMF hardware
483  * registers.
484  */
485 dmfparam(unit)
486 	register int unit;
487 {
488 	register struct tty *tp;
489 	register struct dmfdevice *addr;
490 	register int lpar, lcr;
491 	int s;
492 
493 	tp = &dmf_tty[unit];
494 	addr = (struct dmfdevice *)tp->t_addr;
495 	/*
496 	 * Block interrupts so parameters will be set
497 	 * before the line interrupts.
498 	 */
499 	s = spl5();
500 	addr->dmfcsr = (unit&07) | DMFIR_LCR | DMF_IE;
501 	if ((tp->t_ispeed)==0) {
502 		tp->t_state |= TS_HUPCLS;
503 		dmfmctl(unit, DMF_OFF, DMSET);
504 		return;
505 	}
506 	lpar = (dmf_speeds[tp->t_ospeed]<<12) | (dmf_speeds[tp->t_ispeed]<<8);
507 	lcr = DMFLCR_ENA;
508 	if ((tp->t_ispeed) == B134)
509 		lpar |= BITS6|PENABLE;
510 	else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
511 		lpar |= BITS8;
512 	else {
513 		lpar |= BITS7|PENABLE;
514 		/* CHECK FOR XON/XOFF AND SET lcr |= DMF_AUTOX; */
515 	}
516 	if ((tp->t_flags&EVENP) == 0)
517 		lpar |= OPAR;
518 	if ((tp->t_ospeed) == B110)
519 		lpar |= TWOSB;
520 	lpar |= (unit&07);
521 	addr->dmflpr = lpar;
522 	addr->dmflcr = lcr;
523 	splx(s);
524 }
525 
526 /*
527  * DMF32 transmitter interrupt.
528  * Restart the idle line.
529  */
530 dmfxint(dmf)
531 	int dmf;
532 {
533 	register struct tty *tp;
534 	register struct dmfdevice *addr;
535 	register struct uba_device *ui;
536 	register int unit, t;
537 #ifdef DMFDMA
538 	short cntr;
539 #endif
540 
541 	ui = dmfinfo[dmf];
542 	addr = (struct dmfdevice *)ui->ui_addr;
543 	while ((t = addr->dmfcsr) & DMF_TI) {
544 		unit = dmf*8 + ((t>>8)&07);
545 		tp = &dmf_tty[unit];
546 		tp->t_state &= ~TS_BUSY;
547 		if (t & DMF_NXM) {
548 			printf("dmf%d: NXM line %d\n", dmf, unit&7);
549 			/* SHOULD RESTART OR SOMETHING... */
550 		}
551 		if (tp->t_state&TS_FLUSH)
552 			tp->t_state &= ~TS_FLUSH;
553 #ifdef DMFDMA
554 		else {
555 			addr->dmfcsr = DMFIR_TBUF | DMF_IE | (unit&07);
556 			if (addr->dmftsc == 0) {
557 				/*
558 				 * Do arithmetic in a short to make up
559 				 * for lost 16&17 bits.
560 				 */
561 				addr->dmfcsr = DMFIR_TBA | DMF_IE | (unit&07);
562 				cntr = addr->dmftba -
563 				    UBACVT(tp->t_outq.c_cf, ui->ui_ubanum);
564 				ndflush(&tp->t_outq, (int)cntr);
565 			}
566 		}
567 #endif
568 		if (tp->t_line)
569 			(*linesw[tp->t_line].l_start)(tp);
570 		else
571 			dmfstart(tp);
572 	}
573 }
574 
575 /*
576  * Start (restart) transmission on the given DMF32 line.
577  */
578 dmfstart(tp)
579 	register struct tty *tp;
580 {
581 	register struct dmfdevice *addr;
582 	register int car, dmf, unit, nch;
583 	int s;
584 
585 	unit = minor(tp->t_dev);
586 	dmf = unit >> 3;
587 	unit &= 07;
588 	addr = (struct dmfdevice *)tp->t_addr;
589 
590 	/*
591 	 * Must hold interrupts in following code to prevent
592 	 * state of the tp from changing.
593 	 */
594 	s = spl5();
595 	/*
596 	 * If it's currently active, or delaying, no need to do anything.
597 	 */
598 	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
599 		goto out;
600 	/*
601 	 * If there are still characters in the silo,
602 	 * just reenable the transmitter.
603 	 */
604 	addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
605 	if (addr->dmftsc) {
606 		addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
607 		addr->dmflcr |= DMF_TE;
608 		tp->t_state |= TS_BUSY;
609 		goto out;
610 	}
611 	/*
612 	 * If there are sleepers, and output has drained below low
613 	 * water mark, wake up the sleepers.
614 	 */
615 	if ((tp->t_state&TS_ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) {
616 		tp->t_state &= ~TS_ASLEEP;
617 		wakeup((caddr_t)&tp->t_outq);
618 	}
619 	/*
620 	 * Now restart transmission unless the output queue is
621 	 * empty.
622 	 */
623 	if (tp->t_outq.c_cc == 0)
624 		goto out;
625 	if (tp->t_flags&RAW || tp->t_local&LLITOUT)
626 		nch = ndqb(&tp->t_outq, 0);
627 	else {
628 		nch = ndqb(&tp->t_outq, 0200);
629 		/*
630 		 * If first thing on queue is a delay process it.
631 		 */
632 		if (nch == 0) {
633 			nch = getc(&tp->t_outq);
634 			timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
635 			tp->t_state |= TS_TIMEOUT;
636 			goto out;
637 		}
638 	}
639 	/*
640 	 * If characters to transmit, restart transmission.
641 	 */
642 	if (nch) {
643 #ifdef DMFDMA
644 		addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
645 		addr->dmflcr |= DMF_TE;
646 		car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum);
647 		addr->dmfcsr = DMF_IE | DMFIR_TBA | unit;
648 		addr->dmftba = car;
649 		addr->dmftcc = ((car>>2)&0xc000) | nch;
650 #else
651 		register char *cp = tp->t_outq.c_cf;
652 		register int i;
653 
654 		nch = MIN(nch, DMF_SILOCNT);
655 		addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
656 		addr->dmflcr |= DMF_TE;
657 		addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
658 		for (i = 0; i < nch; i++)
659 			addr->dmftbuf = *cp++;
660 		ndflush(&tp->t_outq, nch);
661 #endif
662 		tp->t_state |= TS_BUSY;
663 	}
664 out:
665 	splx(s);
666 }
667 
668 /*
669  * Stop output on a line, e.g. for ^S/^Q or output flush.
670  */
671 /*ARGSUSED*/
672 dmfstop(tp, flag)
673 	register struct tty *tp;
674 {
675 	register struct dmfdevice *addr;
676 	register int unit, s;
677 
678 	addr = (struct dmfdevice *)tp->t_addr;
679 	/*
680 	 * Block input/output interrupts while messing with state.
681 	 */
682 	s = spl5();
683 	if (tp->t_state & TS_BUSY) {
684 		/*
685 		 * Device is transmitting; stop output
686 		 * by selecting the line and disabling
687 		 * the transmitter.  If this is a flush
688 		 * request then flush the output silo,
689 		 * otherwise we will pick up where we
690 		 * left off by enabling the transmitter.
691 		 */
692 		unit = minor(tp->t_dev);
693 		addr->dmfcsr = DMFIR_LCR | (unit&07) | DMF_IE;
694 		addr->dmflcr &= ~DMF_TE;
695 		if ((tp->t_state&TS_TTSTOP)==0) {
696 			tp->t_state |= TS_FLUSH;
697 			addr->dmflcr |= DMF_FLUSH;
698 		} else
699 			tp->t_state &= ~TS_BUSY;
700 	}
701 	splx(s);
702 }
703 
704 /*
705  * DMF32 modem control
706  */
707 dmfmctl(dev, bits, how)
708 	dev_t dev;
709 	int bits, how;
710 {
711 	register struct dmfdevice *dmfaddr;
712 	register int unit, mbits, lcr;
713 	int s;
714 
715 	unit = minor(dev);
716 	dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr);
717 	unit &= 07;
718 	s = spl5();
719 	dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
720 	mbits = dmfaddr->dmfrms << 8;
721 	dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
722 	mbits |= dmfaddr->dmftms;
723 	lcr = dmfaddr->dmflcr;
724 	switch (how) {
725 	case DMSET:
726 		mbits = bits;
727 		break;
728 
729 	case DMBIS:
730 		mbits |= bits;
731 		break;
732 
733 	case DMBIC:
734 		mbits &= ~bits;
735 		break;
736 
737 	case DMGET:
738 		(void) splx(s);
739 		return(mbits);
740 	}
741 	dmfaddr->dmftms = mbits&037;
742 	if (mbits & DMF_BRK)
743 		lcr |= DMF_RBRK;
744 	else
745 		lcr &= ~DMF_RBRK;
746 	dmfaddr->dmflcr = lcr;
747 	(void) splx(s);
748 	return(mbits);
749 }
750 
751 /*
752  * Reset state of driver if UBA reset was necessary.
753  * Reset the csr, lpr, and lcr registers on open lines, and
754  * restart transmitters.
755  */
756 dmfreset(uban)
757 	int uban;
758 {
759 	register int dmf, unit;
760 	register struct tty *tp;
761 	register struct uba_device *ui;
762 	register struct dmfdevice *addr;
763 	int i;
764 
765 #ifdef DMFDMA
766 	if (dmf_ubinfo[uban] == 0)
767 		return;
768 	ubarelse(uban, &dmf_ubinfo[uban]);
769 	dmf_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
770 	    nclist*sizeof (struct cblock), 0);
771 	cbase[uban] = dmf_ubinfo[uban]&0x3ffff;
772 #endif
773 	for (dmf = 0; dmf < NDMF; dmf++) {
774 		ui = dmfinfo[dmf];
775 		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
776 			continue;
777 		printf(" dmf%d", dmf);
778 		addr = (struct dmfdevice *)ui->ui_addr;
779 		addr->dmfcsr = DMF_IE;
780 		addr->dmfrsp = 1;
781 		unit = dmf * 8;
782 		for (i = 0; i < 8; i++) {
783 			tp = &dmf_tty[unit];
784 			if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
785 				dmfparam(unit);
786 				dmfmctl(unit, DMF_ON, DMSET);
787 				tp->t_state &= ~TS_BUSY;
788 				dmfstart(tp);
789 			}
790 			unit++;
791 		}
792 	}
793 }
794 
795 /* stubs for interrupt routines for devices not yet supported */
796 
797 dmfsrint() { printf("dmfsrint\n"); }
798 
799 dmfsxint() { printf("dmfsxint\n"); }
800 
801 dmfdaint() { printf("dmfdaint\n"); }
802 
803 dmfdbint() { printf("dmfdbint\n"); }
804 
805 dmflint() { printf("dmflint\n"); }
806 #endif
807