save D space in disk&tape drivers, TS&TMSCP fixes

Steven M. Schultz sms at wlv.imsd.contel.com
Wed May 29 05:46:04 AEST 1991


Subject: save D space in disc&tape drivers, TS11&TMSCP fixes
Index:	sys/pdpuba/* 2.11BSD

Description:
	This two part patch addresses several enhancments and fixes:

	1) Each disc and tape drive statically allocates at least one
	   (possibly more)  "struct buf" to be used for 'raw' I/O.  The
	   new method has the drivers passing a NULL pointer to physio()
	   and dynamically allocating a buffer header from the system pool.

	   The step of replacing the XXread and XXwrite routines with
	   common "rawread" and "rawwrite" routines was not done because
	   that involved adding a 'd_strategy' entry point in the cdevsw[]
	   table and that would cost 48 bytes of D space, negating part of the
	   space savings.  In many of the drivers the validation code and 
	   block number calculation was either removed as redundant (the 
	   strategy routine already was performing the checks) or relocated 
	   to the strategy routine.

	   Drivers are still allowed to statically allocate a raw i/o buffer
	   if needed (driver has not yet been converted for example).

	   vm_swp.c no longer has 2 statically allocated buffer headers,
	   swapping now dynamically allocates buffer headers also.

	2) The TS11 driver now supports multiple controllers.  The controller
	   number is coded in bits 6 and 7 of the minor device number now.

	3) /boot now constructs the "default" boot image name from the
	   information passed by boot ROMs.  After all, the system did
	   boot from the device, so the device name and CSR information has
	   to be correct.  Previously /boot would have to be recompiled
	   with a different RB_DEFNAME (which is not defined/used now)
	   depending on the current system disc name.

	4) The B_RH70 bit in the buffer flags word has been replaced by
	   the B_LOCKED bit and the necessary changes to ufs_bio.c made
	   to add the 'locked' queue.  At present nothing uses this, future
	   use may be to relocate the superblock information (for mounted
	   filesystems) external to the kernel.

	   The ht.c driver was the ONLY module to refer to the B_RH70 bit,
	   the driver has been modified to use a static flag word internal
	   to itself (like the other drivers which can be in a RH70 slot).

	5) Enough space was saved that the GENERIC kernel could have the
	   number of buffers raised from 20 to 32.

	6) The density selection logic in the TMSCP driver (tmscp.c) was
	   redone to support tri-density drives.  Although 4 densities
	   are defined, the middle two are identical at present.  If a
	   different choice of "middle" density was desired, it is a simple
	   matter to alter the table.  Also fixed was a minor typo in the
	   multi-controller support.

	7) /dev/MAKEDEV was modified to create the tape device nodes 
	   placing the controller number in bits 6 and 7.  Also for TMSCP
	   (tu) devices the additional nodes for tri-density drives are
	   created.  For devices such as the TK50 and TU81 the extra
	   nodes can be removed later to keep /dev smaller.

	8) in /etc/rc a blank line is output before the "skipping disk
 	   checks" message.

Repeat-By:
	Examine the code.
Fix:
	Gather both parts of this patch kit.  Apply the patches, then
	recompile and install /boot, /unix, and /netnix

	This is part 1 of 2

*** /usr/src/sys/pdpuba/tmscp.c.old	Fri May 10 20:42:24 1991
--- /usr/src/sys/pdpuba/tmscp.c	Fri May 24 22:38:01 1991
***************
*** 31,36 ****
--- 31,42 ----
   * tmscp.c - TMSCP (TK50/TU81) tape device driver
   * 
   * Modification History:
+  * 23-May-91 - sms at wlv.imsd.contel.com [2.11BSD]
+  *	Minor typo in the multicontroller support fixed.  Major overhaul
+  *	of the density selection, apparently some TMSCP controllers
+  *	do not treat 0 in the mscp_format word as meaning the highest
+  *	density, instead leaving the drive in the current/last-used
+  *	density.
   *
   * 29-Mar-91 - sms at wlv.imsd.contel.com [2.11BSD]
   *	Major changes to 1) support multiple drives per controller
***************
*** 186,191 ****
--- 192,212 ----
  
  	short	TMSvec = TMSCP_VEC;	/* patchable base of vectors */
  
+ /*
+  * The density array is indexed by the density bits (bits 3 and 4) of the
+  * minor device number AND the format menu returned for the drive.  Since
+  * only 3 densities are apparently supported by TMSCP (no DPE/3200bpi), the 
+  * second MEDium table is a copy of the first MEDium entry.
+ */
+ 
+ 	char	Dmatrix[4][8] =
+ 		{
+ /* LOW */   {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_800},
+ /* MED1 */  {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_PE },
+ /* MED2 */  {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_PE },
+ /* HI */    {0,M_TF_800,M_TF_PE,M_TF_PE,M_TF_GCR,M_TF_GCR,M_TF_GCR,M_TF_GCR}
+ 		};
+ 
  /* Software state per controller */
  
  struct tmscp_softc {
***************
*** 232,238 ****
  	short		tms_format;	/* the unit's current format (density) */
  	struct tty	*tms_ttyp;	/* record user's tty for errors */
  	struct	buf	tms_dtab;	/* I/O tape drive queues */
- 	struct	buf	tms_rtab;	/* raw I/O tape block header */
  	short		tms_online;	/* 0=available, 1=online, -1=offline */
  } tms_info[NTMS];
  
--- 253,258 ----
***************
*** 239,246 ****
  /* Bits in minor device */
  #define	TMSUNIT(dev)	(minor(dev)&03)
  #define	TMSCTLR(dev)	((minor(dev) >> 6) & 3)
  #define	T_NOREWIND	04
- #define	T_HIDENSITY	010
  
  /* Size to map in when mapping a controller's command packet area */
  #define	MAPBUFDESC	(((btoc(sizeof (struct tmscp)) - 1) << 8) | RW)
--- 259,268 ----
  /* Bits in minor device */
  #define	TMSUNIT(dev)	(minor(dev)&03)
  #define	TMSCTLR(dev)	((minor(dev) >> 6) & 3)
+ #define	TMSDENS(dev)	((minor(dev) >> 3) & 3)
+ #define	FMTMASK		(M_TF_800|M_TF_PE|M_TF_GCR)	/* = 7 */
+ 
  #define	T_NOREWIND	04
  
  /* Size to map in when mapping a controller's command packet area */
  #define	MAPBUFDESC	(((btoc(sizeof (struct tmscp)) - 1) << 8) | RW)
***************
*** 261,268 ****
  #define TMS_NOCACHE	9		/* disable cache */
  /* These go last: after all real mt cmds, just bump the numbers up */
  #define TMS_CSE		10		/* clear serious exception */
! #define TMS_LOWDENSITY	11		/* set unit to low density */
! #define TMS_HIDENSITY	12		/* set unit to high density */
  
  /*
   * Controller states
--- 283,289 ----
  #define TMS_NOCACHE	9		/* disable cache */
  /* These go last: after all real mt cmds, just bump the numbers up */
  #define TMS_CSE		10		/* clear serious exception */
! #define TMS_SETDENSITY	11		/* set unit density */
  
  /*
   * Controller states
***************
*** 358,364 ****
  	switch (sc->sc_state) {
  
  	case S_IDLE:
! 		printf("tms%d: random interrupt ignored\n", dev);
  		return;
  
  	/* Controller was in step 1 last, see if its gone to step 2 */
--- 379,385 ----
  	switch (sc->sc_state) {
  
  	case S_IDLE:
! 		printf("tms%d: random intr ignored\n", dev);
  		return;
  
  	/* Controller was in step 1 last, see if its gone to step 2 */
***************
*** 381,387 ****
  			{
  			sc->sc_state = S_IDLE;
  			sc->sc_ctab.b_active = 0;
! 			printf("failed to init, in step1: sa 0x%x", tmscpaddr->tmscpsa);
  			wakeup((caddr_t)&sc->sc_ctab);
  			return;
  			}
--- 402,408 ----
  			{
  			sc->sc_state = S_IDLE;
  			sc->sc_ctab.b_active = 0;
! 			printf("step1 init failed: sa 0x%x",tmscpaddr->tmscpsa);
  			wakeup((caddr_t)&sc->sc_ctab);
  			return;
  			}
***************
*** 409,415 ****
  			{
  			sc->sc_state = S_IDLE;
  			sc->sc_ctab.b_active = 0;
! 			printf("failed to init, in step2: sa 0x%x", tmscpaddr->tmscpsa);
  			wakeup((caddr_t)&sc->sc_ctab);
  			return;
  			}
--- 430,436 ----
  			{
  			sc->sc_state = S_IDLE;
  			sc->sc_ctab.b_active = 0;
! 			printf("step2 init failed: sa 0x%x",tmscpaddr->tmscpsa);
  			wakeup((caddr_t)&sc->sc_ctab);
  			return;
  			}
***************
*** 437,443 ****
  			{
  			sc->sc_state = S_IDLE;
  			sc->sc_ctab.b_active = 0;
! 			printf("failed to init, in step3: sa 0x%x", tmscpaddr->tmscpsa);
  			wakeup((caddr_t)&sc->sc_ctab);
  			return;
  			}
--- 458,464 ----
  			{
  			sc->sc_state = S_IDLE;
  			sc->sc_ctab.b_active = 0;
! 			printf("step3 init failed: sa 0x%x",tmscpaddr->tmscpsa);
  			wakeup((caddr_t)&sc->sc_ctab);
  			return;
  			}
***************
*** 491,497 ****
  		break;
  
  	default:
! 	    printf("tms%d: interrupt in unknown state %d ignored\n",dev,sc->sc_state);
  	    return;
  	}	/* end switch */
  
