1: #define TMSDEBUG    1
   2: 
   3: /*	@(#)tmscp.c	1.12 (2.11BSD) 1999/2/25 */
   4: 
   5: #if !defined(lint) && defined(DOSCCS)
   6: static  char    *sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
   7: #endif
   8: 
   9: /************************************************************************
  10:  *        Licensed from Digital Equipment Corporation 			*
  11:  *                       Copyright (c) 					*
  12:  *               Digital Equipment Corporation				*
  13:  *                   Maynard, Massachusetts 				*
  14:  *                         1985, 1986 					*
  15:  *                    All rights reserved. 				*
  16:  *									*
  17:  *        The Information in this software is subject to change 	*
  18:  *   without notice and should not be construed as a commitment 	*
  19:  *   by  Digital  Equipment  Corporation.   Digital   makes  no 	*
  20:  *   representations about the suitability of this software for 	*
  21:  *   any purpose.  It is supplied "As Is" without expressed  or 	*
  22:  *   implied  warranty. 						*
  23:  *									*
  24:  *        If the Regents of the University of California or its 	*
  25:  *   licensees modify the software in a manner creating  		*
  26:  *   diriviative copyright rights, appropriate copyright  		*
  27:  *   legends may be placed on  the drivative work in addition  		*
  28:  *   to that set forth above. 						*
  29:  ************************************************************************
  30:  *
  31:  * tmscp.c - TMSCP (TK50/TU81) tape device driver
  32:  *
  33:  * Modification History:
  34:  * 25-Feb-99 - sms
  35:  *	Fix density selection to preserve the high byte of m_format.  This
  36:  *	is required devices (such as the TK70) which have a nonzero value
  37:  *	in this field.
  38:  *
  39:  * 22-Feb-99 - sms
  40:  *	Add timeout logic to tmscpcommand to catch hardware going catatonic.
  41:  *	When tmscpcommand() was first created the only use was to issue a
  42:  *	nonblocking rewind upon close.  Tmscpcommand is now called for many
  43:  *	other functions some of which can leave a process (and the drive) hung
  44:  *	unless a timeout is done.
  45:  *
  46:  *	Remove special treatment of OFFLINE and AVLBL status codes in
  47:  *	tms_iodone().  The code is suspected of having been a bug even in
  48:  *	its old location but is definitely causing problems now - if a read
  49:  *	completes with a 'AVLBL' status the drive is hung because an iodone()
  50:  *	is never performed.
  51:  *
  52:  *	Minor cleanup done thruout (reduce D space consumption ,etc).
  53:  *
  54:  * 24-Apr-98 - sms
  55:  *	An incorrect pointer was being passed to tms_iodone() from tmscprsp()
  56:  *	when dealing with the 'invalid endcode' case.  While that value should
  57:  * 	never be generated by normal hardware the kernel should not panic.
  58:  *
  59:  * 07-Mar-98 - sms
  60:  *	Fix a bug that caused EOM to be 'sticky'.  Once EndOfMedia was detected
  61:  *	the only way to clear it was to unload and reload the tape.  Remove
  62:  *	unused flag definitions.  Only use a single 'written' flag instead of
  63:  *	two (one in tms_flags and another in Tflags).
  64:  *
  65:  * 01-Feb-98 - sms
  66:  *	Initially the thought was the driver was broken sometime around June
  67:  *	1996.  After adding additional logging and the 'sysctl' interface it
  68:  *	was discovered (eventually after several long nights) that both my
  69:  *	TK50 and another person's TU81+ had developed hardware problems.  The
  70:  *	better logging and sysctl changes were retained for future use ;)
  71:  *
  72:  *	Failure to 'online' a drive was changed to return EIO instead of ENXIO
  73:  *	because 'device not configured' means the drive is not present.
  74:  *
  75:  *	A 'sysctl' interface was added so that 'tmscpprintf' could be changed
  76:  *	without rebooting/recompiling the system.  Also sysctl can be used to
  77:  *	set the cache on/off status even if a tape is not at the load point -
  78:  *	the setting takes effect on the next open().
  79:  *
  80:  * 14-May-96 - sms
  81:  *	Missing parens caused mtflush,mtcache,mtnocache to be always skipped.
  82:  *	The use cache bit was being cleared in tmscpopen(). The use cache bit
  83:  *	is sticky in that once set via MTCACHE it stays set until cleared by
  84:  *	MTNOCACHE.
  85:  *
  86:  * 14-Dec-95 - sms@wlv...
  87:  *	Success!  But the size of the driver is even more of a problem now.
  88:  *	If the crash dump option is defined the driver could exceed the max
  89:  *	size permitted for an overlay.  The 'tmsdump' routine was moved to
  90:  *	a separate file.  This driver almost always must be in an overlay
  91:  *	by itself now.
  92:  *
  93:  * 08-Dec-95 - sms@wlv...
  94:  *	Begin serious surgery on this driver.  The goals are: 1) to correctly
  95:  *	handle TU81/81+ drives (do not set density unless at BOT), 2) support
  96:  *	use of the cache on drives which implement it (TU81+), 3) improve
  97:  *	error detection and reporting, 4) improve readability by replacing
  98:  *	multipage 'switch' statements with calls to functions, 5) make it
  99:  *	easier to add new capabilities and fix problems without wholescale
 100:  *	changes again.
 101:  *
 102:  * 30-Nov-95 - sms@wlv...
 103:  *	Experiment to see if M_MD_IMMED being set for the rewind on close
 104:  *	obviates the need for skipping the iowait().  Success - only 2 ticks
 105:  *	elapse doing the iowait!.
 106:  *
 107:  * 02-Jan-93 - sms@wlv. [2.11BSD]
 108:  *	Remove unibus map ifdefs and rely on run time testing of 'ubmap' which
 109:  * 	does the right thing and makes kernels easier to move between machines.
 110:  *
 111:  * 20-Nov-92 - sms@wlv.iipo.gtegsc.com [2.11BSD]
 112:  *	Add tmsVec() for autoconfig to use in passing the vector from /etc/dtab
 113:  *	to this driver.  The previous scheme of having a fixed vector with
 114:  *	all TMSCP vectors contiguous has been removed.
 115:  *
 116:  * 23-May-91 - sms@wlv.iipo.gtegsc.com [2.11BSD]
 117:  *	Minor typo in the multicontroller support fixed.  Major overhaul
 118:  *	of the density selection, apparently some TMSCP controllers
 119:  *	do not treat 0 in the mscp_format word as meaning the highest
 120:  *	density, instead leaving the drive in the current/last-used
 121:  *	density.
 122:  *
 123:  * 29-Mar-91 - sms@wlv.iipo.gtegsc.com [2.11BSD]
 124:  *	Major changes to 1) support multiple drives per controller
 125:  *	(the maximum number of drives per controller is 4 for now in order
 126:  *	to maximize compatibility with existing minor device numbers - the
 127:  *	norewind and density bit stay in the same place) and 2) more
 128:  *	importantly reduce the bloat of this driver.  The command
 129:  *	packet area is now allocated from an external heap setup at boot
 130:  *	time (the MSCP, ra.c driver also does this).  Allocating from an
 131:  * 	external arena save approximately 2kb of kernel D space PER CONTROLLER
 132:  *	and costs little in speed because the amount of remapping involved is
 133:  *	quite small.
 134:  *
 135:  *	The 'errinfo' routine was removed in the interest of space savings,
 136:  *	the error code was already being printed out in hex and it's not
 137:  *	worth eating up another 250 or so bytes of kernel D space to pretty
 138:  *	print messages for which tmscp.h provides the cross reference (I space
 139:  *	is also saved by not printing the messages).  Besides, the ra.c (MSCP)
 140:  *	driver doesn't do it and it is worth a degree of non 4.3BSD verisimility
 141:  *	to save a significant amount of space.
 142:  *
 143:  *	The tms_type field should have been a 'long' (mediatype).  Since the
 144:  *	drives are not probed at autoconfigure time a GTUNT (TMS_SENSE) command
 145:  *	is done at open() time to fetch the format/density menu and unit flags.
 146:  *	iodone() proccessing was missing for the GTUNT function in tmscprsp()
 147:  *	causing hangs in both open and ioctl functions.
 148:  *
 149:  *	Multiple controller support made to work, the top 2 bits of the minor
 150:  *	device number are used to designate the controller, thus there is
 151:  *	a maximum of 4 TMSCP controllers per system.
 152:  *
 153:  * 17-Jun-90,14Aug90 - sms@wlv.iipo.gtegsc.com
 154:  *	Began porting to 2.10.1BSD/2.11BSD.  Multiple drives per controller
 155:  *	NOT supported, although multiple controllers are (maybe).  Programmable
 156:  *	vectors don't work very well with the autoconfigure scheme in use.
 157:  *	the define TMSCP_VEC will have to be adjusted in tms.h (see
 158:  *	conf/config and the sample config files).  For patching purposes
 159:  *	the global "TMSvec" is declared and initialized with TMSCP_VEC.
 160:  *
 161:  * 06-Jan-86 - afd
 162:  *	Changed the probe routine to use DELAY (not TODR).  This now
 163:  *	works for MicroVAXen as well.  This eliminates the busy-wait
 164:  *	for MicroVAXen so a dead TK50 controller will not hang autoconf.
 165:  *
 166:  * 06-Dec-85 - afd
 167:  *	Fixed a bug in density selection.  The "set unit characteristics"
 168:  *	command to select density, was clearing the "unit flags" field
 169:  *	where the CACHE bit was for TU81-E.  Now the unit's "format" and
 170:  *	"unitflgs" are saved in tms_info struct.  And are used on STUNT
 171:  *	commands.
 172:  *
 173:  * 19-Oct-85 - afd
 174:  *	Added support to the open routine to allow drives to be opened
 175:  *	for low density (800 or 1600 bpi) use.  When the slave routine
 176:  *	initiates a "get-unit-char" cmd, the format menu for the unit
 177:  *	is saved in the tms_info structure. The format menu is used in the
 178:  *	start routine to select the proper low density.
 179:  *
 180:  * 02-Oct-85 - afd
 181:  *	When a tmscp-type controller is initializing, it is possible for
 182:  *	the sa reg to become 0 between states.  Thus the init code in
 183:  *	the interrupt routine had to be modified to reflect this.
 184:  *
 185:  * 21-Sep-85 - afd
 186:  *	The TK50 declares a serious exception when a tape mark is encountered.
 187:  *	This causes problems to dd (& other UN*X utilities).  So a flag
 188:  *	is set in the rsp() routine when a tape mark is encountered.  If
 189:  *	this flag is set, the start() routine appends the Clear Serious
 190:  *	Exception modifier to the next command.
 191:  *
 192:  * 03-Sep-85 -- jaw
 193:  *	messed up previous edit..
 194:  *
 195:  * 29-Aug-85 - jaw
 196:  *	fixed bugs in 8200 and 750 buffered datapath handling.
 197:  *
 198:  * 06-Aug-85 - afd
 199:  *   1. When repositioning records or files, the count of items skipped
 200:  *	does NOT HAVE to be returned by controllers (& the TU81 doesn't).
 201:  *	So tmscprsp() had to be modified to stop reporting
 202:  *	residual count errors on reposition commands.
 203:  *
 204:  *   2. Fixed bug in the open routine which allowed multiple opens.
 205:  *
 206:  * 18-Jul-85 - afd
 207:  *   1. Need to return status when mt status (or corresponding ioctl) is done.
 208:  *	Save resid, flags, endcode & status in tmscprsp() routine (except on
 209:  *	clear serious exception no-op).  Return these fields when status
 210:  *	ioctl is done (in tmscpcommand()).  How they are returned:
 211:  *		mt_resid = resid
 212:  *		mt_dsreg = flags|endcode
 213:  *		mt_erreg = status
 214:  *
 215:  *   2. Added latent support for enabling/disabling caching.  This is
 216:  *	handled along with all other ioctl commands.
 217:  *
 218:  *   3. Need to issue a no-op on unrecognized ioctl in tmsstart(), since
 219:  *	we have already commited to issuing a command at that point.
 220:  *
 221:  *   4. In tmscprsp() routine if encode is 0200 (invalid command issued);
 222:  *	We need to: Unlink the buffer from the I/O wait queue,
 223:  *	and signal iodone, so the higher level command can exit!
 224:  *	Just as if it were a valid command.
 225:  *
 226:  * 11-jul-85 -- jaw
 227:  *	fix bua/bda map registers.
 228:  *
 229:  * 19-Jun-85 -- jaw
 230:  *	VAX8200 name change.
 231:  *
 232:  * 06-Jun-85 - jaw
 233:  *	fixes for 8200.
 234:  *
 235:  * 9-Apr-85 - afd
 236:  *	Added timeout code to the probe routine, so if the controller
 237:  *	fails to init in 10 seconds we return failed status.
 238:  *
 239:  * 13-Mar-85 -jaw
 240:  *	Changes for support of the VAX8200 were merged in.
 241:  *
 242:  * 27-Feb-85 -tresvik
 243:  *	Changes for support of the VAX8600 were merged in.
 244:  *
 245:  */
 246: 
 247: #include "tms.h"
 248: #if NTMSCP > 0
 249: 
 250: #include "param.h"
 251: #include "systm.h"
 252: #include "buf.h"
 253: #include "conf.h"
 254: #include "user.h"
 255: #include "file.h"
 256: #include "map.h"
 257: #include "ioctl.h"
 258: #include "syslog.h"
 259: #include "mtio.h"
 260: #include "uio.h"
 261: #include "tty.h"
 262: #include "uba.h"
 263: #include "kernel.h"
 264: 
 265: #include "tmscpreg.h"
 266: #include "../pdp/tmscp.h"
 267: #include "../machine/seg.h"
 268: 
 269: /*
 270:  * The density array is indexed by the density bits (bits 3 and 4) of the
 271:  * minor device number AND the format menu returned for the drive.  Since
 272:  * only 3 densities are apparently supported by TMSCP (no DPE/3200bpi), the
 273:  * second MEDium table is a copy of the first MEDium entry.
 274: */
 275: 
 276:     char    Dmatrix[4][8] =
 277:         {
 278: /* LOW */   {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_800},
 279: /* MED1 */  {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_PE },
 280: /* MED2 */  {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_PE },
 281: /* HI */    {0,M_TF_800,M_TF_PE,M_TF_PE,M_TF_GCR,M_TF_GCR,M_TF_GCR,M_TF_GCR}
 282:         };
 283: 
 284: struct  tmscp_softc tmscp_softc[NTMSCP];    /* Controller info */
 285: struct  tms_info tms_info[NTMS];        /* Drive info */
 286: 
 287:     memaddr tmscp[NTMSCP];      /* click addresses of ctrl comm area */
 288: 
 289: /*
 290:  * Tflags definitions.  These take the place of several
 291:  * individual structure members in tms_info.
 292: */
 293: 
 294: #define _SEREX      0x0001      /* Serious Exception exists */
 295: #define _CLSEREX    0x0002      /* Do Clear Serious Exception */
 296: #define _LOST       0x0004      /* Position lost error happened */
 297: #define _BUFMARK    0x0008      /* Encountered a tape mark */
 298: #define _HASCACHE   0x0010      /* Drive has cache capability */
 299: #define _CACHE_ON   0x0020      /* Cache enabled */
 300: #define _CACHE_LOST 0x0040      /* Cache data loss has happened */
 301: #define _CACHE_WRITTEN  0x0080      /* Cache has been written */
 302: #define _INUSE      0x0100      /* Drive is in use */
 303: #define _ONLINE     0x0200      /* Drive is online */
 304: 
 305: /*
 306:  * Internal (ioctl) command codes (these must also be declared in the
 307:  * tmscpioctl routine).  These correspond to ioctls in mtio.h
 308:  */
 309: #define TMS_WRITM   0       /* write tape mark */
 310: #define TMS_FSF     1       /* forward space file */
 311: #define TMS_BSF     2       /* backward space file */
 312: #define TMS_FSR     3       /* forward space record */
 313: #define TMS_BSR     4       /* backward space record */
 314: #define TMS_REW     5       /* rewind tape */
 315: #define TMS_OFFL    6       /* rewind tape & mark unit offline */
 316: #define TMS_SENSE   7       /* noop - do a get unit status */
 317: #define TMS_CACHE   8       /* enable cache */
 318: #define TMS_NOCACHE 9       /* disable cache */
 319: #define TMS_FLUSH   10      /* flush cache */
 320: /* These go last: after all real mt cmds, just bump the numbers up */
 321: #define TMS_CSE     11      /* clear serious exception */
 322: #define TMS_SETDENSITY  12      /* set unit density */
 323: 
 324: /*
 325:  * Controller states
 326:  */
 327: #define S_IDLE  0               /* hasn't been initialized */
 328: #define S_STEP1 1               /* doing step 1 init */
 329: #define S_STEP2 2               /* doing step 2 init */
 330: #define S_STEP3 3               /* doing step 3 init */
 331: #define S_SCHAR 4               /* doing "set controller characteristics" */
 332: #define S_RUN   5               /* running */
 333: 
 334: static  char *tmscpstepfailed = "step%d init failed: sa %x\n";
 335:     char *tmscpfatalerr = "tms%d,%d: fatal error %x\n";
 336: 
 337: int tmscp_cp_wait = 0;  /* Something to wait on for command */
 338:                 /* packets and or credits. */
 339: int wakeup();
 340:     int tmswatchdog();
 341: extern  int hz;     /* Should find the right include */
 342: extern  long    _iomap();
 343: extern  u_int   tmscp_cache;    /* See pdp/kern_pdp.c */
 344: 
 345: /*
 346:  * Bit 0 = print all non-successful response packets _except_ hitting a
 347:  *	   tapemark (which really isn't an error).
 348:  * Bit 1 = print datagram arrival message.
 349:  * Bit 2 = print status of all response packets except datagrams.
 350:  * Bit 3 = enable debugging print and log statements not covered above
 351: */
 352: int tmscpprintf = 1;
 353: 
 354: /*
 355:  * This is settable via "sysctl -w machdep.tmscp.cache=0xXXXX".  There is one
 356:  * bit per drive.  Bit 0 is the first drive on the first controller, bit 4 is
 357:  * the first drive on the second controller, and so on.
 358:  *
 359: */
 360: 
 361: int tmscpcache = 0;
 362: 
 363: struct  mscp *tmscpgetcp();
 364: 
 365: #define b_qsize         b_resid         /* queue size per drive, in tmsutab */
 366: 
 367: tmsVec(ctlr, vector)
 368:     int ctlr, vector;
 369:     {
 370:     register struct tmscp_softc *sc = &tmscp_softc[ctlr];
 371: 
 372:     if  (ctlr >= NTMSCP || sc->sc_ivec)
 373:         return(-1);
 374:     sc->sc_ivec = vector;
 375:     return(0);
 376:     }
 377: 
 378: /*
 379:  * Open routine will issue the online command, later.
 380:  *
 381:  * This routine attaches controllers, not drives - sc_unit and 'unit' are
 382:  * the controller number not a drive unit number.  sc_com is initialized
 383:  * to SEG5 because all communication areas are mapped to the same virtual
 384:  * address now.
 385:  */
 386: tmsattach(addr, unit)
 387:     struct tmscpdevice *addr;
 388:     register int unit;
 389: {
 390:     register struct tmscp_softc *sc = &tmscp_softc[unit];
 391: 
 392:     if (unit >= NTMSCP)
 393:         return(0);
 394:     if (sc->sc_addr == NULL && addr != NULL) {
 395:         tmscp[unit] = (memaddr)_ioget(sizeof (struct tmscp));
 396:         if (tmscp[unit] == NULL)
 397:             return(0);
 398:         sc->sc_addr = addr;
 399:         sc->sc_unit = unit;
 400:         sc->sc_com = (struct tmscp *)SEG5;
 401:         return (1);
 402:     }
 403:     return(0);
 404: }
 405: 
 406: struct tms_info *
 407: getdd()
 408:     {
 409:     register struct tms_info *p;
 410: 
 411:     for (p = tms_info; p < &tms_info[NTMS]; p++)
 412:         {
 413:         if  (p->tms_type == 0)
 414:             {
 415: /*
 416:  * Set the type with a placeholder value - we may have to sleep waiting for
 417:  * the drive to come on line and we don't want this slot to be grabbed again.
 418:  * The online response will load the real drive type.
 419: */
 420:             p->tms_type = 1;    /* XXX */
 421:             return(p);
 422:             }
 423:         }
 424:     log(LOG_INFO, "tms: !drives\n");
 425:     return(NULL);
 426:     }
 427: 
 428: static int
 429: wait_step(mask, good, csr, sc)
 430:     u_short mask, good;
 431:     register struct tmscpdevice *csr;
 432:     register struct tmscp_softc *sc;
 433:     {
 434:     register int i;
 435: 
 436:     for (i = 0; i < 150; i++)
 437:         {
 438:         if  ((csr->tmscpsa & mask) == good)
 439:             return(0);
 440:         delay(10000L);      /* still in step - wait 1/100 sec */
 441:         }
 442:     sc->sc_state = S_IDLE;
 443:     sc->sc_ctab.b_active = 0;
 444:     log(LOG_INFO, tmscpstepfailed, sc->sc_state, csr->tmscpsa);
 445:     wakeup((caddr_t)&sc->sc_ctab);
 446:     return(-1);
 447:     }
 448: 
 449: /*
 450:  * TMSCP interrupt routine.
 451:  */
 452: tmsintr(dev)
 453:     dev_t dev;
 454: {
 455:     register struct tmscpdevice *tmscpaddr;
 456:     struct buf *bp;
 457:     int i;
 458:     register struct tmscp_softc *sc = &tmscp_softc[dev];
 459:     register struct tmscp *tm = sc->sc_com;
 460:     struct mscp *mp;
 461:     segm seg5;
 462: 
 463:     tmscpaddr = sc->sc_addr;
 464: 
 465:     /*
 466: 	 * How the interrupt is handled depends on the state of the controller.
 467: 	 */
 468:     switch (sc->sc_state) {
 469: 
 470:     case S_IDLE:
 471:         log(LOG_INFO, "tms%d: rand intr\n", dev);
 472:         return;
 473: 
 474:     /* Controller was in step 1 last, see if its gone to step 2 */
 475:     case S_STEP1:
 476: #		define STEP1MASK 0174377
 477: #		define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
 478: 
 479:         if  (wait_step(STEP1MASK, STEP1GOOD, tmscpaddr, sc) < 0)
 480:             return;
 481:         tmscpaddr->tmscpsa = (short)sc->sc_ctab.b_un.b_addr;
 482:         sc->sc_state = S_STEP2;
 483:         return;
 484: 
 485:     /* Controller was in step 2 last, see if its gone to step 3 */
 486:     case S_STEP2:
 487: #		define STEP2MASK 0174377
 488: #		define STEP2GOOD (TMSCP_STEP3|TMSCP_IE|(sc->sc_ivec/4))
 489: 
 490:         if  (wait_step(STEP2MASK, STEP2GOOD, tmscpaddr, sc) < 0)
 491:             return;
 492:         tmscpaddr->tmscpsa = sc->sc_ctab.b_xmem;
 493:         sc->sc_state = S_STEP3;
 494:         return;
 495: 
 496:     /* Controller was in step 3 last, see if its gone to step 4 */
 497:     case S_STEP3:
 498: #		define STEP3MASK 0174000
 499: #		define STEP3GOOD TMSCP_STEP4
 500: 
 501:         if  (wait_step(STEP3MASK, STEP3GOOD, tmscpaddr, sc) < 0)
 502:             return;
 503:         /*
 504: 		 * Get microcode version and model number of controller;
 505: 		 * Signal initialization complete (_GO) (to the controller);
 506: 		 * Set state to "set controller characteristics".
 507: 		 */
 508:         i = tmscpaddr->tmscpsa;
 509:         tmscpaddr->tmscpsa = TMSCP_GO | TMSCP_LF;
 510:         sc->sc_state = S_SCHAR;
 511: 
 512:         log(LOG_INFO, "tms%d Ver %d Mod %d\n", dev, i & 0xf,
 513:             (i >> 4) & 0xf);
 514: 
 515:         /*
 516: 	     * Initialize the data structures (response and command queues).
 517: 	     */
 518:         saveseg5(seg5);
 519:         mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
 520:         tmsginit(sc, sc->sc_com->tmscp_ca.ca_rspdsc, sc->sc_com->tmscp_rsp,
 521:             0, NRSP, TMSCP_OWN|TMSCP_INT);
 522:         tmsginit(sc, sc->sc_com->tmscp_ca.ca_cmddsc, sc->sc_com->tmscp_cmd,
 523:             NRSP, NCMD, TMSCP_INT);
 524:         bp = &sc->sc_wtab;
 525:         bp->av_forw = bp->av_back = bp;
 526:         sc->sc_lastcmd = 1;
 527:         sc->sc_lastrsp = 0;
 528:         mp = sc->sc_com->tmscp_cmd;
 529:         mp->mscp_unit = mp->mscp_modifier = 0;
 530:         mp->mscp_flags = 0;
 531:         mp->mscp_version = 0;
 532:         mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS;
 533:         /*
 534: 	     * A host time out value of 0 means that the controller will not
 535: 	     * time out.  This is ok for the TK50.
 536: 	     */
 537:         mp->mscp_hsttmo = 0;
 538:         bzero(&mp->mscp_time, sizeof (mp->mscp_time));
 539:         mp->mscp_cntdep = 0;
 540:         mp->mscp_opcode = M_OP_STCON;
 541:         ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT);
 542:         i = tmscpaddr->tmscpip;      /* initiate polling */
 543:         restorseg5(seg5);
 544:         return;
 545: 
 546:     case S_SCHAR:
 547:     case S_RUN:
 548:         break;
 549: 
 550:     default:
 551:         log(LOG_INFO, "tms%d: ST %d\n", dev, sc->sc_state);
 552:         return;
 553:     }   /* end switch */
 554: 
 555:     /*
 556: 	 * The controller state is S_SCHAR or S_RUN
 557: 	 */
 558: 
 559:     /*
 560: 	 * If the error bit is set in the SA register then print an error
 561: 	 * message and reinitialize the controller.
 562: 	 */
 563:     if (tmscpaddr->tmscpsa&TMSCP_ERR)
 564:         {
 565:         log(LOG_INFO, tmscpfatalerr, dev, sc->sc_unit, tmscpaddr->tmscpsa);
 566:         tmscpaddr->tmscpip = 0;
 567:         sc->sc_state = S_IDLE;
 568:         sc->sc_ctab.b_active = 0;
 569:         wakeup((caddr_t)&sc->sc_ctab);
 570:         }
 571:     /*
 572: 	 * Check for a buffer purge request. (Won't happen w/ TK50 on Q22 bus)
 573: 	 */
 574:     saveseg5(seg5);
 575:     mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
 576:     if (tm->tmscp_ca.ca_bdp)
 577:         {
 578:         tm->tmscp_ca.ca_bdp = 0;
 579:         tmscpaddr->tmscpsa = 0;      /* signal purge complete */
 580:         }
 581: 
 582:     /*
 583: 	 * Check for response ring transition.
 584: 	 */
 585:     if (tm->tmscp_ca.ca_rspint)
 586:         {
 587:         tm->tmscp_ca.ca_rspint = 0;
 588:         for (i = sc->sc_lastrsp;; i++)
 589:             {
 590:             i %= NRSP;
 591:             if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN)
 592:                 break;
 593:             tmscprsp(sc, i);
 594:             tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN;
 595:             }
 596:         sc->sc_lastrsp = i;
 597:         }
 598: 
 599:     /*
 600: 	 * Check for command ring transition. (Should never happen!)
 601: 	 */
 602:     if  (tm->tmscp_ca.ca_cmdint)
 603:         tm->tmscp_ca.ca_cmdint = 0;
 604:     restorseg5(seg5);
 605:         if (tmscp_cp_wait)
 606:         wakeup((caddr_t)&tmscp_cp_wait);
 607:         (void) tmsstart(sc);
 608: }
 609: 
 610: 
 611: /*
 612:  * Open a tmscp device and set the unit online.  If the controller is not
 613:  * in the run state, call init to initialize the tmscp controller first.
 614:  */
 615: 
 616: /* ARGSUSED */
 617: tmscpopen(dev, flag)
 618:     dev_t dev;
 619:     int flag;
 620: {
 621:     register int unit = TMSUNIT(dev);
 622:     int ctlr = TMSCTLR(dev);
 623:     register struct tmscp_softc *sc;
 624:     register struct tms_info *tms;
 625:     register struct mscp *mp;
 626:     struct tmscpdevice *tmscpaddr;
 627:     u_short cmdref;
 628:     int s,i;
 629: 
 630:     if (ctlr >= NTMSCP)
 631:         return (ENXIO);
 632:     sc = &tmscp_softc[ctlr];
 633:     if (sc->sc_addr == NULL)
 634:         return (ENXIO);
 635:     if ((tms = sc->sc_drives[unit]) == NULL) {
 636:         tms = getdd();
 637:         if (!tms)
 638:             return(ENXIO);
 639:         tms->Tflags = 0;
 640:         sc->sc_drives[unit] = tms;
 641:     }
 642:     else if (tms->Tflags & _INUSE)
 643:         return(EBUSY);
 644:     tms->Tflags |= _INUSE;
 645: 
 646:     s = spl5();
 647:     if (sc->sc_state != S_RUN)
 648:         {
 649:         if (sc->sc_state == S_IDLE)
 650:             if  (!tkini(sc))
 651:                 {
 652:                 log(LOG_INFO, "tms%d init\n", ctlr);
 653:                 sc->sc_drives[unit] = NULL;
 654:                 tms->Tflags = 0;
 655:                 tms->tms_type = 0;
 656:                 (void) splx(s);
 657:                 return(ENXIO);
 658:                 }
 659:         /*
 660: 		 * Wait for initialization to complete
 661: 		 */
 662:         timeout(wakeup,(caddr_t)&sc->sc_ctab,11*hz);    /* to be sure*/
 663:         sleep((caddr_t)&sc->sc_ctab, PSWP+1);
 664:         if  (sc->sc_state != S_RUN)
 665:             {
 666:             sc->sc_drives[unit] = NULL;
 667:             tms->Tflags = 0;
 668:             tms->tms_type = 0;
 669:             (void) splx(s);
 670:             return(EIO);
 671:             }
 672:         }
 673:     (void) splx(s);
 674: 
 675:     /*
 676: 	 * If drive is not online get a command packet, sleeping if no
 677: 	 * controller credits are available at the moment.  Then start
 678: 	 * the ONLINE process.
 679: 	 */
 680:     tmscpaddr = (struct tmscpdevice *) sc->sc_addr;
 681:     if  (!(tms->Tflags & _ONLINE))
 682:         {
 683:         s = spl5();
 684:         while   ((mp = tmscpgetcp(sc)) == 0)
 685:             {
 686:             tmscp_cp_wait++;
 687:             sleep((caddr_t)&tmscp_cp_wait,PSWP+1);
 688:             tmscp_cp_wait--;
 689:             }
 690:         (void) splx(s);
 691:         mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
 692:         mp->mscp_opcode = M_OP_ONLIN;
 693:         mp->mscp_unit = unit;       /* unit? */
 694:         tms_clrerr(tms, mp);
 695:     /* calculate this once instead of 4 times */
 696:         cmdref = (u_short)&tms->tms_type;
 697:         mp->mscp_cmdref = cmdref;   /* need to sleep on something */
 698:         ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN | TMSCP_INT);
 699:         normalseg5();
 700:         i = tmscpaddr->tmscpip;
 701:         /*
 702: 		 * To make sure we wake up, timeout in 240 seconds.
 703: 		 * Wakeup in tmscprsp routine.
 704: 		 * 240 seconds (4 minutes) is necessary since a rewind
 705: 		 * can take a few minutes.
 706: 		 */
 707:         timeout(wakeup,(caddr_t) cmdref,240 * hz);
 708:         sleep((caddr_t)cmdref,PSWP+1);
 709:         untimeout(wakeup, cmdref);
 710:         }
 711:     if  (!(tms->Tflags & _ONLINE))
 712:         {
 713: oops:       tms->Tflags = 0;
 714:         tms->tms_type = 0;
 715:         sc->sc_drives[unit] = NULL;
 716:         return(EIO);  /* Didn't go online */
 717:         }
 718: /*
 719:  * Get the unit characteristics (GTUNT).  This 1) Verifies the drive
 720:  * is really still online and 2) Retrieves information about the drive
 721:  * such as density choices, cache presence, etc.
 722: */
 723:     tms->tms_flags = 0;
 724:     if  (tmscpcache & ((1 << unit) << (4 * ctlr)))
 725:         tms->Tflags |= _CACHE_ON;
 726:     i = tms->Tflags & _CACHE_ON;
 727:     tms->Tflags = _ONLINE | _INUSE | i; /* Clear all other flags */
 728:     tmscpcommand(dev, TMS_SENSE, 1);
 729:     if  (!(tms->Tflags & _ONLINE))
 730:         goto oops;
 731: 
 732: /*
 733:  * Next issue a reposition NOP by spacing forward 0 records.  This returns
 734:  * the current position (so we can tell if we're at BOT or not) and also
 735:  * clears any serious exceptions outstanding.
 736: */
 737:     tmscpcommand(dev, TMS_CSE, 1);
 738: 
 739: /*
 740:  * Now go set the density - the lower level routines set the density if
 741:  * the drive is at BOT.
 742: */
 743:     tmscpcommand(dev, TMS_SETDENSITY, 1);
 744:     return(0);
 745: }
 746: 
 747: /*
 748:  * Close tape device.
 749:  *
 750:  * If tape was open for writing or last operation was
 751:  * a write, then write two EOF's and backspace over the last one.
 752:  * Unless this is a non-rewinding special file, rewind the tape.
 753: */
 754: tmscpclose(dev, flag)
 755:     register dev_t dev;
 756:     register flag;
 757:     {
 758:     struct tmscp_softc *sc;
 759:     register struct tms_info *tms;
 760:     int unit = TMSUNIT(dev);
 761: 
 762:     sc = &tmscp_softc[TMSCTLR(dev)];
 763:     tms = sc->sc_drives[unit];
 764: 
 765:     if  ((tms->Tflags & _CACHE_ON) && (tms->Tflags & _CACHE_WRITTEN))
 766:         {
 767: /*
 768:  * A misbehaving application has closed the device without flushing
 769:  * the enabled cache by issuing a MTFLUSH - we'll do it for it.
 770: */
 771:         tmscpcommand(dev, TMS_FLUSH, 1);
 772:         if  (tms->tms_status != M_ST_SUCC)
 773:             {
 774: /*
 775:  * This is BAD news - the flush didn't work.  The drive is in a serious
 776:  * exception state, leave that alone for the non-rewind case so that further
 777:  * operations fail.  About all that can be done now is log the error.
 778: */
 779:             log(LOG_INFO, "tms%d,%d flsh\n", TMSCTLR(dev), unit);
 780:             tms->Tflags &= ~_CACHE_WRITTEN;
 781:             }
 782:         }
 783:     if  (tms->tms_flags & MTF_WRITTEN)
 784:         tms_wrteof(dev, tms);
 785:     tms->Tflags &= ~(_BUFMARK | _INUSE);
 786:     if  ((dev & T_NOREWIND) == 0)
 787:         {
 788:         tmscpcommand(dev, TMS_REW, 0);
 789:         tms->Tflags &= ~(_LOST | _CLSEREX | _SEREX);
 790:         }
 791:     return(0);
 792:     }
 793: 
 794: /*
 795:  * Execute a command on the tape drive a specified number of times.
 796:  * This routine sets up a buffer and calls the strategy routine which
 797:  * links the buffer onto the drive's buffer queue.
 798:  * The start routine will take care of creating a tmscp command packet
 799:  * with the command.  The start routine is called by the strategy or the
 800:  * interrupt routine.
 801:  */
 802: 
 803: tmscpcommand(dev, com, count)
 804:     register dev_t dev;
 805:     int com, count;
 806: {
 807:     register struct buf *bp;
 808:     register int s;
 809:     int unit = TMSUNIT(dev);
 810: 
 811:     bp = &tmscp_softc[TMSCTLR(dev)].sc_cmdbuf;
 812: 
 813:     s = spl5();
 814:     while   (bp->b_flags&B_BUSY)
 815:         {
 816:         bp->b_flags |= B_WANTED;
 817:         sleep((caddr_t)bp, PRIBIO);
 818:         }
 819:     bp->b_flags = B_BUSY|B_READ;
 820:     splx(s);
 821:     /*
 822: 	 * Load the buffer.  The b_count field gets used to hold the command
 823: 	 * count.  the b_resid field gets used to hold the command mneumonic.
 824: 	 * These 2 fields are "known" to be "safe" to use for this purpose.
 825: 	 * (Most other drivers also use these fields in this way.)
 826: 	 */
 827:     bp->b_dev = dev;
 828:     bp->b_bcount = count;
 829:     bp->b_resid = com;
 830:     bp->b_blkno = 0;
 831: /*
 832:  * Start the timer before entering the strategy routine.  If it declares
 833:  * an immediate error it will also perform an iodone which will cause us
 834:  * to fall thru and cancel the timer.
 835: */
 836:     timeout(tmswatchdog, bp, 240 * hz);
 837:     tmscpstrategy(bp);
 838:     iowait(bp);
 839:     untimeout(tmswatchdog, bp);
 840:     if  (bp->b_flags & B_WANTED)    /* Anyone waiting above? */
 841:         wakeup(bp);
 842:     bp->b_flags &= B_ERROR;     /* Clears B_BUSY */
 843: }
 844: 
 845: /*
 846:  * If this routine is called then  (after 4 minutes) something is hung.
 847:  * Set the I/O done flag, set error to be ETIMEDOUT, and issue the wakeup.
 848: */
 849: tmswatchdog(bp)
 850:     struct  buf *bp;
 851:     {
 852: 
 853:     bp->b_error = ETIMEDOUT;
 854:     biodone(bp);
 855:     }
 856: 
 857: /*
 858:  * Init mscp communications area
 859:  */
 860: tmsginit(sc, com, msgs, offset, length, flags)
 861:     register struct tmscp_softc *sc;
 862:     register    Trl     *com;
 863:     register struct mscp        *msgs;
 864:     int             offset;
 865:     int             length;
 866:     int             flags;
 867: {
 868:     long                vaddr;
 869: 
 870:     /*
 871: 	 * Figure out virtual address of message
 872: 	 * skip comm area and mscp messages header and previous messages
 873: 	 *
 874: 	 * N.B. Assumes SEG5 has been remapped to the comm area for this
 875: 	 * controller.
 876: 	 */
 877:     vaddr = _iomap(tmscp[sc->sc_unit]);
 878:     vaddr += sizeof(struct tmscpca)         /* skip comm area */
 879:         +sizeof(struct mscp_header);        /* m_cmdref disp */
 880:     vaddr += offset * sizeof(struct mscp);      /* skip previous */
 881:     while (length--) {
 882:         com->lsh = loint(vaddr);
 883:         com->hsh = flags | hiint(vaddr);
 884:         msgs->mscp_dscptr = (long *)com;
 885:         msgs->mscp_header.mscp_msglen = sizeof(struct mscp);
 886:         msgs->mscp_header.mscp_vcid = 1; /* tape VCID = 1 */
 887:         ++com; ++msgs; vaddr += sizeof(struct mscp);
 888:     }
 889: }
 890: 
 891: /*
 892:  * Find an unused command packet
 893:  */
 894: struct mscp *
 895: tmscpgetcp(sc)
 896:     register struct tmscp_softc *sc;
 897: {
 898:     register struct mscp *mp = NULL;
 899:     register struct tmscpca *cp;
 900:     int i;
 901:     int s;
 902:     segm seg5;
 903: 
 904:     s = spl5();
 905:     saveseg5(seg5);
 906:     mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
 907:     cp = &sc->sc_com->tmscp_ca;
 908:     /*
 909: 	 * If no credits, can't issue any commands
 910: 	 * until some outstanding commands complete.
 911: 	 */
 912:     i = sc->sc_lastcmd;
 913:     if  (((cp->ca_cmddsc[i].hsh&(TMSCP_OWN|TMSCP_INT))==TMSCP_INT) &&
 914:           (sc->sc_credits >= 2))
 915:         {
 916:         sc->sc_credits--;       /* This commits to issuing a command */
 917:         cp->ca_cmddsc[i].hsh &= ~TMSCP_INT;
 918:         mp = &sc->sc_com->tmscp_cmd[i];
 919:         mp->mscp_cmdref = 0;
 920:         mp->mscp_modifier = 0;
 921:         mp->mscp_flags = 0;
 922:         bzero(&mp->un, sizeof (mp->un));
 923:         sc->sc_lastcmd = (i + 1) % NCMD;
 924:         }
 925:     restorseg5(seg5);
 926:     (void) splx(s);
 927:     return(mp);
 928: }
 929: 
 930: /*
 931:  * Initialize a TMSCP device.  Set up UBA mapping registers,
 932:  * initialize data structures, and start hardware
 933:  * initialization sequence.
 934:  */
 935: tkini(sc)
 936:     register struct tmscp_softc *sc;
 937: {
 938:     register struct tmscpdevice *tmscpaddr;
 939:     long adr;
 940: 
 941:     sc->sc_ctab.b_active++;
 942:     adr = _iomap(tmscp[sc->sc_unit]) + (u_int)RINGBASE;
 943:     sc->sc_ctab.b_un.b_addr = (caddr_t)loint(adr);
 944:     sc->sc_ctab.b_xmem = hiint(adr);
 945:     tmscpaddr = sc->sc_addr;
 946: 
 947:     /*
 948: 	 * Start the hardware initialization sequence.
 949: 	 */
 950:     tmscpaddr->tmscpip = 0;              /* start initialization */
 951: 
 952:     while((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
 953:         {
 954:         if  (tmscpaddr->tmscpsa & TMSCP_ERR)
 955:             return(0);  /* CHECK */
 956:         }
 957:     tmscpaddr->tmscpsa=TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8)|TMSCP_IE|(sc->sc_ivec/4);
 958:     /*
 959: 	 * Initialization continues in the interrupt routine.
 960: 	 */
 961:     sc->sc_state = S_STEP1;
 962:     sc->sc_credits = 0;
 963:     return(1);
 964: }
 965: 
 966: /*
 967:  * Start I/O operation
 968:  * This code is convoluted.  The majority of it was copied from the uda driver.
 969:  */
 970: 
 971: tmsstart(sc)
 972:     register struct tmscp_softc *sc;
 973: {
 974:     register struct mscp *mp;
 975:     register struct buf *bp, *dp;
 976:     register struct tms_info *tms;
 977:     struct   tmscpdevice *tmscpaddr;
 978:     int i, unit;
 979:     segm seg5;
 980: 
 981:      saveseg5(seg5);        /* save just once at top */
 982:      for(;;)
 983:     {
 984:     if  ((dp = sc->sc_ctab.b_actf) == NULL)
 985:         {
 986:         /* (drive was inactive) */
 987:         sc->sc_ctab.b_active = 0;
 988:         break;
 989:         }
 990:     if  ((bp = dp->b_actf) == NULL)
 991:         {
 992:         /*
 993: 		 * No more requests for this drive, remove
 994: 		 * from controller queue and look at next drive.
 995: 		 * We know we're at the head of the controller queue.
 996: 		 */
 997:         dp->b_active = 0;
 998:         sc->sc_ctab.b_actf = dp->b_forw;
 999:         continue;
1000:         }
1001:     sc->sc_ctab.b_active++;
1002:     unit = TMSUNIT(bp->b_dev);
1003:     tmscpaddr = (struct tmscpdevice *)sc->sc_addr;
1004:     tms = sc->sc_drives[unit];
1005:     if  ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN)
1006:         {
1007:         log(LOG_INFO, "tms%d,%d: sa %x st %d\n", sc->sc_unit,
1008:             unit, tmscpaddr->tmscpsa, sc->sc_state);
1009:         (void)tkini(sc);
1010:         /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */
1011:         break;
1012:         }
1013: 
1014:     if  (!(tms->Tflags & _ONLINE))
1015:         {
1016:         if  ((mp = tmscpgetcp(sc)) == NULL)
1017:             break;
1018:         mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
1019:         mp->mscp_opcode = M_OP_ONLIN;
1020:         mp->mscp_unit = unit;
1021:         tms_clrerr(tms, mp);
1022:         dp->b_active = 2;
1023:         sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */
1024:         ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT);
1025:         if  (tmscpaddr->tmscpsa&TMSCP_ERR)
1026:             log(LOG_INFO, tmscpfatalerr, sc->sc_unit,
1027:                     TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa);
1028:         restorseg5(seg5);
1029:         i = tmscpaddr->tmscpip;
1030:         continue;
1031:         }
1032:     if  ((mp = tmscpgetcp(sc)) == NULL)
1033:         break;
1034:     mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
1035:     mp->mscp_cmdref = (u_short)bp;      /* pointer to get back */
1036:     mp->mscp_unit = unit;
1037:     /*
1038: 	 * If its an ioctl-type command then set up the appropriate
1039: 	 * tmscp command;  by doing a switch on the "b_resid" field where
1040: 	 * the command mneumonic is stored.
1041: 	 */
1042:     if  (bp == &sc->sc_cmdbuf)
1043:         {
1044:         /*
1045: 		 * The reccnt and tmkcnt fields are set to zero by the getcp
1046: 		 * routine (as bytecnt and buffer fields).  Thus reccnt and
1047: 		 * tmkcnt are only modified here if they need to be set to
1048: 		 * a non-zero value.
1049: 		 */
1050:         switch ((int)bp->b_resid) {
1051: 
1052:         case TMS_WRITM:
1053:             tms_wtm_st(mp, sc, 0);
1054:             break;
1055:         case TMS_FSF:
1056:             tms_repos_st(mp, sc, 0);
1057:             break;
1058:         case TMS_BSF:
1059:             tms_repos_st(mp, sc, M_MD_REVRS);
1060:             break;
1061:         case TMS_FSR:
1062:             tms_reposrec_st(mp, sc, M_MD_OBJCT);
1063:             break;
1064:         case TMS_BSR:
1065:             tms_reposrec_st(mp, sc, M_MD_OBJCT | M_MD_REVRS);
1066:             break;
1067:         case TMS_REW:
1068:             if  (bp->b_bcount)
1069:                 i = M_MD_REWND;
1070:             else
1071:                 i = M_MD_REWND | M_MD_IMMED;
1072:             bp->b_bcount = 0;   /* XXX */
1073:             tms_repos_st(mp, sc, i);
1074:             break;
1075:         case TMS_OFFL:
1076:             tms_avail_st(mp, sc, M_MD_UNLOD);
1077:             break;
1078:         case TMS_SENSE:
1079:             mp->mscp_opcode = M_OP_GTUNT;
1080:             break;
1081:         case TMS_FLUSH:
1082:             mp->mscp_opcode = M_OP_FLUSH;
1083:             break;
1084:         case TMS_CACHE:
1085:             tms->tms_unitflgs |= M_UF_WBKNV;
1086:             tms->tms_unitflgs &= ~M_UF_SCCHH;
1087:             tms->Tflags |= _CACHE_ON;
1088:             tms_stunt_st(mp, sc, 0);
1089:             break;
1090:         case TMS_NOCACHE:
1091:             tms->tms_unitflgs &= ~M_UF_WBKNV;
1092:             tms->tms_unitflgs |= M_UF_SCCHH;
1093:             tms->Tflags &= ~_CACHE_ON;
1094:             tms_stunt_st(mp, sc, 0);
1095:             break;
1096:         case TMS_CSE:
1097:             bp->b_bcount = 0;   /* 0 objects to skip */
1098:             tms_repos_st(mp, sc, M_MD_OBJCT);
1099:             break;
1100:         case TMS_SETDENSITY:
1101:             tms->tms_format &= ~M_TF_MASK;
1102:             tms->tms_format |= Dmatrix[TMSDENS(bp->b_dev)][tms->tms_fmtmenu & FMTMASK];
1103:             tms_stunt_st(mp, sc, 0);
1104:             break;
1105:         default:
1106:             log(LOG_INFO, "ioctl %x\n", bp->b_resid);
1107:             /* Need a no-op. Reposition no amount */
1108:             mp->mscp_opcode = M_OP_REPOS;
1109:             break;
1110:         }   /* end switch (bp->b_resid) */
1111:         }
1112:     else    /* Its a read/write command (not an ioctl) */
1113:         {
1114:         mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE;
1115:         mp->mscp_bytecnt = bp->b_bcount;
1116:         mp->mscp_buffer_l = (u_short) bp->b_un.b_addr;
1117:         mp->mscp_buffer_h = bp->b_xmem;
1118:         }
1119: 
1120:     if  ((tms->Tflags & _CACHE_ON) && (mp->mscp_opcode == M_OP_WRITE))
1121:         tms->Tflags |= _CACHE_WRITTEN;
1122:     if  ((tms->Tflags & _BUFMARK) && (mp->mscp_opcode == M_OP_READ) &&
1123:          (tms->Tflags & _CLSEREX))
1124:         {
1125:         tms->Tflags &= ~(_BUFMARK | _CLSEREX);
1126:         mp->mscp_modifier |= M_MD_CLSEX;
1127:         }
1128: 
1129:     if  (tmscpprintf & 0x8)
1130:         {
1131:         log(LOG_INFO, "tms%d,%d -> op %x fl %x mod %x\n",
1132:             sc->sc_unit, mp->mscp_unit,
1133:             mp->mscp_opcode, mp->mscp_flags, mp->mscp_modifier);
1134:         }
1135: 
1136:     ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT);
1137:     i = tmscpaddr->tmscpip;              /* initiate polling */
1138:     dp->b_qsize++;
1139:     /*
1140: 	 * Move drive to the end of the controller queue
1141: 	 */
1142:     if (dp->b_forw != NULL)
1143:         {
1144:         sc->sc_ctab.b_actf = dp->b_forw;
1145:         sc->sc_ctab.b_actl->b_forw = dp;
1146:         sc->sc_ctab.b_actl = dp;
1147:         dp->b_forw = NULL;
1148:         }
1149:     /*
1150: 	 * Move buffer to I/O wait queue
1151: 	 */
1152:     dp->b_actf = bp->av_forw;
1153:     dp = &sc->sc_wtab;
1154:     bp->av_forw = dp;
1155:     bp->av_back = dp->av_back;
1156:     dp->av_back->av_forw = bp;
1157:     dp->av_back = bp;
1158:     if (tmscpaddr->tmscpsa&TMSCP_ERR)
1159:         {
1160:         log(LOG_INFO, tmscpfatalerr,sc->sc_unit,
1161:             mp->mscp_unit, tmscpaddr->tmscpsa);
1162:         (void)tkini(sc);
1163:         break;
1164:         }
1165:     }   /* end for */
1166:     /*
1167:      * Check for response ring transitions lost in the
1168:      * Race condition.  Map SEG5 in case we escaped early from the for().
1169:      */
1170:     mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
1171:     for (i = sc->sc_lastrsp;; i++)
1172:         {
1173:         i %= NRSP;
1174:         if (sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN)
1175:             break;
1176:         tmscprsp(sc, i);
1177:         sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN;
1178:         }
1179:     sc->sc_lastrsp = i;
1180:     restorseg5(seg5);
1181: }
1182: 
1183: 
1184: /*
1185:  * Process a response packet.  N.B.  Assumes SEG5 maps comm area for controller
1186:  */
1187: tmscprsp(sc, i)
1188:     register struct tmscp_softc *sc;
1189:     int i;
1190: {
1191:     register struct mscp *mp;
1192:     register struct tms_info *tms;
1193:     struct buf *dp, *bp;
1194:     int em_status, em_endcode;
1195: 
1196:     mp = &sc->sc_com->tmscp_rsp[i];
1197:     mp->mscp_header.mscp_msglen = sizeof (struct mscp);
1198:     sc->sc_credits += mp->mscp_header.mscp_credits & 0xf;  /* low 4 bits */
1199:     if  ((mp->mscp_header.mscp_credits & 0xf0) > 0x10)  /* Check */
1200:         return;
1201: 
1202:     /*
1203: 	 * If it's an error log message (datagram),
1204: 	 * pass it on for more extensive processing.
1205: 	 */
1206:     if  ((mp->mscp_header.mscp_credits & 0xf0) == 0x10)
1207:         {
1208:         tmserror(sc->sc_unit, (struct mslg *)mp);
1209:         return;
1210:         }
1211: 
1212:     if  (tmscpprintf & 0x4)
1213:         log(LOG_INFO, "tms%d,%d: op %x st %x\n", sc->sc_unit,
1214:             mp->mscp_unit,mp->mscp_opcode,
1215:             mp->mscp_status & M_ST_MASK);
1216: 
1217:     em_status = mp->mscp_status&M_ST_MASK;
1218:     em_endcode = mp->mscp_endcode & ~M_OP_END;
1219:     /*
1220: 	 * The controller interrupts as any drive.
1221: 	 * This means that you must check for controller interrupts
1222: 	 * before drive responses.
1223: 	 */
1224:     if  (em_endcode == M_OP_STCON)
1225:         {
1226:         if  (em_status == M_ST_SUCC)
1227:             sc->sc_state = S_RUN;
1228:         else
1229:             sc->sc_state = S_IDLE;
1230:         sc->sc_ctab.b_active = 0;
1231:         wakeup((caddr_t)&sc->sc_ctab);
1232:         return;
1233:         }
1234:     if  (mp->mscp_unit >= 4)
1235:         return;
1236:     tms = sc->sc_drives[mp->mscp_unit];
1237:     if  (!tms)      /* unopened unit coming online - ignore it */
1238:         return;
1239:     dp = &tms->tms_dtab;
1240: 
1241:     switch (em_endcode) {
1242:     case    M_OP_ONLIN:
1243:         if  (em_status == M_ST_SUCC || em_status == M_ST_WRTPR)
1244:             {
1245:             tms->Tflags |= _ONLINE;
1246:             tms->Tflags &= ~_CACHE_WRITTEN;
1247: /*
1248:  * Normally this is done in the 'tms_check_ret' routine.  The ONLIN case is
1249:  * special (well, ok - weird) in that it was never put on the I/O wait queue.
1250:  * Thus we need to do this here.
1251: */
1252:             tms->tms_endcode = em_endcode;
1253:             tms->tms_status = em_status;
1254:             tms->tms_type = mp->mscp_mediaid;
1255:             tms->tms_unitflgs = mp->mscp_unitflgs;
1256:             tms->tms_format = mp->mscp_format;
1257:             /*
1258: 			 * Link the drive onto the controller queue
1259: 			 */
1260:             dp->b_forw = NULL;
1261:             if  (sc->sc_ctab.b_actf == NULL)
1262:                 sc->sc_ctab.b_actf = dp;
1263:             else
1264:                 sc->sc_ctab.b_actl->b_forw = dp;
1265:             sc->sc_ctab.b_actl = dp;
1266:             dp->b_active = 1;
1267:             }
1268:         else
1269:             {
1270:             while   (bp = dp->b_actf)
1271:                 {
1272:                 dp->b_actf = bp->av_forw;
1273:                 bp->b_flags |= B_ERROR;
1274:                 iodone(bp);
1275:                 }
1276:             }
1277:         if  (mp->mscp_cmdref)
1278:             wakeup((caddr_t)mp->mscp_cmdref);
1279:         return;
1280:     /*
1281: 	 * The AVAILABLE ATTENTION message occurs when the
1282: 	 * unit becomes available after loading.
1283: 	 * Marking the unit offline will force an
1284: 	 * online command prior to using the unit.
1285: 	 */
1286:     case    M_OP_AVATN:
1287:         tms->Tflags &= ~_ONLINE;
1288:         return;
1289: /*
1290:  * An endcode with no opcode (0x80) is an invalid command.  This is supposed
1291:  * to indicate a protocol error (illegal opcode, parameter error, etc) but
1292:  * without the real opcode we don't know which command (reposition, write,
1293:  * read, ...) failed.  So, just declare I/O done and hope for the best.
1294: */
1295:     case    0:
1296:         if  (tmscpprintf & 0x8)
1297:             log(LOG_INFO, "tms%d,%d: inv end=%x st=%x\n",
1298:                 sc->sc_unit,mp->mscp_unit,em_endcode,em_status);
1299:         tms_iodone(mp, sc);
1300:         return;
1301:     case    M_OP_WRITE:
1302:     case    M_OP_READ:
1303:         tms_rw_em(mp, sc);
1304:         return;
1305:     case    M_OP_WRITM:
1306:         tms_wtm_em(mp, sc);
1307:         return;
1308:     case    M_OP_REPOS:
1309:         tms_repos_em(mp, sc);
1310:         return;
1311:     case    M_OP_STUNT:
1312:         tms_stunt_em(mp, sc);
1313:         return;
1314:     case    M_OP_AVAIL:
1315:         tms_avail_em(mp, sc);
1316:         return;
1317:     case    M_OP_GTUNT:
1318:         tms_gtunt_em(mp, sc);
1319:         return;
1320:     case    M_OP_FLUSH:
1321:         tms_flush_em(mp, sc);
1322:         return;
1323:     default:
1324:         if  (tmscpprintf & 0x8)
1325:             log(LOG_INFO, "tms%d,%d rsp %x\n", sc->sc_unit,
1326:                 mp->mscp_unit, em_endcode);
1327:         return;
1328:     }   /* end switch mp->mscp_opcode */
1329: }
1330: 
1331: /*
1332:  * Manage buffers and perform block mode read and write operations.
1333:  */
1334: 
1335: tmscpstrategy (bp)
1336:     register struct buf *bp;
1337:     {
1338:     register struct buf *dp;
1339:     register struct tmscp_softc *sc;
1340:     struct  tms_info *tms;
1341:     int ctlr = TMSCTLR(bp->b_dev);
1342:     int s;
1343: 
1344:     sc = &tmscp_softc[ctlr];
1345:     tms = sc->sc_drives[TMSUNIT(bp->b_dev)];
1346:     if  (!tms || !(tms->Tflags & _ONLINE))
1347:         {
1348:         bp->b_flags |= B_ERROR;
1349:         iodone(bp);
1350:         return;
1351:         }
1352: /*
1353:  * If we're at the end of the tape and this is not an 'ioctl' command
1354:  * then return an error rather than reading or writing off the end of the tape.
1355:  * Ioctl commands are allowed to proceed so that tapemarks can be written and
1356:  * repositioning (rewind, etc) can be done.
1357: */
1358:     if  ((tms->tms_flags & MTF_EOM) && bp != &sc->sc_cmdbuf)
1359:         {
1360:         bp->b_resid = bp->b_bcount;
1361:         bp->b_error = ENOSPC;
1362:         bp->b_flags |= B_ERROR;
1363:         iodone(bp);
1364:         return;
1365:         }
1366:     mapalloc(bp);
1367:     s = spl5();
1368:     /*
1369: 	 * Link the buffer onto the drive queue
1370: 	 */
1371:     dp = &tms->tms_dtab;
1372:     if (dp->b_actf == 0)
1373:         dp->b_actf = bp;
1374:     else
1375:         dp->b_actl->av_forw = bp;
1376:     dp->b_actl = bp;
1377:     bp->av_forw = 0;
1378:     /*
1379: 	 * Link the drive onto the controller queue
1380: 	 */
1381:     if (dp->b_active == 0)
1382:         {
1383:         dp->b_forw = NULL;
1384:         if (sc->sc_ctab.b_actf == NULL)
1385:             sc->sc_ctab.b_actf = dp;
1386:         else
1387:             sc->sc_ctab.b_actl->b_forw = dp;
1388:         sc->sc_ctab.b_actl = dp;
1389:         dp->b_active = 1;
1390:         }
1391:     /*
1392: 	 * If the controller is not active, start it.
1393: 	 */
1394:     if  (sc->sc_ctab.b_active == 0)
1395:         (void) tmsstart(sc);
1396:     splx(s);
1397:     return;
1398:     }
1399: 
1400: /* ARGSUSED */
1401: tmscpioctl(dev, cmd, data, flag)
1402:     dev_t dev;
1403:     int cmd;
1404:     caddr_t data;
1405:     int flag;
1406: {
1407:     struct tmscp_softc *sc = &tmscp_softc[TMSCTLR(dev)];
1408:     struct buf *bp = &sc->sc_cmdbuf;
1409:     register struct tms_info *tms = sc->sc_drives[TMSUNIT(dev)];
1410:     int fcount;     /* number of files (or records) to space */
1411:     register struct mtop *mtop; /* mag tape cmd op to perform */
1412:     register struct mtget *mtget;   /* mag tape struct to get info in */
1413: 
1414:     /* we depend of the values and order of the TMS ioctl codes here */
1415:     static char tmsops[] =
1416:      {TMS_WRITM,TMS_FSF,TMS_BSF,TMS_FSR,TMS_BSR,TMS_REW,TMS_OFFL,TMS_SENSE,
1417:       TMS_CACHE,TMS_NOCACHE,TMS_FLUSH};
1418: 
1419:     if  (!tms)
1420:         return(ENXIO);
1421:     if  (cmd != MTIOCGET)
1422:         tms->tms_status = ~M_ST_SUCC;
1423:     if  (tms->tms_position == 0)
1424:         tms->tms_flags |= MTF_BOM;
1425:     else
1426:         tms->tms_flags &= ~MTF_BOM;
1427: 
1428:     switch (cmd) {
1429:     case    MTIOCTOP:
1430:         mtop = (struct mtop *)data;
1431:         switch (mtop->mt_op) {
1432: 
1433:         case    MTWEOF:
1434:             return(tms_wrteof(dev, tms));
1435:         case    MTFSF:
1436:         case    MTBSF:
1437:         case    MTFSR:
1438:         case    MTBSR:
1439:             fcount = mtop->mt_count;
1440:             break;
1441:         case    MTFLUSH:
1442:         case    MTCACHE:
1443:         case    MTNOCACHE:
1444:             if  ((tms->Tflags & (_HASCACHE|_ONLINE)) !=
1445:                  (_HASCACHE|_ONLINE))
1446:                 return(0);
1447:         case    MTREW:
1448:         case    MTOFFL:
1449:         case    MTNOP:
1450:             fcount = 1;
1451:             break;
1452:         default:
1453:             return(ENXIO);
1454:         }   /* end switch mtop->mt_op */
1455: 
1456:         if  (fcount <= 0)
1457:             return(EINVAL);
1458:         tmscpcommand(dev, tmsops[mtop->mt_op], fcount);
1459:         if  (tms->tms_status != M_ST_SUCC)
1460:             {
1461:             if  (tms->Tflags & _CLSEREX)
1462:                 tmscpcommand(dev, TMS_CSE, 1);
1463:             return(EIO);
1464:             }
1465:         return(geterror(bp));
1466: 
1467:     case    MTIOCGET:
1468:         /*
1469: 		 * Return status info associated with the particular UNIT.
1470: 		 */
1471:         mtget = (struct mtget *)data;
1472:         mtget->mt_type = MT_ISTMSCP;
1473:         mtget->mt_dsreg = tms->tms_flags << 8;
1474:         mtget->mt_dsreg |= tms->tms_endcode;
1475:         mtget->mt_erreg = tms->tms_status;
1476:         mtget->mt_resid = tms->tms_resid;
1477:         break;
1478:     default:
1479:         return(ENXIO);
1480:     }
1481:     return (0);
1482: }
1483: 
1484: tms_wrteof(dev, tms)
1485:     dev_t   dev;
1486:     register struct tms_info *tms;
1487:     {
1488: 
1489:     tmscpcommand(dev, TMS_WRITM, 1);
1490:     if  (tms->tms_status != M_ST_SUCC)
1491:         return(EIO);
1492:     tms->tms_status = ~M_ST_SUCC;
1493:     tmscpcommand(dev, TMS_WRITM, 1);
1494:     if  (tms->tms_status != M_ST_SUCC)
1495:         return(EIO);
1496:     tms->Tflags &= ~_CACHE_WRITTEN;
1497:     tms->tms_status = ~M_ST_SUCC;
1498:     tmscpcommand(dev, TMS_BSR, 1);
1499:     if  (tms->tms_status != M_ST_SUCC)
1500:         return(EIO);
1501:     return(0);
1502:     }
1503: 
1504: /*
1505:  * Initialize the mscp packet for a STUNT command.  If the drive is in a
1506:  * 'cache lost' but 'written' state then clear it and log the error.
1507: */
1508: 
1509: tms_stunt_st(mp, sc, flgs)
1510:     register struct mscp    *mp;
1511:     register struct tmscp_softc *sc;
1512:     int flgs;
1513:     {
1514:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1515: 
1516:     mp->mscp_opcode = M_OP_STUNT;
1517:     mp->mscp_modifier = flgs | M_MD_EXCAC;
1518:     tms_cache_cmn(sc, tms, mp);
1519: 
1520: /*
1521:  * Set the unit flags - this includes the cache enable/disable flags.
1522: */
1523: 
1524:     mp->mscp_unitflgs = tms->tms_unitflgs;
1525: 
1526: /*
1527:  * Only initialize the density if the position is not at BOT.  On some
1528:  * drives (notably the TU81) selecting a density other than the 'current'
1529:  * (0) causes an illegal command error.
1530: */
1531:     if  (tms->tms_position != 0)
1532:         mp->mscp_format = 0;
1533:     else
1534:         mp->mscp_format = tms->tms_format;
1535:     }
1536: 
1537: /*
1538:  * Initialize the mscp packet for a REPOS command.  The 'flgs' parameter
1539:  * specifies if the movement if forwards or backwards and if records or
1540:  * tape marks (objects) are to be skipped.
1541: */
1542: 
1543: tms_repos_st(mp, sc, flgs)
1544:     register struct mscp    *mp;
1545:     register struct tmscp_softc *sc;
1546:     int flgs;
1547:     {
1548:     struct  buf *bp = (struct buf *)mp->mscp_cmdref;
1549:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1550: 
1551:     mp->mscp_opcode = M_OP_REPOS;
1552:     mp->mscp_modifier = flgs | M_MD_CLSEX;
1553:     tms->Tflags &= ~_CLSEREX;
1554:     tms_cache_cmn(sc, tms, mp); /* shared code with tms_reposrec_st */
1555:     if  (mp->mscp_modifier & M_MD_OBJCT)
1556:         mp->mscp_reccnt = bp->b_bcount;
1557:     else
1558:         mp->mscp_tmkcnt = bp->b_bcount;
1559:     }
1560: 
1561: /*
1562:  * Initialize the mscp packet for a REPOS 'record' command.  Tape records do
1563:  * not include tapemarks (which is why this is a separate routine from
1564:  * tms_repos_st above).
1565: */
1566: 
1567: tms_reposrec_st(mp, sc, flgs)
1568:     register struct mscp    *mp;
1569:     register struct tmscp_softc *sc;
1570:     int flgs;
1571:     {
1572:     struct  buf *bp = (struct buf *)mp->mscp_cmdref;
1573:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1574: 
1575:     mp->mscp_opcode = M_OP_REPOS;
1576:     mp->mscp_modifier = flgs;
1577:     tms_cache_cmn(sc, tms, mp);
1578:     mp->mscp_reccnt = bp->b_bcount;
1579:     }
1580: 
1581: /*
1582:  * Initialize the mscp packet for an AVAIL command.  The only time this is
1583:  * done is on a 'rewoffl' command.
1584: */
1585: 
1586: tms_avail_st(mp, sc, flgs)
1587:     register struct mscp    *mp;
1588:     struct  tmscp_softc *sc;
1589:     int flgs;
1590:     {
1591:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1592: 
1593:     mp->mscp_opcode = M_OP_AVAIL;
1594:     mp->mscp_modifier = flgs;
1595:     tms_clrerr(tms, mp);
1596:     }
1597: 
1598: tms_clrerr(tms, mp)
1599:     register struct tms_info *tms;
1600:     register struct mscp *mp;
1601:     {
1602: 
1603:     mp->mscp_modifier |= M_MD_CLSEX;
1604:     tms->Tflags &= ~_CLSEREX;
1605:     if  (tms->Tflags & _CACHE_LOST)
1606:         {
1607:         tms->Tflags &= ~(_CACHE_LOST | _CACHE_WRITTEN);
1608:         mp->mscp_modifier |= M_MD_CDATL;
1609:         }
1610:     }
1611: 
1612: /*
1613:  * Initialize the mscp packet for a WTM (write tapemark) command.
1614: */
1615: 
1616: tms_wtm_st(mp, sc, flgs)
1617:     register struct mscp    *mp;
1618:     register struct tmscp_softc *sc;
1619:     int flgs;
1620:     {
1621:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1622: 
1623:     mp->mscp_opcode = M_OP_WRITM;
1624:     mp->mscp_modifier = flgs | M_MD_CLSEX;
1625:     tms->Tflags &= ~_CLSEREX;
1626:     tms_cache_cmn(sc, tms, mp);
1627:     }
1628: 
1629: tms_cache_cmn(sc, tms, mp)
1630:     register struct tmscp_softc *sc;
1631:     register struct tms_info *tms;
1632:     register struct mscp *mp;
1633:     {
1634: 
1635:     if  (tms->Tflags & _CACHE_LOST)
1636:         {
1637:         if  (!(tms->Tflags & _CACHE_WRITTEN))
1638:             {
1639:             tms->Tflags &= ~(_CACHE_LOST | _CACHE_WRITTEN);
1640:             mp->mscp_modifier |= M_MD_CDATL;
1641:             }
1642:         else
1643:             log(LOG_INFO, "tms%d,%d clost\n",
1644:                 sc->sc_unit, mp->mscp_unit);
1645:         }
1646:     }
1647: 
1648: /*
1649:  * Process the end message from a REPOS command.  Called from tmscprsp().
1650: */
1651: 
1652: tms_repos_em(mp, sc)
1653:     register struct mscp *mp;
1654:     register struct tmscp_softc *sc;
1655:     {
1656:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1657:     u_short em_status = mp->mscp_status & M_ST_MASK;
1658: 
1659:     (void)tms_check_ret(mp, sc);
1660:     if  (em_status == M_ST_SUCC)
1661:         {
1662:         if  (tms->tms_position != mp->mscp_position)
1663:             tms->tms_flags &= ~MTF_WRITTEN;
1664:         if  (tms->tms_position = mp->mscp_position)
1665:             tms->tms_flags &= ~MTF_BOM;
1666:         else
1667:             {
1668:             tms->tms_flags |= MTF_BOM;
1669:             tms->Tflags &= ~_LOST;
1670:             }
1671:         tms->Tflags &= ~_CACHE_WRITTEN;
1672:         }
1673:     tms->tms_resid = 0;
1674:     tms_iodone(mp, sc);
1675:     }
1676: 
1677: /*
1678:  * Process the end message from a STUNT command.
1679: */
1680: 
1681: tms_stunt_em(mp, sc)
1682:     register struct mscp *mp;
1683:     register struct tmscp_softc *sc;
1684:     {
1685:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1686:     u_short em_status = mp->mscp_status & M_ST_MASK;
1687: 
1688:     (void)tms_check_ret(mp, sc);
1689:     tms->Tflags &= ~_CACHE_WRITTEN;
1690:     if  (em_status == M_ST_SUCC)
1691:         {
1692:         tms->tms_unitflgs = mp->mscp_unitflgs;
1693:         tms->tms_format = mp->mscp_format;
1694:         tms->tms_type = mp->mscp_mediaid;
1695:         tms->Tflags |= _ONLINE;
1696:         }
1697:     tms->tms_resid = 0;
1698:     tms_iodone(mp, sc);
1699:     }
1700: 
1701: /*
1702:  * Process the end message from a WRITM (Write Tape Mark) command.
1703: */
1704: 
1705: tms_wtm_em(mp, sc)
1706:     register struct mscp *mp;
1707:     register struct tmscp_softc *sc;
1708:     {
1709:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1710:     u_short em_status = mp->mscp_status & M_ST_MASK;
1711: 
1712:     if  (em_status == M_ST_SUCC)
1713:         {
1714:         tms->tms_flags &= ~MTF_WRITTEN;
1715:         tms->tms_position = mp->mscp_position;
1716:         }
1717:     (void)tms_check_ret(mp, sc);
1718:     tms->tms_resid = 0;
1719:     tms_iodone(mp, sc);
1720:     }
1721: 
1722: tms_avail_em(mp, sc)
1723:     register struct mscp *mp;
1724:     register struct tmscp_softc *sc;
1725:     {
1726:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1727: 
1728:     (void)tms_check_ret(mp, sc);
1729:     tms->Tflags &= ~(_INUSE | _ONLINE);
1730:     tms->tms_position = 0;
1731:     tms->tms_flags |= MTF_BOM;
1732:     if  (tms->tms_status == M_ST_SUCC)
1733:         tms->Tflags &= ~_CACHE_WRITTEN;
1734:     tms->tms_resid = 0;
1735:     tms_iodone(mp, sc);
1736:     }
1737: 
1738: tms_flush_em(mp, sc)
1739:     register struct mscp *mp;
1740:     register struct tmscp_softc *sc;
1741:     {
1742:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1743:     u_short em_status = mp->mscp_status & M_ST_MASK;
1744: 
1745:     if  (em_status == M_ST_SUCC)
1746:         tms->Tflags &= ~_CACHE_WRITTEN;
1747:     else
1748:         log(LOG_INFO, "tms%d,%d Flush\n",sc->sc_unit,mp->mscp_unit);
1749:     tms->tms_position = mp->mscp_position;
1750:     (void)tms_check_ret(mp, sc);
1751:     tms->tms_resid = 0;
1752:     tms_iodone(mp, sc);
1753:     }
1754: 
1755: tms_gtunt_em(mp, sc)
1756:     register struct mscp *mp;
1757:     register struct tmscp_softc *sc;
1758:     {
1759:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1760:     u_short em_status = mp->mscp_status & M_ST_MASK;
1761:     u_short em_flags = mp->mscp_unitflgs;
1762: 
1763:     (void)tms_check_ret(mp, sc);
1764:     if  (em_status == M_ST_SUCC)
1765:         {
1766:         tms->tms_format = mp->mscp_format;
1767:         tms->tms_type = mp->mscp_mediaid;
1768:         tms->tms_fmtmenu = mp->mscp_fmtmenu;
1769:         tms->tms_unitflgs = mp->mscp_unitflgs;
1770:         tms->Tflags |= _ONLINE;
1771:         if  (em_flags & (M_UF_WRTPH | M_UF_WRTPS | M_UF_WRTPD))
1772:             tms->tms_flags |= MTF_WRTLCK;
1773:         else
1774:             tms->tms_flags &= ~MTF_WRTLCK;
1775:         if  (em_flags & M_UF_CACH)
1776:             {
1777:             tms->Tflags |= _HASCACHE;
1778:             if  (tms->Tflags & _CACHE_ON)
1779:                 {
1780:                 tms->tms_unitflgs |= M_UF_WBKNV;
1781:                 tms->tms_unitflgs &= ~M_UF_SCCHH;
1782:                 }
1783:             else
1784:                 {
1785:                 tms->tms_unitflgs &= ~M_UF_WBKNV;
1786:                 tms->tms_unitflgs |= M_UF_SCCHH;
1787:                 }
1788:             }
1789:         if  (tms->tms_position == 0)
1790:             tms->tms_flags |= MTF_BOM;
1791:         else
1792:             tms->tms_flags &= ~MTF_BOM;
1793:         }
1794:     tms->tms_resid = 0;
1795:     tms_iodone(mp, sc);
1796:     }
1797: 
1798: tms_rw_em(mp, sc)
1799:     register struct mscp *mp;
1800:     register struct tmscp_softc *sc;
1801:     {
1802:     struct  buf *bp = (struct buf *)mp->mscp_cmdref;
1803:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1804:     u_short em_status = mp->mscp_status & M_ST_MASK;
1805: 
1806:     tms->tms_flags &= ~MTF_WRITTEN;
1807:     (void)tms_check_ret(mp, sc);
1808:     if  (em_status == M_ST_SUCC)
1809:         {
1810:         if  ((tms->tms_endcode & ~M_OP_END) == M_OP_WRITE)
1811:             tms->tms_flags |= MTF_WRITTEN;
1812:         else
1813:             tms->Tflags &= ~_CACHE_WRITTEN;
1814:         }
1815:     tms->tms_resid = bp->b_bcount - mp->mscp_bytecnt;
1816:     if  (tms->tms_position = mp->mscp_position)
1817:         tms->tms_flags &= ~MTF_BOM;
1818:     else
1819:         tms->tms_flags |= MTF_BOM;
1820:     tms_iodone(mp, sc);
1821:     }
1822: 
1823: tms_iodone(mp, sc)
1824:     struct  mscp    *mp;
1825:     struct  tmscp_softc *sc;
1826:     {
1827:     struct  tms_info *tms = sc->sc_drives[mp->mscp_unit];
1828:     register struct buf *bp = (struct buf *)mp->mscp_cmdref;
1829:     register struct buf *dp = &tms->tms_dtab;
1830: 
1831: /*
1832:  * Remove the buffer from the I/O wait queue.  Set the residual count and
1833:  * declare the I/O done.
1834: */
1835:     bp->av_back->av_forw = bp->av_forw;
1836:     bp->av_forw->av_back = bp->av_back;
1837:     dp->b_qsize--;
1838:     bp->b_resid = tms->tms_resid;
1839:     iodone(bp);
1840:     }
1841: 
1842: /*
1843:  * Check the return status of an mscp packet and adjust the drive's flags
1844:  * appropriately.  On error conditions set the error flag and code in the
1845:  * buffer header.
1846:  *
1847:  * Many of the 'case' statements below are finer grained than strictly
1848:  * necessary - this is done to provide easy access for logging of specific
1849:  * conditions during debugging.
1850: */
1851: 
1852: tms_check_ret(mp, sc)
1853:     struct  mscp    *mp;
1854:     struct  tmscp_softc *sc;
1855:     {
1856:     register struct tms_info *tms = sc->sc_drives[mp->mscp_unit];
1857:     register struct buf *bp = (struct buf *)mp->mscp_cmdref;
1858:     u_short em_status = mp->mscp_status & M_ST_MASK;
1859:     u_short em_subcode = mp->mscp_status >> M_ST_SBBIT;
1860:     u_short em_flags = mp->mscp_flags;
1861:     u_short em_endcode = mp->mscp_endcode & ~M_OP_END;
1862:     char    berr, unkerr;
1863: 
1864:     if  (em_status != M_ST_SUCC && em_status != M_ST_TAPEM &&
1865:             (tmscpprintf & 0x1))
1866:         log(LOG_INFO, "tms%d,%d st=%x sb=%x fl=%x en=%x\n",
1867:             sc->sc_unit, mp->mscp_unit,
1868:             em_status, em_subcode, em_flags, em_endcode);
1869:     tms->tms_endcode = mp->mscp_endcode;
1870:     if  (em_flags & M_EF_EOT)
1871:         tms->tms_flags |= MTF_EOM;
1872:     else
1873:         tms->tms_flags &= ~MTF_EOM;
1874:     if  (em_flags & M_EF_DLS)
1875:         tms->Tflags |= _CACHE_LOST;
1876:     if  (em_flags & M_EF_PLS)
1877:         tms->Tflags |= _LOST;
1878:     tms->tms_status = mp->mscp_status;
1879: 
1880:     berr = 0;
1881:     unkerr = 0;
1882: 
1883:     switch  (em_status)
1884:         {
1885:         case    M_ST_SUCC:
1886:             {
1887:             switch  (em_subcode)
1888:                 {
1889:                 case    M_SC_DUPUN: /* Duplicate unit */
1890:                     berr = ENXIO;
1891:                     break;
1892:                 case    M_SC_ALONL: /* Already online */
1893:                 case    M_SC_STONL: /* Still online */
1894:                 case    M_SC_UNIGN: /* Unload ignored */
1895:                 case    M_SC_ROVOL: /* Readonly unit */
1896:                     tms->Tflags |= _ONLINE;
1897:                     break;
1898:                 case    M_SC_EOT:   /* End of Tape */
1899:                     tms->tms_flags |= MTF_EOM;
1900:                     break;
1901:                 }
1902:             }
1903:             break;
1904:         case    M_ST_OFFLN:
1905:             tms->Tflags &= ~_ONLINE;
1906:             if  ((tms->Tflags & _CACHE_ON) &&
1907:                  (tms->Tflags & _CACHE_WRITTEN))
1908:                 log(LOG_INFO, "tms%d,%d closs2\n",
1909:                     sc->sc_unit, mp->mscp_unit);
1910:             berr = ENXIO;
1911:             break;
1912:         case    M_ST_WRTPR:         /* Write Protected */
1913:             tms->tms_flags |= MTF_WRTLCK;
1914:             berr = EACCES;          /* Really an error ? */
1915:             break;
1916:         case    M_ST_ICMD:          /* Byte count too big */
1917:         case    M_ST_ABRTD:         /* Command aborted */
1918:         case    M_ST_COMP:          /* Data Compare error */
1919:         case    M_ST_DATA:          /* Data error */
1920:         case    M_ST_HSTBF:         /* Host buffer error */
1921:         case    M_ST_CNTLR:         /* Controller error */
1922:         case    M_ST_FMTER:         /* Formatter error */
1923:             berr = EIO;
1924:             break;
1925:         case    M_ST_AVLBL:         /* Unit available */
1926:             tms->Tflags &= ~(_LOST | _CLSEREX | _SEREX | _ONLINE);
1927:             break;
1928:         case    M_ST_BOT:           /* Beginning of tape */
1929:             tms->tms_flags |= MTF_BOM;
1930:             tms->tms_position = 0;
1931:             break;
1932:         case    M_ST_TAPEM:         /* Tape Mark */
1933:             tms->Tflags |= (_BUFMARK | _CLSEREX);
1934:             break;
1935:         case    M_ST_SEX:           /* Serious Exception */
1936:             if  (em_flags & M_EF_EOT)
1937:                 {
1938:                 tms->tms_flags |= MTF_EOM;
1939:                 berr = ENOSPC;
1940:                 }
1941:             else
1942:                 {
1943:                 tms->Tflags &= ~_CLSEREX;
1944:                 log(LOG_INFO, "tms%d,%d serex sb %x\n",
1945:                     sc->sc_unit, mp->mscp_unit, em_subcode);
1946:                 berr = EIO;
1947:                 }
1948:             break;
1949:         case    M_ST_PLOST:         /* Position Lost */
1950:             log(LOG_INFO, "tms%d,%d plost\n", sc->sc_unit,
1951:                     mp->mscp_unit);
1952:             tms->Tflags |= (_LOST | _SEREX);
1953:             tms->Tflags &= ~_CLSEREX;
1954:             berr = EIO;
1955:             break;
1956:         case    M_ST_LED:           /* Logical end of dev */
1957:             tms->Tflags |= _CLSEREX;
1958:             break;
1959:         case    M_ST_MFMTE:         /* Media format err */
1960:         case    M_ST_DRIVE:         /* Drive error */
1961:         case    M_ST_RDTRN:         /* Record truncated */
1962:             tms->Tflags |= _SEREX;
1963:             tms->Tflags &= ~_CLSEREX;
1964:         case    M_ST_LOADR:
1965:         case    M_ST_DIAG:          /* Intern diag err */
1966:         case    M_ST_IPARM:         /* Invalid parameter */
1967:             berr = EIO;
1968:             break;
1969:         default:
1970:             unkerr = 1;
1971:             berr = EIO;
1972:             break;
1973:         }
1974:     if  (unkerr)
1975:         log(LOG_INFO, "tms%d,%d: st/sb =%x/%x\n",
1976:             sc->sc_unit, mp->mscp_unit, em_status, em_subcode);
1977:     if  (berr && bp)
1978:         {
1979:         bp->b_flags |= B_ERROR;
1980:         bp->b_error = berr;
1981:         }
1982:     return;
1983:     }
1984: 
1985: /*
1986:  * Process an error log datagram.
1987:  *
1988:  * No decoding is done - it wasn't worth the D space.  If bit 1 is set
1989:  * in the print flags then a simple message is generated out of (hopefully)
1990:  * useful fields.
1991:  *
1992:  * Eventually a error log daemon will be written and the datagram sent to
1993:  * it for capture and detailed analysis.  Until then the logging in
1994:  * 'tms_check_ret' and a few other strategic spots will have to suffice.
1995:  */
1996: 
1997:     u_short tms_datagrams[NTMSCP];
1998: 
1999: tmserror(ctlr, mp)
2000:     int ctlr;
2001:     register struct mslg *mp;
2002:     {
2003: 
2004:     tms_datagrams[ctlr]++;
2005:     if  (tmscpprintf & 0x2)
2006:         log(LOG_INFO,
2007:         "tms%d,%d dgram fmt=%x evt=%x grp=%x flg=%x pos=%D\n",
2008:             ctlr, mp->mslg_unit, mp->mslg_format,
2009:             mp->mslg_event, mp->mslg_group, mp->mslg_flags,
2010:             mp->mslg_position);
2011:     }
2012: #endif NTMSCP

