🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Steven M. Schultz Sat, 18 May 1991 06:29
/boot,/mdec/,[T]MSCP (Part 7b of 22)
#107
Author: Steven M. Schultz
Date: Sat, 18 May 1991 06:29
2300 lines
59872 bytes
Subject: Part 7b of 22 /boot,/mdec,[T]MSCP updates
Index:	/sys/<many>, /usr/src/etc/<several> 2.11BSD

Description:
Repeat-By:
Fix:
	See part 0 (the README) for the Description, the Reason and
	the instructions on how update your system.

This is part 7b of 22

Remove this introductory text and append to part 7a.  
---------------------------cut here------------------------------
*** /usr/src/sys/pdpstand.old/rk.c	Fri Aug 19 11:57:25 1988
--- /usr/src/sys/pdpstand/rk.c	Sun Apr 21 00:14:35 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rk.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.
   *
!  *	@(#)rk.c	2.0 (2.11BSD) 4/20/91
   */
  
  /*
***************
*** 15,48 ****
  #include "../pdpuba/rkreg.h"
  #include "saio.h"
  
! #define	RKADDR	((struct rkdevice *)0177400)
  
  rkstrategy(io, func)
  	register struct iob *io;
  {
  	register com;
  	daddr_t bn;
  	int dn, cn, sn;
  
  	bn = io->i_bn;
! 	dn = io->i_unit;
  	cn = bn/12;
  	sn = bn%12;
! 	RKADDR->rkda = (dn<<13) | (cn<<4) | sn;
! 	RKADDR->rkba = io->i_ma;
! 	RKADDR->rkwc = -(io->i_cc>>1);
  	com = (segflag<<4)|RKCS_GO;
  	if (func == READ)
  		com |= RKCS_RCOM;
  	else
  		com |= RKCS_WCOM;
! 	RKADDR->rkcs = com;
! 	while ((RKADDR->rkcs & RKCS_RDY) == 0)
  		continue;
! 	if (RKADDR->rkcs<0) {	/* error bit */
! 		printf("disk error: cyl=%d, sector=%d, er=%o, ds=%o\n",
! 		    cn, sn, RKADDR->rker, RKADDR->rkds);
  		return(-1);
  	}
  	return(io->i_cc);
  }
--- 15,64 ----
  #include "../pdpuba/rkreg.h"
  #include "saio.h"
  
! #define	NRK	2
  
+ 	struct	rkdevice *RKcsr[NRK + 1] =
+ 		{
+ 		(struct rkdevice *)0177400,
+ 		(struct	rkdevice *)0,
+ 		(struct rkdevice *)-1
+ 		};
+ 
  rkstrategy(io, func)
  	register struct iob *io;
  {
  	register com;
+ 	register struct rkdevice *rkaddr;
  	daddr_t bn;
  	int dn, cn, sn;
  
  	bn = io->i_bn;
! 	dn = UNITn(io->i_unit);
  	cn = bn/12;
  	sn = bn%12;
! 	rkaddr = RKcsr[CTLRn(io->i_unit)];
! 	rkaddr->rkda = (dn<<13) | (cn<<4) | sn;
! 	rkaddr->rkba = io->i_ma;
! 	rkaddr->rkwc = -(io->i_cc>>1);
  	com = (segflag<<4)|RKCS_GO;
  	if (func == READ)
  		com |= RKCS_RCOM;
  	else
  		com |= RKCS_WCOM;
! 	rkaddr->rkcs = com;
! 	while ((rkaddr->rkcs & RKCS_RDY) == 0)
  		continue;
! 	if (rkaddr->rkcs<0) {	/* error bit */
! 		printf("RK%d,%d err cy=%d sc=%d, er=%o, ds=%o\n",
! 		    CTLRn(io->i_unit), UNITn(io->i_unit), cn, sn,
! 		    rkaddr->rker, rkaddr->rkds);
  		return(-1);
  	}
  	return(io->i_cc);
+ }
+ 
+ rkopen(io)
+ 	struct iob *io;
+ {
+ 	return(genopen(NRK, io));
  }
*** /usr/src/sys/pdpstand.old/rl.c	Fri Aug 19 11:57:42 1988
--- /usr/src/sys/pdpstand/rl.c	Sun Apr 21 00:15:03 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rl.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.
   *
!  *	@(#)rl.c	2.0 (2.11BSD) 4/20/91
   */
  
  /*
***************
*** 18,31 ****
  #include "../pdpuba/rlreg.h"
  #include "saio.h"
  
! #define RLADDR	((struct rldevice *)0174400)
  
  #define	BLKRL1	10240		/* Number of UNIX blocks for an RL01 drive */
  #define BLKRL2	20480		/* Number of UNIX blocks for an RL02 drive */
  #define RLCYLSZ 10240		/* bytes per cylinder */
  #define RLSECSZ 256		/* bytes per sector */
  
! struct 
  {
  	int	cn[4];		/* location of heads for each drive */
  	int	type[4];	/* parameter dependent upon drive type  (RL01/02) */
--- 18,38 ----
  #include "../pdpuba/rlreg.h"
  #include "saio.h"
  
! #define	NRL	2
  
+ 	struct	rldevice *RLcsr[NRL + 1] =
+ 		{
+ 		(struct rldevice *)0174400,
+ 		(struct rldevice *)0,
+ 		(struct rldevice *)-1
+ 		};
+ 
  #define	BLKRL1	10240		/* Number of UNIX blocks for an RL01 drive */
  #define BLKRL2	20480		/* Number of UNIX blocks for an RL02 drive */
  #define RLCYLSZ 10240		/* bytes per cylinder */
  #define RLSECSZ 256		/* bytes per sector */
  
! struct	Rldrives
  {
  	int	cn[4];		/* location of heads for each drive */
  	int	type[4];	/* parameter dependent upon drive type  (RL01/02) */
***************
*** 39,45 ****
  		long	l;
  	} addr;			/* address of memory for transfer */
  
! }	rl = {-1,-1,-1,-1,-1,-1,-1,-1};  /* initialize cn[] and type[] */
  
  rlstrategy(io, func)
  	register struct iob *io;
--- 46,53 ----
  		long	l;
  	} addr;			/* address of memory for transfer */
  
