xref: /original-bsd/sys/vax/stand/mt.c (revision d6141097)
1 /*	mt.c	4.2	82/07/15	*/
2 
3 /*
4  * TM78/TU78 tape driver
5  */
6 
7 #include "../h/mtreg.h"
8 #include "../h/param.h"
9 #include "../h/inode.h"
10 #include "../h/pte.h"
11 #include "../h/mbareg.h"
12 #include "../h/fs.h"
13 #include "saio.h"
14 #include "savax.h"
15 
16 short	mttypes[] =
17 	{ MBDT_TU78, 0 };
18 
19 #define	MASKREG(reg)	((reg)&0xffff)
20 
21 mtopen(io)
22 	register struct iob *io;
23 {
24 	register int skip;
25 	register struct mtdevice *mtaddr = (struct mtdevice *)mbadrv(io->i_unit);
26 	int i;
27 
28 	for (i = 0; mttypes[i]; i++)
29 		if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE))
30 			goto found;
31 	_stop("not a tape\n");
32 found:
33 	mbainit(UNITTOMBA(io->i_unit));
34 	mtaddr->mtid = MTID_CLR;
35 	DELAY(250);
36 	while ((mtaddr->mtid & MTID_RDY) == 0)
37 		;
38 	mtstrategy(io, MT_REW);
39 	skip = io->i_boff;
40 	while (skip--) {
41 		io->i_cc = -1;
42 		mtstrategy(io, MT_SFORWF);
43 	}
44 }
45 
46 mtclose(io)
47 	register struct iob *io;
48 {
49 
50 	mtstrategy(io, MT_REW);
51 }
52 
53 mtstrategy(io, func)
54 	register struct iob *io;
55 	int func;
56 {
57 	register int errcnt, s, ic;
58 	register struct mtdevice *mtaddr =
59 	    (struct mtdevice *)mbadrv(io->i_unit);
60 
61 	errcnt = 0;
62 retry:
63 	if (func == READ || func == WRITE) {
64 		mtaddr->mtca = 1<<2;	/* 1 record */
65 		mtaddr->mtbc = io->i_cc;
66 		mtaddr->mter = 0;
67 		mbastart(io, func);
68 		do
69 			s = mtaddr->mter & MTER_INTCODE;
70 		while (s == 0);
71 		ic = s;
72 		DELAY(2000);
73 	} else {
74 		mtaddr->mtas = -1;
75 		mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO;
76 	rwait:
77 		do
78 			s = mtaddr->mtas&0xffff;
79 		while (s == 0);
80 		mtaddr->mtas = mtaddr->mtas;	/* clear attention */
81 		ic = mtaddr->mtner & MTER_INTCODE;
82 	}
83 	switch (ic) {
84 	case MTER_TM:
85 	case MTER_EOT:
86 	case MTER_LEOT:
87 		return (0);
88 
89 	case MTER_DONE:
90 		break;
91 
92 	case MTER_RWDING:
93 		goto rwait;
94 	default:
95 		printf("mt hard error: er=%b\n",
96 		    MASKREG(mtaddr->mter));
97 		mtaddr->mtid = MTID_CLR;
98 		DELAY(250);
99 		while ((mtaddr->mtid & MTID_RDY) == 0)
100 			;
101 		return (-1);
102 
103 	case MTER_RETRY:
104 		printf("mt error: er=%b\n",
105 		    MASKREG(mtaddr->mter));
106 		if (errcnt == 10) {
107 			printf("mt: unrecovered error\n");
108 			return (-1);
109 		}
110 		errcnt++;
111 		goto retry;
112 	}
113 	if (errcnt)
114 		printf("mt: recovered by retry\n");
115 	return (io->i_cc);	/* NO PARTIAL RECORD READS!!! */
116 }
117