Defined functions

getdd defined in line 406; used 1 times
tkini defined in line 935; used 3 times
tmsVec defined in line 367; never used
tms_avail_em defined in line 1722; used 1 times
tms_avail_st defined in line 1586; used 1 times
tms_cache_cmn defined in line 1629; used 4 times
tms_check_ret defined in line 1852; used 7 times
tms_clrerr defined in line 1598; used 3 times
tms_flush_em defined in line 1738; used 1 times
tms_gtunt_em defined in line 1755; used 1 times
tms_iodone defined in line 1823; used 8 times
tms_repos_em defined in line 1652; used 1 times
tms_repos_st defined in line 1543; used 4 times
tms_reposrec_st defined in line 1567; used 2 times
tms_rw_em defined in line 1798; used 1 times
tms_stunt_em defined in line 1681; used 1 times
tms_stunt_st defined in line 1509; used 3 times
tms_wrteof defined in line 1484; used 2 times
tms_wtm_em defined in line 1705; used 1 times
tms_wtm_st defined in line 1616; used 1 times
tmsattach defined in line 386; never used
tmscpclose defined in line 754; never used
tmscpcommand defined in line 803; used 10 times
tmscpgetcp defined in line 894; used 4 times
tmscpioctl defined in line 1401; never used
tmscpopen defined in line 617; never used
tmscprsp defined in line 1187; used 2 times
tmscpstrategy defined in line 1335; used 1 times
tmserror defined in line 1999; used 1 times
tmsginit defined in line 860; used 3 times
tmsintr defined in line 452; used 1 times
tmsstart defined in line 971; used 2 times
tmswatchdog defined in line 849; used 3 times
wait_step defined in line 428; used 3 times

