*BSD News Article 63559


Return to BSD News archive

Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!newshost.telstra.net!act.news.telstra.net!psgrain!news.uoregon.edu!cs.uoregon.edu!sgigate.sgi.com!imci3!imci4!newsfeed.internetmci.com!gatech!europa.chnt.gtegsc.com!wlbr!sms
From: sms@wlv.iipo.gtegsc.com (Steven M. Schultz)
Subject: Standalone I/O system problems and a bug (#307)
Sender: news@wlbr.iipo.gtegsc.com (Steven M. Schultz)
Organization: GTE Government Systems, Thousand Oaks CA USA
Message-ID: <Dnzr0A.FLB@wlbr.iipo.gtegsc.com>
X-Nntp-Posting-Host: wlv.iipo.gtegsc.com
Date: Sat, 9 Mar 1996 08:16:57 GMT
Lines: 1255

Subject: Standalone I/O system problems and a bug (#307)
Index:	sys/pdpstand/* 2.11BSD

Description:
	1. The standalone I/O system can not handle unlabeled disks as
	sequential tape-like devices.

	2. Multivolume dump sets (e.g. root filesystem dump on several
	RX33 or RX50 diskettes) do not work.  Standalone 'restor' does not
	receive the 0 return value signifying EOF (end of media) when reading
	disk volumes.

Repeat-By:
	Create a multivolume dump of a 'generic' root filesystem to RX33
	(or RX50, but you will need a lot more of them).  An RX33 looks like
	a 70 foot tape to 'dump'
	
		dump 0sf 70 /dev/rra9a /dev/rra8a

	is how I dumped the root partition of ra8 (an RD54) to ra9 (a RX33).
	The 'generic' root filesystem fits on 4 floppies.

	1.  Boot from a standalone tape or floppy.  Load 'restor'.  Specify
	    'ra(1,0)' in response to the "Tape?" prompt.  

	    Note that the 'disklabel is missing or corrupt' message appears
	    and is interpreted as a fatal error causing the 'open' to fail.

	2. You will not be able to reproduce the second problem as long as
	   the error above is 'fatal'.  I stumbled across the second problem
	   after fixing the first.  'restor' reads the input media until
	   EOF (0) is returned.  However, the disk drivers in the standalone
	   system had no "EOF" detection logic - the first error that would
	   be encountered would be when the 'read' went off the end of the
	   disk and that was considered to be a "hard"/"fatal" error.

Fix:
	The initial 'fix' (for the first problem) was 3 lines long (excluding
	comments) in pdpstand/label.c.

	You guessed it - things snowballed downhill from there.

	Fixing the second problem was considerably more complex.  The three
	drivers which support disklabels (RA, RL, XP) needed to have inserted
	a check for a read/write being off the end of a partition/drive.

	The 'end of volume' check was placed in a routine that all drivers
	can use (in conf.c) although at the present time only 3 of the disk
	drivers call it.  If an I/O request is exactly at the end of the
	partition/volume then EOF (0) is returned.  If the request is past
	the end of the volume then an error (-1) is returned.  Partial requests
	are now handled correctly but nothing in the standalone environment
	performs them.

	During the debugging and testing of the changes it was noticed that
	the device names printed in error messages were quite inconsistent.
	Sometimes a device/partition name would be printed as "xp(0,0,0)"
	while other times it would appear as "xp0,0a" or "rl0,0,0".   A
	common format was selected and all (except for a couple very rare
	messages in the TMSCP driver) error messages were changed to use
	the "dev(ctlr,unit,part)" format for a device name.

	To install this fix cut where indicated and save to a file (/tmp/307).
	Then:

		patch -p0 < /tmp/307
		cd /sys/pdpstand
		make clean
		make
		cp boot /boot

	If you keep bootable tapes/floppies around (a *very* good idea)
	then now would be an excellent time to recreate them using 'maketape':

		./maketape /dev/nrmt0 maketape.data
		dump 0f /dev/rmt0 /

	will create a bootable tape with a dump of the root filesystem on it.

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

-----------------cut here----------------
*** /sys/pdpstand/saio.h.old	Thu Jun  8 19:31:19 1995
--- /sys/pdpstand/saio.h	Fri Mar  8 15:27:52 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)saio.h	2.1 (2.11BSD GTE) 1995/06/08
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)saio.h	2.2 (2.11BSD GTE) 1996/3/8
   */
  
  /*
***************
*** 68,70 ****
--- 68,73 ----
   * when it expects to be reading an unlabeled disk.
  */
  int	Nolabelerr;
+ 
+ extern	char	*itoa();
+ extern	char	*devname();
*** /sys/pdpstand/conf.c.old	Tue Dec  5 20:26:35 1995
--- /sys/pdpstand/conf.c	Fri Mar  8 21:24:28 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)conf.c	2.5 (2.11BSD) 1995/12/05
   */
  
  #include "../h/param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)conf.c	2.6 (2.11BSD) 1996/3/8
   */
  
  #include "../h/param.h"
***************
*** 127,140 ****
  	int	(*strat)() = devsw[io->i_ino.i_dev].dv_strategy;
  	register struct disklabel *lp;
  	register struct partition *pi;
- 	char	*name = devsw[io->i_ino.i_dev].dv_name;
  	
  	switch	(fnc)
  		{
  		case	WRITELABEL:
! 			return(writelabel(io, strat, name));
  		case	READLABEL:
! 			return(readlabel(io, strat, name));
  		case	DEFAULTLABEL:
  /*
   * Zero out the label buffer and then assign defaults common to all drivers.
--- 127,139 ----
  	int	(*strat)() = devsw[io->i_ino.i_dev].dv_strategy;
  	register struct disklabel *lp;
  	register struct partition *pi;
  	
  	switch	(fnc)
  		{
  		case	WRITELABEL:
! 			return(writelabel(io, strat));
  		case	READLABEL:
! 			return(readlabel(io, strat));
  		case	DEFAULTLABEL:
  /*
   * Zero out the label buffer and then assign defaults common to all drivers.
***************
*** 171,176 ****
--- 170,246 ----
  			printf("devlabel: bad fnc %d\n");
  			return(-1);
  		}
+ 	}
+ 
+ /*
+  * Common routine to print out the full device name in the form:
+  *
+  *	dev(ctlr,unit,part)
+  * 
+  * Have to do it the hard way since there's no sprintf to call.  Register
+  * oriented string copies are small though.
+ */
+ 
+ char	*
+ devname(io)
+ 	register struct iob *io;
+ 	{
+ 	static	char	dname[16];
+ 	register char *cp, *dp;
+ 
+ 	cp = dname;
+ 	dp = devsw[io->i_ino.i_dev].dv_name;
+ 	while	(*cp = *dp++)
+ 		cp++;
+ 	*cp++ = '(';
+ 	dp = itoa(io->i_ctlr);
+ 	while	(*cp = *dp++)
+ 		cp++;
+ 	*cp++ = ',';
+ 	dp = itoa(io->i_unit);
+ 	while	(*cp = *dp++)
+ 		cp++;
+ 	*cp++ = ',';
+ 	dp = itoa(io->i_part);
+ 	while	(*cp = *dp++)
+ 		cp++;
+ 	*cp++ = ')';
+ 	*cp++ = '\0';
+ 	return(dname);
+ 	}
+ /*
+  * Check for end of volume.  Actually this checks for end of partition.
+  * Since this is almost always called when reading unlabeled disks (treating
+  * a floppy as a short tape for example) it's effectively an EOV check.
+ */
+ 
+ deveovchk(io)
+ 	register struct iob *io;
+ 	{
+ 	register struct partition *pi;
+ 	daddr_t  sz, eov;
+ 
+ 	pi = &io->i_label.d_partitions[io->i_part];
+ 	sz = io->i_cc / 512;
+ /*
+  * i_bn already has the p_offset added in, thus we have to add in the partition
+  * offset when calculating the end point. 
+ */
+ 	eov = pi->p_offset + pi->p_size;
+ 	if	(io->i_bn + sz > eov)
+ 		{
+ 		sz = eov - io->i_bn;
+ 		if	(sz == 0)
+ 			return(0);	/* EOF */
+ /*
+  * Probably should call this EOF too since there is no 'errno' to specify
+  * what type of error has happened.
+ */
+ 		if	(sz < 0)
+ 			return(-1);
+ 		io->i_cc = dbtob(sz);
+ 		}
+ 	return(1);
  	}
  
  nullsys()
*** /sys/pdpstand/label.c.old	Tue Aug  1 22:53:43 1995
--- /sys/pdpstand/label.c	Fri Mar  8 21:22:21 1996
***************
*** 1,7 ****
  /*-
   * Public domain, May 1995
   *
!  *	@(#)label.c	1.1 (2.11BSD GTE) 1995/08/01
   *
   * Date: 1995/08/01
   * Move the check for a partition number being out of bounds to the
--- 1,7 ----
  /*-
   * Public domain, May 1995
   *
!  *	@(#)label.c	1.2 (2.11BSD GTE) 1996/03/07
   *
   * Date: 1995/08/01
   * Move the check for a partition number being out of bounds to the
***************
*** 25,36 ****
   *	   (this is not expected to be a problem since LABELSECTOR is 1).
  */
  
! readlabel(io, strat, name)
! 	struct	iob	*io;
  	int	(*strat)();
- 	char	*name;
  	{
! 	struct disklabel *lp = &io->i_label;
  
  	io->i_bn = LABELSECTOR;
  	io->i_ma = io->i_buf;
--- 25,36 ----
   *	   (this is not expected to be a problem since LABELSECTOR is 1).
  */
  
! readlabel(io, strat)
! 	register struct	iob	*io;
  	int	(*strat)();
  	{
! 	register struct disklabel *lp = &io->i_label;
! 	register struct partition *pi;
  
  	io->i_bn = LABELSECTOR;
  	io->i_ma = io->i_buf;
***************
*** 38,47 ****
  	lp->d_nsectors = LABELSECTOR + 1;	/* # sectors per track */
  	lp->d_ntracks = 1;			/* # tracks per cylinder */
  	lp->d_secpercyl = LABELSECTOR + 1;	/* # sectors per cylinder */
  	if	((*strat)(io, READ) != 512)
  		{
! 		printf("%s%d,%d: error reading labelsector\n", name,
! 			io->i_ctlr, io->i_unit);
  		return(-1);
  		}
  	bcopy(io->i_buf, lp, sizeof (struct disklabel));
--- 38,55 ----
  	lp->d_nsectors = LABELSECTOR + 1;	/* # sectors per track */
  	lp->d_ntracks = 1;			/* # tracks per cylinder */
  	lp->d_secpercyl = LABELSECTOR + 1;	/* # sectors per cylinder */
+ 
+ 	pi = &lp->d_partitions[0];
+ 	lp->d_npartitions = 1;
+ 	pi->p_offset = 0;
+ 	pi->p_size = LABELSECTOR + 1;
+ 	pi->p_fsize = DEV_BSIZE;
+ 	pi->p_frag = 1;
+ 	pi->p_fstype = FS_V71K;
+ 
  	if	((*strat)(io, READ) != 512)
  		{
! 		printf("%s error reading labelsector\n", devname(io));
  		return(-1);
  		}
  	bcopy(io->i_buf, lp, sizeof (struct disklabel));
***************
*** 50,73 ****
  	if	(lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
  		 dkcksum(lp) != 0)
  		{
! 		printf("%s%d,%d disklabel missing or corrupt\n", name,
! 			io->i_ctlr, io->i_unit);
! 		return(-1);
  		}
  	if	(io->i_part >= lp->d_npartitions ||
  			lp->d_partitions[io->i_part].p_size == 0)
  		{
! 		printf("%s%d,%d%c bad partition # or size = 0\n",
! 			name, io->i_ctlr, io->i_unit, 'a' + io->i_part);
  		return(-1);
  		}
  	return(0);
  	}
  
! writelabel(io, strat, name)
  	register struct	iob	*io;
  	int	(*strat)();
- 	char	*name;
  	{
  	register struct disklabel *lp = &io->i_label;
  
--- 58,80 ----
  	if	(lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
  		 dkcksum(lp) != 0)
  		{
! 		printf("%s disklabel missing/corrupt\n", devname(io));
! 		if	(devlabel(io, DEFAULTLABEL) < 0)
! 			return(-1);
! 		printf("%s spans volume\n", devname(io));
  		}
  	if	(io->i_part >= lp->d_npartitions ||
  			lp->d_partitions[io->i_part].p_size == 0)
  		{
! 		printf("%s bad partition # or size = 0\n", devname(io));
  		return(-1);
  		}
  	return(0);
  	}
  
! writelabel(io, strat)
  	register struct	iob	*io;
  	int	(*strat)();
  	{
  	register struct disklabel *lp = &io->i_label;
  
***************
*** 89,99 ****
  
  	if	((*strat)(io, WRITE) != 512)
  		{
! 		printf("%s: error writing labelsector\n", name);
  		return(-1);
  		}
  	return(0);
  	}
  /*
   * Compute checksum for disk label.
   */
--- 96,107 ----
  
  	if	((*strat)(io, WRITE) != 512)
  		{
! 		printf("%s error writing label\n", devname(io));
  		return(-1);
  		}
  	return(0);
  	}
+ 
  /*
   * Compute checksum for disk label.
   */
*** /sys/pdpstand/sys.c.old	Wed Aug 23 21:20:15 1995
--- /sys/pdpstand/sys.c	Fri Mar  8 15:41:32 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)sys.c	2.3 (2.11BSD) 1995/08/23
   */
  
  #include "../h/param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)sys.c	2.4 (2.11BSD) 1996/3/8
   */
  
  #include "../h/param.h"
***************
*** 411,417 ****
  		file->i_cc = count;
  		file->i_ma = buf;
  		i = devread(file);
! 		file->i_bn += (count / NBPG);
  		return(i);
  	}
  	else {
--- 411,418 ----
  		file->i_cc = count;
  		file->i_ma = buf;
  		i = devread(file);
! 		if	(i > 0)
! 			file->i_bn += (i / NBPG);
  		return(i);
  	}
  	else {
*** /sys/pdpstand/ra.c.old	Tue Aug  1 22:50:48 1995
--- /sys/pdpstand/ra.c	Fri Mar  8 16:29:05 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	2.6 (2.11BSD GTE) 1995/08/01
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	2.7 (2.11BSD GTE) 1996/3/8
   */
  
  /*
***************
*** 53,60 ****
  static	u_char 	rainit[NRA];
  static	int	mx();
  
- extern	char	*itoa();
- 
  /*
   * This contains the volume size in sectors of units which have been
   * brought online.  This value is used at default label generation time
--- 53,58 ----
***************
*** 94,100 ****
  			goto again;
  		raaddr->rasa = RA_GO;
  		if (racmd(M_O_STCON, io) < 0) {
! 			printf("ra%d STCON err\n", ctlr);
  			return(-1);
  		}
  		rainit[ctlr] = 1;
--- 92,98 ----
  			goto again;
  		raaddr->rasa = RA_GO;
  		if (racmd(M_O_STCON, io) < 0) {
! 			printf("%s STCON err\n", devname(io));
  			return(-1);
  		}
  		rainit[ctlr] = 1;
***************
*** 123,129 ****
  	register int unit = io->i_unit;
  
  	if (racmd(M_O_ONLIN, io) < 0) {
! 		printf("ra%d,%d: !online\n", ctlr, unit);
  		return(-1);
  	}
  	raonline[ctlr][unit] = rd[ctlr].ra_rsp.m_uslow +  
--- 121,127 ----
  	register int unit = io->i_unit;
  
  	if (racmd(M_O_ONLIN, io) < 0) {
! 		printf("%s !online\n", devname(io));
  		return(-1);
  	}
  	raonline[ctlr][unit] = rd[ctlr].ra_rsp.m_uslow +  
***************
*** 174,191 ****
  		racom->ra_ca.ca_rspint = 0;
  		if (mp->m_opcode == (op | M_O_END))
  			break;
! 		printf("ra%d: rsp %x op %x ignored\n",
! 			ctlr,mp->m_header.ra_credits & 0xf0, mp->m_opcode);
  		racom->ra_ca.ca_rsph |= RA_OWN;
  	}
  	if ((mp->m_status & M_S_MASK) != M_S_SUCC) {
! 		printf("ra%d,%d: err op=%x sts=%x\n", ctlr, unit,
  			mp->m_opcode, mp->m_status);
  		return(-1);
  	}
  	return(0);
  fail:
! 	printf("ra%d: rasa=%o\n", ctlr, csr->rasa);
  }
  
  rastrategy(io, func)
--- 172,189 ----
  		racom->ra_ca.ca_rspint = 0;
  		if (mp->m_opcode == (op | M_O_END))
  			break;
! 		printf("%s rsp %x op %x ignored\n", devname(io),
! 			mp->m_header.ra_credits & 0xf0, mp->m_opcode);
  		racom->ra_ca.ca_rsph |= RA_OWN;
  	}
  	if ((mp->m_status & M_S_MASK) != M_S_SUCC) {
! 		printf("%s err op=%x sts=%x\n", devname(io),
  			mp->m_opcode, mp->m_status);
  		return(-1);
  	}
  	return(0);
  fail:
! 	printf("%s rasa=%x\n", devname(io), csr->rasa);
  }
  
  rastrategy(io, func)
***************
*** 194,201 ****
  {
  	register struct mscp *mp;
  	struct ra *racom;
! 	int	bae, lo16;
  
  	racom = &rd[io->i_ctlr];
  	mp = &racom->ra_cmd;
  	iomapadr(io->i_ma, &bae, &lo16);
--- 192,203 ----
  {
  	register struct mscp *mp;
  	struct ra *racom;
! 	int	bae, lo16, i;
  
+ 	i = deveovchk(io);		/* check for end of volume/partition */
+ 	if	(i <= 0)
+ 		return(i);
+ 
  	racom = &rd[io->i_ctlr];
  	mp = &racom->ra_cmd;
  	iomapadr(io->i_ma, &bae, &lo16);
***************
*** 221,227 ****
  		cnt++;
  		if	(cnt < 5000)
  			continue;
! 		printf("RA(%o) failed step %d. retrying\n",csr,step);
  		return(1);
  		}
  	return(0);
