Subject: Tmscp EOT bug, redundant disklabel code, sysctl MSCP interface (#403)
Index:	pdpuba/tmscp.c,mscp.c,more 2.11BSD

Description:
	1) If EOT is encountered on a TMSCP (TK50 for example) tape the only
	   recovery is to manually unload the tape.
	
	2) Each diskdriver which implements disklabels has an identical 
	   paragraph (~256bytes of instructions) of code in the strategy
	   routine to determine if a diskblock is within a partition.

	3) The MSCP driver lacks a debug/log sysctl interface such as the one
	   implemented in the TMSCP driver.  
	   
	   The MSCP driver wastes a noticeable amount of D space on error
	   message strings which are never or rarely seen.

	   There are numerous 'printf' statements which should be 'log' calls.

	   All in all the MSCP driver was in need of some cleanup.

Repeat-By:
	1) Write to a TK50 (or TU81+) until it is full.  The program will 
	   properly receive an error at EOT.  Then try to rewind the tape using 
	   the 'mt -f /dev/rmt0 rewind' command.  Notice the failure of the
	   tape to rewind as well as the error returned to 'mt'.

	2) Observation.  While adding the sysctl interface to the MSCP driver
	   it was observed that the partition validation check of a block 
	   number was a substantial amount of code and it was replicated in
	   all disk drivers.  If multiple controller types are present in the
	   kernel (a MSCP and RL for example) there is about 256 bytes of
	   extra code present.

	3) This was noticed when the sysctl interface was being added to the
	   TMSCP driver.  The MSCP and TMSCP drivers are similar in many ways
	   and it was felt that the ability to tune the debug/log level of
	   the MSCP driver without recompiling/rebooting was desireable.

Fix:
	#1 was caused by the EOM (EndOfMedia) status being 'sticky' - the 
	   strategy routine would see the EOM bit set and always return an
	   ENOSPC (no space) error.  This prevented any ioctl commands from
	   being accepted including the 'rewind' command.  The strategy routine
	   was modified to block further read or write requests but allow
	   ioctl commands thru.  NOTE:  If at EOM a program issues a 'space
	   forward' command it deserves what it gets :)

	#2 - fixed by creating the common routine 'partition_check' and
	   placing it in ufs_disksubr.c.  All drivers which implement disk
	   labels were changed to call this new routine.  In the GENERIC
	   kernel (which has RL, MSCP, HK, and XP) this saved about 700 bytes
	   of code.

	#3 - The cleanup involved replacing 'printf' calls with  'log' calls, 
	     removing redundant error checks, and collapsing repeated code 
	     into "helper functions".  The datagram/error reporting was made 
	     to look like the TMSCP version.  In the future there will be an 
	     error log daemon to which the MSCP and TMSCP (as well as other
	     drivers) can submit packets for capture.

	The following files are modified by this update:

/usr/src/sys/pdpuba/tmscp.c
/usr/src/sys/pdpuba/ra.c
/usr/src/sys/pdpuba/rl.c
/usr/src/sys/pdpuba/xp.c
/usr/src/sys/pdpuba/hk.c
/usr/src/sys/sys/ufs_disksubr.c
/usr/src/sys/h/mtio.h
/usr/src/sys/pdp/kern_pdp.c
/usr/src/sys/pdp/cpu.h
/usr/src/bin/sysctl/sysctl.c
/usr/src/bin/sysctl/sysctl.8
/VERSION

	To install this update cut where indicated and save to a file (/tmp/403)
	then:

		patch -p0 < /tmp/403
		cd /usr/src/bin/sysctl
		make clean
		make
		make install

	A new kernel is now built. It is presumed that a networking kernel is
	being built and installed.  If this is not the case then omit references
	to 'netnix'.

		cd /sys/YOUR_KERNEL_NAME
		make clean
		make
		mv /unix /ounix
		mv /netnix /onetnix
		mv unix netnix /
		chmod 744 /netnix /unix

	Then shutdown and reboot the system.

	Next a new GENERIC kernel is created and installed.  This step is 
	optional but it is a good idea to keep a current GENERIC kernel around:

		cd /sys/GENERIC
		make clean
		make
		install -m 744 unix /genunix
		make clean

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

==========================cut here=====================
*** /usr/src/sys/pdpuba/tmscp.c.old	Sun Feb  1 14:07:30 1998
--- /usr/src/sys/pdpuba/tmscp.c	Sat Mar  7 18:10:56 1998
***************
*** 1,6 ****
  #define	TMSDEBUG	1
  
! /*	@(#)tmscp.c	1.9 (2.11BSD GTE) 1998/2/1 */
  
  #if	!defined(lint) && defined(DOSCCS)
  static	char	*sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
--- 1,6 ----
  #define	TMSDEBUG	1
  
! /*	@(#)tmscp.c	1.10 (2.11BSD GTE) 1998/3/7 */
  
  #if	!defined(lint) && defined(DOSCCS)
  static	char	*sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
***************
*** 32,37 ****
--- 32,43 ----
   * 
   * Modification History:
   *
+  * 07-Mar-98 - sms
+  *	Fix a bug that caused EOM to be 'sticky'.  Once EndOfMedia was detected
+  *	the only way to clear it was to unload and reload the tape.  Remove
+  *	unused flag definitions.  Only use a single 'written' flag instead of
+  *	two (one in tms_flags and another in Tflags).
+  *
   * 01-Feb-98 - sms
   *	Initially the thought was the driver was broken sometime around June
   *	1996.  After adding additional logging and the 'sysctl' interface it
***************
*** 263,279 ****
  
  #define	_SEREX		0x0001		/* Serious Exception exists */
  #define	_CLSEREX	0x0002		/* Do Clear Serious Exception */
! #define	_EOM		0x0004		/* At End Of Media */
! #define	_BOM		0x0008		/* At Beginning Of Media */
! #define	_WRITTEN	0x0010		/* Tape has been Written */
! #define	_LOST		0x0020		/* Position lost error happened */
! #define	_BUFMARK	0x0040		/* Encountered a tape mark */
! #define	_HASCACHE	0x0080		/* Drive has cache capability */
! #define	_CACHE_ON	0x0100		/* Cache enabled */
! #define	_CACHE_LOST	0x0200		/* Cache data loss has happened */
! #define	_CACHE_WRITTEN	0x0400		/* Cache has been written */
! #define	_INUSE		0x0800		/* Drive is in use */
! #define	_ONLINE		0x1000		/* Drive is online */
  
  /*
   * Internal (ioctl) command codes (these must also be declared in the
--- 269,282 ----
  
  #define	_SEREX		0x0001		/* Serious Exception exists */
  #define	_CLSEREX	0x0002		/* Do Clear Serious Exception */
! #define	_LOST		0x0004		/* Position lost error happened */
! #define	_BUFMARK	0x0008		/* Encountered a tape mark */
! #define	_HASCACHE	0x0010		/* Drive has cache capability */
! #define	_CACHE_ON	0x0020		/* Cache enabled */
! #define	_CACHE_LOST	0x0040		/* Cache data loss has happened */
! #define	_CACHE_WRITTEN	0x0080		/* Cache has been written */
! #define	_INUSE		0x0100		/* Drive is in use */
! #define	_ONLINE		0x0200		/* Drive is online */
  
  /*
   * Internal (ioctl) command codes (these must also be declared in the
***************
*** 751,760 ****
  			tms->Tflags &= ~_CACHE_WRITTEN;
  			}
  		}
! 	tms->tms_flags &= ~MTF_CSE;
! 	if	(tms->Tflags & _WRITTEN)
  		tms_wrteof(dev, tms);
! 	tms->Tflags &= ~(_WRITTEN | _BUFMARK | _INUSE);
  	if	((dev & T_NOREWIND) == 0)
  		{
  		tmscpcommand(dev, TMS_REW, 0);
--- 754,762 ----
  			tms->Tflags &= ~_CACHE_WRITTEN;
  			}
  		}
! 	if	(tms->tms_flags & MTF_WRITTEN)
  		tms_wrteof(dev, tms);
! 	tms->Tflags &= ~(_BUFMARK | _INUSE);
  	if	((dev & T_NOREWIND) == 0)
  		{
  		tmscpcommand(dev, TMS_REW, 0);
***************
*** 1293,1302 ****
  		return;
  		}
  /*
!  * If we're at the end of the tape and no Clear Serious Exception has been
!  * done then return an error rather than reading off the end of the tape.
  */
