*** /old/src/sys/pdpstand/tmscp.c	Wed Dec 19 10:18:53 1990
--- /usr/src/sys/pdpstand/tmscp.c	Sun Apr 21 00:21:54 1991
***************
*** 26,35 ****
   */
   
  /* static char *sccsid = "@(#)tmscp.c	1.5	(ULTRIX) 4/18/86"; */
!  
  /* ------------------------------------------------------------------------
   * Modification History: /sys/pdpstand/tmscp.c
   *
   * 8-20-90 steven m. schultz (sms@wlv.imsd.contel.com)
   *	Port from 4.3BSD to 2.11BSD
   * 3-15-85  afd
--- 26,36 ----
   */
   
  /* static char *sccsid = "@(#)tmscp.c	1.5	(ULTRIX) 4/18/86"; */
! 
  /* ------------------------------------------------------------------------
   * Modification History: /sys/pdpstand/tmscp.c
   *
+  * 4-20-91 sms - add multi controller and unit support (sms)
   * 8-20-90 steven m. schultz (sms@wlv.imsd.contel.com)
   *	Port from 4.3BSD to 2.11BSD
   * 3-15-85  afd
***************
*** 44,50 ****
  #include "../h/param.h"
  #include "../h/inode.h"
  #include "saio.h"
!  
  /*
   * Parameters for the communications area
   * (Only 1 cmd & 1 rsp packet)
--- 45,51 ----
  #include "../h/param.h"
  #include "../h/inode.h"
  #include "saio.h"
! 
  /*
   * Parameters for the communications area
   * (Only 1 cmd & 1 rsp packet)
***************
*** 53,76 ****
  #define	NCMDL2	0
  #define	NRSP	(1<<NRSPL2)
  #define	NCMD	(1<<NCMDL2)
!  
  #include "../pdpuba/tmscpreg.h"
  #include "../pdp/tmscp.h"
  
! struct tmscpdevice *tmscpaddr = (struct tmscpdevice *)0174500;
   
  struct tmscp {
  	struct tmscpca	tmscp_ca;
  	struct mscp	tmscp_rsp;
  	struct mscp	tmscp_cmd;
! 	} tmscp;
   
! struct mscp *tmscpcmd();
   
- int tmsoffline = 1;		/* Flag to prevent multiple STCON */
- u_char tms_offline[4] = {1,1,1,1}; /* Flag to prevent multiple ONLIN */
- static char opnmsg[] = "tmscpopen: step %d not successful sa=0%o\n";
-  
  extern int tapemark;		/* flag to indicate tapemark encountered
  				   (see sys.c as to how it's used) */
   
--- 54,84 ----
  #define	NCMDL2	0
  #define	NRSP	(1<<NRSPL2)
  #define	NCMD	(1<<NCMDL2)
! 
  #include "../pdpuba/tmscpreg.h"
  #include "../pdp/tmscp.h"
  
! #define	NTMS	2
! #define	TMSDENS(dev) ((minor(dev) >> 3) & 3)	/* unused for now */
! 
! 	struct	tmscpdevice *TMScsr[NTMS + 1] =
! 		{
! 		(struct tmscpdevice *)0174500,
! 		(struct tmscpdevice *)0,
! 		(struct tmscpdevice *)-1
! 		};
   
  struct tmscp {
  	struct tmscpca	tmscp_ca;
  	struct mscp	tmscp_rsp;
  	struct mscp	tmscp_cmd;
! 	} tmscp[NTMS];
   
! u_char tmsoffline[NTMS] = {1, 1};	/* Flag to prevent multiple STCON */
! u_char tms_offline[NTMS][4] = {{1,1,1,1},
! 			       {1,1,1,1}}; /* Flag to prevent multiple ONLIN */
! static char opnmsg[] = "tms%d: step %d failed sa=0%o\n";
   
  extern int tapemark;		/* flag to indicate tapemark encountered
  				   (see sys.c as to how it's used) */
   
***************
*** 80,92 ****
  tmscpopen(io)
  	register struct iob *io;
  {
! 	register struct mscp *mp;
   
  	/*
  	 * Have the tmscp controller characteristics already been set up
  	 * (STCON)?
  	 */
! 	if (tmsoffline)
  		{
  		/*
  		 * Initialize the tmscp device and wait for the 4 steps
--- 88,106 ----
  tmscpopen(io)
  	register struct iob *io;
  {
! 	register struct tmscpdevice *tmscpaddr;
! 	int ctlr = CTLRn(io->i_unit);
! 	register struct tmscp *tms = &tmscp[ctlr];
   
+ 	if (genopen(NTMS, io) < 0)
+ 		return(-1);
+ 	tmscpaddr = TMScsr[ctlr];
+ 
  	/*
  	 * Have the tmscp controller characteristics already been set up
  	 * (STCON)?
  	 */
! 	if (tmsoffline[ctlr])
  		{
  		/*
  		 * Initialize the tmscp device and wait for the 4 steps
***************
*** 102,109 ****
  #		define STEP1MASK 0174377
  #		define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
  		if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD)
! 			printf(opnmsg, 1, tmscpaddr->tmscpsa);
! 		tmscpaddr->tmscpsa = (short)&tmscp.tmscp_ca.ca_ringbase;
   
  		while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
  			;
--- 116,123 ----
  #		define STEP1MASK 0174377
  #		define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
  		if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD)
! 			printf(opnmsg, ctlr, 1, tmscpaddr->tmscpsa);
! 		tmscpaddr->tmscpsa = (short)&tms->tmscp_ca.ca_ringbase;
   
  		while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
  			;
***************
*** 110,116 ****
  #		define STEP2MASK 0174377
  #		define STEP2GOOD (TMSCP_STEP3)
  		if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD)
! 			printf(opnmsg, 2, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpsa = (short) (segflag & 3);
   
  		while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
--- 124,130 ----
  #		define STEP2MASK 0174377
  #		define STEP2GOOD (TMSCP_STEP3)
  		if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD)
! 			printf(opnmsg, ctlr, 2, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpsa = (short) (segflag & 3);
   
  		while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
***************
*** 118,159 ****
  #		define STEP3MASK 0174000
  #		define STEP3GOOD TMSCP_STEP4
  		if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
! 			printf(opnmsg, 2, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpsa = TMSCP_GO;
!  
! 		if (tmscpcmd(M_OP_STCON, 0) == 0)
  			{
! 			_stop("tms: open error, STCON");
! 			return;
  			}
! 		tmsoffline = 0;
  		}
! 	tmscp.tmscp_cmd.mscp_unit = io->i_unit&03;
  	/* 
  	 * Has this unit been issued an ONLIN?
  	 */
! 	if (tms_offline[tmscp.tmscp_cmd.mscp_unit])
  		{
! 		if ((mp = tmscpcmd(M_OP_ONLIN, 0)) == 0)
  			{
! 			_stop("tms: open error, ONLIN");
! 			return;
  			}
! 		tms_offline[tmscp.tmscp_cmd.mscp_unit] = 0;
  		}
! 	if (io->i_boff < 0)
! 		_stop("tms: bad offset");
  	else if (io->i_boff > 0)
  		/*
  		 * Skip forward the appropriate number of files on the tape.
  		 */
  		{
! 		tmscp.tmscp_cmd.mscp_tmkcnt = io->i_boff;
! 		tmscp.tmscp_cmd.mscp_buffer_h = 0;
! 		tmscp.tmscp_cmd.mscp_bytecnt = 0;
! 		tmscpcmd(M_OP_REPOS, 0);
! 		tmscp.tmscp_cmd.mscp_tmkcnt = 0;
  		}
  }
   
  /*
--- 132,176 ----
  #		define STEP3MASK 0174000
  #		define STEP3GOOD TMSCP_STEP4
  		if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
! 			printf(opnmsg, ctlr, 2, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpsa = TMSCP_GO;
! 		if (tmscpcmd(ctlr, M_OP_STCON, 0) == 0)
  			{
! 			printf("tms%d STCON", ctlr);
! 			return(-1);
  			}
! 		tmsoffline[ctlr] = 0;
  		}
! 	tms->tmscp_cmd.mscp_unit = UNITn(io->i_unit);
  	/* 
  	 * Has this unit been issued an ONLIN?
  	 */
! 	if (tms_offline[ctlr][tms->tmscp_cmd.mscp_unit])
  		{
! 		if (tmscpcmd(ctlr, M_OP_ONLIN, 0) == 0)
  			{
! 			printf("tms%d ONLIN", ctlr);
! 			return(-1);
  			}
! 		tms_offline[ctlr][tms->tmscp_cmd.mscp_unit] = 0;
  		}
! 	tmscpclose(io);		/* close just does a rewind */
! 	if (io->i_boff < 0) {
! 		printf("tms%d bad offset", ctlr);
! 		return(-1);
! 	}
  	else if (io->i_boff > 0)
  		/*
  		 * Skip forward the appropriate number of files on the tape.
  		 */
  		{
! 		tms->tmscp_cmd.mscp_tmkcnt = io->i_boff;
! 		tms->tmscp_cmd.mscp_buffer_h = 0;
! 		tms->tmscp_cmd.mscp_bytecnt = 0;
! 		tmscpcmd(ctlr, M_OP_REPOS, 0);
! 		tms->tmscp_cmd.mscp_tmkcnt = 0;
  		}
+ 	return(0);
  }
   
  /*
***************
*** 162,171 ****
  tmscpclose(io)
  	register struct iob *io;
  {
! 	tmscp.tmscp_cmd.mscp_buffer_l = 0;	/* tmkcnt */
! 	tmscp.tmscp_cmd.mscp_buffer_h = 0;
! 	tmscp.tmscp_cmd.mscp_bytecnt = 0;
! 	tmscpcmd(M_OP_REPOS, M_MD_REWND | M_MD_CLSEX);
  }
   
  /*
--- 179,192 ----
  tmscpclose(io)
  	register struct iob *io;
  {
! 	register int ctlr = CTLRn(io->i_unit);
! 	register struct tmscp *tms = &tmscp[ctlr];
! 
! 	tms->tmscp_cmd.mscp_buffer_l = 0;	/* tmkcnt */
! 	tms->tmscp_cmd.mscp_buffer_h = 0;
! 	tms->tmscp_cmd.mscp_bytecnt = 0;
! 	tms->tmscp_cmd.mscp_unit = UNITn(io->i_unit);
! 	tmscpcmd(ctlr, M_OP_REPOS, M_MD_REWND | M_MD_CLSEX);
  }
   
  /*
***************
*** 172,181 ****
   * Set up tmscp command packet.  Cause the controller to poll to pick up
   * the command.
   */
