Subject: TMSCP driver problems, sysctl(8) enhancement (#401)
Index:	sys/pdpuba/tmscp.c,sys/pdp/*mscp*.h,bin/sysctl 2.11BSD

Description:
	Drives fail to 'online' but have done so successfully in the past. 

	TU81+ drives randomly return 'position lost' errors at 6250 but
	not at 1600.

	There is no way (with the kernel at secure level 1 or higher) to
	set the 'tmscpprintf' variable which regulates how much debugging
	output the TMSCP driver generates.  

	If a tape is not at the load point it is not possible to enable
	or disable the TU81+ cache.

Repeat-By:
	Assuming that /dev/rmt0 is the device node for a TMSCP device:

		mt -f /dev/rmt0 status
	or
		dump 0f /dev/rmt0 /

	If you are rewarded with a "device not configured" the bug is
	present.  One part of the problem is that the error returned is
	'ENXIO' (no such device) rather than EIO (I/O error).  This is
	confusing and might lead you to think the controller/drive was not
	probed correctly at boot time.

	Another failure (which was thought to be in the driver) was with a 
	TU81+: 'dump 0f /dev/rmt24 /'.  It would fail at different lengths
	into the dump but never succeed.

Fix:
	What was initially thought to be a driver problem turned out to
	be a hardware problem.  Determining that it was a hardware problem
	was complicated by two different drives on two systems dying within
	days of each other.

	Some of the changes made in the patch below are a result of debugging
	the driver to find out why a TK50 would not go online and why a TU81+
	would fail to write at 6250bpi.  Eventually it was discovered that the
	drives had failed but the changes to ease debugging of the TMSCP
	driver were retained for future use.

	The error code returned when a drive fails to come 'ONLINE' has been
	changed from ENXIO to EIO.  This should reduce the confusion factor
	when debugging future problems.

	Since the driver was being modified the opportunity to perform
	some cleanup and reorganization was taken advantage of.  The MSCP
	and TMSCP include files each had their own set of definitions for
	the command and response codes.  These were merged and placed into
	'mscp_common.h'.

	Many new status codes have been added to mscp_common.h.  These are
	included inside '#ifdef notnow ... #endif' because nothing in the
	kernel uses them but the definitions are extremely useful in decoding
	the status messages returned by the controller.

	The TMSCP command and response packet was reorganized to be (hopefully)
	less confusing (if that's possible with [T]MSCP).  Greater care is now
	taken to completely clear the entire packet upon reuse.  Leaving fields
	filled in with old data has caused mysterious errors to happen in the
	past (if you have had spurious failures of drives to come online, etc 
	you may have encountered this type of problem).

		NOTE:  The TMSCP command/response packet is now 4 bytes smaller
		       than before (a field which was not needed has been 
		       removed).  It is important to do a 'make clean' 
		       before rebuilding pdpstand/ or the kernel to make sure
		       that any old .o files (with the old structure size) are
		       not used!

	In sysctl(8) the ability to set/clear the 'tmscpprintf' variable has
	been added.  It is no longer required to "poke" the kernel (in single
	user mode) or recompile the TMSCP driver to change the level of debug
	output.  The new command (which is mentioned briefly but not documented
	fully in the sysctl manpage) works like this:

		sysctl [-w] machdep.tmscp.printf[=n]

	will display the debugging mask from the driver.  The bits are defined
	in tmscp.c as: 

		bit 0 = print all non-successful response packets EXCEPT hitting
			an EOT marker
		bit 1 = print datagram arrival message
		bit 2 = print status of ALL response packets except datagrams
			(this can generate a lot of output in a hurry)
		bit 3 = enable debugging print/log statements not covered by
			one of the above

	TU81+ drives have cache memory on them.  While there is a 'ioctl' call
	to enable/disable the cache not all applications are 'ioctl(MTCACHE)'
	aware.  Also to issue an ioctl the drive has to be online.  To get 
	around these limitations a new sysctl option is present:

		sysctl [-w] machdep.tmscp.cache[=n]

		bit 0 = enable cache for drive 0 on first controller
		bit 4 = enable cache for drive 0 on second controller
		bit 8 = enable cache for drive 0 on third controller
		bit 12 = enable cache for drive 0 on fourth controller

	Since a maximum of 4 drives on 4 controllers is supported a 16 bit 
	field is sufficient to handle the maximum number of drives.

	The standalone MSCP and TMSCP drivers were lightly edited to change
	references to some symbols (which were renamed during the migration of
	symbols to mscp_common.h).  No functional changes were made but it
	is a GOOD idea to recompile the programs in pdpstand/ because the
	TMSCP packet size is 4 bytes smaller now.

	To install this update cut where indicated and save to a file
	(/tmp/401.patch).  Then:

		patch -p0 < /tmp/401.patch
		cd /sys/pdpstand
		make clean
		make

		cd /usr/src/bin/sysctl
		make clean
		make
		make install

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

		cd /sys/pdpstand
		make clean
		make
		cp boot /boot

	This only applies if you have TMSCP devices present in your
	kernel.  Of course it does not hurt anything to recompile and
	install a new kernel (there is the updated 'sysctl' logic but
	the addition was TMSCP specific):

		cd /sys/YOUR_KERNEL_DIRECTORY
		make clean
		make
		cp -p /unix /ounix
		cp -p /netnix /onetnix
		make install

	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	Wed Jun  5 20:33:45 1996
--- /usr/src/sys/pdpuba/tmscp.c	Sun Feb  1 14:07:30 1998
***************
*** 1,6 ****
  #define	TMSDEBUG	1
  
! /*	@(#)tmscp.c	1.8 (2.11BSD GTE) 1996/6/5 */
  
  #if	!defined(lint) && defined(DOSCCS)
  static	char	*sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
--- 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";
***************
*** 7,13 ****
  #endif
  
  /************************************************************************
-  *									*
   *        Licensed from Digital Equipment Corporation 			*
   *                       Copyright (c) 					*
   *               Digital Equipment Corporation				*
--- 7,12 ----
***************
*** 27,33 ****
   *   diriviative copyright rights, appropriate copyright  		*
   *   legends may be placed on  the drivative work in addition  		*
   *   to that set forth above. 						*
-  *									*
   ************************************************************************
   * 
   * tmscp.c - TMSCP (TK50/TU81) tape device driver
--- 26,31 ----
***************
*** 34,39 ****
--- 32,52 ----
   * 
   * Modification History:
   *
+  * 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
+  *	was discovered (eventually after several long nights) that both my
+  *	TK50 and another person's TU81+ had developed hardware problems.  The
+  *	better logging and sysctl changes were retained for future use ;)
+  *	
+  *	Failure to 'online' a drive was changed to return EIO instead of ENXIO
+  *	because 'device not configured' means the drive is not present.
+  *
+  *	A 'sysctl' interface was added so that 'tmscpprintf' could be changed
+  *	without rebooting/recompiling the system.  Also sysctl can be used to
+  *	set the cache on/off status even if a tape is not at the load point - 
+  *	the setting takes effect on the next open().
+  *
   * 14-May-96 - sms
   *	Missing parens caused mtflush,mtcache,mtnocache to be always skipped.
   *	The use cache bit was being cleared in tmscpopen(). The use cache bit
***************
*** 294,316 ****
  static	char *tmscpstepfailed = "step%d init failed: sa %x\n";
  	char *tmscpfatalerr = "tms%d,%d: fatal error %x\n";
  
- int     tmscperror = 0;		/* enable last failed packet return */
  int	tmscp_cp_wait = 0;	/* Something to wait on for command */
  				/* packets and or credits. */
  int	wakeup();
  extern	int	hz;		/* Should find the right include */
  extern	long	_iomap();
  
  /*
-  * Most of these only take effect when TMSDEBUG is defined.
-  *
   * Bit 0 = print all non-successful response packets _except_ hitting a
   *	   tapemark (which really isn't an error).
   * Bit 1 = print datagram arrival message.
   * Bit 2 = print status of all response packets except datagrams.
  */
  int	tmscpprintf = 1;
  
  struct  mscp *tmscpgetcp();
  
  #define b_qsize         b_resid         /* queue size per drive, in tmsutab */
--- 307,337 ----
  static	char *tmscpstepfailed = "step%d init failed: sa %x\n";
  	char *tmscpfatalerr = "tms%d,%d: fatal error %x\n";
  
  int	tmscp_cp_wait = 0;	/* Something to wait on for command */
  				/* packets and or credits. */
  int	wakeup();
  extern	int	hz;		/* Should find the right include */
  extern	long	_iomap();
+ extern	u_int	tmscp_cache;	/* See pdp/kern_pdp.c */
  
  /*
   * Bit 0 = print all non-successful response packets _except_ hitting a
   *	   tapemark (which really isn't an error).
   * Bit 1 = print datagram arrival message.
   * Bit 2 = print status of all response packets except datagrams.
+  * Bit 3 = enable debugging print and log statements not covered above
  */
  int	tmscpprintf = 1;
  
+ /*
+  * This is settable via "sysctl -w machdep.tmscp.cache=0xXXXX".  There is one
+  * bit per drive.  Bit 0 is the first drive on the first controller, bit 4 is
+  * the first drive on the second controller, and so on.
+  *
+ */
+ 
+ int	tmscpcache = 0;
+ 
  struct  mscp *tmscpgetcp();
  
  #define b_qsize         b_resid         /* queue size per drive, in tmsutab */
***************
*** 419,425 ****
  	switch (sc->sc_state) {
  
  	case S_IDLE:
! 		log(LOG_INFO, "tms%d: random intr\n", dev);
  		return;
  
  	/* Controller was in step 1 last, see if its gone to step 2 */
--- 440,446 ----
  	switch (sc->sc_state) {
  
  	case S_IDLE:
! 		log(LOG_INFO, "tms%d: rand intr\n", dev);
  		return;
  
  	/* Controller was in step 1 last, see if its gone to step 2 */
***************
*** 641,646 ****
--- 662,668 ----
  		mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  		mp->mscp_opcode = M_OP_ONLIN;
  		mp->mscp_unit = unit;		/* unit? */
+ 		tms_clrerr(tms, mp);
  		mp->mscp_cmdref = (u_short)&tms->tms_type;
  					    /* need to sleep on something */
  		((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN | TMSCP_INT);
***************
*** 661,667 ****
  oops:		tms->Tflags = 0;
  		tms->tms_type = 0;
  		sc->sc_drives[unit] = NULL;
! 		return(ENXIO);  /* Didn't go online */
  		}
  /*
   * Get the unit characteristics (GTUNT).  This 1) Verifies the drive
--- 683,689 ----
  oops:		tms->Tflags = 0;
  		tms->tms_type = 0;
  		sc->sc_drives[unit] = NULL;
! 		return(EIO);  /* Didn't go online */
  		}
  /*
   * Get the unit characteristics (GTUNT).  This 1) Verifies the drive
***************
*** 669,674 ****
--- 691,698 ----
   * such as density choices, cache presence, etc.
  */
  	tms->tms_flags = 0;
+ 	if	(tmscpcache & ((1 << unit) << (4 * ctlr)))
+ 		tms->Tflags |= _CACHE_ON;
  	i = tms->Tflags & _CACHE_ON;
  	tms->Tflags = _ONLINE | _INUSE | i;	/* Clear all other flags */
  	tmscpcommand(dev, TMS_SENSE, 1);
***************
*** 815,822 ****
  		com->lsh = loint(vaddr);
  		com->hsh = flags | hiint(vaddr);
  		msgs->mscp_dscptr = (long *)com;
! 		msgs->mscp_header.tmscp_msglen = sizeof(struct mscp);
! 		msgs->mscp_header.tmscp_vcid = 1; /* tape VCID = 1 */
  		++com; ++msgs; vaddr += sizeof(struct mscp);
  	}
  }