! } rl[NRL] = {{-1,-1,-1,-1,-1,-1,-1,-1},
! 	     {-1,-1,-1,-1,-1,-1,-1,-1}};  /* initialize cn[] and type[] */
  
  rlstrategy(io, func)
  	register struct iob *io;
***************
*** 50,57 ****
  	int dif;
  	int head;
  	int ctr;
  
- 
  	/*
  	 * We must determine what type of drive we are talking to in order 
  	 * to determine how many blocks are on the device.  The rl.type[]
--- 58,67 ----
  	int dif;
  	int head;
  	int ctr;
+ 	int ctlr = CTLRn(io->i_unit);
+ 	register struct rldevice *rladdr;
+ 	register struct Rldrives *rlp;
  
  	/*
  	 * We must determine what type of drive we are talking to in order 
  	 * to determine how many blocks are on the device.  The rl.type[]
***************
*** 72,152 ****
  	 * drive type. If a valid status is not returned after eight
  	 * attempts, then an error message is printed.
  	 */
! 	drive = io->i_unit;
! 	if (rl.type[drive] < 0) {
  		ctr = 0;
  		do {
  			/* load this register; what a dumb controller */
! 			RLADDR->rlda = RLDA_RESET|RLDA_GS;
  			/* set up csr */
! 			RLADDR->rlcs = (drive << 8) | RL_GETSTATUS;
! 			while ((RLADDR->rlcs & RL_CRDY) == 0)	/* wait for it */		
  				continue;
! 		} while (((RLADDR->rlmp & 0177477) != 035) && (++ctr < 8));
  		if (ctr >= 8)
! 			printf("\nCan't get status of RL unit %d\n", drive);
! 		if (RLADDR->rlmp & RLMP_DTYP) 
! 			rl.type[drive] = BLKRL2;	/* drive is RL02 */
  		else
! 			rl.type[drive] = BLKRL1;	/* drive RL01 */
  		/*
  		 * When the device is first touched, find out where the heads are.
  		 */
  		/* find where the heads are */
! 		RLADDR->rlcs = (drive << 8) | RL_RHDR;
! 		while ((RLADDR->rlcs&RL_CRDY) == 0)
  			continue;
! 		rl.cn[drive] = ((RLADDR->rlmp) >> 6) & 01777;
  	}
! 	nblocks = rl.type[drive];	/* how many blocks on this drive */
  	if (io->i_bn >= nblocks)
  		return -1;
! 	rl.chn = io->i_bn/20;
! 	rl.sn = (io->i_bn%20) << 1;
! 	rl.bleft = io->i_cc;
! 	rl.addr.w[0] = segflag & 3;
! 	rl.addr.w[1] = (int)io->i_ma;
! 	rl.com = (drive << 8);
  	if (func == READ)
! 		rl.com |= RL_RCOM;
  	else
! 		rl.com |= RL_WCOM;
  reading:
  	/*
  	 * One has to seek an RL head, relativily.
  	 */
! 	dif =(rl.cn[drive] >> 1) - (rl.chn >>1);
! 	head = (rl.chn & 1) << 4;
  	if (dif < 0)
! 		RLADDR->rlda = (-dif <<7) | RLDA_SEEKHI | head;
  	else
! 		RLADDR->rlda = (dif << 7) | RLDA_SEEKLO | head;
! 	RLADDR->rlcs = (drive << 8) | RL_SEEK;
! 	rl.cn[drive] = rl.chn; 	/* keep current, our notion of where the heads are */
! 	if (rl.bleft < (rl.bpart = RLCYLSZ - (rl.sn * RLSECSZ)))
! 		rl.bpart = rl.bleft;
! 	while ((RLADDR->rlcs&RL_CRDY) == 0)
  		continue;
! 	RLADDR->rlda = (rl.chn << 6) | rl.sn;
! 	RLADDR->rlba = (caddr_t) rl.addr.w[1];
! 	RLADDR->rlmp = -(rl.bpart >> 1);
! 	RLADDR->rlcs = rl.com | rl.addr.w[0] << 4;
! 	while ((RLADDR->rlcs & RL_CRDY) == 0)	/* wait for completion */
  		continue;