--- 512,518 ----
  		break;
  
  	default:
! 	    printf("tms%d: intr unknown state %d ignored\n",dev,sc->sc_state);
  	    return;
  	}	/* end switch */
  
***************
*** 580,586 ****
  #endif
  	if (ctlr >= NTMSCP)
  		return (ENXIO);
! 	sc = &tmscp_softc[unit];
  	if (sc->sc_addr == NULL)
  		return (ENXIO);
  	if ((tms = sc->sc_drives[unit]) == NULL) {
--- 601,607 ----
  #endif
  	if (ctlr >= NTMSCP)
  		return (ENXIO);
! 	sc = &tmscp_softc[ctlr];
  	if (sc->sc_addr == NULL)
  		return (ENXIO);
  	if ((tms = sc->sc_drives[unit]) == NULL) {
***************
*** 600,606 ****
  		if (sc->sc_state == S_IDLE)
  			if(!tkini(sc))
  				{
! 				printf("tms%d failed to init\n", ctlr);
  				(void) splx(s);
  				return(ENXIO);
  				}
--- 621,627 ----
  		if (sc->sc_state == S_IDLE)
  			if(!tkini(sc))
  				{
! 				printf("tms%d init failed\n", ctlr);
  				(void) splx(s);
  				return(ENXIO);
  				}
***************
*** 672,686 ****
  		goto oops;
  	tms->tms_lastiow = 0;
  	/*
! 	 * If the high density device is not specified, set unit to low
! 	 * density.  This is done as an "internal" ioctl command so
  	 * that the command setup and response handling
  	 * is done thru "regular" command routines.
  	 */
! 	if ((minor(dev) & T_HIDENSITY) == 0)
! 		tmscpcommand(dev, TMS_LOWDENSITY, 1);
! 	else
! 		tmscpcommand(dev, TMS_HIDENSITY, 1);
  	return (0);
  }
  
--- 693,704 ----
  		goto oops;
  	tms->tms_lastiow = 0;
  	/*
! 	 * Set unit density using the density matrix.
! 	 * This is done as an "internal" ioctl command so
  	 * that the command setup and response handling
  	 * is done thru "regular" command routines.
  	 */
! 	tmscpcommand(dev, TMS_SETDENSITY, 1);
  	return (0);
  }
  
***************
*** 923,929 ****
  	register struct buf *bp, *dp;
  	register struct tms_info *tms;
  	struct   tmscpdevice *tmscpaddr;
! 	int i;
  	segm seg5;
  
       saveseg5(seg5);		/* save just once at top */
--- 941,947 ----
  	register struct buf *bp, *dp;
  	register struct tms_info *tms;
  	struct   tmscpdevice *tmscpaddr;
! 	int i, unit;
  	segm seg5;
  
       saveseg5(seg5);		/* save just once at top */
***************
*** 950,964 ****
  		continue;		/* Need to check for loop */
  		}
  	sc->sc_ctab.b_active++;
  	tmscpaddr = (struct tmscpdevice *)sc->sc_addr;
! 	tms = sc->sc_drives[TMSUNIT(bp->b_dev)];
  	if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN)
  		{
  		tprintf(tms->tms_ttyp,
! 		    "tms%d,%d: hard error bn%ld\n", sc->sc_unit,
! 		    TMSUNIT(bp->b_dev), bp->b_blkno);
! 		log(TMS_PRI, "tms%d,%d: sa 0%o, state %d\n", sc->sc_unit,
! 			TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa, sc->sc_state);
  		(void)tkini(sc);
  		/* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */
  		break;
--- 968,983 ----
  		continue;		/* Need to check for loop */
  		}
  	sc->sc_ctab.b_active++;
+ 	unit = TMSUNIT(bp->b_dev);
  	tmscpaddr = (struct tmscpdevice *)sc->sc_addr;
! 	tms = sc->sc_drives[unit];
  	if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN)
  		{
  		tprintf(tms->tms_ttyp,
! 		    "tms%d,%d: hard error bn%ld\n", sc->sc_unit, unit,
! 		    bp->b_blkno);
! 		log(TMS_PRI, "tms%d,%d: sa 0%o state %d\n", sc->sc_unit,
! 			unit, tmscpaddr->tmscpsa, sc->sc_state);
  		(void)tkini(sc);
  		/* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */
  		break;
***************
*** 974,980 ****
  			break;
  		mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  		mp->mscp_opcode = M_OP_ONLIN;
! 		mp->mscp_unit = TMSUNIT(bp->b_dev);
  		dp->b_active = 2;
  		sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */
  		((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT;
--- 993,999 ----
  			break;
  		mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  		mp->mscp_opcode = M_OP_ONLIN;
! 		mp->mscp_unit = unit;
  		dp->b_active = 2;
  		sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */
  		((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT;
***************
*** 989,995 ****
  		break;
  	mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  	mp->mscp_cmdref = (u_short)bp;		/* pointer to get back */
! 	mp->mscp_unit = TMSUNIT(bp->b_dev);
  	/*
  	 * If its an ioctl-type command then set up the appropriate
  	 * tmscp command;  by doing a switch on the "b_resid" field where
--- 1008,1014 ----
  		break;
  	mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  	mp->mscp_cmdref = (u_short)bp;		/* pointer to get back */
! 	mp->mscp_unit = unit;
  	/*
  	 * If its an ioctl-type command then set up the appropriate
  	 * tmscp command;  by doing a switch on the "b_resid" field where
***************
*** 1075,1106 ****
  			tms->tms_serex = 0;
  			tms->tms_clserex = 1;
  			break;
! 		case TMS_LOWDENSITY:
  			/*
! 			 * Set the unit to low density
  			 */
  			mp->mscp_opcode = M_OP_STUNT;
  			mp->mscp_unitflgs = tms->tms_unitflgs;
  			mp->mscp_mediaid = 0;	/* default device dependant parameters */
! 			if ((tms->tms_fmtmenu & M_TF_800) != 0)
! 				mp->mscp_format = M_TF_800;
! 			else
! 				mp->mscp_format = M_TF_PE & tms->tms_fmtmenu;
  			tms->tms_format = mp->mscp_format;
  			break;
- 		case TMS_HIDENSITY:
- 			/*
- 			 * Set the unit to high density (format == 0)
- 			 */
- 			mp->mscp_opcode = M_OP_STUNT;
- 			mp->mscp_unitflgs = tms->tms_unitflgs;
- 			mp->mscp_mediaid = 0;	/* default device dependant parameters */
- 			mp->mscp_format = 0;
- 			tms->tms_format = 0;
- 			break;
  		default:
! 			printf("Bad ioctl on tms%d,%d\n", sc->sc_unit,
! 				TMSUNIT(bp->b_dev));
  			/* Need a no-op. Reposition no amount */
  			mp->mscp_opcode = M_OP_REPOS;
  			break;
--- 1094,1115 ----
  			tms->tms_serex = 0;
  			tms->tms_clserex = 1;
  			break;
! 		case TMS_SETDENSITY:
  			/*
! 			 * Set the unit density
  			 */
  			mp->mscp_opcode = M_OP_STUNT;
  			mp->mscp_unitflgs = tms->tms_unitflgs;
  			mp->mscp_mediaid = 0;	/* default device dependant parameters */
! 			mp->mscp_format = Dmatrix[TMSDENS(bp->b_dev)][tms->tms_fmtmenu & FMTMASK];
! #ifdef	TMSCP_DEBUG
! 			printd("b_dev: 0%o fmtmenu: 0%o format: 0%o\n", bp->b_dev, tms->tms_fmtmenu, mp->mscp_format);
! 			delay(4000000L);
! #endif
  			tms->tms_format = mp->mscp_format;
  			break;
  		default:
! 			printf("tms%d,%d bad ioctl\n",sc->sc_unit,mp->mscp_unit);
  			/* Need a no-op. Reposition no amount */
  			mp->mscp_opcode = M_OP_REPOS;
  			break;
***************
*** 1147,1153 ****
  	if (tmscpaddr->tmscpsa&TMSCP_ERR)
  		{
  		printf("tms%d,%d: fatal error 0%o\n",sc->sc_unit, 
! 			TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa);
  		(void)tkini(sc);
  		break;
  		}
--- 1156,1162 ----
  	if (tmscpaddr->tmscpsa&TMSCP_ERR)
  		{
  		printf("tms%d,%d: fatal error 0%o\n",sc->sc_unit, 
! 			mp->mscp_unit, tmscpaddr->tmscpsa);
  		(void)tkini(sc);
  		break;
  		}
***************
*** 1310,1316 ****
  		 * of 0200 instead of the 0241 (read) that was expected.
  		 */
  			
! 		printf("tms%d,%d: invalid cmd, endcode = %o, status=%o\n",
  			sc->sc_unit, mp->mscp_unit, mp->mscp_opcode, st);
  common:	/* GTUNT finishes up thru here too */
  		bp = (struct buf *)mp->mscp_cmdref;
--- 1319,1325 ----
  		 * of 0200 instead of the 0241 (read) that was expected.
  		 */
  			
! 		printf("tms%d,%d: invalid cmd endcode = %o status=%o\n",
  			sc->sc_unit, mp->mscp_unit, mp->mscp_opcode, st);
  common:	/* GTUNT finishes up thru here too */
  		bp = (struct buf *)mp->mscp_cmdref;
***************
*** 1412,1422 ****
  	case M_OP_GTUNT|M_OP_END:
  #ifdef TMSCP_DEBUG
  		printd("tmscprsp: GTUNT end packet status = 0%o\n",st);
! 		printd("tmscprsp: %d,%d mediaid 0x%lx %x %x format=%d\n",
  		    sc->sc_unit,mp->mscp_unit, mp->mscp_mediaid
  		    ,mp->mscp_unitid.val[0]
  		    ,mp->mscp_unitid.val[1]
! 		    ,mp->mscp_format);
  #endif
  		tms->tms_type = mp->mscp_mediaid;
  		tms->tms_fmtmenu = mp->mscp_fmtmenu;
--- 1421,1431 ----
  	case M_OP_GTUNT|M_OP_END:
  #ifdef TMSCP_DEBUG
  		printd("tmscprsp: GTUNT end packet status = 0%o\n",st);
! 		printd("tmscprsp: %d,%d mediaid 0x%lx 0x%lx 0x%lx format=%d speed = %d\n",
  		    sc->sc_unit,mp->mscp_unit, mp->mscp_mediaid
  		    ,mp->mscp_unitid.val[0]
  		    ,mp->mscp_unitid.val[1]
! 		    ,mp->mscp_format, mp->mscp_speed);
  #endif
  		tms->tms_type = mp->mscp_mediaid;
  		tms->tms_fmtmenu = mp->mscp_fmtmenu;
***************
*** 1424,1430 ****
  		goto common;	/* need to dequeue buffer and do iodone() */
  
  	default:
! 		printf("tms %d,%d unknown packet\n", sc->sc_unit,mp->mscp_unit);
  		tmserror(sc->sc_unit, (struct mslg *)mp);
  	}	/* end switch mp->mscp_opcode */
  }
--- 1433,1439 ----
  		goto common;	/* need to dequeue buffer and do iodone() */
  
  	default:
! 		printf("tms%d,%d unknown packet\n", sc->sc_unit,mp->mscp_unit);
  		tmserror(sc->sc_unit, (struct mslg *)mp);
  	}	/* end switch mp->mscp_opcode */
  }
***************
*** 1628,1647 ****
  }
  #endif TMSCP_DUMP
  