! struct mscp *
! tmscpcmd(op,mod)
! 	register int op, mod;		/* opcode and modifier (usu 0) */
  {
  	register struct mscp *mp;	/* ptr to cmd packet */
  	int i;				/* read into to init polling */
   
--- 193,203 ----
   * Set up tmscp command packet.  Cause the controller to poll to pick up
   * the command.
   */
! tmscpcmd(ctlr, op,mod)
! 	register int ctlr;
! 	int op, mod;		/* opcode and modifier (usu 0) */
  {
+ 	register struct tmscp *tms = &tmscp[ctlr];
  	register struct mscp *mp;	/* ptr to cmd packet */
  	int i;				/* read into to init polling */
   
***************
*** 182,214 ****
  	/*
  	 * Init cmd & rsp area
  	 */
! 	tmscp.tmscp_ca.ca_cmddsc[0].lsh = (short)&tmscp.tmscp_cmd.mscp_cmdref;
! 	tmscp.tmscp_ca.ca_cmddsc[0].hsh = segflag & 3;
! 	tmscp.tmscp_cmd.mscp_dscptr = (long *)tmscp.tmscp_ca.ca_cmddsc;
! 	tmscp.tmscp_cmd.mscp_header.tmscp_vcid = 1;	/* for tape */
! 	tmscp.tmscp_ca.ca_rspdsc[0].lsh = (short)&tmscp.tmscp_rsp.mscp_cmdref;
! 	tmscp.tmscp_ca.ca_rspdsc[0].hsh = segflag & 3;
! 	tmscp.tmscp_rsp.mscp_dscptr = (long *)tmscp.tmscp_ca.ca_rspdsc;
! 	tmscp.tmscp_cmd.mscp_cntflgs = 0;
  
! 	tmscp.tmscp_cmd.mscp_opcode = op;
! 	tmscp.tmscp_cmd.mscp_modifier = mod;
! 	tmscp.tmscp_cmd.mscp_header.tmscp_msglen = mscp_msglen;
! 	tmscp.tmscp_ca.ca_cmddsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
! 	tmscp.tmscp_rsp.mscp_header.tmscp_msglen = mscp_msglen;
! 	tmscp.tmscp_ca.ca_rspdsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
! 	tmscp.tmscp_cmd.mscp_zzz2 = 0;
   
! 	i = tmscpaddr->tmscpip;
  	for (;;)
  		{
! 		if (tmscpaddr->tmscpsa & TMSCP_ERR) {
! 			printf("tmscpcmd: Fatal error sa=%o\n",tmscpaddr->tmscpsa);
  			return(0);
  		}
   
! 		if (tmscp.tmscp_ca.ca_cmdint)
! 			tmscp.tmscp_ca.ca_cmdint = 0;
  		/*
  		 * This is to handle the case of devices not setting the
  		 * interrupt field in the communications area. Some
--- 204,237 ----
  	/*
  	 * Init cmd & rsp area
  	 */
! 	tms->tmscp_ca.ca_cmddsc[0].lsh = (short)&tms->tmscp_cmd.mscp_cmdref;
! 	tms->tmscp_ca.ca_cmddsc[0].hsh = segflag & 3;
! 	tms->tmscp_cmd.mscp_dscptr = (long *)tms->tmscp_ca.ca_cmddsc;
! 	tms->tmscp_cmd.mscp_header.tmscp_vcid = 1;	/* for tape */
! 	tms->tmscp_ca.ca_rspdsc[0].lsh = (short)&tms->tmscp_rsp.mscp_cmdref;
! 	tms->tmscp_ca.ca_rspdsc[0].hsh = segflag & 3;
! 	tms->tmscp_rsp.mscp_dscptr = (long *)tms->tmscp_ca.ca_rspdsc;
! 	tms->tmscp_cmd.mscp_cntflgs = 0;
  
! 	tms->tmscp_cmd.mscp_opcode = op;
! 	tms->tmscp_cmd.mscp_modifier = mod;
! 	tms->tmscp_cmd.mscp_header.tmscp_msglen = mscp_msglen;
! 	tms->tmscp_ca.ca_cmddsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
! 	tms->tmscp_rsp.mscp_header.tmscp_msglen = mscp_msglen;
! 	tms->tmscp_ca.ca_rspdsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
! 	tms->tmscp_cmd.mscp_zzz2 = 0;
   
! 	i = TMScsr[ctlr]->tmscpip;
  	for (;;)
  		{
! 		if (TMScsr[ctlr]->tmscpsa & TMSCP_ERR) {
! 			printf("tmscp%d: Fatal error sa=%o\n",
! 				ctlr, TMScsr[ctlr]->tmscpsa);
  			return(0);
  		}
   
! 		if (tms->tmscp_ca.ca_cmdint)
! 			tms->tmscp_ca.ca_cmdint = 0;
  		/*
  		 * This is to handle the case of devices not setting the
  		 * interrupt field in the communications area. Some
***************
*** 216,229 ****
  		 * in the Response Descriptor.
  		 */
  /*
! 		if (tmscp.tmscp_ca.ca_rspint)
  			break;
  */
! 		if (!(tmscp.tmscp_ca.ca_rspdsc[0].hsh & TMSCP_OWN))
  			break;
  		}
! 	tmscp.tmscp_ca.ca_rspint = 0;
! 	mp = &tmscp.tmscp_rsp;
  	if (mp->mscp_opcode != (op|M_OP_END) ||
  	   (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) {
  		/* Detect hitting tape mark.  This signifies the end of the
--- 239,252 ----
  		 * in the Response Descriptor.
  		 */
  /*
! 		if (tms->tmscp_ca.ca_rspint)
  			break;
  */
! 		if (!(tms->tmscp_ca.ca_rspdsc[0].hsh & TMSCP_OWN))
  			break;
  		}
! 	tms->tmscp_ca.ca_rspint = 0;
! 	mp = &tms->tmscp_rsp;
  	if (mp->mscp_opcode != (op|M_OP_END) ||
  	   (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) {
  		/* Detect hitting tape mark.  This signifies the end of the
***************
*** 233,243 ****
  		 */
  		if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM) {
  			tapemark = 1;
! 			return(mp);
  		}
  		return(0);
  	}
! 	return(mp);
  }
   
  /*
--- 256,266 ----
  		 */
  		if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM) {
  			tapemark = 1;
! 			return(1);
  		}
  		return(0);
  	}
! 	return(1);
  }
   
  /*
***************
*** 247,263 ****
  	register struct iob *io;
  	int func;
  {
  	register struct mscp *mp;
   
! 	mp = &tmscp.tmscp_cmd;
  	mp->mscp_lbn_l = loint(io->i_bn);
  	mp->mscp_lbn_h = hiint(io->i_bn);
! 	mp->mscp_unit = io->i_unit&03;
  	mp->mscp_bytecnt = io->i_cc;
  	mp->mscp_buffer_l = (u_short)io->i_ma;
  	mp->mscp_buffer_h = segflag & 3;
! 	if ((mp = tmscpcmd(func == READ ? M_OP_READ : M_OP_WRITE, 0)) == 0) {
! 		printf("tms: I/O error\n");
  		return(-1);
  	}
  	/*
--- 270,288 ----
  	register struct iob *io;
  	int func;
  {
+ 	int ctlr = CTLRn(io->i_unit);
+ 	register struct tmscp *tms = &tmscp[ctlr];
  	register struct mscp *mp;
   
! 	mp = &tms->tmscp_cmd;
  	mp->mscp_lbn_l = loint(io->i_bn);
  	mp->mscp_lbn_h = hiint(io->i_bn);
! 	mp->mscp_unit = UNITn(io->i_unit);
  	mp->mscp_bytecnt = io->i_cc;
  	mp->mscp_buffer_l = (u_short)io->i_ma;
  	mp->mscp_buffer_h = segflag & 3;
! 	if (tmscpcmd(ctlr, func == READ ? M_OP_READ : M_OP_WRITE, 0)==0) {
! 		printf("tms%d,%d: I/O err\n", ctlr, UNITn(io->i_unit));
  		return(-1);
  	}
  	/*
***************
*** 264,270 ****
  	 * Detect hitting tape mark so we do it gracefully and return a
  	 * character count of 0 to signify end of copy.
  	 */
