/boot,/mdec,[T]MSCP (Part 11 of 22)

Steven M. Schultz sms at wlv.imsd.contel.com
Sat May 18 16:46:02 AEST 1991


Subject: Part 11 of 22 /boot,/mdec,[T]MSCP updates
Index:	/sys/<many>, /usr/src/etc/<several> 2.11BSD

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

This is part 11 of 22

The TMSCP (TK50/TU81) driver was modified to use an externally mapped
communication packet arena.  Also a number of changes were made to
reduce the size of the driver.  Other fixes dealing with onlining
the unit were made.  Space savings were achieved partially by altering
the error messages.

*** /usr/src/sys/pdpuba/tmscp.c.old	Wed Dec 19 10:11:09 1990
--- /usr/src/sys/pdpuba/tmscp.c	Fri May 10 20:42:24 1991
***************
*** 1,4 ****
! /*	@(#)tmscp.c	7.1 (Berkeley) 6/5/86 */
  
  #if	!defined(lint) && defined(DOSCCS)
  static	char	*sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
--- 1,4 ----
! /*	@(#)tmscp.c	1.1 (2.11BSD) 5/10/91 */
  
  #if	!defined(lint) && defined(DOSCCS)
  static	char	*sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
***************
*** 32,40 ****
   * 
   * Modification History:
   *
   * 17-Jun-90,14Aug90 - sms at wlv.imsd.contel.com
   *	Began porting to 2.10.1BSD/2.11BSD.  Multiple drives per controller
!  *	NOT supported, although multiple controllers are.  Programmable
   *	vectors don't work very well with the autoconfigure scheme in use.
   *	the define TMSCP_VEC will have to be adjusted in tms.h (see
   *	conf/config and the sample config files).  For patching purposes
--- 32,70 ----
   * 
   * Modification History:
   *
+  * 29-Mar-91 - sms at wlv.imsd.contel.com [2.11BSD]
+  *	Major changes to 1) support multiple drives per controller
+  *	(the maximum number of drives per controller is 4 for now in order
+  *	to maximize compatibility with existing minor device numbers - the
+  *	norewind and density bit stay in the same place) and 2) more
+  *	importantly reduce the bloat of this driver.  The command
+  *	packet area is now allocated from an external heap setup at boot
+  *	time (the MSCP, ra.c driver also does this).  Allocating from an
+  * 	external arena save approximately 2kb of kernel D space PER CONTROLLER
+  *	and costs little in speed because the amount of remapping involved is
+  *	quite small.
+  *
+  *	The 'errinfo' routine was removed in the interest of space savings,
+  *	the error code was already being printed out in hex and it's not
+  *	worth eating up another 250 or so bytes of kernel D space to pretty
+  *	print messages for which tmscp.h provides the cross reference (I space
+  *	is also saved by not printing the messages).  Besides, the ra.c (MSCP)
+  *	driver doesn't do it and it is worth a degree of non 4.3BSD verisimility
+  *	to save a significant amount of space.
+  *
+  *	The tms_type field should have been a 'long' (mediatype).  Since the
+  *	drives are not probed at autoconfigure time a GTUNT (TMS_SENSE) command
+  *	is done at open() time to fetch the format/density menu and unit flags.
+  *	iodone() proccessing was missing for the GTUNT function in tmscprsp()
+  *	causing hangs in both open and ioctl functions.
+  *
+  *	Multiple controller support made to work, the top 2 bits of the minor
+  *	device number are used to designate the controller, thus there is
+  *	a maximum of 4 TMSCP controllers per system.
+  *
   * 17-Jun-90,14Aug90 - sms at wlv.imsd.contel.com
   *	Began porting to 2.10.1BSD/2.11BSD.  Multiple drives per controller
!  *	NOT supported, although multiple controllers are (maybe).  Programmable
   *	vectors don't work very well with the autoconfigure scheme in use.
   *	the define TMSCP_VEC will have to be adjusted in tms.h (see
   *	conf/config and the sample config files).  For patching purposes
***************
*** 162,167 ****
--- 192,198 ----
  	struct	tmscpdevice *sc_addr;	/* controller CSR address */
  	short   sc_state;       /* state of controller */
  	short	sc_ivec;        /* interrupt vector address */
+ 	short	sc_unit;	/* CONTROLLER number - NOT drive unit # */
  	short   sc_credits;     /* transfer credits */
  	short   sc_lastcmd;     /* pointer into command ring */
  	short   sc_lastrsp;     /* pointer into response ring */
***************
*** 169,174 ****
--- 200,206 ----
  	struct	buf sc_ctab;	/* controller queue */
  	struct	buf sc_wtab;	/* I/O wait queue for controller */
  	struct	tmscp *sc_com;	/* communications area pointer */
+ 	struct	tms_info *sc_drives[4];	/* pointers to per drive info */
  } tmscp_softc[NTMSCP];
  
  #define	RINGBASE	(4 * sizeof (short))
***************
*** 177,190 ****
  	struct tmscpca	tmscp_ca;         /* communications area */
  	struct mscp	tmscp_rsp[NRSP];  /* response packets */
  	struct mscp	tmscp_cmd[NCMD];  /* command packets */
! } tmscp[NTMSCP];
  
  /*
   * Per drive-unit info
   */
  struct tms_info {
  	daddr_t		tms_dsize;	/* Max user size from online pkt */
! 	unsigned	tms_type;	/* Drive type int field  */
  	int		tms_resid;	/* residual from last xfer */
  	u_char		tms_endcode;	/* last command endcode */
  	u_char		tms_flags;	/* last command end flags */
--- 209,224 ----
  	struct tmscpca	tmscp_ca;         /* communications area */
  	struct mscp	tmscp_rsp[NRSP];  /* response packets */
  	struct mscp	tmscp_cmd[NCMD];  /* command packets */
! };					  /* 1896 bytes per controller! */
  
+ 	memaddr	tmscp[NTMSCP];		/* click addresses of ctrl comm area */
+ 
  /*
   * Per drive-unit info
   */
  struct tms_info {
  	daddr_t		tms_dsize;	/* Max user size from online pkt */
! 	long		tms_type;	/* Drive type field  */
  	int		tms_resid;	/* residual from last xfer */
  	u_char		tms_endcode;	/* last command endcode */
  	u_char		tms_flags;	/* last command end flags */
***************
*** 199,218 ****
  	struct tty	*tms_ttyp;	/* record user's tty for errors */
  	struct	buf	tms_dtab;	/* I/O tape drive queues */
  	struct	buf	tms_rtab;	/* raw I/O tape block header */
! 	short		tms_online;	/* online flag */
  } tms_info[NTMS];
  
- struct	buf	tmscomphys;		/* Communication area phys map */
- long	tmsphys();
- 
- #ifndef	KDSA0
- #define KDSA0		((u_short *)0172360)
- #endif
  /* Bits in minor device */
  #define	TMSUNIT(dev)	(minor(dev)&03)
  #define	T_NOREWIND	04
  #define	T_HIDENSITY	010
  
  /*
   * Internal (ioctl) command codes (these must also be declared in the
   * tmscpioctl routine).  These correspond to ioctls in mtio.h
--- 233,250 ----
  	struct tty	*tms_ttyp;	/* record user's tty for errors */
  	struct	buf	tms_dtab;	/* I/O tape drive queues */
  	struct	buf	tms_rtab;	/* raw I/O tape block header */
! 	short		tms_online;	/* 0=available, 1=online, -1=offline */
  } tms_info[NTMS];
  
  /* Bits in minor device */
  #define	TMSUNIT(dev)	(minor(dev)&03)
+ #define	TMSCTLR(dev)	((minor(dev) >> 6) & 3)
  #define	T_NOREWIND	04
  #define	T_HIDENSITY	010
  
+ /* Size to map in when mapping a controller's command packet area */
+ #define	MAPBUFDESC	(((btoc(sizeof (struct tmscp)) - 1) << 8) | RW)
+ 
  /*
   * Internal (ioctl) command codes (these must also be declared in the
   * tmscpioctl routine).  These correspond to ioctls in mtio.h
***************
*** 247,252 ****
--- 279,285 ----
  				/* packets and or credits. */
  int	wakeup();
  extern	int	hz;		/* Should find the right include */