--- 839,846 ----
  		com->lsh = loint(vaddr);
  		com->hsh = flags | hiint(vaddr);
  		msgs->mscp_dscptr = (long *)com;
! 		msgs->mscp_header.mscp_msglen = sizeof(struct mscp);
! 		msgs->mscp_header.mscp_vcid = 1; /* tape VCID = 1 */
  		++com; ++msgs; vaddr += sizeof(struct mscp);
  	}
  }
***************
*** 850,861 ****
  		cp->ca_cmddsc[i].hsh &= ~TMSCP_INT;
  		mp = &sc->sc_com->tmscp_cmd[i];
  		mp->mscp_cmdref = 0;
! 		mp->mscp_mediaid = 0;
! 		mp->mscp_unit = mp->mscp_modifier = 0;
! 		mp->mscp_opcode = mp->mscp_flags = 0;
! 		mp->mscp_bytecnt = 0;
! 		mp->mscp_buffer_h = mp->mscp_buffer_l = 0;
! 		mp->mscp_zzz2 = 0;
  		sc->sc_lastcmd = (i + 1) % NCMD;
  		}
  	restorseg5(seg5);
--- 874,882 ----
  		cp->ca_cmddsc[i].hsh &= ~TMSCP_INT;
  		mp = &sc->sc_com->tmscp_cmd[i];
  		mp->mscp_cmdref = 0;
! 		mp->mscp_modifier = 0;
! 		mp->mscp_flags = 0;
! 		bzero(&mp->un, sizeof (mp->un));
  		sc->sc_lastcmd = (i + 1) % NCMD;
  		}
  	restorseg5(seg5);
***************
*** 954,959 ****
--- 975,981 ----
  		mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  		mp->mscp_opcode = M_OP_ONLIN;
  		mp->mscp_unit = unit;
+ 		tms_clrerr(tms, mp);
  		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);
***************
*** 1121,1129 ****
  	int	em_status, em_endcode;
  
  	mp = &sc->sc_com->tmscp_rsp[i];
! 	mp->mscp_header.tmscp_msglen = mscp_msglen;
! 	sc->sc_credits += mp->mscp_header.tmscp_credits & 0xf;  /* low 4 bits */
! 	if	((mp->mscp_header.tmscp_credits & 0xf0) > 0x10)	/* Check */
  		return;
  
  	/*
--- 1143,1151 ----
  	int	em_status, em_endcode;
  
  	mp = &sc->sc_com->tmscp_rsp[i];
! 	mp->mscp_header.mscp_msglen = sizeof (struct mscp);
! 	sc->sc_credits += mp->mscp_header.mscp_credits & 0xf;  /* low 4 bits */
! 	if	((mp->mscp_header.mscp_credits & 0xf0) > 0x10)	/* Check */
  		return;
  
  	/*
***************
*** 1130,1146 ****
  	 * If it's an error log message (datagram),
  	 * pass it on for more extensive processing.
  	 */
! 	if	((mp->mscp_header.tmscp_credits & 0xf0) == 0x10)
  		{
  		tmserror(sc->sc_unit, (struct mslg *)mp);
  		return;
  		}
! #ifdef	TMSDEBUG
  	if	(tmscpprintf & 0x4)
  		log(LOG_INFO, "tms%d,%d: op %x st %x\n", sc->sc_unit,
  			mp->mscp_unit,mp->mscp_opcode,
  			mp->mscp_status & M_ST_MASK);
- #endif
  
  	em_status = mp->mscp_status&M_ST_MASK;
  	em_endcode = mp->mscp_endcode & ~M_OP_END;
--- 1152,1167 ----
  	 * If it's an error log message (datagram),
  	 * pass it on for more extensive processing.
  	 */
! 	if	((mp->mscp_header.mscp_credits & 0xf0) == 0x10)
  		{
  		tmserror(sc->sc_unit, (struct mslg *)mp);
  		return;
  		}
! 
  	if	(tmscpprintf & 0x4)
  		log(LOG_INFO, "tms%d,%d: op %x st %x\n", sc->sc_unit,
  			mp->mscp_unit,mp->mscp_opcode,
  			mp->mscp_status & M_ST_MASK);
  
  	em_status = mp->mscp_status&M_ST_MASK;
  	em_endcode = mp->mscp_endcode & ~M_OP_END;
***************
*** 1215,1222 ****
  		tms->Tflags &= ~_ONLINE;
  		return;
  	case 0:
! 		log(LOG_INFO, "tms%d,%d: inv end=%x st=%x\n",
! 			sc->sc_unit, mp->mscp_unit, em_endcode, em_status);
  		tms_iodone(mp, tms);
  		return;
  	case	M_OP_WRITE:
--- 1236,1244 ----
  		tms->Tflags &= ~_ONLINE;
  		return;
  	case 0:
! 		if	(tmscpprintf & 0x8)
! 			log(LOG_INFO, "tms%d,%d: inv end=%x st=%x\n",
! 				sc->sc_unit,mp->mscp_unit,em_endcode,em_status);
  		tms_iodone(mp, tms);
  		return;
  	case	M_OP_WRITE:
***************
*** 1242,1249 ****
  		tms_flush_em(mp, sc);
  		return;
  	default:
! 		log(LOG_INFO, "tms%d,%d bad rsp: %x\n", sc->sc_unit,
! 			mp->mscp_unit, em_endcode);
  		return;
  	}	/* end switch mp->mscp_opcode */
  }
--- 1264,1272 ----
  		tms_flush_em(mp, sc);
  		return;
  	default:
! 		if	(tmscpprintf & 0x8)
! 			log(LOG_INFO, "tms%d,%d bad rsp: %x\n", sc->sc_unit,
! 				mp->mscp_unit, em_endcode);
  		return;
  	}	/* end switch mp->mscp_opcode */
  }
***************
*** 1503,1515 ****
  
  tms_avail_st(mp, sc, flgs)
  	register struct	mscp	*mp;