Defined variables

Dmatrix defined in line 276; used 1 times
sccsid defined in line 6; never used
tms_datagrams defined in line 1997; used 1 times
tms_info defined in line 285; used 2 times
  • in line 411(2)
tmscp defined in line 287; used 13 times
tmscp_cp_wait defined in line 337; used 5 times
tmscp_softc defined in line 284; used 9 times
tmscpcache defined in line 361; used 2 times
tmscpfatalerr defined in line 335; used 4 times
tmscpprintf defined in line 352; used 7 times
tmscpstepfailed defined in line 334; used 1 times

Defined macros

STEP1GOOD defined in line 477; used 1 times
STEP1MASK defined in line 476; used 1 times
STEP2GOOD defined in line 488; used 1 times
STEP2MASK defined in line 487; used 1 times
STEP3GOOD defined in line 499; used 1 times
STEP3MASK defined in line 498; used 1 times
S_IDLE defined in line 327; used 4 times
S_RUN defined in line 332; used 4 times
S_SCHAR defined in line 331; used 1 times
S_STEP1 defined in line 328; used 1 times
S_STEP2 defined in line 329; used 1 times
S_STEP3 defined in line 330; used 1 times
TMSDEBUG defined in line 1; never used
TMS_BSF defined in line 311; used 1 times
TMS_BSR defined in line 313; used 2 times
TMS_CACHE defined in line 317; used 1 times
TMS_CSE defined in line 321; used 2 times
TMS_FLUSH defined in line 319; used 2 times
TMS_FSF defined in line 310; used 1 times
TMS_FSR defined in line 312; used 1 times
TMS_NOCACHE defined in line 318; used 1 times
TMS_OFFL defined in line 315; used 1 times
TMS_REW defined in line 314; used 2 times
TMS_SENSE defined in line 316; used 2 times
TMS_SETDENSITY defined in line 322; used 1 times
TMS_WRITM defined in line 309; used 3 times
_BUFMARK defined in line 297; used 4 times
_CACHE_LOST defined in line 300; used 5 times
_CACHE_ON defined in line 299; used 8 times
_CACHE_WRITTEN defined in line 301; used 14 times
_CLSEREX defined in line 295; used 13 times
_HASCACHE defined in line 298; used 3 times
_INUSE defined in line 302; used 5 times
_LOST defined in line 296; used 5 times
_ONLINE defined in line 303; used 16 times
_SEREX defined in line 294; used 4 times
b_qsize defined in line 365; used 2 times
Last modified: 1999-02-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 274
Valid CSS Valid XHTML 1.0 Strict