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