! 	register struct	tmscp_softc *sc;
  	int	flgs;
  	{
  	register struct	tms_info *tms = sc->sc_drives[mp->mscp_unit];
  
  	mp->mscp_opcode = M_OP_AVAIL;
! 	mp->mscp_modifier = flgs | M_MD_CLSEX;
  	tms->Tflags &= ~_CLSEREX;
  	if	(tms->Tflags & _CACHE_LOST)
  		{
--- 1526,1547 ----
  
  tms_avail_st(mp, sc, flgs)
  	register struct	mscp	*mp;
! 	struct	tmscp_softc *sc;
  	int	flgs;
  	{
  	register struct	tms_info *tms = sc->sc_drives[mp->mscp_unit];
  
  	mp->mscp_opcode = M_OP_AVAIL;
! 	mp->mscp_modifier = flgs;
! 	tms_clrerr(tms, mp);
! 	}
! 
! tms_clrerr(tms, mp)
! 	register struct tms_info *tms;
! 	register struct mscp *mp;
! 	{
! 
! 	mp->mscp_modifier |= M_MD_CLSEX;
  	tms->Tflags &= ~_CLSEREX;
  	if	(tms->Tflags & _CACHE_LOST)
  		{
***************
*** 1809,1821 ****
  	u_short	em_endcode = mp->mscp_endcode & ~M_OP_END;
  	char	berr, unkerr;
  
- #ifdef	TMSDEBUG
  	if	(em_status != M_ST_SUCC && em_status != M_ST_TAPEM &&
  			(tmscpprintf & 0x1))
  		log(LOG_INFO, "tms%d,%d st=%x sb=%x fl=%x en=%x\n",
  			sc->sc_unit, mp->mscp_unit,
  			em_status, em_subcode, em_flags, em_endcode);
- #endif
  	tms->tms_endcode = mp->mscp_endcode;
  	if	(em_flags & M_EF_EOT)
  		tms->tms_flags |= MTF_EOM;
--- 1841,1851 ----
***************
*** 1891,1908 ****
  			else
  				{
  				tms->Tflags &= ~_CLSEREX;
- #ifdef	TMSDEBUG
  				log(LOG_INFO, "tms%d,%d serex, subcode %x\n",
! 					sc->sc_unit, mp->mscp_unit);
! #endif
  				berr = EIO;
  				}
  			break;
  		case	M_ST_PLOST:			/* Position Lost */
- #ifdef	TMSDEBUG
  			log(LOG_INFO, "tms%d,%d plost\n", sc->sc_unit,
! 				mp->mscp_unit);
! #endif
  			tms->Tflags |= (_LOST | _SEREX);
  			tms->Tflags &= ~_CLSEREX;
  			berr = EIO;
--- 1921,1934 ----
  			else
  				{
  				tms->Tflags &= ~_CLSEREX;
  				log(LOG_INFO, "tms%d,%d serex, subcode %x\n",
! 					sc->sc_unit, mp->mscp_unit, em_subcode);
  				berr = EIO;
  				}
  			break;
  		case	M_ST_PLOST:			/* Position Lost */
  			log(LOG_INFO, "tms%d,%d plost\n", sc->sc_unit,
! 					mp->mscp_unit);
  			tms->Tflags |= (_LOST | _SEREX);
  			tms->Tflags &= ~_CLSEREX;
  			berr = EIO;
*** /usr/src/sys/pdpuba/ra.c.old	Fri Feb 14 21:08:46 1997
--- /usr/src/sys/pdpuba/ra.c	Wed Jan 28 23:29:40 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	3.2 (2.11BSD GTE) 1997/2/14
   */
  
   /***********************************************************************
--- 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
   */
  
   /***********************************************************************
***************
*** 14,19 ****
--- 14,24 ----
  
  /* 
   * ra.c - MSCP Driver
+  * 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
+  * and TMSCP drivers.
+  *
   * Date:	February 14, 1997
   * Use 'hz' to calculate delays rather than compile time constant.
   *
***************
*** 406,412 ****
  			--sc->sc_cp_wait;
  		}
  		mapseg5(ra_com[sc->sc_unit], MAPSEGDESC);
! 		mp->m_opcode = M_O_ONLIN;
  		mp->m_unit = unit;
  		mp->m_cmdref = (unsigned)&disk->ra_flags;
  		((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT;
--- 411,417 ----
  			--sc->sc_cp_wait;
  		}
  		mapseg5(ra_com[sc->sc_unit], MAPSEGDESC);
! 		mp->m_opcode = M_OP_ONLIN;
  		mp->m_unit = unit;
  		mp->m_cmdref = (unsigned)&disk->ra_flags;
  		((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT;
***************
*** 791,797 ****
  	if ((mp = ragetcp(sc)) == NULL)
  		goto out;
  	mp->m_cmdref = (unsigned)bp;	/* pointer to get back */
! 	mp->m_opcode = bp->b_flags & B_READ ? M_O_READ : M_O_WRITE;
  	mp->m_unit = RAUNIT(bp->b_dev);
  	disk = sc->sc_drives[mp->m_unit];
  	pi = &disk->ra_parts[dkpart(bp->b_dev)];
--- 796,802 ----
  	if ((mp = ragetcp(sc)) == NULL)
  		goto out;
  	mp->m_cmdref = (unsigned)bp;	/* pointer to get back */
! 	mp->m_opcode = bp->b_flags & B_READ ? M_OP_READ : M_OP_WRITE;
  	mp->m_unit = RAUNIT(bp->b_dev);
  	disk = sc->sc_drives[mp->m_unit];
  	pi = &disk->ra_parts[dkpart(bp->b_dev)];
***************
*** 916,923 ****
  		sc->sc_lastrsp = 0;
  		mp = sc->sc_com->ra_cmd;
  		ramsgclear(mp);
! 		mp->m_opcode = M_O_STCON;
! 		mp->m_cntflgs = M_C_ATTN | M_C_MISC | M_C_THIS;	
  		((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT;
  		i = sc->RAADDR->raip;
  		restorseg5(seg5);
--- 921,928 ----
  		sc->sc_lastrsp = 0;
  		mp = sc->sc_com->ra_cmd;
  		ramsgclear(mp);
! 		mp->m_opcode = M_OP_STCON;
! 		mp->m_cntflgs = M_CF_ATTN | M_CF_MISC | M_CF_THIS;	
  		((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT;
  		i = sc->RAADDR->raip;
  		restorseg5(seg5);
***************
*** 996,1002 ****
  		com->lsh = loint(vaddr);
  		com->hsh = flags | hiint(vaddr);
  		msgs->m_dscptr = (long *)com;
! 		msgs->m_header.ra_msglen = sizeof(struct mscp);
  		++com; ++msgs; vaddr += sizeof(struct mscp);
  	}
  }
--- 1001,1007 ----
  		com->lsh = loint(vaddr);
  		com->hsh = flags | hiint(vaddr);
  		msgs->m_dscptr = (long *)com;
! 		msgs->m_header.mscp_msglen = sizeof(struct mscp);
  		++com; ++msgs; vaddr += sizeof(struct mscp);
  	}
  }
***************
*** 1074,1082 ****
  	/*
  	 * Reset packet length and check controller credits
  	 */
! 	mp->m_header.ra_msglen = sizeof(struct mscp);
! 	sc->sc_credits += mp->m_header.ra_credits & 0xf;
! 	if ((mp->m_header.ra_credits & 0xf0) > 0x10)
  		return;
  
  	/*
--- 1079,1087 ----
  	/*
  	 * Reset packet length and check controller credits
  	 */
! 	mp->m_header.mscp_msglen = sizeof(struct mscp);
! 	sc->sc_credits += mp->m_header.mscp_credits & 0xf;
! 	if ((mp->m_header.mscp_credits & 0xf0) > 0x10)
  		return;
  
  	/*
***************
*** 1083,1089 ****
  	 * If it's an error log message (datagram),
  	 * pass it on for more extensive processing.
  	 */
! 	if ((mp->m_header.ra_credits & 0xf0) == 0x10) {
  		ra_error((struct mslg *)mp);
  		return;
  	}
--- 1088,1094 ----
  	 * If it's an error log message (datagram),
  	 * pass it on for more extensive processing.
  	 */
! 	if ((mp->m_header.mscp_credits & 0xf0) == 0x10) {
  		ra_error((struct mslg *)mp);
  		return;
  	}
***************
*** 1091,1099 ****
  	/*
  	 * The controller interrupts as drive ZERO so check for it first.
  	 */
! 	st = mp->m_status & M_S_MASK;
! 	if (mp->m_opcode == (M_O_STCON|M_O_END)) {
! 		if (st == M_S_SUCC)
  			sc->sc_state = S_RUN;
  		else
  			sc->sc_state = S_IDLE;
--- 1096,1104 ----
  	/*
  	 * The controller interrupts as drive ZERO so check for it first.
  	 */
! 	st = mp->m_status & M_ST_MASK;
! 	if (mp->m_opcode == (M_OP_STCON|M_OP_END)) {
! 		if (st == M_ST_SUCC)
  			sc->sc_state = S_RUN;
  		else
  			sc->sc_state = S_IDLE;
***************
*** 1106,1112 ****
  	 * Check drive and then decode response and take action.
  	 */
  	switch (mp->m_opcode) {
! 	case M_O_ONLIN|M_O_END:
  		if ((disk = sc->sc_drives[mp->m_unit]) == NULL) {
  			log(LOG_NOTICE,"ra%d !ONLINE\n", sc->sc_unit * 8 +
  				mp->m_unit);
--- 1111,1117 ----
  	 * Check drive and then decode response and take action.
  	 */
  	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);
***************
*** 1114,1120 ****
  		}
  		dp = &disk->ra_utab;
  
! 		if (st == M_S_SUCC) {
  			/* Link the drive onto the controller queue */
  			dp->b_forw = NULL;
  			if (sc->sc_ctab.b_actf == NULL)
--- 1119,1125 ----
  		}
  		dp = &disk->ra_utab;
  
! 		if (st == M_ST_SUCC) {
  			/* Link the drive onto the controller queue */
  			dp->b_forw = NULL;
  			if (sc->sc_ctab.b_actf == NULL)
***************
*** 1140,1146 ****
  			wakeup((caddr_t)mp->m_cmdref);
  		break;
  
! 	case M_O_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)
--- 1145,1151 ----
  			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)
***************
*** 1147,1160 ****
  			disk->ra_flags &= ~DKF_ONLINE;
  		break;
  
! 	case M_O_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_O_READ | M_O_END:
! 	case M_O_WRITE | M_O_END:
  		/* normal termination of read/write request */
  		if ((disk = sc->sc_drives[mp->m_unit]) == NULL)
  			break;
--- 1152,1165 ----
  			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 */
  		if ((disk = sc->sc_drives[mp->m_unit]) == NULL)
  			break;
***************
*** 1174,1180 ****
  				dk_busy &= ~(1 << (ra_dkn + mp->m_unit));
  		}
  #endif
! 		if (st == M_S_OFFLN || st == M_S_AVLBL) {
  			/* mark unit offline */
  			disk->ra_flags &= ~DKF_ONLINE;
  
--- 1179,1185 ----
  				dk_busy &= ~(1 << (ra_dkn + mp->m_unit));
  		}
  #endif
! 		if (st == M_ST_OFFLN || st == M_ST_AVLBL) {
  			/* mark unit offline */
  			disk->ra_flags &= ~DKF_ONLINE;
  
***************
*** 1195,1201 ****
  			}
  			return;
  		}
! 		if (st != M_S_SUCC) {
  			harderr(bp, "ra");
  			log(LOG_INFO, "status %o\n", mp->m_status);
  			bp->b_flags |= B_ERROR;
--- 1200,1206 ----
  			}
  			return;
  		}
! 		if (st != M_ST_SUCC) {
  			harderr(bp, "ra");
  			log(LOG_INFO, "status %o\n", mp->m_status);
  			bp->b_flags |= B_ERROR;
***************
*** 1204,1210 ****
  		iodone(bp);
  		break;
  
! 	case M_O_GTUNT|M_O_END:
  		break;
  
  	default:
--- 1209,1215 ----
  		iodone(bp);
  		break;
  
! 	case M_OP_GTUNT|M_OP_END:
  		break;
  
  	default:
***************
*** 1282,1301 ****
  		mp->me_flags & (M_LF_SUCC|M_LF_CONT) ? "soft" : "hard");
  
  	switch (mp->me_format) {
! 	case M_F_CNTERR:
  		printf("ctlr");
  		break;
! 	case M_F_BUSADDR:
  		printf("M_F_BUSADDR %o", mp->me_busaddr);
  		break;
! 	case M_F_DISKTRN:
  		printf("disk xfr, unit %d grp x%x hdr x%x",
  			mp->me_unit, mp->me_group, mp->me_hdr);
  		break;
! 	case M_F_SDI:
  		printf("SDI unit %d hdr x%x", mp->me_unit, mp->me_hdr);
  		break;
! 	case M_F_SMLDSK:
  		printf("small disk unit %d cyl %d", mp->me_unit, mp->me_sdecyl);
  		break;
  	default:
--- 1287,1306 ----
  		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:
***************
*** 1310,1316 ****
  		register char *p = (char *)mp;
  		register int i;
  
! 		for (i = mp->me_header.ra_msglen; i--; /*void*/)
  			printf("%x ", *p++ & 0xff);
  		printf("\n");
  	}
--- 1315,1321 ----
  		register char *p = (char *)mp;
  		register int i;
  
! 		for (i = mp->me_header.mscp_msglen; i--; /*void*/)
  			printf("%x ", *p++ & 0xff);
  		printf("\n");
  	}
***************
*** 1389,1395 ****
  		/*void*/;
  	sc->RAADDR->rasa = RA_GO;
  	ramsginit(sc, sc->sc_com->ra_ca.ca_rsp, mp, 0, 2, 0);
! 	if (!racmd(M_O_STCON, unit, sc)) {
  		PRINTB(("radump: failed start controller\n"));
  		return(EFAULT);
  	}
--- 1394,1400 ----
  		/*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);
  	}
***************
*** 1396,1402 ****
  	PRINTB(("radump: controller up\n"));
  
  	/* Bring disk for dump online */
! 	if (!(mp = racmd(M_O_ONLIN, unit, sc))) {
  		PRINTB(("radump: failed online\n"));
  		return(EFAULT);
  	}
--- 1401,1407 ----
  	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);
  	}