--- 223,229 ----
  		cnt++;
  		if	(cnt < 5000)
  			continue;
! 		printf("ra(%o) fail step %d. retrying\n",csr,step);
  		return(1);
  		}
  	return(0);
***************
*** 251,257 ****
  
  	if	(racmd(M_O_GTUNT, io) != 0)
  		{
! 		printf("ra%d,%d M_OP_GTUNT failed\n", io->i_ctlr, io->i_unit);
  		return(-1);
  		}
  /*
--- 253,259 ----
  
  	if	(racmd(M_O_GTUNT, io) != 0)
  		{
! 		printf("%s M_OP_GTUNT failed\n", devname(io));
  		return(-1);
  		}
  /*
*** /sys/pdpstand/rl.c.old	Tue Aug  1 22:50:24 1995
--- /sys/pdpstand/rl.c	Fri Mar  8 16:36:18 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rl.c	2.4 (2.11BSD) 1995/08/01
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rl.c	2.5 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 64,69 ****
--- 64,73 ----
  	rladdr = RLcsr[ctlr];
  	rlp = &rl[ctlr];
  
+ 	dif = deveovchk(io);
+ 	if	(dif <= 0)
+ 		return(dif);
+ 
  	iomapadr(io->i_ma, &bae, &lo16);
  	rlp->chn = io->i_bn/20;
  	rlp->sn = (io->i_bn%20) << 1;
***************
*** 109,116 ****
  			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);
  	}
--- 113,120 ----
  			while ((rladdr->rlcs & RL_CRDY) == 0)	/* wait for controller */
  				continue;
  		}