! 	if (RLADDR->rlcs < 0) {
  		/* check error bit */
! 		if (RLADDR->rlcs & 040000) {
  			/* Drive error */
  			/*
  			 * get status from drive
  			 */
! 			RLADDR->rlda = RLDA_GS;
! 			RLADDR->rlcs = (drive << 8) | RL_GETSTATUS;
! 			while ((RLADDR->rlcs & RL_CRDY) == 0)	/* wait for controller */
  				continue;
  		}
! 		printf("Rl disk error: cyl=%d, head=%d, sector=%d, rlcs=%o, rlmp=%o\n",
! 			rl.chn>>01, rl.chn&01, rl.sn, RLADDR->rlcs, RLADDR->rlmp);
  		return(-1);
  	}
  	/*
--- 82,166 ----
  	 * drive type. If a valid status is not returned after eight
  	 * attempts, then an error message is printed.
  	 */
! 	drive = UNITn(io->i_unit);
! 	rladdr = RLcsr[ctlr];
! 	rlp = &rl[ctlr];
! 
! 	if (rlp->type[drive] < 0) {
  		ctr = 0;
  		do {
  			/* load this register; what a dumb controller */
! 			rladdr->rlda = RLDA_RESET|RLDA_GS;
  			/* set up csr */
! 			rladdr->rlcs = (drive << 8) | RL_GETSTATUS;
! 			while ((rladdr->rlcs & RL_CRDY) == 0)	/* wait for it */		
  				continue;
! 		} while (((rladdr->rlmp & 0177477) != 035) && (++ctr < 8));
  		if (ctr >= 8)
! 			printf("\nCan't get RL%d,%d sts\n", ctlr, drive);
! 		if (rladdr->rlmp & RLMP_DTYP) 
! 			rlp->type[drive] = BLKRL2;	/* drive is RL02 */
  		else
! 			rlp->type[drive] = BLKRL1;	/* drive RL01 */
  		/*
  		 * When the device is first touched, find out where the heads are.
  		 */
  		/* find where the heads are */
! 		rladdr->rlcs = (drive << 8) | RL_RHDR;
! 		while ((rladdr->rlcs&RL_CRDY) == 0)
  			continue;
! 		rlp->cn[drive] = ((rladdr->rlmp) >> 6) & 01777;
  	}
! 	nblocks = rlp->type[drive];	/* how many blocks on this drive */
  	if (io->i_bn >= nblocks)
  		return -1;
! 	rlp->chn = io->i_bn/20;
! 	rlp->sn = (io->i_bn%20) << 1;
! 	rlp->bleft = io->i_cc;
! 	rlp->addr.w[0] = segflag & 3;
! 	rlp->addr.w[1] = (int)io->i_ma;
! 	rlp->com = (drive << 8);
  	if (func == READ)
! 		rlp->com |= RL_RCOM;
  	else
! 		rlp->com |= RL_WCOM;
  reading:
  	/*
  	 * One has to seek an RL head, relativily.
  	 */
! 	dif =(rlp->cn[drive] >> 1) - (rlp->chn >>1);
! 	head = (rlp->chn & 1) << 4;
  	if (dif < 0)
! 		rladdr->rlda = (-dif <<7) | RLDA_SEEKHI | head;
  	else
! 		rladdr->rlda = (dif << 7) | RLDA_SEEKLO | head;
! 	rladdr->rlcs = (drive << 8) | RL_SEEK;
! 	rlp->cn[drive] = rlp->chn; 	/* keep current, our notion of where the heads are */
! 	if (rlp->bleft < (rlp->bpart = RLCYLSZ - (rl->sn * RLSECSZ)))
! 		rlp->bpart = rlp->bleft;
! 	while ((rladdr->rlcs&RL_CRDY) == 0)
  		continue;
! 	rladdr->rlda = (rlp->chn << 6) | rlp->sn;
! 	rladdr->rlba = (caddr_t) rlp->addr.w[1];
! 	rladdr->rlmp = -(rlp->bpart >> 1);
! 	rladdr->rlcs = rlp->com | rlp->addr.w[0] << 4;
! 	while ((rladdr->rlcs & RL_CRDY) == 0)	/* wait for completion */
  		continue;
! 	if (rladdr->rlcs < 0) {
  		/* check error bit */
! 		if (rladdr->rlcs & 040000) {
  			/* Drive error */
  			/*
  			 * get status from drive
  			 */
! 			rladdr->rlda = RLDA_GS;
! 			rladdr->rlcs = (drive << 8) | RL_GETSTATUS;
! 			while ((rladdr->rlcs & RL_CRDY) == 0)	/* wait for controller */
  				continue;
  		}
! 		printf("RL%d,%d err cy=%d, hd=%d, sc=%d, rlcs=%o, rlmp=%o\n",
! 			ctlr, drive, rlp->chn>>01, rlp->chn&01, rlp->sn, 
! 			rladdr->rlcs, rladdr->rlmp);
  		return(-1);
  	}
  	/*
***************
*** 153,163 ****
  	 * Determine if there is more to read to satisfy this request.
  	 * This is to compensate for the lacl of spiraling reads.
  	 */
! 	if ((rl.bleft -= rl.bpart) > 0) {
! 		rl.addr.l += rl.bpart;
! 		rl.sn = 0;
! 		rl.chn++;
  		goto reading;	/* read some more */
  	}
  	return(io->i_cc);
  }
--- 167,183 ----
  	 * Determine if there is more to read to satisfy this request.
  	 * This is to compensate for the lacl of spiraling reads.
  	 */