- struct buf *
- tmsrtab(dev)
- 	register dev_t dev;
- {
- 	register struct tmscp_softc *sc = &tmscp_softc[TMSCTLR(dev)];
- 
- 	return(&sc->sc_drives[TMSUNIT(dev)]->tms_rtab);
- }
- 
  tmscpread(dev, uio)
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(tmscpstrategy, tmsrtab(dev), dev, B_READ, BYTE, uio));
  }
  
  tmscpwrite(dev, uio)
--- 1637,1647 ----
  }
  #endif TMSCP_DUMP
  
  tmscpread(dev, uio)
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(tmscpstrategy, (struct buf *)NULL, dev, B_READ, BYTE, uio));
  }
  
  tmscpwrite(dev, uio)
***************
*** 1648,1654 ****
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(tmscpstrategy, tmsrtab(dev), dev, B_WRITE, BYTE, uio));
  }
  
  /*
--- 1648,1654 ----
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(tmscpstrategy, (struct buf *)NULL, dev, B_WRITE, BYTE, uio));
  }
  
  /*
***************
*** 1750,1762 ****
  	printd("tmserror:\n");
  #endif
  	if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
! 		log(TMS_PRI, "tms%d,%d: %s err, ", ctlr, mp->mslg_unit,
  		mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
  
  	switch (mp->mslg_format) {
  
  	case M_FM_CNTERR:
! 		log(TMS_PRI, "ctlr err, event 0%o\n", mp->mslg_event);
  		break;
  	case M_FM_BUSADDR:
  		log(TMS_PRI, "host memory access err, event 0%o, addr 0%o\n",
--- 1750,1762 ----
  	printd("tmserror:\n");
  #endif
  	if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
! 		log(TMS_PRI, "tms%d,%d: %s err ", ctlr, mp->mslg_unit,
  		mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
  
  	switch (mp->mslg_format) {
  
  	case M_FM_CNTERR:
! 		log(TMS_PRI, "ctlr err event 0%o\n", mp->mslg_event);
  		break;
  	case M_FM_BUSADDR:
  		log(TMS_PRI, "host memory access err, event 0%o, addr 0%o\n",
***************
*** 1763,1773 ****
  			mp->mslg_event, mp->mslg_busaddr);
  		break;
  	case M_FM_TAPETRN:
! 		log(TMS_PRI, "tape transfer err, unit %d, grp 0x%x, event 0%o\n",
  			mp->mslg_unit, mp->mslg_group, mp->mslg_event);
  		break;
  	case M_FM_STIERR:
! 		log(TMS_PRI, "STI err, unit %d, event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  #ifdef notdef
  		/* too painful to do with log() */
--- 1763,1773 ----
  			mp->mslg_event, mp->mslg_busaddr);
  		break;
  	case M_FM_TAPETRN:
! 		log(TMS_PRI, "tape transfer err unit %d grp 0x%x event 0%o\n",
  			mp->mslg_unit, mp->mslg_group, mp->mslg_event);
  		break;
  	case M_FM_STIERR:
! 		log(TMS_PRI, "STI err unit %d event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  #ifdef notdef
  		/* too painful to do with log() */
***************
*** 1777,1791 ****
  #endif
  		break;
  	case M_FM_STIDEL:
! 		log(TMS_PRI, "STI Drive Error Log, unit %d, event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  		break;
  	case M_FM_STIFEL:
! 		log(TMS_PRI, "STI Formatter Error Log, unit %d, event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  		break;
  	default:
! 		log(TMS_PRI, "unknown err, %d,%d, format 0%o, event 0%o\n",
  			ctlr,mp->mslg_unit, mp->mslg_format, mp->mslg_event);
  	}
  
--- 1777,1791 ----
  #endif
  		break;
  	case M_FM_STIDEL:
! 		log(TMS_PRI, "STI Drive ErrorLog unit %d event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  		break;
  	case M_FM_STIFEL:
! 		log(TMS_PRI, "STI Formatter ErrorLog unit %d event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  		break;
  	default:
! 		log(TMS_PRI, "unknown err %d,%d format 0%o event 0%o\n",
  			ctlr,mp->mslg_unit, mp->mslg_format, mp->mslg_event);
  	}
  
*** /usr/src/sys/pdpuba/ra.c.old	Fri May 10 20:40:03 1991
--- /usr/src/sys/pdpuba/ra.c	Sun May 19 01:14:45 1991
***************
*** 174,180 ****
  	daddr_t		ra_dsize;	/* Max user size from online pkt */
  	short		ra_unit;	/* controller unit # */
  	struct	buf	ra_dtab;	/* I/O disk drive queues */
- 	struct	buf	ra_rtab;	/* raw I/O disk block header */
  } ra_infoT;
  
  typedef	struct	{
--- 174,179 ----
***************
*** 489,508 ****
  	return;
  }
  
- struct buf *
- rartab(dev)
- 	register dev_t dev;
- {
- 	register ra_softcT *sc = &ra_sc[RACON(dev)];
- 
- 	return(&sc->sc_drives[RAUNIT(dev)]->ra_rtab);
- }
- 
  raread(dev, uio)
  	register dev_t 	dev;
  	struct	uio *uio;
  {
! 	return(physio(rastrategy, rartab(dev), dev, B_READ, WORD, uio));
  }
  
  rawrite(dev, uio)
--- 488,498 ----
  	return;
  }
  
  raread(dev, uio)
  	register dev_t 	dev;
  	struct	uio *uio;
  {
! 	return(physio(rastrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  rawrite(dev, uio)
***************
*** 509,515 ****
  	register dev_t 	dev;
  	struct	uio *uio;
  {
! 	return(physio(rastrategy, rartab(dev), dev, B_WRITE, WORD, uio));
  }
  
  /* Start i/o, must be called at level splbio */
--- 499,505 ----
  	register dev_t 	dev;
  	struct	uio *uio;
  {
! 	return(physio(rastrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  /* Start i/o, must be called at level splbio */
***************
*** 996,1002 ****
  		ra_error((caddr_t)mp);
  	}
  }
- 
  
  /*
   * Init disk info structure from data in mscp packet
--- 986,991 ----
*** /usr/src/sys/pdpuba/br.c.old	Tue Apr  3 17:36:33 1990
--- /usr/src/sys/pdpuba/br.c	Sun May 19 18:00:55 1991
***************
*** 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;
  
--- 115,121 ----
  #ifdef UCB_METER
  static int br_dkn = -1;
  #endif
! struct buf brtab;
  struct br_char *br_disk[NBR];
  struct brdevice *Br_addr;
  
***************
*** 358,364 ****
  	int dev;
  	struct uio *uio;
  {
! 	return(physio(brstrategy, &rbrbuf, dev, B_READ, WORD, uio));
  }
  
  brwrite(dev, uio)
--- 358,364 ----
  	int dev;
  	struct uio *uio;
  {
! 	return(physio(brstrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  brwrite(dev, uio)
***************
*** 365,371 ****
  	int dev;
  	struct uio *uio;
  {
! 	return(physio(brstrategy, &rbrbuf, dev, B_WRITE, WORD, uio));
  }
  
  #ifdef BR_DUMP
--- 365,371 ----
  	int dev;
  	struct uio *uio;
  {
! 	return(physio(brstrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  #ifdef BR_DUMP
*** /usr/src/sys/pdpuba/dr.c.old	Tue Apr  3 16:43:20 1990
--- /usr/src/sys/pdpuba/dr.c	Sun May 19 18:02:54 1991
***************
*** 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 ----
***************
*** 206,213 ****
  	dev_t dev;
  	struct uio *uio;
  {
! 	return (physio(drstrategy, &dr11[minor(dev) & 07].i_buf,
! 	    dev, B_READ, WORD, uio));
  }
  
  drwrite(dev, uio)
--- 205,211 ----
  	dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(drstrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  drwrite(dev, uio)
***************
*** 214,221 ****
  	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)
--- 212,218 ----
  	dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(drstrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  drioctl(dev, cmd, data, flag)
*** /usr/src/sys/pdpuba/hk.c.old	Tue Oct 23 18:00:15 1990
--- /usr/src/sys/pdpuba/hk.c	Sun May 19 18:07:02 1991
***************
*** 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 ----
***************
*** 511,517 ****
  	dev_t dev;
  	struct uio *uio;
  {
! 	return (physio(hkstrategy, &rhkbuf[hkunit(dev)], dev, B_READ, WORD, uio));
  }
  
  hkwrite(dev, uio)
--- 510,516 ----
  	dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(hkstrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  hkwrite(dev, uio)
***************
*** 518,524 ****
  	dev_t dev;
  	struct uio *uio;
  {
! 	return (physio(hkstrategy, &rhkbuf[hkunit(dev)], dev, B_WRITE, WORD, uio));
  }
  
  #ifdef HK_DUMP
--- 517,523 ----
  	dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(hkstrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  #ifdef HK_DUMP
*** /usr/src/sys/pdpuba/rk.c.old	Tue Apr  3 13:32:23 1990
--- /usr/src/sys/pdpuba/rk.c	Sun May 19 18:09:55 1991
***************
*** 26,32 ****
  struct	rkdevice *RKADDR;
  
  struct	buf	rktab;
- struct	buf	rrkbuf[NRK];
  
  #define	rkunit(dev)	minor(dev)
  
--- 26,31 ----
***************
*** 172,178 ****
  	register dev_t dev;
  	struct	uio *uio;
  {
! 	return (physio(rkstrategy, &rrkbuf[rkunit(dev)], dev, B_READ, WORD, uio));
  }
  
  rkwrite(dev, uio)
--- 171,177 ----
  	register dev_t dev;
  	struct	uio *uio;
  {
! 	return(physio(rkstrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  rkwrite(dev, uio)
***************
*** 179,184 ****
  	register dev_t dev;
  	struct	uio *uio;
  {
! 	return (physio(rkstrategy, &rrkbuf[rkunit(dev)], dev, B_WRITE, WORD, uio));
  }
  #endif NRK
--- 178,183 ----
  	register dev_t dev;
  	struct	uio *uio;
  {
! 	return(physio(rkstrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  #endif NRK
*** /usr/src/sys/pdpuba/rl.c.old	Wed Apr 24 20:51:12 1991
--- /usr/src/sys/pdpuba/rl.c	Sun May 19 18:11:00 1991
***************
*** 34,40 ****
  
  static	int	q22bae = 1;
  
- struct	buf	rrlbuf[NRL];	/* Raw header for each drive */
  struct	buf	rlutab[NRL];	/* Seek structure for each device */
  struct	buf	rltab;
  
--- 34,39 ----
***************
*** 296,302 ****
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return (physio(rlstrategy, &rrlbuf[minor(dev)], dev, B_READ, WORD, uio));
  }
  
  rlwrite(dev, uio)
--- 295,301 ----
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(rlstrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  rlwrite(dev, uio)
***************
*** 303,309 ****
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return (physio(rlstrategy, &rrlbuf[minor(dev)], dev, B_WRITE, WORD, uio));
  }
  
  /*
--- 302,308 ----
  	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(rlstrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  /*
*** /usr/src/sys/pdpuba/rx.c.old	Tue Apr  3 11:10:34 1990
--- /usr/src/sys/pdpuba/rx.c	Sun May 19 18:11:46 1991
***************
*** 53,59 ****
  #define	seccnt(bp)	((int)((bp)->b_seccnt))
  
  struct	buf	rxtab;
- struct	buf	rrxbuf;
  struct	buf	crxbuf;		/* buffer header for control functions */
  
  /*
--- 53,58 ----
***************
*** 303,309 ****
  	dev_t dev;
  	struct uio *uio;
  {
! 	return (physio(rxstrategy, &rrxbuf, dev, B_READ, WORD, uio));
  }
  
  
--- 302,308 ----
  	dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(rxstrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  
***************
*** 311,317 ****
  	dev_t dev;
  	struct uio *uio;
  {
! 	return (physio(rxstrategy, &rrxbuf, dev, B_WRITE, WORD, uio));
  }
  
  /*
--- 310,316 ----
  	dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(rxstrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  /*
*** /usr/src/sys/pdpuba/si.c.old	Tue Apr  3 09:59:43 1990
--- /usr/src/sys/pdpuba/si.c	Sun May 19 18:12:30 1991
***************
*** 59,65 ****
  int	si_offset[] = { SI_OFP,	SI_OFM };
  
  struct	buf	sitab;
- struct	buf	rsibuf;
  struct	buf	siutab[NSI];
  
  int	sicc[NSI];	/* Current cylinder */
--- 59,64 ----
***************
*** 404,410 ****
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return (physio(sistrategy, &rsibuf, dev, B_READ, WORD, uio));
  }
  
  siwrite(dev, uio)
--- 403,409 ----
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return(physio(sistrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  siwrite(dev, uio)
***************
*** 411,417 ****
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return (physio(sistrategy, &rsibuf, dev, B_WRITE, WORD, uio));
  }
  
  #ifdef SI_DUMP
--- 410,416 ----
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return(physio(sistrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  #ifdef SI_DUMP
*** /usr/src/sys/pdpuba/xp.c.old	Fri May 10 21:54:44 1991
--- /usr/src/sys/pdpuba/xp.c	Sun May 19 18:14:35 1991
***************
*** 273,279 ****
  #endif
  
  struct	buf	xptab;
- struct	buf	rxpbuf[NXPD];
  struct	buf	xputab[NXPD];
  
  #ifdef BADSECT
--- 273,278 ----
***************
*** 886,892 ****
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return (physio(xpstrategy, &rxpbuf[xpunit(dev)], dev, B_READ, WORD, uio));
  }
  
  xpwrite(dev, uio)
--- 885,891 ----
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return(physio(xpstrategy, (struct buf *)NULL, dev, B_READ, WORD, uio));
  }
  
  xpwrite(dev, uio)
***************
*** 893,899 ****
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return (physio(xpstrategy, &rxpbuf[xpunit(dev)], dev, B_WRITE, WORD, uio));
  }
  
  
--- 892,898 ----
  	dev_t	dev;
  	struct uio *uio;
  {
! 	return(physio(xpstrategy, (struct buf *)NULL, dev, B_WRITE, WORD, uio));
  }
  
  
*** /usr/src/sys/pdpuba/tm.c.old	Tue Apr  3 21:47:56 1990
--- /usr/src/sys/pdpuba/tm.c	Thu May 23 17:41:36 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) 5/22/91
   */
  
  /*
***************
*** 28,39 ****
  
  struct	buf	tmtab;
  struct	buf	ctmbuf;
- /*
-  * Raw tape operations use rtmbuf.  The driver notices when rtmbuf is being
-  * used and allows the user program to continue after errors and read records
-  * not of the standard length (DEV_BSIZE).
-  */
- struct	buf	rtmbuf;
  
  /*
   * Software state per tape transport:
--- 28,33 ----
***************
*** 244,254 ****
  register struct buf *bp;
  {
  	register s;
  
  #ifdef UNIBUS_MAP
- 	if (bp != &ctmbuf)
  		mapalloc(bp);
  #endif
  	bp->av_forw = NULL;
  	s = splbio();
  	if (tmtab.b_actf == NULL)
--- 238,252 ----
  register struct buf *bp;
  {
  	register s;
+ 	register struct te_softc *sc = &te_softc[TEUNIT(bp->b_dev)];
  
+ 	if (bp->b_flags & B_PHYS) {
  #ifdef UNIBUS_MAP
  		mapalloc(bp);
  #endif
+ 		sc->sc_blkno = sc->sc_nxrec = dbtofsb(bp->b_blkno);
+ 		sc->sc_nxrec++;
+ 	}
  	bp->av_forw = NULL;
  	s = splbio();
  	if (tmtab.b_actf == NULL)
***************
*** 325,331 ****
  	/*
  	 * The following checks handle boundary cases for operation
  	 * on non-raw tapes.  On raw tapes the initialization of
! 	 * sc->sc_nxrec by tmphys causes them to be skipped normally
  	 * (except in the case of retries).
  	 */
  	if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) {
--- 323,329 ----
  	/*
  	 * The following checks handle boundary cases for operation
  	 * on non-raw tapes.  On raw tapes the initialization of
! 	 * sc->sc_nxrec on entry causes them to be skipped normally
  	 * (except in the case of retries).
  	 */
  	if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) {
***************
*** 339,345 ****
  	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 writei.
  		 */
  		bp->b_resid = bp->b_bcount;
  		goto next;
--- 337,343 ----
  	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;
***************
*** 463,469 ****
  		 * If we were reading raw tape and the only error was that the
  		 * record was too long, then we don't consider this an error.
  		 */
! 		if (bp == &rtmbuf && (bp->b_flags & B_READ) &&
  		    (tmaddr->tmer & (TMER_HARD | TMER_SOFT)) == TMER_RLE)
  			goto ignoreerr;
  		/*
--- 461,467 ----
  		 * If we were reading raw tape and the only error was that the
  		 * record was too long, then we don't consider this an error.
  		 */
! 		if ((bp->b_flags & B_PHYS) && (bp->b_flags & B_READ) &&
  		    (tmaddr->tmer & (TMER_HARD | TMER_SOFT)) == TMER_RLE)
  			goto ignoreerr;
  		/*
***************
*** 480,486 ****
  			 * Hard or non-i/o errors on non-raw tape
  			 * cause it to close.
  			 */
! 			if (sc->sc_openf > 0 && bp != &rtmbuf)
  				sc->sc_openf = -1;
  		/*
  		 * Couldn't recover error
--- 478,484 ----
  			 * Hard or non-i/o errors on non-raw tape
  			 * cause it to close.
  			 */
! 			if (sc->sc_openf > 0 && !(bp->b_flags & B_PHYS))
  				sc->sc_openf = -1;
  		/*
  		 * Couldn't recover error
***************
*** 575,617 ****
  }
  
  tmread(dev, uio)
! register dev_t dev;
! register struct uio *uio;
  {
! 	int errno;
! 
! 	errno = tmphys(dev, uio);
! 	if (errno)
! 		return (errno);
! 	return (physio(tmstrategy, &rtmbuf, dev, B_READ, BYTE, uio));
  }
  
  tmwrite(dev, uio)
! register dev_t dev;
! register struct uio *uio;
  {
! 	int errno;
! 
! 	errno = tmphys(dev, uio);
! 	if (errno)
! 		return (errno);
! 	return (physio(tmstrategy, &rtmbuf, dev, B_WRITE, BYTE, uio));
! }
! 
! /*
!  * Set up sc_blkno and sc_nxrec
!  * so that the tape will appear positioned correctly.
!  */
! tmphys(dev, uio)
! dev_t dev;
! register struct uio *uio;
! {
! 	daddr_t a;
! 	register struct te_softc *sc = &te_softc[TEUNIT(dev)];
! 
! 	a = dbtofsb(uio->uio_offset >> 9);
! 	sc->sc_blkno = a;
! 	sc->sc_nxrec = a + 1;
  }
  
  /*ARGSUSED*/
--- 573,589 ----
  }
  
  tmread(dev, uio)
! 	dev_t dev;
! 	struct uio *uio;
  {
! 	return(physio(tmstrategy, (struct buf *)NULL, dev, B_READ, BYTE, uio));
  }
  
  tmwrite(dev, uio)
! 	dev_t dev;
! 	struct uio *uio;
  {
! 	return(physio(tmstrategy, (struct buf *)NULL, dev, B_WRITE, BYTE, uio));
  }
  
  /*ARGSUSED*/
*** /usr/src/sys/pdpuba/ts.c.old	Tue Apr  3 09:55:25 1990
--- /usr/src/sys/pdpuba/ts.c	Fri May 24 20:46:13 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) 5/23/91
   */
  
  /*
***************
*** 36,41 ****
--- 36,42 ----
   */
  
  struct	ts_softc {
+ 	struct	tsdevice *sc_addr; /* CSR of controller */
  	char	sc_openf;	/* lock against multiple opens */
  	char	sc_lastiow;	/* last op was a write */
  	short	sc_resid;	/* copy of last bc */
***************
*** 49,57 ****
  	ubadr_t	sc_uadr;	/* actual unibus address */
  	short	sc_mapped;	/* is sc_cmd mapped in Unibus space? */
  #endif
! } *ts_softc;
  
