xref: /original-bsd/sys/vax/uba/dh.c (revision d19c88bc)
1 /*	dh.c	4.42	82/03/14	*/
2 
3 #include "dh.h"
4 #if NDH > 0
5 /*
6  * DH-11/DM-11 driver
7  */
8 #include "bk.h"
9 #include "../h/param.h"
10 #include "../h/conf.h"
11 #include "../h/dir.h"
12 #include "../h/user.h"
13 #include "../h/proc.h"
14 #include "../h/tty.h"
15 #include "../h/map.h"
16 #include "../h/pte.h"
17 #include "../h/buf.h"
18 #include "../h/vm.h"
19 #include "../h/ubareg.h"
20 #include "../h/ubavar.h"
21 #include "../h/bk.h"
22 #include "../h/clist.h"
23 #include "../h/file.h"
24 
25 /*
26  * Definition of the driver for the auto-configuration program.
27  * There is one definition for the dh and one for the dm.
28  */
29 int	dhprobe(), dhattach(), dhrint(), dhxint();
30 struct	uba_device *dhinfo[NDH];
31 u_short	dhstd[] = { 0 };
32 struct	uba_driver dhdriver =
33 	{ dhprobe, 0, dhattach, 0, dhstd, "dh", dhinfo };
34 
35 int	dmprobe(), dmattach(), dmintr();
36 struct	uba_device *dminfo[NDH];
37 u_short	dmstd[] = { 0 };
38 struct	uba_driver dmdriver =
39 	{ dmprobe, 0, dmattach, 0, dmstd, "dm", dminfo };
40 
41 struct dhdevice
42 {
43 	union {
44 		short	dhcsr;		/* control-status register */
45 		char	dhcsrl;		/* low byte for line select */
46 	} un;
47 	short	dhrcr;			/* receive character register */
48 	short	dhlpr;			/* line parameter register */
49 	u_short dhcar;			/* current address register */
50 	short	dhbcr;			/* byte count register */
51 	u_short	dhbar;			/* buffer active register */
52 	short	dhbreak;		/* break control register */
53 	short	dhsilo;			/* silo status register */
54 };
55 
56 /* Bits in dhcsr */
57 #define	DH_TI	0100000		/* transmit interrupt */
58 #define	DH_SI	0040000		/* storage interrupt */
59 #define	DH_TIE	0020000		/* transmit interrupt enable */
60 #define	DH_SIE	0010000		/* storage interrupt enable */
61 #define	DH_MC	0004000		/* master clear */
62 #define	DH_NXM	0002000		/* non-existant memory */
63 #define	DH_MM	0001000		/* maintenance mode */
64 #define	DH_CNI	0000400		/* clear non-existant memory interrupt */
65 #define	DH_RI	0000200		/* receiver interrupt */
66 #define	DH_RIE	0000100		/* receiver interrupt enable */
67 
68 /* Bits in dhlpr */
69 #define	BITS6	01
70 #define	BITS7	02
71 #define	BITS8	03
72 #define	TWOSB	04
73 #define	PENABLE	020
74 /* DEC manuals incorrectly say this bit causes generation of even parity. */
75 #define	OPAR	040
76 #define	HDUPLX	040000
77 
78 #define	DH_IE	(DH_TIE|DH_SIE|DH_RIE)
79 
80 /* Bits in dhrcr */
81 #define	DH_PE		0010000		/* parity error */
82 #define	DH_FE		0020000		/* framing error */
83 #define	DH_DO		0040000		/* data overrun */
84 
85 struct dmdevice
86 {
87 	short	dmcsr;		/* control status register */
88 	short	dmlstat;	/* line status register */
89 	short	dmpad1[2];
90 };
91 
92 /* bits in dm csr */
93 #define	DM_RF		0100000		/* ring flag */
94 #define	DM_CF		0040000		/* carrier flag */
95 #define	DM_CTS		0020000		/* clear to send */
96 #define	DM_SRF		0010000		/* secondary receive flag */
97 #define	DM_CS		0004000		/* clear scan */
98 #define	DM_CM		0002000		/* clear multiplexor */
99 #define	DM_MM		0001000		/* maintenance mode */
100 #define	DM_STP		0000400		/* step */
101 #define	DM_DONE		0000200		/* scanner is done */
102 #define	DM_IE		0000100		/* interrupt enable */
103 #define	DM_SE		0000040		/* scan enable */
104 #define	DM_BUSY		0000020		/* scan busy */
105 
106 /* bits in dm lsr */
107 #define	DML_RNG		0000200		/* ring */
108 #define	DML_CAR		0000100		/* carrier detect */
109 #define	DML_CTS		0000040		/* clear to send */
110 #define	DML_SR		0000020		/* secondary receive */
111 #define	DML_ST		0000010		/* secondary transmit */
112 #define	DML_RTS		0000004		/* request to send */
113 #define	DML_DTR		0000002		/* data terminal ready */
114 #define	DML_LE		0000001		/* line enable */
115 
116 #define	DML_ON		(DML_DTR|DML_RTS|DML_LE)
117 #define	DML_OFF		(DML_LE)
118 
119 /*
120  * Local variables for the driver
121  */
122 short	dhsar[NDH];			/* software copy of last bar */
123 short	dhsoftCAR[NDH];
124 
125 struct	tty dh11[NDH*16];
126 int	ndh11	= NDH*16;
127 int	dhact;				/* mask of active dh's */
128 int	dhstart(), ttrstrt();
129 
130 /*
131  * The clist space is mapped by the driver onto each UNIBUS.
132  * The UBACVT macro converts a clist space address for unibus uban
133  * into an i/o space address for the DMA routine.
134  */
135 int	dh_ubinfo[MAXNUBA];		/* info about allocated unibus map */
136 int	cbase[MAXNUBA];			/* base address in unibus map */
137 #define	UBACVT(x, uban)		(cbase[uban] + ((x)-(char *)cfree))
138 
139 /*
140  * Routine for configuration to force a dh to interrupt.
141  * Set to transmit at 9600 baud, and cause a transmitter interrupt.
142  */
143 /*ARGSUSED*/
144 dhprobe(reg)
145 	caddr_t reg;
146 {
147 	register int br, cvec;		/* these are ``value-result'' */
148 	register struct dhdevice *dhaddr = (struct dhdevice *)reg;
149 
150 #ifdef lint
151 	br = 0; cvec = br; br = cvec;
152 	dhrint(0); dhxint(0);
153 #endif
154 #ifndef notdef
155 	dhaddr->un.dhcsr = DH_RIE|DH_MM|DH_RI;
156 	DELAY(25);
157 	dhaddr->un.dhcsr = 0;
158 #else
159 	dhaddr->un.dhcsr = DH_TIE;
160 	DELAY(5);
161 	dhaddr->dhlpr = (B9600 << 10) | (B9600 << 6) | BITS7|PENABLE;
162 	dhaddr->dhbcr = -1;
163 	dhaddr->dhcar = 0;
164 	dhaddr->dhbar = 1;
165 	DELAY(100000);		/* wait 1/10'th of a sec for interrupt */
166 	dhaddr->un.dhcsr = 0;
167 	if (cvec && cvec != 0x200)
168 		cvec -= 4;		/* transmit -> receive */
169 #endif
170 	return (1);
171 }
172 
173 /*
174  * Routine called to attach a dh.
175  */
176 dhattach(ui)
177 	struct uba_device *ui;
178 {
179 
180 	dhsoftCAR[ui->ui_unit] = ui->ui_flags;
181 }
182 
183 /*
184  * Configuration routine to cause a dm to interrupt.
185  */
186 dmprobe(reg)
187 	caddr_t reg;
188 {
189 	register int br, vec;			/* value-result */
190 	register struct dmdevice *dmaddr = (struct dmdevice *)reg;
191 
192 #ifdef lint
193 	br = 0; vec = br; br = vec;
194 	dmintr(0);
195 #endif
196 	dmaddr->dmcsr = DM_DONE|DM_IE;
197 	DELAY(20);
198 	dmaddr->dmcsr = 0;
199 	return (1);
200 }
201 
202 /*ARGSUSED*/
203 dmattach(ui)
204 	struct uba_device *ui;
205 {
206 
207 	/* no local state to set up */
208 }
209 
210 /*
211  * Open a DH11 line, mapping the clist onto the uba if this
212  * is the first dh on this uba.  Turn on this dh if this is
213  * the first use of it.  Also do a dmopen to wait for carrier.
214  */
215 /*ARGSUSED*/
216 dhopen(dev, flag)
217 	dev_t dev;
218 {
219 	register struct tty *tp;
220 	register int unit, dh;
221 	register struct dhdevice *addr;
222 	register struct uba_device *ui;
223 	int s;
224 
225 	unit = minor(dev);
226 	dh = unit >> 4;
227 	if (unit >= NDH*16 || (ui = dhinfo[dh])== 0 || ui->ui_alive == 0) {
228 		u.u_error = ENXIO;
229 		return;
230 	}
231 	tp = &dh11[unit];
232 	if (tp->t_state&TS_XCLUDE && u.u_uid!=0) {
233 		u.u_error = EBUSY;
234 		return;
235 	}
236 	addr = (struct dhdevice *)ui->ui_addr;
237 	tp->t_addr = (caddr_t)addr;
238 	tp->t_oproc = dhstart;
239 	tp->t_state |= TS_WOPEN;
240 	/*
241 	 * While setting up state for this uba and this dh,
242 	 * block uba resets which can clear the state.
243 	 */
244 	s = spl5();
245 	if (dh_ubinfo[ui->ui_ubanum] == 0) {
246 		/* 512+ is a kludge to try to get around a hardware problem */
247 		dh_ubinfo[ui->ui_ubanum] =
248 		    uballoc(ui->ui_ubanum, (caddr_t)cfree,
249 			512+nclist*sizeof(struct cblock), 0);
250 		cbase[ui->ui_ubanum] = dh_ubinfo[ui->ui_ubanum]&0x3ffff;
251 	}
252 	if ((dhact&(1<<dh)) == 0) {
253 		addr->un.dhcsr |= DH_IE;
254 		dhact |= (1<<dh);
255 		addr->dhsilo = 16;
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 		dhparam(unit);
269 	}
270 	/*
271 	 * Wait for carrier, then process line discipline specific open.
272 	 */
273 	dmopen(dev);
274 	(*linesw[tp->t_line].l_open)(dev, tp);
275 }
276 
277 /*
278  * Close a DH11 line, turning off the DM11.
279  */
280 /*ARGSUSED*/
281 dhclose(dev, flag)
282 	dev_t dev;
283 	int flag;
284 {
285 	register struct tty *tp;
286 	register unit;
287 
288 	unit = minor(dev);
289 	tp = &dh11[unit];
290 	(*linesw[tp->t_line].l_close)(tp);
291 	((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
292 	if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0)
293 		dmctl(unit, DML_OFF, DMSET);
294 	ttyclose(tp);
295 }
296 
297 dhread(dev)
298 	dev_t dev;
299 {
300 	register struct tty *tp;
301 
302 	tp = &dh11[minor(dev)];
303 	(*linesw[tp->t_line].l_read)(tp);
304 }
305 
306 dhwrite(dev)
307 	dev_t dev;
308 {
309 	register struct tty *tp;
310 
311 	tp = &dh11[minor(dev)];
312 	(*linesw[tp->t_line].l_write)(tp);
313 }
314 
315 /*
316  * DH11 receiver interrupt.
317  */
318 dhrint(dh)
319 	int dh;
320 {
321 	register struct tty *tp;
322 	register c;
323 	register struct dhdevice *addr;
324 	register struct tty *tp0;
325 	register struct uba_device *ui;
326 	int overrun = 0;
327 
328 	ui = dhinfo[dh];
329 	if (ui == 0 || ui->ui_alive == 0)
330 		return;
331 	addr = (struct dhdevice *)ui->ui_addr;
332 	tp0 = &dh11[dh<<4];
333 	/*
334 	 * Loop fetching characters from the silo for this
335 	 * dh until there are no more in the silo.
336 	 */
337 	while ((c = addr->dhrcr) < 0) {
338 		tp = tp0 + ((c>>8)&0xf);
339 		if ((tp->t_state&TS_ISOPEN)==0) {
340 			wakeup((caddr_t)tp);
341 			continue;
342 		}
343 		if (c & DH_PE)
344 			if ((tp->t_flags&(EVENP|ODDP))==EVENP
345 			 || (tp->t_flags&(EVENP|ODDP))==ODDP )
346 				continue;
347 		if ((c & DH_DO) && overrun == 0) {
348 			printf("dh%d: silo overflow\n", dh);
349 			overrun = 1;
350 		}
351 		if (c & DH_FE)
352 			/*
353 			 * At framing error (break) generate
354 			 * a null (in raw mode, for getty), or a
355 			 * interrupt (in cooked/cbreak mode).
356 			 */
357 			if (tp->t_flags&RAW)
358 				c = 0;
359 			else
360 				c = tun.t_intrc;
361 #if NBK > 0
362 		if (tp->t_line == NETLDISC) {
363 			c &= 0177;
364 			BKINPUT(c, tp);
365 		} else
366 #endif
367 			(*linesw[tp->t_line].l_rint)(c, tp);
368 	}
369 }
370 
371 /*
372  * Ioctl for DH11.
373  */
374 /*ARGSUSED*/
375 dhioctl(dev, cmd, addr, flag)
376 	caddr_t addr;
377 {
378 	register struct tty *tp;
379 	register unit = minor(dev);
380 
381 	tp = &dh11[unit];
382 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
383 	if (cmd == 0)
384 		return;
385 	if (ttioctl(tp, cmd, addr, flag)) {
386 		if (cmd==TIOCSETP || cmd==TIOCSETN)
387 			dhparam(unit);
388 	} else switch(cmd) {
389 	case TIOCSBRK:
390 		((struct dhdevice *)(tp->t_addr))->dhbreak |= 1<<(unit&017);
391 		break;
392 	case TIOCCBRK:
393 		((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
394 		break;
395 	case TIOCSDTR:
396 		dmctl(unit, DML_DTR|DML_RTS, DMBIS);
397 		break;
398 	case TIOCCDTR:
399 		dmctl(unit, DML_DTR|DML_RTS, DMBIC);
400 		break;
401 	default:
402 		u.u_error = ENOTTY;
403 	}
404 }
405 
406 /*
407  * Set parameters from open or stty into the DH hardware
408  * registers.
409  */
410 dhparam(unit)
411 	register int unit;
412 {
413 	register struct tty *tp;
414 	register struct dhdevice *addr;
415 	register int lpar;
416 	int s;
417 
418 	tp = &dh11[unit];
419 	addr = (struct dhdevice *)tp->t_addr;
420 	/*
421 	 * Block interrupts so parameters will be set
422 	 * before the line interrupts.
423 	 */
424 	s = spl5();
425 	addr->un.dhcsrl = (unit&0xf) | DH_IE;
426 	if ((tp->t_ispeed)==0) {
427 		tp->t_state |= TS_HUPCLS;
428 		dmctl(unit, DML_OFF, DMSET);
429 		return;
430 	}
431 	lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
432 	if ((tp->t_ispeed) == B134)
433 		lpar |= BITS6|PENABLE|HDUPLX;
434 	else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
435 		lpar |= BITS8;
436 	else
437 		lpar |= BITS7|PENABLE;
438 	if ((tp->t_flags&EVENP) == 0)
439 		lpar |= OPAR;
440 	if ((tp->t_ospeed) == B110)
441 		lpar |= TWOSB;
442 	addr->dhlpr = lpar;
443 	splx(s);
444 }
445 
446 /*
447  * DH11 transmitter interrupt.
448  * Restart each line which used to be active but has
449  * terminated transmission since the last interrupt.
450  */
451 dhxint(dh)
452 	int dh;
453 {
454 	register struct tty *tp;
455 	register struct dhdevice *addr;
456 	short ttybit, bar, *sbar;
457 	register struct uba_device *ui;
458 	register int unit;
459 	u_short cntr;
460 
461 	ui = dhinfo[dh];
462 	addr = (struct dhdevice *)ui->ui_addr;
463 	if (addr->un.dhcsr & DH_NXM) {
464 		addr->un.dhcsr |= DH_CNI;
465 		printf("dh%d: NXM\n", dh);
466 	}
467 	sbar = &dhsar[dh];
468 	bar = *sbar & ~addr->dhbar;
469 	unit = dh * 16; ttybit = 1;
470 	addr->un.dhcsr &= (short)~DH_TI;
471 	for (; bar; unit++, ttybit <<= 1) {
472 		if (bar & ttybit) {
473 			*sbar &= ~ttybit;
474 			bar &= ~ttybit;
475 			tp = &dh11[unit];
476 			tp->t_state &= ~TS_BUSY;
477 			if (tp->t_state&TS_FLUSH)
478 				tp->t_state &= ~TS_FLUSH;
479 			else {
480 				addr->un.dhcsrl = (unit&017)|DH_IE;
481 				/*
482 				 * Do arithmetic in a short to make up
483 				 * for lost 16&17 bits.
484 				 */
485 				cntr = addr->dhcar -
486 				    UBACVT(tp->t_outq.c_cf, ui->ui_ubanum);
487 				ndflush(&tp->t_outq, (int)cntr);
488 			}
489 			if (tp->t_line)
490 				(*linesw[tp->t_line].l_start)(tp);
491 			else
492 				dhstart(tp);
493 		}
494 	}
495 }
496 
497 /*
498  * Start (restart) transmission on the given DH11 line.
499  */
500 dhstart(tp)
501 	register struct tty *tp;
502 {
503 	register struct dhdevice *addr;
504 	register int car, dh, unit, nch;
505 	int s;
506 
507 	unit = minor(tp->t_dev);
508 	dh = unit >> 4;
509 	unit &= 0xf;
510 	addr = (struct dhdevice *)tp->t_addr;
511 
512 	/*
513 	 * Must hold interrupts in following code to prevent
514 	 * state of the tp from changing.
515 	 */
516 	s = spl5();
517 	/*
518 	 * If it's currently active, or delaying, no need to do anything.
519 	 */
520 	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
521 		goto out;
522 	/*
523 	 * If there are sleepers, and output has drained below low
524 	 * water mark, wake up the sleepers.
525 	 */
526 	if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
527 		if (tp->t_state&TS_ASLEEP) {
528 			tp->t_state &= ~TS_ASLEEP;
529 			wakeup((caddr_t)&tp->t_outq);
530 		}
531 		if (tp->t_wsel) {
532 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
533 			tp->t_wsel = 0;
534 			tp->t_state &= ~TS_WCOLL;
535 		}
536 	}
537 	/*
538 	 * Now restart transmission unless the output queue is
539 	 * empty.
540 	 */
541 	if (tp->t_outq.c_cc == 0)
542 		goto out;
543 	if (tp->t_flags&RAW || tp->t_local&LLITOUT)
544 		nch = ndqb(&tp->t_outq, 0);
545 	else {
546 		nch = ndqb(&tp->t_outq, 0200);
547 		/*
548 		 * If first thing on queue is a delay process it.
549 		 */
550 		if (nch == 0) {
551 			nch = getc(&tp->t_outq);
552 			timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
553 			tp->t_state |= TS_TIMEOUT;
554 			goto out;
555 		}
556 	}
557 	/*
558 	 * If characters to transmit, restart transmission.
559 	 */
560 	if (nch) {
561 		car = UBACVT(tp->t_outq.c_cf, dhinfo[dh]->ui_ubanum);
562 		addr->un.dhcsrl = unit|((car>>12)&0x30)|DH_IE;
563 		/*
564 		 * The following nonsense with short word
565 		 * is to make sure the dhbar |= word below
566 		 * is done with an interlocking bisw2 instruction.
567 		 */
568 		{ short word = 1 << unit;
569 		dhsar[dh] |= word;
570 		addr->dhcar = car;
571 		addr->dhbcr = -nch;
572 		addr->dhbar |= word;
573 		}
574 		tp->t_state |= TS_BUSY;
575 	}
576 out:
577 	splx(s);
578 }
579 
580 /*
581  * Stop output on a line, e.g. for ^S/^Q or output flush.
582  */
583 /*ARGSUSED*/
584 dhstop(tp, flag)
585 	register struct tty *tp;
586 {
587 	register struct dhdevice *addr;
588 	register int unit, s;
589 
590 	addr = (struct dhdevice *)tp->t_addr;
591 	/*
592 	 * Block input/output interrupts while messing with state.
593 	 */
594 	s = spl5();
595 	if (tp->t_state & TS_BUSY) {
596 		/*
597 		 * Device is transmitting; stop output
598 		 * by selecting the line and setting the byte
599 		 * count to -1.  We will clean up later
600 		 * by examining the address where the dh stopped.
601 		 */
602 		unit = minor(tp->t_dev);
603 		addr->un.dhcsrl = (unit&017) | DH_IE;
604 		if ((tp->t_state&TS_TTSTOP)==0)
605 			tp->t_state |= TS_FLUSH;
606 		addr->dhbcr = -1;
607 	}
608 	splx(s);
609 }
610 
611 /*
612  * Reset state of driver if UBA reset was necessary.
613  * Reset the csrl and lpr registers on open lines, and
614  * restart transmitters.
615  */
616 dhreset(uban)
617 	int uban;
618 {
619 	register int dh, unit;
620 	register struct tty *tp;
621 	register struct uba_device *ui;
622 	int i;
623 
624 	if (dh_ubinfo[uban] == 0)
625 		return;
626 	ubarelse(uban, &dh_ubinfo[uban]);
627 	dh_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
628 	    512+nclist*sizeof (struct cblock), 0);
629 	cbase[uban] = dh_ubinfo[uban]&0x3ffff;
630 	dh = 0;
631 	for (dh = 0; dh < NDH; dh++) {
632 		ui = dhinfo[dh];
633 		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
634 			continue;
635 		printf(" dh%d", dh);
636 		((struct dhdevice *)ui->ui_addr)->un.dhcsr |= DH_IE;
637 		((struct dhdevice *)ui->ui_addr)->dhsilo = 16;
638 		unit = dh * 16;
639 		for (i = 0; i < 16; i++) {
640 			tp = &dh11[unit];
641 			if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
642 				dhparam(unit);
643 				dmctl(unit, DML_ON, DMSET);
644 				tp->t_state &= ~TS_BUSY;
645 				dhstart(tp);
646 			}
647 			unit++;
648 		}
649 	}
650 	dhtimer();
651 }
652 
653 /*
654  * At software clock interrupt time or after a UNIBUS reset
655  * empty all the dh silos.
656  */
657 dhtimer()
658 {
659 	register int dh;
660 
661 	for (dh = 0; dh < NDH; dh++)
662 		dhrint(dh);
663 }
664 
665 /*
666  * Turn on the line associated with dh dev.
667  */
668 dmopen(dev)
669 	dev_t dev;
670 {
671 	register struct tty *tp;
672 	register struct dmdevice *addr;
673 	register struct uba_device *ui;
674 	register int unit;
675 	register int dm;
676 	int s;
677 
678 	unit = minor(dev);
679 	dm = unit >> 4;
680 	tp = &dh11[unit];
681 	unit &= 0xf;
682 	if (dm >= NDH || (ui = dminfo[dm]) == 0 || ui->ui_alive == 0 ||
683 	    (dhsoftCAR[dm]&(1<<unit))) {
684 		tp->t_state |= TS_CARR_ON;
685 		return;
686 	}
687 	addr = (struct dmdevice *)ui->ui_addr;
688 	s = spl5();
689 	addr->dmcsr &= ~DM_SE;
690 	while (addr->dmcsr & DM_BUSY)
691 		;
692 	addr->dmcsr = unit;
693 	addr->dmlstat = DML_ON;
694 	if (addr->dmlstat&DML_CAR)
695 		tp->t_state |= TS_CARR_ON;
696 	addr->dmcsr = DM_IE|DM_SE;
697 	while ((tp->t_state&TS_CARR_ON)==0)
698 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
699 	splx(s);
700 }
701 
702 /*
703  * Dump control bits into the DM registers.
704  */
705 dmctl(dev, bits, how)
706 	dev_t dev;
707 	int bits, how;
708 {
709 	register struct uba_device *ui;
710 	register struct dmdevice *addr;
711 	register int unit, s;
712 	int dm;
713 
714 	unit = minor(dev);
715 	dm = unit >> 4;
716 	if ((ui = dminfo[dm]) == 0 || ui->ui_alive == 0)
717 		return;
718 	addr = (struct dmdevice *)ui->ui_addr;
719 	s = spl5();
720 	addr->dmcsr &= ~DM_SE;
721 	while (addr->dmcsr & DM_BUSY)
722 		;
723 	addr->dmcsr = unit & 0xf;
724 	switch(how) {
725 	case DMSET:
726 		addr->dmlstat = bits;
727 		break;
728 	case DMBIS:
729 		addr->dmlstat |= bits;
730 		break;
731 	case DMBIC:
732 		addr->dmlstat &= ~bits;
733 		break;
734 	}
735 	addr->dmcsr = DM_IE|DM_SE;
736 	splx(s);
737 }
738 
739 /*
740  * DM11 interrupt; deal with carrier transitions.
741  */
742 dmintr(dm)
743 	register int dm;
744 {
745 	register struct uba_device *ui;
746 	register struct tty *tp;
747 	register struct dmdevice *addr;
748 
749 	ui = dminfo[dm];
750 	if (ui == 0)
751 		return;
752 	addr = (struct dmdevice *)ui->ui_addr;
753 	if (addr->dmcsr&DM_DONE) {
754 		if (addr->dmcsr&DM_CF) {
755 			tp = &dh11[(dm<<4)+(addr->dmcsr&0xf)];
756 			wakeup((caddr_t)&tp->t_rawq);
757 			if ((tp->t_state&TS_WOPEN)==0 &&
758 			    (tp->t_local&LMDMBUF)) {
759 				if (addr->dmlstat & DML_CAR) {
760 					tp->t_state &= ~TS_TTSTOP;
761 					ttstart(tp);
762 				} else if ((tp->t_state&TS_TTSTOP) == 0) {
763 					tp->t_state |= TS_TTSTOP;
764 					dhstop(tp, 0);
765 				}
766 			} else if ((addr->dmlstat&DML_CAR)==0) {
767 				if ((tp->t_state&TS_WOPEN)==0 &&
768 				    (tp->t_local&LNOHANG)==0) {
769 					gsignal(tp->t_pgrp, SIGHUP);
770 					gsignal(tp->t_pgrp, SIGCONT);
771 					addr->dmlstat = 0;
772 					flushtty(tp, FREAD|FWRITE);
773 				}
774 				tp->t_state &= ~TS_CARR_ON;
775 			} else
776 				tp->t_state |= TS_CARR_ON;
777 		}
778 		addr->dmcsr = DM_IE|DM_SE;
779 	}
780 }
781 #endif
782