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