***************
*** 1432,1438 ****
  		mp->m_bytecnt = count * NBPG;
  		mp->m_buf_l = loint(maddr);
  		mp->m_buf_h = hiint(maddr);
! 		if (racmd(M_O_WRITE, unit, sc) == 0)
  			return(EIO);
  
  		paddr += (count << PGSHIFT);
--- 1437,1443 ----
  		mp->m_bytecnt = count * NBPG;
  		mp->m_buf_l = loint(maddr);
  		mp->m_buf_h = hiint(maddr);
! 		if (racmd(M_OP_WRITE, unit, sc) == 0)
  			return(EIO);
  
  		paddr += (count << PGSHIFT);
***************
*** 1457,1463 ****
  	rlp = &sc->sc_com->ra_ca.ca_rsp[0];
  	cmp->m_opcode = op;
  	cmp->m_unit = unit;
! 	cmp->m_header.ra_msglen = rmp->m_header.ra_msglen = sizeof(struct mscp);
  	rlp[0].hsh &= ~RA_INT;
  	rlp[1].hsh &= ~RA_INT;
  	rlp[0].hsh &= ~RA_INT;
--- 1462,1469 ----
  	rlp = &sc->sc_com->ra_ca.ca_rsp[0];
  	cmp->m_opcode = op;
  	cmp->m_unit = unit;
! 	cmp->m_header.mscp_msglen = rmp->m_header.mscp_msglen = 
! 			sizeof(struct mscp);
  	rlp[0].hsh &= ~RA_INT;
  	rlp[1].hsh &= ~RA_INT;
  	rlp[0].hsh &= ~RA_INT;
***************
*** 1471,1478 ****
  		/*void*/;
  	sc->sc_com->ra_ca.ca_rspint = 0;
  	sc->sc_com->ra_ca.ca_cmdint = 0;
! 	if (rmp->m_opcode != (op | M_O_END)
! 	    || (rmp->m_status & M_S_MASK) != M_S_SUCC) {
  		ra_error(rmp);
  		return(0);
  	}
--- 1477,1484 ----
  		/*void*/;
  	sc->sc_com->ra_ca.ca_rspint = 0;
  	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);
  	}
*** /usr/src/sys/pdpuba/tmscpreg.h.old	Sun Dec 31 10:58:11 1995
--- /usr/src/sys/pdpuba/tmscpreg.h	Wed Jan 28 23:34:39 1998
***************
*** 1,7 ****
! /* @(#)tmscpreg.h	7.1 (Berkeley) 6/5/86 */
  
- /*	@(#)tmscpreg.h	1.3	(2.11BSD) 1995/12/31 */
- 
  /****************************************************************
   *								*
   *        Licensed from Digital Equipment Corporation 		*
--- 1,5 ----
! /*	@(#)tmscpreg.h	1.4	(2.11BSD) 1998/1/28 */
  
  /****************************************************************
   *								*
   *        Licensed from Digital Equipment Corporation 		*
***************
*** 90,101 ****
   
  #define	TMSCP_OWN	0x8000	/* port owns descriptor (else host owns it) */
  #define	TMSCP_INT	0x4000	/* allow interrupt on ring transition */