! 	if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM)
  		return(0);
  	return(io->i_cc);
  }
--- 289,295 ----
  	 * Detect hitting tape mark so we do it gracefully and return a
  	 * character count of 0 to signify end of copy.
  	 */
! 	if (tapemark)
  		return(0);
  	return(io->i_cc);
  }
*** /old/src/sys/pdpstand/ts.c	Sat Aug 20 21:49:47 1988
--- /usr/src/sys/pdpstand/ts.c	Wed Apr 24 20:32:32 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ts.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ts.c	2.0 (2.11BSD) 4/20/91
   */
  
  /*
***************
*** 18,58 ****
  extern int tapemark;	/* flag to indicate tapemark encountered
  			   (see sys.c as to how its used) */
  
! caddr_t tsptr;
! struct	ts_char	chrbuf;		/* characteristics buffer */
! struct	ts_sts	mesbuf;		/* message buffer */
! struct	ts_cmd	*combuf;	/* command packet buffer */
! char	softspace[sizeof(struct ts_cmd)+3];
  
! #define	TSADDR	((struct tsdevice *)0172520)
  
  
  	/* bit definitions for Command mode field during read command */
  #define	TS_RPREV	0400	/* read previous (reverse) */
  
- 
  tsopen(io)
  	register struct iob *io;
  {
! 	register skip;
  
  	/* combuf must be alligned on a mod 4 byte boundary */
! 	combuf = (struct ts_cmd *)((u_short)softspace + 3 & ~3);
! 	tsptr = (caddr_t)((int)&combuf->c_cmd | (int)segflag);
! 	combuf->c_cmd = (TS_ACK|TS_CVC|TS_INIT);
! 	TSADDR->tsdb = (u_short) tsptr;
! 	while ((TSADDR->tssr & TS_SSR) == 0)
  		continue;
! 	chrbuf.char_bptr = (u_short) &mesbuf;
! 	chrbuf.char_bae = segflag;
! 	chrbuf.char_size = 016;
! 	chrbuf.char_mode = 0;
! 	combuf->c_cmd = (TS_ACK|TS_CVC|TS_SETCHR);
! 	combuf->c_loba = (u_short) &chrbuf;
! 	combuf->c_hiba = segflag;
! 	combuf->c_size = 010;
! 	TSADDR->tsdb = (u_short) tsptr;
! 	while ((TSADDR->tssr & TS_SSR) == 0)
  		continue;
  	tsstrategy(io, TS_REW);
  	skip = io->i_boff;
--- 18,75 ----
  extern int tapemark;	/* flag to indicate tapemark encountered
  			   (see sys.c as to how its used) */
  
! #define	NTS	2
  
! 	struct	tsdevice *TScsr[NTS + 1] =
! 		{
! 		(struct tsdevice *)0172520,
! 		(struct tsdevice *)0,
! 		(struct tsdevice *)-1
! 		};
  
+ caddr_t tsptr[NTS];
+ struct	ts_char	chrbuf[NTS];		/* characteristics buffer */
+ struct	ts_sts	mesbuf[NTS];		/* message buffer */
+ struct	ts_cmd	*combuf[NTS];		/* command packet buffer */
+ char	softspace[(NTS * sizeof(struct ts_cmd)) + 3];
  
  	/* bit definitions for Command mode field during read command */
  #define	TS_RPREV	0400	/* read previous (reverse) */
  
  tsopen(io)
  	register struct iob *io;
  {
! 	int skip;
! 	register struct tsdevice *tsaddr;
! 	register struct ts_char *chrb;
! 	struct ts_cmd *cmb;
! 	int ctlr = CTLRn(io->i_unit);
! 	char *cp;
  
+ 	if (genopen(NTS, io) < 0)
+ 		return(-1);
+ 	tsaddr = TScsr[ctlr];
+ 
  	/* combuf must be alligned on a mod 4 byte boundary */
! 	cp = (char *)((u_short)softspace + 3 & ~3);
! 	cp += (ctlr * sizeof (struct ts_cmd));
! 	cmb = combuf[ctlr] = (struct ts_cmd *)cp;
! 	tsptr[ctlr] = (caddr_t)((int)&combuf[ctlr]->c_cmd | (int)segflag);
! 	cmb->c_cmd = (TS_ACK|TS_CVC|TS_INIT);
! 	tsaddr->tsdb = (u_short) tsptr[ctlr];
! 	while ((tsaddr->tssr & TS_SSR) == 0)
  		continue;
! 	chrb = &chrbuf[ctlr];
! 	chrb->char_bptr = (u_short) &mesbuf;
! 	chrb->char_bae = segflag;
! 	chrb->char_size = 016;
! 	chrb->char_mode = 0;
! 	cmb->c_cmd = (TS_ACK|TS_CVC|TS_SETCHR);
! 	cmb->c_loba = (u_short) &chrbuf;
! 	cmb->c_hiba = segflag;
! 	cmb->c_size = 010;
! 	tsaddr->tsdb = (u_short) tsptr[ctlr];
! 	while ((tsaddr->tssr & TS_SSR) == 0)
  		continue;
  	tsstrategy(io, TS_REW);
  	skip = io->i_boff;
***************
*** 61,69 ****
  		while (tsstrategy(io, TS_SFORW))
  			continue;
  	}
  }
  tsclose(io)