! 	if ((rlp->bleft -= rlp->bpart) > 0) {
! 		rlp->addr.l += rlp->bpart;
! 		rlp->sn = 0;
! 		rlp->chn++;
  		goto reading;	/* read some more */
  	}
  	return(io->i_cc);
+ }
+ 
+ rlopen(io)
+ 	struct iob *io;
+ {
+ 	return(genopen(NRL, io));
  }
*** /usr/src/sys/pdpstand.old/saio.h	Fri Apr 29 20:01:13 1988
--- /usr/src/sys/pdpstand/saio.h	Fri Apr 12 22:06:04 1991
***************
*** 43,48 ****
--- 43,49 ----
  	int	(*dv_strategy)();
  	int	(*dv_open)();
  	int	(*dv_close)();
+ 	caddr_t	**dv_csr;
  };
  
  struct	devsw	devsw[];
***************
*** 60,62 ****
--- 61,71 ----
   * Must be set by the user's main (or thereabouts).
   */
  int	segflag;
+ 
+ /*
+  * macros to extract the controller and unit number.  common to all drivers
+  * so the macros are defined here rather than in each driver.
+ */
+ 
+ #define	CTLRn(dev)	((minor(dev) >> 6) & 3)
+ #define	UNITn(dev)	(minor(dev) & 7)
*** /usr/src/sys/pdpstand.old/si.c	Fri Aug 19 11:58:28 1988
--- /usr/src/sys/pdpstand/si.c	Sun Apr 21 00:15:46 1991
***************
*** 3,12 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)si.c	1.1 (2.10BSD Berkeley) 12/1/86
!  */
! 
! /*
   *	SI 9500 CDC 9766 Stand Alone disk driver
   */
  
--- 3,10 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)si.c	2.0 (2.11BSD) 4/20/91
!  *
   *	SI 9500 CDC 9766 Stand Alone disk driver
   */
  
***************
*** 15,88 ****
  #include "../pdpuba/sireg.h"
  #include "saio.h"
  
! #define SIADDR ((struct sidevice *)0176700)
  
  /* defines for 9766 */
  #define NHEADS	19
  #define NSECT	32
  
  #define NSPC	NSECT*NHEADS
! static int dualsi;
  
  sistrategy(io, func)
  	register struct iob *io;
  {
! 	register unit;
! 	register ii;
  	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;
! 		ii = unit + 1;
! 		unit = bn % ii;
! 		bn /= ii;
! 		bn += io->i_boff;
! 	}
! 
  	cn = bn / (NSPC);
  	sn = bn % (NSPC);
  	tn = sn / (NSECT);
  	sn = sn % (NSECT);
  
! 	if (!dualsi) {
! 		if (SIADDR->siscr != 0)
! 			dualsi++;
  		else
! 			if ((SIADDR->sierr & (SIERR_ERR | SIERR_CNT)) == (SIERR_ERR | SIERR_CNT))
! 				dualsi++;
  	}
! 	if (dualsi)
! 		while (!(SIADDR->siscr & 0200)) {
! 			SIADDR->sicnr = SI_RESET;
! 			SIADDR->siscr = 1;
  		}
! 	SIADDR->sipcr = cn;
! 	SIADDR->sihsr = (tn << 5) + sn;
! 	SIADDR->simar = io->i_ma;
! 	SIADDR->siwcr = io->i_cc >> 1;
! 	/*
! 	 * warning: unit is being used as a temporary.
! 	 */
! 	unit = ((segflag & 03) << 4) | SI_GO;
  	if (func == READ)
! 		unit |= SI_READ;
  	else if (func == WRITE)
! 		unit |= SI_WRITE;
  	
! 	SIADDR->sicnr = unit;
  
! 	while ((SIADDR->sicnr & SI_DONE) == 0)
  		continue;
  
! 	if (SIADDR->sierr & SIERR_ERR) {
! 		printf("disk error cyl=%d head=%d sect=%d cnr=%o, err=%o\n",
! 			cn, tn, sn, SIADDR->sicnr, SIADDR->sierr);
  		return(-1);
  	}
  	return(io->i_cc);
  }
--- 13,91 ----
  #include "../pdpuba/sireg.h"
  #include "saio.h"
  
! #define	NSI	2
  
+ 	struct	sidevice *SIcsr[NSI + 1] =
+ 		{
+ 		(struct sidevice *)0176700,
+ 		(struct sidevice *)0,
+ 		(struct sidevice *)-1
+ 		};
+ 
  /* defines for 9766 */
  #define NHEADS	19
  #define NSECT	32
  
  #define NSPC	NSECT*NHEADS