-  
- /*
-  * TMSCP packet info (same as MSCP)
-  */
- struct mscp_header {
- 	short	tmscp_msglen;	/* length of MSCP packet */
- 	char	tmscp_credits;	/* low 4 bits: credits, high 4 bits: msgtype */
- 	char	tmscp_vcid;	/* virtual circuit id (connection id) */
- };
--- 88,90 ----
*** /usr/src/sys/pdpuba/tmscpdump.c.old	Thu Dec 14 21:41:19 1995
--- /usr/src/sys/pdpuba/tmscpdump.c	Wed Jan 28 23:40:30 1998
***************
*** 1,5 ****
  /*
!  * 	1.1	(2.11BSD)	1995/12/14
   *
   * This routine was moved from the main TMSCP driver due to size problems.
   * The driver could become over 8kb in size and would not fit within an
--- 1,5 ----
  /*
!  * 	1.2	(2.11BSD)	1998/1/28
   *
   * This routine was moved from the main TMSCP driver due to size problems.
   * The driver could become over 8kb in size and would not fit within an
***************
*** 132,139 ****
  
  	cmp->mscp_opcode = op;
  	cmp->mscp_unit = unit;
! 	cmp->mscp_header.tmscp_msglen = mscp_msglen;
! 	rmp->mscp_header.tmscp_msglen = mscp_msglen;
  	rlp[0].hsh |= TMSCP_OWN|TMSCP_INT;
  	rlp[1].hsh |= TMSCP_OWN|TMSCP_INT;
  	if (sc->sc_addr->tmscpsa&TMSCP_ERR)
--- 132,139 ----
  
  	cmp->mscp_opcode = op;
  	cmp->mscp_unit = unit;
! 	cmp->mscp_header.mscp_msglen = sizeof (struct mscp);
! 	rmp->mscp_header.mscp_msglen = sizeof (struct mscp);
  	rlp[0].hsh |= TMSCP_OWN|TMSCP_INT;
  	rlp[1].hsh |= TMSCP_OWN|TMSCP_INT;
  	if (sc->sc_addr->tmscpsa&TMSCP_ERR)
*** /usr/src/sys/sys/kern_sysctl.c.old	Tue Sep  2 20:22:34 1997
--- /usr/src/sys/sys/kern_sysctl.c	Thu Jan 29 20:07:58 1998
***************
*** 33,39 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)kern_sysctl.c	8.4.7 (2.11BSD GTE) 1997/9/2
   */
  
  /*
--- 33,39 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)kern_sysctl.c	8.4.8 (2.11BSD GTE) 1998/1/28
   */
  
  /*
***************
*** 394,428 ****
  			name, namelen, oldp, oldlenp, newp, newlen));
  }
  #endif
- 
- /*
-  * Rather useless - but it's not very big so let's do it.
- */
- 
- int
- cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
- 	int *name;
- 	u_int namelen;
- 	void *oldp;
- 	size_t *oldlenp;
- 	void *newp;
- 	size_t newlen;
- {
- 	extern	struct tty cons[];
- 
- 	/* all sysctl names at this level are terminal */
- 	if (namelen != 1)
- 		return (ENOTDIR);		/* overloaded */
- 
- 	switch (name[0]) {
- 	case CPU_CONSDEV:
- 		return (sysctl_rdstruct(oldp, oldlenp, newp, &cons[0].t_dev,
- 		    sizeof &cons[0].t_dev));
- 	default:
- 		return (EOPNOTSUPP);
- 	}
- 	/* NOTREACHED */
- }
  
  /*
   * Bit of a hack.  2.11 currently uses 'short avenrun[3]' and a fixed scale 
--- 394,399 ----
*** /usr/src/sys/pdp/mscp_common.h.old	Tue Dec 12 21:27:42 1995
--- /usr/src/sys/pdp/mscp_common.h	Sun Feb  1 14:34:57 1998
***************
*** 1,5 ****
  /*
!  *	1.1	(2.11BSD) 1995/12/12
   *
   * Definitions common to both MSCP and TMSCP were moved here from tmscp.h.
   * Eventually the MSCP driver and include file will be modified to use these
--- 1,5 ----
  /*
!  *	1.2	(2.11BSD) 1998/2/31
   *
   * Definitions common to both MSCP and TMSCP were moved here from tmscp.h.
   * Eventually the MSCP driver and include file will be modified to use these
***************
*** 9,14 ****
--- 9,20 ----
  #ifndef	_MSCP_COMMON_H_
  #define	_MSCP_COMMON_H_
  
+ struct mscp_header {
+ 	u_short	mscp_msglen;	/* length of MSCP packet */
+ 	char	mscp_credits;	/* low 4 bits: credits, high 4 bits: msgtype */
+ 	char	mscp_vcid;	/* virtual circuit id */
+ };
+ 
  /*
   * Control message opcodes
  */
***************
*** 163,170 ****
  #define	M_SC_DUPUN	0x0004		/* Duplicate unit number */
  #define	M_SC_ALONL	0x0008		/* Already online */
  #define	M_SC_STONL	0x0010		/* Still online */
! #define	M_SC_UNIGN	0x0011		/* Unload ignored */
  #define	M_SC_EOT	0x0020		/* EOT seen */
  #define	M_SC_ROVOL	0x0080		/* Read only volume */
  
  /*
--- 169,180 ----
  #define	M_SC_DUPUN	0x0004		/* Duplicate unit number */
  #define	M_SC_ALONL	0x0008		/* Already online */
  #define	M_SC_STONL	0x0010		/* Still online */
! #define	M_SC_UNIGN	0x0011		/* Still online/Unload ignored (T) */
  #define	M_SC_EOT	0x0020		/* EOT seen */
+ #ifdef	notnow
+ #define	M_SC_INREP	0x0020		/* Incomplete replacement (D)
+ #define	M_SC_IVRCT	0x0040		/* Invalid RCT */
+ #endif
  #define	M_SC_ROVOL	0x0080		/* Read only volume */
  
  /*
***************
*** 192,197 ****
--- 202,211 ----
   * Unit available subcodes
  */
  #define	M_SC_AVAIL	0x0000		/* Success */
+ #ifdef	notnow
+ #define	M_SC_NOMEMB	0x0001		/* No members */
+ #define	M_SC_ALUSE	0x0020		/* Online to another host */
+ #endif
  
  /*
   * Write protect subcodes
***************
*** 201,214 ****
  #define	M_SC_HARDW	0x0100		/* Hardware write protected */
  
  /*
!  * Error Log message format codes
   */
  #define	M_FM_CNTERR	0	/* Controller error */
  #define	M_FM_BUSADDR	1	/* Host memory access error */
! #define	M_FM_TAPETRN	5	/* Tape transfer error */
! #define	M_FM_STIERR	6	/* STI communication or command failure */
! #define	M_FM_STIDEL	7	/* STI drive error log */
! #define	M_FM_STIFEL   010	/* STI formatter error log */
   
  /*
   * Error Log message flags
--- 215,325 ----
  #define	M_SC_HARDW	0x0100		/* Hardware write protected */
  
  /*
!  * Invalid parameter sub-codes
! */
! #ifdef	notnow
! #define	M_SC_IVKLN	0x0001		/* Invalid key length */
! #define	M_SC_IVKTP	0x0002		/* Invalid key type */
! #define	M_SC_IVKVL	0x0003		/* Invalid key value */
! 
! /*
!  * Media format error sub-codes
! */
! #define M_SC_NO512	0x0005	/* 576 byte sectors on a 512 byte drive	     */
! #define	M_SC_UNFMT	0x0006	/* Disk unformatted or FCT corrupted	     */
! #define M_SC_RCTBD	0x0008	/* RCT corrupted			     */
! #define M_SC_NORBL	0x0009	/* No replacement block available	     */
! #define M_SC_MULT	0x000A	/* Multi-copy protection warning	     */
! 
! /*
!  * Data error sub-codes
!  *
!  * sub-codes marked (*) may also appear in media format errors
! */
! #define M_SC_FRCER	0x0000	/* Forced error (*)			     */
! #define M_SC_IVHDR	0x0002	/* Invalid header (*)			     */
! #define M_SC_SYNTO	0x0003	/* Data synch timeout (*)		     */
! #define M_SC_ECCFL	0x0004	/* Correctable error in ECC field	     */
! #define M_SC_UNECC	0x0007	/* Uncorrectable ECC error (*)		     */
! #define M_SC_1SECC	0x0008	/* 1 symbol correctable ECC error	     */
! #define M_SC_2SECC	0x0009	/* 2 symbol correctable ECC error	     */
! #define M_SC_3SECC	0x000a	/* 3 symbol correctable ECC error	     */
! #define M_SC_4SECC	0x000b	/* 4 symbol correctable ECC error	     */
! #define M_SC_5SECC	0x000c	/* 5 symbol correctable ECC error	     */
! #define M_SC_6SECC	0x000d	/* 6 symbol correctable ECC error	     */
! #define M_SC_7SECC	0x000e	/* 7 symbol correctable ECC error	     */
! #define M_SC_8SECC	0x000f	/* 8 symbol correctable ECC error	     */
! 
! /*
!  * Host buffer access error sub-codes
   */
