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) 6/5/86
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: }
Defined functions
Defined variables
Defined macros