! static u_char dualsi[NSI];
  
  sistrategy(io, func)
  	register struct iob *io;
  {
! 	int unit = UNITn(io->i_unit);
! 	register int ctlr = CTLRn(io->i_unit);
! 	register struct sidevice *siaddr = SIcsr[ctlr];
! 	int ii;
  	daddr_t bn;
  	int sn, cn, tn;
  
! 	/*
! 	 * weirdness with bit 2 (04) removed - see xp.c for comments
! 	 * about this
! 	*/
! 	bn = io->i_bn;
  	cn = bn / (NSPC);
  	sn = bn % (NSPC);
  	tn = sn / (NSECT);
  	sn = sn % (NSECT);
  
! 	if (!dualsi[ctlr]) {
! 		if (siaddr->siscr != 0)
! 			dualsi[ctlr]++;
  		else
! 			if ((siaddr->sierr & (SIERR_ERR | SIERR_CNT)) == (SIERR_ERR | SIERR_CNT))
! 				dualsi[ctlr]++;
  	}
! 	if (dualsi[ctlr])
! 		while (!(siaddr->siscr & 0200)) {
! 			siaddr->sicnr = SI_RESET;
! 			siaddr->siscr = 1;
  		}
! 	siaddr->sipcr = cn + (unit <<10);
! 	siaddr->sihsr = (tn << 5) + sn;
! 	siaddr->simar = io->i_ma;
! 	siaddr->siwcr = io->i_cc >> 1;
! 	ii = ((segflag & 03) << 4) | SI_GO;
  	if (func == READ)
! 		ii |= SI_READ;
  	else if (func == WRITE)
! 		ii |= SI_WRITE;
  	
! 	siaddr->sicnr = ii;
  
! 	while ((siaddr->sicnr & SI_DONE) == 0)
  		continue;
  
! 	if (siaddr->sierr & SIERR_ERR) {
! 		printf("SI%d,%d err cy=%d hd=%d sc=%d cnr=%o, err=%o\n",
! 			ctlr, unit, cn, tn, sn, siaddr->sicnr, siaddr->sierr);
  		return(-1);
  	}
  	return(io->i_cc);
+ }
+ 
+ siopen(io)
+ 	struct iob *io;
+ {
+ 	return(genopen(NSI, io));
  }
*** /usr/src/sys/pdpstand.old/srt0.s	Thu Aug 18 22:53:21 1988
--- /usr/src/sys/pdpstand/srt0.s	Tue Apr 23 21:29:33 1991
***************
*** 1,4 ****
--- 1,5 ----
  / Startup code for standalone utilities
+ / sms- mods to pass boot device and csr on to program
  / wfj- mod's to allow non sep i/d machines, error recovery
  /      note that the bootstrap passes the cputype through in
  /      r0.
***************
*** 6,12 ****
  PS	= 177776
  
  .globl	_end
! .globl	_main, __rtt
  .globl	_edata
  	jmp	start
  
--- 7,13 ----
  PS	= 177776
  
  .globl	_end
! .globl	_main, __rtt, _devsw, _ADJcsr
  .globl	_edata
  	jmp	start
  
***************
*** 31,43 ****
  /
  / restore what kind of cpu we are running on
  	mov	r0,*$_cputype	/ assume that the boot left this in r0
! / check if there is a switch register
! 	mov	$1f,nofault
! 	tst	CSW
! 	incb	_haveCSW
! 1:
! 	clr	nofault
! 	mov	$157776,sp
  	mov	$_edata,r0
  	mov	$_end,r1
  	sub	r0,r1
--- 32,40 ----
  /
  / restore what kind of cpu we are running on
  	mov	r0,*$_cputype	/ assume that the boot left this in r0
! 	mov	r1,_bootcsr	/ assume that boot left csr in r1
! 	mov	r3,_bootdev	/ and boot device major,minor in r3
! 	mov	$157772,sp	/ return address,psw at 157774&6
  	mov	$_edata,r0
  	mov	$_end,r1
  	sub	r0,r1
***************
*** 47,60 ****
  1:
  	clr	(r0)+
  	sob	r1,1b
  	jsr	pc,_main
  
! / fix up stack to point at trap ps-pc pair,
! / located at bottom of memory.
! / so we can return to the bootstrap
  
  __rtt:
! 	mov	$140000,sp
  	rtt				/ we hope!
  	br	.
  
--- 44,85 ----
  1:
  	clr	(r0)+
  	sob	r1,1b
+ 
+ / controller number is in bits 6&7 of r3 (_bootdev).  major device number
+ / is in bits 8-15.  what we need to do now is place the csr into
+ / the appropriate driver's csrlist which is indexed by controller number.
+ 
+ 	ash	$-5,r3			/ r3 = controller# * 2
+ 	mov	r3,r0			/ controller number in bits 1,2
+ 	bic	$!6,r0			/ make a word index
+ 	ash	$-3,r3			/ major device # to bits 0-7
+ 	mov	r3,r2			/ save major for later
+ 	mul	$10.,r3			/ devsw[] members are 10. bytes each
+ 	mov	_devsw+10(r3),r3	/ get csrlist for driver
+ 	add	r0,r3			/ point to controller's entry
+ 
+ / the CSR passed from the ROMs is not necessarily the first address
+ / of a device!  We therefore have to adjust the CSR so that the structure
+ / pointers in the drivers are origined at the base address rather than
+ / the ROM supplied address.  The adjustment was not stored in devsw[] to
+ / save space (can get by with an array of bytes instead of words).
+ 
+ 	movb	_ADJcsr(r2),r2		/ adjust (possibly) the CSR
+ 	mov	_bootcsr,r1
+ 	sub	r2,r1
+ 
+ 	mov	r1,(r3)			/ store controller's csr in table
  	jsr	pc,_main
  
! / fix up stack to point at trap ps-pc pair located at top of memory
! / so we can return to the bootstrap.
! /
! / the return protocol originally changed from 140000 because icheck was
! / too large.  icheck was reduced in size but the 157774 return protocol
! / was retained to allow for slightly oversized programs.
  
  __rtt:
! 	mov	$157774,sp
  	rtt				/ we hope!
  	br	.
  
***************
*** 62,90 ****
  .globl	_trap
  trap:
  	mov	*$PS,-(sp)
- 	mov	r0,-(sp)
- 	mov	r1,-(sp)
  	tst	nofault
  	bne	3f
  2:	jsr	pc,_trap
  	mov	(sp)+,r1
  	mov	(sp)+,r0
  	tst	(sp)+
  	rtt
! 3:	mov	(sp)+,r1
! 	mov	(sp)+,r0
! 	tst	(sp)+
  	mov	nofault,(sp)
  	rtt
  
  .data
! .globl	_cputype, _haveCSW
  
  nofault:	.=.+2	/ where to go on predicted trap
! _cputype:	.=.+2	/ cpu type (currently 24,40,45 or 70)
! _haveCSW:	.=.+1	/ one if there is a switch register
! KISA6 = 172354
! KISA7 = 172356
! KDSA6 = 172374
! UBMAP = 170200
! CSW   = 177570
--- 87,109 ----
  .globl	_trap
  trap:
  	mov	*$PS,-(sp)
  	tst	nofault
  	bne	3f
+ 	mov	r0,-(sp)
+ 	mov	r1,-(sp)
  2:	jsr	pc,_trap
  	mov	(sp)+,r1
  	mov	(sp)+,r0
  	tst	(sp)+
  	rtt
! 3:	tst	(sp)+
  	mov	nofault,(sp)
  	rtt
  
  .data
! .globl	_cputype, _bootcsr, _bootdev
  
  nofault:	.=.+2	/ where to go on predicted trap
! _cputype:	.=.+2	/ cpu type (currently 44, 70, 73)
! _bootdev:	.=.+2	/ makedev(major,unit) for boot device
! _bootcsr:	.=.+2	/ csr of boot controller
*** /usr/src/sys/pdpstand.old/sys.c	Wed May 23 14:50:13 1990
--- /usr/src/sys/pdpstand/sys.c	Sun Apr 21 00:18:28 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)sys.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  #include "../h/param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)sys.c	2.0 (2.11BSD) 4/20/91
   */
  
  #include "../h/param.h"
***************
*** 28,34 ****
  
  static
  openi(n, io)