! 		printf("%s err cy=%d, hd=%d, sc=%d, rlcs=%o, rlmp=%o\n",
! 			devname(io), rlp->chn>>01, rlp->chn&01, rlp->sn, 
  			rladdr->rlcs, rladdr->rlmp);
  		return(-1);
  	}
***************
*** 185,191 ****
  				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
--- 189,195 ----
  				continue;
  		} while (((rladdr->rlmp & 0177477) != 035) && (++ctr < 8));
  		if (ctr >= 8)
! 			printf("\nCan't get %s sts\n", devname(io));
  		if (rladdr->rlmp & RLMP_DTYP) 
  			rlp->type[drive] = BLKRL2;	/* drive is RL02 */
  		else
*** /sys/pdpstand/rx.c.old	Tue Dec  5 20:26:36 1995
--- /sys/pdpstand/rx.c	Fri Mar  8 16:37:50 1996
***************
*** 1,5 ****
--- 1,6 ----
  /*
   * RX02 Standalone disk driver.
+  * 96/3/8, Steve Schultz (sms@moe.2bsd.com)
   * 95/12/02, Tim Shoppa (shoppa@altair.krl.caltech.edu)
   *
   *	Layout of logical devices:
***************
*** 94,100 ****
  	}
  	return(io->i_cc);
  
! rxerr:	printf("rx error: rxcs %o rxes %o\n",rxaddr->rxcs,rxaddr->rxes);
  	return(-1);
  }
  
--- 95,101 ----
  	}
  	return(io->i_cc);
  
! rxerr:	printf("%s rxcs %o rxes %o\n",devname(io), rxaddr->rxcs,rxaddr->rxes);
  	return(-1);
  }
  
*** /sys/pdpstand/si.c.old	Thu Jun  8 19:36:51 1995
--- /sys/pdpstand/si.c	Fri Mar  8 16:38:32 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)si.c	2.1 (2.11BSD) 1995/06/08
   *
   *	SI 9500 CDC 9766 Stand Alone disk driver
   */
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)si.c	2.2 (2.11BSD) 1996/3/8
   *
   *	SI 9500 CDC 9766 Stand Alone disk driver
   */