! 	register struct iob *io;
  {
  	tsstrategy(io, TS_REW);
  }
--- 78,88 ----
  		while (tsstrategy(io, TS_SFORW))
  			continue;
  	}
+ 	return(0);
  }
+ 
  tsclose(io)
! 	struct iob *io;
  {
  	tsstrategy(io, TS_REW);
  }
***************
*** 71,119 ****
  tsstrategy(io, func)
  	register struct iob *io;
  {
! 	register unit, errcnt;
  
! 	unit = io->i_unit;
  	errcnt = 0;
! 	combuf->c_loba = (u_short) io->i_ma;
! 	combuf->c_hiba = segflag;
! 	combuf->c_size = io->i_cc;
  	if (func == READ)
! 		combuf->c_cmd = TS_ACK|TS_RCOM;
  	else if (func == WRITE)
! 		combuf->c_cmd = TS_ACK|TS_WCOM;
  	else
! 		combuf->c_cmd = TS_ACK|func;
! 	TSADDR->tsdb = (u_short) tsptr;
  retry:
! 	while ((TSADDR->tssr & TS_SSR) == 0)
  		continue;
! 	if (mesbuf.s_xs0 & TS_TMK) {
  		tapemark = 1;
  		return(0);
  	}
! 	if (TSADDR->tssr & TS_SC) {
  		if (errcnt == 0)
! 		    printf("\nTS tape error: sr=%o xs0=%o xs1=%o xs2=%o xs3=%o",
! 			TSADDR->tssr,
! 			mesbuf.s_xs0, mesbuf.s_xs1,
! 			mesbuf.s_xs2, mesbuf.s_xs3);
  		if (errcnt++ == 10) {
  			printf("\n(FATAL ERROR)\n");
  			return(-1);
  		}
  		if (func == READ)
! 			combuf->c_cmd = (TS_ACK|TS_RPREV|TS_RCOM);
  		else if (func == WRITE)
! 			combuf->c_cmd = (TS_ACK|TS_RETRY|TS_WCOM);
  		else {
  			printf("\n");
  			return(-1);
  		}
! 		TSADDR->tsdb = (u_short) tsptr;
  		goto retry;
  	}
! 	if (errcnt)
! 		printf("\n(RECOVERED by retry)\n");
! 	return (io->i_cc+mesbuf.s_rbpcr);
  }
--- 90,138 ----
  tsstrategy(io, func)
  	register struct iob *io;
  {
! 	register int ctlr = CTLRn(io->i_unit);
! 	int errcnt, unit;
! 	register struct tsdevice *tsaddr = TScsr[ctlr];
  
! 	unit = UNITn(io->i_unit);
  	errcnt = 0;
! 	combuf[ctlr]->c_loba = (u_short) io->i_ma;
! 	combuf[ctlr]->c_hiba = segflag;
! 	combuf[ctlr]->c_size = io->i_cc;
  	if (func == READ)
! 		combuf[ctlr]->c_cmd = TS_ACK|TS_RCOM;
  	else if (func == WRITE)
! 		combuf[ctlr]->c_cmd = TS_ACK|TS_WCOM;
  	else
! 		combuf[ctlr]->c_cmd = TS_ACK|func;
! 	tsaddr->tsdb = (u_short) tsptr[ctlr];
  retry:
! 	while ((tsaddr->tssr & TS_SSR) == 0)
  		continue;
! 	if (mesbuf[ctlr].s_xs0 & TS_TMK) {
  		tapemark = 1;
  		return(0);
  	}
! 	if (tsaddr->tssr & TS_SC) {
  		if (errcnt == 0)
! 		    printf("\nTS%d,%d err sr=%o xs0=%o xs1=%o xs2=%o xs3=%o",
! 			ctlr, UNITn(io->i_unit), tsaddr->tssr,
! 			mesbuf[ctlr].s_xs0, mesbuf[ctlr].s_xs1,
! 			mesbuf[ctlr].s_xs2, mesbuf[ctlr].s_xs3);
  		if (errcnt++ == 10) {
  			printf("\n(FATAL ERROR)\n");
  			return(-1);
  		}
  		if (func == READ)
! 			combuf[ctlr]->c_cmd = (TS_ACK|TS_RPREV|TS_RCOM);
  		else if (func == WRITE)
! 			combuf[ctlr]->c_cmd = (TS_ACK|TS_RETRY|TS_WCOM);
  		else {
  			printf("\n");
  			return(-1);
  		}
! 		tsaddr->tsdb = (u_short) tsptr[ctlr];
  		goto retry;
  	}
! 	return (io->i_cc+mesbuf[ctlr].s_rbpcr);
  }
*** /old/src/sys/pdpstand/xp.c	Tue Sep 27 13:44:23 1988
--- /usr/src/sys/pdpstand/xp.c	Sat May  4 17:49:43 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	1.2 (2.10BSD Berkeley) 1/12/88
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	2.0 (2.11BSD) 4/20/91
   */
  
  /*
***************
*** 15,75 ****
  #include "../machine/iopage.h"
  #include "saio.h"
  
! #define	XPADDR	((struct hpdevice *)0176700)
  
! extern	char haveCSW;		/* bool, set if switch register exists */
  
  /*
   * Drive type; declared so we can patch; see hpreg.h for more information.
   */