+ #define M_SC_ODDTA	0x0001	/* Odd transfer address			     */
+ #define M_SC_ODDBC	0x0002	/* Odd byte count			     */
+ #define M_SC_NXM	0x0003	/* Non-existent memory			     */
+ #define M_SC_MPAR	0x0004	/* Host memory parity error		     */
+ #define M_SC_IVPTE	0x0005	/* Invalid Page Table Entry (UQSSP)	     */
+ #define M_SC_IVBFN	0x0006	/* Invalid buffer name			     */
+ #define M_SC_BLENV	0x0007	/* Buffer length violation		     */
+ #define M_SC_ACVIO	0x0008	/* Access violation			     */
+ 
+ /*
+  * Controller error sub-codes
+  */
+ #define	M_SC_HDETO	0x0000	/* Host detected controller timeout	     */
+ #define M_SC_DLATE	0x0001	/* Data late (SERDES) error		     */
+ #define M_SC_EDCER	0x0002	/* EDC error				     */
+ #define M_SC_DTSTR	0x0003	/* Data structure error			     */
+ #define M_SC_IEDC	0x0004	/* Internal EDC error			     */
+ #define M_SC_LACIN	0x0005	/* LESI adaptor card input error	     */
+ #define M_SC_LACOU	0x0006	/* LESI adaptor card output error	     */
+ #define M_SC_LACCB	0x0007	/* LESI adaptor card cable not in place	     */
+ #define M_SC_OVRUN	0x0008	/* Controller overrun or underrun	     */
+ #define M_SC_MEMER	0x0009	/* Controller memory error		     */
+ 
+ /*
+  * Drive error sub-codes
+  */
+ #define M_SC_CMDTO	0x0001	/* SDI command timed out		     */
+ #define M_SC_XMSER	0x0002	/* Controller-detected transmission error    */
+ #define M_SC_MISSK	0x0003	/* Positioner error (mis-seek)		     */
+ #define M_SC_RWRDY	0x0004	/* Lost read/write ready between transfers   */
+ #define M_SC_CLKDO	0x0005	/* Drive clock dropout			     */
+ #define M_SC_RXRDY	0x0006	/* Lost receiver ready between sectors	     */
+ #define M_SC_DRDET	0x0007	/* Drive-detected error			     */
+ #define	M_SC_PULSE	0x0008	/* Ctlr-detected pulse/state parity error    */
+ #define M_SC_PRTCL	0x000a	/* Controller detected protocol error	     */
+ #define	M_SC_FLINI	0x000b	/* Drive failed initialization		     */
+ #define	M_SC_IGINI	0x000c	/* Drive ignored initialization		     */
+ #define	M_SC_RRCOL	0x000d	/* Receiver ready collision		     */
+ 
+ /*
+  * Informational event only subcodes
+ */
+ #define M_SC_IQUAL	0x0001	/* Media Quality Log			     */
+ #define M_SC_ISTAT	0x0002	/* Unload, spin down statistics		     */
+ 
+ #endif /* notnow */
+ 
+ /*
+  * Error Log message format codes.  Many of these are ifdef'd out so as to
+  * not overload the C preprocessor.  The symbols themselves are not used by
+  * the kernel but are very handy to have when deciphering datagrams logged
+  * to the console or the messages file.
+  */
  #define	M_FM_CNTERR	0	/* Controller error */
  #define	M_FM_BUSADDR	1	/* Host memory access error */
! #define	M_FM_DISKTRN	2	/* Disk transfer error (D) */
! #define	M_FM_SDI	3	/* SDI errors */
! #define	M_FM_SMLDSK	4	/* Small disk errors */
! #define	M_FM_TAPETRN	5	/* Tape transfer error (T) */
! #define	M_FM_STIERR	6	/* STI communication or command failure (T) */
! #define	M_FM_STIDEL	7	/* STI drive error log (T) */
! #define	M_FM_STIFEL	0x8	/* STI formatter error log (T) */
! #ifdef	notnow
! #define	M_FM_REPLACE	0x9	/* Bad block replacement attempt */
! #define	M_FM_LDRERR	0xa	/* Media loader errors */
! #define	M_FM_IBMSENSE	0xb	/* Sense data error log (T) */
! #endif
   
  /*
   * Error Log message flags
***************
*** 215,220 ****
--- 326,336 ----
   */
  #define	M_LF_SUCC	0x80	/* Operation successful */
  #define	M_LF_CONT	0x40	/* Operation continuing */
+ #ifdef	notnow
+ #define	M_LF_BBR	0x20	/* Bad block replacement attempt */
+ #define	M_LF_RPLER	0x10	/* Error during replacement */
+ #define	M_LF_INFO	0x02	/* Informational */
+ #endif
  #define	M_LF_SQNRS	0x01	/* Sequence number reset */
   
  /*
*** /usr/src/sys/pdp/mscp.h.old	Sun Mar 15 22:53:31 1987
--- /usr/src/sys/pdp/mscp.h	Wed Jan 28 23:19:23 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)mscp.h	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.
   *
!  *	@(#)mscp.h	1.2 (2.11BSD) 1998/1/28
   */
  
  /*
***************
*** 21,100 ****
   *	Fred Canter 10/22/83
  */
  
! /*
!  * Control message opcodes
!  */
! #define	M_O_ABORT	0001	/* Abort command */
! #define	M_O_GTCMD	0002	/* Get command status command */
! #define	M_O_GTUNT	0003	/* Get unit status command */
! #define	M_O_STCON	0004	/* Set controller characteristics command */
! #define	M_O_SEREX	0007	/* Serious exception end message */
! #define	M_O_AVAIL	0010	/* Available command */
! #define	M_O_ONLIN	0011	/* Online command */
! #define	M_O_STUNT	0012	/* Set unit characteristics command */
! #define	M_O_DTACP	0013	/* Determine access paths command */
! #define	M_O_ACCES	0020	/* Access command */
! #define	M_O_CMPCD	0021	/* Compare controller data command */
! #define	M_O_ERASE	0022	/* Erase command */
! #define	M_O_FLUSH	0023	/* Flush command */
! #define	M_O_REPLC	0024	/* Replace command */
! #define	M_O_COMP	0040	/* Compare host data command */
! #define	M_O_READ	0041	/* Read command */
! #define	M_O_WRITE	0042	/* Write command */
! #define	M_O_AVATN	0100	/* Available attention message */
! #define	M_O_DUPUN	0101	/* Duplicate unit number attention message */
! #define	M_O_ACPTH	0102	/* Access path attention message */
! #define	M_O_END		0200	/* End message flag */
  
  /*
-  * End message flags
- */
- #define	M_E_BBLR	0200	/* Bad block reported */
- #define	M_E_BBLU	0100	/* Bad block unreported */
- #define	M_E_ERLOG	0040	/* Error log generated */
- #define	M_E_SEREX	0020	/* Serious exception */
- 
- 
- /*
-  * Controller flags
- */
- #define	M_C_ATTN	0200	/* Enable attention messages */
- #define	M_C_MISC	0100	/* Enable miscellaneous error log messages */
- #define	M_C_OTHER	0040	/* Enable other host's error log messages */
- #define	M_C_THIS	0020	/* Enable this host's error log messages */
- #define	M_C_MLTHS	0004	/* Multi-host */
- #define	M_C_SHADW	0002	/* Shadowing */
- #define	M_C_576		0001	/* 576 byte sectors */
- 
- /*
-  * Status codes
- */
- #define	M_S_MASK	037		/* Status code mask */
- #define	M_S_SUCC	000		/* Success */
- #define	M_S_ICMD	001		/* Invalid command */
- #define	M_S_ABRTD	002		/* Command aborted */
- #define	M_S_OFFLN	003		/* Unit offline */
- #define	M_S_AVLBL	004		/* Unit available */
- #define	M_S_MFMTE	005		/* Media format error */
- #define	M_S_WRTPR	006		/* Write protected */
- #define	M_S_COMP	007		/* Compare error */
- #define	M_S_DATA	010		/* Data error */
- #define	M_S_HSTBF	011		/* Host buffer access error */
- #define	M_S_CNTLR	012		/* Controller error */
- #define	M_S_DRIVE	013		/* Drive error */
- #define	M_S_DIAG	037		/* Message from a internal diagnostic */
- 
- /*
-  * MSCP packet info
- */
- 
- struct mscp_header {
- 	u_short	ra_msglen;	/* length of MSCP packet */
- 	char	ra_credits;	/* low 4 bits: credits, high 4 bits: msgtype */
- 	char	ra_vcid;	/* virtual circuit id */
- };
- 
- /*
   * An MSCP packet
   */
  
--- 21,29 ----
   *	Fred Canter 10/22/83
  */
  
! #include "pdp/mscp_common.h"
  
  /*
   * An MSCP packet
   */
  
***************
*** 225,247 ****
  #define	m_cnttmo	m_hsttmo
  #define	m_cntcmdl	m_usefrac
  #define	m_cntid		m_unitid