+ extern	long	_iomap();
  
  #ifdef	TMSCP_DEBUG
  #define printd if (tmscpdebug) printf
***************
*** 259,282 ****
  #define b_qsize         b_resid         /* queue size per drive, in tmsutab */
  
  /* 
-  * Set ui flags to zero to show device is not online & set tmscpip.
-  * Unit to Controller mapping is set up here.
   * Open routine will issue the online command, later.
   */
  tmsattach(addr, unit)
  	struct tmscpdevice *addr;
  	register int unit;
  {
! 	register struct tmscp_softc *sc = &tmscp_softc[TMSUNIT(unit)];
  
  	if (sc->sc_addr == NULL && addr != NULL) {
  		sc->sc_addr = addr;
! 		sc->sc_com = &tmscp[TMSUNIT(unit)];
  		return (1);
  	}
  	return(0);
  }
  
  /*
   * TMSCP interrupt routine.
   */
--- 292,338 ----
  #define b_qsize         b_resid         /* queue size per drive, in tmsutab */
  
  /* 
   * Open routine will issue the online command, later.
+  *
+  * This routine attaches controllers, not drives - sc_unit and 'unit' are 
+  * the controller number not a drive unit number.  sc_com is initialized
+  * to SEG5 because all communication areas are mapped to the same virtual
+  * address now.
   */
  tmsattach(addr, unit)
  	struct tmscpdevice *addr;
  	register int unit;
  {
! 	register struct tmscp_softc *sc = &tmscp_softc[unit];
  
+ 	if (unit >= NTMSCP)
+ 		return(0);
  	if (sc->sc_addr == NULL && addr != NULL) {
+ 		tmscp[unit] = (memaddr)_ioget(sizeof (struct tmscp));
+ 		if (tmscp[unit] == NULL)
+ 			return(0);
  		sc->sc_addr = addr;
! 		sc->sc_unit = unit;
! 		sc->sc_com = (struct tmscp *)SEG5;
  		return (1);
  	}
  	return(0);
  }
  
+ struct tms_info *
+ getdd()
+ {
+ 	register int i;
+ 	register struct tms_info *p;
+ 
+ 	for (i = NTMS, p = tms_info; i--; p++) {
+ 		if (p->tms_online == 0)
+ 			return(p);
+ 	}
+ 	log(TMS_PRI, "tms: no drive descriptors\n");
+ 	return(NULL);
+ }
+ 
  /*
   * TMSCP interrupt routine.
   */