! int	xptype = 0;
  
  xpstrategy(io, func)
  	register struct iob *io;
  {
! 	register unit;
! 	register i;
  	register nm_sect_per_cyl, nsect;
  	daddr_t bn;
  	int sn, cn, tn;
  
! 	if (((unit = io->i_unit) & 04) == 0)
! 		bn = io->i_bn;
! 	else {
! 		unit &= 03;
! 		bn = io->i_bn;
! 		bn -= io->i_boff;
! 		i = unit + 1;
! 		unit = bn%i;
! 		bn /= i;
! 		bn += io->i_boff;
! 	}
  
! 	XPADDR->hpcs2.w = unit;
! 
! 	if ((XPADDR->hpds & HPDS_VV) == 0) {
! 		XPADDR->hpcs1.c[0] = HP_PRESET|HP_GO;
! 		XPADDR->hpof = HPOF_FMT22;
  	}
  	/*
!  	 *	This next weirdness handled the look up into the Drive Type
!  	 *	register to tell what type of disk we have here.
! 	 *	Look in switch register first (if there is one).
!  	 *
!  	 *	Note: No need to look up after the first time.
   	 */
  	
! 	if (xptype == 0) {
! 		if (haveCSW && (*CSW == RP04 || *CSW == RP05 || *CSW == RP06
! 		    || *CSW == RM02 || *CSW == RM03 || *CSW == RM05
! 		    || *CSW == CAP  || *CSW == SI5  || *CSW == SI
! 		    || *CSW == RM2X || *CSW == RM5X || *CSW == DV))
! 			xptype = *CSW;
! 		else
! 			xptype = (XPADDR->hpdt & 077);
  	}
  
! 	switch (xptype) {
  	case RP04:
  	case RP05:
  	case RP06:
--- 15,73 ----
  #include "../machine/iopage.h"
  #include "saio.h"
  
! #define	NXP	2
  
! 	struct	hpdevice *XPcsr[NXP + 1] =
! 		{
! 		(struct hpdevice *)0176700,
! 		(struct hpdevice *)0,
! 		(struct hpdevice *)-1
! 		};
  
  /*
   * Drive type; declared so we can patch; see hpreg.h for more information.
   */
! int	xptype[NXP] = 0;
  
  xpstrategy(io, func)
  	register struct iob *io;
  {
! 	int unit = UNITn(io->i_unit);
! 	int ctlr = CTLRn(io->i_unit);
! 	int i;
  	register nm_sect_per_cyl, nsect;
  	daddr_t bn;
  	int sn, cn, tn;
+ 	struct hpdevice *xpaddr = XPcsr[ctlr];
  
! 	bn = io->i_bn;
! 	/*
! 	 * The weirdness involving bit 2 (04) in the unit # was removed
! 	 * because 1) the xp driver in the kernel didn't know about it,
! 	 * 2) no mention was made in any .h file or documentation/notes
! 	*/
! 	xpaddr->hpcs2.w = unit;
  
! 	if ((xpaddr->hpds & HPDS_VV) == 0) {
! 		xpaddr->hpcs1.c[0] = HP_PRESET|HP_GO;
! 		xpaddr->hpof = HPOF_FMT22;
  	}
  	/*
!  	 *	The weirdness of (possibly) looking at the console switch
!  	 *	register to tell what type of disk we have here was removed
! 	 *	because 1) most systems do not have one, 2) space contraints
! 	 *	imposed by adding multi controller support were creating a
! 	 * 	size problem, and 3) an alternative method is provided for
! 	 *	setting the type (the address and content is printed).
   	 */
  	
! 	if (xptype[ctlr] == 0) {
! 		xptype[ctlr] = (xpaddr->hpdt & 077);
! 		printf("\n&xptype=0%o xptype[%d]=0%o\n", xptype, ctlr, 
! 			xptype[ctlr]);
  	}
  
! 	switch (xptype[ctlr]) {
  	case RP04:
  	case RP05:
  	case RP06:
***************
*** 76,121 ****
  		nm_sect_per_cyl = HP_SECT * HP_TRAC;
  		nsect = HP_SECT;
  		break;
- 
  	case RM02:
  	case RM03:
  		nm_sect_per_cyl = RM_SECT * RM_TRAC;
  		nsect = RM_SECT;
  		break;
- 
  	case RM05:
  	case RM5X:
  		nm_sect_per_cyl = RM5_SECT * RM5_TRAC;
  		nsect = RM5_SECT;
  		break;
- 
  	case CAP:
  		nm_sect_per_cyl = CAP_SECT * CAP_TRAC;
  		nsect = CAP_SECT;
  		break;
- 
  	case SI5:
  		nm_sect_per_cyl = SI5_SECT * SI5_TRAC;
  		nsect = SI5_SECT;
  		break;
- 
  	case SI:
  		nm_sect_per_cyl = SI_SECT * SI_TRAC;
  		nsect = SI_SECT;
  		break;
- 
  	case RM2X:
  		nm_sect_per_cyl = RM2X_SECT * RM2X_TRAC;
  		nsect = RM2X_SECT;
  		break;
- 
  	case DV:
  		nm_sect_per_cyl = DV_SECT * DV_TRAC;
  		nsect = DV_SECT;
  		break;
- 
  	default:
! 		printf("xp: unknown device type 0%o\n", xptype);
  		return(-1);	
  	}
  	cn = bn/(nm_sect_per_cyl);
--- 74,111 ----
  		nm_sect_per_cyl = HP_SECT * HP_TRAC;
  		nsect = HP_SECT;
  		break;
  	case RM02:
  	case RM03:
  		nm_sect_per_cyl = RM_SECT * RM_TRAC;
  		nsect = RM_SECT;
  		break;
  	case RM05:
  	case RM5X:
  		nm_sect_per_cyl = RM5_SECT * RM5_TRAC;
  		nsect = RM5_SECT;
  		break;
  	case CAP:
  		nm_sect_per_cyl = CAP_SECT * CAP_TRAC;
  		nsect = CAP_SECT;
  		break;
  	case SI5:
  		nm_sect_per_cyl = SI5_SECT * SI5_TRAC;
  		nsect = SI5_SECT;
  		break;
  	case SI:
  		nm_sect_per_cyl = SI_SECT * SI_TRAC;
  		nsect = SI_SECT;
  		break;
  	case RM2X:
  		nm_sect_per_cyl = RM2X_SECT * RM2X_TRAC;
  		nsect = RM2X_SECT;
  		break;
  	case DV:
  		nm_sect_per_cyl = DV_SECT * DV_TRAC;
  		nsect = DV_SECT;
  		break;
  	default:
! 		printf("xp%d: unknown type 0%o\n", ctlr, xptype[ctlr]);
  		return(-1);	
  	}
  	cn = bn/(nm_sect_per_cyl);
***************
*** 123,144 ****
  	tn = sn/nsect;
  	sn = sn%nsect;
  
! 	XPADDR->hpdc = cn;
! 	XPADDR->hpda = (tn << 8) + sn;
! 	XPADDR->hpba = io->i_ma;
! 	XPADDR->hpwc = -(io->i_cc>>1);
! 	unit = (segflag << 8) | HP_GO;
  	if (func == READ)
! 		unit |= HP_RCOM;
  	else if (func == WRITE)
! 		unit |= HP_WCOM;
! 	XPADDR->hpcs1.w = unit;
! 	while ((XPADDR->hpcs1.w & HP_RDY) == 0)
  			continue;
! 	if (XPADDR->hpcs1.w & HP_TRE) {
! 		printf("disk error: cyl=%d track=%d sect=%d cs2=%o, er1=%o\n",
! 		    cn, tn, sn, XPADDR->hpcs2, XPADDR->hper1);
  		return(-1);
  	}
  	return(io->i_cc);
  }
--- 113,140 ----
  	tn = sn/nsect;
  	sn = sn%nsect;
  
! 	xpaddr->hpdc = cn;
! 	xpaddr->hpda = (tn << 8) + sn;
! 	xpaddr->hpba = io->i_ma;
! 	xpaddr->hpwc = -(io->i_cc>>1);
! 	i = (segflag << 8) | HP_GO;
  	if (func == READ)
! 		i |= HP_RCOM;
  	else if (func == WRITE)
! 		i |= HP_WCOM;
! 	xpaddr->hpcs1.w = i;
! 	while ((xpaddr->hpcs1.w & HP_RDY) == 0)
  			continue;
! 	if (xpaddr->hpcs1.w & HP_TRE) {
! 		printf("xp%d,%d err cy=%d tr=%d sc=%d cs2=%o er1=%o\n",
! 		    ctlr, unit, cn, tn, sn, xpaddr->hpcs2, xpaddr->hper1);
  		return(-1);
  	}
  	return(io->i_cc);
+ }
+ 
+ xpopen(io)
+ 	struct iob *io;
+ {
+ 	return(genopen(NXP, io));
  }