- 
- 
- /*
-  * Error Log message format codes
-  */
- #define	M_F_CNTERR	0	/* Controller error */
- #define	M_F_BUSADDR	1	/* Host memory access error */
- #define	M_F_DISKTRN	2	/* Disk transfer error */
- #define	M_F_SDI		3	/* SDI error */
- #define	M_F_SMLDSK	4	/* Small disk error */
- 
- /*
-  * Error Log message flags
-  */
- #define	M_LF_SUCC	0200	/* Operation successful */
- #define	M_LF_CONT	0100	/* Operation continuing */
- #define	M_LF_SQNRS	0001	/* Sequence number reset */
  
  /*
   * MSCP Error Log packet
--- 154,159 ----
*** /usr/src/sys/pdp/tmscp.h.old	Thu Dec 14 21:17:04 1995
--- /usr/src/sys/pdp/tmscp.h	Thu Jan 29 22:33:33 1998
***************
*** 61,66 ****
--- 61,67 ----
  	u_char	mscp_flags;		/* end message flags */
  	short	mscp_modifier;		/* modifiers */
  	union {
+ 	char	FILLER[94];		/* sizeof (mslg) after 16 byte header */
  	struct {
  		u_short	bytecnt;	/* byte count (low order) */
  		u_short	zzz2;		/* 64kb max for pdp-11 (high order) */
***************
*** 69,83 ****
  		long	xxx2[2];	/* unused */
  		u_short	lbn_l;		/* logical block number low word */
  		u_short	lbn_h;		/* logical block number high word */
- 		long	xxx4;		/* unused */
- /*
-  * TMSCP only looks this far into the command packet.   The 'dscptr' is 26
-  * bytes offset from the start of the mscp structure and the 17 longwords of
-  * padding are necessary to make this structure the same length as the longest
-  * errorlog datagram received
- */
- 		long	*dscptr;	/* pointer to descriptor (software) */
- 		long	sftwds[17];	/* software words, padding */
  	} gen;
  	struct {
  		short	version;	/* MSCP version */
--- 70,75 ----
***************
*** 111,121 ****
  		u_long	position;	/* tape position */
  	} rep_em;
  	} un;
! 	short m_filler[3];
  };
   
- #define mscp_msglen (sizeof (struct mscp) - sizeof(struct mscp_header))
-  
  /*
   * generic packet
   */
--- 103,111 ----
  		u_long	position;	/* tape position */
  	} rep_em;
  	} un;
! 	long	*mscp_dscptr;	/* pointer to descriptor (software) */
  };
   
  /*
   * generic packet
   */
***************
*** 126,132 ****
  #define	mscp_buffer_l	un.gen.buf_l
  #define	mscp_lbn_h	un.gen.lbn_h
  #define	mscp_lbn_l	un.gen.lbn_l
- #define	mscp_dscptr	un.gen.dscptr
  #define	mscp_status	mscp_modifier
  #define	mscp_endcode	mscp_opcode
  #define	mscp_position	un.rep_em.position
--- 116,121 ----
*** /usr/src/sys/pdp/cpu.h.old	Sat Jan 14 01:07:04 1995
--- /usr/src/sys/pdp/cpu.h	Wed Jan 28 22:44:18 1998
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)cpu.h	1.3 (2.11BSD GTE) 1/14/95
   */
  
  /*
--- 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
   */
  
  /*
***************
*** 18,28 ****
   * CTL_MACHDEP definitions.
   */
  #define	CPU_CONSDEV		1	/* dev_t: console terminal device */
! #define	CPU_MAXID		2	/* number of valid machdep ids */
  
  #ifndef	KERNEL
  #define CTL_MACHDEP_NAMES { \
  	{ 0, 0 }, \
  	{ "console_device", CTLTYPE_STRUCT }, \
  }
  #endif
--- 18,42 ----
   * CTL_MACHDEP definitions.
   */
  #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 { \
  	{ 0, 0 }, \
  	{ "console_device", CTLTYPE_STRUCT }, \
+ 	{ "tmscp", CTLTYPE_NODE }, \
+ }
+ #endif
+ 
+ #define	TMSCP_CACHE	1		/* enable/disable drive cache */
+ #define	TMSCP_PRINTF	2		/* get/set print flag */
+ #define	TMSCP_MAXID	3		/* number of valid TMSCP ids */
+ 
+ #ifndef	KERNEL
+ #define	TMSCP_NAMES { \
+ 	{ 0, 0 }, \
+ 	{ "cache", CTLTYPE_INT }, \
+ 	{ "printf", CTLTYPE_INT }, \
  }
  #endif
*** /usr/src/sys/pdp/kern_pdp.c.old	Wed Aug 27 08:43:40 1997
--- /usr/src/sys/pdp/kern_pdp.c	Thu Jan 29 20:23:51 1998
***************
*** 11,19 ****
--- 11,22 ----
  #include "../machine/seg.h"
  
  #include "user.h"
+ #include "ioctl.h"
  #include "proc.h"
  #include "kernel.h"
  #include "systm.h"
+ #include "cpu.h"
+ #include "tty.h"
  
  /*
   * used to pass result from int service to probe();
***************
*** 185,187 ****
--- 188,247 ----
  bad:
  	u.u_error = EINVAL;
  }
+ 
+ /*
+  * 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[];
+ 
+ /*
+  * This was moved here when the TMSCP portion was added.  At that time it
+  * became (even more) system specific and didn't belong in kern_sysctl.c
+ */
+ 
+ int
+ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
+ 	int *name;
+ 	u_int namelen;
+ 	void *oldp;
+ 	size_t *oldlenp;
+ 	void *newp;
+ 	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
+ 		case	CPU_TMSCP:
+ 		/* All sysctl names at this level are terminal */
+ 			if	(namelen != 2)
+ 				return(ENOTDIR);
+ 			switch	(name[1])
+ 				{
+ 				case	TMSCP_CACHE:
+ 					return(sysctl_int(oldp, oldlenp, newp, 
+ 						newlen, &tmscpcache));
+ 				case	TMSCP_PRINTF:
+ 					return(sysctl_int(oldp, oldlenp, newp,
+ 						newlen,&tmscpprintf));
+ 				default:
+ 					return(EOPNOTSUPP);
+ 				}
+ #endif
+ 		default:
+ 			return(EOPNOTSUPP);
+ 		}
+ 	/* NOTREACHED */
+ 	}
*** /usr/src/sys/pdpstand/tmscp.c.old	Fri Mar  8 16:44:54 1996
--- /usr/src/sys/pdpstand/tmscp.c	Fri Jan 30 21:03:35 1998
***************
*** 1,4 ****
! /*	@(#)tmscp.c	7.1.4 (2.11BSD GTE) 1996/3/8 */
  
  /****************************************************************
   *        Licensed from Digital Equipment Corporation           *
--- 1,4 ----
! /*	@(#)tmscp.c	7.1.5 (2.11BSD GTE) 1998/1/30 */
  
  /****************************************************************
   *        Licensed from Digital Equipment Corporation           *
***************
*** 202,208 ****
  	tms->tmscp_ca.ca_cmddsc[0].lsh = lo16;
  	tms->tmscp_ca.ca_cmddsc[0].hsh = bae;
  	tms->tmscp_cmd[0].mscp_dscptr = (long *)tms->tmscp_ca.ca_cmddsc;
! 	tms->tmscp_cmd[0].mscp_header.tmscp_vcid = 1;	/* for tape */
  
  	iomapadr(&tms->tmscp_rsp[0].mscp_cmdref, &bae, &lo16);
  	tms->tmscp_ca.ca_rspdsc[0].lsh = lo16;
--- 202,208 ----
  	tms->tmscp_ca.ca_cmddsc[0].lsh = lo16;
  	tms->tmscp_ca.ca_cmddsc[0].hsh = bae;
  	tms->tmscp_cmd[0].mscp_dscptr = (long *)tms->tmscp_ca.ca_cmddsc;
! 	tms->tmscp_cmd[0].mscp_header.mscp_vcid = 1;	/* for tape */
  
  	iomapadr(&tms->tmscp_rsp[0].mscp_cmdref, &bae, &lo16);
  	tms->tmscp_ca.ca_rspdsc[0].lsh = lo16;
***************
*** 212,220 ****
  
  	tms->tmscp_cmd[0].mscp_opcode = op;
  	tms->tmscp_cmd[0].mscp_modifier = mod;
! 	tms->tmscp_cmd[0].mscp_header.tmscp_msglen = mscp_msglen;
  	tms->tmscp_ca.ca_cmddsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
! 	tms->tmscp_rsp[0].mscp_header.tmscp_msglen = mscp_msglen;
  	tms->tmscp_ca.ca_rspdsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
  	tms->tmscp_cmd[0].mscp_zzz2 = 0;
   
--- 212,220 ----
  
  	tms->tmscp_cmd[0].mscp_opcode = op;
  	tms->tmscp_cmd[0].mscp_modifier = mod;
! 	tms->tmscp_cmd[0].mscp_header.mscp_msglen = sizeof (struct tmscp);
  	tms->tmscp_ca.ca_cmddsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
! 	tms->tmscp_rsp[0].mscp_header.mscp_msglen = sizeof (struct tmscp);
  	tms->tmscp_ca.ca_rspdsc[0].hsh |= TMSCP_OWN;	/* | TMSCP_INT */
  	tms->tmscp_cmd[0].mscp_zzz2 = 0;
   