! 	if	((tms->tms_flags & MTF_CSE) == 0 && (tms->tms_flags & MTF_EOM))
  		{
  		bp->b_resid = bp->b_bcount;
  		bp->b_error = ENOSPC;
--- 1295,1306 ----
  		return;
  		}
  /*
!  * If we're at the end of the tape and this is not an 'ioctl' command
!  * then return an error rather than reading or writing off the end of the tape.
!  * Ioctl commands are allowed to proceed so that tapemarks can be written and
!  * repositioning (rewind, etc) can be done.
  */
! 	if	((tms->tms_flags & MTF_EOM) && bp != &sc->sc_cmdbuf)
  		{
  		bp->b_resid = bp->b_bcount;
  		bp->b_error = ENOSPC;
***************
*** 1575,1582 ****
  
  	if	(tms->Tflags & _CACHE_LOST)
  		{
! 		if	(!(tms->Tflags & _CACHE_WRITTEN) || 
! 			   (tms->tms_flags & MTF_CSE))
  			{
  			tms->Tflags &= ~(_CACHE_LOST | _CACHE_WRITTEN);
  			mp->mscp_modifier |= M_MD_CDATL;
--- 1579,1585 ----
  
  	if	(tms->Tflags & _CACHE_LOST)
  		{
! 		if	(!(tms->Tflags & _CACHE_WRITTEN))
  			{
  			tms->Tflags &= ~(_CACHE_LOST | _CACHE_WRITTEN);
  			mp->mscp_modifier |= M_MD_CDATL;
***************
*** 1602,1608 ****
  	if	(em_status == M_ST_SUCC)
  		{
  		if	(tms->tms_position != mp->mscp_position)
! 			tms->Tflags &= ~_WRITTEN;
  		if	(tms->tms_position = mp->mscp_position)
  			tms->tms_flags &= ~MTF_BOM;
  		else
--- 1605,1611 ----
  	if	(em_status == M_ST_SUCC)
  		{
  		if	(tms->tms_position != mp->mscp_position)
! 			tms->tms_flags &= ~MTF_WRITTEN;
  		if	(tms->tms_position = mp->mscp_position)
  			tms->tms_flags &= ~MTF_BOM;
  		else
***************
*** 1653,1659 ****
  
  	if	(em_status == M_ST_SUCC)
  		{
! 		tms->Tflags &= ~_WRITTEN;
  		tms->tms_position = mp->mscp_position;
  		}
  	(void)tms_check_ret(mp, sc);
--- 1656,1662 ----
  
  	if	(em_status == M_ST_SUCC)
  		{
! 		tms->tms_flags &= ~MTF_WRITTEN;
  		tms->tms_position = mp->mscp_position;
  		}
  	(void)tms_check_ret(mp, sc);
***************
*** 1751,1760 ****
  	if	(em_status == M_ST_SUCC)
  		{
  		if	((tms->tms_endcode & ~M_OP_END) == M_OP_WRITE)
- 			{
- 			tms->Tflags |= _WRITTEN;
  			tms->tms_flags |= MTF_WRITTEN;
- 			}
  		else
  			tms->Tflags &= ~_CACHE_WRITTEN;
  		}
--- 1754,1760 ----
*** /usr/src/sys/pdpuba/ra.c.old	Wed Jan 28 23:29:40 1998
--- /usr/src/sys/pdpuba/ra.c	Fri Apr  3 17:42:22 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	3.3 (2.11BSD GTE) 1998/1/28
   */
  
   /***********************************************************************
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	3.4 (2.11BSD GTE) 1998/4/3
   */
  
   /***********************************************************************
***************
*** 14,19 ****
--- 14,25 ----
  
  /* 
   * ra.c - MSCP Driver
+  * Date:	April 3, 1998
+  * Implement a sysctl interface for manipulating datagram/error logging (as was
+  * done for the TMSCP driver earlier).  Finish changing printf() statements to
+  * log() statements.  Clean the drive up by removing obsolete debugging state-
+  * ments.
+  *
   * Date:	January 28, 1998
   * Define the 'mscp_header' structure in the mscp_common.h and change the
   * member names from ra_* to mscp_*.  A small step towards merging the MSCP
***************
*** 143,149 ****
  #include <sys/kernel.h>
  
  #define	RACON(x)			((minor(x) >> 6) & 03)
! #define	RAUNIT(x)			((minor(x) >> 3) & 07)
  
  #define	NRSPL2	3		/* log2 number of response packets */
  #define	NCMDL2	3		/* log2 number of command packets */
--- 149,155 ----
  #include <sys/kernel.h>
  
  #define	RACON(x)			((minor(x) >> 6) & 03)
! #define	RAUNIT(x)			(dkunit(x) & 07)
  
  #define	NRSPL2	3		/* log2 number of response packets */
  #define	NCMDL2	3		/* log2 number of command packets */
***************
*** 228,247 ****
  #define	S_SCHAR	4		/* doing "set controller characteristics" */
  #define	S_RUN	5		/* running */
  
- #ifdef RADEBUG
- #define PRINTD(x)	printf x 
- #else
- #define PRINTD(x)
- #endif
- 
- #ifdef RABUGDUMP
- #define PRINTB(x)	printf x 
- #else
- #define PRINTB(x)
- #endif
- 
  int	rastrategy();
  daddr_t	rasize();
  
  extern	int	wakeup();
  extern	ubadr_t	_iomap();
--- 234,248 ----
  #define	S_SCHAR	4		/* doing "set controller characteristics" */
  #define	S_RUN	5		/* running */
  
  int	rastrategy();
  daddr_t	rasize();
+ /*
+  * Bit 0 = print/log all non successful response packets
+  * Bit 1 = print/log datagram arrival
+  * Bit 2 = print status of all response packets _except_ for datagrams
+  * Bit 3 = enable debug/log statements not covered by one of the above
+ */
+ 	int	mscpprintf = 0x1;
  
  extern	int	wakeup();
  extern	ubadr_t	_iomap();
***************
*** 356,363 ****
  	int	mask;
  	int	s, i;
  
- 	PRINTD(("raopen: dev=%x, flags=%d\n", dev, flag));
- 
  	/* Check that controller exists */
  	if	(ctlr >= NRAC || sc->RAADDR == NULL)
  		return(ENXIO);
--- 357,362 ----
***************
*** 390,396 ****
  	 */
  	disk = sc->sc_drives[unit];
  	if (disk == NULL) {
- 		PRINTD(("raopen: opening new disk %d\n", unit));
  		s = splbio();
  		/* Allocate disk table entry for disk */
  		if ((disk = ragetdd()) != NULL) {
--- 389,394 ----
***************
*** 397,403 ****
  			sc->sc_drives[unit] = disk;
  			disk->ra_unit = ctlr;	/* controller number */
  		} else {
! 			printf("ra: !disk structs\n");
  			splx(s);
  			return(ENXIO);
  		}
--- 395,402 ----
  			sc->sc_drives[unit] = disk;
  			disk->ra_unit = ctlr;	/* controller number */
  		} else {
! 			if	(mscpprintf & 0x8)
! 				log(LOG_NOTICE, "ra: !disk struc\n");
  			splx(s);
  			return(ENXIO);
  		}
***************
*** 424,435 ****
  
  	/* Did it go online? */
  	if ((disk->ra_flags & DKF_ONLINE) == 0) {
- 		PRINTD(("raopen: disk didn't go online\n"));
  		s = splbio();
  		disk->ra_flags = 0;
  		sc->sc_drives[unit] = NULL;
  		splx(s);
! 		return(ENXIO);
  	}
  /*
   * Now we read the label.  Allocate an external label structure if one has
--- 423,433 ----
  
  	/* Did it go online? */
  	if ((disk->ra_flags & DKF_ONLINE) == 0) {
  		s = splbio();
  		disk->ra_flags = 0;
  		sc->sc_drives[unit] = NULL;
  		splx(s);
! 		return(EIO);
  	}
  /*
   * Now we read the label.  Allocate an external label structure if one has
***************
*** 481,487 ****
  	else
  		return(EINVAL);
  	disk->ra_open |= mask;
- 	PRINTD(("raopen: disk online\n"));
  	return(0);
  }
  
--- 479,484 ----
***************
*** 584,590 ****
  	msg = readdisklabel((dev & ~7) | 0, rastrategy, lp);	/* 'a' */
  	if	(msg != 0)
  		{
! 		log(LOG_NOTICE, "ra%da is entire disk: %s\n", dkunit(dev), msg);
  		radfltlbl(disk, lp);
  		}
  	mapseg5(disk->ra_label, LABELDESC);
--- 581,589 ----
  	msg = readdisklabel((dev & ~7) | 0, rastrategy, lp);	/* 'a' */
  	if	(msg != 0)
  		{
! 		if	(mscpprintf & 0x8)
! 			log(LOG_NOTICE, "ra%da=entire disk: %s\n", 
! 				dkunit(dev), msg);
  		radfltlbl(disk, lp);
  		}
  	mapseg5(disk->ra_label, LABELDESC);
***************
*** 607,613 ****
  	 * Cold init of controller
  	 */
  	++sc->sc_ctab.b_active;
- 	PRINTD(("rainit: unit=%d, vec=%o\n", sc->sc_unit, sc->sc_ivec));
  
  	/*
  	 * Get physical address of RINGBASE
--- 606,611 ----
***************
*** 642,693 ****
  rastrategy(bp)
  	register struct	buf *bp;
  {
! 	register ra_infoT *disk;
  	register struct buf *dp;
! 	ra_softcT *sc = &ra_sc[RACON(bp->b_dev)];
! 	int	unit = RAUNIT(bp->b_dev);
! 	int	part = dkpart(bp->b_dev);
! 	struct	partition *pi;
! 	daddr_t sz, maxsz;
  	int s;
  
  	/* Is disk online */
! 	if ((disk = sc->sc_drives[unit]) == NULL || 
  			!(disk->ra_flags & (DKF_ONLINE | DKF_ALIVE)))
  		goto bad;
! 	pi = &disk->ra_parts[part];
! 
! 	/* Valid block in device partition */
! 	sz = (bp->b_bcount + 511) >> 9;
! 	if	(bp->b_blkno < 0 || bp->b_blkno + sz > pi->p_size)
! 		{
! 		sz = pi->p_size - bp->b_blkno;
! 		/* if exactly at end of disk, return an EOF */
! 		if	(sz == 0)
! 			{
! 			bp->b_resid = bp->b_bcount;
! 			goto done;	
! 			}
! 		/* or truncate if part of it fits */
! 		if	(sz < 0)
! 			{
! 			bp->b_error = EINVAL;
! 			goto bad;
! 			}
! 		bp->b_bcount = dbtob(sz);	/* compute byte count */
! 		}
! /*
!  * Check for write to write-protected label area.  This does not include
!  * sector 0 which is the boot block.
! */
! 	if	(bp->b_blkno + pi->p_offset <= LABELSECTOR &&
! 		 bp->b_blkno + pi->p_offset + sz > LABELSECTOR &&
! 		 !(bp->b_flags & B_READ) && !(disk->ra_flags & DKF_WLABEL))
! 		{
! 		bp->b_error = EROFS;
  		goto bad;
! 		}
! 
  	mapalloc(bp);		/* Unibus Map buffer if required */
  
  	/*
--- 640,659 ----
  rastrategy(bp)
  	register struct	buf *bp;
  {
! 	ra_infoT *disk;
  	register struct buf *dp;
! 	register ra_softcT *sc = &ra_sc[RACON(bp->b_dev)];
  	int s;
  
  	/* Is disk online */
! 	if	((disk = sc->sc_drives[RAUNIT(bp->b_dev)]) == NULL || 
  			!(disk->ra_flags & (DKF_ONLINE | DKF_ALIVE)))
  		goto bad;
! 	s = partition_check(bp, &disk->ra_dk);
! 	if	(s < 0)
  		goto bad;
! 	if	(s == 0)
! 		goto done;
  	mapalloc(bp);		/* Unibus Map buffer if required */
  
  	/*
***************
*** 718,726 ****
  	/*
  	 * Start controller if idle.
  	 */
! 	if (sc->sc_ctab.b_active == 0) {
  		rastart(sc);
- 	}
  	splx(s);
  	return;
  bad:
--- 684,691 ----
  	/*
  	 * Start controller if idle.
  	 */
! 	if (sc->sc_ctab.b_active == 0)
  		rastart(sc);
  	splx(s);
  	return;
  bad:
***************
*** 782,789 ****
  	++sc->sc_ctab.b_active;
  	if (sc->RAADDR->rasa & RA_ERR || sc->sc_state != S_RUN) {
  		harderr(bp, "ra");
- 		log(LOG_INFO, "rasa %o state %d\n", sc->RAADDR->rasa,
- 			sc->sc_state);
  		/* Should requeue outstanding requests somehow */
  		rainit(sc);
  out:
--- 747,752 ----
***************
*** 806,817 ****
  	mp->m_bytecnt = bp->b_bcount;
  	mp->m_buf_l = (u_short)bp->b_un.b_addr;
  	mp->m_buf_h = bp->b_xmem;
- 	PRINTD(("ra: unit=%d op=0%o lbn=%d,%d len=%d buf=0%o,0%o\n",
- 		mp->m_unit, mp->m_opcode, mp->m_lbn_h, mp->m_lbn_l,
- 		mp->m_bytecnt, mp->m_buf_h, mp->m_buf_l));
  	((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT;
- 	if (sc->RAADDR->rasa & RA_ERR)
- 		printf("ra: Err %d\n", sc->RAADDR->rasa);
  	i = sc->RAADDR->raip;		/* initiate polling */
  
  #ifdef UCB_METER
--- 769,775 ----
***************
*** 860,868 ****
  	u_int i;
  	segm seg5;
  
- 	PRINTD(("raintr%d: state %d, rasa %o\n", unit, sc->sc_state,
- 		sc->RAADDR->rasa));
- 
  	saveseg5(seg5);		/* save it just once */
  
  	switch (sc->sc_state) {
--- 818,823 ----
***************
*** 869,909 ****
  	case S_STEP1:
  #define	STEP1MASK	0174377
  #define	STEP1GOOD	(RA_STEP2|RA_IE|(NCMDL2<<3)|NRSPL2)
! 		if ((sc->RAADDR->rasa & STEP1MASK) != STEP1GOOD) {
! 			sc->sc_state = S_IDLE;
! 			sc->sc_ctab.b_active = 0;
! 			wakeup((caddr_t)&sc->sc_ctab);
  			return;
- 		}
  		sc->RAADDR->rasa = (short)sc->sc_ctab.b_un.b_addr;
  		sc->sc_state = S_STEP2;
  		return;
- 
  	case S_STEP2:
  #define	STEP2MASK	0174377
  #define	STEP2GOOD	(RA_STEP3|RA_IE|(sc->sc_ivec/4))
! 		if ((sc->RAADDR->rasa & STEP2MASK) != STEP2GOOD) {
! 			sc->sc_state = S_IDLE;
! 			sc->sc_ctab.b_active = 0;
! 			wakeup((caddr_t)&sc->sc_ctab);
  			return;
- 		}
  		sc->RAADDR->rasa = sc->sc_ctab.b_xmem;
  		sc->sc_state = S_STEP3;
  		return;
- 
  	case S_STEP3:
  #define	STEP3MASK	0174000
  #define	STEP3GOOD	RA_STEP4
! 		if ((sc->RAADDR->rasa & STEP3MASK) != STEP3GOOD) {
! 			sc->sc_state = S_IDLE;
! 			sc->sc_ctab.b_active = 0;
! 			wakeup((caddr_t)&sc->sc_ctab);
  			return;
- 		}
  		i = sc->RAADDR->rasa;
! 		PRINTD(("ra: Version %d model %d\n",
! 				i & 0xf, (i >> 4) & 0xf));
  		sc->RAADDR->rasa = RA_GO;
  		sc->sc_state = S_SCHAR;
  
--- 824,850 ----
  	case S_STEP1:
  #define	STEP1MASK	0174377
  #define	STEP1GOOD	(RA_STEP2|RA_IE|(NCMDL2<<3)|NRSPL2)
! 		if	(radostep(sc, STEP1MASK, STEP1GOOD))
  			return;
  		sc->RAADDR->rasa = (short)sc->sc_ctab.b_un.b_addr;
  		sc->sc_state = S_STEP2;
  		return;
  	case S_STEP2:
  #define	STEP2MASK	0174377
  #define	STEP2GOOD	(RA_STEP3|RA_IE|(sc->sc_ivec/4))
! 		if	(radostep(sc, STEP2MASK, STEP2GOOD))
  			return;
  		sc->RAADDR->rasa = sc->sc_ctab.b_xmem;
  		sc->sc_state = S_STEP3;
  		return;
  	case S_STEP3:
  #define	STEP3MASK	0174000
  #define	STEP3GOOD	RA_STEP4
! 		if	(radostep(sc, STEP3MASK, STEP3GOOD))
  			return;
  		i = sc->RAADDR->rasa;
! 		log(LOG_NOTICE, "ra%d: Ver %d mod %d\n", sc->sc_unit,
! 				i & 0xf, (i >> 4) & 0xf);
  		sc->RAADDR->rasa = RA_GO;
  		sc->sc_state = S_SCHAR;
  
***************
*** 927,939 ****
  		i = sc->RAADDR->raip;
  		restorseg5(seg5);
  		return;
- 
  	case S_SCHAR:
  	case S_RUN:
  		break;
- 
  	default:
! 		printf("ra: state %d ign\n", sc->sc_state);
  		return;
  	}
  
--- 868,878 ----
  		i = sc->RAADDR->raip;
  		restorseg5(seg5);
  		return;
  	case S_SCHAR:
  	case S_RUN:
  		break;
  	default:
! 		log(LOG_NOTICE, "ra: st %d\n", sc->sc_state);
  		return;
  	}
  
***************
*** 940,951 ****
  	/*
  	 * If this happens we are in BIG trouble!
  	 */
! 	if (sc->RAADDR->rasa & RA_ERR) {
! 		printf("ra: fatal err %o\n", sc->RAADDR->rasa);
! 		sc->sc_state = S_IDLE;
! 		sc->sc_ctab.b_active = 0;
! 		wakeup((caddr_t)&sc->sc_ctab);
! 	}
  
  	mapseg5(ra_com[sc->sc_unit], MAPSEGDESC);
  
--- 879,886 ----
  	/*
  	 * If this happens we are in BIG trouble!
  	 */
! 	if	(radostep(sc, RA_ERR, 0))
! 		log(LOG_ERR, "ra: err %o\n", sc->RAADDR->rasa);
  
  	mapseg5(ra_com[sc->sc_unit], MAPSEGDESC);
  
***************
*** 960,968 ****
  	/*
  	 * Check for response ring transition.
  	 */
! 	if (sc->sc_com->ra_ca.ca_rspint) {
  		rarspring(sc);
- 	}
  
  	/*
  	 * Check for command ring transition (Should never happen!)
--- 895,902 ----
  	/*
  	 * Check for response ring transition.
  	 */
! 	if (sc->sc_com->ra_ca.ca_rspint)
  		rarspring(sc);
  
  	/*
  	 * Check for command ring transition (Should never happen!)
***************
*** 978,983 ****
--- 912,932 ----
  	rastart(sc);
  }
  
+ radostep(sc, mask, good)
+ 	register ra_softcT *sc;
+ 	int	mask, good;
+ 	{
+ 
+ 	if	((sc->RAADDR->rasa & mask) != good)
+ 		{
+ 		sc->sc_state = S_IDLE;
+ 		sc->sc_ctab.b_active = 0;
+ 		wakeup((caddr_t)&sc->sc_ctab);
+ 		return(1);
+ 		}
+ 	return(0);
+ 	}
+ 
  /*
   * Init mscp communications area
   */
***************
*** 1089,1095 ****
  	 * pass it on for more extensive processing.
  	 */
  	if ((mp->m_header.mscp_credits & 0xf0) == 0x10) {
! 		ra_error((struct mslg *)mp);
  		return;
  	}
  
--- 1038,1044 ----
  	 * pass it on for more extensive processing.
  	 */
  	if ((mp->m_header.mscp_credits & 0xf0) == 0x10) {
! 		ra_error(sc->sc_unit, (struct mslg *)mp);
  		return;
  	}
  
***************
*** 1097,1102 ****
--- 1046,1056 ----
  	 * The controller interrupts as drive ZERO so check for it first.
  	 */
  	st = mp->m_status & M_ST_MASK;
+ 	if	(mscpprintf & 0x4 || ((mscpprintf & 0x1) && (st != M_ST_SUCC)))
+ 		log(LOG_INFO, "ra%d st=%x sb=%x fl=%x en=%x\n",
+ 			sc->sc_unit*8 + mp->m_unit, st,
+ 			mp->m_status >> M_ST_SBBIT,
+ 			mp->m_flags, mp->m_opcode & ~M_OP_END);
  	if (mp->m_opcode == (M_OP_STCON|M_OP_END)) {
  		if (st == M_ST_SUCC)
  			sc->sc_state = S_RUN;
***************
*** 1112,1122 ****
  	 */
  	switch (mp->m_opcode) {
  	case M_OP_ONLIN|M_OP_END:
! 		if ((disk = sc->sc_drives[mp->m_unit]) == NULL) {
! 			log(LOG_NOTICE,"ra%d !ONLINE\n", sc->sc_unit * 8 +
! 				mp->m_unit);
  			break;
- 		}
  		dp = &disk->ra_utab;
  
  		if (st == M_ST_SUCC) {
--- 1066,1073 ----
  	 */
  	switch (mp->m_opcode) {
  	case M_OP_ONLIN|M_OP_END:
! 		if	((disk = sc->sc_drives[mp->m_unit]) == NULL)
  			break;
  		dp = &disk->ra_utab;
  
  		if (st == M_ST_SUCC) {
***************
*** 1132,1138 ****
  			radisksetup(disk, mp);
  			dp->b_active = 1;
  		} else {
- 			printf("ra%d: OFFLINE\n", sc->sc_unit * 8 + mp->m_unit);
  			while (bp = dp->b_actf) {
  				dp->b_actf = bp->av_forw;
  				bp->b_flags |= B_ERROR;
--- 1083,1088 ----
***************
*** 1144,1163 ****
  		if (mp->m_cmdref != NULL)
  			wakeup((caddr_t)mp->m_cmdref);
  		break;
- 
  	case M_OP_AVATN:
  		/* it went offline and we didn't notice */
- 		PRINTD(("ra%d: attention\n", sc->sc_unit * 8 + mp->m_unit));
  		if ((disk = sc->sc_drives[mp->m_unit]) != NULL)
  			disk->ra_flags &= ~DKF_ONLINE;
  		break;
- 
  	case M_OP_END:
  		/* controller incorrectly returns code 0200 instead of 0241 */
- 		PRINTD(("ra: back logical block request\n"));
  		bp = (struct buf *)mp->m_cmdref;
  		bp->b_flags |= B_ERROR;
- 
  	case M_OP_READ | M_OP_END:
  	case M_OP_WRITE | M_OP_END:
  		/* normal termination of read/write request */
--- 1094,1108 ----
***************
*** 1208,1220 ****
  		bp->b_resid = bp->b_bcount - mp->m_bytecnt;
  		iodone(bp);
  		break;
- 
  	case M_OP_GTUNT|M_OP_END:
  		break;
- 
  	default:
! 		log(LOG_INFO,"ra: op %o\n", mp->m_opcode);
! 		ra_error((caddr_t)mp);
  	}
  }
  
--- 1153,1162 ----
  		bp->b_resid = bp->b_bcount - mp->m_bytecnt;
  		iodone(bp);
  		break;
  	case M_OP_GTUNT|M_OP_END:
  		break;
  	default:
! 		ra_error(sc->sc_unit, (caddr_t)mp);
  	}
  }
  
***************
*** 1273,1326 ****
  	}
  
  /*
!  * Process an error log message
!  *
!  * For now, just log the error on the console.  Only minimal decoding is done,
!  * only "useful" information is printed.  Eventually should send message to
!  * an error logger.  At least 90 bytes of D space were saved without losing
!  * functionality.
   */
- ra_error(mp)
- 	register struct mslg *mp;
- {
- 	printf("ra: %s err, ",
- 		mp->me_flags & (M_LF_SUCC|M_LF_CONT) ? "soft" : "hard");
  
! 	switch (mp->me_format) {
! 	case M_FM_CNTERR:
! 		printf("ctlr");
! 		break;
! 	case M_FM_BUSADDR:
! 		printf("M_F_BUSADDR %o", mp->me_busaddr);
! 		break;
! 	case M_FM_DISKTRN:
! 		printf("disk xfr, unit %d grp x%x hdr x%x",
! 			mp->me_unit, mp->me_group, mp->me_hdr);
! 		break;
! 	case M_FM_SDI:
! 		printf("SDI unit %d hdr x%x", mp->me_unit, mp->me_hdr);
! 		break;
! 	case M_FM_SMLDSK:
! 		printf("small disk unit %d cyl %d", mp->me_unit, mp->me_sdecyl);
! 		break;
! 	default:
! 		printf("?, unit %d format %o",mp->me_unit,mp->me_format);
! 	}
  
! 	printf(", event 0%o\n", mp->me_event);
! 
! #ifdef RADEBUG
! 	/* If error debug on, do hex dump */
  	{
- 		register char *p = (char *)mp;
- 		register int i;
  
! 		for (i = mp->me_header.mscp_msglen; i--; /*void*/)
! 			printf("%x ", *p++ & 0xff);
! 		printf("\n");
  	}
- #endif
- }
  
  /*
   * RA dump routines (act like stand alone driver)
--- 1215,1240 ----
  	}
  
  /*
!  * For now just count the datagrams and log a short message of (hopefully)
!  * interesting fields if the appropriate bit in turned on in mscpprintf.
!  * 
!  * An error log daemon is in the process of being written.  When it is ready
!  * many drivers (including this one) will be converted to use it.
   */
  
! 	u_short	mscp_datagrams[NRAC];
  
! ra_error(ctlr, mp)
! 	int	ctlr;
! 	register struct mslg *mp;
  	{
  
! 	mscp_datagrams[ctlr]++;
! 	if	(mscpprintf & 0x2)
! 		log(LOG_INFO, "ra%d dgram fmt %x grp %x hdr %x evt %x cyl %x\n",
! 			ctlr*8 + mp->me_unit, mp->me_format, mp->me_group,
! 			mp->me_hdr, mp->me_event, mp->me_sdecyl);
  	}
  
  /*
   * RA dump routines (act like stand alone driver)
***************
*** 1394,1415 ****
  		/*void*/;
  	sc->RAADDR->rasa = RA_GO;
  	ramsginit(sc, sc->sc_com->ra_ca.ca_rsp, mp, 0, 2, 0);
! 	if (!racmd(M_OP_STCON, unit, sc)) {
! 		PRINTB(("radump: failed start controller\n"));
  		return(EFAULT);
- 	}
- 	PRINTB(("radump: controller up\n"));
  
  	/* Bring disk for dump online */
! 	if (!(mp = racmd(M_OP_ONLIN, unit, sc))) {
! 		PRINTB(("radump: failed online\n"));
  		return(EFAULT);
- 	}
  
   	dumpsize = rasize(dev) - dumplo;
  	memblks = ctod(physmem);
- 	PRINTB(("radump: disk up, size=%D, type=%d\n",
- 		dumpsize, hiint(mp->m_mediaid) & 0xff));
  
  	/* Check if dump ok on this disk */
  	if (dumplo < 0 || dumpsize <= 0)
--- 1308,1322 ----
  		/*void*/;
  	sc->RAADDR->rasa = RA_GO;
  	ramsginit(sc, sc->sc_com->ra_ca.ca_rsp, mp, 0, 2, 0);
! 	if (!racmd(M_OP_STCON, unit, sc))
  		return(EFAULT);
  
  	/* Bring disk for dump online */
! 	if (!(mp = racmd(M_OP_ONLIN, unit, sc)))
  		return(EFAULT);
  
   	dumpsize = rasize(dev) - dumplo;
  	memblks = ctod(physmem);
  
  	/* Check if dump ok on this disk */
  	if (dumplo < 0 || dumpsize <= 0)
***************
*** 1439,1445 ****
  		mp->m_buf_h = hiint(maddr);
  		if (racmd(M_OP_WRITE, unit, sc) == 0)
  			return(EIO);
- 
  		paddr += (count << PGSHIFT);
  		bn += count;
  		memblks -= count;
--- 1346,1351 ----
***************
*** 1479,1485 ****
  	sc->sc_com->ra_ca.ca_cmdint = 0;
  	if (rmp->m_opcode != (op | M_OP_END)
  	    || (rmp->m_status & M_ST_MASK) != M_ST_SUCC) {
! 		ra_error(rmp);
  		return(0);
  	}
  	return(rmp);
--- 1385,1391 ----
  	sc->sc_com->ra_ca.ca_cmdint = 0;
  	if (rmp->m_opcode != (op | M_OP_END)
  	    || (rmp->m_status & M_ST_MASK) != M_ST_SUCC) {
! 		ra_error(sc->sc_unit, rmp);
  		return(0);
  	}
  	return(rmp);
*** /usr/src/sys/pdpuba/rl.c.old	Sun Jul 20 11:37:47 1997
--- /usr/src/sys/pdpuba/rl.c	Fri Apr  3 21:35:34 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rl.c	1.10 (2.11BSD GTE) 1997/7/20
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)rl.c	1.11 (2.11BSD GTE) 1998/4/3
   */
  
  /*
***************
*** 64,70 ****
  #define	RL_SECSZ	256	/* bytes per sector */
  
  #define	rlwait(r)	while (((r)->rlcs & RL_CRDY) == 0)
! #define	RLUNIT(x) 	((minor(x) >> 3) & 7)
  #define RLMP_MASK	( ~( RLMP_WL | RLMP_DTYP | RLMP_HSEL ) )
  #define RLMP_OK		( RLMP_HO | RLMP_BH | RLMP_LCKON )
  
--- 64,70 ----
  #define	RL_SECSZ	256	/* bytes per sector */
  
  #define	rlwait(r)	while (((r)->rlcs & RL_CRDY) == 0)
! #define	RLUNIT(x) 	(dkunit(x) & 7)
  #define RLMP_MASK	( ~( RLMP_WL | RLMP_DTYP | RLMP_HSEL ) )
  #define RLMP_OK		( RLMP_HO | RLMP_BH | RLMP_LCKON )
  
***************
*** 110,116 ****
  }
  
  rlattach(addr, unit)
! 	struct rldevice *addr;
  {
  #ifdef UCB_METER
  	if (rl_dkn < 0) {
--- 110,116 ----
  }
  
  rlattach(addr, unit)
! 	register struct rldevice *addr;
  {
  #ifdef UCB_METER
  	if (rl_dkn < 0) {
***************
*** 320,333 ****
  rlstrategy(bp)
  	register struct	buf *bp;
  {
! 	int	drive, part;
! 	int	s, ctr;
! 	daddr_t	sz;
  	register struct dkdevice *disk;
- 	register struct partition *pi;
  
  	drive = RLUNIT(bp->b_dev);
- 	part = dkpart(bp->b_dev);
  	disk = &rl_dk[drive];
  
  	if	(drive >= NRL || !RLADDR || !(disk->dk_flags & DKF_ALIVE))
--- 320,330 ----
  rlstrategy(bp)
  	register struct	buf *bp;
  {
! 	int	drive;
! 	register int	s;
  	register struct dkdevice *disk;
  
  	drive = RLUNIT(bp->b_dev);
  	disk = &rl_dk[drive];
  
  	if	(drive >= NRL || !RLADDR || !(disk->dk_flags & DKF_ALIVE))
***************
*** 335,373 ****
  		bp->b_error = ENXIO;
  		goto bad;
  		}
! 
! 	pi = &disk->dk_parts[part];
! 
! 	/* Valid block in device partition */
! 	sz = (bp->b_bcount + 511) >> 9;
! 	if	(bp->b_blkno < 0 || bp->b_blkno + sz > pi->p_size)
! 		{
! 		sz = pi->p_size - bp->b_blkno;
! 		/* if exactly at end of disk, return an EOF */
! 		if	(sz == 0)
! 			{
! 			bp->b_resid = bp->b_bcount;
! 			goto done;	
! 			}
! 		/* or truncate if part of it fits */
! 		if	(sz < 0)
! 			{
! 			bp->b_error = EINVAL;
! 			goto bad;
! 			}
! 		bp->b_bcount = dbtob(sz);	/* compute byte count */
! 		}
! /*
!  * Check for write to write-protected label area.  This does not include
!  * sector 0 which is the boot block.
! */
! 	if	(bp->b_blkno + pi->p_offset <= LABELSECTOR &&
! 		 bp->b_blkno + pi->p_offset + sz > LABELSECTOR &&
! 		 !(bp->b_flags & B_READ) && !(disk->dk_flags & DKF_WLABEL))
! 		{
! 		bp->b_error = EROFS;
  		goto bad;
! 		}
  #ifdef	SOFUB_MAP
  	if	(rlsoftmap == 1)
  		{
--- 332,342 ----
  		bp->b_error = ENXIO;
  		goto bad;
  		}
! 	s = partition_check(bp, disk);
! 	if	(s < 0)
  		goto bad;
! 	if	(s == 0)
! 		goto done;
  #ifdef	SOFUB_MAP
  	if	(rlsoftmap == 1)
  		{
***************
*** 773,779 ****
   * attempts, then an error message is printed.
   */
  rlgsts(drive)
! 	int	drive;
  	{
  	register int	ctr = 0;
  	register struct	rldevice *rp = RLADDR;
--- 742,748 ----
   * attempts, then an error message is printed.
   */
  rlgsts(drive)
! 	register int	drive;
  	{
  	register int	ctr = 0;
  	register struct	rldevice *rp = RLADDR;
***************
*** 785,791 ****
  		} while (((rp->rlmp & RLMP_MASK) != RLMP_OK) && (++ctr < 16));
  	if	(ctr >= 16)
  		{
! 		log(LOG_ERR, "rl%d: !status cs=%b da=%b\n", drive,
  			rp->rlcs, RL_BITS, rp->rlda, RLDA_BITS);
  		rl_dk[drive].dk_flags &= ~DKF_ALIVE;
  		return(-1);
--- 754,760 ----
  		} while (((rp->rlmp & RLMP_MASK) != RLMP_OK) && (++ctr < 16));
  	if	(ctr >= 16)
  		{
! 		log(LOG_ERR, "rl%d: !sts cs=%b da=%b\n", drive,
  			rp->rlcs, RL_BITS, rp->rlda, RLDA_BITS);
  		rl_dk[drive].dk_flags &= ~DKF_ALIVE;
  		return(-1);
*** /usr/src/sys/pdpuba/xp.c.old	Tue Nov 11 21:20:36 1997
--- /usr/src/sys/pdpuba/xp.c	Fri Apr  3 21:57:38 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	2.5 (2.11BSD GTE) 1997/11/11
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	2.6 (2.11BSD GTE) 1998/4/3
   */
  
  /*
***************
*** 45,51 ****
   * NOTE: this  is different than /boot's view of the world.  Sigh.
  */
  
! #define	XPUNIT(dev)	((minor(dev) >> 3) & 0x1f)
  
  int xp_offset[] = {
  	HPOF_P400,	HPOF_M400,	HPOF_P400,	HPOF_M400,
--- 45,51 ----
   * NOTE: this  is different than /boot's view of the world.  Sigh.
  */
  
! #define	XPUNIT(dev)	(dkunit(dev) & 0x1f)
  
  int xp_offset[] = {
  	HPOF_P400,	HPOF_M400,	HPOF_P400,	HPOF_M400,
***************
*** 386,399 ****
  register struct buf *bp;
  	{
  	register struct xp_drive *xd;
! 	register struct partition *pi;
! 	int	unit, part;
  	struct buf *dp;
! 	int	s;
! 	daddr_t	sz;
  
  	unit = XPUNIT(bp->b_dev);
- 	part = dkpart(bp->b_dev);
  	xd = &xp_drive[unit];
  
  	if	(unit >= NXPD || !xd->xp_ctlr || !(xd->xp_flags & DKF_ALIVE))
--- 386,397 ----
  register struct buf *bp;
  	{
  	register struct xp_drive *xd;
! 	struct partition *pi;
! 	int	unit;
  	struct buf *dp;
! 	register int	s;
  
  	unit = XPUNIT(bp->b_dev);
  	xd = &xp_drive[unit];
  
  	if	(unit >= NXPD || !xd->xp_ctlr || !(xd->xp_flags & DKF_ALIVE))
***************
*** 401,439 ****
  		bp->b_error = ENXIO;
  		goto bad;
  		}
! 	pi = &xd->xp_parts[part];
! 
! 	sz = (bp->b_bcount + 511) >> 9;
! 	if	(bp->b_blkno < 0 || bp->b_blkno + sz > pi->p_size)
! 		{
! 		sz = pi->p_size - bp->b_blkno;
! 		/* If exactly at end of disk, return an EOF */
! 		if	(sz == 0)
! 			{
! 			bp->b_resid = bp->b_bcount;
! 			goto done;
! 			}
! 		/* or truncate if part of it fits */
! 		if	(sz < 0)
! 			{
! 			bp->b_error = EINVAL;
! 			goto bad;
! 			}
! 		bp->b_bcount = dbtob(sz);	/* compute byte count */
! 		}
! /*
!  * Check for write to write-protected label area.  This does not include
!  * sector 0 which is the boot block.
! */
! 	if	(bp->b_blkno + pi->p_offset <= LABELSECTOR &&
! 		 bp->b_blkno + pi->p_offset + sz > LABELSECTOR &&
! 		 !(bp->b_flags & B_READ) && !(xd->xp_flags & DKF_WLABEL))
! 		{
! 		bp->b_error = EROFS;
  		goto bad;
! 		}
  	if	(xd->xp_ctlr->xp_rh70 == 0)
  		mapalloc(bp);
  	bp->b_cylin = (bp->b_blkno + pi->p_offset) / xd->xp_nspc;
  	dp = &xputab[unit];
  	s = splbio();
--- 399,412 ----
  		bp->b_error = ENXIO;
  		goto bad;
  		}
! 	s = partition_check(bp, &xd->xp_dk);
! 	if	(s < 0)
  		goto bad;
! 	if	(s == 0)
! 		goto done;
  	if	(xd->xp_ctlr->xp_rh70 == 0)
  		mapalloc(bp);
+ 	pi = &xd->xp_parts[dkpart(bp->b_dev)];
  	bp->b_cylin = (bp->b_blkno + pi->p_offset) / xd->xp_nspc;
  	dp = &xputab[unit];
  	s = splbio();
*** /usr/src/sys/pdpuba/hk.c.old	Wed Nov 12 21:07:59 1997
--- /usr/src/sys/pdpuba/hk.c	Fri Apr  3 22:11:19 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)hk.c	2.2 (2.11BSD GTE) 1997/11/11
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)hk.c	2.3 (2.11BSD GTE) 1998/4/3
   */
  
  /*
***************
*** 327,339 ****
  register struct buf *bp;
  {
  	register struct buf *dp;
! 	int s, drive, part;
! 	daddr_t sz;
  	register struct dkdevice *disk;
- 	struct partition *pi;
  
  	drive = dkunit(bp->b_dev);
- 	part = dkpart(bp->b_dev);
  	disk = &hk_dk[drive];
  
  	if	(drive >= NHK || !HKADDR  || !(disk->dk_flags & DKF_ALIVE))
--- 327,336 ----
  register struct buf *bp;
  {
  	register struct buf *dp;
! 	int s, drive;
  	register struct dkdevice *disk;
  
  	drive = dkunit(bp->b_dev);
  	disk = &hk_dk[drive];
  
  	if	(drive >= NHK || !HKADDR  || !(disk->dk_flags & DKF_ALIVE))
***************
*** 341,378 ****
  		bp->b_error = ENXIO;
  		goto bad;
  		}
! 	pi = &disk->dk_parts[part];
! 
!         /* Valid block in device partition */
! 	sz = (bp->b_bcount + 511) >> 9;
! 	if      (bp->b_blkno < 0 || bp->b_blkno + sz > pi->p_size)
! 		{
! 		sz = pi->p_size - bp->b_blkno;
! 		/* if exactly at end of disk, return an EOF */
! 		if      (sz == 0)
! 			{
! 			bp->b_resid = bp->b_bcount;
! 			goto done;
! 			}
! 		/* or truncate if part of it fits */
! 		if      (sz < 0)
! 			{
! 			bp->b_error = EINVAL;
! 			goto bad;
! 			}
! 		bp->b_bcount = dbtob(sz);       /* compute byte count */
! 		}
! /*
!  * Check for write to write-protected label area.  This does not include
!  * sector 0 which is the boot block.
! */
! 	if      (bp->b_blkno + pi->p_offset <= LABELSECTOR &&
! 		bp->b_blkno + pi->p_offset + sz > LABELSECTOR &&
! 		!(bp->b_flags & B_READ) && !(disk->dk_flags & DKF_WLABEL))
! 		{
! 		bp->b_error = EROFS;
  		goto bad;
! 		}
  
  	bp->b_cylin = bp->b_blkno / HK_NSPC;
  	mapalloc(bp);
--- 338,348 ----
  		bp->b_error = ENXIO;
  		goto bad;
  		}
! 	s = partition_check(bp, disk);
! 	if	(s < 0)
  		goto bad;
! 	if	(s == 0)
! 		goto done;
  
  	bp->b_cylin = bp->b_blkno / HK_NSPC;
  	mapalloc(bp);
*** /usr/src/sys/sys/ufs_disksubr.c.old	Sat Jan 18 23:39:15 1997
--- /usr/src/sys/sys/ufs_disksubr.c	Fri Apr  3 17:05:33 1998
***************
*** 35,41 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)ufs_disksubr.c	8.5.4 (2.11BSD GTE) 1997/1/18
   */
  
  #include <errno.h>
--- 35,41 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)ufs_disksubr.c	8.5.5 (2.11BSD GTE) 1998/4/3
   */
  
  #include <errno.h>
***************
*** 360,363 ****
--- 360,415 ----
  			return(error);
  		}
  	return(EINVAL);
+ 	}
+ 
+ 
+ /*
+  * This was extracted from the MSCP driver so it could be shared between
+  * all disk drivers which implement disk labels.
+ */
+ 
+ partition_check(bp, dk)
+ 	struct	buf *bp;
+ 	struct	dkdevice *dk;
+ 	{
+ 	struct	partition *pi;
+ 	daddr_t	sz;
+ 
+ 	pi = &dk->dk_parts[dkpart(bp->b_dev)];
+ 
+ 	/* Valid block in device partition */
+ 	sz = (bp->b_bcount + 511) >> 9;
+ 	if	(bp->b_blkno < 0 || bp->b_blkno + sz > pi->p_size)
+ 		{
+ 		sz = pi->p_size - bp->b_blkno;
+ 		/* if exactly at end of disk, return an EOF */
+ 		if	(sz == 0)
+ 			{
+ 			bp->b_resid = bp->b_bcount;
+ 			goto done;	
+ 			}
+ 		/* or truncate if part of it fits */
+ 		if	(sz < 0)
+ 			{
+ 			bp->b_error = EINVAL;
+ 			goto bad;
+ 			}
+ 		bp->b_bcount = dbtob(sz);	/* compute byte count */
+ 		}
+ /*
+  * Check for write to write-protected label area.  This does not include
+  * sector 0 which is the boot block.
+ */
+ 	if	(bp->b_blkno + pi->p_offset <= LABELSECTOR &&
+ 		 bp->b_blkno + pi->p_offset + sz > LABELSECTOR &&
+ 		 !(bp->b_flags & B_READ) && !(dk->dk_flags & DKF_WLABEL))
+ 		{
+ 		bp->b_error = EROFS;
+ 		goto bad;
+ 		}
+ 	return(1);		/* success */
+ bad:
+ 	return(-1);
+ done:
+ 	return(0);
  	}
*** /usr/src/sys/h/mtio.h.old	Tue Dec 12 21:16:13 1995
--- /usr/src/sys/h/mtio.h	Sat Mar  7 18:11:41 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)mtio.h	7.1.1 (2.11BSD) 1995/12/12
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)mtio.h	7.1.2 (2.11BSD) 1998/3/7
   */
  
  /*
***************
*** 67,73 ****
  #define	MTF_OFFLINE	0x04		/* Drive is offline */
  #define	MTF_WRTLCK	0x08		/* Drive is write protected */
  #define	MTF_WRITTEN	0x10		/* Tape has been written */
- #define	MTF_CSE		0x20		/* Clear serious exception done */
  
  /* mag tape io control commands */
  #define	MTIOCTOP	_IOW(m, 1, struct mtop)		/* do a mag tape op */
--- 67,72 ----
*** /usr/src/sys/pdp/kern_pdp.c.old	Thu Jan 29 20:23:51 1998
--- /usr/src/sys/pdp/kern_pdp.c	Fri Apr  3 20:15:08 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_pdp.c	1.2 (2.11BSD) 1997/8/27
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_pdp.c	1.3 (2.11BSD) 1998/4/3
   */
  
  #include "param.h"
***************
*** 190,202 ****
  }
  
  /*
!  * This is ugly but it's either this or always include TMSCP code even
   * for systems without that type of device.
  */
  #include "tms.h"
  #if NTMSCP > 0
  	extern	int tmscpprintf, tmscpcache;		/* see pdpuba/tmscp.c */
  #endif
  	extern	struct tty cons[];
  
  /*
--- 190,206 ----
  }
  
  /*
!  * This is ugly but it's either this or always include [T]MSCP code even
   * for systems without that type of device.
  */
  #include "tms.h"
+ #include "ra.h"
  #if NTMSCP > 0
  	extern	int tmscpprintf, tmscpcache;		/* see pdpuba/tmscp.c */
  #endif
+ #if	NRAC > 0
+ 	extern	int mscpprintf;
+ #endif
  	extern	struct tty cons[];
  
  /*
***************
*** 214,226 ****
  	size_t newlen;
  	{
  
- 	/* all sysctl names at this level are terminal except TMSCP */
- 	if	(namelen != 1 && name[0] != CPU_TMSCP)
- 		return(ENOTDIR);		/* overloaded */
- 
  	switch	(name[0])
  		{
  		case	CPU_CONSDEV:
  			return(sysctl_rdstruct(oldp, oldlenp, newp, 
  					&cons[0].t_dev, sizeof &cons[0].t_dev));
  #if NTMSCP > 0
--- 218,228 ----
  	size_t newlen;
  	{
  
  	switch	(name[0])
  		{
  		case	CPU_CONSDEV:
+ 			if	(namelen != 1)
+ 				return(ENOTDIR);
  			return(sysctl_rdstruct(oldp, oldlenp, newp, 
  					&cons[0].t_dev, sizeof &cons[0].t_dev));
  #if NTMSCP > 0
***************
*** 236,241 ****
--- 238,257 ----
  				case	TMSCP_PRINTF:
  					return(sysctl_int(oldp, oldlenp, newp,
  						newlen,&tmscpprintf));
+ 				default:
+ 					return(EOPNOTSUPP);
+ 				}
+ #endif
+ #ifdef	NRAC > 0
+ 		case	CPU_MSCP:
+ 		/* All sysctl names at this level are terminal */
+ 			if	(namelen != 2)
+ 				return(ENOTDIR);
+ 			switch	(name[1])
+ 				{
+ 				case	MSCP_PRINTF:
+ 					return(sysctl_int(oldp, oldlenp, newp,
+ 						newlen,&mscpprintf));
  				default:
  					return(EOPNOTSUPP);
  				}
*** /usr/src/sys/pdp/cpu.h.old	Wed Jan 28 22:44:18 1998
--- /usr/src/sys/pdp/cpu.h	Fri Apr  3 19:53:23 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)cpu.h	1.4 (2.11BSD GTE) 1998/1/28
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)cpu.h	1.5 (2.11BSD GTE) 1998/4/3
   */
  
  /*
***************
*** 19,25 ****
   */
  #define	CPU_CONSDEV		1	/* dev_t: console terminal device */
  #define	CPU_TMSCP		2	/* tmscp debugging */
! #define	CPU_MAXID		3	/* number of valid machdep ids */
  
  #ifndef	KERNEL
  #define CTL_MACHDEP_NAMES { \
--- 19,26 ----
   */
  #define	CPU_CONSDEV		1	/* dev_t: console terminal device */
  #define	CPU_TMSCP		2	/* tmscp debugging */
! #define	CPU_MSCP		3	/* mscp debugging/logging */
! #define	CPU_MAXID		4	/* number of valid machdep ids */
  
  #ifndef	KERNEL
  #define CTL_MACHDEP_NAMES { \
***************
*** 26,31 ****
--- 27,33 ----
  	{ 0, 0 }, \
  	{ "console_device", CTLTYPE_STRUCT }, \
  	{ "tmscp", CTLTYPE_NODE }, \
+ 	{ "mscp", CTLTYPE_NODE }, \
  }
  #endif
  
***************
*** 33,42 ****
--- 35,52 ----
  #define	TMSCP_PRINTF	2		/* get/set print flag */
  #define	TMSCP_MAXID	3		/* number of valid TMSCP ids */
  
+ #define	MSCP_PRINTF	1		/* get/set print/logging flag */
+ #define	MSCP_MAXID	2		/* number of valid MSCP ids */
+ 
  #ifndef	KERNEL
  #define	TMSCP_NAMES { \
  	{ 0, 0 }, \
  	{ "cache", CTLTYPE_INT }, \
+ 	{ "printf", CTLTYPE_INT }, \
+ }
+ 
+ #define	MSCP_NAMES { \
+ 	{ 0, 0 }, \
  	{ "printf", CTLTYPE_INT }, \
  }
  #endif
*** /usr/src/bin/sysctl/sysctl.c.old	Thu Jan 29 20:01:40 1998
--- /usr/src/bin/sysctl/sysctl.c	Fri Apr  3 19:37:16 1998
***************
*** 36,42 ****
  "@(#) Copyright (c) 1993\n\
  	The Regents of the University of California.  All rights reserved.\n";
  
! static char sccsid[] = "@(#)sysctl.c	8.1.3 (2.11BSD GTE) 1995/10/11";
  #endif /* not lint */
  
  #include <sys/param.h>
--- 36,42 ----
  "@(#) Copyright (c) 1993\n\
  	The Regents of the University of California.  All rights reserved.\n";
  
! static char sccsid[] = "@(#)sysctl.c	8.1.4 (2.11BSD GTE) 1998/4/3";
  #endif /* not lint */
  
  #include <sys/param.h>
***************
*** 302,307 ****
--- 302,313 ----
  				goto doit;
  			return;
  		}
+ 		if (mib[1] == CPU_MSCP) {
+ 			len = sysctl_mscp(string, &bufp, mib, flags, &type);
+ 			if (len >= 0)
+ 				goto doit;
+ 			return;
+ 		}
  		break;
  
  	case CTL_FS:
***************
*** 439,444 ****
--- 445,453 ----
  struct	ctlname tmscpname[]  = TMSCP_NAMES;
  struct	list tmscplist = { tmscpname, TMSCP_MAXID };
  
+ struct	ctlname mscpname[]  = MSCP_NAMES;
+ struct	list mscplist = { mscpname, MSCP_MAXID };
+ 
  /*
   * Handle machdep.tmscp.x 
  */
***************
*** 459,464 ****
--- 468,496 ----
  		return (-1);
  	mib[2] = indx;
  	*typep = tmscpname[indx].ctl_type;
+ 	return (3);
+ }
+ 
+ /*
+  * Handle machdep.mscp.x 
+ */
+ sysctl_mscp(string, bufpp, mib, flags, typep)
+ 	char *string;
+ 	char **bufpp;
+ 	int mib[];
+ 	int flags;
+ 	int *typep;
+ {
+ 	int indx;
+ 
+ 	if (*bufpp == NULL) {
+ 		listall(string, &mscplist);
+ 		return (-1);
+ 	}
+ 	if ((indx = findname(string, "third", bufpp, &mscplist)) == -1)
+ 		return (-1);
+ 	mib[2] = indx;
+ 	*typep = mscpname[indx].ctl_type;
  	return (3);
  }
  
*** /usr/src/bin/sysctl/sysctl.8.old	Thu Jan 29 20:43:08 1998
--- /usr/src/bin/sysctl/sysctl.8	Fri Apr  3 20:33:02 1998
***************
*** 29,35 ****
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .\"	@(#)sysctl.8	8.1.3 (2.11BSD GTE) 1998/1/29
  .\"
  .TH SYSCTL 8 "June 6, 1993"
  .UC 4
--- 29,35 ----
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .\"	@(#)sysctl.8	8.1.4 (2.11BSD GTE) 1998/4/3
  .\"
  .TH SYSCTL 8 "June 6, 1993"
  .UC 4
***************
*** 138,143 ****
--- 138,144 ----
  	kern.boottime	struct	no
  	vm.loadavg	struct	no
  	machdep.console_device	dev_t	no
+ 	machdep.mscp.printf	integer	yes
  	machdep.tmscp.cache	integer	yes
  	machdep.tmscp.printf	integer	yes
  	net.inet.ip.forwarding	integer	yes
*** /VERSION.old	Mon Mar  2 21:33:59 1998
--- /VERSION	Fri Apr  3 22:21:18 1998
***************
*** 1,5 ****
! Current Patch Level: 402
! Date: March 2, 1998
  
  2.11 BSD
  ============
--- 1,5 ----
! Current Patch Level: 403
! Date: April 3, 1998
  
  2.11 BSD
  ============