! struct	buf	tstab;
  
  /*
   * There is a ctsbuf per tape controller.
--- 50,58 ----
  	ubadr_t	sc_uadr;	/* actual unibus address */
  	short	sc_mapped;	/* is sc_cmd mapped in Unibus space? */
  #endif
! } *ts_softc[NTS];
  
! struct	buf	tstab[NTS];
  
  /*
   * There is a ctsbuf per tape controller.
***************
*** 61,86 ****
   * the user process but any further attempts to use the tape drive
   * before the rewind completes will hang waiting for ctsbuf.
   */
! struct	buf	ctsbuf;
  
- /*
-  * Raw tape operations use rtsbuf.  The driver
-  * notices when rtsbuf is being used and allows the user
-  * program to continue after errors and read records
-  * not of the standard length (DEV_BSIZE).
-  */
- struct	buf	rtsbuf;
- 
- struct	tsdevice *TSADDR;
- 
  #define	INF		((daddr_t) ((u_short) 65535))
  
  /* bits in minor device */
! #define	TSUNIT(dev)	(minor(dev)&03)
  #define	T_NOREWIND	04
  
- 	/* command code definitions */
- 
  /*
   * States for tstab.b_active, the state flag.
   * This is used to sequence control in the driver.
--- 62,76 ----
   * the user process but any further attempts to use the tape drive
   * before the rewind completes will hang waiting for ctsbuf.
   */
! struct	buf	ctsbuf[NTS];
  
  #define	INF		((daddr_t) ((u_short) 65535))
  
  /* bits in minor device */
! #define	TSUNIT(dev)	(minor(dev)&03)		/* not used */
! #define	TSCTLR(dev)	((minor(dev) >> 6) & 3)
  #define	T_NOREWIND	04
  
  /*
   * States for tstab.b_active, the state flag.
   * This is used to sequence control in the driver.
***************
*** 94,117 ****
  
  tsattach(addr, unit)
  struct tsdevice *addr;
  {
  	/*
! 	 * This driver supports only one controller.
  	 */
! 	if (unit == 0) {
! 		/*
! 		 * We want space for an array of NTS ts_softc structures,
! 		 * where the sc_cmd field of each is long-aligned, i.e. the
! 		 * core address is a 4-byte multiple.  The compiler only
! 		 * guarantees word alignment.  We reserve and extra 3 bytes
! 		 * so that we can slide the array down by 2 if the compiler
! 		 * gets it wrong.
! 		 */
! 		ts_softc = (struct ts_softc *)((u_short)softspace + 3 & ~3);
! 		TSADDR = addr;
! 		return(1);
! 	}
! 	return(0);
  }
  
  /*
--- 84,108 ----
  
  tsattach(addr, unit)
  struct tsdevice *addr;
+ register int unit;
  {
+ 	register u_short sp = ((u_short)softspace + 3) & ~3;
+ 	register struct ts_softc *sc;
+ 
+ 	if (unit >= NTS)
+ 		return(0);
  	/*
! 	 * We want space for an array of NTS ts_softc structures,
! 	 * where the sc_cmd field of each is long-aligned, i.e. the
! 	 * core address is a 4-byte multiple.  The compiler only
! 	 * guarantees word alignment.  We reserve and extra 3 bytes
! 	 * so that we can slide the array down by 2 if the compiler
! 	 * gets it wrong.
  	 */