*** /old/src/sys/pdpuba/br.c	Tue Apr  3 17:36:33 1990
--- /usr/src/sys/pdpuba/br.c	Sun Sep 22 08:36:20 1991
***************
*** 26,31 ****
--- 26,32 ----
   *	      partitions as partitions 'e', 'f', and 'g' as an aid in
   *	      converting the systems.  BE CAREFUL!  For T300 only.
   * 8/4/89   - Use the log() function to record soft errors.
+  * 9/22/91  - remove read and write entry - use common raw read/write routine.
   */
  
  #include "br.h"
***************
*** 115,121 ****
  #ifdef UCB_METER
  static int br_dkn = -1;
  #endif
! struct buf brtab, rbrbuf;
  struct br_char *br_disk[NBR];
  struct brdevice *Br_addr;
  
--- 116,122 ----
  #ifdef UCB_METER
  static int br_dkn = -1;
  #endif
! struct buf brtab;
  struct br_char *br_disk[NBR];
  struct brdevice *Br_addr;
  
***************
*** 354,373 ****
  	brstart();
  }
   
- brread(dev, uio)
- 	int dev;
- 	struct uio *uio;
- {
- 	return(physio(brstrategy, &rbrbuf, dev, B_READ, WORD, uio));
- }
- 
- brwrite(dev, uio)
- 	int dev;
- 	struct uio *uio;
- {
- 	return(physio(brstrategy, &rbrbuf, dev, B_WRITE, WORD, uio));
- }
- 
  #ifdef BR_DUMP
  /*
   * Dump routine.  Dumps from dumplo to end of memory/end of disk section for
--- 355,360 ----
*** /old/src/sys/pdpuba/dhv.c	Thu Sep  1 14:14:03 1988
--- /usr/src/sys/pdpuba/dhv.c	Thu Jul  2 22:53:43 1992
***************
*** 3,12 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)dhv.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  /*
   * based on	dh.c 6.3	84/03/15
   * and on	dmf.c	6.2	84/02/16
   *
--- 3,13 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)dhv.c	2.0 (2.11BSD Berkeley) 12/22/91
   */
  
  /*
+  * ported to 2.11BSD (uio logic added) 12/22/91 - SMS
   * based on	dh.c 6.3	84/03/15
   * and on	dmf.c	6.2	84/02/16
   *
***************
*** 43,49 ****
  #define	NDHVLINE	(NDHV*8)
  
  #define	UNIT(x)		(minor(x) & 077)
! #define CDWAIT(x)	(minor(x) & 0200)
  #define HWFLOW(x)	(minor(x) & 0100)
  
  #define ISPEED	B9600
--- 44,50 ----
  #define	NDHVLINE	(NDHV*8)
  
  #define	UNIT(x)		(minor(x) & 077)
! #define CDWAIT(x)	(!(minor(x) & 0200))
  #define HWFLOW(x)	(minor(x) & 0100)
  
  #define ISPEED	B9600
***************
*** 75,81 ****
  struct	tty dhv_tty[NDHVLINE];
  int	ndhv = NDHVLINE;
  int	dhv_ie[NDHV];
- int	dhvtsize = sizeof(struct tty);
  int	dhvact;				/* mask of active dhv's */
  int	dhv_rcnt[16];
  int	dhvstart(), ttrstrt();
--- 76,81 ----
***************
*** 91,99 ****
  
  /*
   * Routine called to attach a dhv.
-  * Called dvattach for autoconfig.
   */
! dvattach(addr,unit)
  	register caddr_t addr;
  	register u_int unit;
  {
--- 91,98 ----
  
  /*
   * Routine called to attach a dhv.
   */
! dhvattach(addr,unit)
  	register caddr_t addr;
  	register u_int unit;
  {
***************
*** 230,249 ****
      return ( ttselect ( dev & ~0300, rw ) );
  }
  
! dhvread(dev)
  	dev_t dev;
  {
  	register struct tty *tp = &dhv_tty[UNIT(dev)];
  
!     return ( (*linesw[tp->t_line].l_read) (tp) );
  }
  
! dhvwrite(dev)
  	dev_t dev;
  {
  	register struct tty *tp = &dhv_tty[UNIT(dev)];
  
!     return ( (*linesw[tp->t_line].l_write) (tp) );
  }
  
  /*
--- 229,250 ----
      return ( ttselect ( dev & ~0300, rw ) );
  }
  
! dhvread(dev, uio)
  	dev_t dev;
+ 	struct uio *uio;
  {
  	register struct tty *tp = &dhv_tty[UNIT(dev)];
  
!     return((*linesw[tp->t_line].l_read) (tp, uio));
  }
  
! dhvwrite(dev, uio)
  	dev_t dev;
+ 	struct uio *uio;
  {
  	register struct tty *tp = &dhv_tty[UNIT(dev)];
  
!     return((*linesw[tp->t_line].l_write) (tp, uio));
  }
  
  /*
***************
*** 403,408 ****
--- 404,410 ----
   */
  /*ARGSUSED*/
  dhvioctl(dev, cmd, data, flag)
+ 	register dev_t dev;
  	u_int cmd;
  	caddr_t data;
  {
***************
*** 543,549 ****
  	else
  	{
  	    addr->dhvlcr &= ~DHV_LC_OAUTOF;
! 	    DELAY(25); /* see the dhv manual, sec 3.3.6 */
  	    addr->dhvlcr2 |= DHV_LC2_TXEN;
  	}
  	splx(s);
--- 545,551 ----
  	else
  	{
  	    addr->dhvlcr &= ~DHV_LC_OAUTOF;
! 	    delay(25L); /* see the dhv manual, sec 3.3.6 */
  	    addr->dhvlcr2 |= DHV_LC2_TXEN;
  	}
  	splx(s);
***************
*** 718,724 ****
  		unit = UNIT(tp->t_dev);
  		addr->dhvcsrl = DHV_SELECT(unit) | dhv_ie[unit>>3];
  		addr->dhvlcr |= DHV_LC_TXABORT;
! 		DELAY(25); /* see the dhv manual, sec 3.3.6 */
  		addr->dhvlcr2 |= DHV_LC2_TXEN;
  		if ((tp->t_state&TS_TTSTOP)==0)
  			tp->t_state |= TS_FLUSH;
--- 720,726 ----
  		unit = UNIT(tp->t_dev);
  		addr->dhvcsrl = DHV_SELECT(unit) | dhv_ie[unit>>3];
  		addr->dhvlcr |= DHV_LC_TXABORT;
! 		delay(25L); /* see the dhv manual, sec 3.3.6 */
  		addr->dhvlcr2 |= DHV_LC2_TXEN;
  		if ((tp->t_state&TS_TTSTOP)==0)
  			tp->t_state |= TS_FLUSH;
*** /old/src/sys/pdpuba/dr.c	Tue Apr  3 16:43:20 1990
--- /usr/src/sys/pdpuba/dr.c	Sun Sep 22 08:36:38 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)dr.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)dr.c	1.2 (2.11BSD Berkeley) 9/22/91
   */
  
  /*
***************
*** 33,39 ****
  	int	i_sig;			/* signal to send on ATTN */
  	int	i_tsig;			/* signal to send on timeout */
  	struct	buf i_tab;		/* buffer for device */