***************
*** 77,84 ****
  		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);
--- 77,84 ----
  		continue;
  
  	if (siaddr->sierr & SIERR_ERR) {
! 		printf("%s err cy=%d hd=%d sc=%d cnr=%o, err=%o\n",
! 			devname(io), cn, tn, sn, siaddr->sicnr, siaddr->sierr);
  		return(-1);
  	}
  	return(io->i_cc);
*** /sys/pdpstand/tm.c.old	Thu Jun  8 19:37:33 1995
--- /sys/pdpstand/tm.c	Fri Mar  8 16:39:15 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)tm.c	2.1 (2.11BSD) 1995/06/08
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)tm.c	2.2 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 95,102 ****
  	}
  	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);
--- 95,102 ----
  	}
  	if (tmaddr->tmer & TM_ERR) {
  		if (errcnt == 0)
! 			printf("\n%s err: er=%o cs=%o",
! 				devname(io), tmaddr->tmer, tmaddr->tmcs);
  		if (errcnt++ == 10) {
  			printf("\n(FATAL ERROR)\n");
  			return(-1);
*** /sys/pdpstand/tmscp.c.old	Sun Dec 31 11:00:10 1995
--- /sys/pdpstand/tmscp.c	Fri Mar  8 16:44:54 1996
***************
*** 1,4 ****
! /*	@(#)tmscp.c	7.1.3 (2.11BSD GTE) 1995/12/31 */
  
  /****************************************************************
   *        Licensed from Digital Equipment Corporation           *
--- 1,4 ----
! /*	@(#)tmscp.c	7.1.4 (2.11BSD GTE) 1996/3/8 */
  
  /****************************************************************
   *        Licensed from Digital Equipment Corporation           *
***************
*** 131,139 ****
  		if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
  			printf(opnmsg, ctlr, 3, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpsa = TMSCP_GO;
! 		if (tmscpcmd(ctlr, M_OP_STCON, 0) == 0)
  			{
! 			printf("tms%d STCON", ctlr);
  			return(-1);
  			}
  		tmsoffline[ctlr] = 0;
--- 131,139 ----
  		if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
  			printf(opnmsg, ctlr, 3, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpsa = TMSCP_GO;
! 		if (tmscpcmd(io, M_OP_STCON, 0) == 0)
  			{
! 			printf("%s STCON", devname(io));
  			return(-1);
  			}
  		tmsoffline[ctlr] = 0;
***************
*** 144,152 ****
  	 */
  	if (tms_offline[ctlr][unit])
  		{
! 		if (tmscpcmd(ctlr, M_OP_ONLIN, 0) == 0)
  			{
! 			printf("tms%d,%d ONLIN", ctlr, unit);
  			return(-1);
  			}
  		tms_offline[ctlr][unit] = 0;
--- 144,152 ----
  	 */
  	if (tms_offline[ctlr][unit])
  		{
! 		if (tmscpcmd(io, M_OP_ONLIN, 0) == 0)
  			{
! 			printf("%s ONLIN", devname(io));
  			return(-1);
  			}
  		tms_offline[ctlr][unit] = 0;
***************
*** 160,166 ****
  		tms->tmscp_cmd[0].mscp_tmkcnt = io->i_part;
  		tms->tmscp_cmd[0].mscp_buffer_h = 0;
  		tms->tmscp_cmd[0].mscp_bytecnt = 0;
! 		tmscpcmd(ctlr, M_OP_REPOS, 0);
  		tms->tmscp_cmd[0].mscp_tmkcnt = 0;
  		}
  	return(0);
--- 160,166 ----
  		tms->tmscp_cmd[0].mscp_tmkcnt = io->i_part;
  		tms->tmscp_cmd[0].mscp_buffer_h = 0;
  		tms->tmscp_cmd[0].mscp_bytecnt = 0;
! 		tmscpcmd(io, M_OP_REPOS, 0);
  		tms->tmscp_cmd[0].mscp_tmkcnt = 0;
  		}
  	return(0);
***************
*** 178,184 ****
  	tms->tmscp_cmd[0].mscp_buffer_h = 0;
  	tms->tmscp_cmd[0].mscp_bytecnt = 0;
  	tms->tmscp_cmd[0].mscp_unit = io->i_unit;
! 	tmscpcmd(io->i_ctlr, M_OP_REPOS, M_MD_REWND | M_MD_CLSEX);
  }
   
  /*
--- 178,184 ----
  	tms->tmscp_cmd[0].mscp_buffer_h = 0;
  	tms->tmscp_cmd[0].mscp_bytecnt = 0;
  	tms->tmscp_cmd[0].mscp_unit = io->i_unit;
! 	tmscpcmd(io, M_OP_REPOS, M_MD_REWND | M_MD_CLSEX);
  }
   
  /*
***************
*** 185,194 ****
   * 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 */
--- 185,195 ----
   * Set up tmscp command packet.  Cause the controller to poll to pick up
   * the command.
   */
! tmscpcmd(io, op,mod)
! 	struct	iob *io;
  	int op, mod;		/* opcode and modifier (usu 0) */
  {
+ 	int ctlr = io->i_ctlr;
  	register struct tmscp *tms = &tmscp[ctlr];
  	register struct mscp *mp;	/* ptr to cmd packet */
  	int i;				/* read into to init polling */
***************
*** 221,228 ****
  	for (;;)
  		{
  		if (TMScsr[ctlr]->tmscpsa & TMSCP_ERR) {
! 			printf("tms%d: Fatal error sa=%o\n",
! 				ctlr, TMScsr[ctlr]->tmscpsa);
  			return(0);
  		}
   
--- 222,229 ----
  	for (;;)
  		{
  		if (TMScsr[ctlr]->tmscpsa & TMSCP_ERR) {
! 			printf("%s Fatal err sa=%o\n",
! 				devname(io), TMScsr[ctlr]->tmscpsa);
  			return(0);
  		}
   
***************
*** 254,261 ****
  			tapemark = 1;
  			return(1);
  		}
! 		printf("tms%d,%d: I/O err 0%o op=0%o mod=0%o\n", ctlr,
! 			mp->mscp_unit, mp->mscp_status, op, mod);
  		return(0);
  	}
  	return(1);
--- 255,262 ----
  			tapemark = 1;
  			return(1);
  		}
! 		printf("%s I/O err 0%o op=0%o mod=0%o\n", devname(io),
! 			mp->mscp_status, op, mod);
  		return(0);
  	}
  	return(1);
