xref: /csrg-svn/sys/vax/uba/dh.c (revision 2395)
1*2395Swnj /*	dh.c	4.13	81/02/10	*/
213Sbill 
31934Swnj #include "dh.h"
41561Sbill #if NDH11 > 0
513Sbill /*
61561Sbill  * DH-11 driver
71561Sbill  *
81561Sbill  * Loaded with dhdm if there are DM-11's otherwise with dhfdm.
91561Sbill  *
101561Sbill  * NB: WE HAVEN'T TESTED dhdm CODE ON VAX.
1113Sbill  */
1213Sbill 
1313Sbill #include "../h/param.h"
1413Sbill #include "../h/conf.h"
1513Sbill #include "../h/dir.h"
1613Sbill #include "../h/user.h"
1713Sbill #include "../h/tty.h"
1813Sbill #include "../h/map.h"
1913Sbill #include "../h/pte.h"
20*2395Swnj #include "../h/buf.h"
2113Sbill #include "../h/uba.h"
22113Sbill #include "../h/bk.h"
231561Sbill #include "../h/clist.h"
241786Sbill #include "../h/mx.h"
2513Sbill 
26*2395Swnj /* This is to block the clock because we are using the silos */
27*2395Swnj /* SHOULD RATHER QUEUE SOFTWARE INTERRUPT AT CLOCK TIME */
28144Sbill #define	spl5	spl6
29144Sbill 
30*2395Swnj #define	UBACVT(x,uban) (cbase[uban] + (short)((x)-(char *)cfree))
3113Sbill 
32*2395Swnj int	dhcntrlr(), dhslave(), dhrint(), dhxint();
33*2395Swnj struct	uba_dinfo *dhinfo[NDH11];
34*2395Swnj u_short	dhstd[] = { 0 };
35*2395Swnj int	(*dhivec[])() = { dhrint, dhxint, 0 };	/* note: order matters */
36*2395Swnj struct	uba_driver dhdriver =
37*2395Swnj 	{ dhcntrlr, dhslave, (int (*)())0, 0, 0, dhstd, dhinfo, dhivec };
38*2395Swnj 
39*2395Swnj struct	tty dh11[NDH11*16];
40117Sbill int	dhact;
41280Sbill int	dhisilo;
42*2395Swnj int	ndh11	= NDH11*16;
4313Sbill int	dhstart();
4413Sbill int	ttrstrt();
45*2395Swnj int	dh_ubinfo[4];
46*2395Swnj int	cbase[4];
4713Sbill 
4813Sbill /*
4913Sbill  * Hardware control bits
5013Sbill  */
5113Sbill #define	BITS6	01
5213Sbill #define	BITS7	02
5313Sbill #define	BITS8	03
5413Sbill #define	TWOSB	04
5513Sbill #define	PENABLE	020
5613Sbill /* DEC manuals incorrectly say this bit causes generation of even parity. */
5713Sbill #define	OPAR	040
5813Sbill #define	HDUPLX	040000
5913Sbill 
6013Sbill #define	IENAB	030100
61105Sbill #define	NXM	02000
62105Sbill #define	CLRNXM	0400
6313Sbill #define	PERROR	010000
6413Sbill #define	FRERROR	020000
6513Sbill #define	OVERRUN	040000
6613Sbill #define	XINT	0100000
6713Sbill #define	SSPEED	7	/* standard speed: 300 baud */
6813Sbill 
6913Sbill /*
7013Sbill  * DM control bits
7113Sbill  */
7213Sbill #define	TURNON	03	/* CD lead + line enable */
7313Sbill #define	TURNOFF	01	/* line enable */
74168Sbill #define	DTR	02	/* data terminal ready */
7513Sbill #define	RQS	04	/* request to send */
7613Sbill 
7713Sbill /*
7813Sbill  * Software copy of last dhbar
7913Sbill  */
80*2395Swnj short	dhsar[NDH11];
8113Sbill 
8213Sbill struct device
8313Sbill {
8413Sbill 	union {
8513Sbill 		short	dhcsr;
8613Sbill 		char	dhcsrl;
8713Sbill 	} un;
8813Sbill 	short	dhnxch;
8913Sbill 	short	dhlpr;
9013Sbill 	unsigned short	dhcar;
9113Sbill 	short	dhbcr;
9213Sbill 	unsigned short	dhbar;
9313Sbill 	short	dhbreak;
9413Sbill 	short	dhsilo;
9513Sbill };
9613Sbill 
97*2395Swnj dhcntrlr(ui, reg)
98*2395Swnj 	struct uba_dinfo *ui;
99*2395Swnj 	caddr_t reg;
100*2395Swnj {
101*2395Swnj 
102*2395Swnj 	((struct device *)reg)->un.dhcsr |= IENABLE;
103*2395Swnj 	/* get it to interrupt */
104*2395Swnj }
105*2395Swnj 
106*2395Swnj dhslave(ui, reg, slaveno)
107*2395Swnj 	struct uba_dinfo *ui;
108*2395Swnj 	caddr_t reg;
109*2395Swnj {
110*2395Swnj 
111*2395Swnj 	/* could fill in local tables for the dh here */
112*2395Swnj }
113*2395Swnj 
11413Sbill /*
11513Sbill  * Open a DH11 line.
11613Sbill  */
11713Sbill /*ARGSUSED*/
11813Sbill dhopen(dev, flag)
119*2395Swnj 	dev_t dev;
12013Sbill {
12113Sbill 	register struct tty *tp;
122*2395Swnj 	register int unit, dh;
12313Sbill 	register struct device *addr;
124*2395Swnj 	register struct uba_dinfo *ui;
12513Sbill 	int s;
12613Sbill 
127*2395Swnj 	unit = minor(dev);
128*2395Swnj 	dh = unit >> 4;
129*2395Swnj 	if (unit >= NDH11*16 || (ui = dhinfo[dh])->ui_alive == 0) {
13013Sbill 		u.u_error = ENXIO;
13113Sbill 		return;
13213Sbill 	}
133*2395Swnj 	tp = &dh11[unit];
134*2395Swnj 	ui = dhinfo[dh];
135*2395Swnj 	addr = (struct device *)ui->ui_addr;
13613Sbill 	tp->t_addr = (caddr_t)addr;
13713Sbill 	tp->t_oproc = dhstart;
13813Sbill 	tp->t_iproc = NULL;
13913Sbill 	tp->t_state |= WOPEN;
14013Sbill 	s = spl6();
141*2395Swnj 	if (dh_ubinfo[ui->ui_ubanum]) {
142717Sbill 		/* 512+ is a kludge to try to get around a hardware problem */
143*2395Swnj 		dh_ubinfo[ui->ui_ubanum] =
144*2395Swnj 		    uballoc((caddr_t)cfree,
145*2395Swnj 			512+NCLIST*sizeof(struct cblock), 0);
146*2395Swnj 		cbase[ui->ui_ubanum] = (short)dh_ubinfo[ui->ui_ubanum];
14713Sbill 	}
14813Sbill 	splx(s);
14913Sbill 	addr->un.dhcsr |= IENAB;
150*2395Swnj 	dhact |= (1<<dh);
15113Sbill 	if ((tp->t_state&ISOPEN) == 0) {
15213Sbill 		ttychars(tp);
153168Sbill 		if (tp->t_ispeed == 0) {
154168Sbill 			tp->t_ispeed = SSPEED;
155168Sbill 			tp->t_ospeed = SSPEED;
156168Sbill 			tp->t_flags = ODDP|EVENP|ECHO;
157168Sbill 		}
158*2395Swnj 		dhparam(unit);
15913Sbill 	}
16013Sbill 	if (tp->t_state&XCLUDE && u.u_uid!=0) {
16113Sbill 		u.u_error = EBUSY;
16213Sbill 		return;
16313Sbill 	}
16413Sbill 	dmopen(dev);
165*2395Swnj 	(*linesw[tp->t_line].l_open)(dev, tp);
16613Sbill }
16713Sbill 
16813Sbill /*
16913Sbill  * Close a DH11 line.
17013Sbill  */
17113Sbill /*ARGSUSED*/
17213Sbill dhclose(dev, flag)
173*2395Swnj 	dev_t dev;
174*2395Swnj 	int flag;
17513Sbill {
17613Sbill 	register struct tty *tp;
177*2395Swnj 	register unit;
17813Sbill 
179*2395Swnj 	unit = minor(dev);
180*2395Swnj 	tp = &dh11[unit];
18113Sbill 	(*linesw[tp->t_line].l_close)(tp);
1822196Stoy 	/*
1832196Stoy 	 * Turn of the break bit in case somebody did a TIOCSBRK without
1842196Stoy 	 * a TIOCCBRK.
1852196Stoy 	 */
186*2395Swnj 	((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
18713Sbill 	if (tp->t_state&HUPCLS || (tp->t_state&ISOPEN)==0)
188*2395Swnj 		dmctl(unit, TURNOFF, DMSET);
18913Sbill 	ttyclose(tp);
19013Sbill }
19113Sbill 
19213Sbill /*
19313Sbill  * Read from a DH11 line.
19413Sbill  */
19513Sbill dhread(dev)
196*2395Swnj 	dev_t dev;
19713Sbill {
198*2395Swnj 	register struct tty *tp;
19913Sbill 
200*2395Swnj 	tp = &dh11[minor(dev)];
20113Sbill 	(*linesw[tp->t_line].l_read)(tp);
20213Sbill }
20313Sbill 
20413Sbill /*
20513Sbill  * write on a DH11 line
20613Sbill  */
20713Sbill dhwrite(dev)
208*2395Swnj 	dev_t dev;
20913Sbill {
210*2395Swnj 	register struct tty *tp;
21113Sbill 
212*2395Swnj 	tp = &dh11[minor(dev)];
21313Sbill 	(*linesw[tp->t_line].l_write)(tp);
21413Sbill }
21513Sbill 
21613Sbill /*
21713Sbill  * DH11 receiver interrupt.
21813Sbill  */
219*2395Swnj dhrint(dh)
220*2395Swnj 	int dh;
22113Sbill {
22213Sbill 	register struct tty *tp;
223*2395Swnj 	register c;
22413Sbill 	register struct device *addr;
225117Sbill 	register struct tty *tp0;
226*2395Swnj 	register struct uba_dinfo *ui;
227139Sbill 	int s;
22813Sbill 
229139Sbill 	s = spl6();	/* see comment in clock.c */
230*2395Swnj 	ui = dhinfo[dh];
231*2395Swnj 	addr = (struct device *)ui->ui_addr;
232*2395Swnj 	tp0 = &dh11[dh*16];
23313Sbill 	while ((c = addr->dhnxch) < 0) {	/* char. present */
234117Sbill 		tp = tp0 + ((c>>8)&017);
235*2395Swnj 		if (tp >= &dh11[NDH11*16])
23613Sbill 			continue;
23713Sbill 		if((tp->t_state&ISOPEN)==0) {
23813Sbill 			wakeup((caddr_t)tp);
23913Sbill 			continue;
24013Sbill 		}
24113Sbill 		if (c&PERROR)
24213Sbill 			if ((tp->t_flags&(EVENP|ODDP))==EVENP
24313Sbill 			 || (tp->t_flags&(EVENP|ODDP))==ODDP )
24413Sbill 				continue;
24513Sbill 		if (c&OVERRUN)
24613Sbill 			printf("O");
24713Sbill 		if (c&FRERROR)		/* break */
24813Sbill 			if (tp->t_flags&RAW)
24913Sbill 				c = 0;	/* null (for getty) */
25013Sbill 			else
251168Sbill #ifdef IIASA
252168Sbill 				continue;
253168Sbill #else
254184Sbill 				c = tun.t_intrc;
255168Sbill #endif
256139Sbill 		if (tp->t_line == NETLDISC) {
257117Sbill 			c &= 0177;
258168Sbill 			BKINPUT(c, tp);
259117Sbill 		} else
260117Sbill 			(*linesw[tp->t_line].l_rint)(c,tp);
26113Sbill 	}
262139Sbill 	splx(s);
26313Sbill }
26413Sbill 
26513Sbill /*
26613Sbill  * stty/gtty for DH11
26713Sbill  */
26813Sbill /*ARGSUSED*/
26913Sbill dhioctl(dev, cmd, addr, flag)
270*2395Swnj 	caddr_t addr;
27113Sbill {
27213Sbill 	register struct tty *tp;
273*2395Swnj 	register unit = minor(dev);
27413Sbill 
275*2395Swnj 	tp = &dh11[unit];
276113Sbill 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
277113Sbill 	if (cmd==0)
278113Sbill 		return;
2791895Swnj 	if (ttioctl(tp, cmd, addr, flag)) {
28013Sbill 		if (cmd==TIOCSETP||cmd==TIOCSETN)
281*2395Swnj 			dhparam(unit);
282168Sbill 	} else switch(cmd) {
283168Sbill 	case TIOCSBRK:
284*2395Swnj 		((struct device *)(tp->t_addr))->dhbreak |= 1<<(unit&017);
285168Sbill 		break;
286168Sbill 	case TIOCCBRK:
287*2395Swnj 		((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
288168Sbill 		break;
289168Sbill 	case TIOCSDTR:
290*2395Swnj 		dmctl(unit, DTR|RQS, DMBIS);
291168Sbill 		break;
292168Sbill 	case TIOCCDTR:
293*2395Swnj 		dmctl(unit, DTR|RQS, DMBIC);
294168Sbill 		break;
295168Sbill 	default:
29613Sbill 		u.u_error = ENOTTY;
297168Sbill 	}
29813Sbill }
29913Sbill 
30013Sbill /*
30113Sbill  * Set parameters from open or stty into the DH hardware
30213Sbill  * registers.
30313Sbill  */
304*2395Swnj dhparam(unit)
305*2395Swnj 	register int unit;
30613Sbill {
30713Sbill 	register struct tty *tp;
30813Sbill 	register struct device *addr;
309*2395Swnj 	register int lpar;
310300Sbill 	int s;
31113Sbill 
312*2395Swnj 	tp = &dh11[unit];
31313Sbill 	addr = (struct device *)tp->t_addr;
314300Sbill 	s = spl5();
315*2395Swnj 	addr->un.dhcsrl = (unit&017) | IENAB;
31613Sbill 	/*
31713Sbill 	 * Hang up line?
31813Sbill 	 */
31913Sbill 	if ((tp->t_ispeed)==0) {
32013Sbill 		tp->t_state |= HUPCLS;
321*2395Swnj 		dmctl(unit, TURNOFF, DMSET);
32213Sbill 		return;
32313Sbill 	}
324*2395Swnj 	lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
32513Sbill 	if ((tp->t_ispeed) == 4)		/* 134.5 baud */
326*2395Swnj 		lpar |= BITS6|PENABLE|HDUPLX;
3272312Skre 	else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
328*2395Swnj 		lpar |= BITS8;
32913Sbill 	else
330*2395Swnj 		lpar |= BITS7|PENABLE;
33113Sbill 	if ((tp->t_flags&EVENP) == 0)
332*2395Swnj 		lpar |= OPAR;
33313Sbill 	if ((tp->t_ospeed) == 3)	/* 110 baud */
334*2395Swnj 		lpar |= TWOSB;
335*2395Swnj 	addr->dhlpr = lpar;
336300Sbill 	splx(s);
33713Sbill }
33813Sbill 
33913Sbill /*
34013Sbill  * DH11 transmitter interrupt.
34113Sbill  * Restart each line which used to be active but has
34213Sbill  * terminated transmission since the last interrupt.
34313Sbill  */
344*2395Swnj dhxint(dh)
345*2395Swnj 	int dh;
34613Sbill {
34713Sbill 	register struct tty *tp;
34813Sbill 	register struct device *addr;
34913Sbill 	short ttybit, bar, *sbar;
350*2395Swnj 	register struct uba_dinfo *ui;
351*2395Swnj 	register unit;
352144Sbill 	int s;
35313Sbill 
354144Sbill 	s = spl6();	/* block the clock */
355*2395Swnj 	ui = dhinfo[dh];
356*2395Swnj 	addr = (struct device *)ui->ui_addr;
35713Sbill 	addr->un.dhcsr &= (short)~XINT;
358105Sbill 	if (addr->un.dhcsr & NXM) {
359105Sbill 		addr->un.dhcsr |= CLRNXM;
360105Sbill 		printf("dh clr NXM\n");
361105Sbill 	}
362*2395Swnj 	sbar = &dhsar[dh];
36313Sbill 	bar = *sbar & ~addr->dhbar;
364*2395Swnj 	unit = dh * 16; ttybit = 1;
365*2395Swnj 	for(; bar; unit++, ttybit <<= 1) {
36613Sbill 		if(bar&ttybit) {
36713Sbill 			*sbar &= ~ttybit;
36813Sbill 			bar &= ~ttybit;
369*2395Swnj 			tp = &dh11[unit];
370113Sbill 			tp->t_state &= ~BUSY;
371113Sbill 			if (tp->t_state&FLUSH)
372113Sbill 				tp->t_state &= ~FLUSH;
373113Sbill 			else {
374*2395Swnj 				addr->un.dhcsrl = (unit&017)|IENAB;
375219Sbill 				ndflush(&tp->t_outq,
376*2395Swnj 				    (int)(short)addr->dhcar-
377*2395Swnj 					UBACVT(tp->t_outq.c_cf,ui->ui_ubanum));
378113Sbill 			}
379113Sbill 			if (tp->t_line)
38013Sbill 				(*linesw[tp->t_line].l_start)(tp);
381113Sbill 			else
38213Sbill 				dhstart(tp);
38313Sbill 		}
38413Sbill 	}
385144Sbill 	splx(s);
38613Sbill }
38713Sbill 
38813Sbill /*
38913Sbill  * Start (restart) transmission on the given DH11 line.
39013Sbill  */
39113Sbill dhstart(tp)
392*2395Swnj 	register struct tty *tp;
39313Sbill {
39413Sbill 	register struct device *addr;
395*2395Swnj 	register int nch, dh, unit;
396*2395Swnj 	int s;
39713Sbill 
39813Sbill 	/*
39913Sbill 	 * If it's currently active, or delaying,
40013Sbill 	 * no need to do anything.
40113Sbill 	 */
40213Sbill 	s = spl5();
403*2395Swnj 	unit = minor(tp->t_dev);
404*2395Swnj 	dh = unit >> 4;
40513Sbill 	addr = (struct device *)tp->t_addr;
40613Sbill 	if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))
40713Sbill 		goto out;
408*2395Swnj 	if ((tp->t_state&ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) {
40913Sbill 		tp->t_state &= ~ASLEEP;
41013Sbill 		if (tp->t_chan)
411168Sbill 			mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
412168Sbill 		else
41313Sbill 			wakeup((caddr_t)&tp->t_outq);
41413Sbill 	}
41513Sbill 	if (tp->t_outq.c_cc == 0)
41613Sbill 		goto out;
417*2395Swnj 	if (tp->t_flags & RAW)
41813Sbill 		nch = ndqb(&tp->t_outq, 0);
419*2395Swnj 	else {
42013Sbill 		nch = ndqb(&tp->t_outq, 0200);
42113Sbill 		if (nch == 0) {
42213Sbill 			nch = getc(&tp->t_outq);
42313Sbill 			timeout(ttrstrt, (caddr_t)tp, (nch&0177)+6);
42413Sbill 			tp->t_state |= TIMEOUT;
42513Sbill 			goto out;
42613Sbill 		}
42713Sbill 	}
42813Sbill 	if (nch) {
429*2395Swnj 		addr->un.dhcsrl = (unit&017)|IENAB;
430*2395Swnj 		addr->dhcar = UBACVT(tp->t_outq.c_cf,
431*2395Swnj 		    dhinfo[dh]->ui_ubanum);
43213Sbill 		addr->dhbcr = -nch;
433*2395Swnj 		nch = 1<<(unit&017);
43413Sbill 		addr->dhbar |= nch;
435*2395Swnj 		dhsar[dh] |= nch;
43613Sbill 		tp->t_state |= BUSY;
43713Sbill 	}
438*2395Swnj out:
43913Sbill 	splx(s);
44013Sbill }
44113Sbill 
44213Sbill /*
44313Sbill  * Stop output on a line.
44413Sbill  * Assume call is made at spl6.
44513Sbill  */
44613Sbill /*ARGSUSED*/
44713Sbill dhstop(tp, flag)
44813Sbill register struct tty *tp;
44913Sbill {
450113Sbill 	register struct device *addr;
451*2395Swnj 	register int unit, s;
45213Sbill 
453113Sbill 	addr = (struct device *)tp->t_addr;
45413Sbill 	s = spl6();
455113Sbill 	if (tp->t_state & BUSY) {
456*2395Swnj 		unit = minor(tp->t_dev);
457*2395Swnj 		addr->un.dhcsrl = (unit&017) | IENAB;
45813Sbill 		if ((tp->t_state&TTSTOP)==0)
45913Sbill 			tp->t_state |= FLUSH;
460113Sbill 		addr->dhbcr = -1;
461113Sbill 	}
46213Sbill 	splx(s);
46313Sbill }
46413Sbill 
465117Sbill int	dhsilo = 16;
466168Sbill /*
467168Sbill  * Silo control is fixed strategy
468168Sbill  * here, paralleling only option available
469168Sbill  * on DZ-11.
470168Sbill  */
47113Sbill /*ARGSUSED*/
472168Sbill dhtimer()
47313Sbill {
474*2395Swnj 	register int dh;
475117Sbill 	register struct device *addr;
476*2395Swnj 	register struct uba_dinfo *ui;
477117Sbill 
478*2395Swnj 	dh = 0;
47913Sbill 	do {
480*2395Swnj 		ui = dhinfo[dh];
481*2395Swnj 		addr = (struct device *)ui->ui_addr;
482*2395Swnj 		if (dhact & (1<<dh)) {
483*2395Swnj 			if ((dhisilo & (1<<dh)) == 0) {
484280Sbill 				addr->dhsilo = dhsilo;
485*2395Swnj 				dhisilo |= 1<<dh;
486280Sbill 			}
487*2395Swnj 			dhrint(dh);
488117Sbill 		}
489*2395Swnj 		dh++;
490*2395Swnj 	} while (dh < NDH11);
49113Sbill }
492280Sbill 
493280Sbill /*
494280Sbill  * Reset state of driver if UBA reset was necessary.
495280Sbill  * Reset the csrl and lpr registers on open lines, and
496280Sbill  * restart transmitters.
497280Sbill  */
498*2395Swnj dhreset(uban)
499280Sbill {
500*2395Swnj 	register int dh, unit;
501280Sbill 	register struct tty *tp;
502280Sbill 	register struct device *addr;
503*2395Swnj 	register struct uba_dinfo *ui;
504*2395Swnj 	int uba;
505280Sbill 
506*2395Swnj 	/*** WE SHOULD LOOK TO SEE IF UBA BEING RESET IS INTERESTING ***/
507*2395Swnj 
508280Sbill 	printf(" dh");
509280Sbill 	dhisilo = 0;
510*2395Swnj 	for (uba = 0; uba < numuba; uba++)
511*2395Swnj 		if (dh_ubinfo[uba]) {
512*2395Swnj 			ubarelse(uba, &dh_ubinfo[uba]);
513*2395Swnj 			dh_ubinfo[uba] = uballoc(uba, (caddr_t)cfree,
514*2395Swnj 			    512+NCLIST*sizeof (struct cblock), 0);
515*2395Swnj 			cbase[uba] = (short)dh_ubinfo;
516*2395Swnj 		}
517*2395Swnj 	dh = 0;
518280Sbill 	do {
519*2395Swnj 		if (dhact & (1<<dh))
520*2395Swnj 			((struct device *)dhinfo[dh]->ui_addr)->un.dhcsr |=
521*2395Swnj 			    IENAB;
522*2395Swnj 		dh++;
523*2395Swnj 	} while (dh < NDH11);
524*2395Swnj 	for (unit = 0; unit < NDH11*16; unit++) {
525*2395Swnj 		tp = &dh11[unit];
526300Sbill 		if (tp->t_state & (ISOPEN|WOPEN)) {
527*2395Swnj 			dhparam(unit);
528*2395Swnj 			dmctl(unit, TURNON, DMSET);
529300Sbill 			tp->t_state &= ~BUSY;
530300Sbill 			dhstart(tp);
531300Sbill 		}
532300Sbill 	}
533300Sbill 	dhtimer();
534280Sbill }
535*2395Swnj 
536*2395Swnj #if DHDM
5371944Swnj #include "../dev/dhdm.c"
5381944Swnj #else
5391944Swnj #include "../dev/dhfdm.c"
5401808Sbill #endif
5411944Swnj #endif
542