xref: /original-bsd/sys/vax/mba/mt.c (revision cd18b70b)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)mt.c	7.1 (Berkeley) 06/05/86
7  */
8 
9 #include "mu.h"
10 #if NMT > 0
11 /*
12  * TM78/TU78 tape driver
13  *
14  *	Original author - ?
15  *	Most error recovery bug fixes - ggs (ulysses!ggs)
16  *
17  * OPTIONS:
18  *	MTLERRM - Long error message text - twd, Brown University
19  *	MTRDREV - `read reverse' error recovery - ggs (ulysses!ggs)
20  *
21  * TODO:
22  *	Add odd byte count kludge from VMS driver (?)
23  *	Write dump routine
24  */
25 
26 #include "../machine/pte.h"
27 
28 #include "param.h"
29 #include "systm.h"
30 #include "buf.h"
31 #include "conf.h"
32 #include "dir.h"
33 #include "file.h"
34 #include "user.h"
35 #include "map.h"
36 #include "ioctl.h"
37 #include "mtio.h"
38 #include "cmap.h"
39 #include "uio.h"
40 #include "tty.h"
41 
42 #include "../vax/cpu.h"
43 #include "mbareg.h"
44 #include "mbavar.h"
45 #include "mtreg.h"
46 
47 #define MTTIMEOUT	10000		/* loop limit for controller test */
48 #define	INF		1000000L	/* a block number that won't exist */
49 #define MASKREG(r)	((r) & 0xffff)	/* the control registers have 16 bits */
50 
51 /* Bits for sc_flags */
52 
53 #define	H_WRITTEN	01		/* last operation was a write */
54 #define H_EOT		02		/* end of tape encountered */
55 #define H_IEOT		04		/* ignore EOT condition */
56 
57 /* Bits in minor device */
58 
59 #define	MUUNIT(dev)	(minor(dev)&03)
60 #define	H_NOREWIND	04
61 #define	H_6250BPI	010
62 
63 #define MTUNIT(dev)	(mutomt[MUUNIT(dev)])
64 
65 #ifdef MTRDREV
66 	int mt_do_readrev = 1;
67 #else
68 	int mt_do_readrev = 0;
69 #endif
70 
71 /* Per unit status information */
72 
73 struct	mu_softc {
74 	char	sc_openf;		/* unit is open if != 0 */
75 	char	sc_flags;		/* state flags */
76 	daddr_t	sc_blkno;		/* current physical block number */
77 	daddr_t	sc_nxrec;		/* firewall input block number */
78 	u_short	sc_erreg;		/* copy of mter or mtner */
79 	u_short	sc_dsreg;		/* copy of mtds */
80 	short	sc_resid;		/* residual function count for ioctl */
81 	short	sc_dens;		/* density code - MT_GCR or zero */
82 	struct	mba_device *sc_mi;	/* massbus structure for unit */
83 	int	sc_slave;		/* slave number for unit */
84 	int	sc_i_mtas;		/* mtas at slave attach time */
85 	int	sc_i_mtner;		/* mtner at slave attach time */
86 	int	sc_i_mtds;		/* mtds at slave attach time */
87 #ifdef MTLERRM
88 	char	*sc_mesg;		/* text for interrupt type code */
89 	char	*sc_fmesg;		/* text for tape error code */
90 #endif
91 	struct	tty *sc_ttyp;		/* record user's tty for errors */
92 } mu_softc[NMU];
93 
94 struct	buf	rmtbuf[NMT];		/* data transfer buffer structures */
95 struct	buf	cmtbuf[NMT];		/* tape command buffer structures */
96 
97 struct	mba_device *mtinfo[NMT];	/* unit massbus structure pointers */
98 short	mutomt[NMU];			/* tape unit to controller number map */
99 char	mtds_bits[] = MTDS_BITS;	/* mtds bit names for error messages */
100 short	mttypes[] = { MBDT_TU78, 0 };
101 
102 int	mtattach(), mtslave(), mtustart(), mtstart(), mtndtint(), mtdtint();
103 struct	mba_driver mtdriver =
104 	{ mtattach, mtslave, mtustart, mtstart, mtdtint, mtndtint,
105 	  mttypes, "mt", "mu", mtinfo };
106 
107 void mtcreset();
108 
109 /*ARGSUSED*/
110 mtattach(mi)
111 	struct mba_device *mi;
112 {
113 }
114 
115 mtslave(mi, ms, sn)
116 	struct mba_device *mi;
117 	struct mba_slave *ms;
118 	int sn;
119 {
120 	register struct mu_softc *sc = &mu_softc[ms->ms_unit];
121 	register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv;
122 	int s = spl5(), rtn = 0, i;
123 
124 	/* Just in case the controller is ill, reset it.  Then issue	*/
125 	/* a sense operation and wait about a second for it to respond.	*/
126 
127 	mtcreset(mtaddr);
128 	mtaddr->mtas = -1;
129 	mtaddr->mtncs[sn] = MT_SENSE|MT_GO;
130 	for (i = MTTIMEOUT; i> 0; i--) {
131 		DELAY(50);
132 		if (MASKREG(mtaddr->mtas) != 0)
133 			break;
134 	}
135 	sc->sc_i_mtas = mtaddr->mtas;
136 	sc->sc_i_mtner = mtaddr->mtner;
137 	sc->sc_i_mtds = mtaddr->mtds;
138 
139 	/* If no response, whimper.  If wrong response, call it an	*/
140 	/* unsolicited interrupt and use mtndtint to log and correct.	*/
141 	/* Otherwise, note whether this slave exists.			*/
142 
143 	if (i <= 0) {
144 		printf("mt: controller hung\n");
145 	} else if ((mtaddr->mtner & MTER_INTCODE) != MTER_DONE) {
146 		(void) mtndtint(mi);
147 	} else if (mtaddr->mtds & MTDS_PRES) {
148 		sc->sc_mi = mi;
149 		sc->sc_slave = sn;
150 		mutomt[ms->ms_unit] = mi->mi_unit;
151 		rtn = 1;
152 	}
153 
154 	/* Cancel the interrupt, then wait a little while for it to go away. */
155 
156 	mtaddr->mtas = mtaddr->mtas;
157 	DELAY(10);
158 	splx(s);
159 	return (rtn);
160 }
161 
162 mtopen(dev, flag)
163 	dev_t dev;
164 	int flag;
165 {
166 	register int muunit;
167 	register struct mba_device *mi;
168 	register struct mu_softc *sc;
169 
170 	muunit = MUUNIT(dev);
171 	if (   (muunit >= NMU)
172 	    || ((mi = mtinfo[MTUNIT(dev)]) == 0)
173 	    || (mi->mi_alive == 0) )
174 		return (ENXIO);
175 	if ((sc = &mu_softc[muunit])->sc_openf)
176 		return (EBUSY);
177 	sc->sc_dens = (minor(dev) & H_6250BPI) ? MT_GCR : 0;
178 	mtcommand(dev, MT_SENSE, 1);
179 	if ((sc->sc_dsreg & MTDS_ONL) == 0) {
180 		uprintf("mu%d: not online\n", muunit);
181 		return (EIO);
182 	}
183 	if ((sc->sc_dsreg & MTDS_AVAIL) == 0) {
184 		uprintf("mu%d: not online (port selector)\n", muunit);
185 		return (EIO);
186 	}
187 	if ((flag & FWRITE) && (sc->sc_dsreg & MTDS_FPT)) {
188 		uprintf("mu%d: no write ring\n", muunit);
189 		return (EIO);
190 	}
191 	if (   ((sc->sc_dsreg & MTDS_BOT) == 0)
192 	    && (flag & FWRITE)
193 	    && (   (   (sc->sc_dens == MT_GCR)
194 		    && (sc->sc_dsreg & MTDS_PE) )
195 		|| (   (sc->sc_dens != MT_GCR)
196 		    && ((sc->sc_dsreg & MTDS_PE) == 0)))) {
197 		uprintf("mu%d: can't change density in mid-tape\n", muunit);
198 		return (EIO);
199 	}
200 	sc->sc_openf = 1;
201 	sc->sc_blkno = (daddr_t)0;
202 
203 	/* Since cooked I/O may do a read-ahead before a write, trash	*/
204 	/* on a tape can make the first write fail.  Suppress the first	*/
205 	/* read-ahead unless definitely doing read-write		*/
206 
207 	sc->sc_nxrec =  ((flag & (FTRUNC | FWRITE)) == (FTRUNC | FWRITE))
208 		      ? (daddr_t)0
209 		      : (daddr_t)INF;
210 	sc->sc_flags = 0;
211 	sc->sc_ttyp = u.u_ttyp;
212 	return (0);
213 }
214 
215 mtclose(dev, flag)
216 	register dev_t dev;
217 	register int flag;
218 {
219 	register struct mu_softc *sc = &mu_softc[MUUNIT(dev)];
220 
221 	if (   ((flag & (FREAD | FWRITE)) == FWRITE)
222 	    || (   (flag & FWRITE)
223 		&& (sc->sc_flags & H_WRITTEN) ))
224 		mtcommand(dev, MT_CLS|sc->sc_dens, 1);
225 	if ((minor(dev) & H_NOREWIND) == 0)
226 		mtcommand(dev, MT_REW, 0);
227 	sc->sc_openf = 0;
228 }
229 
230 mtcommand(dev, com, count)
231 	dev_t dev;
232 	int com, count;
233 {
234 	register struct buf *bp;
235 	register int s;
236 
237 	bp = &cmtbuf[MTUNIT(dev)];
238 	s = spl5();
239 	while (bp->b_flags & B_BUSY) {
240 		if((bp->b_repcnt == 0) && (bp->b_flags & B_DONE))
241 			break;
242 		bp->b_flags |= B_WANTED;
243 		sleep((caddr_t)bp, PRIBIO);
244 	}
245 	bp->b_flags = B_BUSY|B_READ;
246 	splx(s);
247 	bp->b_dev = dev;
248 	bp->b_command = com;
249 	bp->b_repcnt = count;
250 	bp->b_blkno = 0;
251 	bp->b_error = 0;
252 	mtstrategy(bp);
253 	if (count == 0)
254 		return;
255 	iowait(bp);
256 	if (bp->b_flags & B_WANTED)
257 		wakeup((caddr_t)bp);
258 	bp->b_flags &= B_ERROR;
259 }
260 
261 mtstrategy(bp)
262 	register struct buf *bp;
263 {
264 	register struct mba_device *mi = mtinfo[MTUNIT(bp->b_dev)];
265 	register struct buf *dp;
266 	register int s;
267 
268 	/* If this is a data transfer operation, set the resid to a	*/
269 	/* default value (EOF) to simplify getting it right during	*/
270 	/* error recovery or bail out.					*/
271 
272 	if (bp != &cmtbuf[MTUNIT(bp->b_dev)])
273 		bp->b_resid = bp->b_bcount;
274 
275 	/* Link this request onto the end of the queue for this		*/
276 	/* controller, then start I/O if not already active.		*/
277 
278 	bp->av_forw = NULL;
279 	dp = &mi->mi_tab;
280 	s = spl5();
281 	if (dp->b_actf == NULL)
282 		dp->b_actf = bp;
283 	else
284 		dp->b_actl->av_forw = bp;
285 	dp->b_actl = bp;
286 	if (dp->b_active == 0)
287 		mbustart(mi);
288 	splx(s);
289 }
290 
291 mtustart(mi)
292 	register struct mba_device *mi;
293 {
294 	register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv;
295 	register struct buf *bp = mi->mi_tab.b_actf;
296 	register struct mu_softc *sc = &mu_softc[MUUNIT(bp->b_dev)];
297 	daddr_t blkno;
298 	int count;
299 
300 	if (sc->sc_openf < 0) {
301 		bp->b_flags |= B_ERROR;
302 		return (MBU_NEXT);
303 	}
304 	if (bp != &cmtbuf[MTUNIT(bp->b_dev)]) {
305 
306 		/* Signal "no space" if out of tape unless suppressed	*/
307 		/* by MTIOCIEOT.					*/
308 
309 		if (   ((sc->sc_flags & (H_EOT | H_IEOT)) == H_EOT)
310 		    && ((bp->b_flags & B_READ) == 0) ) {
311 			bp->b_flags |= B_ERROR;
312 			bp->b_error = ENOSPC;
313 			return (MBU_NEXT);
314 		}
315 
316 		/* special case tests for cooked mode */
317 
318 		if (bp != &rmtbuf[MTUNIT(bp->b_dev)]) {
319 
320 			/* seek beyond end of file */
321 
322 			if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
323 				bp->b_flags |= B_ERROR;
324 				bp->b_error = ENXIO;
325 				return (MBU_NEXT);
326 			}
327 
328 			/* This should be end of file, but the buffer	   */
329 			/* system wants a one-block look-ahead.  Humor it. */
330 
331 			if (   (bdbtofsb(bp->b_blkno) == sc->sc_nxrec)
332 			    && (bp->b_flags & B_READ) ) {
333 				clrbuf(bp);
334 				return (MBU_NEXT);
335 			}
336 
337 			/* If writing, mark the next block invalid. */
338 
339 			if ((bp->b_flags & B_READ) == 0)
340 				sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1;
341 		}
342 	} else {
343 
344 		/* It's a command, do it now. */
345 
346 		mtaddr->mtncs[MUUNIT(bp->b_dev)] =
347 			(bp->b_repcnt<<8)|bp->b_command|MT_GO;
348 		return (MBU_STARTED);
349 	}
350 
351 	/* If raw I/O, or if the tape is positioned correctly for	*/
352 	/* cooked I/O, set the byte count, unit number and repeat count	*/
353 	/* then tell the MASSBUS to proceed.  Note that a negative	*/
354 	/* bcount tells mbstart to map the buffer for "read backwards".	*/
355 
356 	if (   (bp == &rmtbuf[MTUNIT(bp->b_dev)])
357 	    || ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) ) {
358 		if (mi->mi_tab.b_errcnt == 2) {
359 			mtaddr->mtbc = -(bp->b_bcount);
360 			mtaddr->mtca = MUUNIT(bp->b_dev);
361 		} else {
362 			mtaddr->mtbc = bp->b_bcount;
363 			mtaddr->mtca = (1<<2)|MUUNIT(bp->b_dev);
364 		}
365 		return (MBU_DODATA);
366 	}
367 
368 	/* Issue skip operations to position the next block for cooked I/O. */
369 
370 	if (blkno < bdbtofsb(bp->b_blkno))
371 		count = (unsigned)(bdbtofsb(bp->b_blkno) - blkno);
372 	else
373 		count = (unsigned)(blkno - bdbtofsb(bp->b_blkno));
374 	if (count > 0377)
375 		count = 0377;
376 	mtaddr->mtncs[MUUNIT(bp->b_dev)] = count | MT_SFORW|MT_GO;
377 	return (MBU_STARTED);
378 }
379 
380 mtstart(mi)
381 	register struct mba_device *mi;
382 {
383 	register struct buf *bp = mi->mi_tab.b_actf;
384 	register struct mu_softc *sc = &mu_softc[MUUNIT(bp->b_dev)];
385 
386 	if (bp->b_flags & B_READ)
387 		if (mi->mi_tab.b_errcnt == 2)
388 			return(MT_READREV|MT_GO);
389 		else
390 			return(MT_READ|MT_GO);
391 	else
392 		return(MT_WRITE|sc->sc_dens|MT_GO);
393 }
394 
395 mtdtint(mi, mbsr)
396 	register struct mba_device *mi;
397 	int mbsr;
398 {
399 	register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv;
400 	register struct buf *bp = mi->mi_tab.b_actf;
401 	register struct mu_softc *sc;
402 	register int er;
403 
404 	/* I'M still NOT SURE IF THIS SHOULD ALWAYS BE THE CASE SO FOR NOW... */
405 
406 	if ((mtaddr->mtca & 3) != MUUNIT(bp->b_dev)) {
407 		printf("mt: wrong unit!\n");
408 		mtaddr->mtca = MUUNIT(bp->b_dev);
409 	}
410 
411 	er = MASKREG(mtaddr->mter);
412 	sc = &mu_softc[MUUNIT(bp->b_dev)];
413 	sc->sc_erreg = er;
414 	if (bp->b_flags & B_READ)
415 		sc->sc_flags &= ~H_WRITTEN;
416 	else
417 		sc->sc_flags |= H_WRITTEN;
418 	switch (er & MTER_INTCODE) {
419 
420 	case MTER_EOT:
421 		sc->sc_flags |= H_EOT;
422 
423 		/* fall into MTER_DONE */
424 
425 	case MTER_DONE:
426 		sc->sc_blkno++;
427 		if (mi->mi_tab.b_errcnt == 2) {
428 			bp->b_bcount = bp->b_resid;
429 			bp->b_resid -= MASKREG(mtaddr->mtbc);
430 			if (   (bp->b_resid > 0)
431 			    && (bp != &rmtbuf[MTUNIT(bp->b_dev)]) )
432 				bp->b_flags |= B_ERROR;
433 		} else {
434 			bp->b_resid = 0;
435 		}
436 		break;
437 
438 	case MTER_SHRTREC:
439 		sc->sc_blkno++;
440 		bp->b_bcount = bp->b_resid;
441 		bp->b_resid -= MASKREG(mtaddr->mtbc);
442 		if (bp != &rmtbuf[MTUNIT(bp->b_dev)])
443 			bp->b_flags |= B_ERROR;
444 		break;
445 
446 	case MTER_RETRY:
447 
448 		/* Simple re-try.  Since resid is always a copy of the	*/
449 		/* original byte count, use it to restore the count.	*/
450 
451 		mi->mi_tab.b_errcnt = 1;
452 		bp->b_bcount = bp->b_resid;
453 		return(MBD_RETRY);
454 
455 	case MTER_RDOPP:
456 
457 		/* The controller just decided to read it backwards.	*/
458 		/* If the controller returns a byte count of zero,	*/
459 		/* change it to 1, since zero encodes 65536, which	*/
460 		/* isn't quite what we had in mind.  The byte count	*/
461 		/* may be larger than the size of the input buffer, so	*/
462 		/* limit the count to the buffer size.  After		*/
463 		/* making the byte count reasonable, set bcount to the	*/
464 		/* negative of the controller's version of the byte	*/
465 		/* count so that the start address for the transfer is	*/
466 		/* set up correctly.					*/
467 
468 		if (mt_do_readrev) {
469 			mi->mi_tab.b_errcnt = 2;
470 			if ((bp->b_bcount = MASKREG(mtaddr->mtbc)) == 0)
471 				bp->b_bcount = 1;
472 			if (bp->b_bcount > bp->b_resid)
473 				bp->b_bcount = bp->b_resid;
474 			bp->b_bcount = -(bp->b_bcount);
475 			return(MBD_RETRY);
476 		} else if (MASKREG(mtaddr->mtbc) <= bp->b_resid) {
477 			sc->sc_blkno++;
478 			bp->b_bcount = bp->b_resid;
479 			bp->b_resid -= MASKREG(mtaddr->mtbc);
480 			bp->b_flags |= B_ERROR;
481 			break;
482 		}
483 		bp->b_flags |= B_ERROR;
484 
485 		/* fall into MTER_LONGREC */
486 
487 	case MTER_LONGREC:
488 		sc->sc_blkno++;
489 		bp->b_bcount = bp->b_resid;
490 		bp->b_resid = 0;
491 		bp->b_error = ENOMEM;
492 		bp->b_flags |= B_ERROR;
493 		break;
494 
495 	case MTER_NOTCAP:
496 		printf("mu%d: blank tape\n", MUUNIT(bp->b_dev));
497 		goto err;
498 
499 	case MTER_TM:
500 
501 		/* End of file.  Since the default byte count has	*/
502 		/* already been set, just count the block and proceed.	*/
503 
504 		sc->sc_blkno++;
505 	err:
506 		if (bp != &rmtbuf[MTUNIT(bp->b_dev)])
507 			sc->sc_nxrec = bdbtofsb(bp->b_blkno);
508 		break;
509 
510 	case MTER_OFFLINE:
511 		if (sc->sc_openf > 0) {
512 			sc->sc_openf = -1;
513 			tprintf(sc->sc_ttyp, "mu%d: offline\n", MUUNIT(bp->b_dev));
514 		}
515 		bp->b_flags |= B_ERROR;
516 		break;
517 
518 	case MTER_NOTAVL:
519 		if (sc->sc_openf > 0) {
520 			sc->sc_openf = -1;
521 			tprintf(sc->sc_ttyp, "mu%d: offline (port selector)\n",
522 			    MUUNIT(bp->b_dev));
523 		}
524 		bp->b_flags |= B_ERROR;
525 		break;
526 
527 	case MTER_FPT:
528 		tprintf(sc->sc_ttyp, "mu%d: no write ring\n", MUUNIT(bp->b_dev));
529 		bp->b_flags |= B_ERROR;
530 		break;
531 
532 	case MTER_UNREAD:
533 		sc->sc_blkno++;
534 		bp->b_bcount = bp->b_resid;
535 		bp->b_resid -= MIN(MASKREG(mtaddr->mtbc), bp->b_bcount);
536 
537 		/* Code 010 means a garbage record, nothing serious. */
538 
539 		if (((er & MTER_FAILCODE) >> 10) == 010) {
540 			tprintf(sc->sc_ttyp, "mu%d: rn=%d bn=%d unreadable record\n",
541 			    MUUNIT(bp->b_dev), sc->sc_blkno, bp->b_blkno);
542 			bp->b_flags |= B_ERROR;
543 			break;
544 		}
545 
546 		/* Anything else might be a hardware problem,	*/
547 		/* fall into the error report.			*/
548 
549 	default:
550 
551 		/* The bits in sc->sc_dsreg are from the last sense	*/
552 		/* command.  To get the most recent copy, you have to	*/
553 		/* do a sense at interrupt level, which requires nested	*/
554 		/* error processing.  This is a bit messy, so leave	*/
555 		/* well enough alone.					*/
556 
557 		tprintf(sc->sc_ttyp, "mu%d: hard error (data transfer) rn=%d bn=%d mbsr=%b er=%o (octal) ds=%b\n",
558 		    MUUNIT(bp->b_dev), sc->sc_blkno, bp->b_blkno,
559 		    mbsr, mbsr_bits, er,
560 		    MASKREG(sc->sc_dsreg), mtds_bits);
561 #ifdef MTLERRM
562 		mtintfail(sc);
563 		printf("     interrupt code = %o (octal) <%s>\n     failure code = %o (octal) <%s>\n",
564 		    er & MTER_INTCODE, sc->sc_mesg,
565 		    (er & MTER_FAILCODE) >> 10, sc->sc_fmesg);
566 #endif
567 		bp->b_flags |= B_ERROR;
568 
569 		/* The TM78 manual says to reset the controller after	*/
570 		/* TM fault B or MASSBUS fault.				*/
571 
572 		if (   ((er & MTER_INTCODE) == MTER_TMFLTB)
573 		    || ((er & MTER_INTCODE) == MTER_MBFLT) ) {
574 			mtcreset(mtaddr);
575 		}
576 	}
577 
578 	/* Just in case some strange error slipped through, (drive off	*/
579 	/* line during read-reverse error recovery comes to mind) make	*/
580 	/* sure the byte count is reasonable.				*/
581 
582 	if (bp->b_bcount < 0)
583 		bp->b_bcount = bp->b_resid;
584 	return (MBD_DONE);
585 }
586 
587 mtndtint(mi)
588 	register struct mba_device *mi;
589 {
590 	register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv;
591 	register struct buf *bp = mi->mi_tab.b_actf;
592 	register struct mu_softc *sc;
593 	register int er, fc;
594 	int unit;
595 
596 	unit = (mtaddr->mtner >> 8) & 3;
597 	er = MASKREG(mtaddr->mtner);
598 	sc = &mu_softc[unit];
599 	sc->sc_erreg = er;
600 
601 	/* Check for unsolicited interrupts. */
602 
603 	if (bp == 0 || unit != MUUNIT(bp->b_dev)) {	/* consistency check */
604 		if ((er & MTER_INTCODE) != MTER_ONLINE) {
605 			printf("mt: unit %d unexpected interrupt (non data transfer) er=%o (octal) ds=%b\n",
606 			    unit, er, MASKREG(sc->sc_dsreg), mtds_bits);
607 #ifdef MTLERRM
608 			mtintfail(sc);
609 			printf("    interrupt code = %o (octal) <%s>\n    failure code = %o (octal) <%s>\n",
610 			    er & MTER_INTCODE, sc->sc_mesg,
611 			    (er & MTER_FAILCODE) >> 10, sc->sc_fmesg);
612 #endif
613 			if (   ((er & MTER_INTCODE) == MTER_TMFLTB)
614 			    || ((er & MTER_INTCODE) == MTER_MBFLT) ) {
615 
616 				/* Reset the controller, then set error	*/
617 				/* status if there was anything active	*/
618 				/* when the fault occurred.  This may	*/
619 				/* shoot an innocent bystander, but	*/
620 				/* it's better than letting an error	*/
621 				/* slip through.			*/
622 
623 				mtcreset(mtaddr);
624 				if (bp != 0) {
625 					bp->b_flags |= B_ERROR;
626 					return (MBN_DONE);
627 				}
628 			}
629 		}
630 		return (MBN_SKIP);
631 	}
632 	if (bp == 0)
633 		return (MBN_SKIP);
634 
635 	fc = (mtaddr->mtncs[unit] >> 8) & 0xff;
636 	sc->sc_resid = fc;
637 
638 	/* Clear the "written" flag after any operation that changes	*/
639 	/* the position of the tape.					*/
640 
641 	if (   (bp != &cmtbuf[MTUNIT(bp->b_dev)])
642 	    || (bp->b_command != MT_SENSE) )
643 		sc->sc_flags &= ~H_WRITTEN;
644 
645 	switch (er & MTER_INTCODE) {
646 
647 	case MTER_EOT:
648 		sc->sc_flags |= H_EOT;
649 
650 		/* fall into MTER_DONE */
651 
652 	case MTER_DONE:
653 
654 		/* If this is a command buffer, just update the status.	*/
655 
656 		if (bp == &cmtbuf[MTUNIT(bp->b_dev)]) {
657 	done:
658 			if (bp->b_command == MT_SENSE)
659 				sc->sc_dsreg = MASKREG(mtaddr->mtds);
660 			return (MBN_DONE);
661 		}
662 
663 		/* It's not a command buffer, must be a cooked I/O	*/
664 		/* skip operation (perhaps a shaky assumption, but it	*/
665 		/* wasn't my idea).					*/
666 
667 		if ((fc = bdbtofsb(bp->b_blkno) - sc->sc_blkno) < 0)
668 			sc->sc_blkno -= MIN(0377, -fc);
669 		else
670 			sc->sc_blkno += MIN(0377, fc);
671 		return (MBN_RETRY);
672 
673 	case MTER_ONLINE:		/* ddj -- shouldn't happen but did */
674 	case MTER_RWDING:
675 		return (MBN_SKIP);	/* ignore "rewind started" interrupt */
676 
677 	case MTER_NOTCAP:
678 		tprintf(sc->sc_ttyp, "mu%d: blank tape\n", MUUNIT(bp->b_dev));
679 		bp->b_flags |= B_ERROR;
680 		return (MBN_DONE);
681 
682 	case MTER_TM:
683 	case MTER_LEOT:
684 
685 		/* For an ioctl skip operation, count a tape mark as	*/
686 		/* a record.  If there's anything left to do, update	*/
687 		/* the repeat count and re-start the command.		*/
688 
689 		if (bp == &cmtbuf[MTUNIT(bp->b_dev)]) {
690 			if ((sc->sc_resid = bp->b_repcnt = fc - 1) == 0)
691 				return (MBN_DONE);
692 			else
693 				return (MBN_RETRY);
694 
695 		/* Cooked I/O again.  Just update the books and wait	*/
696 		/* for someone else to return end of file or complain	*/
697 		/* about a bad seek.					*/
698 
699 		} else if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) {
700 			sc->sc_nxrec = bdbtofsb(bp->b_blkno) + fc - 1;
701 			sc->sc_blkno = sc->sc_nxrec;
702 		} else {
703 			sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc;
704 			sc->sc_blkno = sc->sc_nxrec + 1;
705 		}
706 		return (MBN_RETRY);
707 
708 	case MTER_FPT:
709 		tprintf(sc->sc_ttyp, "mu%d: no write ring\n", MUUNIT(bp->b_dev));
710 		bp->b_flags |= B_ERROR;
711 		return (MBN_DONE);
712 
713 	case MTER_OFFLINE:
714 
715 		/* If `off line' was intentional, don't complain. */
716 
717 		if (   (bp == &cmtbuf[MTUNIT(bp->b_dev)])
718 		    && (bp->b_command == MT_UNLOAD) )
719 			return(MBN_DONE);
720 		if (sc->sc_openf > 0) {
721 			sc->sc_openf = -1;
722 			tprintf(sc->sc_ttyp, "mu%d: offline\n", MUUNIT(bp->b_dev));
723 		}
724 		bp->b_flags |= B_ERROR;
725 		return (MBN_DONE);
726 
727 	case MTER_NOTAVL:
728 		if (sc->sc_openf > 0) {
729 			sc->sc_openf = -1;
730 			tprintf(sc->sc_ttyp, "mu%d: offline (port selector)\n", MUUNIT(bp->b_dev));
731 		}
732 		bp->b_flags |= B_ERROR;
733 		return (MBN_DONE);
734 
735 	case MTER_BOT:
736 		if (bp == &cmtbuf[MTUNIT(bp->b_dev)])
737 			goto done;
738 
739 		/* fall through */
740 
741 	default:
742 		tprintf(sc->sc_ttyp, "mu%d: hard error (non data transfer) rn=%d bn=%d er=%o (octal) ds=%b\n",
743 		    MUUNIT(bp->b_dev), sc->sc_blkno, bp->b_blkno,
744 		    er, MASKREG(sc->sc_dsreg), mtds_bits);
745 #ifdef MTLERRM
746 		mtintfail(sc);
747 		printf("     interrupt code = %o (octal) <%s>\n     failure code = %o (octal) <%s>\n",
748 		    (er & MTER_INTCODE), sc->sc_mesg,
749 		    (er & MTER_FAILCODE) >> 10, sc->sc_fmesg);
750 #endif
751 		if (   ((er & MTER_INTCODE) == MTER_TMFLTB)
752 		    || ((er & MTER_INTCODE) == MTER_MBFLT) ) {
753 			mtcreset(mtaddr);	/* reset the controller */
754 		}
755 		bp->b_flags |= B_ERROR;
756 		return (MBN_DONE);
757 	}
758 	/* NOTREACHED */
759 }
760 
761 void mtcreset(mtaddr)
762 	register struct mtdevice *mtaddr;
763 {
764 	register int i;
765 
766 	mtaddr->mtid = MTID_CLR;		/* reset the TM78 */
767 	DELAY(200);
768 	for (i = MTTIMEOUT; i > 0; i--) {
769 		DELAY(50);			/* don't nag */
770 		if ((mtaddr->mtid & MTID_RDY) != 0)
771 			return;			/* exit when ready */
772 	}
773 	printf("mt: controller hung\n");
774 }
775 
776 mtread(dev, uio)
777 	dev_t dev;
778 	struct uio *uio;
779 {
780 	int errno;
781 
782 	errno = mtphys(dev, uio);
783 	if (errno)
784 		return (errno);
785 	return (physio(mtstrategy, &rmtbuf[MTUNIT(dev)], dev, B_READ, minphys, uio));
786 }
787 
788 
789 mtwrite(dev, uio)
790 	dev_t dev;
791 	struct uio *uio;
792 {
793 	int errno;
794 
795 	errno = mtphys(dev, uio);
796 	if (errno)
797 		return (errno);
798 	return (physio(mtstrategy, &rmtbuf[MTUNIT(dev)], dev, B_WRITE, minphys, uio));
799 }
800 
801 mtphys(dev, uio)
802 	dev_t dev;
803 	struct uio *uio;
804 {
805 	register int mtunit;
806 	struct mba_device *mi;
807 	register int bsize = uio->uio_iov->iov_len;
808 
809 	mtunit = MTUNIT(dev);
810 	if (   (mtunit >= NMT)
811 	    || ((mi = mtinfo[mtunit]) == 0)
812 	    || (mi->mi_alive == 0) )
813 		return (ENXIO);
814 	if (   (bsize > 0xffff)	/* controller limit */
815 	    || (bsize <= 0) )	/* ambiguous */
816 		return (EINVAL);
817 	return (0);
818 }
819 
820 /*ARGSUSED*/
821 mtioctl(dev, cmd, data, flag)
822 	dev_t dev;
823 	int cmd;
824 	caddr_t data;
825 	int flag;
826 {
827 	register struct mu_softc *sc = &mu_softc[MUUNIT(dev)];
828 	register struct buf *bp = &cmtbuf[MTUNIT(dev)];
829 	register struct mtop *mtop;
830 	register struct mtget *mtget;
831 	int callcount, fcount;
832 	int op;
833 
834 	/* We depend on the values and order of the MT codes here. */
835 
836 	static mtops[] =
837 	{MT_WTM,MT_SFORWF,MT_SREVF,MT_SFORW,MT_SREV,MT_REW,MT_UNLOAD,MT_SENSE};
838 
839 	switch (cmd) {
840 
841 	/* tape operation */
842 
843 	case MTIOCTOP:
844 		mtop = (struct mtop *)data;
845 		switch (mtop->mt_op) {
846 
847 		case MTWEOF:
848 			callcount = mtop->mt_count;
849 			fcount = 1;
850 			break;
851 
852 		case MTFSF: case MTBSF:
853 			callcount = mtop->mt_count;
854 			fcount = 1;
855 			break;
856 
857 		case MTFSR: case MTBSR:
858 			callcount = 1;
859 			fcount = mtop->mt_count;
860 			break;
861 
862 		case MTREW: case MTOFFL:
863 			callcount = 1;
864 			fcount = 1;
865 			break;
866 
867 		default:
868 			return (ENXIO);
869 		}
870 		if ((callcount <= 0) || (fcount <= 0))
871 			return (EINVAL);
872 		op = mtops[mtop->mt_op];
873 		if (op == MT_WTM)
874 			op |= sc->sc_dens;
875 		while (--callcount >= 0) {
876 			register int n, fc = fcount;
877 
878 			do {
879 				n = MIN(fc, 0xff);
880 				mtcommand(dev, op, n);
881 				n -= sc->sc_resid;
882 				fc -= n;
883 				switch (mtop->mt_op) {
884 
885 				case MTWEOF:
886 					sc->sc_blkno += (daddr_t)n;
887 					sc->sc_nxrec = sc->sc_blkno - 1;
888 					break;
889 
890 				case MTOFFL:
891 				case MTREW:
892 				case MTFSF:
893 					sc->sc_blkno = (daddr_t)0;
894 					sc->sc_nxrec = (daddr_t)INF;
895 					break;
896 
897 				case MTBSF:
898 					if (sc->sc_resid) {
899 						sc->sc_blkno = (daddr_t)0;
900 						sc->sc_nxrec = (daddr_t)INF;
901 					} else {
902 						sc->sc_blkno = (daddr_t)(-1);
903 						sc->sc_nxrec = (daddr_t)(-1);
904 					}
905 					break;
906 
907 				case MTFSR:
908 					sc->sc_blkno += (daddr_t)n;
909 					break;
910 
911 				case MTBSR:
912 					sc->sc_blkno -= (daddr_t)n;
913 					break;
914 				}
915 				if (sc->sc_resid)
916 					break;
917 			} while (fc);
918 			if (fc) {
919 				sc->sc_resid = callcount + fc;
920 				if (   (mtop->mt_op == MTFSR)
921 				    || (mtop->mt_op == MTBSR) )
922 					return (EIO);
923 				else
924 					break;
925 			}
926 			if (bp->b_flags & B_ERROR)
927 				break;
928 		}
929 		return (geterror(bp));
930 
931 	/* tape status */
932 
933 	case MTIOCGET:
934 		mtget = (struct mtget *)data;
935 		mtget->mt_erreg = sc->sc_erreg;
936 		mtget->mt_resid = sc->sc_resid;
937 		mtcommand(dev, MT_SENSE, 1);	/* update drive status */
938 		mtget->mt_dsreg = sc->sc_dsreg;
939 		mtget->mt_type = MT_ISMT;
940 		break;
941 
942 	/* ignore EOT condition */
943 
944 	case MTIOCIEOT:
945 		sc->sc_flags |= H_IEOT;
946 		break;
947 
948 	/* enable EOT condition */
949 
950 	case MTIOCEEOT:
951 		sc->sc_flags &= ~H_IEOT;
952 		break;
953 
954 	default:
955 		return (ENXIO);
956 	}
957 	return (0);
958 }
959 
960 #define	DBSIZE	20
961 
962 mtdump()
963 {
964 	register struct mba_device *mi;
965 	register struct mba_regs *mp;
966 	int blk, num;
967 	int start;
968 
969 	start = 0;
970 	num = maxfree;
971 #define	phys(a,b)		((b)((int)(a)&0x7fffffff))
972 	if (mtinfo[0] == 0)
973 		return (ENXIO);
974 	mi = phys(mtinfo[0], struct mba_device *);
975 	mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
976 	mp->mba_cr = MBCR_IE;
977 #if lint
978 	blk = 0; num = blk; start = num; blk = start;
979 	return (0);
980 #endif
981 #ifdef notyet
982 	mtaddr = (struct mtdevice *)&mp->mba_drv[mi->mi_drive];
983 	mtaddr->mttc = MTTC_PDP11|MTTC_1600BPI;
984 	mtaddr->mtcs1 = MT_DCLR|MT_GO;
985 	while (num > 0) {
986 		blk = num > DBSIZE ? DBSIZE : num;
987 		mtdwrite(start, blk, mtaddr, mp);
988 		start += blk;
989 		num -= blk;
990 	}
991 	mteof(mtaddr);
992 	mteof(mtaddr);
993 	mtwait(mtaddr);
994 	if (mtaddr->mtds&MTDS_ERR)
995 		return (EIO);
996 	mtaddr->mtcs1 = MT_REW|MT_GO;
997 	return (0);
998 }
999 
1000 mtdwrite(dbuf, num, mtaddr, mp)
1001 	register dbuf, num;
1002 	register struct mtdevice *mtaddr;
1003 	struct mba_regs *mp;
1004 {
1005 	register struct pte *io;
1006 	register int i;
1007 
1008 	mtwait(mtaddr);
1009 	io = mp->mba_map;
1010 	for (i = 0; i < num; i++)
1011 		*(int *)io++ = dbuf++ | PG_V;
1012 	mtaddr->mtfc = -(num*NBPG);
1013 	mp->mba_sr = -1;
1014 	mp->mba_bcr = -(num*NBPG);
1015 	mp->mba_var = 0;
1016 	mtaddr->mtcs1 = MT_WCOM|MT_GO;
1017 }
1018 
1019 mtwait(mtaddr)
1020 	struct mtdevice *mtaddr;
1021 {
1022 	register s;
1023 
1024 	do
1025 		s = mtaddr->mtds;
1026 	while ((s & MTDS_DRY) == 0);
1027 }
1028 
1029 mteof(mtaddr)
1030 	struct mtdevice *mtaddr;
1031 {
1032 
1033 	mtwait(mtaddr);
1034 	mtaddr->mtcs1 = MT_WEOF|MT_GO;
1035 #endif notyet
1036 }
1037 
1038 #ifdef MTLERRM
1039 mtintfail(sc)
1040 	register struct mu_softc *sc;
1041 {
1042 	switch (sc->sc_erreg & MTER_INTCODE) {
1043 
1044 	/* unexpected BOT detected */
1045 
1046 	case MTER_BOT:
1047 		sc->sc_mesg = "unexpected BOT";
1048 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1049 		case 01:
1050 			sc->sc_fmesg = "tape was at BOT";
1051 			break;
1052 		case 02:
1053 			sc->sc_fmesg = "BOT seen after tape started";
1054 			break;
1055 		case 03:
1056 			sc->sc_fmesg = "ARA ID detected";
1057 			break;
1058 		default:
1059 			sc->sc_fmesg = "unclassified failure code";
1060 		}
1061 		break;
1062 
1063 	/* unexpected LEOT detected */
1064 
1065 	case MTER_LEOT:
1066 		sc->sc_mesg = "unexpected LEOT";
1067 		sc->sc_fmesg = "";
1068 		break;
1069 
1070 	/* rewinding */
1071 
1072 	case MTER_RWDING:
1073 		sc->sc_mesg = "tape rewinding";
1074 		sc->sc_fmesg = "";
1075 		break;
1076 
1077 	/* not ready */
1078 
1079 	case MTER_NOTRDY:
1080 		sc->sc_mesg = "drive not ready";
1081 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1082 		case 01:
1083 			sc->sc_fmesg = "TU on-line but not ready";
1084 			break;
1085 		case 02:
1086 			sc->sc_fmesg = "fatal error has occurred";
1087 			break;
1088 		case 03:
1089 			sc->sc_fmesg = "access allowed but not really";
1090 			break;
1091 		default:
1092 			sc->sc_fmesg = "unclassified failure code";
1093 		}
1094 		break;
1095 
1096 	/* not available */
1097 
1098 	case MTER_NOTAVL:
1099 		sc->sc_mesg = "drive not available";
1100 		sc->sc_fmesg = "";
1101 		break;
1102 
1103 	/* unit does not exist */
1104 
1105 	case MTER_NONEX:
1106 		sc->sc_mesg = "unit does not exist";
1107 		sc->sc_fmesg = "";
1108 		break;
1109 
1110 	/* not capable */
1111 
1112 	case MTER_NOTCAP:
1113 		sc->sc_mesg = "not capable";
1114 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1115 		case 01:
1116 			sc->sc_fmesg = "no record found within 25 feet";
1117 			break;
1118 		case 02:
1119 			sc->sc_fmesg = "ID burst neither PE nor GCR";
1120 			break;
1121 		case 03:
1122 			sc->sc_fmesg = "ARA ID not found";
1123 			break;
1124 		case 04:
1125 			sc->sc_fmesg = "no gap found after ID burst";
1126 			break;
1127 		default:
1128 			sc->sc_fmesg = "unclassified failure code";
1129 		}
1130 		break;
1131 
1132 	/* long tape record */
1133 
1134 	case MTER_LONGREC:
1135 		sc->sc_mesg = "long record";
1136 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1137 		case 00:
1138 			sc->sc_fmesg = "extended sense data not found";
1139 			break;
1140 		case 01:
1141 			sc->sc_fmesg = "extended sense data updated";
1142 			break;
1143 		default:
1144 			sc->sc_fmesg = "unclassified failure code";
1145 		}
1146 		break;
1147 
1148 	/* unreadable */
1149 
1150 	case MTER_UNREAD:
1151 		sc->sc_mesg = "unreadable record";
1152 		goto code22;
1153 
1154 	/* error */
1155 
1156 	case MTER_ERROR:
1157 		sc->sc_mesg = "error";
1158 		goto code22;
1159 
1160 	/* EOT error */
1161 
1162 	case MTER_EOTERR:
1163 		sc->sc_mesg = "EOT error";
1164 		goto code22;
1165 
1166 	/* tape position lost */
1167 
1168 	case MTER_BADTAPE:
1169 		sc->sc_mesg = "bad tape";
1170 	code22:
1171 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1172 		case 01:
1173 			sc->sc_fmesg = "GCR write error";
1174 			break;
1175 		case 02:
1176 			sc->sc_fmesg = "GCR read error";
1177 			break;
1178 		case 03:
1179 			sc->sc_fmesg = "PE read error";
1180 			break;
1181 		case 04:
1182 			sc->sc_fmesg = "PE write error";
1183 			break;
1184 		case 05:
1185 			sc->sc_fmesg = "at least 1 bit set in ECCSTA";
1186 			break;
1187 		case 06:
1188 			sc->sc_fmesg = "PE write error";
1189 			break;
1190 		case 07:
1191 			sc->sc_fmesg = "GCR write error";
1192 			break;
1193 		case 010:
1194 			sc->sc_fmesg = "RSTAT contains bad code";
1195 			break;
1196 		case 011:
1197 			sc->sc_fmesg = "PE write error";
1198 			break;
1199 		case 012:
1200 			sc->sc_fmesg = "MASSBUS parity error";
1201 			break;
1202 		case 013:
1203 			sc->sc_fmesg = "invalid data transferred";
1204 			break;
1205 		default:
1206 			sc->sc_fmesg = "unclassified failure code";
1207 		}
1208 		break;
1209 
1210 	/* TM fault A */
1211 
1212 	case MTER_TMFLTA:
1213 		sc->sc_mesg = "TM fault A";
1214 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1215 		case 01:
1216 			sc->sc_fmesg = "illegal command code";
1217 			break;
1218 		case 02:
1219 			sc->sc_fmesg = "DT command issued when NDT command active";
1220 			break;
1221 		case 03:
1222 			sc->sc_fmesg = "WMC error";
1223 			break;
1224 		case 04:
1225 			sc->sc_fmesg = "RUN not received from MASSBUS controller";
1226 			break;
1227 		case 05:
1228 			sc->sc_fmesg = "mismatch in command read - function routine";
1229 			break;
1230 		case 06:
1231 			sc->sc_fmesg = "ECC ROM parity error";
1232 			break;
1233 		case 07:
1234 			sc->sc_fmesg = "XMC ROM parity error";
1235 			break;
1236 		case 010:
1237 			sc->sc_fmesg = "mismatch in command read - ID burst command";
1238 			break;
1239 		case 011:
1240 			sc->sc_fmesg = "mismatch in command read - verify ARA burst command";
1241 			break;
1242 		case 012:
1243 			sc->sc_fmesg = "mismatch in command read - verify ARA ID command";
1244 			break;
1245 		case 013:
1246 			sc->sc_fmesg = "mismatch in command read - verify gap command";
1247 			break;
1248 		case 014:
1249 			sc->sc_fmesg = "mismatch in command read - read id burst command";
1250 			break;
1251 		case 015:
1252 			sc->sc_fmesg = "mismatch in command read - verify ARA ID command";
1253 			break;
1254 		case 016:
1255 			sc->sc_fmesg = "mismatch in command read - verify gap command";
1256 			break;
1257 		case 017:
1258 			sc->sc_fmesg = "mismatch in command read - find gap command";
1259 			break;
1260 		case 020:
1261 			sc->sc_fmesg = "WMC LEFT failed to set";
1262 			break;
1263 		case 021:
1264 			sc->sc_fmesg = "XL PE set in INTSTA register";
1265 			break;
1266 		case 022:
1267 			sc->sc_fmesg = "XMC DONE did not set";
1268 			break;
1269 		case 023:
1270 			sc->sc_fmesg = "WMC ROM PE or RD PE set in WMCERR register";
1271 			break;
1272 		default:
1273 			sc->sc_fmesg = "unclassified failure code";
1274 		}
1275 		break;
1276 
1277 	/* TU fault A */
1278 
1279 	case MTER_TUFLTA:
1280 		sc->sc_mesg = "TU fault A";
1281 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1282 		case 01:
1283 			sc->sc_fmesg = "TU status parity error";
1284 			break;
1285 		case 02:
1286 			sc->sc_fmesg = "TU command parity error";
1287 			break;
1288 		case 03:
1289 			sc->sc_fmesg = "rewinding tape went offline";
1290 			break;
1291 		case 04:
1292 			sc->sc_fmesg = "tape went not ready during DSE";
1293 			break;
1294 		case 05:
1295 			sc->sc_fmesg = "TU CMD status changed during DSE";
1296 			break;
1297 		case 06:
1298 			sc->sc_fmesg = "TU never came up to speed";
1299 			break;
1300 		case 07:
1301 			sc->sc_fmesg = "TU velocity changed";
1302 			break;
1303 		case 010:
1304 			sc->sc_fmesg = "TU CMD did not load correctly to start tape motion";
1305 			break;
1306 		case 011:
1307 			sc->sc_fmesg = "TU CMD did not load correctly to set drive density";
1308 			break;
1309 		case 012:
1310 			sc->sc_fmesg = "TU CMD did not load correctly to start tape motion to write BOT ID";
1311 			break;
1312 		case 013:
1313 			sc->sc_fmesg = "TU CMD did not load correctly to backup tape to BOT after failing to write BOT ID";
1314 			break;
1315 		case 014:
1316 			sc->sc_fmesg = "failed to write density ID burst";
1317 			break;
1318 		case 015:
1319 			sc->sc_fmesg = "failed to write ARA burst";
1320 			break;
1321 		case 016:
1322 			sc->sc_fmesg = "failed to write ARA ID";
1323 			break;
1324 		case 017:
1325 			sc->sc_fmesg = "ARA error bit set in MTA status B register";
1326 			break;
1327 		case 021:
1328 			sc->sc_fmesg = "could not find a gap after ID code was written correctly";
1329 			break;
1330 		case 022:
1331 			sc->sc_fmesg = "TU CMD did not load correctly to start tape motion to read ID burst";
1332 			break;
1333 		case 023:
1334 			sc->sc_fmesg = "timeout looking for BOT after detecting ARA ID burst";
1335 			break;
1336 		case 024:
1337 			sc->sc_fmesg = "failed to write tape mark";
1338 			break;
1339 		case 025:
1340 			sc->sc_fmesg = "tape never came up to speed while trying to reposition for retry of writing tape mark";
1341 			break;
1342 		case 026:
1343 			sc->sc_fmesg = "TU CMD did not load correctly to start tape motion in erase gap routine";
1344 			break;
1345 		case 027:
1346 			sc->sc_fmesg = "could not detect a gap in in erase gap routine";
1347 			break;
1348 		case 030:
1349 			sc->sc_fmesg = "could not detect a gap after writing record";
1350 			break;
1351 		case 031:
1352 			sc->sc_fmesg = "read path terminated before entire record was written";
1353 			break;
1354 		case 032:
1355 			sc->sc_fmesg = "could not find a gap after writing record and read path terminated early";
1356 			break;
1357 		case 033:
1358 			sc->sc_fmesg = "TU CMD did not load correctly to backup for retry of write tape mark";
1359 			break;
1360 		case 034:
1361 			sc->sc_fmesg = "TU velocity changed after up to speed while trying to reposition for retry of writing tape mark";
1362 			break;
1363 		case 035:
1364 			sc->sc_fmesg = "TU CMD did not load correctly to backup to retry a load of BOT ID";
1365 			break;
1366 		case 036:
1367 			sc->sc_fmesg = "timeout looking for BOT after failing to write BOT ID";
1368 			break;
1369 		case 037:
1370 			sc->sc_fmesg = "TU velocity changed while writing PE gap before starting to write record";
1371 			break;
1372 		case 040:
1373 			sc->sc_fmesg = "TU CMD did not load correctly to set PE tape density at start of write BOT ID burst";
1374 			break;
1375 		case 041:
1376 			sc->sc_fmesg = "TU CMD did not load correctly to set GCR tape density after writing Density ID";
1377 			break;
1378 		case 042:
1379 			sc->sc_fmesg = "TU CMD did not load correctly to set PE tape density at start of read from BOT";
1380 			break;
1381 		case 043:
1382 			sc->sc_fmesg = "TU CMD did not load correctly to set GCR tape density after reading a GCR Density ID burst";
1383 			break;
1384 		default:
1385 			sc->sc_fmesg = "unclassified failure code";
1386 		}
1387 		break;
1388 
1389 	/* TM fault B */
1390 
1391 	case MTER_TMFLTB:
1392 		sc->sc_mesg = "TM fault B";
1393 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1394 		case 00:
1395 			sc->sc_fmesg = "RST0 interrupt occurred with TM RDY set";
1396 			break;
1397 		case 01:
1398 			sc->sc_fmesg = "power failed to interrupt";
1399 			break;
1400 		case 02:
1401 			sc->sc_fmesg = "unknown interrupt on channel 5.5";
1402 			break;
1403 		case 03:
1404 			sc->sc_fmesg = "unknown interrupt on channel 6.5";
1405 			break;
1406 		case 04:
1407 			sc->sc_fmesg = "unknown interrupt on channel 7";
1408 			break;
1409 		case 05:
1410 			sc->sc_fmesg = "unknown interrupt on channel 7.5";
1411 			break;
1412 		case 06:
1413 			sc->sc_fmesg = "CAS contention retry count expired";
1414 			break;
1415 		case 07:
1416 			sc->sc_fmesg = "CAS contention error not retryable";
1417 			break;
1418 		case 010:
1419 			sc->sc_fmesg = "queue error, could not find queue entry";
1420 			break;
1421 		case 011:
1422 			sc->sc_fmesg = "queue entry already full";
1423 			break;
1424 		case 012:
1425 			sc->sc_fmesg = "8085 ROM parity error";
1426 			break;
1427 		case 013:
1428 		case 014:
1429 		case 015:
1430 		case 016:
1431 		case 017:
1432 		case 020:
1433 		case 021:
1434 		case 022:
1435 		case 023:
1436 		case 024:
1437 		case 025:
1438 		case 026:
1439 		case 027:
1440 		case 030:
1441 		case 031:
1442 		case 032:
1443 		case 033:
1444 		case 034:
1445 		case 035:
1446 		case 036:
1447 		case 037:
1448 		case 040:
1449 		case 041:
1450 		case 042:
1451 		case 043:
1452 		case 044:
1453 		case 045:
1454 		case 046:
1455 		case 047:
1456 		case 050:
1457 		case 051:
1458 		case 052:
1459 		case 053:
1460 		case 054:
1461 		case 055:
1462 		case 056:
1463 		case 057:
1464 			sc->sc_fmesg = "inline test failed";
1465 			break;
1466 		default:
1467 			sc->sc_fmesg = "unclassified failure code";
1468 		}
1469 		break;
1470 
1471 	/* MASSBUS fault */
1472 
1473 	case MTER_MBFLT:
1474 		sc->sc_mesg = "MB fault";
1475 		switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) {
1476 		case 01:
1477 			sc->sc_fmesg = "control bus parity error";
1478 			break;
1479 		case 02:
1480 			sc->sc_fmesg = "illegal register referenced";
1481 			break;
1482 		default:
1483 			sc->sc_fmesg = "unclassified failure code";
1484 		}
1485 		break;
1486 
1487 	/* keypad entry error */
1488 
1489 	case MTER_KEYFAIL:
1490 		sc->sc_mesg = "keypad entry error";
1491 		sc->sc_fmesg = "";
1492 		break;
1493 	default:
1494 		sc->sc_mesg = "unclassified error";
1495 		sc->sc_fmesg = "";
1496 		break;
1497 	}
1498 }
1499 #endif MTLERRM
1500 #endif
1501