***************
*** 281,287 ****
  	iomapadr(io->i_ma, &bae, &lo16);
  	mp->mscp_buffer_l = lo16;
  	mp->mscp_buffer_h = bae;
! 	if	(tmscpcmd(ctlr, func == READ ? M_OP_READ : M_OP_WRITE, 0) ==0)
  		return(-1);
  	/*
  	 * Detect hitting tape mark so we do it gracefully and return a
--- 282,288 ----
  	iomapadr(io->i_ma, &bae, &lo16);
  	mp->mscp_buffer_l = lo16;
  	mp->mscp_buffer_h = bae;
! 	if	(tmscpcmd(io, func == READ ? M_OP_READ : M_OP_WRITE, 0) ==0)
  		return(-1);
  	/*
  	 * Detect hitting tape mark so we do it gracefully and return a
***************
*** 312,317 ****
  	tms->tmscp_cmd[0].mscp_buffer_h = 0;
  	tms->tmscp_cmd[0].mscp_unit = io->i_unit;
  	tms->tmscp_cmd[0].mscp_reccnt = space;
! 	tmscpcmd(io->i_ctlr, M_OP_REPOS, mod | M_MD_OBJCT);
  	return(0);
  	}
--- 313,318 ----
  	tms->tmscp_cmd[0].mscp_buffer_h = 0;
  	tms->tmscp_cmd[0].mscp_unit = io->i_unit;
  	tms->tmscp_cmd[0].mscp_reccnt = space;
! 	tmscpcmd(io, M_OP_REPOS, mod | M_MD_OBJCT);
  	return(0);
  	}
*** /sys/pdpstand/ts.c.old	Thu Jun  8 19:38:04 1995
--- /sys/pdpstand/ts.c	Fri Mar  8 16:45:35 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ts.c	2.2 (2.11BSD) 1995/06/08
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ts.c	2.3 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 125,132 ****
  	}
  	if (tsaddr->tssr & TS_SC) {
  		if (errcnt == 0)
! 		    printf("\nts%d,%d err sr=%o xs0=%o xs1=%o xs2=%o xs3=%o",
! 			ctlr, unit, tsaddr->tssr,
  			mesbuf[ctlr].s_xs0, mesbuf[ctlr].s_xs1,
  			mesbuf[ctlr].s_xs2, mesbuf[ctlr].s_xs3);
  		if (errcnt++ == 10) {
--- 125,132 ----
  	}
  	if (tsaddr->tssr & TS_SC) {
  		if (errcnt == 0)
! 		    printf("\n%s err sr=%o xs0=%o xs1=%o xs2=%o xs3=%o",
! 			devname(io), tsaddr->tssr,
  			mesbuf[ctlr].s_xs0, mesbuf[ctlr].s_xs1,
  			mesbuf[ctlr].s_xs2, mesbuf[ctlr].s_xs3);
  		if (errcnt++ == 10) {
*** /sys/pdpstand/xp.c.old	Tue Aug  1 22:51:44 1995
--- /sys/pdpstand/xp.c	Fri Mar  8 17:14:56 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	2.2 (2.11BSD) 1995/08/01
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	2.3 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 76,81 ****
--- 76,85 ----
  	register struct hpdevice *xpaddr = XPcsr[io->i_ctlr];
  	register struct disklabel *lp = &io->i_label;
  
+ 	i = deveovchk(io);
+ 	if	(i <= 0)
+ 		return(i);
+ 
  	bn = io->i_bn;
  	xpaddr->hpcs2.w = io->i_unit;
  
***************
*** 102,109 ****
  	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",
! 		    io->i_ctlr, io->i_unit, cn, tn, sn, xpaddr->hpcs2,
  		    xpaddr->hper1);
  		return(-1);
  	}
--- 106,113 ----
  	while ((xpaddr->hpcs1.w & HP_RDY) == 0)
  			continue;
  	if (xpaddr->hpcs1.w & HP_TRE) {
! 		printf("%s err cy=%d tr=%d sc=%d cs2=%o er1=%o\n",
! 		    devname(io), cn, tn, sn, xpaddr->hpcs2,
  		    xpaddr->hper1);
  		return(-1);
  	}
***************
*** 220,227 ****
  				st->ntpc, st->nspt);
  			break;
  		default:
! 			printf("xp%d,%d unknown drive type: %d -- ", 
! 				io->i_ctlr, io->i_unit, type);
  			printf("using 1 cyl, 1 trk, 2 sec/trk\n");
  			st = &default_st;
  			break;
--- 224,231 ----
  				st->ntpc, st->nspt);
  			break;
  		default:
! 			printf("%s unknown drive type: %d -- ", 
! 				devname(io), type);
  			printf("using 1 cyl, 1 trk, 2 sec/trk\n");
  			st = &default_st;
  			break;
***************
*** 257,264 ****
  				st = &eagle_st;
  				break;
  			default:
! 				printf("xp%d,%d unknown SI drive model %d -- ", 
! 					io->i_ctlr, io->i_unit, xpsn);
  				printf("using 1 cyl, 1 trk, 2 sec/trk\n");
  				st = &default_st;
  				break;
--- 261,268 ----
  				st = &eagle_st;
  				break;
  			default:
! 				printf("%s unknown SI drive model %d -- ", 
! 					devname(io), xpsn);
  				printf("using 1 cyl, 1 trk, 2 sec/trk\n");
  				st = &default_st;
  				break;
*** /sys/pdpstand/br.c.old	Thu Jun  8 19:32:49 1995
--- /sys/pdpstand/br.c	Fri Mar  8 16:31:54 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)br.c	2.2 (2.11BSD) 1995/06/08
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)br.c	2.3 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 49,55 ****
  		while ((braddr->brcs.w & BR_RDY) == 0 && --ctr)
  			continue;
  		if (braddr->brcs.w & BR_HE) {
! 			printf("br%d,%d !ready\n", ctlr,unit);
  			return(-1);
  		}
  		com = braddr->brae;
--- 49,55 ----
  		while ((braddr->brcs.w & BR_RDY) == 0 && --ctr)
  			continue;
  		if (braddr->brcs.w & BR_HE) {
! 			printf("%s !ready\n", devname(io));
  			return(-1);
  		}
  		com = braddr->brae;
***************
*** 85,92 ****
  	while ((braddr->brcs.w& BR_RDY)==0)
  		continue;
  	if (braddr->brcs.w < 0) {	/* error bit */
