|
|
1.1 root 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.3 (Berkeley) 2/22/88
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 "param.h"
16: #include "inode.h"
17: #include "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 struct mtdevice *mtaddr;
34: register int i, skip;
35:
36: if (mbainit(io->i_adapt) == 0)
37: return (EADAPT);
38: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr);
39: for (i = 0;; i++) {
40: if (!mttypes[i]) {
41: printf("mt: not a tape\n");
42: return (ENXIO);
43: }
44: if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE))
45: break;
46: }
47: mtaddr->mtid = MTID_CLR;
48: DELAY(250);
49: while ((mtaddr->mtid & MTID_RDY) == 0);
50:
51: /* clear any attention bits present on open */
52: i = mtaddr->mtner;
53: mtaddr->mtas = mtaddr->mtas;
54:
55: mtstrategy(io, MT_REW);
56: for (skip = io->i_part; skip--;) {
57: io->i_cc = -1;
58: mtstrategy(io, MT_SFORWF);
59: }
60: return (0);
61: }
62:
63: mtclose(io)
64: register struct iob *io;
65: {
66: mtstrategy(io, MT_REW);
67: }
68:
69: mtstrategy(io, func)
70: register struct iob *io;
71: int func;
72: {
73: register int errcnt, s, ic;
74: register struct mtdevice *mtaddr;
75: struct mba_regs *mba;
76:
77: errcnt = 0;
78: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr);
79: mba = mbamba(io->i_adapt);
80: retry:
81: /* code to trap for attention up prior to start of command */
82: if ((mtaddr->mtas & 0xffff) != 0) {
83: printf("mt unexpected attention er=%x - continuing\n",
84: MASKREG(mtaddr->mtner));
85: mtaddr->mtas = mtaddr->mtas;
86: }
87:
88: if (func == READ || func == WRITE) {
89: mtaddr->mtca = 1<<2; /* 1 record */
90: mtaddr->mtbc = io->i_cc;
91: mbastart(io, io->i_ctlr, func);
92: /* wait for mba to go idle and read result status */
93: while((mba->mba_sr & MBSR_DTBUSY) != 0)
94: ;
95: ic = mtaddr->mter & MTER_INTCODE;
96: } else {
97: mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO;
98: rwait:
99: do
100: s = mtaddr->mtas&0xffff;
101: while (s == 0);
102: ic = mtaddr->mtner & MTER_INTCODE;
103: mtaddr->mtas = mtaddr->mtas; /* clear attention */
104: }
105: switch (ic) {
106: case MTER_TM:
107: case MTER_EOT:
108: case MTER_LEOT:
109: return (0);
110:
111: case MTER_DONE:
112: /* make sure a record was read */
113: if ((mtaddr->mtca & (1 << 2)) != 0) {
114: printf("mt record count not decremented - retrying\n");
115: goto retry;
116: }
117: break;
118:
119: case MTER_RWDING:
120: goto rwait;
121: default:
122: printf("mt hard error: er=%x\n",
123: MASKREG(mtaddr->mter));
124: mtaddr->mtid = MTID_CLR;
125: DELAY(250);
126: while ((mtaddr->mtid & MTID_RDY) == 0)
127: ;
128: return (-1);
129:
130: case MTER_RETRY:
131: printf("mt error: er=%x\n", MASKREG(mtaddr->mter));
132: if (errcnt++ == 10) {
133: printf("mt: unrecovered error\n");
134: return (-1);
135: }
136: goto retry;
137: }
138: if (errcnt)
139: printf("mt: recovered by retry\n");
140: return (io->i_cc); /* NO PARTIAL RECORD READS!!! */
141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.