***************
*** 283,295 ****
  tmsintr(dev)
  	dev_t dev;
  {
- 	int unit = TMSUNIT(dev);
  	register struct tmscpdevice *tmscpaddr;
  	struct buf *bp;
  	register int i;
! 	register struct tmscp_softc *sc = &tmscp_softc[unit];
! 	register struct tmscp *tm = &tmscp[unit];
  	struct mscp *mp;
  
  	tmscpaddr = sc->sc_addr;
  #ifdef TMSCP_DEBUG
--- 339,351 ----
  tmsintr(dev)
  	dev_t dev;
  {
  	register struct tmscpdevice *tmscpaddr;
  	struct buf *bp;
  	register int i;
! 	register struct tmscp_softc *sc = &tmscp_softc[dev];
! 	register struct tmscp *tm = sc->sc_com;
  	struct mscp *mp;
+ 	segm seg5;
  
  	tmscpaddr = sc->sc_addr;
  #ifdef TMSCP_DEBUG
***************
*** 302,308 ****
  	switch (sc->sc_state) {
  
  	case S_IDLE:
! 		printf("tms%d: random interrupt ignored\n", unit);
  		return;
  
  	/* Controller was in step 1 last, see if its gone to step 2 */
--- 358,364 ----
  	switch (sc->sc_state) {
  
  	case S_IDLE:
! 		printf("tms%d: random interrupt ignored\n", dev);
  		return;
  
  	/* Controller was in step 1 last, see if its gone to step 2 */
***************
*** 402,407 ****
--- 458,465 ----
  	    /*
  	     * Initialize the data structures (response and command queues).
  	     */
+ 	    saveseg5(seg5);
+ 	    mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  	    tmsginit(sc, sc->sc_com->tmscp_ca.ca_rspdsc, sc->sc_com->tmscp_rsp,
  			0, NRSP, TMSCP_OWN|TMSCP_INT);
  	    tmsginit(sc, sc->sc_com->tmscp_ca.ca_cmddsc, sc->sc_com->tmscp_cmd,
***************
*** 425,430 ****
--- 483,489 ----
  	    mp->mscp_opcode = M_OP_STCON;
  	    ((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT;
  	    i = tmscpaddr->tmscpip;      /* initiate polling */
+ 	    restorseg5(seg5);
  	    return;
  
  	case S_SCHAR:
***************
*** 432,438 ****
  		break;
  
  	default:
! 	    printf("tms%d: interrupt in unknown state %d ignored\n",unit,sc->sc_state);
  	    return;
  	}	/* end switch */
  
--- 491,497 ----
  		break;
  
  	default:
! 	    printf("tms%d: interrupt in unknown state %d ignored\n",dev,sc->sc_state);
  	    return;
  	}	/* end switch */
  
***************
*** 446,452 ****
  	 */
  	if (tmscpaddr->tmscpsa&TMSCP_ERR)
  		{
! 		printf("tms%d: fatal error (%o)\n", unit, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpip = 0;
  		sc->sc_state = S_IDLE;
  		sc->sc_ctab.b_active = 0;
--- 505,511 ----
  	 */
  	if (tmscpaddr->tmscpsa&TMSCP_ERR)
  		{
! 		printf("tms%d: fatal error %o\n", dev, tmscpaddr->tmscpsa);
  		tmscpaddr->tmscpip = 0;
  		sc->sc_state = S_IDLE;
  		sc->sc_ctab.b_active = 0;
***************
*** 455,460 ****
--- 514,521 ----
  	/*
  	 * Check for a buffer purge request. (Won't happen w/ TK50 on Q22 bus)
  	 */
+ 	saveseg5(seg5);
+ 	mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  	if (tm->tmscp_ca.ca_bdp)
  		{
  		tm->tmscp_ca.ca_bdp = 0;
***************
*** 472,478 ****
  			i %= NRSP;
  			if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN)
  			    break;
! 			tmscprsp(unit, tm, sc, i);
  			tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN;
  			}
  		sc->sc_lastrsp = i;
--- 533,539 ----
  			i %= NRSP;
  			if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN)
  			    break;
! 			tmscprsp(sc, i);
  			tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN;
  			}
  		sc->sc_lastrsp = i;
***************
*** 488,494 ****
  #endif		
  		tm->tmscp_ca.ca_cmdint = 0;
  		}
!     	if(tmscp_cp_wait)
  		wakeup((caddr_t)&tmscp_cp_wait);
      	(void) tmsstart(sc);
  }
--- 549,556 ----
  #endif		
  		tm->tmscp_ca.ca_cmdint = 0;
  		}
! 	restorseg5(seg5);
!     	if (tmscp_cp_wait)
  		wakeup((caddr_t)&tmscp_cp_wait);
      	(void) tmsstart(sc);
  }
***************
*** 504,510 ****
  	dev_t dev;
  	int flag;
  {
! 	register int unit;
  	register struct tmscp_softc *sc;
  	register struct tms_info *tms;
  	register struct mscp *mp;
--- 566,573 ----
  	dev_t dev;
  	int flag;
  {
! 	register int unit = TMSUNIT(dev);
! 	int ctlr = TMSCTLR(dev);
  	register struct tmscp_softc *sc;
  	register struct tms_info *tms;
  	register struct mscp *mp;
***************
*** 511,529 ****
  	struct tmscpdevice *tmscpaddr;
  	int s,i;
  	
- 	unit = TMSUNIT(dev);
  #ifdef TMSCP_DEBUG
! 	printd("tmscpopen unit %d\n",unit);
! 	if(tmscpdebug)delay(10000L);
  #endif
! 	if (unit >= NTMS)
  		return (ENXIO);
- 	tms = &tms_info[unit];
- 	if (tms->tms_openf)
- 		return (EBUSY);
  	sc = &tmscp_softc[unit];
  	if (sc->sc_addr == NULL)
  		return (ENXIO);
  	tms->tms_openf = 1;
  	tms->tms_ttyp = u.u_ttyp;
  	s = spl5();
--- 574,597 ----
  	struct tmscpdevice *tmscpaddr;
  	int s,i;
  	
  #ifdef TMSCP_DEBUG
! 	printd("tmscpopen %d,%d\n", ctlr, unit);
! 	if (tmscpdebug) delay(10000L);
  #endif
! 	if (ctlr >= NTMSCP)
  		return (ENXIO);
  	sc = &tmscp_softc[unit];
  	if (sc->sc_addr == NULL)
  		return (ENXIO);
+ 	if ((tms = sc->sc_drives[unit]) == NULL) {
+ 		tms = getdd();
+ 		if (!tms)
+ 			return(ENXIO);
+ 		tms->tms_online = -1;
+ 		sc->sc_drives[unit] = tms;
+ 	}
+ 	if (tms->tms_openf)
+ 		return(EBUSY);
  	tms->tms_openf = 1;
  	tms->tms_ttyp = u.u_ttyp;
  	s = spl5();
***************
*** 532,538 ****
  		if (sc->sc_state == S_IDLE)
  			if(!tkini(sc))
  				{
! 				printf("tms ctrl failed to init\n");
  				(void) splx(s);
  				return(ENXIO);
  				}
--- 600,606 ----
  		if (sc->sc_state == S_IDLE)
  			if(!tkini(sc))
  				{
! 				printf("tms%d failed to init\n", ctlr);
  				(void) splx(s);
  				return(ENXIO);
  				}
***************
*** 543,550 ****
  		sleep((caddr_t)&sc->sc_ctab, PSWP+1);
  		if (sc->sc_state != S_RUN)
  			{
  			(void) splx(s);
- 			tms->tms_openf = 0;
  			return (EIO);
  			}
  		}
--- 611,619 ----
  		sleep((caddr_t)&sc->sc_ctab, PSWP+1);
  		if (sc->sc_state != S_RUN)
  			{
+ 			sc->sc_drives[unit] = NULL;
+ 			tms->tms_online = tms->tms_openf = 0;
  			(void) splx(s);
  			return (EIO);
  			}
  		}
***************
*** 554,563 ****
  	 */
  	tmscpaddr = (struct tmscpdevice *) sc->sc_addr;
  	(void) splx(s);
! 	if(tms->tms_online == 0)
  		{
  		s = spl5();
! 		while((mp = tmscpgetcp(sc)) == 0)
  			{
  			tmscp_cp_wait++;
  			sleep((caddr_t)&tmscp_cp_wait,PSWP+1);
--- 623,632 ----
  	 */
  	tmscpaddr = (struct tmscpdevice *) sc->sc_addr;
  	(void) splx(s);
! 	if(tms->tms_online == -1)
  		{
  		s = spl5();
! 		while ((mp = tmscpgetcp(sc)) == 0)
  			{
  			tmscp_cp_wait++;
  			sleep((caddr_t)&tmscp_cp_wait,PSWP+1);
***************
*** 564,577 ****
  			tmscp_cp_wait--;
  			}
  		(void) splx(s);
  		mp->mscp_opcode = M_OP_ONLIN;
! 		mp->mscp_unit = 0;		/* unit? */
  		mp->mscp_cmdref = (u_short)&tms->tms_type;
  					    /* need to sleep on something */
  #ifdef TMSCP_DEBUG
! 		printd("tmscpopen: bring unit %d online\n",unit);
  #endif	
  		((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN | TMSCP_INT;
  		i = tmscpaddr->tmscpip;
  		/* 
  		 * To make sure we wake up, timeout in 240 seconds.
--- 633,648 ----
  			tmscp_cp_wait--;
  			}
  		(void) splx(s);
+ 		mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  		mp->mscp_opcode = M_OP_ONLIN;
! 		mp->mscp_unit = unit;		/* unit? */
  		mp->mscp_cmdref = (u_short)&tms->tms_type;
  					    /* need to sleep on something */
  #ifdef TMSCP_DEBUG
! 		printd("tmscpopen: bring unit %d,%d online\n",ctlr, unit);
  #endif	
  		((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN | TMSCP_INT;
+ 		normalseg5();
  		i = tmscpaddr->tmscpip;
  		/* 
  		 * To make sure we wake up, timeout in 240 seconds.
***************
*** 579,591 ****
  		 * 240 seconds (4 minutes) is necessary since a rewind
  		 * can take a few minutes.
  		 */
! 		timeout(wakeup,(caddr_t) mp->mscp_cmdref,240 * hz);
! 		sleep((caddr_t) mp->mscp_cmdref,PSWP+1);
  		}
! 	if(tms->tms_online == 0) {
! 		tms->tms_openf = 0;
  		return(ENXIO);  /* Didn't go online */
! 	}
  	tms->tms_lastiow = 0;
  	/*
  	 * If the high density device is not specified, set unit to low
--- 650,675 ----
  		 * 240 seconds (4 minutes) is necessary since a rewind
  		 * can take a few minutes.
  		 */
! 		timeout(wakeup,(caddr_t) &tms->tms_type,240 * hz);
! 		sleep((caddr_t) &tms->tms_type,PSWP+1);
  		}
! 	if	(tms->tms_online == -1)
! 		{
! oops:		tms->tms_online = tms->tms_openf = 0;
! 		sc->sc_drives[unit] = NULL;
  		return(ENXIO);  /* Didn't go online */
! 		}
! 	/*
! 	 * Get the unit characteristics (GTUNT).  Done here because we
! 	 * do not check for slave units at autoconfigure time.  This really
! 	 * only need be done once, but it's easier to do it on each open.
! 	 * tmscpcommand() is used since the iodone() handling for GTUNT has
! 	 * been fixed.
! 	*/
! 	tms->tms_type = 0;
! 	tmscpcommand(dev, TMS_SENSE, 1);
! 	if	(tms->tms_type == 0)
! 		goto oops;
  	tms->tms_lastiow = 0;
  	/*
  	 * If the high density device is not specified, set unit to low
***************
*** 619,632 ****
  	register dev_t dev;
  	register flag;
  {
  	register struct tms_info *tms;
  	int unit = TMSUNIT(dev);
  
  #ifdef TMSCP_DEBUG
! 	printd("tmscpclose: unit = %d\n", unit);
  	if(tmscpdebug)delay(10000L);
  #endif
! 	tms = &tms_info[unit];
  	if (flag == FWRITE || (flag&FWRITE) && tms->tms_lastiow)
  		{
  		/*	   device, command, count */
--- 703,718 ----
  	register dev_t dev;
  	register flag;
  {
+ 	struct tmscp_softc *sc;
  	register struct tms_info *tms;
  	int unit = TMSUNIT(dev);
  
  #ifdef TMSCP_DEBUG
! 	printd("tmscpclose: %d,%d\n", TMSCTLR(dev), unit);
  	if(tmscpdebug)delay(10000L);
  #endif
! 	sc = &tmscp_softc[TMSCTLR(dev)];
! 	tms = sc->sc_drives[unit];
  	if (flag == FWRITE || (flag&FWRITE) && tms->tms_lastiow)
  		{
  		/*	   device, command, count */
***************
*** 668,674 ****
  	register int s;
  	int unit = TMSUNIT(dev);
  
! 	bp = &tmscp_softc[unit].sc_cmdbuf;
  
  	s = spl5();
  	while (bp->b_flags&B_BUSY)
--- 754,760 ----
  	register int s;
  	int unit = TMSUNIT(dev);
  
! 	bp = &tmscp_softc[TMSCTLR(dev)].sc_cmdbuf;
  
  	s = spl5();
  	while (bp->b_flags&B_BUSY)
***************
*** 723,731 ****
  	/* 
  	 * Figure out virtual address of message 
  	 * skip comm area and mscp messages header and previous messages
  	 */
! 	vaddr = (u_int)tmscomphys.b_un.b_addr | ((long)tmscomphys.b_xmem << 16);
! 	vaddr += (u_int)sc->sc_com - (u_int)tmscp;	/* unit offset */
  	vaddr += sizeof(struct tmscpca)			/* skip comm area */
  		+sizeof(struct mscp_header);		/* m_cmdref disp */
  	vaddr += offset * sizeof(struct mscp);		/* skip previous */
--- 809,819 ----
  	/* 
  	 * Figure out virtual address of message 
  	 * skip comm area and mscp messages header and previous messages
+ 	 *
+ 	 * N.B. Assumes SEG5 has been remapped to the comm area for this
+ 	 * controller.
  	 */
! 	vaddr = _iomap(tmscp[sc->sc_unit]);
  	vaddr += sizeof(struct tmscpca)			/* skip comm area */
  		+sizeof(struct mscp_header);		/* m_cmdref disp */
  	vaddr += offset * sizeof(struct mscp);		/* skip previous */
***************
*** 746,757 ****
  tmscpgetcp(sc)
  	register struct tmscp_softc *sc;
  {
! 	register struct mscp *mp;
  	struct tmscpca *cp;
  	register int i;
  	int	s;
  
  	s = spl5();
  	cp = &sc->sc_com->tmscp_ca;
  	/*
  	 * If no credits, can't issue any commands
--- 834,848 ----
  tmscpgetcp(sc)
  	register struct tmscp_softc *sc;
  {
! 	register struct mscp *mp = NULL;
  	struct tmscpca *cp;
  	register int i;
  	int	s;
+ 	segm seg5;
  
  	s = spl5();
+ 	saveseg5(seg5);
+ 	mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  	cp = &sc->sc_com->tmscp_ca;
  	/*
  	 * If no credits, can't issue any commands
***************
*** 773,786 ****
  		mp->mscp_buffer_h = mp->mscp_buffer_l = 0;
  		mp->mscp_zzz2 = 0;
  		sc->sc_lastcmd = (i + 1) % NCMD;
- 		(void) splx(s);
- 		return(mp);
  		}
  	(void) splx(s);
! 	return(NULL);
  }
  
- 
  /*
   * Initialize a TMSCP device.  Set up UBA mapping registers,
   * initialize data structures, and start hardware
--- 864,875 ----
  		mp->mscp_buffer_h = mp->mscp_buffer_l = 0;
  		mp->mscp_zzz2 = 0;
  		sc->sc_lastcmd = (i + 1) % NCMD;
  		}
+ 	restorseg5(seg5);
  	(void) splx(s);
! 	return(mp);
  }
  
  /*
   * Initialize a TMSCP device.  Set up UBA mapping registers,
   * initialize data structures, and start hardware
***************
*** 790,822 ****
  	register struct tmscp_softc *sc;
  {
  	register struct tmscpdevice *tmscpaddr;
! 	register int unit = sc - tmscp_softc;
! 	long comaddr, rap;
  
! 	sc->sc_ivec = TMSvec + unit * 4;
  	sc->sc_ctab.b_active++;
  	tmscpaddr = sc->sc_addr;
- 	if (tmscomphys.b_flags == 0)
- 		{
- 		/*
- 		 * Map or calculate the addresses (Qbus) of communications area
- 		 * and response packets
- 		 */
- 		rap = tmsphys((u_int)tmscp);
- 		tmscomphys.b_un.b_addr = (caddr_t)loint(rap);
- 		tmscomphys.b_xmem = hiint(rap);
- 		tmscomphys.b_bcount = sizeof (tmscp);
- 		tmscomphys.b_flags = B_PHYS;
- #ifdef	UNIBUS_MAP
- 		mapalloc(&tmscomphys);
- #endif
- 		comaddr = ((u_int)tmscomphys.b_un.b_addr | 
- 				((long)tmscomphys.b_xmem << 16)) +
- 				sizeof (struct tmscp) * unit +
- 				(u_int)RINGBASE;
- 		sc->sc_ctab.b_un.b_addr = (caddr_t)loint(comaddr);
- 		sc->sc_ctab.b_xmem = hiint(comaddr);
- 		}
  
  	/*
  	 * Start the hardware initialization sequence.
--- 879,892 ----
  	register struct tmscp_softc *sc;
  {
  	register struct tmscpdevice *tmscpaddr;
! 	long adr;
  
! 	sc->sc_ivec = TMSvec + sc->sc_unit * 4;
  	sc->sc_ctab.b_active++;
+ 	adr = _iomap(tmscp[sc->sc_unit]) + (u_int)RINGBASE;
+ 	sc->sc_ctab.b_un.b_addr = (caddr_t)loint(adr);
+ 	sc->sc_ctab.b_xmem = hiint(adr);
  	tmscpaddr = sc->sc_addr;
  
  	/*
  	 * Start the hardware initialization sequence.
***************
*** 841,847 ****
  	return(1);
  }
  
- 
  /*
   * Start I/O operation
   * This code is convoluted.  The majority of it was copied from the uda driver.
--- 911,916 ----
***************
*** 850,864 ****
  tmsstart(sc)
  	register struct tmscp_softc *sc;
  {
- 	register struct buf *bp, *dp;
  	register struct mscp *mp;
  	register struct tms_info *tms;
  	struct   tmscpdevice *tmscpaddr;
! 	struct   tmscp *tm;
! 	int i, unit = sc - tmscp_softc;
! 	char ioctl;		/* flag: set true if its an IOCTL command */
  
! 	tm = &tmscp[unit];
       for(;;)
  	{
  	if ((dp = sc->sc_ctab.b_actf) == NULL)
--- 919,932 ----
  tmsstart(sc)
  	register struct tmscp_softc *sc;
  {
  	register struct mscp *mp;
+ 	register struct buf *bp, *dp;
  	register struct tms_info *tms;
  	struct   tmscpdevice *tmscpaddr;
! 	int i;
! 	segm seg5;
  
!      saveseg5(seg5);		/* save just once at top */
       for(;;)
  	{
  	if ((dp = sc->sc_ctab.b_actf) == NULL)
***************
*** 883,896 ****
  		}
  	sc->sc_ctab.b_active++;
  	tmscpaddr = (struct tmscpdevice *)sc->sc_addr;
! 	tms = &tms_info[TMSUNIT(bp->b_dev)];
  	if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN)
  		{
  		tprintf(tms->tms_ttyp,
! 		    "tms%d: hard error bn%ld\n",
! 		    minor(bp->b_dev)&03, bp->b_blkno);
! 		log(TMS_PRI, "tms%d: sa 0%o, state %d\n", unit,
! 				tmscpaddr->tmscpsa&0xffff, sc->sc_state);
  		(void)tkini(sc);
  		/* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */
  		break;
--- 951,964 ----
  		}
  	sc->sc_ctab.b_active++;
  	tmscpaddr = (struct tmscpdevice *)sc->sc_addr;
! 	tms = sc->sc_drives[TMSUNIT(bp->b_dev)];
  	if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN)
  		{
  		tprintf(tms->tms_ttyp,
! 		    "tms%d,%d: hard error bn%ld\n", sc->sc_unit,
! 		    TMSUNIT(bp->b_dev), bp->b_blkno);
! 		log(TMS_PRI, "tms%d,%d: sa 0%o, state %d\n", sc->sc_unit,
! 			TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa, sc->sc_state);
  		(void)tkini(sc);
  		/* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */
  		break;
***************
*** 900,938 ****
  	 * if a write command is done it will be detected in tmscprsp.
  	 */
  	tms->tms_lastiow = 0;
! 	if (tms->tms_online == 0)
  		{        /* not online */
  		if ((mp = tmscpgetcp(sc)) == NULL)
  			break;
  		mp->mscp_opcode = M_OP_ONLIN;
! 		mp->mscp_unit = 0;	/* ui->ui_slave; */
  		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;
  		if (tmscpaddr->tmscpsa&TMSCP_ERR)
! 			printf("tms%d fatal error (0%o)\n", unit,
! 					tmscpaddr->tmscpsa);
  		i = tmscpaddr->tmscpip;
  		continue;
  		}
- 	/*
- 	 * If command is an ioctl command then set the ioctl flag for later use.
- 	 * If not (i.e. it is a read or write) then attempt
- 	 * to set up a buffer pointer.
- 	 */
- 	ioctl = 0;
- 	if (bp == &sc->sc_cmdbuf)
- 		ioctl = 1;
  	if ((mp = tmscpgetcp(sc)) == NULL)
  		break;
  	mp->mscp_cmdref = (u_short)bp;		/* pointer to get back */
! 	mp->mscp_unit = 0;	/* ui->ui_slave; */
  	/*
  	 * If its an ioctl-type command then set up the appropriate
  	 * tmscp command;  by doing a switch on the "b_resid" field where
  	 * the command mneumonic is stored.
  	 */
! 	if (ioctl)
  		{
  #ifdef TMSCP_DEBUG
  		printd("tmsstart: doing ioctl cmd %d\n", bp->b_resid);
--- 968,1001 ----
  	 * if a write command is done it will be detected in tmscprsp.
  	 */
  	tms->tms_lastiow = 0;
! 	if (tms->tms_online == -1)
  		{        /* not online */
  		if ((mp = tmscpgetcp(sc)) == NULL)
  			break;
+ 		mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  		mp->mscp_opcode = M_OP_ONLIN;
! 		mp->mscp_unit = TMSUNIT(bp->b_dev);
  		dp->b_active = 2;
  		sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */
  		((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT;
  		if (tmscpaddr->tmscpsa&TMSCP_ERR)
! 			printf("tms%d,%d fatal error 0%o\n", sc->sc_unit,
! 					TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa);
! 		restorseg5(seg5);
  		i = tmscpaddr->tmscpip;
  		continue;
  		}
  	if ((mp = tmscpgetcp(sc)) == NULL)
  		break;
+ 	mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  	mp->mscp_cmdref = (u_short)bp;		/* pointer to get back */
! 	mp->mscp_unit = TMSUNIT(bp->b_dev);
  	/*
  	 * If its an ioctl-type command then set up the appropriate
  	 * tmscp command;  by doing a switch on the "b_resid" field where
  	 * the command mneumonic is stored.
  	 */
! 	if (bp == &sc->sc_cmdbuf)
  		{
  #ifdef TMSCP_DEBUG
  		printd("tmsstart: doing ioctl cmd %d\n", bp->b_resid);
***************
*** 1036,1042 ****
  			tms->tms_format = 0;
  			break;
  		default:
! 			printf("Bad ioctl on tms%d\n", unit);
  			/* Need a no-op. Reposition no amount */
  			mp->mscp_opcode = M_OP_REPOS;
  			break;
--- 1099,1106 ----
  			tms->tms_format = 0;
  			break;
  		default:
! 			printf("Bad ioctl on tms%d,%d\n", sc->sc_unit,
! 				TMSUNIT(bp->b_dev));
  			/* Need a no-op. Reposition no amount */
  			mp->mscp_opcode = M_OP_REPOS;
  			break;
***************
*** 1082,1088 ****
  	dp->av_back = bp;
  	if (tmscpaddr->tmscpsa&TMSCP_ERR)
  		{
! 		printf("tms%d: fatal error (0%o)\n",unit, tmscpaddr->tmscpsa);
  		(void)tkini(sc);
  		break;
  		}
--- 1146,1153 ----
  	dp->av_back = bp;
  	if (tmscpaddr->tmscpsa&TMSCP_ERR)
  		{
! 		printf("tms%d,%d: fatal error 0%o\n",sc->sc_unit, 
! 			TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa);
  		(void)tkini(sc);
  		break;
  		}
***************
*** 1089,1114 ****
      }   /* end for */
      /*
       * Check for response ring transitions lost in the
!      * Race condition
       */
      for (i = sc->sc_lastrsp;; i++)
  	    {
  	    i %= NRSP;
! 	    if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN)
  		    break;
! 	    tmscprsp(unit, tm, sc, i);
! 	    tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN;
  	    }
      sc->sc_lastrsp = i;
  }
  
  
  /*
!  * Process a response packet
   */
! tmscprsp(unit, tm, sc, i)
! 	int unit;
! 	register struct tmscp *tm;
  	register struct tmscp_softc *sc;
  	int i;
  {
--- 1154,1179 ----
      }   /* end for */
      /*
       * Check for response ring transitions lost in the
!      * Race condition.  Map SEG5 in case we escaped early from the for().
       */
+     mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
      for (i = sc->sc_lastrsp;; i++)
  	    {
  	    i %= NRSP;
! 	    if (sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN)
  		    break;
! 	    tmscprsp(sc, i);
! 	    sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN;
  	    }
      sc->sc_lastrsp = i;
+     restorseg5(seg5);
  }
  
  
  /*
!  * Process a response packet.  N.B.  Assumes SEG5 maps comm area for controller
   */
! tmscprsp(sc, i)
  	register struct tmscp_softc *sc;
  	int i;
  {
***************
*** 1117,1123 ****
  	struct buf *dp, *bp;
  	int st;
  
! 	mp = &tm->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 */
--- 1182,1188 ----
  	struct buf *dp, *bp;
  	int st;
  
! 	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 */
***************
*** 1124,1129 ****
--- 1189,1195 ----
  		return;
  #ifdef TMSCP_DEBUG
  	printd("tmscprsp, opcode 0%o status 0%o\n",mp->mscp_opcode,mp->mscp_status&M_ST_MASK);
+ 	printd("  SEG5: 0%o sc: 0%o mp: 0%o i: %d\n",*KDSA5, sc, mp, i);
  #endif	
  	/*
  	 * If it's an error log message (datagram),
***************
*** 1131,1137 ****
  	 */
  	if ((mp->mscp_header.tmscp_credits & 0xf0) == 0x10)
  		{	/* check */
! 		tmserror(unit, (struct mslg *)mp);
  		return;
  		}
  	st = mp->mscp_status&M_ST_MASK;
--- 1197,1203 ----
  	 */
  	if ((mp->mscp_header.tmscp_credits & 0xf0) == 0x10)
  		{	/* check */
! 		tmserror(sc->sc_unit, (struct mslg *)mp);
  		return;
  		}
  	st = mp->mscp_status&M_ST_MASK;
***************
*** 1156,1164 ****
  		wakeup((caddr_t)&sc->sc_ctab);
  		return;
  		}
! 	if (mp->mscp_unit >= NTMS)
  		return;
! 	tms = &tms_info[unit];
  	/*
  	 * Save endcode, endflags, and status for mtioctl get unit status.
  	 * NOTE: Don't do this on Clear serious exception (reposition no-op);
--- 1222,1232 ----
  		wakeup((caddr_t)&sc->sc_ctab);
  		return;
  		}
! 	if (mp->mscp_unit >= 4)
  		return;
! 	tms = sc->sc_drives[mp->mscp_unit];
! 	if (!tms)		/* unopened unit coming online - ignore it */
! 		return;
  	/*
  	 * Save endcode, endflags, and status for mtioctl get unit status.
  	 * NOTE: Don't do this on Clear serious exception (reposition no-op);
***************
*** 1190,1207 ****
  			sc->sc_ctab.b_actl = dp;
  			tms->tms_online = 1;       /* mark it online */
  			tms->tms_dsize=(daddr_t)mp->mscp_maxwrt;
- #ifdef TMSCP_DEBUG
- 			printd("tmscprsp: unit %d online\n", mp->mscp_unit);
- #endif			
  			/* 
  			 * This define decodes the Media type identifier
  			 */
- #	        	define F_to_C(x,i)     ( ((x)->mscp_mediaid) >> (i*5+7) & 0x1f ? ( ( (((x)->mscp_mediaid) >>( i*5 + 7)) & 0x1f) + 'A' - 1): ' ')
  #ifdef TMSCP_DEBUG
! 			printd("tmscprsp: unit %d online %x %c%c %c%c%c%d\n"
! 				,mp->mscp_unit, mp->mscp_mediaid ,F_to_C(mp,4)
! 				,F_to_C(mp,3), F_to_C(mp,2)
! 				,F_to_C(mp,1), F_to_C(mp,0), mp->mscp_mediaid & 0x7f);
  #endif				
  			dp->b_active = 1;
  			}	/* end if st == M_ST_SUCC */
--- 1258,1270 ----
  			sc->sc_ctab.b_actl = dp;
  			tms->tms_online = 1;       /* mark it online */
  			tms->tms_dsize=(daddr_t)mp->mscp_maxwrt;
  			/* 
  			 * This define decodes the Media type identifier
  			 */
  #ifdef TMSCP_DEBUG
! 			printd("tmscprsp: %d,%d online mediaid 0x%lx format 0x%x\n",
! 				sc->sc_unit, mp->mscp_unit, mp->mscp_mediaid,
! 				mp->mscp_format);
  #endif				
  			dp->b_active = 1;
  			}	/* end if st == M_ST_SUCC */
***************
*** 1209,1219 ****
  			{
  			if (bp = dp->b_actf)
  				tprintf(tms->tms_ttyp,
! 				    "tms%d: hard error bn%ld: OFFLINE\n",
! 				    minor(bp->b_dev)&03, bp->b_blkno);
  			else
  				tprintf(tms->tms_ttyp,
! 				    "tms%d: hard error: OFFLINE\n", unit);
  			while (bp = dp->b_actf)
  				{
  				dp->b_actf = bp->av_forw;
--- 1272,1283 ----
  			{
  			if (bp = dp->b_actf)
  				tprintf(tms->tms_ttyp,
! 				    "tms%d,%d: hard error bn%ld: OFFLINE\n",
! 				    sc->sc_unit, mp->mscp_unit, bp->b_blkno);
  			else
  				tprintf(tms->tms_ttyp,
! 				    "tms%d,%d: hard error: OFFLINE\n", 
! 				    sc->sc_unit, mp->mscp_unit);
  			while (bp = dp->b_actf)
  				{
  				dp->b_actf = bp->av_forw;
***************
*** 1228,1238 ****
  	/*
  	 * The AVAILABLE ATTENTION message occurs when the
  	 * unit becomes available after loading,
! 	 * marking the unit offline (ui_flags = 0) will force an
  	 * online command prior to using the unit.
  	 */
  	case M_OP_AVATN:
! 		tms->tms_online = 0;
  		tms->tms_type = mp->mscp_mediaid;
  		break;
  	case M_OP_END:
--- 1292,1302 ----
  	/*
  	 * The AVAILABLE ATTENTION message occurs when the
  	 * unit becomes available after loading,
! 	 * marking the unit offline (tms_online = -1) will force an
  	 * online command prior to using the unit.
  	 */
  	case M_OP_AVATN:
! 		tms->tms_online = -1;
  		tms->tms_type = mp->mscp_mediaid;
  		break;
  	case M_OP_END:
***************
*** 1246,1253 ****
  		 * of 0200 instead of the 0241 (read) that was expected.
  		 */
  			
! 		printf("tms%d: invalid cmd, endcode = %o, status=%o\n",
! 			unit, mp->mscp_opcode, st);
  		bp = (struct buf *)mp->mscp_cmdref;
  		/*
  		 * Unlink buffer from I/O wait queue.
--- 1310,1318 ----
  		 * of 0200 instead of the 0241 (read) that was expected.
  		 */
  			
! 		printf("tms%d,%d: invalid cmd, endcode = %o, status=%o\n",
! 			sc->sc_unit, mp->mscp_unit, mp->mscp_opcode, st);
! common:	/* GTUNT finishes up thru here too */
  		bp = (struct buf *)mp->mscp_cmdref;
  		/*
  		 * Unlink buffer from I/O wait queue.
***************
*** 1272,1279 ****
  	 * issued.  For the ioctl, "rewoffl", a tmscp AVAILABLE command is
  	 * done with the UNLOAD modifier.  This performs a rewind, followed
  	 * by marking the unit offline.  So mark the unit offline
! 	 * software wise as well (ui_flags = 0 and 
! 	 * tms->tms_openf = 0).
  	 */
  	case M_OP_AVAIL|M_OP_END:
  #ifdef TMSCP_DEBUG
--- 1337,1343 ----
  	 * issued.  For the ioctl, "rewoffl", a tmscp AVAILABLE command is
  	 * done with the UNLOAD modifier.  This performs a rewind, followed
  	 * by marking the unit offline.  So mark the unit offline
! 	 * software wise as well (tms->tms_online = -1 and tms_open = 0).
  	 */
  	case M_OP_AVAIL|M_OP_END:
  #ifdef TMSCP_DEBUG
***************
*** 1289,1295 ****
  		dp->b_qsize--;
  		if (st == M_ST_OFFLN || st == M_ST_AVLBL)
  			{
! 			tms->tms_online = 0;       /* mark unit offline */
  			tms->tms_openf = 0;
  			tms->tms_type = mp->mscp_mediaid;
  			/*
--- 1353,1359 ----
  		dp->b_qsize--;
  		if (st == M_ST_OFFLN || st == M_ST_AVLBL)
  			{
! 			tms->tms_online = -1;       /* mark unit offline */
  			tms->tms_openf = 0;
  			tms->tms_type = mp->mscp_mediaid;
  			/*
***************
*** 1320,1329 ****
  			if (st != M_ST_TAPEM)
  				{
  				tprintf(tms->tms_ttyp,
! 				    "tms%d: hard error bn%ld\n",minor(bp->b_dev)&03, bp->b_blkno);
! 				tprintf(tms->tms_ttyp, "status:0%o flags:0%o\n",
! 				     (mp->mscp_status & 177740)>>5, mp->mscp_flags);
! 				errinfo(st);		/* produces more info */
  				bp->b_flags |= B_ERROR;
  				}
  			else
--- 1384,1392 ----
  			if (st != M_ST_TAPEM)
  				{
  				tprintf(tms->tms_ttyp,
! 				"tms%d,%d: hard error bn%ld status:0%o flags:0%o\n",
! 				    sc->sc_unit, mp->mscp_unit, bp->b_blkno,
! 				    mp->mscp_status >> 5, mp->mscp_flags);
  				bp->b_flags |= B_ERROR;
  				}
  			else
***************
*** 1349,1450 ****
  	case M_OP_GTUNT|M_OP_END:
  #ifdef TMSCP_DEBUG
  		printd("tmscprsp: GTUNT end packet status = 0%o\n",st);
! 		printd("tmscprsp: unit %d mediaid %x %c%c %c%c%c%d %x %x t=%d\n"
! 		    ,mp->mscp_unit, mp->mscp_mediaid
! 		    ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)
! 		    ,F_to_C(mp,1),F_to_C(mp,0)
! 		    ,mp->mscp_mediaid & 0x7f
  		    ,mp->mscp_unitid.val[0]
  		    ,mp->mscp_unitid.val[1]
  		    ,mp->mscp_format);
! #endif		
  		tms->tms_type = mp->mscp_mediaid;
  		tms->tms_fmtmenu = mp->mscp_fmtmenu;
  		tms->tms_unitflgs = mp->mscp_unitflgs;
! 		break;
  
  	default:
! 		printf("tms unknown packet\n");
! 		tmserror(unit, (struct mslg *)mp);
  	}	/* end switch mp->mscp_opcode */
  }
  
- 
- /* 
-  * Give a meaningful error when the mscp_status field returns an error code.
-  */
- 
- errinfo(st)
- 	int st;			/* the status code */
- {
- 	switch(st) {
- 	case M_ST_ICMD:
- 		printf("invalid command\n");
- 		break;
- 	case M_ST_ABRTD:
- 		printf("command aborted\n");
- 		break;
- 	case M_ST_OFFLN:
- 		printf("unit offline\n");
- 		break;
- 	case M_ST_WRTPR:
- 		printf("unit write protected\n");
- 		break;
- 	case M_ST_COMP:
- 		printf("compare error\n");
- 		break;
- 	case M_ST_DATA:
- 		printf("data error\n");
- 		break;
- 	case M_ST_HSTBF:
- 		printf("host buffer access error\n");
- 		break;
- 	case M_ST_CNTLR:
- 		printf("controller error\n");
- 		break;
- 	case M_ST_DRIVE:
- 		printf("drive error\n");
- 		break;
- 	case M_ST_FMTER:
- 		printf("formatter error\n");
- 		break;
- 	case M_ST_BOT:
- 		printf("BOT encountered\n");
- 		break;
- 	case M_ST_TAPEM:
- 		printf("tape mark encountered\n");
- 		break;
- 	case M_ST_RDTRN:
- 		printf("record data truncated\n");
- 		break;
- 	case M_ST_PLOST:
- 		printf("position lost\n");
- 		break;
- 	case M_ST_SEX:
- 		printf("serious exception\n");
- 		break;
- 	case M_ST_LED:
- 		printf("LEOT detected\n");
- 		break;
- 	}
- }
- 
  /*
-  * Return the physical address corresponding to a virtual data space address.
-  * On a separate I&D CPU this is a noop, but it's only called when the first
-  * controller is initialized and on a dump.
-  */
- long
- tmsphys(vaddr)
- 	register	unsigned	vaddr;
- {
- 	register	unsigned	click;
- 
- 	click = (sep_id ? KDSA0 : KISA0)[(vaddr >> 13) & 07];
- 	return(((long)click << 6) + (vaddr & 017777));
- }
- 
- /*
   * Manage buffers and perform block mode read and write operations.
   */
  
--- 1412,1435 ----
  	case M_OP_GTUNT|M_OP_END:
  #ifdef TMSCP_DEBUG
  		printd("tmscprsp: GTUNT end packet status = 0%o\n",st);
! 		printd("tmscprsp: %d,%d mediaid 0x%lx %x %x format=%d\n",
! 		    sc->sc_unit,mp->mscp_unit, mp->mscp_mediaid
  		    ,mp->mscp_unitid.val[0]
  		    ,mp->mscp_unitid.val[1]
  		    ,mp->mscp_format);
! #endif
  		tms->tms_type = mp->mscp_mediaid;
  		tms->tms_fmtmenu = mp->mscp_fmtmenu;
  		tms->tms_unitflgs = mp->mscp_unitflgs;
! 		goto common;	/* need to dequeue buffer and do iodone() */
  
  	default:
! 		printf("tms %d,%d unknown packet\n", sc->sc_unit,mp->mscp_unit);
! 		tmserror(sc->sc_unit, (struct mslg *)mp);
  	}	/* end switch mp->mscp_opcode */
  }
  
  /*
   * Manage buffers and perform block mode read and write operations.
   */
  
***************
*** 1454,1479 ****
  	register struct buf *dp;
  	register struct tmscp_softc *sc;
  	struct	tms_info *tms;
! 	int unit = TMSUNIT(bp->b_dev);
  	int s;
  
! 	if (unit >= NTMS)
  		{
- #ifdef TMSCP_DEBUG
- 		printd ("tmscpstrategy: bad unit # %d\n",unit);
- #endif
  		bp->b_flags |= B_ERROR;
  		iodone(bp);
  		return;
  		}
- 	sc = &tmscp_softc[unit];
- 	tms = &tms_info[unit];
- 	if (tms->tms_online == 0)
- 		{
- 		bp->b_flags |= B_ERROR;
- 		iodone(bp);
- 		return;
- 		}
  #ifdef	UNIBUS_MAP
  	mapalloc(bp);
  #endif
--- 1439,1455 ----
  	register struct buf *dp;
  	register struct tmscp_softc *sc;
  	struct	tms_info *tms;
! 	int ctlr = TMSCTLR(bp->b_dev);
  	int s;
  
! 	sc = &tmscp_softc[ctlr];
! 	tms = sc->sc_drives[TMSUNIT(bp->b_dev)];
! 	if (!tms || tms->tms_online != 1)
  		{
  		bp->b_flags |= B_ERROR;
  		iodone(bp);
  		return;
  		}
  #ifdef	UNIBUS_MAP
  	mapalloc(bp);
  #endif
***************
*** 1526,1555 ****
  	register struct	mscp	*mp;
  	daddr_t bn, dumpsize;
  	long paddr, maddr;
! 	int unit, count;
  	struct	ubmap *ubp;
  
! 	unit = TMSUNIT(dev);
! 	if (unit >= NTMS)
  		return (ENXIO);
! 	sc = &tmscp_softc[unit];
  	tmscpaddr = sc->sc_addr;
  	if (tmscpaddr == NULL)
  		return(ENXIO);
  
  #ifdef	UNIBUS_MAP
  	if (ubmap) {
  		ubp = UBMAP;
! 		ubp->ub_lo = loint(tmscomphys.b_un.b_addr);
! 		ubp->ub_hi = hiint(tmscomphys.b_xmem);
! 		tmscomphys.b_un.b_addr = NULL;
! 		tmscomphys.b_xmem = 0;
  	}
  #endif
! 	paddr = (u_int)tmscomphys.b_un.b_addr +
! 			((long)tmscomphys.b_xmem << 16) +
! 			(u_int)RINGBASE;
! 	sc->sc_com = tmscp;
  	mp = sc->sc_com->tmscp_rsp;
  	sc->sc_com->tmscp_ca.ca_cmdint = sc->sc_com->tmscp_ca.ca_rspint = 0;
  	bzero(mp, 2 * sizeof (*mp));
--- 1502,1529 ----
  	register struct	mscp	*mp;
  	daddr_t bn, dumpsize;
  	long paddr, maddr;
! 	int unit = TMSUNIT(dev), count, ctlr = TMSCTLR(dev);
  	struct	ubmap *ubp;
+ 	segm seg5;
  
! 	if (ctlr >= NTMSCP)
  		return (ENXIO);
! 	sc = &tmscp_softc[ctlr];
  	tmscpaddr = sc->sc_addr;
  	if (tmscpaddr == NULL)
  		return(ENXIO);
  
+ 	paddr = _iomap(tmscp[sc->sc_unit]);
  #ifdef	UNIBUS_MAP
  	if (ubmap) {
  		ubp = UBMAP;
! 		ubp->ub_lo = loint(paddr);
! 		ubp->ub_hi = hiint(paddr);
  	}
  #endif
! 	paddr += RINGBASE;
! 	saveseg5(seg5);
! 	mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
  	mp = sc->sc_com->tmscp_rsp;
  	sc->sc_com->tmscp_ca.ca_cmdint = sc->sc_com->tmscp_ca.ca_rspint = 0;
  	bzero(mp, 2 * sizeof (*mp));
***************
*** 1573,1579 ****
  	if (tmscpcmd(M_OP_STCON, unit, sc) == 0) {
  		return(EFAULT);
  	}
! 	sc->sc_com->tmscp_cmd[0].mscp_unit = 0;		/* ui->ui_slave */
  	if (tmscpcmd(M_OP_ONLIN, unit, sc) == 0) {
  		return(EFAULT);
  	}
--- 1547,1553 ----
  	if (tmscpcmd(M_OP_STCON, unit, sc) == 0) {
  		return(EFAULT);
  	}
! 	sc->sc_com->tmscp_cmd[0].mscp_unit = unit;
  	if (tmscpcmd(M_OP_ONLIN, unit, sc) == 0) {
  		return(EFAULT);
  	}
***************
*** 1604,1609 ****
--- 1578,1584 ----
  		return(EIO);
  	paddr += (DBSIZE << PGSHIFT);
  	}
+ 	restorseg5(seg5);
  	return (0);
  }
  
***************
*** 1625,1637 ****
  	rlp = &sc->sc_com->tmscp_ca.ca_rspdsc[0];
  
  	cmp->mscp_opcode = op;
! 	cmp->mscp_unit = 0;		/* 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)
! 		printf("tms fatal error (0%o)\n", sc->sc_addr->tmscpsa);
  	i = sc->sc_addr->tmscpip;
  
  	while ((rlp[1].hsh & TMSCP_INT) == 0)
--- 1600,1613 ----
  	rlp = &sc->sc_com->tmscp_ca.ca_rspdsc[0];
  
  	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)
! 		printf("tms%d,%d fatal error 0%o\n", sc->sc_unit, unit,
! 			sc->sc_addr->tmscpsa);
  	i = sc->sc_addr->tmscpip;
  
  	while ((rlp[1].hsh & TMSCP_INT) == 0)
***************
*** 1644,1650 ****
  	if (rmp->mscp_opcode != (op|M_OP_END) ||
  	    (rmp->mscp_status&M_ST_MASK) != M_ST_SUCC)
  		{
! 		printf("error: com %d opc 0x%x stat 0x%x\ndump ", op,
  			rmp->mscp_opcode, rmp->mscp_status);
  		return(0);
  		}
--- 1620,1626 ----
  	if (rmp->mscp_opcode != (op|M_OP_END) ||
  	    (rmp->mscp_status&M_ST_MASK) != M_ST_SUCC)
  		{
! 		printf("err: com %d opc 0x%x stat 0x%x\ndump ", op,
  			rmp->mscp_opcode, rmp->mscp_status);
  		return(0);
  		}
***************
*** 1652,1689 ****
  }
  #endif TMSCP_DUMP
  
! /*
!  * Perform raw read
!  */
  
  tmscpread(dev, uio)
! 	dev_t dev;
  	struct uio *uio;
  {
! 	register int unit = TMSUNIT(dev);
! 
! 	if (unit >= NTMS)
! 		return (ENXIO);
! 	return (physio(tmscpstrategy, &tms_info[unit].tms_rtab, dev, B_READ, BYTE, uio));
  }
  
- 
- /*
-  * Perform raw write
-  */
- 
  tmscpwrite(dev, uio)
! 	dev_t dev;
  	struct uio *uio;
  {
! 	register int unit = TMSUNIT(dev);
! 
! 	if (unit >= NTMS)
! 		return (ENXIO);
! 	return (physio(tmscpstrategy, &tms_info[unit].tms_rtab, dev, B_WRITE, BYTE, uio));
  }
  
- 
  /*
   * Catch ioctl commands, and call the "command" routine to do them.
   */
--- 1628,1656 ----
  }
  #endif TMSCP_DUMP
  
! struct buf *
! tmsrtab(dev)
! 	register dev_t dev;
! {
! 	register struct tmscp_softc *sc = &tmscp_softc[TMSCTLR(dev)];
  
+ 	return(&sc->sc_drives[TMSUNIT(dev)]->tms_rtab);
+ }
+ 
  tmscpread(dev, uio)
! 	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(tmscpstrategy, tmsrtab(dev), dev, B_READ, BYTE, uio));
  }
  
  tmscpwrite(dev, uio)
! 	register dev_t dev;
  	struct uio *uio;
  {
! 	return(physio(tmscpstrategy, tmsrtab(dev), dev, B_WRITE, BYTE, uio));
  }
  
  /*
   * Catch ioctl commands, and call the "command" routine to do them.
   */
***************
*** 1695,1701 ****
  	caddr_t data;
  	int flag;
  {
! 	register struct buf *bp = &tmscp_softc[TMSUNIT(dev)].sc_cmdbuf;
  	register callcount;	/* number of times to call cmd routine */
  	register struct tms_info *tms;
  	int fcount;		/* number of files (or records) to space */
--- 1662,1669 ----
  	caddr_t data;
  	int flag;
  {
! 	struct tmscp_softc *sc = &tmscp_softc[TMSCTLR(dev)];
! 	register struct buf *bp = &sc->sc_cmdbuf;
  	register callcount;	/* number of times to call cmd routine */
  	register struct tms_info *tms;
  	int fcount;		/* number of files (or records) to space */
***************
*** 1747,1753 ****
  		/*
  		 * Return status info associated with the particular UNIT.
  		 */
! 		tms = &tms_info[TMSUNIT(dev)];
  		mtget = (struct mtget *)data;
  		mtget->mt_type = MT_ISTMSCP;
  		mtget->mt_dsreg = tms->tms_flags << 8;
--- 1715,1723 ----
  		/*
  		 * Return status info associated with the particular UNIT.
  		 */
! 		tms = sc->sc_drives[TMSUNIT(dev)];
! 		if (!tms)
! 			return(ENXIO);
  		mtget = (struct mtget *)data;
  		mtget->mt_type = MT_ISTMSCP;
  		mtget->mt_dsreg = tms->tms_flags << 8;
***************
*** 1770,1777 ****
   * send message to an error logger.
   */
  
! tmserror(unit, mp)
! 	register int unit;
  	register struct mslg *mp;
  {
  	register i;
--- 1740,1747 ----
   * send message to an error logger.
   */
  
! tmserror(ctlr, mp)
! 	register int ctlr;
  	register struct mslg *mp;
  {
  	register i;
***************
*** 1780,1803 ****
  	printd("tmserror:\n");
  #endif
  	if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
! 		log(TMS_PRI, "tms%d: %s error, ", unit,
  		mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
  
  	switch (mp->mslg_format) {
  
  	case M_FM_CNTERR:
! 		log(TMS_PRI, "controller error, event 0%o\n", mp->mslg_event);
  		break;
  	case M_FM_BUSADDR:
! 		log(TMS_PRI, "host memory access error, event 0%o, addr 0%o\n",
  			mp->mslg_event, mp->mslg_busaddr);
  		break;
  	case M_FM_TAPETRN:
! 		log(TMS_PRI, "tape transfer error, unit %d, grp 0x%x, event 0%o\n",
  			mp->mslg_unit, mp->mslg_group, mp->mslg_event);
  		break;
  	case M_FM_STIERR:
! 		log(TMS_PRI, "STI error, unit %d, event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  #ifdef notdef
  		/* too painful to do with log() */
--- 1750,1773 ----
  	printd("tmserror:\n");
  #endif
  	if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
! 		log(TMS_PRI, "tms%d,%d: %s err, ", ctlr, mp->mslg_unit,
  		mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
  
  	switch (mp->mslg_format) {
  
  	case M_FM_CNTERR:
! 		log(TMS_PRI, "ctlr err, event 0%o\n", mp->mslg_event);
  		break;
  	case M_FM_BUSADDR:
! 		log(TMS_PRI, "host memory access err, event 0%o, addr 0%o\n",
  			mp->mslg_event, mp->mslg_busaddr);
  		break;
  	case M_FM_TAPETRN:
! 		log(TMS_PRI, "tape transfer err, unit %d, grp 0x%x, event 0%o\n",
  			mp->mslg_unit, mp->mslg_group, mp->mslg_event);
  		break;
  	case M_FM_STIERR:
! 		log(TMS_PRI, "STI err, unit %d, event 0%o\n",
  			mp->mslg_unit, mp->mslg_event);
  #ifdef notdef
  		/* too painful to do with log() */
***************
*** 1815,1822 ****
  			mp->mslg_unit, mp->mslg_event);
  		break;
  	default:
! 		log(TMS_PRI, "unknown error, unit %d, format 0%o, event 0%o\n",
! 			mp->mslg_unit, mp->mslg_format, mp->mslg_event);
  	}
  
  	if (tmscperror)
--- 1785,1792 ----
  			mp->mslg_unit, mp->mslg_event);
  		break;
  	default:
! 		log(TMS_PRI, "unknown err, %d,%d, format 0%o, event 0%o\n",
! 			ctlr,mp->mslg_unit, mp->mslg_format, mp->mslg_event);
  	}
  
  	if (tmscperror)
***************
*** 1828,1849 ****
  		printf("\n");
  		}
  }
! 
! #ifdef	notSMS
! tprintf(pri,fmt,a)
! 	int pri;
! 	char *fmt;
! 	unsigned a;
! 	{
! 	prf(fmt, &a, 5);	/* 5 = TOLOG|TOCONSOLE */
! 	}
! 
! log(pri,fmt,a)
! 	int pri;
! 	char *fmt;
! 	unsigned a;
! 	{
! 	prf(fmt, &a, 5);
! 	}
! #endif	notSMS
! #endif
--- 1798,1801 ----
  		printf("\n");
  		}
  }
! #endif NTMSCP



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