! 		printf("br%d err: cy=%d tr=%d sc=%d er=%o ds=%o\n",
! 		    unit, cn, tn, sn, braddr->brer, braddr->brds);
  		return(-1);
  	}
  	return(io->i_cc);
--- 85,92 ----
  	while ((braddr->brcs.w& BR_RDY)==0)
  		continue;
  	if (braddr->brcs.w < 0) {	/* error bit */
! 		printf("%s err: cy=%d tr=%d sc=%d er=%o ds=%o\n",
! 		    devname(io), cn, tn, sn, braddr->brer, braddr->brds);
  		return(-1);
  	}
  	return(io->i_cc);
*** /sys/pdpstand/hk.c.old	Thu Jun  8 19:35:27 1995
--- /sys/pdpstand/hk.c	Fri Mar  8 16:33:15 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)hk.c	2.1 (2.11BSD) 1995/06/08
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)hk.c	2.2 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 85,92 ****
  		continue;
  
  	if (hkaddr->hkcs1 & HK_CERR) {
! 		printf("hk%d,%d err: cy=%d tr=%d sc=%d cs2=%d er=%o\n",
! 			ctlr, unit, cn, tn, sn, hkaddr->hkcs2, hkaddr->hker);
  		return(-1);
  	}
  	return(io->i_cc);