! 	sp += (unit * sizeof (struct ts_softc));
! 	sc = ts_softc[unit] = (struct ts_softc *)sp;
! 	sc->sc_addr = addr;
! 	return(1);
  }
  
  /*
***************
*** 123,150 ****
   */
  tsopen(dev, flag)
  dev_t	dev;
  {
! 	register tsunit;
! 	register struct ts_softc *sc;
  
! 	tsunit = TSUNIT(dev);
! 	if (TSADDR == (struct tsdevice *) NULL || tsunit >= NTS
! 	    || (sc = &ts_softc[tsunit])->sc_openf)
  		return(ENXIO);
! 	if(tsinit(tsunit)) {
! 		printf("ts%d: initialization failure tssr=%b\n",
! 			tsunit, TSADDR->tssr, TSSR_BITS);
  		return(ENXIO);
  	}
! 	tstab.b_flags |= B_TAPE;
  	tscommand(dev, TS_SENSE, 1);
  	if ((sc->sc_sts.s_xs0 & TS_ONL) == 0) {
! 		uprintf("ts%d: not online\n", tsunit);
  		return(EIO);
  	}
  	if ((flag & (FREAD | FWRITE)) == FWRITE
  	    && (sc->sc_sts.s_xs0 & TS_WLK)) {
! 		uprintf("ts%d: no write ring\n", tsunit);
  		return(EIO);
  	}
  	sc->sc_openf = 1;
--- 114,140 ----
   */
  tsopen(dev, flag)
  dev_t	dev;
+ int	flag;
  {
! 	register ts11 = TSCTLR(dev);
! 	register struct ts_softc *sc = ts_softc[ts11];
  
! 	if (ts11 >= NTS || !sc || sc->sc_openf)
  		return(ENXIO);
! 	if (tsinit(ts11)) {
! 		printf("ts%d: init failure tssr=%b\n",
! 			ts11, sc->sc_addr->tssr, TSSR_BITS);
  		return(ENXIO);
  	}
! 	tstab[ts11].b_flags |= B_TAPE;
  	tscommand(dev, TS_SENSE, 1);
  	if ((sc->sc_sts.s_xs0 & TS_ONL) == 0) {
! 		uprintf("ts%d: not online\n", ts11);
  		return(EIO);
  	}
  	if ((flag & (FREAD | FWRITE)) == FWRITE
  	    && (sc->sc_sts.s_xs0 & TS_WLK)) {
! 		uprintf("ts%d: no write ring\n", ts11);
  		return(EIO);
  	}
  	sc->sc_openf = 1;
***************
*** 164,174 ****
   */
  tsclose(dev, flag)
  register dev_t	dev;
! register flag;
  {
! 	register struct ts_softc *sc = &ts_softc[TSUNIT(dev)];
  
! 	if(flag == FWRITE || ((flag & FWRITE) && sc->sc_lastiow)) {
  		tscommand(dev, TS_WEOF, 1);
  		tscommand(dev, TS_WEOF, 1);
  		tscommand(dev, TS_SREV, 1);
--- 154,164 ----
   */
  tsclose(dev, flag)
  register dev_t	dev;
! register int flag;
  {
! 	register struct ts_softc *sc = ts_softc[TSCTLR(dev)];
  
! 	if (flag == FWRITE || ((flag & FWRITE) && sc->sc_lastiow)) {
  		tscommand(dev, TS_WEOF, 1);
  		tscommand(dev, TS_WEOF, 1);
  		tscommand(dev, TS_SREV, 1);
***************
*** 189,201 ****
   * a specified number of times.
   */
  tscommand(dev, com, count)
! dev_t	dev;
  register u_short count;
  {
! 	register s;
  	register struct buf *bp;
  
! 	bp = &ctsbuf;
  	s = splbio();
  	while(bp->b_flags & B_BUSY) {
  		/*
--- 179,191 ----
   * a specified number of times.
   */
  tscommand(dev, com, count)
! 	dev_t	dev;
  register u_short count;
  {
! 	register int s;
  	register struct buf *bp;
  
! 	bp = &ctsbuf[TSCTLR(dev)];
  	s = splbio();
  	while(bp->b_flags & B_BUSY) {
  		/*
***************
*** 233,256 ****
  register struct buf *bp;
  {
  	register int s;
  
  #ifdef UNIBUS_MAP
- 	if (bp->b_flags & B_PHYS)	/* if RAW I/O call */
  		mapalloc(bp);
  #endif
  	bp->av_forw = NULL;
  	s = splbio();
! 	if (tstab.b_actf == NULL)
! 		tstab.b_actf = bp;
  	else
! 		tstab.b_actl->av_forw = bp;
! 	tstab.b_actl = bp;
  	/*
  	 * If the controller is not busy, get
  	 * it going.
  	 */
! 	if (tstab.b_active == 0)
! 		tsstart();
  	splx(s);
  }
  
--- 223,252 ----
  register struct buf *bp;
  {
  	register int s;
+ 	int ts11 = TSCTLR(bp->b_dev);
+ 	struct ts_softc *sc = ts_softc[ts11];
+ 	register struct buf *dp = &tstab[ts11];
  
+ 	if (bp->b_flags & B_PHYS) {	/* if RAW I/O call */
  #ifdef UNIBUS_MAP
  		mapalloc(bp);
  #endif
+ 		sc->sc_blkno = sc->sc_nxrec = dbtofsb(bp->b_blkno);
+ 		sc->sc_nxrec++;
+ 	}
  	bp->av_forw = NULL;
  	s = splbio();
! 	if (dp->b_actf == NULL)
! 		dp->b_actf = bp;
  	else
! 		dp->b_actl->av_forw = bp;
! 	dp->b_actl = bp;
  	/*
  	 * If the controller is not busy, get
  	 * it going.
  	 */
! 	if (dp->b_active == 0)
! 		tsstart(ts11);
  	splx(s);
  }
  
***************
*** 257,278 ****
  /*
   * Start activity on a ts controller.
   */
! tsstart()
  {
  	daddr_t	blkno;
! 	int	cmd, tsunit;
  	register struct ts_softc *sc;
  	register struct ts_cmd *tc;
  	register struct buf *bp;
  
  	/*
  	 * Start the controller if there is something for it to do.
  	 */
  loop:
! 	if ((bp = tstab.b_actf) == NULL)
  		return;
! 	tsunit = TSUNIT(bp->b_dev);
! 	sc = &ts_softc[tsunit];
  	tc = &sc->sc_cmd;
  	/*
  	 * Default is that last command was NOT a write command;
--- 253,275 ----
  /*
   * Start activity on a ts controller.
   */
! tsstart(ts11)
! 	int ts11;
  {
  	daddr_t	blkno;
! 	int	cmd;
  	register struct ts_softc *sc;
  	register struct ts_cmd *tc;
  	register struct buf *bp;
+ 	struct buf *um = &tstab[ts11];
  
  	/*
  	 * Start the controller if there is something for it to do.
  	 */
  loop:
! 	if ((bp = um->b_actf) == NULL)
  		return;
! 	sc = ts_softc[ts11];
  	tc = &sc->sc_cmd;
  	/*
  	 * Default is that last command was NOT a write command;
***************
*** 279,285 ****
  	 * if we do a write command we will notice this in tsintr().
  	 */
  	sc->sc_lastiow = 0;
! 	if (sc->sc_openf < 0 || (TSADDR->tssr & TS_OFL)) {
  		/*
  		 * Have had a hard error on a non-raw tape
  		 * or the tape unit is now unavailable
--- 276,282 ----
  	 * if we do a write command we will notice this in tsintr().
  	 */
  	sc->sc_lastiow = 0;
! 	if (sc->sc_openf < 0 || (sc->sc_addr->tssr & TS_OFL)) {
  		/*
  		 * Have had a hard error on a non-raw tape
  		 * or the tape unit is now unavailable
***************
*** 288,298 ****
  		bp->b_flags |= B_ERROR;
  		goto next;
  	}
! 	if (bp == &ctsbuf) {
  		/*
  		 * Execute control operation with the specified count.
  		 */
! 		tstab.b_active = bp->b_command == TS_REW ?  SREW : SCOM;
  		goto dobpcmd;
  	}
  	/*
--- 285,295 ----
  		bp->b_flags |= B_ERROR;
  		goto next;
  	}
! 	if (bp == &ctsbuf[ts11]) {
  		/*
  		 * Execute control operation with the specified count.
  		 */
! 		um->b_active = bp->b_command == TS_REW ?  SREW : SCOM;
  		goto dobpcmd;
  	}
  	/*
***************
*** 301,307 ****
  	 * sc->sc_nxrec by tsphys causes them to be skipped normally
  	 * (except in the case of retries).
  	 */
! 	if(dbtofsb(bp->b_blkno) > sc->sc_nxrec) {
  		/*
  		 * Can't read past known end-of-file.
  		 */
--- 298,304 ----
  	 * sc->sc_nxrec by tsphys causes them to be skipped normally
  	 * (except in the case of retries).
  	 */
! 	if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) {
  		/*
  		 * Can't read past known end-of-file.
  		 */
***************
*** 309,318 ****
  		bp->b_error = ENXIO;
  		goto next;
  	}
! 	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 writei.
  		 */
  		bp->b_resid = bp->b_bcount;
  		goto next;
--- 306,315 ----
  		bp->b_error = ENXIO;
  		goto next;
  	}
! 	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;
***************
*** 327,333 ****
  	 * set up all registers and do the transfer.
  	 */
  	if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) {
! 		tstab.b_active = SIO;
  		tc->c_loba = (u_short)bp->b_un.b_addr;
  		tc->c_hiba = bp->b_xmem;
  		tc->c_size = bp->b_bcount;
--- 324,330 ----
  	 * set up all registers and do the transfer.
  	 */
  	if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) {
! 		um->b_active = SIO;
  		tc->c_loba = (u_short)bp->b_un.b_addr;
  		tc->c_hiba = bp->b_xmem;
  		tc->c_size = bp->b_bcount;
***************
*** 335,347 ****
  			cmd = TS_WCOM;
  		else
  			cmd = TS_RCOM;
! 		if (tstab.b_errcnt)
  			cmd |= TS_RETRY;
  		tc->c_cmd = TS_ACK | TS_CVC | TS_IE | cmd;
  #ifdef UNIBUS_MAP
! 		TSADDR->tsdb = sc->sc_uba;
  #else
! 		TSADDR->tsdb = (u_short)&sc->sc_cmd.c_cmd;
  #endif
  		return;
  	}
--- 332,344 ----
  			cmd = TS_WCOM;
  		else
  			cmd = TS_RCOM;
! 		if (um->b_errcnt)
  			cmd |= TS_RETRY;
  		tc->c_cmd = TS_ACK | TS_CVC | TS_IE | cmd;
  #ifdef UNIBUS_MAP
! 		sc->sc_addr->tsdb = sc->sc_uba;
  #else
! 		sc->sc_addr->tsdb = (u_short)&sc->sc_cmd.c_cmd;
  #endif
  		return;
  	}
***************
*** 350,357 ****
  	 * set to seek forward or backward to the correct spot.
  	 * This happens for raw tapes only on error retries.
  	 */
! 	tstab.b_active = SSEEK;
! 	if(blkno < dbtofsb(bp->b_blkno)) {
  		bp->b_command = TS_SFORW;
  		bp->b_repcnt = dbtofsb(bp->b_blkno) - blkno;
  	} else
--- 347,354 ----
  	 * set to seek forward or backward to the correct spot.
  	 * This happens for raw tapes only on error retries.
  	 */
! 	um->b_active = SSEEK;
! 	if (blkno < dbtofsb(bp->b_blkno)) {
  		bp->b_command = TS_SFORW;
  		bp->b_repcnt = dbtofsb(bp->b_blkno) - blkno;
  	} else
***************
*** 366,374 ****
  	 */
  	tc->c_cmd = TS_ACK | TS_CVC | TS_IE | bp->b_command;
  #ifdef UNIBUS_MAP
! 	TSADDR->tsdb = sc->sc_uba;
  #else
! 	TSADDR->tsdb = (u_short)&sc->sc_cmd.c_cmd;
  #endif
  	return;
  
--- 363,371 ----
  	 */
  	tc->c_cmd = TS_ACK | TS_CVC | TS_IE | bp->b_command;
  #ifdef UNIBUS_MAP
! 	sc->sc_addr->tsdb = sc->sc_uba;
  #else
! 	sc->sc_addr->tsdb = (u_short)&sc->sc_cmd.c_cmd;
  #endif
  	return;
  
***************
*** 378,385 ****
  	 * the fact that it doesn't do anything.
  	 * Dequeue the transfer and continue processing this slave.
  	 */
! 	tstab.b_errcnt = 0;
! 	tstab.b_actf = bp->av_forw;
  	iodone(bp);
  	goto loop;
  }
--- 375,382 ----
  	 * the fact that it doesn't do anything.
  	 * Dequeue the transfer and continue processing this slave.
  	 */
! 	um->b_errcnt = 0;
! 	um->b_actf = bp->av_forw;
  	iodone(bp);
  	goto loop;
  }
***************
*** 387,402 ****
  /*
   * TS interrupt routine
   */
! tsintr()
  {
! 	register state;
! 	register struct buf *bp;
  	register struct ts_softc *sc;
- 	int	tsunit;
  
! 	if((bp = tstab.b_actf) == NULL)
  		return;
- 	tsunit = TSUNIT (bp->b_dev);
  
  	/*
  	 * If last command was a rewind, and tape is still
--- 384,398 ----
  /*
   * TS interrupt routine
   */
! tsintr(dev)
! 	int dev;
  {
! 	int state;
! 	register struct buf *bp, *um = &tstab[dev];
  	register struct ts_softc *sc;
  
! 	if ((bp = um->b_actf) == NULL)
  		return;
  
  	/*
  	 * If last command was a rewind, and tape is still
***************
*** 404,428 ****
  	 *
  	 * SHOULD NEVER GET AN INTERRUPT IN THIS STATE.
  	 */
! 	if (tstab.b_active == SREW) {
! 		tstab.b_active = SCOM;
! 		if ((TSADDR->tssr & TS_SSR) == 0)
  			return;
  	}
  	/*
  	 * An operation completed... record status
  	 */
! 	sc = &ts_softc[tsunit];
  	if ((bp->b_flags & B_READ) == 0)
  		sc->sc_lastiow = 1;
! 	state = tstab.b_active;
! 	tstab.b_active = 0;
  
  	/*
  	 * Check for errors.
  	 */
! 	if(TSADDR->tssr & TS_SC) {
! 		switch (TSADDR->tssr & TS_TC) {
  			case TS_UNREC:	/* unrecoverable */
  			case TS_FATAL:	/* fatal error */
  			case TS_ATTN:	/* attention (shouldn't happen) */
--- 400,424 ----
  	 *
  	 * SHOULD NEVER GET AN INTERRUPT IN THIS STATE.
  	 */
! 	if (um->b_active == SREW) {
! 		um->b_active = SCOM;
! 		if ((sc->sc_addr->tssr & TS_SSR) == 0)
  			return;
  	}
  	/*
  	 * An operation completed... record status
  	 */
! 	sc = ts_softc[dev];
  	if ((bp->b_flags & B_READ) == 0)
  		sc->sc_lastiow = 1;
! 	state = um->b_active;
! 	um->b_active = 0;
  
  	/*
  	 * Check for errors.
  	 */
! 	if (sc->sc_addr->tssr & TS_SC) {
! 		switch (sc->sc_addr->tssr & TS_TC) {
  			case TS_UNREC:	/* unrecoverable */
  			case TS_FATAL:	/* fatal error */
  			case TS_ATTN:	/* attention (shouldn't happen) */
***************
*** 454,460 ****
  				 * was too long or too short, then we don't
  				 * consider this an error.
  				 */
! 				if (bp == &rtsbuf && (bp->b_flags & B_READ)
  				    && sc->sc_sts.s_xs0 & (TS_RLS | TS_RLL))
  					goto ignoreerr;
  					/*NOTREACHED*/
--- 450,456 ----
  				 * was too long or too short, then we don't
  				 * consider this an error.
  				 */
! 				if ((bp->b_flags & B_PHYS) && (bp->b_flags & B_READ)
  				    && sc->sc_sts.s_xs0 & (TS_RLS | TS_RLL))
  					goto ignoreerr;
  					/*NOTREACHED*/
***************
*** 465,471 ****
  				 * retry up to 8 times.
  				 */
  				if (state == SIO) {
! 					if (++tstab.b_errcnt < 7)
  						goto opcont;
  					else
  						sc->sc_blkno++;
--- 461,467 ----
  				 * retry up to 8 times.
  				 */
  				if (state == SIO) {
! 					if (++(um->b_errcnt) < 7)
  						goto opcont;
  					else
  						sc->sc_blkno++;
***************
*** 475,481 ****
  					 * Non-i/o errors on non-raw tape
  					 * cause it to close.
  					 */
! 					if (sc->sc_openf > 0 && bp != &rtsbuf)
  						sc->sc_openf = -1;
  				}
  				break;
--- 471,477 ----
  					 * Non-i/o errors on non-raw tape
  					 * cause it to close.
  					 */
! 					if (sc->sc_openf > 0 && !(bp->b_flags & B_PHYS))
  						sc->sc_openf = -1;
  				}
  				break;
***************
*** 482,496 ****
  
  			case TS_REJECT:
  				if (state == SIO && sc->sc_sts.s_xs0 & TS_WLE)
! 					printf("ts%d: no write ring\n", tsunit);
  				if ((sc->sc_sts.s_xs0 & TS_ONL) == 0)
! 					printf("ts%d: not online\n", tsunit);
  				break;
  		}
  		/*
  		 * Couldn't recover error.
  		 */
! 		printf("ts%d: hard error bn%D xs0=%b", TSUNIT(bp->b_dev),
  		     bp->b_blkno, sc->sc_sts.s_xs0, TSXS0_BITS);
  		if (sc->sc_sts.s_xs1)
  			printf(" xs1=%b", sc->sc_sts.s_xs1, TSXS1_BITS);
--- 478,492 ----
  
  			case TS_REJECT:
  				if (state == SIO && sc->sc_sts.s_xs0 & TS_WLE)
! 					printf("ts%d: no write ring\n", dev);
  				if ((sc->sc_sts.s_xs0 & TS_ONL) == 0)
! 					printf("ts%d: not online\n", dev);
  				break;
  		}
  		/*
  		 * Couldn't recover error.
  		 */
! 		printf("ts%d: hard error bn%D xs0=%b", dev,
  		     bp->b_blkno, sc->sc_sts.s_xs0, TSXS0_BITS);
  		if (sc->sc_sts.s_xs1)
  			printf(" xs1=%b", sc->sc_sts.s_xs1, TSXS1_BITS);
***************
*** 521,527 ****
  			 * For forward/backward space record
  			 * update current position.
  			 */
! 			if (bp == &ctsbuf)
  				switch (bp->b_command) {
  					case TS_SFORW:
  						sc->sc_blkno += bp->b_repcnt;
--- 517,523 ----
  			 * For forward/backward space record
  			 * update current position.
  			 */
! 			if (bp == &ctsbuf[dev])
  				switch (bp->b_command) {
  					case TS_SFORW:
  						sc->sc_blkno += bp->b_repcnt;
***************
*** 549,571 ****
  	 * Reset error count and remove
  	 * from device queue.
  	 */
! 	tstab.b_errcnt = 0;
! 	tstab.b_actf = bp->av_forw;
  	bp->b_resid = sc->sc_sts.s_rbpcr;
  	iodone(bp);
! 	if (tstab.b_actf == NULL)
  		return;
  opcont:
! 	tsstart();
  }
  
  tsseteof(bp)
  register struct buf *bp;
  {
! 	register tsunit = TSUNIT(bp->b_dev);
! 	register struct ts_softc *sc = &ts_softc[tsunit];
  
! 	if (bp == &ctsbuf) {
  		if (sc->sc_blkno > dbtofsb(bp->b_blkno)) {
  			/* reversing */
  			sc->sc_nxrec = dbtofsb(bp->b_blkno) - sc->sc_sts.s_rbpcr;
--- 545,567 ----
  	 * Reset error count and remove
  	 * from device queue.
  	 */
! 	um->b_errcnt = 0;
! 	um->b_actf = bp->av_forw;
  	bp->b_resid = sc->sc_sts.s_rbpcr;
  	iodone(bp);
! 	if (um->b_actf == NULL)
  		return;
  opcont:
! 	tsstart(dev);
  }
  
  tsseteof(bp)
  register struct buf *bp;
  {
! 	register int ts11 = TSCTLR(bp->b_dev);
! 	register struct ts_softc *sc = ts_softc[ts11];
  
! 	if (bp == &ctsbuf[ts11]) {
  		if (sc->sc_blkno > dbtofsb(bp->b_blkno)) {
  			/* reversing */
  			sc->sc_nxrec = dbtofsb(bp->b_blkno) - sc->sc_sts.s_rbpcr;
***************
*** 586,594 ****
  /*
   * Initialize the TS11.
   */
! tsinit(tsunit)
  {
! 	struct	ts_softc *sc = &ts_softc[tsunit];
  	register struct ts_cmd *tcmd = &sc->sc_cmd;
  	register struct ts_char *tchar = &sc->sc_char;
  	int cnt;
--- 582,590 ----
  /*
   * Initialize the TS11.
   */
! tsinit(ts11)
  {
! 	struct	ts_softc *sc = ts_softc[ts11];
  	register struct ts_cmd *tcmd = &sc->sc_cmd;
  	register struct ts_char *tchar = &sc->sc_char;
  	int cnt;
***************
*** 617,650 ****
  	 * Now initialize the TS11 controller.
  	 * Set the characteristics.
  	 */
! 	if (TSADDR->tssr & (TS_NBA | TS_OFL)) {
  		tcmd->c_cmd = TS_ACK | TS_CVC | TS_INIT;
  #ifdef	UNIBUS_MAP
  		sc->sc_uba = loint(sc->sc_uadr)
  			   | hiint(sc->sc_uadr); /*register format*/
  #endif
- #ifdef DIAGNOSTIC
- #ifdef UNIBUS_MAP
- 		if (sc->sc_uadr & 03)
- #else	UNIBUS_MAP
- 		if (((u_short) tcmd) & 03)
- #endif
- 		{
- 			printf("ts%d: addr mod 4 != 0\n", tsunit);
- 			return (1);
- 		}
- #endif
- #ifdef	UNIBUS_MAP
- 		TSADDR->tsdb = sc->sc_uba;
- #else	UNIBUS_MAP
- 		TSADDR->tsdb = (u_short) tcmd;
- #endif
  		for (cnt = 0; cnt < 10000; cnt++) {
! 			if (TSADDR->tssr & TS_SSR)
  				break;
  		}
  		if (cnt >= 10000) {
! 			printf("ts%d: subsystem init. failure\n", tsunit);
  			return (1);
  		}
  #ifdef	UNIBUS_MAP
--- 613,633 ----
  	 * Now initialize the TS11 controller.
  	 * Set the characteristics.
  	 */
! 	if (sc->sc_addr->tssr & (TS_NBA | TS_OFL)) {
  		tcmd->c_cmd = TS_ACK | TS_CVC | TS_INIT;
  #ifdef	UNIBUS_MAP
  		sc->sc_uba = loint(sc->sc_uadr)
  			   | hiint(sc->sc_uadr); /*register format*/
+ 		sc->sc_addr->tsdb = sc->sc_uba;
+ #else
+ 		sc->sc_addr->tsdb = (u_short) tcmd;
  #endif
  		for (cnt = 0; cnt < 10000; cnt++) {
! 			if (sc->sc_addr->tssr & TS_SSR)
  				break;
  		}
  		if (cnt >= 10000) {
! 			printf("ts%d: subsystem init. failure\n", ts11);
  			return (1);
  		}
  #ifdef	UNIBUS_MAP
***************
*** 668,683 ****
  #endif
  		tcmd->c_size = sizeof(struct ts_char);
  #ifdef	UNIBUS_MAP
! 		TSADDR->tsdb = sc->sc_uba;
  #else	UNIBUS_MAP
! 		TSADDR->tsdb = (u_short) tcmd;
  #endif
  		for (cnt = 0; cnt < 10000; cnt++) {
! 			if (TSADDR->tssr & TS_SSR)
  				break;
  		}
! 		if (TSADDR->tssr & TS_NBA) {
! 			printf("ts%d: set characteristics failure\n", tsunit);
  			return (1);
  		}
  	}
--- 651,666 ----
  #endif
  		tcmd->c_size = sizeof(struct ts_char);
  #ifdef	UNIBUS_MAP
! 		sc->sc_addr->tsdb = sc->sc_uba;
  #else	UNIBUS_MAP
! 		sc->sc_addr->tsdb = (u_short) tcmd;
  #endif
  		for (cnt = 0; cnt < 10000; cnt++) {
! 			if (sc->sc_addr->tssr & TS_SSR)
  				break;
  		}
! 		if (sc->sc_addr->tssr & TS_NBA) {
! 			printf("ts%d: set char. failure\n", ts11);
  			return (1);
  		}
  	}
***************
*** 685,734 ****
  }
  
  tsread(dev, uio)
! 	register dev_t	dev;
! 	register struct uio *uio;
  {
! 	register int error;
! 
! 	error = tsphys(dev, uio);
! 	if (error)
! 		return (error);
! 	return (physio(tsstrategy, &rtsbuf, dev, B_READ, BYTE, uio));
  }
  
  tswrite(dev, uio)
- 	register dev_t	dev;
- 	register struct uio *uio;
- {
- 	register int error;
- 
- 	error = tsphys(dev, uio);
- 	if (error)
- 		return (error);
- 	return (physio(tsstrategy, &rtsbuf, dev, B_WRITE, BYTE, uio));
- }
- 
- /*
-  * Check that a raw device exists.
-  * If it does, set up sc_blkno and sc_nxrec
-  * so that the tape will appear positioned correctly.
-  */
- static
- tsphys(dev, uio)
  	dev_t	dev;
! 	register struct uio *uio;
  {
! 	register int tsunit = TSUNIT(dev);
! 	register struct ts_softc *sc;
! 	daddr_t a;
! 
! 	if (tsunit >= NTS)
! 		return (ENXIO);
! 	sc = &ts_softc[tsunit];
! 	a = dbtofsb(uio->uio_offset >> 9);
! 	sc->sc_blkno = a;
! 	sc->sc_nxrec = a + 1;
! 	return (0);
  }
  
  /*ARGSUSED*/
--- 668,684 ----
  }
  
  tsread(dev, uio)
! 	dev_t	dev;
! 	struct uio *uio;
  {
! 	return(physio(tsstrategy, (struct buf *)NULL, dev, B_READ, BYTE, uio));
  }
  
  tswrite(dev, uio)
  	dev_t	dev;
! 	struct uio *uio;
  {
! 	return(physio(tsstrategy, (struct buf *)NULL, dev, B_WRITE, BYTE, uio));
  }
  
  /*ARGSUSED*/
***************
*** 737,744 ****
  	u_int cmd;
  	caddr_t data;
  {
! 	register struct ts_softc *sc = &ts_softc[TSUNIT(dev)];
! 	register struct buf *bp = &ctsbuf;
  	register callcount;
  	u_short	fcount;
  	struct	mtop *mtop;
--- 687,695 ----
  	u_int cmd;
  	caddr_t data;
  {
! 	int ts11 = TSCTLR(dev);
! 	register struct ts_softc *sc = ts_softc[ts11];
! 	register struct buf *bp = &ctsbuf[ts11];
  	register callcount;
  	u_short	fcount;
  	struct	mtop *mtop;
*** /usr/src/sys/pdpuba/ht.c.old	Tue Apr  3 23:00:43 1990
--- /usr/src/sys/pdpuba/ht.c	Sun May 26 23:10:54 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.0 (2.11BSD) 5/23/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);
***************
*** 404,434 ****
  }
  
  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*/
--- 395,411 ----
  }
  
  htread(dev, uio)
! 	dev_t	dev;
! 	struct uio *uio;
  {
! 	return(physio(htstrategy, (struct buf *)NULL, dev, B_READ, BYTE, uio));
  }
  
  htwrite(dev, uio)
! 	dev_t	dev;
! 	struct uio *uio;
  {
! 	return(physio(htstrategy, (struct buf *)NULL, dev, B_WRITE, BYTE, uio));
  }
  
  /*ARGSUSED*/



More information about the Comp.bugs.2bsd mailing list