xref: /csrg-svn/sys/vax/uba/dh.c (revision 2421)
1*2421Skre /*	dh.c	4.14	81/02/15	*/
213Sbill 
31934Swnj #include "dh.h"
41561Sbill #if NDH11 > 0
513Sbill /*
61561Sbill  * DH-11 driver
71561Sbill  *
8*2421Skre  * 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 
242395Swnj /* This is to block the clock because we are using the silos */
252395Swnj /* SHOULD RATHER QUEUE SOFTWARE INTERRUPT AT CLOCK TIME */
26144Sbill #define	spl5	spl6
27144Sbill 
282395Swnj #define	UBACVT(x,uban) (cbase[uban] + (short)((x)-(char *)cfree))
2913Sbill 
302395Swnj int	dhcntrlr(), dhslave(), dhrint(), dhxint();
312395Swnj struct	uba_dinfo *dhinfo[NDH11];
322395Swnj u_short	dhstd[] = { 0 };
332395Swnj struct	uba_driver dhdriver =
34*2421Skre 	{ dhcntrlr, dhslave, (int (*)())0, 0, 0, dhstd, "dh", dhinfo };
352395Swnj 
362395Swnj struct	tty dh11[NDH11*16];
37117Sbill int	dhact;
38280Sbill int	dhisilo;
392395Swnj int	ndh11	= NDH11*16;
4013Sbill int	dhstart();
4113Sbill int	ttrstrt();
42*2421Skre int	dh_ubinfo[MAXNUBA];
43*2421Skre int	cbase[MAXNUBA];
4413Sbill 
4513Sbill /*
4613Sbill  * Hardware control bits
4713Sbill  */
4813Sbill #define	BITS6	01
4913Sbill #define	BITS7	02
5013Sbill #define	BITS8	03
5113Sbill #define	TWOSB	04
5213Sbill #define	PENABLE	020
5313Sbill /* DEC manuals incorrectly say this bit causes generation of even parity. */
5413Sbill #define	OPAR	040
5513Sbill #define	HDUPLX	040000
5613Sbill 
57*2421Skre #define	MAINT	01000
5813Sbill #define	IENAB	030100
59105Sbill #define	NXM	02000
60105Sbill #define	CLRNXM	0400
6113Sbill #define	PERROR	010000
6213Sbill #define	FRERROR	020000
6313Sbill #define	OVERRUN	040000
6413Sbill #define	XINT	0100000
65*2421Skre #define	RINT	0100
6613Sbill #define	SSPEED	7	/* standard speed: 300 baud */
6713Sbill 
6813Sbill /*
6913Sbill  * DM control bits
7013Sbill  */
7113Sbill #define	TURNON	03	/* CD lead + line enable */
7213Sbill #define	TURNOFF	01	/* line enable */
73168Sbill #define	DTR	02	/* data terminal ready */
7413Sbill #define	RQS	04	/* request to send */
7513Sbill 
7613Sbill /*
7713Sbill  * Software copy of last dhbar
7813Sbill  */
792395Swnj short	dhsar[NDH11];
8013Sbill 
8113Sbill struct device
8213Sbill {
8313Sbill 	union {
8413Sbill 		short	dhcsr;
8513Sbill 		char	dhcsrl;
8613Sbill 	} un;
8713Sbill 	short	dhnxch;
8813Sbill 	short	dhlpr;
8913Sbill 	unsigned short	dhcar;
9013Sbill 	short	dhbcr;
9113Sbill 	unsigned short	dhbar;
9213Sbill 	short	dhbreak;
9313Sbill 	short	dhsilo;
9413Sbill };
9513Sbill 
962395Swnj dhcntrlr(ui, reg)
972395Swnj 	struct uba_dinfo *ui;
982395Swnj 	caddr_t reg;
992395Swnj {
100*2421Skre 	struct device *dhaddr = (struct device *)reg;
101*2421Skre 	int i;
1022395Swnj 
103*2421Skre 	dhaddr->un.dhcsr = IENAB;
104*2421Skre 	dhaddr->dhbcr = -1;
105*2421Skre 	dhaddr->dhbar = 1;
106*2421Skre 	dhaddr->dhcar = 0;
107*2421Skre 	for (i = 0; i < 1000000; i++)
108*2421Skre 		;
109*2421Skre 	/* we should have had an interrupt */
110*2421Skre 	dhaddr->un.dhcsr = 0;
111*2421Skre 	asm("cmpl r10,$0x200;beql 1f;subl2 $4,r10;1:;");
1122395Swnj }
1132395Swnj 
1142395Swnj dhslave(ui, reg, slaveno)
1152395Swnj 	struct uba_dinfo *ui;
1162395Swnj 	caddr_t reg;
1172395Swnj {
1182395Swnj 
1192395Swnj 	/* could fill in local tables for the dh here */
1202395Swnj }
1212395Swnj 
12213Sbill /*
12313Sbill  * Open a DH11 line.
12413Sbill  */
12513Sbill /*ARGSUSED*/
12613Sbill dhopen(dev, flag)
1272395Swnj 	dev_t dev;
12813Sbill {
12913Sbill 	register struct tty *tp;
1302395Swnj 	register int unit, dh;
13113Sbill 	register struct device *addr;
1322395Swnj 	register struct uba_dinfo *ui;
13313Sbill 	int s;
13413Sbill 
1352395Swnj 	unit = minor(dev);
1362395Swnj 	dh = unit >> 4;
1372395Swnj 	if (unit >= NDH11*16 || (ui = dhinfo[dh])->ui_alive == 0) {
13813Sbill 		u.u_error = ENXIO;
13913Sbill 		return;
14013Sbill 	}
1412395Swnj 	tp = &dh11[unit];
1422395Swnj 	ui = dhinfo[dh];
1432395Swnj 	addr = (struct device *)ui->ui_addr;
14413Sbill 	tp->t_addr = (caddr_t)addr;
14513Sbill 	tp->t_oproc = dhstart;
14613Sbill 	tp->t_iproc = NULL;
14713Sbill 	tp->t_state |= WOPEN;
14813Sbill 	s = spl6();
149*2421Skre 	if (dh_ubinfo[ui->ui_ubanum] == 0) {
150717Sbill 		/* 512+ is a kludge to try to get around a hardware problem */
1512395Swnj 		dh_ubinfo[ui->ui_ubanum] =
152*2421Skre 		    uballoc(ui->ui_ubanum, (caddr_t)cfree,
1532395Swnj 			512+NCLIST*sizeof(struct cblock), 0);
1542395Swnj 		cbase[ui->ui_ubanum] = (short)dh_ubinfo[ui->ui_ubanum];
15513Sbill 	}
15613Sbill 	splx(s);
15713Sbill 	addr->un.dhcsr |= IENAB;
1582395Swnj 	dhact |= (1<<dh);
15913Sbill 	if ((tp->t_state&ISOPEN) == 0) {
16013Sbill 		ttychars(tp);
161168Sbill 		if (tp->t_ispeed == 0) {
162168Sbill 			tp->t_ispeed = SSPEED;
163168Sbill 			tp->t_ospeed = SSPEED;
164168Sbill 			tp->t_flags = ODDP|EVENP|ECHO;
165168Sbill 		}
1662395Swnj 		dhparam(unit);
16713Sbill 	}
16813Sbill 	if (tp->t_state&XCLUDE && u.u_uid!=0) {
16913Sbill 		u.u_error = EBUSY;
17013Sbill 		return;
17113Sbill 	}
17213Sbill 	dmopen(dev);
1732395Swnj 	(*linesw[tp->t_line].l_open)(dev, tp);
17413Sbill }
17513Sbill 
17613Sbill /*
17713Sbill  * Close a DH11 line.
17813Sbill  */
17913Sbill /*ARGSUSED*/
18013Sbill dhclose(dev, flag)
1812395Swnj 	dev_t dev;
1822395Swnj 	int flag;
18313Sbill {
18413Sbill 	register struct tty *tp;
1852395Swnj 	register unit;
18613Sbill 
1872395Swnj 	unit = minor(dev);
1882395Swnj 	tp = &dh11[unit];
18913Sbill 	(*linesw[tp->t_line].l_close)(tp);
1902196Stoy 	/*
1912196Stoy 	 * Turn of the break bit in case somebody did a TIOCSBRK without
1922196Stoy 	 * a TIOCCBRK.
1932196Stoy 	 */
1942395Swnj 	((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
19513Sbill 	if (tp->t_state&HUPCLS || (tp->t_state&ISOPEN)==0)
1962395Swnj 		dmctl(unit, TURNOFF, DMSET);
19713Sbill 	ttyclose(tp);
19813Sbill }
19913Sbill 
20013Sbill /*
20113Sbill  * Read from a DH11 line.
20213Sbill  */
20313Sbill dhread(dev)
2042395Swnj 	dev_t dev;
20513Sbill {
2062395Swnj 	register struct tty *tp;
20713Sbill 
2082395Swnj 	tp = &dh11[minor(dev)];
20913Sbill 	(*linesw[tp->t_line].l_read)(tp);
21013Sbill }
21113Sbill 
21213Sbill /*
21313Sbill  * write on a DH11 line
21413Sbill  */
21513Sbill dhwrite(dev)
2162395Swnj 	dev_t dev;
21713Sbill {
2182395Swnj 	register struct tty *tp;
21913Sbill 
2202395Swnj 	tp = &dh11[minor(dev)];
22113Sbill 	(*linesw[tp->t_line].l_write)(tp);
22213Sbill }
22313Sbill 
22413Sbill /*
22513Sbill  * DH11 receiver interrupt.
22613Sbill  */
2272395Swnj dhrint(dh)
2282395Swnj 	int dh;
22913Sbill {
23013Sbill 	register struct tty *tp;
2312395Swnj 	register c;
23213Sbill 	register struct device *addr;
233117Sbill 	register struct tty *tp0;
2342395Swnj 	register struct uba_dinfo *ui;
235139Sbill 	int s;
23613Sbill 
237139Sbill 	s = spl6();	/* see comment in clock.c */
2382395Swnj 	ui = dhinfo[dh];
2392395Swnj 	addr = (struct device *)ui->ui_addr;
2402395Swnj 	tp0 = &dh11[dh*16];
24113Sbill 	while ((c = addr->dhnxch) < 0) {	/* char. present */
242117Sbill 		tp = tp0 + ((c>>8)&017);
2432395Swnj 		if (tp >= &dh11[NDH11*16])
24413Sbill 			continue;
24513Sbill 		if((tp->t_state&ISOPEN)==0) {
24613Sbill 			wakeup((caddr_t)tp);
24713Sbill 			continue;
24813Sbill 		}
24913Sbill 		if (c&PERROR)
25013Sbill 			if ((tp->t_flags&(EVENP|ODDP))==EVENP
25113Sbill 			 || (tp->t_flags&(EVENP|ODDP))==ODDP )
25213Sbill 				continue;
25313Sbill 		if (c&OVERRUN)
25413Sbill 			printf("O");
25513Sbill 		if (c&FRERROR)		/* break */
25613Sbill 			if (tp->t_flags&RAW)
25713Sbill 				c = 0;	/* null (for getty) */
25813Sbill 			else
259168Sbill #ifdef IIASA
260168Sbill 				continue;
261168Sbill #else
262184Sbill 				c = tun.t_intrc;
263168Sbill #endif
264139Sbill 		if (tp->t_line == NETLDISC) {
265117Sbill 			c &= 0177;
266168Sbill 			BKINPUT(c, tp);
267117Sbill 		} else
268117Sbill 			(*linesw[tp->t_line].l_rint)(c,tp);
26913Sbill 	}
270139Sbill 	splx(s);
27113Sbill }
27213Sbill 
27313Sbill /*
27413Sbill  * stty/gtty for DH11
27513Sbill  */
27613Sbill /*ARGSUSED*/
27713Sbill dhioctl(dev, cmd, addr, flag)
2782395Swnj 	caddr_t addr;
27913Sbill {
28013Sbill 	register struct tty *tp;
2812395Swnj 	register unit = minor(dev);
28213Sbill 
2832395Swnj 	tp = &dh11[unit];
284113Sbill 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
285113Sbill 	if (cmd==0)
286113Sbill 		return;
2871895Swnj 	if (ttioctl(tp, cmd, addr, flag)) {
28813Sbill 		if (cmd==TIOCSETP||cmd==TIOCSETN)
2892395Swnj 			dhparam(unit);
290168Sbill 	} else switch(cmd) {
291168Sbill 	case TIOCSBRK:
2922395Swnj 		((struct device *)(tp->t_addr))->dhbreak |= 1<<(unit&017);
293168Sbill 		break;
294168Sbill 	case TIOCCBRK:
2952395Swnj 		((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
296168Sbill 		break;
297168Sbill 	case TIOCSDTR:
2982395Swnj 		dmctl(unit, DTR|RQS, DMBIS);
299168Sbill 		break;
300168Sbill 	case TIOCCDTR:
3012395Swnj 		dmctl(unit, DTR|RQS, DMBIC);
302168Sbill 		break;
303168Sbill 	default:
30413Sbill 		u.u_error = ENOTTY;
305168Sbill 	}
30613Sbill }
30713Sbill 
30813Sbill /*
30913Sbill  * Set parameters from open or stty into the DH hardware
31013Sbill  * registers.
31113Sbill  */
3122395Swnj dhparam(unit)
3132395Swnj 	register int unit;
31413Sbill {
31513Sbill 	register struct tty *tp;
31613Sbill 	register struct device *addr;
3172395Swnj 	register int lpar;
318300Sbill 	int s;
31913Sbill 
3202395Swnj 	tp = &dh11[unit];
32113Sbill 	addr = (struct device *)tp->t_addr;
322300Sbill 	s = spl5();
3232395Swnj 	addr->un.dhcsrl = (unit&017) | IENAB;
32413Sbill 	/*
32513Sbill 	 * Hang up line?
32613Sbill 	 */
32713Sbill 	if ((tp->t_ispeed)==0) {
32813Sbill 		tp->t_state |= HUPCLS;
3292395Swnj 		dmctl(unit, TURNOFF, DMSET);
33013Sbill 		return;
33113Sbill 	}
3322395Swnj 	lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
33313Sbill 	if ((tp->t_ispeed) == 4)		/* 134.5 baud */
3342395Swnj 		lpar |= BITS6|PENABLE|HDUPLX;
3352312Skre 	else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
3362395Swnj 		lpar |= BITS8;
33713Sbill 	else
3382395Swnj 		lpar |= BITS7|PENABLE;
33913Sbill 	if ((tp->t_flags&EVENP) == 0)
3402395Swnj 		lpar |= OPAR;
34113Sbill 	if ((tp->t_ospeed) == 3)	/* 110 baud */
3422395Swnj 		lpar |= TWOSB;
3432395Swnj 	addr->dhlpr = lpar;
344300Sbill 	splx(s);
34513Sbill }
34613Sbill 
34713Sbill /*
34813Sbill  * DH11 transmitter interrupt.
34913Sbill  * Restart each line which used to be active but has
35013Sbill  * terminated transmission since the last interrupt.
35113Sbill  */
3522395Swnj dhxint(dh)
3532395Swnj 	int dh;
35413Sbill {
35513Sbill 	register struct tty *tp;
35613Sbill 	register struct device *addr;
35713Sbill 	short ttybit, bar, *sbar;
3582395Swnj 	register struct uba_dinfo *ui;
3592395Swnj 	register unit;
360144Sbill 	int s;
36113Sbill 
362144Sbill 	s = spl6();	/* block the clock */
3632395Swnj 	ui = dhinfo[dh];
3642395Swnj 	addr = (struct device *)ui->ui_addr;
36513Sbill 	addr->un.dhcsr &= (short)~XINT;
366105Sbill 	if (addr->un.dhcsr & NXM) {
367*2421Skre 		asm("halt");
368105Sbill 		addr->un.dhcsr |= CLRNXM;
369105Sbill 		printf("dh clr NXM\n");
370105Sbill 	}
3712395Swnj 	sbar = &dhsar[dh];
37213Sbill 	bar = *sbar & ~addr->dhbar;
3732395Swnj 	unit = dh * 16; ttybit = 1;
3742395Swnj 	for(; bar; unit++, ttybit <<= 1) {
37513Sbill 		if(bar&ttybit) {
37613Sbill 			*sbar &= ~ttybit;
37713Sbill 			bar &= ~ttybit;
3782395Swnj 			tp = &dh11[unit];
379113Sbill 			tp->t_state &= ~BUSY;
380113Sbill 			if (tp->t_state&FLUSH)
381113Sbill 				tp->t_state &= ~FLUSH;
382113Sbill 			else {
3832395Swnj 				addr->un.dhcsrl = (unit&017)|IENAB;
384219Sbill 				ndflush(&tp->t_outq,
3852395Swnj 				    (int)(short)addr->dhcar-
3862395Swnj 					UBACVT(tp->t_outq.c_cf,ui->ui_ubanum));
387113Sbill 			}
388113Sbill 			if (tp->t_line)
38913Sbill 				(*linesw[tp->t_line].l_start)(tp);
390113Sbill 			else
39113Sbill 				dhstart(tp);
39213Sbill 		}
39313Sbill 	}
394144Sbill 	splx(s);
39513Sbill }
39613Sbill 
39713Sbill /*
39813Sbill  * Start (restart) transmission on the given DH11 line.
39913Sbill  */
40013Sbill dhstart(tp)
4012395Swnj 	register struct tty *tp;
40213Sbill {
40313Sbill 	register struct device *addr;
4042395Swnj 	register int nch, dh, unit;
4052395Swnj 	int s;
40613Sbill 
40713Sbill 	/*
40813Sbill 	 * If it's currently active, or delaying,
40913Sbill 	 * no need to do anything.
41013Sbill 	 */
41113Sbill 	s = spl5();
4122395Swnj 	unit = minor(tp->t_dev);
4132395Swnj 	dh = unit >> 4;
41413Sbill 	addr = (struct device *)tp->t_addr;
41513Sbill 	if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))
41613Sbill 		goto out;
4172395Swnj 	if ((tp->t_state&ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) {
41813Sbill 		tp->t_state &= ~ASLEEP;
41913Sbill 		if (tp->t_chan)
420168Sbill 			mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
421168Sbill 		else
42213Sbill 			wakeup((caddr_t)&tp->t_outq);
42313Sbill 	}
42413Sbill 	if (tp->t_outq.c_cc == 0)
42513Sbill 		goto out;
4262395Swnj 	if (tp->t_flags & RAW)
42713Sbill 		nch = ndqb(&tp->t_outq, 0);
4282395Swnj 	else {
42913Sbill 		nch = ndqb(&tp->t_outq, 0200);
43013Sbill 		if (nch == 0) {
43113Sbill 			nch = getc(&tp->t_outq);
43213Sbill 			timeout(ttrstrt, (caddr_t)tp, (nch&0177)+6);
43313Sbill 			tp->t_state |= TIMEOUT;
43413Sbill 			goto out;
43513Sbill 		}
43613Sbill 	}
43713Sbill 	if (nch) {
4382395Swnj 		addr->un.dhcsrl = (unit&017)|IENAB;
4392395Swnj 		addr->dhcar = UBACVT(tp->t_outq.c_cf,
4402395Swnj 		    dhinfo[dh]->ui_ubanum);
44113Sbill 		addr->dhbcr = -nch;
4422395Swnj 		nch = 1<<(unit&017);
44313Sbill 		addr->dhbar |= nch;
4442395Swnj 		dhsar[dh] |= nch;
44513Sbill 		tp->t_state |= BUSY;
44613Sbill 	}
4472395Swnj out:
44813Sbill 	splx(s);
44913Sbill }
45013Sbill 
45113Sbill /*
45213Sbill  * Stop output on a line.
45313Sbill  * Assume call is made at spl6.
45413Sbill  */
45513Sbill /*ARGSUSED*/
45613Sbill dhstop(tp, flag)
45713Sbill register struct tty *tp;
45813Sbill {
459113Sbill 	register struct device *addr;
4602395Swnj 	register int unit, s;
46113Sbill 
462113Sbill 	addr = (struct device *)tp->t_addr;
46313Sbill 	s = spl6();
464113Sbill 	if (tp->t_state & BUSY) {
4652395Swnj 		unit = minor(tp->t_dev);
4662395Swnj 		addr->un.dhcsrl = (unit&017) | IENAB;
46713Sbill 		if ((tp->t_state&TTSTOP)==0)
46813Sbill 			tp->t_state |= FLUSH;
469113Sbill 		addr->dhbcr = -1;
470113Sbill 	}
47113Sbill 	splx(s);
47213Sbill }
47313Sbill 
474117Sbill int	dhsilo = 16;
475168Sbill /*
476168Sbill  * Silo control is fixed strategy
477168Sbill  * here, paralleling only option available
478168Sbill  * on DZ-11.
479168Sbill  */
48013Sbill /*ARGSUSED*/
481168Sbill dhtimer()
48213Sbill {
4832395Swnj 	register int dh;
484117Sbill 	register struct device *addr;
4852395Swnj 	register struct uba_dinfo *ui;
486117Sbill 
4872395Swnj 	dh = 0;
48813Sbill 	do {
4892395Swnj 		ui = dhinfo[dh];
4902395Swnj 		addr = (struct device *)ui->ui_addr;
4912395Swnj 		if (dhact & (1<<dh)) {
4922395Swnj 			if ((dhisilo & (1<<dh)) == 0) {
493280Sbill 				addr->dhsilo = dhsilo;
4942395Swnj 				dhisilo |= 1<<dh;
495280Sbill 			}
4962395Swnj 			dhrint(dh);
497117Sbill 		}
4982395Swnj 		dh++;
4992395Swnj 	} while (dh < NDH11);
50013Sbill }
501280Sbill 
502280Sbill /*
503280Sbill  * Reset state of driver if UBA reset was necessary.
504280Sbill  * Reset the csrl and lpr registers on open lines, and
505280Sbill  * restart transmitters.
506280Sbill  */
5072395Swnj dhreset(uban)
508280Sbill {
5092395Swnj 	register int dh, unit;
510280Sbill 	register struct tty *tp;
5112395Swnj 	register struct uba_dinfo *ui;
512*2421Skre 	int i;
513280Sbill 
514*2421Skre 	if (dh_ubinfo[uban] == 0)
515*2421Skre 		return;
516280Sbill 	printf(" dh");
517*2421Skre 	ubarelse(uban, &dh_ubinfo[uban]);
518*2421Skre 	dh_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
519*2421Skre 	    512+NCLIST*sizeof (struct cblock), 0);
520*2421Skre 	cbase[uban] = dh_ubinfo[uban]&0x3ffff;
521*2421Skre 	dhisilo = 0;		/* conservative */
5222395Swnj 	dh = 0;
523*2421Skre 	for (dh = 0; dh < NDH11; dh++) {
524*2421Skre 		ui = dhinfo[dh];
525*2421Skre 		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
526*2421Skre 			continue;
527*2421Skre 		((struct device *)ui->ui_addr)->un.dhcsr |= IENAB;
528*2421Skre 		unit = dh * 16;
529*2421Skre 		for (i = 0; i < 16; i++) {
530*2421Skre 			tp = &dh11[unit];
531*2421Skre 			if (tp->t_state & (ISOPEN|WOPEN)) {
532*2421Skre 				dhparam(unit);
533*2421Skre 				dmctl(unit, TURNON, DMSET);
534*2421Skre 				tp->t_state &= ~BUSY;
535*2421Skre 				dhstart(tp);
536*2421Skre 			}
537*2421Skre 			unit++;
538300Sbill 		}
539300Sbill 	}
540300Sbill 	dhtimer();
541280Sbill }
5422395Swnj 
5432395Swnj #if DHDM
5441944Swnj #include "../dev/dhdm.c"
5451944Swnj #else
5461944Swnj #include "../dev/dhfdm.c"
5471808Sbill #endif
5481944Swnj #endif
549