Commit | Line | Data |
---|---|---|
55b4dbd0 KM |
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) %G% | |
7 | */ | |
8d272394 SL |
8 | |
9 | /* | |
10 | * TM78/TU78 tape driver | |
26d5a33e | 11 | * Made to work reliably by by Jeffrey R. Schwab (Purdue) |
8d272394 | 12 | */ |
faeec66d | 13 | #include "../machine/pte.h" |
8d272394 | 14 | |
8d272394 | 15 | #include "../h/param.h" |
a031a31b | 16 | #include "../h/inode.h" |
b5d17f4d | 17 | #include "../h/fs.h" |
a031a31b SL |
18 | |
19 | #include "../vaxmba/mtreg.h" | |
20 | #include "../vaxmba/mbareg.h" | |
21 | ||
8d272394 SL |
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; | |
26d5a33e SL |
34 | register struct mtdevice *mtaddr = |
35 | (struct mtdevice *)mbadrv(io->i_unit); | |
8d272394 SL |
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 | ; | |
26d5a33e SL |
48 | |
49 | /* clear any attention bits present on open */ | |
50 | i = mtaddr->mtner; | |
51 | mtaddr->mtas = mtaddr->mtas; | |
52 | ||
8d272394 SL |
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); | |
26d5a33e | 75 | struct mba_regs *mba = mbamba(io->i_unit); |
8d272394 SL |
76 | |
77 | errcnt = 0; | |
78 | retry: | |
26d5a33e SL |
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 | ||
8d272394 SL |
86 | if (func == READ || func == WRITE) { |
87 | mtaddr->mtca = 1<<2; /* 1 record */ | |
88 | mtaddr->mtbc = io->i_cc; | |
8d272394 | 89 | mbastart(io, func); |
26d5a33e SL |
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; | |
8d272394 | 94 | } else { |
8d272394 SL |
95 | mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO; |
96 | rwait: | |
97 | do | |
98 | s = mtaddr->mtas&0xffff; | |
99 | while (s == 0); | |
8d272394 | 100 | ic = mtaddr->mtner & MTER_INTCODE; |
26d5a33e | 101 | mtaddr->mtas = mtaddr->mtas; /* clear attention */ |
8d272394 SL |
102 | } |
103 | switch (ic) { | |
104 | case MTER_TM: | |
105 | case MTER_EOT: | |
106 | case MTER_LEOT: | |
107 | return (0); | |
108 | ||
109 | case MTER_DONE: | |
26d5a33e SL |
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 | } | |
8d272394 SL |
115 | break; |
116 | ||
117 | case MTER_RWDING: | |
118 | goto rwait; | |
119 | default: | |
26d5a33e | 120 | printf("mt hard error: er=%x\n", |
8d272394 SL |
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: | |
26d5a33e | 129 | printf("mt error: er=%x\n", MASKREG(mtaddr->mter)); |
8d272394 SL |
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 | } |