- 	struct	buf i_buf;		/* raw device buffer */
  	struct	drdevice *i_addr;	/* address of DR11-W interface */
  };
  
--- 33,38 ----
***************
*** 200,221 ****
  	iodone(bp);				/* tell system we are done */
  	if(drptr->i_tab.b_actf)			/* start next request */
  		drstart(drptr);
- }
- 
- drread(dev, uio)
- 	dev_t dev;
- 	struct uio *uio;
- {
- 	return (physio(drstrategy, &dr11[minor(dev) & 07].i_buf,
- 	    dev, B_READ, WORD, uio));
- }
- 
- drwrite(dev, uio)
- 	dev_t dev;
- 	struct uio *uio;
- {
- 	return (physio(drstrategy, &dr11[minor(dev) & 07].i_buf,
- 	    dev, B_WRITE, WORD, uio));
  }
  
  drioctl(dev, cmd, data, flag)
--- 199,204 ----
*** /old/src/sys/pdpuba/dz.c	Tue Apr  3 15:44:25 1990
--- /usr/src/sys/pdpuba/dz.c	Wed Jun  5 23:12:12 1991
***************
*** 157,168 ****
  	else
  		dzsoftCAR[unit >> 3] &= ~(1<<(unit&07));
  #endif /* BSD2_10 */
! 	(void) spl5();
  	while ((tp->t_state & TS_CARR_ON) == 0) {
  		tp->t_state |= TS_WOPEN;
  		sleep((caddr_t)&tp->t_rawq, TTIPRI);
  	}
! 	(void) spl0();
  	return ((*linesw[tp->t_line].l_open)(dev, tp));
  }
  
--- 157,168 ----
  	else
  		dzsoftCAR[unit >> 3] &= ~(1<<(unit&07));
  #endif /* BSD2_10 */
! 	(void) _spl5();
  	while ((tp->t_state & TS_CARR_ON) == 0) {
  		tp->t_state |= TS_WOPEN;
  		sleep((caddr_t)&tp->t_rawq, TTIPRI);
  	}
! 	(void) _spl0();
  	return ((*linesw[tp->t_line].l_open)(dev, tp));
  }
  
*** /old/src/sys/pdpuba/hk.c	Tue Oct 23 18:00:15 1990
--- /usr/src/sys/pdpuba/hk.c	Sun Sep 22 08:37:08 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)hk.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)hk.c	1.l (2.11BSD Berkeley) 9/22/91
   */
  
  /*
***************
*** 83,89 ****
  
  struct	buf	hktab;
  struct	buf	hkutab[NHK];
- struct	buf	rhkbuf[NHK];
  #ifdef BADSECT
  struct	dkbad	hkbad[NHK];
  struct	buf	bhkbuf[NHK];
--- 83,88 ----
***************
*** 505,524 ****
  			needie = 0;
  	if (needie)
  		hkaddr->hkcs1 = HK_IE;
- }
- 
- hkread(dev, uio)
- 	dev_t dev;
- 	struct uio *uio;
- {
- 	return (physio(hkstrategy, &rhkbuf[hkunit(dev)], dev, B_READ, WORD, uio));
- }
- 
- hkwrite(dev, uio)
- 	dev_t dev;
- 	struct uio *uio;
- {
- 	return (physio(hkstrategy, &rhkbuf[hkunit(dev)], dev, B_WRITE, WORD, uio));
  }
  
  #ifdef HK_DUMP
--- 504,509 ----
*** /old/src/sys/pdpuba/ht.c	Tue Apr  3 23:00:43 1990
--- /usr/src/sys/pdpuba/ht.c	Sun Sep 22 08:37:43 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ht.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ht.c	2.1 (2.11BSD) 9/22/91
   */
  
  /*
***************
*** 22,31 ****
  #include "htreg.h"
  #include "systm.h"
  
! struct	buf	httab;
! struct	buf	rhtbuf;
! struct	buf	chtbuf;
! 
  struct	htdevice	*HTADDR;
  
  #define	INF	32760
--- 22,31 ----
  #include "htreg.h"
  #include "systm.h"
  
! struct	buf	httab, chtbuf;
! static	short	rh70;		/* ht.c was ONLY user of B_RH70 and that bit
! 				 * was wanted for something else (B_LOCKED)
! 				*/
  struct	htdevice	*HTADDR;
  
  #define	INF	32760
***************
*** 61,77 ****
  	/*
  	 * This driver supports only one controller.
  	 */
! 	if (unit != 0)
! 		return(0);
! 	if ((addr != (struct htdevice *) NULL) && (fioword(addr) != -1)) {
  		HTADDR = addr;
- #if	PDP11 == 70 || PDP11 == GENERIC
  		if (fioword(&(addr->htbae)) != -1)
! 			httab.b_flags |= B_RH70;
! #endif
  		return(1);
  	}
- 	HTADDR = (struct htdevice *) NULL;
  	return(0);
  }
  
--- 61,72 ----
  	/*
  	 * This driver supports only one controller.
  	 */
! 	if (unit == 0) {
  		HTADDR = addr;
  		if (fioword(&(addr->htbae)) != -1)
! 			rh70 = 1;
  		return(1);
  	}
  	return(0);
  }
  
***************
*** 84,90 ****
  	int olddens, dens;
  
  	httab.b_flags |= B_TAPE;
! 	if (HTADDR == (struct htdevice *) NULL || htunit >= NHT)
  		return(ENXIO);
  	if (sc->sc_openf)
  		return(EBUSY);
--- 79,85 ----
  	int olddens, dens;
  
  	httab.b_flags |= B_TAPE;
! 	if (!HTADDR || htunit >= NHT)
  		return(ENXIO);
  	if (sc->sc_openf)
  		return(EBUSY);
