*BSD News Article 97660


Return to BSD News archive

Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!como.dpie.gov.au!news.gan.net.au!act.news.telstra.net!news-out.internetmci.com!newsfeed.internetmci.com!howland.erols.net!feed1.news.erols.com!chippy.visi.com!news-out.visi.com!news.interactive.net!news.new-york.net!wlbr!moe.2bsd.com!sms
From: sms@moe.2bsd.com (Steven M. Schultz)
Subject: 2.11BSD gets RTS/CTS flow control - continued (#374)
Organization: 2BSD, Simi Valley CA USA
Message-ID: <EBpA5E.I90@moe.2bsd.com>
Date: Fri, 13 Jun 1997 06:03:14 GMT
Lines: 2937
Xref: euryale.cc.adfa.oz.au comp.bugs.2bsd:794

Subject: 2.11BSD gets RTS/CTS flow control - continued (#374)
Index:	pdpuba/dhu,dhv,dh.c,pdpuba/dhureg.h,pdp/conf.c,man/dhv,dh,dvu.4 2.11BSD

Description:
	The DH-11 and DHU-11 drivers do not implement RTS/CTS flowcontrol.

	Also, the dhureg.h file makes the same mistake as dhvreg.h did by
	misdeclaring the value of the CTS bit in the device status register.

	There was no manpage for the DHV device.

	The manpages for the DH and DHU devices were way out of date.

Repeat-By:
	It's fairly obvious - by observation of course ;)

Fix:
	NOTE:  I do not have a DHU-11 to test with.  The DHU is very very
	       close to the DHV-11 and the changes were essentially merged in
	       from the DHV-11 driver.  It is possible (I hesitate to say 
	       "likely", but...) there are bugs present.  If you have a DHU-11
	       and experience problems let me know and I'll work with you to
	       fix them.

	NOTE:  While I do have a DH-11 lookalike (an Able "Supermax") there has
	       only been minimal testing of the driver because no phoneline 
	       is within reach of the 11/44.  The testing done was to make sure
	       that channels on the DH could be opened and that the output of
	       "stty -a -f /dev/ttyi8" looked reasonable (i.e. DTR, RTS, CTS,
	       etc looked right) and no system crash occurs.  If I can get 
	       a modem line installed on the 44 more testing will be done.

	I really don't like sending out poorly tested or untested changes.  But
	the hope is that someone will help out with the testing.  

	The changes to the DH and DHU should be considered "alpha test" in 
	nature.  There is a good chance the modifications will work but if
	not the problems will be fixed and an update posted.

	In the patch kit below the following files are updated:

/usr/src/sys/pdpuba/dhureg.h
/usr/src/sys/pdpuba/dhu.c
/usr/src/sys/pdpuba/dhv.c
/usr/src/sys/pdpuba/dh.c
/usr/src/sys/pdp/conf.c
/usr/src/man/man4/dhu.4
/usr/src/man/man4/dh.4
/usr/src/man/man4/dhv.4
/usr/src/man/man4/Makefile
/VERSION

	dhu.c and dh.c were almost complete rewrites.  The changes to dhv.c
	are small and consist of shortening a couple message strings and
	a return(0) added where only "return" was used before.

	While the DHV is similar to the DHU the differences are sufficient to
	justify a new manpage: dhv(4).

	The dh(4) and dhu(4) manpages were updated to reflect the new minor
	device number layout (bit 6 is used to enable/disable RTS/CTS flow
	control, usw).

	In conf.c the DH  and DHU entries in the cdevsw[] table were changed
	to call the driver specific select() function.  This is necessary for
	ALL serial drivers which do RTS/CTS because the minor device number
	must be modified before being passed to the tty subsystem.

	To install this update first cut where indicated and save to a file
	(/tmp/374).  Then:

			cd /tmp
			sh 374
			patch -p0 < 374.patch
			sh 374.shar
			cd /usr/src/man/man4
			make dh.0 dhu.0 dhv.0
			install -m 444 -o bin -g bin *.0 /usr/man/cat4

	If you can't wait for the 'makewhatis' database to be rebuilt (usually
	done by 'catman' from the /usr/adm/weekly cron run):

			/usr/sbin/makewhatis

	Unless you have DH, DHU or DHV devices present in the system there is
	no compelling reason to rebuild your kernel at this time.  If you have
	the time it doesn't hurt anything to do a kernel recompile.

	As always this and previous updates to 2.11BSD are available via
	anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the
	directory /pub/2.11BSD.

----------------------------cut here--------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	374.patch
#	374.shar
# This archive created: Thu Jun 12 22:44:31 1997
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f '374.patch'
then
	echo shar: "will not over-write existing file '374.patch'"
else
sed 's/^Z//' << \SHAR_EOF > '374.patch'
Z*** /usr/src/sys/pdpuba/dhureg.h.old	Mon Jan 12 14:56:11 1987
Z--- /usr/src/sys/pdpuba/dhureg.h	Fri May  9 20:30:43 1997
Z***************
Z*** 3,9 ****
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dhureg.h	1.1 (2.10BSD Berkeley) 12/1/86
Z   */
Z  
Z  /* 
Z--- 3,9 ----
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dhureg.h	1.2 (2.11BSD) 1997/5/9
Z   */
Z  
Z  /* 
Z***************
Z*** 92,98 ****
Z  #define	DHU_ST_DSR	0x80		/* data set ready */
Z  #define	DHU_ST_RI	0x20		/* ring indicator */
Z  #define	DHU_ST_DCD	0x10		/* carrier detect */
Z! #define	DHU_ST_CTS	0x04		/* clear to send */
Z  #define	DHU_ST_DHU	0x01		/* always one on a dhu, zero on dhv */
Z  
Z  /* Bits in dhulcr */
Z--- 92,98 ----
Z  #define	DHU_ST_DSR	0x80		/* data set ready */
Z  #define	DHU_ST_RI	0x20		/* ring indicator */
Z  #define	DHU_ST_DCD	0x10		/* carrier detect */
Z! #define	DHU_ST_CTS	0x08		/* clear to send */
Z  #define	DHU_ST_DHU	0x01		/* always one on a dhu, zero on dhv */
Z  
Z  /* Bits in dhulcr */
Z***************
Z*** 128,141 ****
Z  #define	DHU_DTR	DHU_LC_DTR
Z  #define DHU_BRK	DHU_LC_BREAK
Z  #define DHU_LE	DHU_LC_MODEM
Z- 
Z- /* bits in dm lsr, copied from dmreg.h */
Z- #define	DML_DSR		0000400		/* data set ready, not a real DM bit */
Z- #define	DML_RNG		0000200		/* ring */
Z- #define	DML_CAR		0000100		/* carrier detect */
Z- #define	DML_CTS		0000040		/* clear to send */
Z- #define	DML_SR		0000020		/* secondary receive */
Z- #define	DML_ST		0000010		/* secondary transmit */
Z- #define	DML_RTS		0000004		/* request to send */
Z- #define	DML_DTR		0000002		/* data terminal ready */
Z- #define	DML_LE		0000001		/* line enable */
Z--- 128,130 ----
Z*** /usr/src/sys/pdpuba/dhu.c.old	Fri Feb 14 21:02:10 1997
Z--- /usr/src/sys/pdpuba/dhu.c	Sat May 31 16:13:24 1997
Z***************
Z*** 3,12 ****
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dhu.c	2.2 (2.11BSD GTE) 1997/2/14
Z   */
Z  
Z  /*
Z   * based on	dh.c 6.3	84/03/15
Z   * and on	dmf.c	6.2	84/02/16
Z   *
Z--- 3,14 ----
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dhu.c	2.3 (2.11BSD GTE) 1997/5/9
Z   */
Z  
Z  /*
Z+  * Rewritten for hardware flow control - sms 1997/5/9
Z+  *
Z   * based on	dh.c 6.3	84/03/15
Z   * and on	dmf.c	6.2	84/02/16
Z   *
Z***************
Z*** 32,37 ****
Z--- 34,40 ----
Z  #include "uba.h"
Z  #include "ubavar.h"
Z  #include "systm.h"
Z+ #include "syslog.h"
Z  #include <sys/kernel.h>
Z  
Z  struct	uba_device dhuinfo[NDHU];
Z***************
Z*** 38,52 ****
Z  
Z  #define	NDHULINE	(NDHU*16)
Z  
Z! #define	UNIT(x)	(minor(x) & 0177)
Z  
Z- #ifndef PORTSELECTOR
Z  #define ISPEED	B9600
Z  #define IFLAGS	(EVENP|ODDP|ECHO)
Z- #else
Z- #define ISPEED	B4800
Z- #define IFLAGS	(EVENP|ODDP)
Z- #endif
Z  
Z  /*
Z   * default receive silo timeout value -- valid values are 2..255
Z--- 41,52 ----
Z  
Z  #define	NDHULINE	(NDHU*16)
Z  
Z! #define	UNIT(x)	(minor(x) & 077)
Z! #define	SOFTCAR	0x80
Z! #define	HWFLOW	0x40
Z  
Z  #define ISPEED	B9600
Z  #define IFLAGS	(EVENP|ODDP|ECHO)
Z  
Z  /*
Z   * default receive silo timeout value -- valid values are 2..255
Z***************
Z*** 54,75 ****
Z   *
Z   * A value of 20 gives same response as ABLE dh/dm with silo alarm = 0
Z   */
Z! #define	DHU_DEF_TIMO	20
Z  
Z  /*
Z-  * Other values for silo timeout register defined here but not used:
Z-  * receive interrupt only on modem control or silo alarm (3/4 full)
Z-  */
Z- #define DHU_POLL_TIMO	0
Z- /*
Z-  * receive interrupt immediately on receive character
Z-  */
Z- #define DHU_NO_TIMO	1
Z- 
Z- /*
Z-  * Local variables for the driver
Z-  */
Z- /*
Z   * Baud rates: no 50, 200, or 38400 baud; all other rates are from "Group B".
Z   *	EXTA => 19200 baud
Z   *	EXTB => 2000 baud
Z--- 54,62 ----
Z   *
Z   * A value of 20 gives same response as ABLE dh/dm with silo alarm = 0
Z   */
Z! int	dhu_def_timo = 20;
Z  
Z  /*
Z   * Baud rates: no 50, 200, or 38400 baud; all other rates are from "Group B".
Z   *	EXTA => 19200 baud
Z   *	EXTB => 2000 baud
Z***************
Z*** 77,89 ****
Z  char	dhu_speeds[] =
Z  	{ 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 };
Z  
Z- short	dhusoftCAR[NDHU];
Z- 
Z  struct	tty dhu_tty[NDHULINE];
Z  int	ndhu = NDHULINE;
Z  int	dhuact;				/* mask of active dhu's */
Z! int	dhustart(), ttrstrt();
Z  long	dhumctl(),dmtodhu();
Z  
Z  #if defined(UCB_CLIST)
Z  extern	ubadr_t clstaddr;
Z--- 64,76 ----
Z  char	dhu_speeds[] =
Z  	{ 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 };
Z  
Z  struct	tty dhu_tty[NDHULINE];
Z  int	ndhu = NDHULINE;
Z  int	dhuact;				/* mask of active dhu's */
Z! int	dhu_overrun[NDHULINE];
Z! int	dhustart();
Z  long	dhumctl(),dmtodhu();
Z+ extern	int wakeup();
Z  
Z  #if defined(UCB_CLIST)
Z  extern	ubadr_t clstaddr;
Z***************
Z*** 99,116 ****
Z  duattach(addr,unit)
Z  	register caddr_t addr;
Z  	register u_int unit;
Z! {
Z  	register struct uba_device *ui;
Z  
Z! 	if (addr && unit < NDHU && !dhuinfo[unit].ui_addr) {
Z  		ui = &dhuinfo[unit];
Z  		ui->ui_unit = unit;
Z  		ui->ui_addr = addr;
Z  		ui->ui_alive = 1;
Z! 		return (1);
Z  	}
Z- 	return (0);
Z- }
Z  
Z  /*
Z   * Open a DHU11 line, mapping the clist onto the uba if this
Z--- 86,104 ----
Z  duattach(addr,unit)
Z  	register caddr_t addr;
Z  	register u_int unit;
Z! 	{
Z  	register struct uba_device *ui;
Z  
Z! 	if	(addr && unit < NDHU && !dhuinfo[unit].ui_addr)
Z! 		{
Z  		ui = &dhuinfo[unit];
Z  		ui->ui_unit = unit;
Z  		ui->ui_addr = addr;
Z  		ui->ui_alive = 1;
Z! 		return(1);
Z! 		}
Z! 	return(0);
Z  	}
Z  
Z  /*
Z   * Open a DHU11 line, mapping the clist onto the uba if this
Z***************
Z*** 120,240 ****
Z  /*ARGSUSED*/
Z  dhuopen(dev, flag)
Z  	dev_t dev;
Z! {
Z  	register struct tty *tp;
Z! 	register int unit, dhu;
Z  	register struct dhudevice *addr;
Z  	register struct uba_device *ui;
Z! 	int s;
Z  
Z  	unit = UNIT(dev);
Z  	dhu = unit >> 4;
Z! 	if (dev & 0200)
Z! 		dhusoftCAR[dhu] |= (1<<(unit&0xf));
Z! 	else
Z! 		dhusoftCAR[dhu] &= ~(1<<(unit&0xf));
Z! 	if (unit >= NDHULINE || (ui = &dhuinfo[dhu])->ui_alive == 0)
Z  		return (ENXIO);
Z  	tp = &dhu_tty[unit];
Z- 	if (tp->t_state & TS_XCLUDE && u.u_uid != 0)
Z- 		return (EBUSY);
Z  	addr = (struct dhudevice *)ui->ui_addr;
Z  	tp->t_addr = (caddr_t)addr;
Z  	tp->t_oproc = dhustart;
Z! 	/*
Z! 	 * While setting up state for this uba and this dhu,
Z! 	 * block uba resets which can clear the state.
Z! 	 */
Z! 	s = spl5();
Z! 	if ((dhuact&(1<<dhu)) == 0) {
Z  		addr->dhucsr = DHU_SELECT(0) | DHU_IE;
Z! 		addr->dhutimo = DHU_DEF_TIMO;
Z  		dhuact |= (1<<dhu);
Z  		/* anything else to configure whole board */
Z! 	}
Z! 	(void) splx(s);
Z  	/*
Z  	 * If this is first open, initialize tty state to default.
Z  	 */
Z! 	if ((tp->t_state&TS_ISOPEN) == 0) {
Z! 		ttychars(tp);
Z! #ifndef PORTSELECTOR
Z! 		if (tp->t_ispeed == 0) {
Z! #else
Z  			tp->t_state |= TS_HUPCLS;
Z- #endif PORTSELECTOR
Z  			tp->t_ispeed = ISPEED;
Z  			tp->t_ospeed = ISPEED;
Z  			tp->t_flags = IFLAGS;
Z! #ifndef PORTSELECTOR
Z! 		}
Z! #endif PORTSELECTOR
Z  		tp->t_dev = dev;
Z  		dhuparam(unit);
Z! 	}
Z! 	/*
Z! 	 * Wait for carrier, then process line discipline specific open.
Z! 	 */
Z! 	s = spl5();
Z! 	if ((dhumctl(dev, (long)DHU_ON, DMSET) & DHU_CAR) ||
Z! 	    (dhusoftCAR[dhu] & (1<<(unit&0xf))))
Z  		tp->t_state |= TS_CARR_ON;
Z! 	while ((tp->t_state & TS_CARR_ON) == 0) {
Z  		tp->t_state |= TS_WOPEN;
Z  		sleep((caddr_t)&tp->t_rawq, TTIPRI);
Z  	}
Z- 	(void) splx(s);
Z- 	return ((*linesw[tp->t_line].l_open)(dev, tp));
Z- }
Z  
Z  /*
Z!  * Close a DHU11 line, turning off the modem control.
Z   */
Z  /*ARGSUSED*/
Z  dhuclose(dev, flag)
Z  	dev_t dev;
Z  	int flag;
Z! {
Z  	register struct tty *tp;
Z! 	register unit;
Z  
Z  	unit = UNIT(dev);
Z  	tp = &dhu_tty[unit];
Z  	(*linesw[tp->t_line].l_close)(tp, flag);
Z  	(void) dhumctl(unit, (long)DHU_BRK, DMBIC);
Z! 	if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0)
Z! #ifdef PORTSELECTOR
Z  	{
Z- 		extern int wakeup();
Z  
Z! 		(void) dhumctl(unit, (long)DHU_OFF, DMSET);
Z! 		/* Hold DTR low for 0.5 seconds */
Z! 		timeout(wakeup, (caddr_t) &tp->t_dev, hz/2);
Z! 		sleep((caddr_t) &tp->t_dev, PZERO);
Z  	}
Z- #else
Z- 		(void) dhumctl(unit, DHU_OFF, DMSET);
Z- #endif PORTSELECTOR
Z- 	ttyclose(tp);
Z- }
Z  
Z  dhuread(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z! {
Z  	register struct tty *tp = &dhu_tty[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
Z! }
Z  
Z  dhuwrite(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z! {
Z  	register struct tty *tp = &dhu_tty[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
Z! }
Z  
Z  /*
Z   * DHU11 receiver interrupt.
Z--- 108,241 ----
Z  /*ARGSUSED*/
Z  dhuopen(dev, flag)
Z  	dev_t dev;
Z! 	int	flag;
Z! 	{
Z  	register struct tty *tp;
Z! 	int unit, dhu;
Z  	register struct dhudevice *addr;
Z  	register struct uba_device *ui;
Z! 	int s, error;
Z  
Z  	unit = UNIT(dev);
Z  	dhu = unit >> 4;
Z! 	if	(unit >= NDHULINE || (ui = &dhuinfo[dhu])->ui_alive == 0)
Z  		return (ENXIO);
Z  	tp = &dhu_tty[unit];
Z  	addr = (struct dhudevice *)ui->ui_addr;
Z  	tp->t_addr = (caddr_t)addr;
Z  	tp->t_oproc = dhustart;
Z! 
Z! 	if	((dhuact&(1<<dhu)) == 0)
Z! 		{
Z  		addr->dhucsr = DHU_SELECT(0) | DHU_IE;
Z! 		addr->dhutimo = dhu_def_timo;
Z  		dhuact |= (1<<dhu);
Z  		/* anything else to configure whole board */
Z! 		}
Z  	/*
Z  	 * If this is first open, initialize tty state to default.
Z  	 */
Z! 	s = spltty();
Z! 	if	((tp->t_state&TS_ISOPEN) == 0)
Z! 		{
Z! 		tp->t_state |= TS_WOPEN;
Z! 		if	(tp->t_ispeed == 0)
Z! 			{
Z  			tp->t_state |= TS_HUPCLS;
Z  			tp->t_ispeed = ISPEED;
Z  			tp->t_ospeed = ISPEED;
Z  			tp->t_flags = IFLAGS;
Z! 			}
Z! 		ttychars(tp);
Z  		tp->t_dev = dev;
Z+ 		if	(dev & HWFLOW)
Z+ 			tp->t_flags |= RTSCTS;
Z+ 		else
Z+ 			tp->t_flags &= ~RTSCTS;
Z  		dhuparam(unit);
Z! 		}
Z! 	else if (tp->t_state & TS_XCLUDE && u.u_uid)
Z! 		{
Z! 		error = EBUSY;
Z! 		goto out;
Z! 		}
Z! /*
Z!  * Turn the device on.  Wait for carrier (the wait is short if this is a
Z!  * softcarrier/hardwired line ;-)).  Then do the line discipline specific open.
Z! */
Z! 	dhumctl(dev, (long)DHU_ON, DMSET);
Z! 	addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
Z! 	if	((addr->dhustat & DHU_ST_DCD) || (dev & SOFTCAR))
Z  		tp->t_state |= TS_CARR_ON;
Z! 	while	((tp->t_state & TS_CARR_ON) == 0 &&
Z! 		 (flag & O_NONBLOCK) == 0)
Z! 		{
Z  		tp->t_state |= TS_WOPEN;
Z  		sleep((caddr_t)&tp->t_rawq, TTIPRI);
Z+ 		}
Z+ 	error = (*linesw[tp->t_line].l_open)(dev, tp);
Z+ out:
Z+ 	splx(s);
Z+ 	return(error);
Z  	}
Z  
Z  /*
Z!  * Close a DHU11 line.  Clear the 'break' state in case it's asserted and 
Z!  * then drop DTR+RTS.
Z   */
Z  /*ARGSUSED*/
Z  dhuclose(dev, flag)
Z  	dev_t dev;
Z  	int flag;
Z! 	{
Z  	register struct tty *tp;
Z! 	register int unit;
Z  
Z  	unit = UNIT(dev);
Z  	tp = &dhu_tty[unit];
Z+ /*
Z+  * Do we need to do this?  Perhaps this should be ifdef'd.  I can't see how
Z+  * this can happen...
Z+ */
Z+ 	if	(!(tp->t_state & TS_ISOPEN))
Z+ 		return(EBADF);
Z  	(*linesw[tp->t_line].l_close)(tp, flag);
Z  	(void) dhumctl(unit, (long)DHU_BRK, DMBIC);
Z! 	(void) dhumctl(unit, DHU_OFF, DMSET);
Z! 	ttyclose(tp);
Z! 	if	(dhu_overrun[unit])
Z! 		{
Z! 		log(LOG_NOTICE, "dhu%d %d overruns\n", unit, dhu_overrun[unit]);
Z! 		dhu_overrun[unit] = 0;
Z! 		}
Z! 	return(0);
Z! 	}
Z! 
Z! dhuselect(dev, rw)
Z! 	dev_t	dev;
Z! 	int	rw;
Z  	{
Z  
Z! 	return(ttyselect(&dhu_tty[UNIT(dev)], rw));
Z  	}
Z  
Z  dhuread(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z! 	{
Z  	register struct tty *tp = &dhu_tty[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
Z! 	}
Z  
Z  dhuwrite(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z! 	{
Z  	register struct tty *tp = &dhu_tty[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
Z! 	}
Z  
Z  /*
Z   * DHU11 receiver interrupt.
Z***************
Z*** 241,298 ****
Z  */
Z  dhurint(dhu)
Z  	int dhu;
Z! {
Z  	register struct tty *tp;
Z! 	register c;
Z  	register struct dhudevice *addr;
Z! 	register struct tty *tp0;
Z! 	register struct uba_device *ui;
Z! 	register line;
Z! 	int overrun = 0;
Z  
Z  	ui = &dhuinfo[dhu];
Z- 	if (ui == 0 || ui->ui_alive == 0)
Z- 		return;
Z  	addr = (struct dhudevice *)ui->ui_addr;
Z  	tp0 = &dhu_tty[dhu<<4];
Z  	/*
Z  	 * Loop fetching characters from the silo for this
Z  	 * dhu until there are no more in the silo.
Z  	*/
Z! 	while ((c = addr->dhurbuf) < 0) {	/* (c & DHU_RB_VALID) == on */
Z  		line = DHU_RX_LINE(c);
Z  		tp = tp0 + line;
Z! 		if ((c & DHU_RB_STAT) == DHU_RB_STAT) {
Z  			/*
Z  			 * modem changed or diag info
Z  			 */
Z! 			if (c & DHU_RB_DIAG) {
Z! 				/* decode diagnostic messages */
Z  				continue;
Z! 			}
Z! 			if (c & DHU_ST_DCD)
Z! 				(void)(*linesw[tp->t_line].l_modem)(tp, 1);
Z! 			else if ((dhusoftCAR[dhu] & (1<<line)) == 0 &&
Z! 			    (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
Z! 				(void) dhumctl((dhu<<4)|line, DHU_OFF, DMSET);
Z  			continue;
Z! 		}
Z! 		if ((tp->t_state&TS_ISOPEN) == 0) {
Z  			wakeup((caddr_t)&tp->t_rawq);
Z! #ifdef PORTSELECTOR
Z! 			if ((tp->t_state&TS_WOPEN) == 0)
Z! #endif
Z  				continue;
Z! 		}
Z! 		if (c & DHU_RB_PE)
Z! 			if ((tp->t_flags&(EVENP|ODDP)) == EVENP ||
Z! 			    (tp->t_flags&(EVENP|ODDP)) == ODDP)
Z! 				continue;
Z! 		if ((c & DHU_RB_DO) && overrun == 0) {
Z! 			printf("dhu%d: silo overflow\n", dhu);
Z! 			overrun = 1;
Z! 		}
Z! 		if (c & DHU_RB_FE)
Z  			/*
Z  			 * At framing error (break) generate
Z  			 * a null (in raw mode, for getty), or a
Z--- 242,318 ----
Z  */
Z  dhurint(dhu)
Z  	int dhu;
Z! 	{
Z  	register struct tty *tp;
Z! 	register int	c;
Z  	register struct dhudevice *addr;
Z! 	struct tty *tp0;
Z! 	struct uba_device *ui;
Z! 	int	line;
Z  
Z  	ui = &dhuinfo[dhu];
Z  	addr = (struct dhudevice *)ui->ui_addr;
Z+ 	if	(!addr)
Z+ 		return;
Z  	tp0 = &dhu_tty[dhu<<4];
Z  	/*
Z  	 * Loop fetching characters from the silo for this
Z  	 * dhu until there are no more in the silo.
Z  	*/
Z! 	while	((c = addr->dhurbuf) < 0)
Z! 		{	/* (c & DHU_RB_VALID) == on */
Z  		line = DHU_RX_LINE(c);
Z  		tp = tp0 + line;
Z! 		if	((c & DHU_RB_STAT) == DHU_RB_STAT)
Z! 			{
Z  			/*
Z  			 * modem changed or diag info
Z  			 */
Z! 			if	(c & DHU_RB_DIAG)
Z! 				{
Z! 				if	((c & 0xff) > 0201)
Z! 					log(LOG_NOTICE,"dhu%d diag %o\n",
Z! 						dhu, c);
Z  				continue;
Z! 				}
Z! 			if	(!(tp->t_dev & SOFTCAR) ||
Z! 				  (tp->t_flags & MDMBUF))
Z! 				(*linesw[tp->t_line].l_modem)(tp,
Z! 						(c & DHU_ST_DCD) != 0);
Z! 			if	(tp->t_flags & RTSCTS)
Z! 				{
Z! 				if	(c & DHU_ST_CTS)
Z! 					{
Z! 					tp->t_state &= ~TS_TTSTOP;
Z! 					ttstart(tp);
Z! 					}
Z! 				else
Z! 					{
Z! 					tp->t_state |= TS_TTSTOP;
Z! 					dhustop(tp, 0);
Z! 					}
Z! 				}
Z  			continue;
Z! 			}
Z! 		if	((tp->t_state&TS_ISOPEN) == 0)
Z! 			{
Z  			wakeup((caddr_t)&tp->t_rawq);
Z! 			continue;
Z! 			}
Z! 		if	(c & DHU_RB_PE)
Z! 			if	((tp->t_flags&(EVENP|ODDP)) == EVENP ||
Z! 				 (tp->t_flags&(EVENP|ODDP)) == ODDP)
Z  				continue;
Z! 		if	(c & DHU_RB_DO)
Z! 			{
Z! 			dhu_overrun[(dhu << 4) + line]++;
Z! 			/* bit bucket the silo to free the cpu */
Z! 			while	(addr->dhurbuf & DHU_RB_VALID)
Z! 				;
Z! 			break;
Z! 			}
Z! 		if	(c & DHU_RB_FE)
Z! 			{
Z  			/*
Z  			 * At framing error (break) generate
Z  			 * a null (in raw mode, for getty), or a
Z***************
Z*** 306,320 ****
Z  #else
Z  				c = tp->t_brkc;
Z  #endif
Z  #if NBK > 0
Z! 		if (tp->t_line == NETLDISC) {
Z  			c &= 0x7f;
Z  			BKINPUT(c, tp);
Z! 		} else
Z  #endif
Z  			(*linesw[tp->t_line].l_rint)(c, tp);
Z  	}
Z- }
Z  
Z  /*
Z   * Ioctl for DHU11.
Z--- 326,343 ----
Z  #else
Z  				c = tp->t_brkc;
Z  #endif
Z+ 			}
Z  #if NBK > 0
Z! 		if	(tp->t_line == NETLDISC)
Z! 			{
Z  			c &= 0x7f;
Z  			BKINPUT(c, tp);
Z! 			}
Z! 		else
Z  #endif
Z  			(*linesw[tp->t_line].l_rint)(c, tp);
Z+ 		}
Z  	}
Z  
Z  /*
Z   * Ioctl for DHU11.
Z***************
Z*** 323,329 ****
Z  dhuioctl(dev, cmd, data, flag)
Z  	u_int cmd;
Z  	caddr_t data;
Z! {
Z  	register struct tty *tp;
Z  	register int unit = UNIT(dev);
Z  	int error;
Z--- 346,352 ----
Z  dhuioctl(dev, cmd, data, flag)
Z  	u_int cmd;
Z  	caddr_t data;
Z! 	{
Z  	register struct tty *tp;
Z  	register int unit = UNIT(dev);
Z  	int error;
Z***************
Z*** 330,410 ****
Z  
Z  	tp = &dhu_tty[unit];
Z  	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
Z! 	if (error >= 0)
Z! 		return (error);
Z  	error = ttioctl(tp, cmd, data, flag);
Z! 	if (error >= 0) {
Z! 		if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLSET ||
Z! 		    cmd == TIOCLBIC || cmd == TIOCLBIS)
Z  			dhuparam(unit);
Z! 		return (error);
Z! 	}
Z  
Z! 	switch (cmd) {
Z! 	case TIOCSBRK:
Z! 		(void) dhumctl(unit, (long)DHU_BRK, DMBIS);
Z! 		break;
Z! 
Z! 	case TIOCCBRK:
Z! 		(void) dhumctl(unit, (long)DHU_BRK, DMBIC);
Z! 		break;
Z! 
Z! 	case TIOCSDTR:
Z! 		(void) dhumctl(unit, (long)DHU_DTR|DHU_RTS, DMBIS);
Z! 		break;
Z! 
Z! 	case TIOCCDTR:
Z! 		(void) dhumctl(unit, (long)DHU_DTR|DHU_RTS, DMBIC);
Z! 		break;
Z! 
Z! 	case TIOCMSET:
Z! 		(void) dhumctl(dev, dmtodhu(*(int *)data), DMSET);
Z! 		break;
Z! 
Z! 	case TIOCMBIS:
Z! 		(void) dhumctl(dev, dmtodhu(*(int *)data), DMBIS);
Z! 		break;
Z! 
Z! 	case TIOCMBIC:
Z! 		(void) dhumctl(dev, dmtodhu(*(int *)data), DMBIC);
Z! 		break;
Z! 
Z! 	case TIOCMGET:
Z! 		*(int *)data = dhutodm(dhumctl(dev, 0L, DMGET));
Z! 		break;
Z! 	default:
Z! 		return (ENOTTY);
Z  	}
Z- 	return (0);
Z- }
Z  
Z  static long
Z  dmtodhu(bits)
Z  	register int bits;
Z! {
Z  	long b = 0;
Z  
Z! 	if (bits & DML_RTS) b |= DHU_RTS;
Z! 	if (bits & DML_DTR) b |= DHU_DTR;
Z! 	if (bits & DML_LE) b |= DHU_LE;
Z  	return(b);
Z! }
Z  
Z  static
Z  dhutodm(bits)
Z  	long bits;
Z! {
Z  	register int b = 0;
Z  
Z! 	if (bits & DHU_DSR) b |= DML_DSR;
Z! 	if (bits & DHU_RNG) b |= DML_RNG;
Z! 	if (bits & DHU_CAR) b |= DML_CAR;
Z! 	if (bits & DHU_CTS) b |= DML_CTS;
Z! 	if (bits & DHU_RTS) b |= DML_RTS;
Z! 	if (bits & DHU_DTR) b |= DML_DTR;
Z! 	if (bits & DHU_LE) b |= DML_LE;
Z  	return(b);
Z! }
Z  
Z  /*
Z   * Set parameters from open or stty into the DHU hardware
Z--- 353,428 ----
Z  
Z  	tp = &dhu_tty[unit];
Z  	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
Z! 	if	(error >= 0)
Z! 		return(error);
Z  	error = ttioctl(tp, cmd, data, flag);
Z! 	if	(error >= 0)
Z! 		{
Z! 		if	(cmd == TIOCSETP || cmd == TIOCSETN || 
Z! 			 cmd == TIOCLSET || cmd == TIOCLBIC || cmd == TIOCLBIS)
Z  			dhuparam(unit);
Z! 		return(error);
Z! 		}
Z  
Z! 	switch	(cmd)
Z! 		{
Z! 		case	TIOCSBRK:
Z! 			(void) dhumctl(unit, (long)DHU_BRK, DMBIS);
Z! 			break;
Z! 		case	TIOCCBRK:
Z! 			(void) dhumctl(unit, (long)DHU_BRK, DMBIC);
Z! 			break;
Z! 		case	TIOCSDTR:
Z! 			(void) dhumctl(unit, (long)DHU_DTR|DHU_RTS, DMBIS);
Z! 			break;
Z! 		case	TIOCCDTR:
Z! 			(void) dhumctl(unit, (long)DHU_DTR|DHU_RTS, DMBIC);
Z! 			break;
Z! 		case	TIOCMSET:
Z! 			(void) dhumctl(dev, dmtodhu(*(int *)data), DMSET);
Z! 			break;
Z! 		case	TIOCMBIS:
Z! 			(void) dhumctl(dev, dmtodhu(*(int *)data), DMBIS);
Z! 			break;
Z! 		case	TIOCMBIC:
Z! 			(void) dhumctl(dev, dmtodhu(*(int *)data), DMBIC);
Z! 			break;
Z! 		case	TIOCMGET:
Z! 			*(int *)data = dhutodm(dhumctl(dev, 0L, DMGET));
Z! 			break;
Z! 		default:
Z! 			return(ENOTTY);
Z! 		}
Z! 	return(0);
Z  	}
Z  
Z  static long
Z  dmtodhu(bits)
Z  	register int bits;
Z! 	{
Z  	long b = 0;
Z  
Z! 	if	(bits & TIOCM_RTS) b |= DHU_RTS;
Z! 	if	(bits & TIOCM_DTR) b |= DHU_DTR;
Z! 	if	(bits & TIOCM_LE) b |= DHU_LE;
Z  	return(b);
Z! 	}
Z  
Z  static
Z  dhutodm(bits)
Z  	long bits;
Z! 	{
Z  	register int b = 0;
Z  
Z! 	if	(bits & DHU_DSR) b |= TIOCM_DSR;
Z! 	if	(bits & DHU_RNG) b |= TIOCM_RNG;
Z! 	if	(bits & DHU_CAR) b |= TIOCM_CAR;
Z! 	if	(bits & DHU_CTS) b |= TIOCM_CTS;
Z! 	if	(bits & DHU_RTS) b |= TIOCM_RTS;
Z! 	if	(bits & DHU_DTR) b |= TIOCM_DTR;
Z! 	if	(bits & DHU_LE) b |= TIOCM_LE;
Z  	return(b);
Z! 	}
Z  
Z  /*
Z   * Set parameters from open or stty into the DHU hardware
Z***************
Z*** 413,419 ****
Z  static
Z  dhuparam(unit)
Z  	register int unit;
Z! {
Z  	register struct tty *tp;
Z  	register struct dhudevice *addr;
Z  	register int lpar;
Z--- 431,437 ----
Z  static
Z  dhuparam(unit)
Z  	register int unit;
Z! 	{
Z  	register struct tty *tp;
Z  	register struct dhudevice *addr;
Z  	register int lpar;
Z***************
Z*** 425,452 ****
Z  	 * Block interrupts so parameters will be set
Z  	 * before the line interrupts.
Z  	 */
Z! 	s = spl5();
Z! 	if ((tp->t_ispeed) == 0) {
Z  		tp->t_state |= TS_HUPCLS;
Z  		(void)dhumctl(unit, (long)DHU_OFF, DMSET);
Z! 		splx(s);
Z! 		return;
Z! 	}
Z  	lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8);
Z! 	if ((tp->t_ispeed) == B134)
Z  		lpar |= DHU_LP_BITS6|DHU_LP_PENABLE;
Z  	else if (tp->t_flags & (RAW|LITOUT|PASS8))
Z  		lpar |= DHU_LP_BITS8;
Z  	else
Z  		lpar |= DHU_LP_BITS7|DHU_LP_PENABLE;
Z! 	if (tp->t_flags&EVENP)
Z  		lpar |= DHU_LP_EPAR;
Z! 	if ((tp->t_ospeed) == B110)
Z  		lpar |= DHU_LP_TWOSB;
Z  	addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
Z  	addr->dhulpr = lpar;
Z  	splx(s);
Z! }
Z  
Z  /*
Z   * DHU11 transmitter interrupt.
Z--- 443,472 ----
Z  	 * Block interrupts so parameters will be set
Z  	 * before the line interrupts.
Z  	 */
Z! 	s = spltty();
Z! 	if	(tp->t_ispeed == 0)
Z! 		{
Z  		tp->t_state |= TS_HUPCLS;
Z  		(void)dhumctl(unit, (long)DHU_OFF, DMSET);
Z! 		goto out;
Z! 		}
Z  	lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8);
Z! 	if	((tp->t_ispeed) == B134)
Z  		lpar |= DHU_LP_BITS6|DHU_LP_PENABLE;
Z  	else if (tp->t_flags & (RAW|LITOUT|PASS8))
Z  		lpar |= DHU_LP_BITS8;
Z  	else
Z  		lpar |= DHU_LP_BITS7|DHU_LP_PENABLE;
Z! 	if	(tp->t_flags&EVENP)
Z  		lpar |= DHU_LP_EPAR;
Z! 	if	((tp->t_ospeed) == B110)
Z  		lpar |= DHU_LP_TWOSB;
Z  	addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
Z  	addr->dhulpr = lpar;
Z+ out:
Z  	splx(s);
Z! 	return;
Z! 	}
Z  
Z  /*
Z   * DHU11 transmitter interrupt.
Z***************
Z*** 455,465 ****
Z   */
Z  dhuxint(dhu)
Z  	int dhu;
Z! {
Z  	register struct tty *tp;
Z  	register struct dhudevice *addr;
Z! 	register struct tty *tp0;
Z! 	register struct uba_device *ui;
Z  	register int line, t;
Z  	u_short cntr;
Z  	ubadr_t	base;
Z--- 475,485 ----
Z   */
Z  dhuxint(dhu)
Z  	int dhu;
Z! 	{
Z  	register struct tty *tp;
Z  	register struct dhudevice *addr;
Z! 	struct tty *tp0;
Z! 	struct uba_device *ui;
Z  	register int line, t;
Z  	u_short cntr;
Z  	ubadr_t	base;
Z***************
Z*** 467,483 ****
Z  	ui = &dhuinfo[dhu];
Z  	tp0 = &dhu_tty[dhu<<4];
Z  	addr = (struct dhudevice *)ui->ui_addr;
Z! 	while ((t = addr->dhucsrh) & DHU_CSH_TI) {
Z  		line = DHU_TX_LINE(t);
Z  		tp = tp0 + line;
Z  		tp->t_state &= ~TS_BUSY;
Z! 		if (t & DHU_CSH_NXM) {
Z! 			printf("dhu(%d,%d): NXM fault\n", dhu, line);
Z  			/* SHOULD RESTART OR SOMETHING... */
Z! 		}
Z! 		if (tp->t_state&TS_FLUSH)
Z  			tp->t_state &= ~TS_FLUSH;
Z! 		else {
Z  			addr->dhucsrl = DHU_SELECT(line) | DHU_IE;
Z  			base = (ubadr_t) addr->dhubar1;
Z  			/*
Z--- 487,506 ----
Z  	ui = &dhuinfo[dhu];
Z  	tp0 = &dhu_tty[dhu<<4];
Z  	addr = (struct dhudevice *)ui->ui_addr;
Z! 	while	((t = addr->dhucsrh) & DHU_CSH_TI)
Z! 		{
Z  		line = DHU_TX_LINE(t);
Z  		tp = tp0 + line;
Z  		tp->t_state &= ~TS_BUSY;
Z! 		if	(t & DHU_CSH_NXM)
Z! 			{
Z! 			log(LOG_NOTICE, "dhu%d,%d NXM\n", dhu, line);
Z  			/* SHOULD RESTART OR SOMETHING... */
Z! 			}
Z! 		if	(tp->t_state&TS_FLUSH)
Z  			tp->t_state &= ~TS_FLUSH;
Z! 		else	
Z! 			{
Z  			addr->dhucsrl = DHU_SELECT(line) | DHU_IE;
Z  			base = (ubadr_t) addr->dhubar1;
Z  			/*
Z***************
Z*** 489,505 ****
Z  			 *
Z  			 * In either case, the extension bits are 0.
Z  			*/
Z! 			if (!ubmap)
Z  				base |= (ubadr_t)((addr->dhubar2 & 037) << 16);
Z  			cntr = base - cpaddr(tp->t_outq.c_cf);
Z! 			ndflush(&tp->t_outq,cntr);
Z! 		}
Z! 		if (tp->t_line)
Z  			(*linesw[tp->t_line].l_start)(tp);
Z  		else
Z  			dhustart(tp);
Z  	}
Z- }
Z  
Z  /*
Z   * Start (restart) transmission on the given DHU11 line.
Z--- 512,528 ----
Z  			 *
Z  			 * In either case, the extension bits are 0.
Z  			*/
Z! 			if	(!ubmap)
Z  				base |= (ubadr_t)((addr->dhubar2 & 037) << 16);
Z  			cntr = base - cpaddr(tp->t_outq.c_cf);
Z! 			ndflush(&tp->t_outq, cntr);
Z! 			}
Z! 		if	(tp->t_line)
Z  			(*linesw[tp->t_line].l_start)(tp);
Z  		else
Z  			dhustart(tp);
Z+ 		}
Z  	}
Z  
Z  /*
Z   * Start (restart) transmission on the given DHU11 line.
Z***************
Z*** 506,584 ****
Z   */
Z  dhustart(tp)
Z  	register struct tty *tp;
Z! {
Z  	register struct dhudevice *addr;
Z  	register int unit, nch;
Z  	ubadr_t car;
Z  	int s;
Z  
Z! 	unit = minor(tp->t_dev);
Z! 	unit &= 0xf;
Z  	addr = (struct dhudevice *)tp->t_addr;
Z  
Z  	/*
Z- 	 * Must hold interrupts in following code to prevent
Z- 	 * state of the tp from changing.
Z- 	 */
Z- 	s = spl5();
Z- 	/*
Z  	 * If it's currently active, or delaying, no need to do anything.
Z  	 */
Z! 	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
Z  		goto out;
Z  	/*
Z  	 * If there are sleepers, and output has drained below low
Z  	 * water mark, wake up the sleepers..
Z  	 */
Z! 	if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
Z! 		if (tp->t_state&TS_ASLEEP) {
Z! 			tp->t_state &= ~TS_ASLEEP;
Z! 			wakeup((caddr_t)&tp->t_outq);
Z! 		}
Z! 		if (tp->t_wsel) {
Z! 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
Z! 			tp->t_wsel = 0;
Z! 			tp->t_state &= ~TS_WCOLL;
Z! 		}
Z! 	}
Z  	/*
Z  	 * Now restart transmission unless the output queue is
Z  	 * empty.
Z  	 */
Z! 	if (tp->t_outq.c_cc == 0)
Z  		goto out;
Z! 	if (tp->t_flags & (RAW|LITOUT))
Z! 		nch = ndqb(&tp->t_outq, 0);
Z! 	else {
Z! 		nch = ndqb(&tp->t_outq, 0200);
Z! 		/*
Z! 		 * If first thing on queue is a delay process it.
Z! 		 */
Z! 		if (nch == 0) {
Z! 			nch = getc(&tp->t_outq);
Z! 			timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
Z! 			tp->t_state |= TS_TIMEOUT;
Z! 			goto out;
Z  		}
Z! 	}
Z  	/*
Z  	 * If characters to transmit, restart transmission.
Z  	 */
Z! 	if (nch) {
Z  		car = cpaddr(tp->t_outq.c_cf);
Z  		addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
Z  		addr->dhulcr &= ~DHU_LC_TXABORT;
Z  		addr->dhubcr = nch;
Z  		addr->dhubar1 = loint(car);
Z! 		if (ubmap)
Z  			addr->dhubar2 = (hiint(car) & DHU_BA2_XBA) | DHU_BA2_DMAGO;
Z  		else
Z  			addr->dhubar2 = (hiint(car) & 037) | DHU_BA2_DMAGO;
Z  		tp->t_state |= TS_BUSY;
Z! 	}
Z  out:
Z  	splx(s);
Z! }
Z  
Z  /*
Z   * Stop output on a line, e.g. for ^S/^Q or output flush.
Z--- 529,597 ----
Z   */
Z  dhustart(tp)
Z  	register struct tty *tp;
Z! 	{
Z  	register struct dhudevice *addr;
Z  	register int unit, nch;
Z  	ubadr_t car;
Z  	int s;
Z  
Z! 	unit = UNIT(tp->t_dev);
Z  	addr = (struct dhudevice *)tp->t_addr;
Z  
Z+ 	s = spltty();
Z  	/*
Z  	 * If it's currently active, or delaying, no need to do anything.
Z  	 */
Z! 	if	(tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
Z  		goto out;
Z  	/*
Z  	 * If there are sleepers, and output has drained below low
Z  	 * water mark, wake up the sleepers..
Z  	 */
Z! 	ttyowake(tp);
Z! 
Z  	/*
Z  	 * Now restart transmission unless the output queue is
Z  	 * empty.
Z  	 */
Z! 	if	(tp->t_outq.c_cc == 0)
Z  		goto out;
Z! 	addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
Z! /*
Z!  * If CTS is off and we're doing hardware flow control then mark the output
Z!  * as stopped and do not transmit anything.
Z! */
Z! 	if	((addr->dhustat & DHU_ST_CTS) == 0 && (tp->t_flags & RTSCTS))
Z! 		{
Z! 		tp->t_state |= TS_TTSTOP;
Z! 		goto out;
Z  		}
Z! /*
Z!  * This is where any per character delay handling for special characters 
Z!  * would go if ever implemented again.  The call to ndqb would be replaced
Z!  * with a scan for special characters and then the appropriate sleep/wakeup
Z!  * done.
Z! */
Z! 	nch = ndqb(&tp->t_outq, 0);
Z  	/*
Z  	 * If characters to transmit, restart transmission.
Z  	 */
Z! 	if	(nch)
Z! 		{
Z  		car = cpaddr(tp->t_outq.c_cf);
Z  		addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
Z  		addr->dhulcr &= ~DHU_LC_TXABORT;
Z  		addr->dhubcr = nch;
Z  		addr->dhubar1 = loint(car);
Z! 		if	(ubmap)
Z  			addr->dhubar2 = (hiint(car) & DHU_BA2_XBA) | DHU_BA2_DMAGO;
Z  		else
Z  			addr->dhubar2 = (hiint(car) & 037) | DHU_BA2_DMAGO;
Z  		tp->t_state |= TS_BUSY;
Z! 		}
Z  out:
Z  	splx(s);
Z! 	}
Z  
Z  /*
Z   * Stop output on a line, e.g. for ^S/^Q or output flush.
Z***************
Z*** 586,592 ****
Z  /*ARGSUSED*/
Z  dhustop(tp, flag)
Z  	register struct tty *tp;
Z! {
Z  	register struct dhudevice *addr;
Z  	register int unit, s;
Z  
Z--- 599,605 ----
Z  /*ARGSUSED*/
Z  dhustop(tp, flag)
Z  	register struct tty *tp;
Z! 	{
Z  	register struct dhudevice *addr;
Z  	register int unit, s;
Z  
Z***************
Z*** 594,601 ****
Z  	/*
Z  	 * Block input/output interrupts while messing with state.
Z  	 */
Z! 	s = spl5();
Z! 	if (tp->t_state & TS_BUSY) {
Z  		/*
Z  		 * Device is transmitting; stop output
Z  		 * by selecting the line and setting the
Z--- 607,615 ----
Z  	/*
Z  	 * Block input/output interrupts while messing with state.
Z  	 */
Z! 	s = spltty();
Z! 	if	(tp->t_state & TS_BUSY)
Z! 		{
Z  		/*
Z  		 * Device is transmitting; stop output
Z  		 * by selecting the line and setting the
Z***************
Z*** 605,618 ****
Z  		 * TS_FLUSH is set, the outq will be flushed.
Z  		 * In either case, dhustart will clear the TXABORT bit.
Z  		 */
Z! 		unit = minor(tp->t_dev);
Z  		addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
Z  		addr->dhulcr |= DHU_LC_TXABORT;
Z! 		if ((tp->t_state&TS_TTSTOP)==0)
Z  			tp->t_state |= TS_FLUSH;
Z! 	}
Z  	(void) splx(s);
Z! }
Z  
Z  /*
Z   * DHU11 modem control
Z--- 619,632 ----
Z  		 * TS_FLUSH is set, the outq will be flushed.
Z  		 * In either case, dhustart will clear the TXABORT bit.
Z  		 */
Z! 		unit = UNIT(tp->t_dev);
Z  		addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
Z  		addr->dhulcr |= DHU_LC_TXABORT;
Z! 		if	((tp->t_state&TS_TTSTOP)==0)
Z  			tp->t_state |= TS_FLUSH;
Z! 		}
Z  	(void) splx(s);
Z! 	}
Z  
Z  /*
Z   * DHU11 modem control
Z***************
Z*** 622,663 ****
Z  	dev_t dev;
Z  	long bits;
Z  	int how;
Z! {
Z  	register struct dhudevice *dhuaddr;
Z! 	register int unit;
Z  	long mbits;
Z  	int s;
Z  
Z  	unit = UNIT(dev);
Z  	dhuaddr = (struct dhudevice *)(dhu_tty[unit].t_addr);
Z! 	unit &= 0xf;
Z! 	s = spl5();
Z! 	dhuaddr->dhucsr = DHU_SELECT(unit) | DHU_IE;
Z  	/*
Z  	 * combine byte from stat register (read only, bits 16..23)
Z  	 * with lcr register (read write, bits 0..15).
Z  	 */
Z  	mbits = (u_short)dhuaddr->dhulcr | ((long)dhuaddr->dhustat << 16);
Z! 	switch (how) {
Z! 
Z! 	case DMSET:
Z! 		mbits = (mbits & 0xff0000L) | bits;
Z! 		break;
Z! 
Z! 	case DMBIS:
Z! 		mbits |= bits;
Z! 		break;
Z! 
Z! 	case DMBIC:
Z! 		mbits &= ~bits;
Z! 		break;
Z! 
Z! 	case DMGET:
Z! 		(void) splx(s);
Z! 		return(mbits);
Z! 	}
Z! 	dhuaddr->dhulcr = (mbits & 0xffff) | DHU_LC_RXEN;
Z  	dhuaddr->dhulcr2 = DHU_LC2_TXEN;
Z  	(void) splx(s);
Z  	return(mbits);
Z  }
Z--- 636,674 ----
Z  	dev_t dev;
Z  	long bits;
Z  	int how;
Z! 	{
Z  	register struct dhudevice *dhuaddr;
Z! 	register int unit, line;
Z  	long mbits;
Z  	int s;
Z  
Z  	unit = UNIT(dev);
Z  	dhuaddr = (struct dhudevice *)(dhu_tty[unit].t_addr);
Z! 	line = unit & 0xf;
Z! 	s = spltty();
Z! 	dhuaddr->dhucsr = DHU_SELECT(line) | DHU_IE;
Z  	/*
Z  	 * combine byte from stat register (read only, bits 16..23)
Z  	 * with lcr register (read write, bits 0..15).
Z  	 */
Z  	mbits = (u_short)dhuaddr->dhulcr | ((long)dhuaddr->dhustat << 16);
Z! 	switch	(how)
Z! 		{
Z! 		case	DMSET:
Z! 			mbits = (mbits & 0xff0000L) | bits;
Z! 			break;
Z! 		case	DMBIS:
Z! 			mbits |= bits;
Z! 			break;
Z! 		case	DMBIC:
Z! 			mbits &= ~bits;
Z! 			break;
Z! 		case	DMGET:
Z! 			goto out;
Z! 		}
Z! 	dhuaddr->dhulcr = (mbits & 0xffffL) | DHU_LC_RXEN;
Z  	dhuaddr->dhulcr2 = DHU_LC2_TXEN;
Z+ out:
Z  	(void) splx(s);
Z  	return(mbits);
Z  }
Z*** /usr/src/sys/pdpuba/dhv.c.old	Fri May  2 20:03:42 1997
Z--- /usr/src/sys/pdpuba/dhv.c	Sat May 31 16:15:26 1997
Z***************
Z*** 3,9 ****
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dhv.c	2.3 (2.11BSD 2.11BSD) 1997/5/1
Z   */
Z  
Z  /*
Z--- 3,9 ----
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dhv.c	2.4 (2.11BSD 2.11BSD) 1997/5/31
Z   */
Z  
Z  /*
Z***************
Z*** 202,209 ****
Z  
Z  	unit = UNIT(dev);
Z  	tp = &dhv_tty[unit];
Z! 	if	(!(tp->t_state & TS_ISOPEN))
Z! 		return;
Z  	(*linesw[tp->t_line].l_close)(tp, flag);
Z  	(void) dhvmctl(unit, (long)DHV_BRK, DMBIC);
Z  	(void) dhvmctl(unit, (long)DHV_OFF, DMSET);
Z--- 202,209 ----
Z  
Z  	unit = UNIT(dev);
Z  	tp = &dhv_tty[unit];
Z! 	if	(!(tp->t_state & (TS_WOPEN|TS_ISOPEN)))
Z! 		return(0);
Z  	(*linesw[tp->t_line].l_close)(tp, flag);
Z  	(void) dhvmctl(unit, (long)DHV_BRK, DMBIC);
Z  	(void) dhvmctl(unit, (long)DHV_OFF, DMSET);
Z***************
Z*** 281,287 ****
Z  			if	(c & DHV_RB_DIAG)
Z  				{
Z  				if	((c & 0xff) > 0201)
Z! 					printf ("dhv%d: diag %o\n",dhv, c&0xff);
Z  			    	continue;
Z  				}
Z  			if	(!(tp->t_dev & SOFTCAR) || 
Z--- 281,287 ----
Z  			if	(c & DHV_RB_DIAG)
Z  				{
Z  				if	((c & 0xff) > 0201)
Z! 					log(LOG_NOTICE,"dhv%d diag %o\n",dhv, c&0xff);
Z  			    	continue;
Z  				}
Z  			if	(!(tp->t_dev & SOFTCAR) || 
Z***************
Z*** 533,539 ****
Z  		tp->t_state &= ~TS_BUSY;
Z  		if	(t & DHV_CSH_NXM)
Z  			{
Z! 			printf("dhv(%d,%d) NXM\n", dhv, line);
Z  			/* SHOULD RESTART OR SOMETHING... */
Z  			}
Z  		if	(tp->t_state&TS_FLUSH)
Z--- 533,539 ----
Z  		tp->t_state &= ~TS_BUSY;
Z  		if	(t & DHV_CSH_NXM)
Z  			{
Z! 			log(LOG_NOTICE, "dhv%d,%d NXM\n", dhv, line);
Z  			/* SHOULD RESTART OR SOMETHING... */
Z  			}
Z  		if	(tp->t_state&TS_FLUSH)
Z*** /usr/src/sys/pdpuba/dh.c.old	Sun Feb 16 18:48:24 1997
Z--- /usr/src/sys/pdpuba/dh.c	Thu Jun 12 21:37:55 1997
Z***************
Z*** 3,9 ****
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dh.c	1.4 (2.11BSD GTE) 1997/2/14
Z   */
Z  
Z  /*
Z--- 3,9 ----
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)dh.c	1.5 (2.11BSD GTE) 1997/6/12
Z   */
Z  
Z  /*
Z***************
Z*** 37,49 ****
Z  struct	uba_device dhinfo[NDH];
Z  struct	uba_device dminfo[NDH];
Z  
Z- #ifndef	PORTSELECTOR
Z- #define	ISPEED	B9600
Z  #define	IFLAGS	(EVENP|ODDP|ECHO)
Z- #else
Z- #define	ISPEED	B4800
Z- #define	IFLAGS	(EVENP|ODDP)
Z- #endif
Z  
Z  /*
Z   * Use 2 ticks rather than doing a divide of 'hz' by 30.  The old method
Z--- 37,43 ----
Z***************
Z*** 56,64 ****
Z   * Local variables for the driver
Z   */
Z  short	dhsar[NDH];			/* software copy of last bar */
Z- short	dhsoftCAR[NDH];
Z  
Z  struct	tty dh11[NDH*16];
Z  int	ndh11	= NDH*16;
Z  int	dhact;				/* mask of active dh's */
Z  int	dhsilos;			/* mask of dh's with silo in use */
Z--- 50,60 ----
Z   * Local variables for the driver
Z   */
Z  short	dhsar[NDH];			/* software copy of last bar */
Z  
Z  struct	tty dh11[NDH*16];
Z+ u_int	dh_overrun[NDH*16];		/* count of silo overruns, cleared on
Z+ 					 * close.
Z+ 					 */
Z  int	ndh11	= NDH*16;
Z  int	dhact;				/* mask of active dh's */
Z  int	dhsilos;			/* mask of dh's with silo in use */
Z***************
Z*** 67,73 ****
Z  int	dhhighrate = 100;		/* silo on if dhchars > dhhighrate */
Z  int	dhlowrate = 75;			/* silo off if dhrate < dhlowrate */
Z  static short timerstarted;
Z! int	dhstart(), ttrstrt();
Z  
Z  #if defined(UCB_CLIST)
Z  extern	ubadr_t	clstaddr;
Z--- 63,70 ----
Z  int	dhhighrate = 100;		/* silo on if dhchars > dhhighrate */
Z  int	dhlowrate = 75;			/* silo off if dhrate < dhlowrate */
Z  static short timerstarted;
Z! int	dhstart();
Z! static	int	dmtodh(), dhtodm();
Z  
Z  #if defined(UCB_CLIST)
Z  extern	ubadr_t	clstaddr;
Z***************
Z*** 76,82 ****
Z  #define	cpaddr(x)	(x)
Z  #endif
Z  
Z! #define	UNIT(x)	(minor(x) & 0177)
Z  
Z  /*
Z   * Routine called to attach a dh.
Z--- 73,81 ----
Z  #define	cpaddr(x)	(x)
Z  #endif
Z  
Z! #define	UNIT(x)	(x & 0x3f)
Z! #define	SOFTCAR	0x80
Z! #define	HWFLOW	0x40
Z  
Z  /*
Z   * Routine called to attach a dh.
Z***************
Z*** 116,220 ****
Z  
Z  /*
Z   * Open a DH11 line.  Turn on this dh if this is
Z!  * the first use of it.  Also do a dmopen to wait for carrier.
Z   */
Z  /*ARGSUSED*/
Z  dhopen(dev, flag)
Z  	dev_t dev;
Z! {
Z  	register struct tty *tp;
Z- 	register int unit, dh;
Z  	register struct dhdevice *addr;
Z! 	register struct uba_device *ui;
Z! 	int s;
Z  
Z  	unit = UNIT(dev);
Z  	dh = unit >> 4;
Z! 	if (unit >= NDH*16 || (ui = &dhinfo[dh])->ui_alive == 0)
Z! 		return (ENXIO);
Z  	tp = &dh11[unit];
Z- 	if (tp->t_state&TS_XCLUDE && u.u_uid!=0)
Z- 		return (EBUSY);
Z  	addr = (struct dhdevice *)ui->ui_addr;
Z  	tp->t_addr = (caddr_t)addr;
Z  	tp->t_oproc = dhstart;
Z- 	tp->t_state |= TS_WOPEN;
Z  
Z! 	/*
Z! 	 * While setting up state for this uba and this dh,
Z! 	 * block uba resets which can clear the state.
Z! 	 */
Z! 	s = spl5();
Z! 	if (timerstarted == 0) {
Z  		timerstarted++;
Z  		timeout(dhtimer, (caddr_t) 0, hz);
Z! 	}
Z! 	if ((dhact&(1<<dh)) == 0) {
Z  		addr->un.dhcsr |= DH_IE;
Z  		dhact |= (1<<dh);
Z  		addr->dhsilo = 0;
Z! 	}
Z! 	splx(s);
Z! 	/*
Z! 	 * If this is first open, initialize tty state to default.
Z! 	 */
Z! 	if ((tp->t_state&TS_ISOPEN) == 0) {
Z! 		ttychars(tp);
Z! #ifndef PORTSELECTOR
Z! 		if (tp->t_ispeed == 0) {
Z! #else
Z  			tp->t_state |= TS_HUPCLS;
Z! #endif PORTSELECTOR
Z! 			tp->t_ispeed = ISPEED;
Z! 			tp->t_ospeed = ISPEED;
Z  			tp->t_flags = IFLAGS;
Z! #ifndef PORTSELECTOR
Z! 		}
Z! #endif
Z  		dhparam(unit);
Z! 	}
Z  	dmopen(dev);
Z! 	return ((*linesw[tp->t_line].l_open)(dev, tp));
Z! }
Z  
Z  /*
Z   * Close a DH line, turning off the DM11.
Z   */
Z- /*ARGSUSED*/
Z  dhclose(dev, flag)
Z! 	dev_t dev;
Z! 	int flag;
Z! {
Z  	register struct tty *tp;
Z! 	register unit;
Z  
Z  	unit = UNIT(dev);
Z  	tp = &dh11[unit];
Z  	(*linesw[tp->t_line].l_close)(tp, flag);
Z  	((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
Z! 	if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0)
Z! 		dmctl(unit, DML_OFF, DMSET);
Z  	ttyclose(tp);
Z! }
Z  
Z  dhread(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z  	int flag;
Z! {
Z  	register struct tty *tp = &dh11[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
Z! }
Z  
Z  dhwrite(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z! {
Z  	register struct tty *tp = &dh11[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
Z! }
Z  
Z  /*
Z   * DH11 receiver interrupt.
Z--- 115,241 ----
Z  
Z  /*
Z   * Open a DH11 line.  Turn on this dh if this is
Z!  * the first use of it.
Z   */
Z  /*ARGSUSED*/
Z  dhopen(dev, flag)
Z  	dev_t dev;
Z! 	{
Z  	register struct tty *tp;
Z  	register struct dhdevice *addr;
Z! 	register int unit;
Z! 	struct	uba_device *ui;
Z! 	int	dh, s, error;
Z  
Z  	unit = UNIT(dev);
Z  	dh = unit >> 4;
Z! 	if	(unit >= NDH*16 || (ui = &dhinfo[dh])->ui_alive == 0)
Z! 		return(ENXIO);
Z  	tp = &dh11[unit];
Z  	addr = (struct dhdevice *)ui->ui_addr;
Z  	tp->t_addr = (caddr_t)addr;
Z  	tp->t_oproc = dhstart;
Z  
Z! 	if	(timerstarted == 0)
Z! 		{
Z  		timerstarted++;
Z  		timeout(dhtimer, (caddr_t) 0, hz);
Z! 		}
Z! 	if	((dhact&(1<<dh)) == 0)
Z! 		{
Z  		addr->un.dhcsr |= DH_IE;
Z  		dhact |= (1<<dh);
Z  		addr->dhsilo = 0;
Z! 		}
Z! 	s = spltty();
Z! 	if	((tp->t_state & TS_ISOPEN) == 0)
Z! 		{
Z! 		tp->t_state |= TS_WOPEN;
Z! 		if	(tp->t_ispeed == 0)
Z! 			{
Z  			tp->t_state |= TS_HUPCLS;
Z! 			tp->t_ispeed = B9600;
Z! 			tp->t_ospeed = B9600;
Z  			tp->t_flags = IFLAGS;
Z! 			}
Z! 		ttychars(tp);
Z! 		tp->t_dev = dev;
Z! 		if	(dev & HWFLOW)
Z! 			tp->t_flags |= RTSCTS;
Z! 		else
Z! 			tp->t_flags &= ~RTSCTS;
Z  		dhparam(unit);
Z! 		}
Z! 	else if	((tp->t_state & TS_XCLUDE) && u.u_uid)
Z! 		{
Z! 		error = EBUSY;
Z! 		goto out;
Z! 		}
Z  	dmopen(dev);
Z! 	if	((dmctl(unit, 0, DMGET) & DML_CAR) || (dev & SOFTCAR))
Z! 		tp->t_state |= TS_CARR_ON;
Z! 	while	((tp->t_state & TS_CARR_ON) == 0 && !(flag & O_NONBLOCK))
Z! 		{
Z! 		tp->t_state |= TS_WOPEN;
Z! 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
Z! 		}
Z! 	error = (*linesw[tp->t_line].l_open)(dev, tp);
Z! out:
Z! 	splx(s);
Z! 	return(error);
Z! 	}
Z  
Z  /*
Z   * Close a DH line, turning off the DM11.
Z   */
Z  dhclose(dev, flag)
Z! 	dev_t	dev;
Z! 	int	flag;
Z! 	{
Z  	register struct tty *tp;
Z! 	register int	unit;
Z  
Z  	unit = UNIT(dev);
Z  	tp = &dh11[unit];
Z+ 	if	((tp->t_state & (TS_WOPEN | TS_ISOPEN)) == 0)
Z+ 		return(EBADF);		/* XXX */
Z  	(*linesw[tp->t_line].l_close)(tp, flag);
Z  	((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
Z! 	dmctl(unit, DML_OFF, DMSET);
Z  	ttyclose(tp);
Z! 	if	(dh_overrun[unit])
Z! 		{
Z! 		log(LOG_NOTICE, "dh%d %d overruns\n", dh_overrun[unit]);
Z! 		dh_overrun[unit] = 0;
Z! 		}
Z! 	return(0);
Z! 	}
Z  
Z+ dhselect(dev, rw)
Z+ 	dev_t	dev;
Z+ 	int	rw;
Z+ 	{
Z+ 	return(ttyselect(&dh11[UNIT(dev)], rw));
Z+ 	}
Z+ 
Z  dhread(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z  	int flag;
Z! 	{
Z  	register struct tty *tp = &dh11[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
Z! 	}
Z  
Z  dhwrite(dev, uio, flag)
Z  	dev_t dev;
Z  	struct uio *uio;
Z! 	{
Z  	register struct tty *tp = &dh11[UNIT(dev)];
Z  
Z  	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
Z! 	}
Z  
Z  /*
Z   * DH11 receiver interrupt.
Z***************
Z*** 226,238 ****
Z  	register int c;
Z  	register struct dhdevice *addr;
Z  	struct tty *tp0;
Z! 	struct uba_device *ui;
Z! 	int overrun = 0;
Z  
Z! 	ui = &dhinfo[dh];
Z! 	if (ui == 0 || ui->ui_alive == 0)
Z  		return;
Z- 	addr = (struct dhdevice *)ui->ui_addr;
Z  	tp0 = &dh11[dh<<4];
Z  	/*
Z  	 * Loop fetching characters from the silo for this
Z--- 247,257 ----
Z  	register int c;
Z  	register struct dhdevice *addr;
Z  	struct tty *tp0;
Z! 	int	line, p;
Z  
Z! 	addr = (struct dhdevice *)dhinfo[dh].ui_addr;
Z! 	if	(addr == 0)		/* Can't happen? */
Z  		return;
Z  	tp0 = &dh11[dh<<4];
Z  	/*
Z  	 * Loop fetching characters from the silo for this
Z***************
Z*** 239,261 ****
Z  	 * dh until there are no more in the silo.
Z  	 */
Z  	while ((c = addr->dhrcr) < 0) {
Z! 		tp = tp0 + ((c>>8)&0xf);
Z  		dhchars[dh]++;
Z  		if ((tp->t_state&TS_ISOPEN)==0) {
Z  			wakeup((caddr_t)&tp->t_rawq);
Z- #ifdef PORTSELECTOR
Z- 			if ((tp->t_state&TS_WOPEN) == 0)
Z- #endif
Z  			continue;
Z  		}
Z! 		if (c & DH_PE)
Z! 			if ((tp->t_flags & (EVENP|ODDP)) == EVENP
Z! 			 || (tp->t_flags & (EVENP|ODDP)) == ODDP)
Z  				continue;
Z! 		if ((c & DH_DO) && overrun == 0) {
Z! 			log(LOG_WARNING, "dh%d: silo overflow\n", dh);
Z! 			overrun = 1;
Z! 		}
Z  		if (c & DH_FE)
Z  			/*
Z  			 * At framing error (break) generate
Z--- 258,281 ----
Z  	 * dh until there are no more in the silo.
Z  	 */
Z  	while ((c = addr->dhrcr) < 0) {
Z! 		line = (c >> 8) & 0xf;
Z! 		tp = tp0 + line;
Z  		dhchars[dh]++;
Z  		if ((tp->t_state&TS_ISOPEN)==0) {
Z  			wakeup((caddr_t)&tp->t_rawq);
Z  			continue;
Z  		}
Z! 		if	(c & DH_PE)
Z! 			{
Z! 			p =  tp->t_flags & (EVENP|ODDP);
Z! 			if	(p == EVENP || p == ODDP)
Z  				continue;
Z! 			}
Z! 		if	(c & DH_DO)
Z! 			{
Z! 			dh_overrun[(dh << 4) + line]++;
Z! 			continue;
Z! 			}
Z  		if (c & DH_FE)
Z  			/*
Z  			 * At framing error (break) generate
Z***************
Z*** 285,331 ****
Z   */
Z  /*ARGSUSED*/
Z  dhioctl(dev, cmd, data, flag)
Z  	u_int cmd;
Z  	caddr_t data;
Z! {
Z  	register struct tty *tp;
Z  	register unit = UNIT(dev);
Z! 	int error;
Z  
Z  	tp = &dh11[unit];
Z  	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
Z! 	if (error >= 0)
Z! 		return (error);
Z  	error = ttioctl(tp, cmd, data, flag);
Z! 	if (error >= 0) {
Z! 		if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS ||
Z! 		    cmd == TIOCLBIC || cmd == TIOCLSET)
Z  			dhparam(unit);
Z! 		return (error);
Z  	}
Z- 	switch (cmd) {
Z  
Z! 	case TIOCSBRK:
Z! 		((struct dhdevice *)(tp->t_addr))->dhbreak |= 1<<(unit&017);
Z! 		break;
Z  
Z! 	case TIOCCBRK:
Z! 		((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
Z! 		break;
Z  
Z! 	case TIOCSDTR:
Z! 		dmctl (unit, DML_DTR|DML_RTS, DMBIS);
Z! 		break;
Z  
Z! 	case TIOCCDTR:
Z! 		dmctl (unit, DML_DTR|DML_RTS, DMBIC);
Z! 		break;
Z! 
Z! 	default:
Z! 		return (ENOTTY);
Z  	}
Z- 	return (0);
Z- }
Z  
Z  /*
Z   * Set parameters from open or stty into the DH hardware
Z--- 305,390 ----
Z   */
Z  /*ARGSUSED*/
Z  dhioctl(dev, cmd, data, flag)
Z+ 	dev_t	dev;
Z  	u_int cmd;
Z  	caddr_t data;
Z! 	int	flag;
Z! 	{
Z  	register struct tty *tp;
Z  	register unit = UNIT(dev);
Z! 	int	error, brkline;
Z  
Z  	tp = &dh11[unit];
Z  	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
Z! 	if	(error >= 0)
Z! 		return(error);
Z  	error = ttioctl(tp, cmd, data, flag);
Z! 	if	(error >= 0)
Z! 		{
Z! 		if	(cmd == TIOCSETP || cmd == TIOCSETN || 
Z! 			 cmd == TIOCLBIS || cmd == TIOCLBIC || cmd == TIOCLSET)
Z  			dhparam(unit);
Z! 		return(error);
Z! 		}
Z! 	brkline = 1 << (unit & 0xf);
Z! 	switch	(cmd)
Z! 		{
Z! 		case	TIOCSBRK:
Z! 			((struct dhdevice *)(tp->t_addr))->dhbreak |= brkline;
Z! 			break;
Z! 		case	TIOCCBRK:
Z! 			((struct dhdevice *)(tp->t_addr))->dhbreak &= ~brkline;
Z! 			break;
Z! 		case	TIOCSDTR:
Z! 			(void)dmctl(unit, DML_DTR|DML_RTS, DMBIS);
Z! 			break;
Z! 		case	TIOCCDTR:
Z! 			(void)dmctl(unit, DML_DTR|DML_RTS, DMBIC);
Z! 			break;
Z! 		case	TIOCMSET:
Z! 			(void)dmctl(unit, dmtodh(*(int *)data, DMSET));
Z! 			break;
Z! 		case	TIOCMBIS:
Z! 			(void)dmctl(unit, dmtodh(*(int *)data, DMBIS));
Z! 			break;
Z! 		case	TIOCMBIC:
Z! 			(void)dmctl(unit, dmtodh(*(int *)data, DMBIC));
Z! 			break;
Z! 		case	TIOCMGET:
Z! 			*(int *)data = dhtodm(dmctl(unit, 0, DMGET));
Z! 			break;
Z! 		default:
Z! 			return(ENOTTY);
Z! 		}
Z! 	return(0);
Z  	}
Z  
Z! static	int
Z! dmtodh(bits)
Z! 	register int bits;
Z! 	{
Z! 	register int	b = 0;
Z  
Z! 	if	(bits & TIOCM_RTS) b |= DML_RTS;
Z! 	if	(bits & TIOCM_DTR) b |= DML_DTR;
Z! 	if	(bits & TIOCM_LE) b |= DML_LE;
Z! 	return(b);
Z! 	}
Z  
Z! static	int
Z! dhtodm(bits)
Z! 	register int bits;
Z! 	{
Z! 	register int b = 0;
Z  
Z! 	if	(bits & DML_RNG) b |= TIOCM_RNG;
Z! 	if	(bits & DML_CAR) b |= TIOCM_CAR;
Z! 	if	(bits & DML_CTS) b |= TIOCM_CTS;
Z! 	if	(bits & DML_RTS) b |= TIOCM_RTS;
Z! 	if	(bits & DML_DTR) b |= TIOCM_DTR;
Z! 	if	(bits & DML_LE)  b |= TIOCM_LE;
Z! 	return(b);
Z  	}
Z  
Z  /*
Z   * Set parameters from open or stty into the DH hardware
Z***************
Z*** 333,339 ****
Z   */
Z  dhparam(unit)
Z  	register int unit;
Z! {
Z  	register struct tty *tp;
Z  	register struct dhdevice *addr;
Z  	register int lpar;
Z--- 392,398 ----
Z   */
Z  dhparam(unit)
Z  	register int unit;
Z! 	{
Z  	register struct tty *tp;
Z  	register struct dhdevice *addr;
Z  	register int lpar;
Z***************
Z*** 345,358 ****
Z  	 * Block interrupts so parameters will be set
Z  	 * before the line interrupts.
Z  	 */
Z! 	s = spl5();
Z  	addr->un.dhcsrl = (unit&0xf)|DH_IE;
Z! 	if ((tp->t_ispeed)==0) {
Z  		tp->t_state |= TS_HUPCLS;
Z  		dmctl(unit, DML_OFF, DMSET);
Z! 		splx(s);
Z! 		return;
Z! 	}
Z  	lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
Z  	if ((tp->t_ispeed) == B134)
Z  		lpar |= BITS6|PENABLE|HDUPLX;
Z--- 404,417 ----
Z  	 * Block interrupts so parameters will be set
Z  	 * before the line interrupts.
Z  	 */
Z! 	s = spltty();
Z  	addr->un.dhcsrl = (unit&0xf)|DH_IE;
Z! 	if	((tp->t_ispeed)==0)
Z! 		{
Z  		tp->t_state |= TS_HUPCLS;
Z  		dmctl(unit, DML_OFF, DMSET);
Z! 		goto out;
Z! 		}
Z  	lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
Z  	if ((tp->t_ispeed) == B134)
Z  		lpar |= BITS6|PENABLE|HDUPLX;
Z***************
Z*** 365,372 ****
Z  	if ((tp->t_ospeed) == B110)
Z  		lpar |= TWOSB;
Z  	addr->dhlpr = lpar;
Z  	splx(s);
Z! }
Z  
Z  /*
Z   * DH transmitter interrupt.
Z--- 424,433 ----
Z  	if ((tp->t_ospeed) == B110)
Z  		lpar |= TWOSB;
Z  	addr->dhlpr = lpar;
Z+ out:
Z  	splx(s);
Z! 	return(0);
Z! 	}
Z  
Z  /*
Z   * DH transmitter interrupt.
Z***************
Z*** 379,395 ****
Z  	register struct tty *tp;
Z  	register struct dhdevice *addr;
Z  	short ttybit, bar, *sbar;
Z- 	struct uba_device *ui;
Z  	register int unit;
Z  	u_short cntr;
Z  	ubadr_t car;
Z  	struct dmdevice *dmaddr;
Z  
Z! 	ui = &dhinfo[dh];
Z! 	addr = (struct dhdevice *)ui->ui_addr;
Z  	if (addr->un.dhcsr & DH_NXM) {
Z  		addr->un.dhcsr |= DH_CNI;
Z! 		printf("dh%d:  NXM\n", dh);
Z  	}
Z  	sbar = &dhsar[dh];
Z  	bar = *sbar & ~addr->dhbar;
Z--- 440,454 ----
Z  	register struct tty *tp;
Z  	register struct dhdevice *addr;
Z  	short ttybit, bar, *sbar;
Z  	register int unit;
Z  	u_short cntr;
Z  	ubadr_t car;
Z  	struct dmdevice *dmaddr;
Z  
Z! 	addr = (struct dhdevice *)dhinfo[dh].ui_addr;
Z  	if (addr->un.dhcsr & DH_NXM) {
Z  		addr->un.dhcsr |= DH_CNI;
Z! 		log(LOG_NOTICE, "dh%d NXM\n", dh);
Z  	}
Z  	sbar = &dhsar[dh];
Z  	bar = *sbar & ~addr->dhbar;
Z***************
Z*** 414,420 ****
Z  				 *
Z  				 * In either case, the extension bits are 0.
Z  				 */
Z! 				car = (caddr_t)addr->dhcar;
Z  				if (!ubmap) {
Z  #if defined(CS02)
Z  					dmaddr = (struct dmdevice *)dminfo[dh].ui_addr;
Z--- 473,479 ----
Z  				 *
Z  				 * In either case, the extension bits are 0.
Z  				 */
Z! 				car = (ubadr_t)addr->dhcar;
Z  				if (!ubmap) {
Z  #if defined(CS02)
Z  					dmaddr = (struct dmdevice *)dminfo[dh].ui_addr;
Z***************
Z*** 456,502 ****
Z  	 * Must hold interrupts in following code to prevent
Z  	 * state of the tp from changing.
Z  	 */
Z! 	s = spl5();
Z  	/*
Z  	 * If it's currently active, or delaying, no need to do anything.
Z  	 */
Z  	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
Z  		goto out;
Z  	/*
Z- 	 * If there are sleepers, and the output has drained below low
Z- 	 * water mark, wake up the sleepers.
Z- 	 */
Z- 	if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
Z- 		if (tp->t_state&TS_ASLEEP) {
Z- 			tp->t_state &= ~TS_ASLEEP;
Z- 				wakeup((caddr_t)&tp->t_outq);
Z- 		}
Z- 		if (tp->t_wsel) {
Z- 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
Z- 			tp->t_wsel = 0;
Z- 			tp->t_state &= ~TS_WCOLL;
Z- 		}
Z- 	}
Z- 	/*
Z  	 * Now restart transmission unless the output queue is
Z  	 * empty.
Z  	 */
Z  	if (tp->t_outq.c_cc == 0)
Z  		goto out;
Z! 	if (tp->t_flags & (RAW|LITOUT))
Z! 		nch = ndqb(&tp->t_outq, 0);
Z! 	else {
Z! 		nch = ndqb(&tp->t_outq, 0200);
Z! 		/*
Z! 		 * If first thing on queue is a delay, process it.
Z! 		 */
Z! 		if (nch == 0) {
Z! 			nch = getc(&tp->t_outq);
Z! 			timeout(ttrstrt, (caddr_t) tp, (nch&0x7f)+6);
Z! 			tp->t_state |= TS_TIMEOUT;
Z! 			goto out;
Z! 		}
Z! 	}
Z  	/*
Z  	 * If characters to transmit, restart transmission.
Z  	 */
Z--- 515,538 ----
Z  	 * Must hold interrupts in following code to prevent
Z  	 * state of the tp from changing.
Z  	 */
Z! 	s = spltty();
Z  	/*
Z  	 * If it's currently active, or delaying, no need to do anything.
Z  	 */
Z  	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
Z  		goto out;
Z+ 	ttyowake(tp);		/* Wake up any sleepers */
Z  	/*
Z  	 * Now restart transmission unless the output queue is
Z  	 * empty.
Z  	 */
Z  	if (tp->t_outq.c_cc == 0)
Z  		goto out;
Z! /*
Z!  * This is where any per character delay handling would be done if ever
Z!  * implemented again.  See the comments in dhv.c and dhu.c
Z! */
Z! 	nch = ndqb(&tp->t_outq, 0);
Z  	/*
Z  	 * If characters to transmit, restart transmission.
Z  	 */
Z***************
Z*** 542,548 ****
Z  	/*
Z  	 * Block input/output interrupts while messing with state.
Z  	 */
Z! 	s = spl5();
Z  	if (tp->t_state & TS_BUSY) {
Z  		/*
Z  		 * Device is transmitting; stop output
Z--- 578,584 ----
Z  	/*
Z  	 * Block input/output interrupts while messing with state.
Z  	 */
Z! 	s = spltty();
Z  	if (tp->t_state & TS_BUSY) {
Z  		/*
Z  		 * Device is transmitting; stop output
Z***************
Z*** 574,580 ****
Z  	if (dhsilos) {
Z  		dhfasttimers++;		/*DEBUG*/
Z  		timercalls++;
Z! 		s = spl5();
Z  		for (dh = 0; dh < NDH; dh++)
Z  			if (dhsilos & (1 << dh))
Z  				dhrint(dh);
Z--- 610,616 ----
Z  	if (dhsilos) {
Z  		dhfasttimers++;		/*DEBUG*/
Z  		timercalls++;
Z! 		s = spltty();
Z  		for (dh = 0; dh < NDH; dh++)
Z  			if (dhsilos & (1 << dh))
Z  				dhrint(dh);
Z***************
Z*** 607,646 ****
Z   */
Z  dmopen(dev)
Z  	dev_t dev;
Z! {
Z  	register struct tty *tp;
Z  	register struct dmdevice *addr;
Z- 	register struct uba_device *ui;
Z  	register int unit;
Z! 	register int dm;
Z! 	int s;
Z  
Z  	unit = UNIT(dev);
Z  	dm = unit >> 4;
Z  	tp = &dh11[unit];
Z! 	unit &= 0xf;
Z! 	if (dev & 0200)
Z! 		dhsoftCAR[dm] |= (1<<(unit&0xf));
Z! 	else
Z! 		dhsoftCAR[dm] &= ~(1<<(unit&0xf));
Z! 	if (dm >= NDH || (ui = &dminfo[dm])->ui_alive == 0) {
Z  		tp->t_state |= TS_CARR_ON;
Z  		return;
Z  	}
Z- 	addr = (struct dmdevice *)ui->ui_addr;
Z- 	s = spl5();
Z- 	addr->dmcsr &= ~DM_SE;
Z- 	while (addr->dmcsr & DM_BUSY)
Z- 		;
Z- 	addr->dmcsr = unit & 017;
Z- 	addr->dmlstat = DML_ON;
Z- 	if ((addr->dmlstat&DML_CAR) || (dhsoftCAR[dm]&(1<<unit)))
Z- 		tp->t_state |= TS_CARR_ON;
Z- 	addr->dmcsr = DM_IE|DM_SE;
Z- 	while ((tp->t_state & TS_CARR_ON)==0)
Z- 		sleep((caddr_t) &tp->t_rawq, TTIPRI);
Z- 	splx(s);
Z- }
Z  
Z  /*
Z   * Dump control bits into the DM registers.
Z--- 643,664 ----
Z   */
Z  dmopen(dev)
Z  	dev_t dev;
Z! 	{
Z  	register struct tty *tp;
Z  	register struct dmdevice *addr;
Z  	register int unit;
Z! 	int	dm;
Z  
Z  	unit = UNIT(dev);
Z  	dm = unit >> 4;
Z  	tp = &dh11[unit];
Z! 	if	(dm >= NDH || dminfo[dm].ui_alive == 0)
Z! 		{
Z  		tp->t_state |= TS_CARR_ON;
Z  		return;
Z+ 		}
Z+ 	(void)dmctl(unit, DML_ON, DMSET);
Z  	}
Z  
Z  /*
Z   * Dump control bits into the DM registers.
Z***************
Z*** 648,689 ****
Z  dmctl(unit, bits, how)
Z  	int unit;
Z  	int bits, how;
Z! {
Z! 	register struct uba_device *ui;
Z  	register struct dmdevice *addr;
Z! 	register s;
Z! 	int dm;
Z  
Z  	dm = unit >> 4;
Z! 	if ((ui = &dminfo[dm])->ui_alive == 0)
Z! 		return;
Z! 	addr = (struct dmdevice *)ui->ui_addr;
Z! 	s = spl5();
Z  	addr->dmcsr &= ~DM_SE;
Z! 	while (addr->dmcsr & DM_BUSY)
Z  		;
Z  	addr->dmcsr = unit & 0xf;
Z! 	switch (how) {
Z! 	case DMSET:
Z! 		addr->dmlstat = bits;
Z! 		break;
Z! 	case DMBIS:
Z! 		addr->dmlstat |= bits;
Z! 		break;
Z! 	case DMBIC:
Z! 		addr->dmlstat &= ~bits;
Z! 		break;
Z! 	}
Z  	addr->dmcsr = DM_IE|DM_SE;
Z  	splx(s);
Z! }
Z  
Z  /*
Z   * DM interrupt; deal with carrier transitions.
Z   */
Z  dmintr(dm)
Z! 	register int dm;
Z! {
Z  	register struct uba_device *ui;
Z  	register struct tty *tp;
Z  	register struct dmdevice *addr;
Z--- 666,713 ----
Z  dmctl(unit, bits, how)
Z  	int unit;
Z  	int bits, how;
Z! 	{
Z  	register struct dmdevice *addr;
Z! 	register int s, mbits;
Z! 	int	dm;
Z  
Z  	dm = unit >> 4;
Z! 	addr = (struct dmdevice *)dminfo[dm].ui_addr;
Z! 	if	(!addr)
Z! 		return(0);
Z! 	s = spltty();
Z  	addr->dmcsr &= ~DM_SE;
Z! 	while	(addr->dmcsr & DM_BUSY)
Z  		;
Z  	addr->dmcsr = unit & 0xf;
Z! 	mbits = addr->dmlstat;
Z! 
Z! 	switch	(how)
Z! 		{
Z! 		case	DMGET:
Z! 			break;		/* go re-enable scan */
Z! 		case	DMSET:
Z! 			mbits = bits;
Z! 			break;
Z! 		case	DMBIS:
Z! 			mbits |= bits;
Z! 			break;
Z! 		case	DMBIC:
Z! 			mbits &= ~bits;
Z! 			break;
Z! 		}
Z! 	addr->dmlstat = mbits;
Z  	addr->dmcsr = DM_IE|DM_SE;
Z  	splx(s);
Z! 	return(mbits);
Z! 	}
Z  
Z  /*
Z   * DM interrupt; deal with carrier transitions.
Z   */
Z  dmintr(dm)
Z! 	int	dm;
Z! 	{
Z  	register struct uba_device *ui;
Z  	register struct tty *tp;
Z  	register struct dmdevice *addr;
Z***************
Z*** 690,709 ****
Z  	int unit;
Z  
Z  	ui = &dminfo[dm];
Z- 	if (ui == 0)
Z- 		return;
Z  	addr = (struct dmdevice *)ui->ui_addr;
Z! 	if (addr->dmcsr&DM_DONE) {
Z! 		if (addr->dmcsr&DM_CF) {
Z! 			unit = addr->dmcsr & 0xf;
Z! 			tp = &dh11[(dm << 4) + unit];
Z! 			if (addr->dmlstat & DML_CAR)
Z! 				(void)(*linesw[tp->t_line].l_modem)(tp, 1);
Z! 			else if ((dhsoftCAR[dm] & (1<<unit)) == 0 &&
Z! 			    (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
Z! 				addr->dmlstat = 0;
Z  		}
Z! 		addr->dmcsr = DM_IE|DM_SE;
Z  	}
Z- }
Z  #endif
Z--- 714,748 ----
Z  	int unit;
Z  
Z  	ui = &dminfo[dm];
Z  	addr = (struct dmdevice *)ui->ui_addr;
Z! 	if	(addr->dmcsr&DM_DONE == 0)
Z! 		return;
Z! 	unit = addr->dmcsr & 0xf;
Z! 	tp = &dh11[(dm << 4) + unit];
Z! 	if	(addr->dmcsr & DM_CF)
Z! 		{
Z! 		if	(addr->dmlstat & DML_CAR)
Z! 			(void)(*linesw[tp->t_line].l_modem)(tp, 1);
Z! 		else if (!(tp->t_dev & SOFTCAR) &&
Z! 			  (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
Z! 			addr->dmlstat = 0;
Z  		}
Z! 	if	(addr->dmcsr & DM_CTS)
Z! 		{
Z! 		if	(tp->t_flags & RTSCTS)
Z! 			{
Z! 			if	(addr->dmlstat & DML_CTS)
Z! 				{
Z! 				tp->t_state &= ~TS_TTSTOP;
Z! 				ttstart(tp);
Z! 				}
Z! 			else
Z! 				{
Z! 				tp->t_state |= TS_TTSTOP;
Z! 				dhstop(tp, 0);
Z! 				}
Z! 			}
Z! 		}
Z! 	addr->dmcsr = DM_IE|DM_SE;
Z  	}
Z  #endif
Z*** /usr/src/sys/pdp/conf.c.old	Fri Jan 31 20:49:43 1997
Z--- /usr/src/sys/pdp/conf.c	Sat May 31 14:38:53 1997
Z***************
Z*** 3,9 ****
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)conf.c	3.0 (2.11BSD GTE) 1997/1/30
Z   */
Z  
Z  #include "param.h"
Z--- 3,9 ----
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)conf.c	3.1 (2.11BSD GTE) 1997/5/31
Z   */
Z  
Z  #include "param.h"
Z***************
Z*** 230,235 ****
Z--- 230,236 ----
Z  #include "dh.h"
Z  #if NDH > 0
Z  int	dhopen(), dhclose(), dhread(), dhwrite(), dhioctl(), dhstop();
Z+ int	dhselect();
Z  extern struct tty	dh11[];
Z  #else
Z  #define	dhopen		nodev
Z***************
Z*** 238,243 ****
Z--- 239,245 ----
Z  #define	dhwrite		nodev
Z  #define	dhioctl		nodev
Z  #define	dhstop		nodev
Z+ #define	dhselect	nodev
Z  #define	dh11		((struct tty *) NULL)
Z  #endif
Z  
Z***************
Z*** 290,295 ****
Z--- 292,298 ----
Z  #include "dhu.h"
Z  #if NDHU > 0
Z  int	dhuopen(), dhuclose(), dhuread(), dhuwrite(), dhuioctl(), dhustop();
Z+ int	dhuselect();
Z  extern struct tty	dhu_tty[];
Z  #else
Z  #define	dhuopen		nodev
Z***************
Z*** 298,303 ****
Z--- 301,307 ----
Z  #define	dhuwrite	nodev
Z  #define	dhuioctl	nodev
Z  #define	dhustop		nodev
Z+ #define	dhuselect	nodev
Z  #define	dhu_tty		((struct tty *) NULL)
Z  #endif
Z  
Z***************
Z*** 368,378 ****
Z  	nulldev,
Z  /* dh = 3 */
Z  	dhopen,		dhclose,	dhread,		dhwrite,
Z! 	dhioctl,	dhstop,		dh11,		ttselect,
Z  	nulldev,
Z  /* dhu = 4 */
Z  	dhuopen,	dhuclose,	dhuread,	dhuwrite,
Z! 	dhuioctl,	dhustop,	dhu_tty,	ttselect,
Z  	nulldev,
Z  /* lp = 5 */
Z  	lpopen,		lpclose,	nodev,		lpwrite,
Z--- 372,382 ----
Z  	nulldev,
Z  /* dh = 3 */
Z  	dhopen,		dhclose,	dhread,		dhwrite,
Z! 	dhioctl,	dhstop,		dh11,		dhselect,
Z  	nulldev,
Z  /* dhu = 4 */
Z  	dhuopen,	dhuclose,	dhuread,	dhuwrite,
Z! 	dhuioctl,	dhustop,	dhu_tty,	dhuselect,
Z  	nulldev,
Z  /* lp = 5 */
Z  	lpopen,		lpclose,	nodev,		lpwrite,
Z*** /usr/src/man/man4/dhu.4.old	Sat Aug  1 11:31:31 1987
Z--- /usr/src/man/man4/dhu.4	Sat May 31 16:18:25 1997
Z***************
Z*** 2,10 ****
Z  .\" All rights reserved.  The Berkeley software License Agreement
Z  .\" specifies the terms and conditions for redistribution.
Z  .\"
Z! .\"	@(#)dhu.4	6.2 (Berkeley) 8/1/87
Z  .\"
Z! .TH DHU 4 "August 1, 1987"
Z  .UC 2
Z  .SH NAME
Z  dhu \- DHU-11 communications multiplexer
Z--- 2,10 ----
Z  .\" All rights reserved.  The Berkeley software License Agreement
Z  .\" specifies the terms and conditions for redistribution.
Z  .\"
Z! .\"	@(#)dhu.4	6.2.1 (2.11BSD) 1997/5/31
Z  .\"
Z! .TH DHU 4 "May 31, 1997"
Z  .UC 2
Z  .SH NAME
Z  dhu \- DHU-11 communications multiplexer
Z***************
Z*** 12,23 ****
Z  .ft B
Z  .nf
Z  /sys/conf/SYSTEM:
Z! 	NDHU	\fIdhu_units\fP	# DHU11, DHV11
Z  
Z  /etc/dtab:
Z  .ta .5i +\w'#Name 'u +\w'Unit# 'u +\w'177777 'u +\w'Vector 'u +\w'Br 'u +\w'xxxxxxx 'u +\w'xxxxxxx 'u
Z  	#Name	Unit#	Addr	Vector	Br	Handler(s)		# Comments
Z! 	du	?	160020	310	5	dhurint	dhuxint	# dhv/dhu11 terminal mux
Z  .DT
Z  
Z  major device number(s):
Z--- 12,23 ----
Z  .ft B
Z  .nf
Z  /sys/conf/SYSTEM:
Z! 	NDHU	\fIdhu_units\fP	# DHU11
Z  
Z  /etc/dtab:
Z  .ta .5i +\w'#Name 'u +\w'Unit# 'u +\w'177777 'u +\w'Vector 'u +\w'Br 'u +\w'xxxxxxx 'u +\w'xxxxxxx 'u
Z  	#Name	Unit#	Addr	Vector	Br	Handler(s)		# Comments
Z! 	du	?	160020	310	5	dhurint	dhuxint	# dhu11 terminal mux
Z  .DT
Z  
Z  major device number(s):
Z***************
Z*** 24,30 ****
Z  	raw: 4
Z  minor device encoding:
Z  	bits 0017 specify line on DHU unit
Z! 	bits 0160 specify DHU unit
Z  	bit  0200 specifies non-blocking open (``CD always on'')
Z  .fi
Z  .ft R
Z--- 24,31 ----
Z  	raw: 4
Z  minor device encoding:
Z  	bits 0017 specify line on DHU unit
Z! 	bits 0060 specify DHU unit
Z! 	bit  0100 specify RTS/CTS flow control
Z  	bit  0200 specifies non-blocking open (``CD always on'')
Z  .fi
Z  .ft R
Z***************
Z*** 47,53 ****
Z  connected, and that the line should be treated as hard-wired with carrier
Z  always present.  Thus creating the special character device node "4, 130" via
Z  .I "mknod /dev/ttyS2 c 4 130"
Z! would cause line ttyS2 to be treated in this way.
Z  .PP
Z  The DHU-11 driver normally uses input silos
Z  and delays receiver interrupts by 20 milliseconds
Z--- 48,57 ----
Z  connected, and that the line should be treated as hard-wired with carrier
Z  always present.  Thus creating the special character device node "4, 130" via
Z  .I "mknod /dev/ttyS2 c 4 130"
Z! would cause line ttyS2 to be treated in this way.  Turning on bit 6 (adding
Z! 64) to the minor device number via
Z! .I "mknod /dev/ttyS2 c 4 194"
Z! enables RTS/CTS flow control.
Z  .PP
Z  The DHU-11 driver normally uses input silos
Z  and delays receiver interrupts by 20 milliseconds
Z***************
Z*** 57,72 ****
Z  .SH "SEE ALSO"
Z  tty(4)
Z  .SH DIAGNOSTICS
Z! \fBdhu(%d,%d): NXM fault\fR.  No response from UNIBUS on a DMA transfer
Z! within a timeout period.  This is often followed by a UNIBUS adapter
Z! error.  This occurs most frequently when the UNIBUS is heavily loaded
Z! and when devices which hog the bus (such as RK07s) are present.
Z  It is not serious.
Z  .PP
Z! \fBdhu%d: silo overflow\fR.  The character input silo overflowed
Z! before it could be serviced.  This can happen if a hard error occurs
Z! when the CPU is running with elevated priority, as the system may
Z! then print a message on the console with interrupts disabled.
Z  .SH NOTES
Z  The driver currently does not make full use of the hardware
Z  capabilities of the DHU-11, for dealing with XON/XOFF flow-control or hard-wired
Z--- 61,75 ----
Z  .SH "SEE ALSO"
Z  tty(4)
Z  .SH DIAGNOSTICS
Z! \fBdhu(%d,%d) NXM\fR.  No response from UNIBUS on a DMA transfer
Z! within a timeout period.  This has never been observed on a PDP-11 and is
Z! believed to be a carryover from the VAX driver when it was ported.
Z  It is not serious.
Z  .PP
Z! \fBdhu%d %d overruns\fR.  The character input silo overflowed
Z! before it could be serviced.  This message is printed only at line close time
Z! rather than on each overrun error.  Kernel printf's are not interrupt driven
Z! and caused more overruns by blocking interrupts for lengthy periods of time.
Z  .SH NOTES
Z  The driver currently does not make full use of the hardware
Z  capabilities of the DHU-11, for dealing with XON/XOFF flow-control or hard-wired
Z*** /usr/src/man/man4/dh.4.old	Thu Jul 23 20:29:11 1992
Z--- /usr/src/man/man4/dh.4	Sat May 31 16:25:08 1997
Z***************
Z*** 2,10 ****
Z  .\" All rights reserved.  The Berkeley software License Agreement
Z  .\" specifies the terms and conditions for redistribution.
Z  .\"
Z! .\"	@(#)dh.4	6.3 (Berkeley) 7/23/92
Z  .\"
Z! .TH DH 4 "January 28, 1988"
Z  .UC 2
Z  .SH NAME
Z  dh \- DH-11/DM-11 communications multiplexer
Z--- 2,10 ----
Z  .\" All rights reserved.  The Berkeley software License Agreement
Z  .\" specifies the terms and conditions for redistribution.
Z  .\"
Z! .\"	@(#)dh.4	6.4 (2.11BSD) 1997/5/31
Z  .\"
Z! .TH DH 4 "May 31, 1997"
Z  .UC 2
Z  .SH NAME
Z  dh \- DH-11/DM-11 communications multiplexer
Z***************
Z*** 27,33 ****
Z  minor device encoding:
Z  	bits 0017 specify line on DH unit
Z  	bits 0060 specify DH unit
Z! 	bit  0100 unused
Z  	bit  0200 specifies non-blocking open (``CD always on'')
Z  .fi
Z  .ft R
Z--- 27,33 ----
Z  minor device encoding:
Z  	bits 0017 specify line on DH unit
Z  	bits 0060 specify DH unit
Z! 	bit  0100 specify RTS/CTS (``hardware'') flowcontrol
Z  	bit  0200 specifies non-blocking open (``CD always on'')
Z  .fi
Z  .ft R
Z***************
Z*** 53,59 ****
Z  connected, and that the line should be treated as hard-wired with carrier
Z  always present.  Thus creating the special character device node "3, 130" via
Z  .I "mknod /dev/ttyh2 c 3 130"
Z! would cause line ttyh2 to be treated in this way.
Z  .PP
Z  The
Z  .I dh
Z--- 53,63 ----
Z  connected, and that the line should be treated as hard-wired with carrier
Z  always present.  Thus creating the special character device node "3, 130" via
Z  .I "mknod /dev/ttyh2 c 3 130"
Z! would cause line ttyh2 to be treated in this way.  Bit
Z! .I 0100
Z! of the minor device number enables RTS/CTS (also called ``hardware'') flow
Z! control. It is enabled by adding 64 to the minor device number:
Z! .I "mknod /dev/ttyh2 c 3 194"
Z  .PP
Z  The
Z  .I dh
Z***************
Z*** 77,90 ****
Z  dtab(5),
Z  autoconfig(8)
Z  .SH DIAGNOSTICS
Z! \fBdh%d: NXM\fR.  No response from UNIBUS on a dma transfer
Z! within a timeout period.  This is often followed by a UNIBUS adapter
Z! error.  This occurs most frequently when the UNIBUS is heavily loaded
Z! and when devices which hog the bus (such as rk07's) are present.
Z  It is not serious.
Z  .PP
Z! \fBdh%d: silo overflow\fR.  The character input silo overflowed
Z! before it could be serviced.  This can happen if a hard error occurs
Z! when the CPU is running with elevated priority, as the system will
Z! then print a message on the console with interrupts disabled.
Z! It is not serious.
Z--- 81,92 ----
Z  dtab(5),
Z  autoconfig(8)
Z  .SH DIAGNOSTICS
Z! \fBdh%d NXM\fR.  No response from UNIBUS on a dma transfer
Z! within a timeout period.  This has never been observed on a PDP-11 and is
Z! a carryover from the VAX driver when it was ported.
Z  It is not serious.
Z  .PP
Z! \fBdh%d %d overruns\fR.  The character input silo overflowed
Z! before it could be serviced.  This message is only printed at line close time.
Z! It is not serious but does indicate that the system was not able to keep up
Z! with the data flow.
Z*** /usr/src/man/man4/Makefile.old	Tue Feb  4 21:03:04 1997
Z--- /usr/src/man/man4/Makefile	Sat May 31 16:11:07 1997
Z***************
Z*** 14,29 ****
Z  # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
Z  # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Z  #
Z! #	@(#)Makefile	5.4.2 (2.11BSD) 1997/2/4
Z  #
Z  DESTDIR=
Z  MDIR=	${DESTDIR}/usr/man/cat4
Z! SRCS=	acc.4 arp.4 bk.4 br.4 cons.4 css.4 de.4 dh.4 dhu.4 dmc.4 dr.4 dz.4  \
Z  	ec.4 en.4 fd.4 hk.4 ht.4 hy.4 icmp.4 idp.4 il.4 imp.4 impconf.4 inet.4 \
Z  	intro.4 ip.4 lo.4 lp.4 mem.4 mtio.4 networking.4 ns.4 nsip.4 \
Z  	null.4 pty.4 qe.4 ra.4 ram.4 rk.4 rl.4 rx.4 si.4 spp.4 sri.4 \
Z  	swap.4 tb.4 tcp.4 tm.4 tmscp.4 ts.4 tty.4 udp.4 vv.4 xp.4
Z! OBJS=	acc.0 arp.0 bk.0 br.0 cons.0 css.0 de.0 dh.0 dhu.0 dmc.0 dr.0 \
Z  	dz.0 ec.0 en.0 fd.0 hk.0 ht.0 hy.0 icmp.0 idp.0 il.0 imp.0 impconf.0 \
Z  	inet.0 intro.0 ip.0 lo.0 lp.0 mem.0 mtio.0 networking.0 ns.0 \
Z  	nsip.0 null.0 pty.0 qe.0 ra.0 ram.0 rk.0 rl.0 rx.0 si.0 spp.0 \
Z--- 14,31 ----
Z  # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
Z  # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Z  #
Z! #	@(#)Makefile	5.4.3 (2.11BSD) 1997/5/31
Z  #
Z  DESTDIR=
Z  MDIR=	${DESTDIR}/usr/man/cat4
Z! SRCS=	acc.4 arp.4 bk.4 br.4 cons.4 css.4 de.4 dh.4 dhu.4 dhv.4 \
Z! 	dmc.4 dr.4 dz.4  \
Z  	ec.4 en.4 fd.4 hk.4 ht.4 hy.4 icmp.4 idp.4 il.4 imp.4 impconf.4 inet.4 \
Z  	intro.4 ip.4 lo.4 lp.4 mem.4 mtio.4 networking.4 ns.4 nsip.4 \
Z  	null.4 pty.4 qe.4 ra.4 ram.4 rk.4 rl.4 rx.4 si.4 spp.4 sri.4 \
Z  	swap.4 tb.4 tcp.4 tm.4 tmscp.4 ts.4 tty.4 udp.4 vv.4 xp.4
Z! OBJS=	acc.0 arp.0 bk.0 br.0 cons.0 css.0 de.0 dh.0 dhu.0 dhv.0 \
Z! 	dmc.0 dr.0 \
Z  	dz.0 ec.0 en.0 fd.0 hk.0 ht.0 hy.0 icmp.0 idp.0 il.0 imp.0 impconf.0 \
Z  	inet.0 intro.0 ip.0 lo.0 lp.0 mem.0 mtio.0 networking.0 ns.0 \
Z  	nsip.0 null.0 pty.0 qe.0 ra.0 ram.0 rk.0 rl.0 rx.0 si.0 spp.0 \
Z*** /VERSION.old	Fri May  9 21:57:12 1997
Z--- /VERSION	Sat May 31 16:40:01 1997
Z***************
Z*** 1,5 ****
Z! Current Patch Level: 373
Z! Date: May 9, 1997
Z  
Z  2.11 BSD
Z  ============
Z--- 1,5 ----
Z! Current Patch Level: 374
Z! Date: May 31, 1997
Z  
Z  2.11 BSD
Z  ============
SHAR_EOF
fi
if test -f '374.shar'
then
	echo shar: "will not over-write existing file '374.shar'"
else
sed 's/^Z//' << \SHAR_EOF > '374.shar'
Z#! /bin/sh
Z# This is a shell archive, meaning:
Z# 1. Remove everything above the #! /bin/sh line.
Z# 2. Save the resulting text in a file.
Z# 3. Execute the file with /bin/sh (not csh) to create:
Z#	/usr/src/man/man4/dhv.4
Z# This archive created: Thu Jun 12 22:25:54 1997
Zexport PATH; PATH=/bin:/usr/bin:$PATH
Zif test -f '/usr/src/man/man4/dhv.4'
Zthen
Z	echo shar: "will not over-write existing file '/usr/src/man/man4/dhv.4'"
Zelse
Zsed 's/^J//' << \SHAR_EOF > '/usr/src/man/man4/dhv.4'
ZJ.\"
ZJ.\"	@(#)dhv.4	1.0 (2.11BSD) 1997/5/31
ZJ.\"
ZJ.TH DHV 4 "May 31, 1997"
ZJ.UC 2
ZJ.SH NAME
ZJdhv \- DHV-11 communications multiplexer
ZJ.SH SYNOPSIS
ZJ.ft B
ZJ.nf
ZJ/sys/conf/SYSTEM:
ZJ	NDHV	\fIdhv_units\fP	# DHV11
ZJ
ZJ/etc/dtab:
ZJ.ta .5i +\w'#Name 'u +\w'Unit# 'u +\w'177777 'u +\w'Vector 'u +\w'Br 'u +\w'xxxxxxx 'u +\w'xxxxxxx 'u
ZJ	#Name	Unit#	Addr	Vector	Br	Handler(s)		# Comments
ZJ	dhv	?	160440	310	5	dhvrint	dhvxint	# dhv terminal mux
ZJ.DT
ZJ
ZJmajor device number(s):
ZJ	raw: 24
ZJminor device encoding:
ZJ	bits 0007 specify line on DHV unit
ZJ	bits 0070 specify DHV unit
ZJ	bit  0100 specifies RTS/CTS (``hardware'') flowcontrol
ZJ	bit  0200 specifies non-blocking open (``CD always on'')
ZJ.fi
ZJ.ft R
ZJ.SH DESCRIPTION
ZJA DHV-11 provides 8 communication lines.
ZJ.PP
ZJEach line attached to the DHV-11 communications multiplexer
ZJbehaves as described in
ZJ.IR tty (4).
ZJInput and output for each line may independently
ZJbe set to run at any of 13 speeds (50 and 200 baud are not available).  While
ZJ38400 is available the underlying hardware is not fast enough to handle it and
ZJthere will be pauses/gaps between characters.
ZJ.PP
ZJBit
ZJ.I 0200
ZJof the minor device number for DHV lines
ZJmay be set to say that a line is not properly
ZJconnected, and that the line should be treated as hard-wired with carrier
ZJalways present.  Thus creating the special character device node "4, 130" via
ZJ.I "mknod /dev/ttyS2 c 4 130"
ZJwould cause line ttyS2 to be treated in this way.  Turning on bit 6 in the
ZJminor device number via
ZJ.I "mknod /dev/ttyS2 c 4 194"
ZJwould enable RTS/CTS flow control.
ZJ.PP
ZJThe DHV-11 has an input silo but does \fBnot\fP have the programmable
ZJreceiver delay that the DHU (and DHQ) have.  Thus system services more
ZJinterrupts (i.e. gets fewer characters per interrupt on average) with a
ZJDHV-11 than with a DHQ (in DHU mode).
ZJ.SH FILES
ZJ/dev/tty[S-Z][0-9a-f]
ZJ.SH "SEE ALSO"
ZJtty(4)
ZJ.SH DIAGNOSTICS
ZJ\fBdhv%d,%d NXM\fR.  No response from QBUS on a DMA transfer
ZJwithin a timeout period.  This error has never been observed on a PDP-11 and
ZJis a carryover from the VAX driver when that was ported to 2BSD.
ZJ.PP
ZJ\fBdhv%d diag %o\fR.  Diagnostic information from the DHV11.  This has never
ZJbeen observed.  The DHV-11 hardware manual will be required to decode the 
ZJvalue printed out.
ZJ.PP
ZJ\fBdhv%d: %d overruns\fR.  The character input silo overflowed
ZJbefore it could be serviced.  This message is printed only when the line is
ZJclosed.  By only printing this when the line is closed further silo overruns 
ZJare avoided (kernel printf statements are not interrupt driven).
ZJ.SH NOTES
ZJThe DHV lacks the receiver delay that the DHU (and DHQ) have.  Thus it is 
ZJextremely easy (indeed it's almost certain at higher data rates) for a 
ZJDHV-11 to enter an interrupt per character mode and use 70-80% of the cpu.
ZSHAR_EOF
Zchmod 444 '/usr/src/man/man4/dhv.4'
Zfi
Zexit 0
Z#	End of shell archive
SHAR_EOF
fi
exit 0
#	End of shell archive