--- 85,92 ----
  		continue;
  
  	if (hkaddr->hkcs1 & HK_CERR) {
! 		printf("%s err: cy=%d tr=%d sc=%d cs2=%d er=%o\n",
! 			devname(io), cn, tn, sn, hkaddr->hkcs2, hkaddr->hker);
  		return(-1);
  	}
  	return(io->i_cc);
*** /sys/pdpstand/ht.c.old	Thu Jun  8 19:35:38 1995
--- /sys/pdpstand/ht.c	Fri Mar  8 16:34:12 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ht.c	2.2 (2.11BSD) 1995/06/08
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ht.c	2.3 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 131,138 ****
  	}
  	if (htaddr->htcs1 & HT_TRE) {
  		if (errcnt == 0)
! 			printf("\nht%d,%d err: cs2=%o, er=%o",
! 			    ctlr, unit, htaddr->htcs2, htaddr->hter);
  		htinit(htaddr);
  		if (errcnt++ == 10) {
  			printf("\n(FATAL ERROR)\n");
--- 131,138 ----
  	}
  	if (htaddr->htcs1 & HT_TRE) {
  		if (errcnt == 0)
! 			printf("\n%s err: cs2=%o, er=%o",
! 			    devname(io), htaddr->htcs2, htaddr->hter);
  		htinit(htaddr);
  		if (errcnt++ == 10) {
  			printf("\n(FATAL ERROR)\n");
*** /sys/pdpstand/rk.c.old	Thu Jun  8 19:36:31 1995
--- /sys/pdpstand/rk.c	Fri Mar  8 16:35:25 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rk.c	2.1 (2.11BSD) 1995/06/08
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rk.c	2.2 (2.11BSD) 1996/3/8
   */
  
  /*
***************
*** 49,56 ****
  	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",
! 		    io->i_ctlr, io->i_unit, cn, sn, rkaddr->rker, rkaddr->rkds);
  		return(-1);
  	}
  	return(io->i_cc);
--- 49,56 ----
  	while ((rkaddr->rkcs & RKCS_RDY) == 0)
  		continue;
  	if (rkaddr->rkcs<0) {	/* error bit */
! 		printf("%s err cy=%d sc=%d, er=%o, ds=%o\n",
! 		    devname(io), cn, sn, rkaddr->rker, rkaddr->rkds);
  		return(-1);
  	}
  	return(io->i_cc);
*** /VERSION.old	Sat Mar  2 01:08:15 1996
--- /VERSION	Fri Mar  8 22:54:36 1996
***************
*** 1,4 ****
! Current Patch Level: 306
  
  2.11 BSD
  ============
--- 1,4 ----
! Current Patch Level: 307
  
  2.11 BSD
  ============