***************
*** 174,204 ****
  htstrategy(bp)
  register struct	buf *bp;
  {
! 	int s;
! 	register daddr_t *p;
  	register struct softc *sc = &tu_softc[TUUNIT(bp->b_dev)];
  
- 	if(bp != &chtbuf) {
  #ifdef	UNIBUS_MAP
! 		if ((httab.b_flags & B_RH70) == 0)
! 			mapalloc(bp);
  #endif
! 		p = &sc->sc_nxrec;
! 		if(dbtofsb(bp->b_blkno) > *p) {
! 			bp->b_flags |= B_ERROR;
! 			bp->b_error = ENXIO;
! 			iodone(bp);
! 			return;
! 		}
! 		if(dbtofsb(bp->b_blkno) == *p && bp->b_flags & B_READ) {
! 			bp->b_resid = bp->b_bcount;
! 			iodone(bp);
! 			return;
! 		}
! 		if ((bp->b_flags & B_READ) == 0) {
! 			*p = dbtofsb(bp->b_blkno) + 1;
! 			sc->sc_lastiow = 1;
! 		}
  	}
  	bp->av_forw = NULL;
  	s = splbio();
--- 169,184 ----
  htstrategy(bp)
  register struct	buf *bp;
  {
! 	register int s;
  	register struct softc *sc = &tu_softc[TUUNIT(bp->b_dev)];
  
  #ifdef	UNIBUS_MAP
! 	if (rh70 == 0)
! 		mapalloc(bp);
  #endif
! 	if (bp->b_flags & B_PHYS) {
! 		sc->sc_blkno = sc->sc_nxrec = dbtofsb(bp->b_blkno);
! 		sc->sc_nxrec++;
  	}
  	bp->av_forw = NULL;
  	s = splbio();
***************
*** 216,222 ****
  {
  	register struct buf *bp;
  	register den;
- 	int htunit;
  	daddr_t	blkno;
  	register struct softc *sc;
  
--- 196,201 ----
***************
*** 223,230 ****
      loop:
  	if ((bp = httab.b_actf) == NULL)
  		return;
! 	htunit = TUUNIT(minor(bp->b_dev));
! 	sc = &tu_softc[htunit];
  	sc->sc_erreg = HTADDR->hter;
  	sc->sc_fsreg = HTADDR->htfs;
  	sc->sc_resid = HTADDR->htfc;
--- 202,208 ----
      loop:
  	if ((bp = httab.b_actf) == NULL)
  		return;
! 	sc = &tu_softc[TUUNIT(bp->b_dev)];
  	sc->sc_erreg = HTADDR->hter;
  	sc->sc_fsreg = HTADDR->htfs;
  	sc->sc_resid = HTADDR->htfc;
***************
*** 231,239 ****
  	HTADDR->htcs2 = 0;	/* controller 0 - do we need this? */
  	if ((HTADDR->httc & 03777) != sc->sc_dens)
  		HTADDR->httc = sc->sc_dens;
! 	if (HTADDR->htcs2 & HTCS2_NEF || (HTADDR->htfs & HTFS_MOL) == 0)
  		goto abort;
- 	blkno = sc->sc_blkno;
  	if (bp == &chtbuf) {
  		if (bp->b_command == HT_SENSE) {
  			bp->b_resid = HTADDR->htfs;
--- 209,217 ----
  	HTADDR->htcs2 = 0;	/* controller 0 - do we need this? */
  	if ((HTADDR->httc & 03777) != sc->sc_dens)
  		HTADDR->httc = sc->sc_dens;
! 	sc->sc_lastiow = 0;
! 	if (sc->sc_openf < 0 || HTADDR->htcs2 & HTCS2_NEF || !(HTADDR->htfs & HTFS_MOL))
  		goto abort;
  	if (bp == &chtbuf) {
  		if (bp->b_command == HT_SENSE) {
  			bp->b_resid = HTADDR->htfs;
***************
*** 244,258 ****
  		HTADDR->htcs1 = bp->b_command | HT_IE | HT_GO;
  		return;
  	}
! 	if (sc->sc_openf < 0 || dbtofsb(bp->b_blkno) > sc->sc_nxrec)
  		goto abort;
! 	if (blkno == dbtofsb(bp->b_blkno)) {
  		httab.b_active = SIO;
  		HTADDR->htba = bp->b_un.b_addr;
! #if	PDP11 == 70 || PDP11 == GENERIC
! 		if(httab.b_flags & B_RH70)
  			HTADDR->htbae = bp->b_xmem;
- #endif
  		HTADDR->htfc = -bp->b_bcount;
  		HTADDR->htwc = -(bp->b_bcount >> 1);
  		den = ((bp->b_xmem & 3) << 8) | HT_IE | HT_GO;
--- 222,247 ----
  		HTADDR->htcs1 = bp->b_command | HT_IE | HT_GO;
  		return;
  	}
! 	if (dbtofsb(bp->b_blkno) > sc->sc_nxrec)
  		goto abort;
! 	if (dbtofsb(bp->b_blkno) == sc->sc_nxrec && bp->b_flags & B_READ) {
! 		/*
! 		 * Reading at end of file returns 0 bytes.
! 		 * Buffer will be cleared (if written) in rwip.
! 		*/
! 		bp->b_resid = bp->b_bcount;
! 		goto next;
! 	}
! 	if ((bp->b_flags & B_READ) == 0)
! 		/*
! 		 * Writing sets EOF
! 		*/
! 		sc->sc_nxrec = dbtofsb(bp->b_blkno) + 1;
! 	if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) {
  		httab.b_active = SIO;
  		HTADDR->htba = bp->b_un.b_addr;
! 		if (rh70)
  			HTADDR->htbae = bp->b_xmem;
  		HTADDR->htfc = -bp->b_bcount;
  		HTADDR->htwc = -(bp->b_bcount >> 1);
  		den = ((bp->b_xmem & 3) << 8) | HT_IE | HT_GO;
***************
*** 300,316 ****
  	if ((bp = httab.b_actf) == NULL)
  		return;
  	htunit = TUUNIT(bp->b_dev);
- 	state = httab.b_active;
- 	httab.b_active = 0;
  	sc = &tu_softc[htunit];
  	sc->sc_erreg = HTADDR->hter;
  	sc->sc_fsreg = HTADDR->htfs;
  	sc->sc_resid = HTADDR->htfc;
  	if (HTADDR->htcs1 & HT_TRE) {
  		err = HTADDR->hter;
  		if (HTADDR->htcs2 & HTCS2_ERR || (err & HTER_HARD))
  			state = 0;
! 		if (bp == &rhtbuf)
  			err &= ~HTER_FCE;
  		if ((bp->b_flags & B_READ) && (HTADDR->htfs & HTFS_PES))
  			err &= ~(HTER_CSITM | HTER_CORCRC);
--- 289,307 ----
  	if ((bp = httab.b_actf) == NULL)
  		return;
  	htunit = TUUNIT(bp->b_dev);
  	sc = &tu_softc[htunit];
  	sc->sc_erreg = HTADDR->hter;
  	sc->sc_fsreg = HTADDR->htfs;
  	sc->sc_resid = HTADDR->htfc;
+ 	if ((bp->b_flags & B_READ) == 0)
+ 		sc->sc_lastiow = 1;
+ 	state = httab.b_active;
+ 	httab.b_active = 0;
  	if (HTADDR->htcs1 & HT_TRE) {
  		err = HTADDR->hter;
  		if (HTADDR->htcs2 & HTCS2_ERR || (err & HTER_HARD))
  			state = 0;
! 		if (bp->b_flags & B_PHYS)
  			err &= ~HTER_FCE;
  		if ((bp->b_flags & B_READ) && (HTADDR->htfs & HTFS_PES))
  			err &= ~(HTER_CSITM | HTER_CORCRC);
***************
*** 401,434 ****
  	HTADDR->htcs2 = ocs2;
  	HTADDR->httc = omttc;
  	HTADDR->htcs1 = HT_DCLR | HT_GO;
- }
- 
- htread(dev, uio)
- register dev_t	dev;
- register struct uio *uio;
- {
- 	htphys(dev, uio);
- 	return (physio(htstrategy, &rhtbuf, dev, B_READ, BYTE, uio));
- }
- 
- htwrite(dev, uio)
- register dev_t	dev;
- register struct uio *uio;
- {
- 	htphys(dev, uio);
- 	return (physio(htstrategy, &rhtbuf, dev, B_WRITE, BYTE, uio));
- }
- 
- htphys(dev, uio)
- dev_t dev;
- register struct uio *uio;
- {
- 	daddr_t a;
- 	register struct softc *sc = &tu_softc[TUUNIT(dev)];
- 
- 	a = dbtofsb(uio->uio_offset >> 9);
- 	sc->sc_blkno = a;
- 	sc->sc_nxrec = a + 1;
  }
  
  /*ARGSUSED*/
--- 392,397 ----
