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