*** /usr/src/sys/pdpstand/ra.c.old	Fri Mar  8 16:29:05 1996
--- /usr/src/sys/pdpstand/ra.c	Fri Jan 30 21:10:09 1998
***************
*** 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
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	2.8 (2.11BSD GTE) 1998/1/30
   */
  
  /*
***************
*** 91,97 ****
  		if	(ra_step(raaddr, RA_STEP4, 4))
  			goto again;
  		raaddr->rasa = RA_GO;
! 		if (racmd(M_O_STCON, io) < 0) {
  			printf("%s STCON err\n", devname(io));
  			return(-1);
  		}
--- 91,97 ----
  		if	(ra_step(raaddr, RA_STEP4, 4))
  			goto again;
  		raaddr->rasa = RA_GO;
! 		if (racmd(M_OP_STCON, io) < 0) {
  			printf("%s STCON err\n", devname(io));
  			return(-1);
  		}
***************
*** 120,126 ****
  	register int ctlr = io->i_ctlr;
  	register int unit = io->i_unit;
  
! 	if (racmd(M_O_ONLIN, io) < 0) {
  		printf("%s !online\n", devname(io));
  		return(-1);
  	}
--- 120,126 ----
  	register int ctlr = io->i_ctlr;
  	register int unit = io->i_unit;
  
! 	if (racmd(M_OP_ONLIN, io) < 0) {
  		printf("%s !online\n", devname(io));
  		return(-1);
  	}
***************
*** 143,150 ****
  	racom->ra_cmd.m_opcode = op;
  	racom->ra_cmd.m_unit = unit;
  	racom->ra_cmd.m_cntflgs = 0;
! 	racom->ra_rsp.m_header.ra_msglen = sizeof(struct mscp);
! 	racom->ra_cmd.m_header.ra_msglen = sizeof(struct mscp);
  
  	iomapadr(&racom->ra_rsp.m_cmdref, &bae, &lo16);
  	racom->ra_ca.ca_rspl = lo16;
--- 143,150 ----
  	racom->ra_cmd.m_opcode = op;
  	racom->ra_cmd.m_unit = unit;
  	racom->ra_cmd.m_cntflgs = 0;
! 	racom->ra_rsp.m_header.mscp_msglen = sizeof(struct mscp);
! 	racom->ra_cmd.m_header.mscp_msglen = sizeof(struct mscp);
  
  	iomapadr(&racom->ra_rsp.m_cmdref, &bae, &lo16);
  	racom->ra_ca.ca_rspl = lo16;
***************
*** 170,182 ****
  		}
  		racom->ra_ca.ca_cmdint = 0;
  		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);
--- 170,182 ----
  		}
  		racom->ra_ca.ca_cmdint = 0;
  		racom->ra_ca.ca_rspint = 0;
! 		if (mp->m_opcode == (op | M_OP_END))
  			break;
  		printf("%s rsp %x op %x ignored\n", devname(io),
! 			mp->m_header.mscp_credits & 0xf0, mp->m_opcode);
  		racom->ra_ca.ca_rsph |= RA_OWN;
  	}
! 	if ((mp->m_status & M_ST_MASK) != M_ST_SUCC) {
  		printf("%s err op=%x sts=%x\n", devname(io),
  			mp->m_opcode, mp->m_status);
  		return(-1);
***************
*** 206,212 ****
  	mp->m_bytecnt = io->i_cc;
  	mp->m_buf_l = lo16;
  	mp->m_buf_h = bae;
! 	if	(racmd(func == READ ? M_O_READ : M_O_WRITE, io) < 0)
  		return(-1);
  	return(io->i_cc);
  }
--- 206,212 ----
  	mp->m_bytecnt = io->i_cc;
  	mp->m_buf_l = lo16;
  	mp->m_buf_h = bae;
! 	if	(racmd(func == READ ? M_OP_READ : M_OP_WRITE, io) < 0)
  		return(-1);
  	return(io->i_cc);
  }
***************
*** 251,259 ****
  	lp->d_partitions[0].p_size = nblks;  /* span the drive with 'a' */
  /*	lp->d_secperunit = nblks;	     /* size of entire volume */
  
! 	if	(racmd(M_O_GTUNT, io) != 0)
  		{
! 		printf("%s M_OP_GTUNT failed\n", devname(io));
  		return(-1);
  		}
  /*
--- 251,259 ----
  	lp->d_partitions[0].p_size = nblks;  /* span the drive with 'a' */
  /*	lp->d_secperunit = nblks;	     /* size of entire volume */
  
! 	if	(racmd(M_OP_GTUNT, io) != 0)
  		{
! 		printf("%s GTUNT failed\n", devname(io));
  		return(-1);
  		}
  /*
*** /usr/src/bin/sysctl/sysctl.c.old	Wed Oct 11 19:58:59 1995
--- /usr/src/bin/sysctl/sysctl.c	Thu Jan 29 20:01:40 1998
***************
*** 68,76 ****
  struct ctlname hwname[] = CTL_HW_NAMES;
  struct ctlname username[] = CTL_USER_NAMES;
  struct ctlname debugname[CTL_DEBUG_MAXID];
- #ifdef CTL_MACHDEP_NAMES
  struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
- #endif
  char names[BUFSIZ];
  
  struct list {
--- 68,74 ----
***************
*** 90,100 ****
  #endif
  	{ 0, CTL_DEBUG_MAXID },		/* CTL_DEBUG */
  	{ hwname, HW_MAXID },		/* CTL_HW */
- #ifdef CTL_MACHDEP_NAMES
  	{ machdepname, CPU_MAXID },	/* CTL_MACHDEP */
- #else
- 	{ 0, 0 },			/* CTL_MACHDEP */
- #endif
  	{ username, USER_MAXID },	/* CTL_USER_NAMES */
  };
  
--- 88,94 ----
***************
*** 300,309 ****
  		break;
  
  	case CTL_MACHDEP:
- #ifdef CPU_CONSDEV
  		if (mib[1] == CPU_CONSDEV)
  			special |= CONSDEV;
! #endif
  		break;
  
  	case CTL_FS:
--- 294,307 ----
  		break;
  
  	case CTL_MACHDEP:
  		if (mib[1] == CPU_CONSDEV)
  			special |= CONSDEV;
! 		if (mib[1] == CPU_TMSCP) {
! 			len = sysctl_tmscp(string, &bufp, mib, flags, &type);
! 			if (len >= 0)
! 				goto doit;
! 			return;
! 		}
  		break;
  
  	case CTL_FS:
***************
*** 315,320 ****
--- 313,319 ----
  		return;
  	
  	}
+ doit:
  	if (bufp) {
  		fprintf(stderr, "name %s in %s is unknown\n", *bufp, string);
  		return;
***************
*** 435,440 ****
--- 434,465 ----
  		    string);
  		return;
  	}
+ }
+ 
+ struct	ctlname tmscpname[]  = TMSCP_NAMES;
+ struct	list tmscplist = { tmscpname, TMSCP_MAXID };
+ 
+ /*
+  * Handle machdep.tmscp.x 
+ */
+ sysctl_tmscp(string, bufpp, mib, flags, typep)
+ 	char *string;
+ 	char **bufpp;
+ 	int mib[];
+ 	int flags;
+ 	int *typep;
+ {
+ 	int indx;
+ 
+ 	if (*bufpp == NULL) {
+ 		listall(string, &tmscplist);
+ 		return (-1);
+ 	}
+ 	if ((indx = findname(string, "third", bufpp, &tmscplist)) == -1)
+ 		return (-1);
+ 	mib[2] = indx;
+ 	*typep = tmscpname[indx].ctl_type;
+ 	return (3);
  }
  
  /*
*** /usr/src/bin/sysctl/sysctl.8.old	Thu Jan 19 21:28:46 1995
--- /usr/src/bin/sysctl/sysctl.8	Thu Jan 29 20:43:08 1998
***************
*** 29,35 ****
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .\"	@(#)sysctl.8	8.1.2 (2.11BSD GTE) 1/19/95
  .\"
  .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.3 (2.11BSD GTE) 1998/1/29
  .\"
  .TH SYSCTL 8 "June 6, 1993"
  .UC 4
***************
*** 138,143 ****
--- 138,145 ----
  	kern.boottime	struct	no
  	vm.loadavg	struct	no
  	machdep.console_device	dev_t	no
+ 	machdep.tmscp.cache	integer	yes
+ 	machdep.tmscp.printf	integer	yes
  	net.inet.ip.forwarding	integer	yes
  	net.inet.ip.redirect	integer	yes
  	net.inet.ip.ttl	integer	yes
***************
*** 211,216 ****
--- 213,221 ----
  .TP 15
  <sys/gmon.h>
  definitions for third level profiling identifiers
+ .TP 15
+ <machine/cpu.h>
+ definitions for second and third level machine dependent identifiers
  .TP 15
  <sys/vmparam.h>
  definitions for second level virtual memory identifiers
*** /VERSION.old	Sat Jan 24 20:13:15 1998
--- /VERSION	Fri Jan 30 22:45:45 1998
***************
*** 1,5 ****
! Current Patch Level: 400
! Date: January 24, 1998
  
  2.11 BSD
  ============
--- 1,5 ----
! Current Patch Level: 401
! Date: January 30, 1998
  
  2.11 BSD
  ============
