|
|
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.5 (Berkeley) 4/4/90
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:
17: #include "../vaxmba/mtreg.h"
18: #include "../vaxmba/mbareg.h"
19:
20: #include "saio.h"
21: #include "savax.h"
22:
23: short mttypes[] =
24: { MBDT_TU78, 0 };
25:
26: #define MASKREG(reg) ((reg)&0xffff)
27:
28: mtopen(io)
29: register struct iob *io;
30: {
31: register struct mtdevice *mtaddr;
32: register int i, skip;
33:
34: if (mbainit(io->i_adapt) == 0)
35: return (EADAPT);
36: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr);
37: for (i = 0;; i++) {
38: if (!mttypes[i]) {
39: printf("mt: not a tape\n");
40: return (ENXIO);
41: }
42: if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE))
43: break;
44: }
45: mtaddr->mtid = MTID_CLR;
46: DELAY(250);
47: while ((mtaddr->mtid & MTID_RDY) == 0);
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: for (skip = io->i_part; skip--;) {
55: io->i_cc = -1;
56: mtstrategy(io, MT_SFORWF);
57: }
58: return (0);
59: }
60:
61: mtclose(io)
62: register struct iob *io;
63: {
64: mtstrategy(io, MT_REW);
65: }
66:
67: mtstrategy(io, func)
68: register struct iob *io;
69: int func;
70: {
71: register int errcnt, s, ic;
72: register struct mtdevice *mtaddr;
73: struct mba_regs *mba;
74:
75: errcnt = 0;
76: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr);
77: mba = mbamba(io->i_adapt);
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, io->i_ctlr, 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: goto retry;
135: }
136: if (errcnt)
137: printf("mt: recovered by retry\n");
138: return (io->i_cc); /* NO PARTIAL RECORD READS!!! */
139: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.