xref: /csrg-svn/sys/vax/uba/dh.c (revision 2456)
1*2456Swnj /*	dh.c	4.15	81/02/16	*/
213Sbill 
31934Swnj #include "dh.h"
41561Sbill #if NDH11 > 0
5*2456Swnj #define	DELAY(i)	{ register int j = i; while (--j > 0); }
613Sbill /*
71561Sbill  * DH-11 driver
82421Skre  * DOESNT HANDLE EXTENDED ADDRESS BITS.
913Sbill  */
1013Sbill 
1113Sbill #include "../h/param.h"
1213Sbill #include "../h/conf.h"
1313Sbill #include "../h/dir.h"
1413Sbill #include "../h/user.h"
1513Sbill #include "../h/tty.h"
1613Sbill #include "../h/map.h"
1713Sbill #include "../h/pte.h"
182395Swnj #include "../h/buf.h"
1913Sbill #include "../h/uba.h"
20113Sbill #include "../h/bk.h"
211561Sbill #include "../h/clist.h"
221786Sbill #include "../h/mx.h"
2313Sbill 
24*2456Swnj #define	UBACVT(x,uban) (cbase[uban] + ((x)-(char *)cfree))
25144Sbill 
262395Swnj int	dhcntrlr(), dhslave(), dhrint(), dhxint();
272395Swnj struct	uba_dinfo *dhinfo[NDH11];
282395Swnj u_short	dhstd[] = { 0 };
292395Swnj struct	uba_driver dhdriver =
30*2456Swnj 	{ dhcntrlr, dhslave, 0, 0, dhstd, "dh", dhinfo };
312395Swnj 
322395Swnj struct	tty dh11[NDH11*16];
33117Sbill int	dhact;
342395Swnj int	ndh11	= NDH11*16;
3513Sbill int	dhstart();
3613Sbill int	ttrstrt();
372421Skre int	dh_ubinfo[MAXNUBA];
382421Skre int	cbase[MAXNUBA];
3913Sbill 
4013Sbill /*
4113Sbill  * Hardware control bits
4213Sbill  */
4313Sbill #define	BITS6	01
4413Sbill #define	BITS7	02
4513Sbill #define	BITS8	03
4613Sbill #define	TWOSB	04
4713Sbill #define	PENABLE	020
4813Sbill /* DEC manuals incorrectly say this bit causes generation of even parity. */
4913Sbill #define	OPAR	040
5013Sbill #define	HDUPLX	040000
5113Sbill 
52*2456Swnj /* Bits in dhcsr */
53*2456Swnj #define	DH_TI	0100000		/* transmit interrupt */
54*2456Swnj #define	DH_SI	0040000		/* storage interrupt */
55*2456Swnj #define	DH_TIE	0020000		/* transmit interrupt enable */
56*2456Swnj #define	DH_SIE	0010000		/* storage interrupt enable */
57*2456Swnj #define	DH_MC	0004000		/* master clear */
58*2456Swnj #define	DH_NXM	0002000		/* non-existant memory */
59*2456Swnj #define	DH_MM	0001000		/* maintenance mode */
60*2456Swnj #define	DH_CNI	0000400		/* clear non-existant memory interrupt */
61*2456Swnj #define	DH_RI	0000200		/* receiver interrupt */
62*2456Swnj #define	DH_RIE	0000100		/* receiver interrupt enable */
6313Sbill 
64*2456Swnj #define	DH_IE	(DH_TIE|DH_SIE|DH_RIE)
65*2456Swnj 
66*2456Swnj /* Bits in dhrcr */
67*2456Swnj #define	DH_PE	010000		/* parity error */
68*2456Swnj #define	DH_FE	020000		/* framing error */
69*2456Swnj #define	DH_DO	040000		/* data overrun */
70*2456Swnj 
7113Sbill /*
7213Sbill  * DM control bits
7313Sbill  */
74*2456Swnj #define	DM_ON	03	/* CD lead + line enable */
75*2456Swnj #define	DM_OFF	01	/* line enable */
76*2456Swnj #define	DM_DTR	02	/* data terminal ready */
77*2456Swnj #define	DM_RQS	04	/* request to send */
7813Sbill 
7913Sbill /*
8013Sbill  * Software copy of last dhbar
8113Sbill  */
822395Swnj short	dhsar[NDH11];
8313Sbill 
8413Sbill struct device
8513Sbill {
8613Sbill 	union {
87*2456Swnj 		short	dhcsr;		/* control-status register */
88*2456Swnj 		char	dhcsrl;		/* low byte for line select */
8913Sbill 	} un;
90*2456Swnj 	short	dhrcr;			/* receive character register */
91*2456Swnj 	short	dhlpr;			/* line parameter register */
92*2456Swnj 	u_short dhcar;			/* current address register */
93*2456Swnj 	short	dhbcr;			/* byte count register */
94*2456Swnj 	u_short	dhbar;			/* buffer active register */
95*2456Swnj 	short	dhbreak;		/* break control register */
96*2456Swnj 	short	dhsilo;			/* silo status register */
9713Sbill };
9813Sbill 
99*2456Swnj /*
100*2456Swnj  * Routine for configuration to force a dh to interrupt.
101*2456Swnj  * Set to transmit at 9600 baud, and cause a transmitter interrupt.
102*2456Swnj  */
1032395Swnj dhcntrlr(ui, reg)
1042395Swnj 	struct uba_dinfo *ui;
1052395Swnj 	caddr_t reg;
1062395Swnj {
107*2456Swnj 	register int br, cvec;
108*2456Swnj 	register struct device *dhaddr = (struct device *)reg;
1092421Skre 	int i;
1102395Swnj 
111*2456Swnj 	dhaddr->un.dhcsr = DH_TIE;
112*2456Swnj 	DELAY(5);
113*2456Swnj 	dhaddr->dhlpr = (B9600 << 10) | (B9600 << 6) | BITS7|PENABLE;
1142421Skre 	dhaddr->dhbcr = -1;
115*2456Swnj 	dhaddr->dhcar = 0;
1162421Skre 	dhaddr->dhbar = 1;
117*2456Swnj 	DELAY(100000);		/* wait 1/10'th of a sec for interrupt */
1182421Skre 	dhaddr->un.dhcsr = 0;
119*2456Swnj 	if (cvec && cvec != 0x200)
120*2456Swnj 		cvec -= 4;		/* transmit -> receive */
121*2456Swnj 	return (1);
1222395Swnj }
1232395Swnj 
124*2456Swnj /*
125*2456Swnj  * Routine called to init slave tables.
126*2456Swnj  */
1272395Swnj dhslave(ui, reg, slaveno)
1282395Swnj 	struct uba_dinfo *ui;
1292395Swnj 	caddr_t reg;
1302395Swnj {
1312395Swnj 
132*2456Swnj 	/* no tables to set up */
1332395Swnj }
1342395Swnj 
13513Sbill /*
13613Sbill  * Open a DH11 line.
13713Sbill  */
13813Sbill /*ARGSUSED*/
13913Sbill dhopen(dev, flag)
1402395Swnj 	dev_t dev;
14113Sbill {
14213Sbill 	register struct tty *tp;
1432395Swnj 	register int unit, dh;
14413Sbill 	register struct device *addr;
1452395Swnj 	register struct uba_dinfo *ui;
14613Sbill 	int s;
14713Sbill 
1482395Swnj 	unit = minor(dev);
1492395Swnj 	dh = unit >> 4;
1502395Swnj 	if (unit >= NDH11*16 || (ui = dhinfo[dh])->ui_alive == 0) {
15113Sbill 		u.u_error = ENXIO;
15213Sbill 		return;
15313Sbill 	}
1542395Swnj 	tp = &dh11[unit];
1552395Swnj 	ui = dhinfo[dh];
1562395Swnj 	addr = (struct device *)ui->ui_addr;
15713Sbill 	tp->t_addr = (caddr_t)addr;
15813Sbill 	tp->t_oproc = dhstart;
15913Sbill 	tp->t_iproc = NULL;
16013Sbill 	tp->t_state |= WOPEN;
16113Sbill 	s = spl6();
1622421Skre 	if (dh_ubinfo[ui->ui_ubanum] == 0) {
163717Sbill 		/* 512+ is a kludge to try to get around a hardware problem */
1642395Swnj 		dh_ubinfo[ui->ui_ubanum] =
1652421Skre 		    uballoc(ui->ui_ubanum, (caddr_t)cfree,
1662395Swnj 			512+NCLIST*sizeof(struct cblock), 0);
167*2456Swnj 		cbase[ui->ui_ubanum] = dh_ubinfo[ui->ui_ubanum]&0x3ffff;
16813Sbill 	}
169*2456Swnj 	if ((dhact&(1<<dh)) == 0) {
170*2456Swnj 		addr->un.dhcsr |= DH_IE;
171*2456Swnj 		addr->dhsilo = 16;
172*2456Swnj 		dhact |= (1<<dh);
173*2456Swnj 	}
17413Sbill 	splx(s);
17513Sbill 	if ((tp->t_state&ISOPEN) == 0) {
17613Sbill 		ttychars(tp);
177168Sbill 		if (tp->t_ispeed == 0) {
178*2456Swnj 			tp->t_ispeed = B300;
179*2456Swnj 			tp->t_ospeed = B300;
180168Sbill 			tp->t_flags = ODDP|EVENP|ECHO;
181168Sbill 		}
1822395Swnj 		dhparam(unit);
18313Sbill 	}
18413Sbill 	if (tp->t_state&XCLUDE && u.u_uid!=0) {
18513Sbill 		u.u_error = EBUSY;
18613Sbill 		return;
18713Sbill 	}
18813Sbill 	dmopen(dev);
1892395Swnj 	(*linesw[tp->t_line].l_open)(dev, tp);
19013Sbill }
19113Sbill 
19213Sbill /*
19313Sbill  * Close a DH11 line.
19413Sbill  */
19513Sbill /*ARGSUSED*/
19613Sbill dhclose(dev, flag)
1972395Swnj 	dev_t dev;
1982395Swnj 	int flag;
19913Sbill {
20013Sbill 	register struct tty *tp;
2012395Swnj 	register unit;
20213Sbill 
2032395Swnj 	unit = minor(dev);
2042395Swnj 	tp = &dh11[unit];
20513Sbill 	(*linesw[tp->t_line].l_close)(tp);
2062395Swnj 	((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
20713Sbill 	if (tp->t_state&HUPCLS || (tp->t_state&ISOPEN)==0)
208*2456Swnj 		dmctl(unit, DM_OFF, DMSET);
20913Sbill 	ttyclose(tp);
21013Sbill }
21113Sbill 
21213Sbill /*
21313Sbill  * Read from a DH11 line.
21413Sbill  */
21513Sbill dhread(dev)
2162395Swnj 	dev_t dev;
21713Sbill {
2182395Swnj 	register struct tty *tp;
21913Sbill 
2202395Swnj 	tp = &dh11[minor(dev)];
22113Sbill 	(*linesw[tp->t_line].l_read)(tp);
22213Sbill }
22313Sbill 
22413Sbill /*
22513Sbill  * write on a DH11 line
22613Sbill  */
22713Sbill dhwrite(dev)
2282395Swnj 	dev_t dev;
22913Sbill {
2302395Swnj 	register struct tty *tp;
23113Sbill 
2322395Swnj 	tp = &dh11[minor(dev)];
23313Sbill 	(*linesw[tp->t_line].l_write)(tp);
23413Sbill }
23513Sbill 
23613Sbill /*
23713Sbill  * DH11 receiver interrupt.
23813Sbill  */
2392395Swnj dhrint(dh)
2402395Swnj 	int dh;
24113Sbill {
24213Sbill 	register struct tty *tp;
2432395Swnj 	register c;
24413Sbill 	register struct device *addr;
245117Sbill 	register struct tty *tp0;
2462395Swnj 	register struct uba_dinfo *ui;
247139Sbill 	int s;
24813Sbill 
2492395Swnj 	ui = dhinfo[dh];
250*2456Swnj 	if (ui == 0) {
251*2456Swnj 		printf("stray dhrint %d\n", dh);
252*2456Swnj 		asm("halt");
253*2456Swnj 		return;
254*2456Swnj 	}
2552395Swnj 	addr = (struct device *)ui->ui_addr;
2562395Swnj 	tp0 = &dh11[dh*16];
257*2456Swnj 	while ((c = addr->dhrcr) < 0) {	/* char. present */
258117Sbill 		tp = tp0 + ((c>>8)&017);
2592395Swnj 		if (tp >= &dh11[NDH11*16])
26013Sbill 			continue;
26113Sbill 		if((tp->t_state&ISOPEN)==0) {
26213Sbill 			wakeup((caddr_t)tp);
26313Sbill 			continue;
26413Sbill 		}
265*2456Swnj 		if (c&DH_PE)
26613Sbill 			if ((tp->t_flags&(EVENP|ODDP))==EVENP
26713Sbill 			 || (tp->t_flags&(EVENP|ODDP))==ODDP )
26813Sbill 				continue;
269*2456Swnj 		if (c&DH_DO)
27013Sbill 			printf("O");
271*2456Swnj 		if (c&DH_FE)		/* break */
27213Sbill 			if (tp->t_flags&RAW)
27313Sbill 				c = 0;	/* null (for getty) */
27413Sbill 			else
275184Sbill 				c = tun.t_intrc;
276139Sbill 		if (tp->t_line == NETLDISC) {
277117Sbill 			c &= 0177;
278168Sbill 			BKINPUT(c, tp);
279117Sbill 		} else
280117Sbill 			(*linesw[tp->t_line].l_rint)(c,tp);
28113Sbill 	}
28213Sbill }
28313Sbill 
28413Sbill /*
28513Sbill  * stty/gtty for DH11
28613Sbill  */
28713Sbill /*ARGSUSED*/
28813Sbill dhioctl(dev, cmd, addr, flag)
2892395Swnj 	caddr_t addr;
29013Sbill {
29113Sbill 	register struct tty *tp;
2922395Swnj 	register unit = minor(dev);
29313Sbill 
2942395Swnj 	tp = &dh11[unit];
295113Sbill 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
296113Sbill 	if (cmd==0)
297113Sbill 		return;
2981895Swnj 	if (ttioctl(tp, cmd, addr, flag)) {
29913Sbill 		if (cmd==TIOCSETP||cmd==TIOCSETN)
3002395Swnj 			dhparam(unit);
301168Sbill 	} else switch(cmd) {
302168Sbill 	case TIOCSBRK:
3032395Swnj 		((struct device *)(tp->t_addr))->dhbreak |= 1<<(unit&017);
304168Sbill 		break;
305168Sbill 	case TIOCCBRK:
3062395Swnj 		((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
307168Sbill 		break;
308168Sbill 	case TIOCSDTR:
309*2456Swnj 		dmctl(unit, DM_DTR|DM_RQS, DMBIS);
310168Sbill 		break;
311168Sbill 	case TIOCCDTR:
312*2456Swnj 		dmctl(unit, DM_DTR|DM_RQS, DMBIC);
313168Sbill 		break;
314168Sbill 	default:
31513Sbill 		u.u_error = ENOTTY;
316168Sbill 	}
31713Sbill }
31813Sbill 
31913Sbill /*
32013Sbill  * Set parameters from open or stty into the DH hardware
32113Sbill  * registers.
32213Sbill  */
3232395Swnj dhparam(unit)
3242395Swnj 	register int unit;
32513Sbill {
32613Sbill 	register struct tty *tp;
32713Sbill 	register struct device *addr;
3282395Swnj 	register int lpar;
329300Sbill 	int s;
33013Sbill 
3312395Swnj 	tp = &dh11[unit];
33213Sbill 	addr = (struct device *)tp->t_addr;
333300Sbill 	s = spl5();
334*2456Swnj 	addr->un.dhcsrl = (unit&017) | DH_IE;
33513Sbill 	if ((tp->t_ispeed)==0) {
33613Sbill 		tp->t_state |= HUPCLS;
337*2456Swnj 		dmctl(unit, DM_OFF, DMSET);
33813Sbill 		return;
33913Sbill 	}
3402395Swnj 	lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
34113Sbill 	if ((tp->t_ispeed) == 4)		/* 134.5 baud */
3422395Swnj 		lpar |= BITS6|PENABLE|HDUPLX;
3432312Skre 	else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
3442395Swnj 		lpar |= BITS8;
34513Sbill 	else
3462395Swnj 		lpar |= BITS7|PENABLE;
34713Sbill 	if ((tp->t_flags&EVENP) == 0)
3482395Swnj 		lpar |= OPAR;
34913Sbill 	if ((tp->t_ospeed) == 3)	/* 110 baud */
3502395Swnj 		lpar |= TWOSB;
3512395Swnj 	addr->dhlpr = lpar;
352300Sbill 	splx(s);
35313Sbill }
35413Sbill 
35513Sbill /*
35613Sbill  * DH11 transmitter interrupt.
35713Sbill  * Restart each line which used to be active but has
35813Sbill  * terminated transmission since the last interrupt.
35913Sbill  */
3602395Swnj dhxint(dh)
3612395Swnj 	int dh;
36213Sbill {
36313Sbill 	register struct tty *tp;
36413Sbill 	register struct device *addr;
36513Sbill 	short ttybit, bar, *sbar;
3662395Swnj 	register struct uba_dinfo *ui;
3672395Swnj 	register unit;
368144Sbill 	int s;
36913Sbill 
3702395Swnj 	ui = dhinfo[dh];
3712395Swnj 	addr = (struct device *)ui->ui_addr;
372*2456Swnj 	if (addr->un.dhcsr & DH_NXM) {
373*2456Swnj 		addr->un.dhcsr |= DH_CNI;
374*2456Swnj 		printf("dh%d NXM\n", ui->ui_ctlr);
375105Sbill 	}
376*2456Swnj 	addr->un.dhcsr &= (short)~DH_TI;
3772395Swnj 	sbar = &dhsar[dh];
37813Sbill 	bar = *sbar & ~addr->dhbar;
3792395Swnj 	unit = dh * 16; ttybit = 1;
3802395Swnj 	for(; bar; unit++, ttybit <<= 1) {
38113Sbill 		if(bar&ttybit) {
38213Sbill 			*sbar &= ~ttybit;
38313Sbill 			bar &= ~ttybit;
3842395Swnj 			tp = &dh11[unit];
385113Sbill 			tp->t_state &= ~BUSY;
386113Sbill 			if (tp->t_state&FLUSH)
387113Sbill 				tp->t_state &= ~FLUSH;
388113Sbill 			else {
389*2456Swnj 				addr->un.dhcsrl = (unit&017)|DH_IE;
390219Sbill 				ndflush(&tp->t_outq,
391*2456Swnj 				    /* SHOULD PASTE ON 16&17 BITS HERE */
392*2456Swnj 				    addr->dhcar-
3932395Swnj 					UBACVT(tp->t_outq.c_cf,ui->ui_ubanum));
394113Sbill 			}
395113Sbill 			if (tp->t_line)
39613Sbill 				(*linesw[tp->t_line].l_start)(tp);
397113Sbill 			else
39813Sbill 				dhstart(tp);
39913Sbill 		}
40013Sbill 	}
40113Sbill }
40213Sbill 
40313Sbill /*
40413Sbill  * Start (restart) transmission on the given DH11 line.
40513Sbill  */
40613Sbill dhstart(tp)
4072395Swnj 	register struct tty *tp;
40813Sbill {
40913Sbill 	register struct device *addr;
4102395Swnj 	register int nch, dh, unit;
4112395Swnj 	int s;
41213Sbill 
41313Sbill 	/*
41413Sbill 	 * If it's currently active, or delaying,
41513Sbill 	 * no need to do anything.
41613Sbill 	 */
41713Sbill 	s = spl5();
4182395Swnj 	unit = minor(tp->t_dev);
4192395Swnj 	dh = unit >> 4;
42013Sbill 	addr = (struct device *)tp->t_addr;
42113Sbill 	if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))
42213Sbill 		goto out;
4232395Swnj 	if ((tp->t_state&ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) {
42413Sbill 		tp->t_state &= ~ASLEEP;
42513Sbill 		if (tp->t_chan)
426168Sbill 			mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
427168Sbill 		else
42813Sbill 			wakeup((caddr_t)&tp->t_outq);
42913Sbill 	}
43013Sbill 	if (tp->t_outq.c_cc == 0)
43113Sbill 		goto out;
4322395Swnj 	if (tp->t_flags & RAW)
43313Sbill 		nch = ndqb(&tp->t_outq, 0);
4342395Swnj 	else {
43513Sbill 		nch = ndqb(&tp->t_outq, 0200);
43613Sbill 		if (nch == 0) {
43713Sbill 			nch = getc(&tp->t_outq);
43813Sbill 			timeout(ttrstrt, (caddr_t)tp, (nch&0177)+6);
43913Sbill 			tp->t_state |= TIMEOUT;
44013Sbill 			goto out;
44113Sbill 		}
44213Sbill 	}
44313Sbill 	if (nch) {
444*2456Swnj 		/* SHOULD PASTE ON BITS 16&17 HERE */
445*2456Swnj 		addr->un.dhcsrl = (unit&017)|DH_IE;
4462395Swnj 		addr->dhcar = UBACVT(tp->t_outq.c_cf,
4472395Swnj 		    dhinfo[dh]->ui_ubanum);
44813Sbill 		addr->dhbcr = -nch;
4492395Swnj 		nch = 1<<(unit&017);
45013Sbill 		addr->dhbar |= nch;
4512395Swnj 		dhsar[dh] |= nch;
45213Sbill 		tp->t_state |= BUSY;
45313Sbill 	}
4542395Swnj out:
45513Sbill 	splx(s);
45613Sbill }
45713Sbill 
45813Sbill /*
45913Sbill  * Stop output on a line.
46013Sbill  */
46113Sbill /*ARGSUSED*/
46213Sbill dhstop(tp, flag)
46313Sbill register struct tty *tp;
46413Sbill {
465113Sbill 	register struct device *addr;
4662395Swnj 	register int unit, s;
46713Sbill 
468113Sbill 	addr = (struct device *)tp->t_addr;
46913Sbill 	s = spl6();
470113Sbill 	if (tp->t_state & BUSY) {
4712395Swnj 		unit = minor(tp->t_dev);
472*2456Swnj 		addr->un.dhcsrl = (unit&017) | DH_IE;
47313Sbill 		if ((tp->t_state&TTSTOP)==0)
47413Sbill 			tp->t_state |= FLUSH;
475113Sbill 		addr->dhbcr = -1;
476113Sbill 	}
47713Sbill 	splx(s);
47813Sbill }
47913Sbill 
480168Sbill /*
481280Sbill  * Reset state of driver if UBA reset was necessary.
482280Sbill  * Reset the csrl and lpr registers on open lines, and
483280Sbill  * restart transmitters.
484280Sbill  */
4852395Swnj dhreset(uban)
486280Sbill {
4872395Swnj 	register int dh, unit;
488280Sbill 	register struct tty *tp;
4892395Swnj 	register struct uba_dinfo *ui;
4902421Skre 	int i;
491280Sbill 
4922421Skre 	if (dh_ubinfo[uban] == 0)
4932421Skre 		return;
494280Sbill 	printf(" dh");
4952421Skre 	ubarelse(uban, &dh_ubinfo[uban]);
4962421Skre 	dh_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
4972421Skre 	    512+NCLIST*sizeof (struct cblock), 0);
4982421Skre 	cbase[uban] = dh_ubinfo[uban]&0x3ffff;
4992395Swnj 	dh = 0;
5002421Skre 	for (dh = 0; dh < NDH11; dh++) {
5012421Skre 		ui = dhinfo[dh];
5022421Skre 		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
5032421Skre 			continue;
504*2456Swnj 		((struct device *)ui->ui_addr)->un.dhcsr |= DH_IE;
505*2456Swnj 		((struct device *)ui->ui_addr)->dhsilo = 16;
5062421Skre 		unit = dh * 16;
5072421Skre 		for (i = 0; i < 16; i++) {
5082421Skre 			tp = &dh11[unit];
5092421Skre 			if (tp->t_state & (ISOPEN|WOPEN)) {
5102421Skre 				dhparam(unit);
511*2456Swnj 				dmctl(unit, DM_ON, DMSET);
5122421Skre 				tp->t_state &= ~BUSY;
5132421Skre 				dhstart(tp);
5142421Skre 			}
5152421Skre 			unit++;
516300Sbill 		}
517300Sbill 	}
518300Sbill 	dhtimer();
519280Sbill }
5202395Swnj 
521*2456Swnj dhtimer()
522*2456Swnj {
523*2456Swnj 	register int dh;
524*2456Swnj 
525*2456Swnj 	for (dh = 0; dh < NDH11; dh++)
526*2456Swnj 		dhrint(dh);
527*2456Swnj }
528*2456Swnj 
5292395Swnj #if DHDM
5301944Swnj #include "../dev/dhdm.c"
5311944Swnj #else
5321944Swnj #include "../dev/dhfdm.c"
5331808Sbill #endif
5341944Swnj #endif
535