! 	ino_t n;
  	register struct iob *io;
  {
  	register struct dinode *dp;
--- 28,34 ----
  
  static
  openi(n, io)
! 	register ino_t n;
  	register struct iob *io;
  {
  	register struct dinode *dp;
***************
*** 55,61 ****
  	struct iob *file;
  {
  	register char *q;
! 	char c;
  	ino_t n;
  
  	if (path==NULL || *path=='\0') {
--- 55,61 ----
  	struct iob *file;
  {
  	register char *q;
! 	register char c;
  	ino_t n;
  
  	if (path==NULL || *path=='\0') {
***************
*** 102,108 ****
  
  	ip = &io->i_ino;
  	if (bn < 0) {
! 		printf("bn negative\n");
  		return((daddr_t)0);
  	}
  
--- 102,108 ----
  
  	ip = &io->i_ino;
  	if (bn < 0) {
! 		printf("bn < 0\n");
  		return((daddr_t)0);
  	}
  
***************
*** 183,194 ****
  		return(0);
  	ip = &io->i_ino;
  	if ((ip->i_mode&IFMT)!=IFDIR) {
! 		printf("%s: not a directory mode %o ip %o\n",s, ip->i_mode, ip);
  		return(0);
  	}
  
  	if (ip->i_size==0) {
! 		printf("%s: zero length directory\n",s);
  		return(0);
  	}
  
--- 183,194 ----
  		return(0);
  	ip = &io->i_ino;
  	if ((ip->i_mode&IFMT)!=IFDIR) {
! 		printf("%s: not directory,mode %o ip %o\n",s, ip->i_mode, ip);
  		return(0);
  	}
  
  	if (ip->i_size==0) {
! 		printf("%s: 0 len directory\n",s);
  		return(0);
  	}
  
***************
*** 236,242 ****
  }
  
  lseek(fdesc, addr, ptr)
! 	int fdesc;
  	off_t addr;
  	int ptr;
  {
--- 236,242 ----
  }
  
  lseek(fdesc, addr, ptr)
! 	register int fdesc;
  	off_t addr;
  	int ptr;
  {
***************
*** 243,249 ****
  	register struct iob *io;
  
  	if (ptr != 0) {
! 		printf("Seek not from beginning of file\n");
  		return(-1);
  	}
  	fdesc -= 3;
--- 243,249 ----
  	register struct iob *io;
  
  	if (ptr != 0) {
! 		printf("illegal lseek\n");
  		return(-1);
  	}
  	fdesc -= 3;
***************
*** 325,331 ****
  }
  
  read(fdesc, buf, count)
! 	int fdesc;
  	char *buf;
  	int count;
  {
--- 325,331 ----
  }
  
  read(fdesc, buf, count)
! 	register int fdesc;
  	char *buf;
  	int count;
  {
***************
*** 364,370 ****
  }
  
  write(fdesc, buf, count)
! 	int fdesc;
  	char *buf;
  	int count;
  {
--- 364,370 ----
  }
  
  write(fdesc, buf, count)
! 	register int fdesc;
  	char *buf;
  	int count;
  {
***************
*** 410,416 ****
  	for (fdesc = 0; fdesc < NFILES; fdesc++)
  		if (iob[fdesc].i_flgs == 0)
  			goto gotfile;
! 	_stop("No more file slots");
  gotfile:
  	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
  
--- 410,416 ----
  	for (fdesc = 0; fdesc < NFILES; fdesc++)
  		if (iob[fdesc].i_flgs == 0)
  			goto gotfile;
! 	_stop("No file slots");
  gotfile:
  	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
  
***************
*** 432,446 ****
  gotdev:
  	*(cp-1) = '(';
  	file->i_ino.i_dev = dp-devsw;
! 	file->i_unit = *cp++ - '0';
! 	if (file->i_unit < 0 || file->i_unit > 7) {
! 		printf("Bad unit specifier\n");
! 		file->i_flgs = 0;
! 		return(-1);
  	}
  	if (*cp++ != ',') {
  badoff:
! 		printf("Missing offset specification\n");
  		file->i_flgs = 0;
  		return(-1);
  	}
--- 432,444 ----
  gotdev:
  	*(cp-1) = '(';
  	file->i_ino.i_dev = dp-devsw;
! 	for (file->i_unit = 0; *cp >= '0' && *cp <= '9'; cp++) {
! 		file->i_unit *= 10;
! 		file->i_unit += (*cp - '0');
  	}
  	if (*cp++ != ',') {
  badoff:
! 		printf("Missing offset\n");
  		file->i_flgs = 0;
  		return(-1);
  	}
***************
*** 452,458 ****
  			continue;
  		goto badoff;
  	}
! 	devopen(file);
  	if (*++cp == '\0') {
  		file->i_flgs |= how+1;
  		file->i_cc = 0;
--- 450,457 ----
  			continue;
  		goto badoff;
  	}
! 	if (devopen(file) < 0)
! 		return(-1);
  	if (*++cp == '\0') {
  		file->i_flgs |= how+1;
  		file->i_cc = 0;
***************
*** 464,470 ****
  		return(-1);
  	}
  	if (how != 0) {
! 		printf("Can't write files yet.. Sorry\n");
  		file->i_flgs = 0;
  		return(-1);
  	}
--- 463,469 ----
  		return(-1);
  	}
  	if (how != 0) {
! 		printf("Can't write files\n");
  		file->i_flgs = 0;
  		return(-1);
  	}
***************
*** 476,484 ****
  }
  
  close(fdesc)
! 	int fdesc;
  {
! 	struct iob *file;
  
  	fdesc -= 3;
  	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
--- 475,483 ----
  }
  
  close(fdesc)
! 	register int fdesc;
  {
! 	register struct iob *file;
  
  	fdesc -= 3;
  	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
***************
*** 537,539 ****
--- 536,562 ----
  	for (;;)
  		;
  }
+ 
+ genopen(maxctlr, io)
+ 	int maxctlr;
+ 	struct iob *io;
+ 	{
+ 	register struct devsw *dp = &devsw[io->i_ino.i_dev];
+ 	register char *cp;
+ 	register int ctlr = CTLRn(io->i_unit);
+ 	int csr;
+ 	char line[64];
+ 
+ 	if (ctlr >= maxctlr)
+ 		return(-1);
+ 	if (dp->dv_csr[ctlr])
+ 		return(0);
+ 	printf("%s%d csr[0%o]: ", dp->dv_name, ctlr, dp->dv_csr[ctlr]);
+ 	gets(line);
+ 	for (csr = 0, cp = line; *cp >= '0' && *cp <= '7'; cp++)
+ 		csr = csr * 8 + (*cp - '0');
+ 	if (csr == 0)
+ 		return(-1);
+ 	dp->dv_csr[ctlr] = (caddr_t *)csr;
+ 	return(0);
+ 	}
*** /usr/src/sys/pdpstand.old/tm.c	Fri Aug 19 11:59:26 1988
--- /usr/src/sys/pdpstand/tm.c	Sun Apr 21 00:19:06 1991
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)tm.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.
   *
!  *	@(#)tm.c	2.0 (2.11BSD) 4/20/91
   */
  
  /*
***************
*** 15,34 ****
  #include "../pdpuba/tmreg.h"
  #include "saio.h"
  
! #define	TMADDR ((struct tmdevice *)0172520)
  
  extern int tapemark;	/* flag to indicate tapemark 
  			has been encountered (see sys.c) 	*/
  
  /*
!  * Bits in deivice code.
   */
- #define	TEUNIT(dev)	((dev) & 03)
  #define	T_NOREWIND	04		/* not used in stand alone driver */
! #define	TEDENS(dev)	(((dev) & 030) >> 3)
  
! tmrew(io)
! 	register struct iob *io;
  {
  	tmstrategy(io, TM_REW);
  }
--- 15,40 ----
  #include "../pdpuba/tmreg.h"
  #include "saio.h"
  
! #define	NTM	2
  
+ 	struct	tmdevice *TMcsr[NTM + 1] =
+ 		{
+ 		(struct tmdevice *)0172520,
+ 		(struct tmdevice *)0,
+ 		(struct tmdevice *)-1
+ 		};
+ 
  extern int tapemark;	/* flag to indicate tapemark 
  			has been encountered (see sys.c) 	*/
  
  /*
!  * Bits in device code.
   */
  #define	T_NOREWIND	04		/* not used in stand alone driver */
! #define	TMDENS(dev)	(((dev) & 030) >> 3)
  
! tmclose(io)
! 	struct iob *io;
  {
  	tmstrategy(io, TM_REW);
  }
***************
*** 38,43 ****
--- 44,51 ----
  {
  	register skip;
  
+ 	if (genopen(NTM, io) < 0)
+ 		return(-1);
  	tmstrategy(io, TM_REW);
  	skip = io->i_boff;
  	while (skip--) {
***************
*** 45,50 ****
--- 53,59 ----
  		while (tmstrategy(io, TM_SFORW))
  			continue;
  	}
+ 	return(0);
  }
  
  u_short tmdens[4] = { TM_D800, TM_D1600, TM_D6250, TM_D800 };
***************
*** 52,86 ****
  tmstrategy(io, func)
  	register struct iob *io;
  {
! 	register int com, unit, errcnt;
  
! 	unit = io->i_unit;
! 	errcnt = 0;
  retry:
! 	tmquiet();
! 	com = (TEUNIT(unit)<<8)|(segflag<<4) | tmdens[TEDENS(unit)];
! 	TMADDR->tmbc = -io->i_cc;
! 	TMADDR->tmba = io->i_ma;
  	if (func == READ)
! 		TMADDR->tmcs = com | TM_RCOM | TM_GO;
  	else if (func == WRITE)
! 		TMADDR->tmcs = com | TM_WCOM | TM_GO;
  	else if (func == TM_SREV) {
! 		TMADDR->tmbc = -1;
! 		TMADDR->tmcs = com | TM_SREV | TM_GO;
  		return(0);
  	} else
! 		TMADDR->tmcs = com | func | TM_GO;
! 	while ((TMADDR->tmcs&TM_CUR) == 0)
  		continue;
! 	if (TMADDR->tmer&TMER_EOF) {
  		tapemark=1;
  		return(0);
  	}
! 	if (TMADDR->tmer & TM_ERR) {
  		if (errcnt == 0)
! 			printf("\nTM unit %d tape error: er=%o cs=%o",
! 				unit, TMADDR->tmer, TMADDR->tmcs);
  		if (errcnt++ == 10) {
  			printf("\n(FATAL ERROR)\n");
  			return(-1);
--- 61,101 ----
  tmstrategy(io, func)
  	register struct iob *io;
  {
! 	register int com, unit = UNITn(io->i_unit);
! 	register struct tmdevice *tmaddr;
! 	int errcnt = 0, ctlr = CTLRn(io->i_unit);
  
! 	tmaddr = TMcsr[ctlr];
  retry:
! 	while ((tmaddr->tmcs&TM_CUR) == 0)
! 		continue;
! 	while ((tmaddr->tmer&TMER_TUR) == 0)
! 		continue;
! 	while ((tmaddr->tmer&TMER_SDWN) != 0)
! 		continue;
! 	com = (unit<<8)|(segflag<<4) | tmdens[TMDENS(unit)];
! 	tmaddr->tmbc = -io->i_cc;
! 	tmaddr->tmba = io->i_ma;
  	if (func == READ)
! 		tmaddr->tmcs = com | TM_RCOM | TM_GO;
  	else if (func == WRITE)
! 		tmaddr->tmcs = com | TM_WCOM | TM_GO;
  	else if (func == TM_SREV) {
! 		tmaddr->tmbc = -1;
! 		tmaddr->tmcs = com | TM_SREV | TM_GO;
  		return(0);
  	} else
! 		tmaddr->tmcs = com | func | TM_GO;
! 	while ((tmaddr->tmcs&TM_CUR) == 0)
  		continue;
! 	if (tmaddr->tmer&TMER_EOF) {
  		tapemark=1;
  		return(0);
  	}
! 	if (tmaddr->tmer & TM_ERR) {
  		if (errcnt == 0)
! 			printf("\nTM%d,%d err: er=%o cs=%o",
! 				ctlr, unit, tmaddr->tmer, tmaddr->tmcs);
  		if (errcnt++ == 10) {
  			printf("\n(FATAL ERROR)\n");
  			return(-1);
***************
*** 88,104 ****
  		tmstrategy(io, TM_SREV);
  		goto retry;
  	}
! 	if (errcnt)
! 		printf("\n(RECOVERED by retry)\n");
! 	return(io->i_cc+TMADDR->tmbc);
! }
! 
! tmquiet()
! {
! 	while ((TMADDR->tmcs&TM_CUR) == 0)
! 		continue;
! 	while ((TMADDR->tmer&TMER_TUR) == 0)
! 		continue;
! 	while ((TMADDR->tmer&TMER_SDWN) != 0)
! 		continue;
  }
--- 103,107 ----
  		tmstrategy(io, TM_SREV);
  		goto retry;
  	}
! 	return(io->i_cc+tmaddr->tmbc);
  }
*** /usr/src/sys/pdpstand.old/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);
  }
*** /usr/src/sys/pdpstand.old/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);
  }
*** /usr/src/sys/pdpstand.old/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));
  }
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads