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