xref: /csrg-svn/sys/vax/stand/mt.c (revision 23235)
1 /*
2  * Copyright (c) 1982 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	6.2 (Berkeley) 06/08/85
7  */
8 
9 /*
10  * TM78/TU78 tape driver
11  * Made to work reliably by by Jeffrey R. Schwab (Purdue)
12  */
13 #include "../machine/pte.h"
14 
15 #include "../h/param.h"
16 #include "../h/inode.h"
17 #include "../h/fs.h"
18 
19 #include "../vaxmba/mtreg.h"
20 #include "../vaxmba/mbareg.h"
21 
22 #include "saio.h"
23 #include "savax.h"
24 
25 short	mttypes[] =
26 	{ MBDT_TU78, 0 };
27 
28 #define	MASKREG(reg)	((reg)&0xffff)
29 
30 mtopen(io)
31 	register struct iob *io;
32 {
33 	register int skip;
34 	register struct mtdevice *mtaddr =
35 		(struct mtdevice *)mbadrv(io->i_unit);
36 	int i;
37 
38 	for (i = 0; mttypes[i]; i++)
39 		if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE))
40 			goto found;
41 	_stop("not a tape\n");
42 found:
43 	mbainit(UNITTOMBA(io->i_unit));
44 	mtaddr->mtid = MTID_CLR;
45 	DELAY(250);
46 	while ((mtaddr->mtid & MTID_RDY) == 0)
47 		;
48 
49 	/* clear any attention bits present on open */
50 	i = mtaddr->mtner;
51 	mtaddr->mtas = mtaddr->mtas;
52 
53 	mtstrategy(io, MT_REW);
54 	skip = io->i_boff;
55 	while (skip--) {
56 		io->i_cc = -1;
57 		mtstrategy(io, MT_SFORWF);
58 	}
59 }
60 
61 mtclose(io)
62 	register struct iob *io;
63 {
64 
65 	mtstrategy(io, MT_REW);
66 }
67 
68 mtstrategy(io, func)
69 	register struct iob *io;
70 	int func;
71 {
72 	register int errcnt, s, ic;
73 	register struct mtdevice *mtaddr =
74 	    (struct mtdevice *)mbadrv(io->i_unit);
75 	struct mba_regs *mba = mbamba(io->i_unit);
76 
77 	errcnt = 0;
78 retry:
79 	/* code to trap for attention up prior to start of command */
80 	if ((mtaddr->mtas & 0xffff) != 0) {
81 		printf("mt unexpected attention er=%x - continuing\n",
82 			MASKREG(mtaddr->mtner));
83 		mtaddr->mtas = mtaddr->mtas;
84 	}
85 
86 	if (func == READ || func == WRITE) {
87 		mtaddr->mtca = 1<<2;	/* 1 record */
88 		mtaddr->mtbc = io->i_cc;
89 		mbastart(io, func);
90 		/* wait for mba to go idle and read result status */
91 		while((mba->mba_sr & MBSR_DTBUSY) != 0)
92 			;
93 		ic = mtaddr->mter & MTER_INTCODE;
94 	} else {
95 		mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO;
96 	rwait:
97 		do
98 			s = mtaddr->mtas&0xffff;
99 		while (s == 0);
100 		ic = mtaddr->mtner & MTER_INTCODE;
101 		mtaddr->mtas = mtaddr->mtas;	/* clear attention */
102 	}
103 	switch (ic) {
104 	case MTER_TM:
105 	case MTER_EOT:
106 	case MTER_LEOT:
107 		return (0);
108 
109 	case MTER_DONE:
110 		/* make sure a record was read */
111 		if ((mtaddr->mtca & (1 << 2)) != 0) {
112 			printf("mt record count not decremented - retrying\n");
113 			goto retry;
114 		}
115 		break;
116 
117 	case MTER_RWDING:
118 		goto rwait;
119 	default:
120 		printf("mt hard error: er=%x\n",
121 		    MASKREG(mtaddr->mter));
122 		mtaddr->mtid = MTID_CLR;
123 		DELAY(250);
124 		while ((mtaddr->mtid & MTID_RDY) == 0)
125 			;
126 		return (-1);
127 
128 	case MTER_RETRY:
129 		printf("mt error: er=%x\n", MASKREG(mtaddr->mter));
130 		if (errcnt == 10) {
131 			printf("mt: unrecovered error\n");
132 			return (-1);
133 		}
134 		errcnt++;
135 		goto retry;
136 	}
137 	if (errcnt)
138 		printf("mt: recovered by retry\n");
139 	return (io->i_cc);	/* NO PARTIAL RECORD READS!!! */
140 }
141