Research V7 development
[unix-history] / .ref-Research-V6 / usr / sys / dmr / ht.c
CommitLineData
8f1d4458
DR
1#
2/*
3 */
4
5/*
6 * TJU16 tape driver
7 */
8
9#include "../param.h"
10#include "../buf.h"
11#include "../conf.h"
12#include "../user.h"
13
14struct {
15 int htcs1;
16 int htwc;
17 int htba;
18 int htfc;
19 int htcs2;
20 int htds;
21 int hter;
22 int htas;
23 int htck;
24 int htdb;
25 int htmr;
26 int htdt;
27 int htsn;
28 int httc;
29 int htbae; /* 11/70 bus extension */
30};
31
32struct devtab httab;
33struct buf rhtbuf;
34
35#define NUNIT 8
36
37char h_openf[NUNIT];
38char *h_blkno[NUNIT];
39char *h_nxrec[NUNIT];
40
41#define HTADDR 0172440
42
43#define GO 01
44#define NOP 0
45#define WEOF 026
46#define SFORW 030
47#define SREV 032
48#define ERASE 024
49#define REW 06
50#define CLR 010
51#define P800 01300 /* 800 + pdp11 mode */
52#define P1600 02300 /* 1600 + pdp11 mode */
53#define IENABLE 0100
54#define CRDY 0200
55#define EOF 04
56#define DRY 0200
57#define MOL 010000
58#define PIP 020000
59#define ERR 040000
60
61#define SSEEK 1
62#define SIO 2
63
64htopen(dev, flag)
65{
66 register unit;
67
68 unit = dev.d_minor&077;
69 if (unit >= NUNIT || h_openf[unit])
70 u.u_error = ENXIO;
71 else {
72 h_openf[unit]++;
73 h_blkno[unit] = 0;
74 h_nxrec[unit] = 65535;
75 hcommand(dev, NOP);
76 }
77}
78
79htclose(dev, flag)
80{
81 register int unit;
82
83 unit = dev.d_minor&077;
84 h_openf[unit] = 0;
85 if (flag) {
86 hcommand(dev, WEOF);
87 hcommand(dev, WEOF);
88 }
89 hcommand(dev, REW);
90}
91
92hcommand(dev, com)
93{
94 register unit;
95 extern lbolt;
96
97 unit = dev.d_minor;
98 while (httab.d_active || (HTADDR->htcs1 & CRDY)==0)
99 sleep(&lbolt, 1);
100 HTADDR->htcs2 = (unit>>3)&07;
101 while((HTADDR->htds&DRY) == 0)
102 sleep(&lbolt, 1);
103 if(unit >= 64)
104 HTADDR->httc = P800 | (unit&07); else
105 HTADDR->httc = P1600 | (unit&07);
106 while((HTADDR->htds&(MOL|PIP)) != MOL)
107 sleep(&lbolt, 1);
108 HTADDR->htcs1 = com | GO;
109}
110
111htstrategy(abp)
112struct buf *abp;
113{
114 register struct buf *bp;
115 register char **p;
116
117 bp = abp;
118 p = &h_nxrec[bp->b_dev.d_minor&077];
119 if (*p <= bp->b_blkno) {
120 if (*p < bp->b_blkno) {
121 bp->b_flags =| B_ERROR;
122 iodone(bp);
123 return;
124 }
125 if (bp->b_flags&B_READ) {
126 clrbuf(bp);
127 iodone(bp);
128 return;
129 }
130 }
131 if ((bp->b_flags&B_READ)==0)
132 *p = bp->b_blkno + 1;
133 bp->av_forw = 0;
134 spl5();
135 if (httab.d_actf==0)
136 httab.d_actf = bp;
137 else
138 httab.d_actl->av_forw = bp;
139 httab.d_actl = bp;
140 if (httab.d_active==0)
141 htstart();
142 spl0();
143}
144
145htstart()
146{
147 register struct buf *bp;
148 register int unit;
149 register char *blkno;
150
151 loop:
152 if ((bp = httab.d_actf) == 0)
153 return;
154 unit = bp->b_dev.d_minor;
155 HTADDR->htcs2 = (unit>>3)&07;
156 if(unit >= 64)
157 HTADDR->httc = P800 | (unit&07); else
158 HTADDR->httc = P1600 | (unit&07);
159 unit =& 077;
160 blkno = h_blkno[unit];
161 if (h_openf[unit] < 0 || (HTADDR->htcs1 & CRDY)==0) {
162 bp->b_flags =| B_ERROR;
163 httab.d_actf = bp->av_forw;
164 iodone(bp);
165 goto loop;
166 }
167 if (blkno != bp->b_blkno) {
168 httab.d_active = SSEEK;
169 if (blkno < bp->b_blkno) {
170 HTADDR->htfc = blkno - bp->b_blkno;
171 HTADDR->htcs1 = SFORW|IENABLE|GO;
172 } else {
173 if (bp->b_blkno == 0)
174 HTADDR->htcs1 = REW|IENABLE|GO;
175 else {
176 HTADDR->htfc = bp->b_blkno - blkno;
177 HTADDR->htcs1 = SREV|IENABLE|GO;
178 }
179 }
180 return;
181 }
182 httab.d_active = SIO;
183 rhstart(bp, &HTADDR->htfc, bp->b_wcount<<1, &HTADDR->htbae);
184}
185
186htintr()
187{
188 register struct buf *bp;
189 register int unit;
190
191 if ((bp = httab.d_actf)==0)
192 return;
193 unit = bp->b_dev.d_minor&077;
194 if (HTADDR->htcs1 & ERR) {
195/*
196 deverror(bp, HTADDR->hter, 0);
197 */
198 if(HTADDR->htds&EOF) {
199 if(bp != &rhtbuf && h_openf[unit])
200 h_openf[unit] = -1;
201 }
202 HTADDR->htcs1 = ERR|CLR|GO;
203 if ((HTADDR->htds&DRY)!=0 && httab.d_active==SIO) {
204 if (++httab.d_errcnt < 10) {
205 h_blkno[unit]++;
206 httab.d_active = 0;
207 htstart();
208 return;
209 }
210 }
211 bp->b_flags =| B_ERROR;
212 httab.d_active = SIO;
213 }
214 if (httab.d_active == SIO) {
215 httab.d_errcnt = 0;
216 h_blkno[unit]++;
217 httab.d_actf = bp->av_forw;
218 httab.d_active = 0;
219 iodone(bp);
220 bp->b_resid = HTADDR->htfc;
221 } else
222 h_blkno[unit] = bp->b_blkno;
223 htstart();
224}
225
226htread(dev)
227{
228 htphys(dev);
229 physio(htstrategy, &rhtbuf, dev, B_READ);
230 u.u_count = -rhtbuf.b_resid;
231}
232
233htwrite(dev)
234{
235 htphys(dev);
236 physio(htstrategy, &rhtbuf, dev, B_WRITE);
237 u.u_count = 0;
238}
239
240htphys(dev)
241{
242 register unit, a;
243
244 unit = dev.d_minor;
245 a = lshift(u.u_offset, -9);
246 h_blkno[unit] = a;
247 h_nxrec[unit] = ++a;
248}