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