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