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