Commit | Line | Data |
---|---|---|
f0a3ddbd | 1 | /* ht.c 4.3 %G% */ |
786dff00 | 2 | |
a5cc519e BJ |
3 | #include "../conf/ht.h" |
4 | #if NHT > 0 | |
786dff00 BJ |
5 | /* |
6 | * TJU16 tape driver | |
7 | */ | |
8 | ||
9 | #include "../h/param.h" | |
10 | #include "../h/systm.h" | |
11 | #include "../h/buf.h" | |
12 | #include "../h/conf.h" | |
13 | #include "../h/dir.h" | |
14 | #include "../h/file.h" | |
15 | #include "../h/user.h" | |
16 | #include "../h/map.h" | |
80e7c811 | 17 | #include "../h/pte.h" |
786dff00 | 18 | #include "../h/mba.h" |
f0a3ddbd BJ |
19 | #include "../h/vm.h" |
20 | #include "../h/cmap.h" | |
786dff00 BJ |
21 | |
22 | struct device | |
23 | { | |
24 | int htcs1; | |
25 | int htds; | |
26 | int hter; | |
27 | int htmr; | |
28 | int htas; | |
29 | int htfc; | |
30 | int htdt; | |
31 | int htck; | |
32 | int htsn; | |
33 | int httc; | |
34 | }; | |
35 | ||
36 | struct buf httab; | |
37 | struct buf rhtbuf; | |
38 | struct buf chtbuf; | |
39 | ||
786dff00 BJ |
40 | #define INF 1000000 |
41 | ||
a5cc519e BJ |
42 | char h_openf[NHT]; |
43 | daddr_t h_blkno[NHT]; | |
44 | char h_flags[NHT]; | |
45 | daddr_t h_nxrec[NHT]; | |
786dff00 BJ |
46 | |
47 | #define GO 01 | |
48 | #define WCOM 060 | |
49 | #define RCOM 070 | |
50 | #define NOP 0 | |
51 | #define WEOF 026 | |
52 | #define SFORW 030 | |
53 | #define SREV 032 | |
54 | #define ERASE 024 | |
55 | #define REW 06 | |
56 | #define DCLR 010 | |
57 | #define P800 01700 /* 800 + pdp11 mode */ | |
58 | #define P1600 02300 /* 1600 + pdp11 mode */ | |
59 | #define IENABLE 0100 | |
60 | #define RDY 0200 | |
61 | #define TM 04 | |
62 | #define DRY 0200 | |
63 | #define EOT 02000 | |
64 | #define CS 02000 | |
65 | #define COR 0100000 | |
66 | #define PES 040 | |
67 | #define WRL 04000 | |
68 | #define MOL 010000 | |
69 | #define ERR 040000 | |
70 | #define FCE 01000 | |
71 | #define TRE 040000 | |
72 | #define HARD 064023 /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */ | |
73 | ||
74 | #define SIO 1 | |
75 | #define SSFOR 2 | |
76 | #define SSREV 3 | |
77 | #define SRETRY 4 | |
78 | #define SCOM 5 | |
79 | #define SOK 6 | |
80 | ||
81 | #define H_WRITTEN 1 | |
82 | ||
83 | htopen(dev, flag) | |
84 | { | |
85 | register unit, ds; | |
86 | ||
80e7c811 BJ |
87 | if ((mbaact&(1<<HTMBANUM)) == 0) |
88 | mbainit(HTMBANUM); | |
786dff00 BJ |
89 | httab.b_flags |= B_TAPE; |
90 | unit = minor(dev) & 03; | |
a5cc519e | 91 | if (unit >= NHT || h_openf[unit]) { |
786dff00 BJ |
92 | u.u_error = ENXIO; |
93 | return; | |
94 | } | |
95 | h_blkno[unit] = 0; | |
96 | h_nxrec[unit] = INF; | |
97 | h_flags[unit] = 0; | |
98 | ds = hcommand(dev, NOP); | |
99 | if ((ds&MOL)==0 || (flag && (ds&WRL))) | |
100 | u.u_error = ENXIO; | |
101 | if (u.u_error==0) | |
102 | h_openf[unit]++; | |
103 | } | |
104 | ||
105 | htclose(dev, flag) | |
106 | { | |
107 | register int unit; | |
108 | ||
109 | unit = minor(dev) & 03; | |
110 | if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) { | |
81263dba BJ |
111 | (void) hcommand(dev, WEOF); |
112 | (void) hcommand(dev, WEOF); | |
113 | (void) hcommand(dev, SREV); | |
786dff00 | 114 | } |
786dff00 | 115 | if((minor(dev)&4) == 0) /* no 4 -> rewind */ |
81263dba | 116 | (void) hcommand(dev, REW); |
786dff00 BJ |
117 | h_openf[unit] = 0; |
118 | } | |
119 | ||
120 | hcommand(dev, com) | |
121 | { | |
122 | register struct buf *bp; | |
123 | ||
124 | bp = &chtbuf; | |
81263dba | 125 | (void) spl5(); |
786dff00 BJ |
126 | while(bp->b_flags&B_BUSY) { |
127 | bp->b_flags |= B_WANTED; | |
128 | sleep((caddr_t)bp, PRIBIO); | |
129 | } | |
81263dba | 130 | (void) spl0(); |
786dff00 BJ |
131 | bp->b_dev = dev; |
132 | bp->b_resid = com; | |
133 | bp->b_blkno = 0; | |
134 | bp->b_flags = B_BUSY|B_READ; | |
135 | htstrategy(bp); | |
136 | iowait(bp); | |
137 | if(bp->b_flags&B_WANTED) | |
138 | wakeup((caddr_t)bp); | |
139 | bp->b_flags = 0; | |
140 | return(bp->b_resid); | |
141 | } | |
142 | ||
143 | htstrategy(bp) | |
144 | register struct buf *bp; | |
145 | { | |
146 | register daddr_t *p; | |
147 | ||
148 | if(bp != &chtbuf) { | |
149 | p = &h_nxrec[minor(bp->b_dev)&03]; | |
150 | if(dbtofsb(bp->b_blkno) > *p) { | |
151 | bp->b_flags |= B_ERROR; | |
152 | bp->b_error = ENXIO; | |
153 | iodone(bp); | |
154 | return; | |
155 | } | |
156 | if(dbtofsb(bp->b_blkno) == *p && bp->b_flags&B_READ) { | |
157 | bp->b_resid = bp->b_bcount; | |
158 | clrbuf(bp); | |
159 | iodone(bp); | |
160 | return; | |
161 | } | |
162 | if ((bp->b_flags&B_READ)==0) { | |
163 | *p = dbtofsb(bp->b_blkno) + 1; | |
164 | h_flags[minor(bp->b_dev)&03] |= H_WRITTEN; | |
165 | } | |
166 | } | |
167 | bp->av_forw = NULL; | |
81263dba | 168 | (void) spl5(); |
786dff00 BJ |
169 | if (httab.b_actf == NULL) |
170 | httab.b_actf = bp; | |
171 | else | |
172 | httab.b_actl->av_forw = bp; | |
173 | httab.b_actl = bp; | |
174 | if (httab.b_active==0) | |
175 | htstart(); | |
81263dba | 176 | (void) spl0(); |
786dff00 BJ |
177 | } |
178 | ||
179 | htstart() | |
180 | { | |
181 | register struct buf *bp; | |
182 | register unit, den; | |
183 | daddr_t blkno; | |
80e7c811 | 184 | register struct device *htp = mbadev(HTMBA,0); |
786dff00 BJ |
185 | |
186 | loop: | |
187 | if ((bp = httab.b_actf) == NULL) | |
188 | return; | |
189 | unit = minor(bp->b_dev); | |
190 | den = P800 | (unit&03); | |
191 | if(unit >= 8) | |
192 | den = P1600 | (unit&03); | |
80e7c811 BJ |
193 | if((htp->httc&03777) != den) |
194 | htp->httc = den; | |
786dff00 BJ |
195 | unit &= 03; |
196 | blkno = h_blkno[unit]; | |
197 | if (bp == &chtbuf) { | |
198 | if (bp->b_resid==NOP) { | |
80e7c811 | 199 | bp->b_resid = htp->htds & 0xffff; |
786dff00 BJ |
200 | goto next; |
201 | } | |
202 | httab.b_active = SCOM; | |
80e7c811 BJ |
203 | htp->htfc = 0; |
204 | htp->htcs1 = bp->b_resid|GO; | |
786dff00 BJ |
205 | return; |
206 | } | |
207 | if (h_openf[unit] < 0 || dbtofsb(bp->b_blkno) > h_nxrec[unit]) | |
208 | goto abort; | |
209 | if (blkno == dbtofsb(bp->b_blkno)) { | |
210 | httab.b_active = SIO; | |
80e7c811 BJ |
211 | htp->htfc = -bp->b_bcount; |
212 | mbastart(bp, (int *)htp); | |
786dff00 BJ |
213 | } else { |
214 | if (blkno < dbtofsb(bp->b_blkno)) { | |
215 | httab.b_active = SSFOR; | |
80e7c811 BJ |
216 | htp->htfc = blkno - dbtofsb(bp->b_blkno); |
217 | htp->htcs1 = SFORW|GO; | |
786dff00 BJ |
218 | } else { |
219 | httab.b_active = SSREV; | |
80e7c811 BJ |
220 | htp->htfc = dbtofsb(bp->b_blkno) - blkno; |
221 | htp->htcs1 = SREV|GO; | |
786dff00 BJ |
222 | } |
223 | } | |
224 | return; | |
225 | ||
226 | abort: | |
227 | bp->b_flags |= B_ERROR; | |
228 | ||
229 | next: | |
230 | httab.b_actf = bp->av_forw; | |
231 | iodone(bp); | |
232 | goto loop; | |
233 | } | |
234 | ||
235 | /*ARGSUSED*/ | |
236 | htintr(mbastat, as) | |
237 | { | |
238 | register struct buf *bp; | |
239 | register int unit, state; | |
240 | int err; | |
80e7c811 | 241 | register struct device *htp = mbadev(HTMBA,0); |
786dff00 BJ |
242 | |
243 | if ((bp = httab.b_actf)==NULL) | |
244 | return; | |
245 | unit = minor(bp->b_dev) & 03; | |
246 | state = httab.b_active; | |
247 | httab.b_active = 0; | |
80e7c811 BJ |
248 | if (htp->htds&(ERR|EOT|TM) || mbastat & MBAEBITS) { |
249 | err = htp->hter & 0xffff; | |
786dff00 BJ |
250 | if ((mbastat & MBAEBITS) || (err&HARD)) |
251 | state = 0; | |
252 | if (bp == &rhtbuf) | |
253 | err &= ~FCE; | |
80e7c811 | 254 | if ((bp->b_flags&B_READ) && (htp->htds&PES)) |
786dff00 | 255 | err &= ~(CS|COR); |
80e7c811 | 256 | if(htp->htds&EOT || (htp->htds&MOL)==0) { |
786dff00 BJ |
257 | if(h_openf[unit]) |
258 | h_openf[unit] = -1; | |
259 | } | |
80e7c811 BJ |
260 | else if(htp->htds&TM) { |
261 | htp->htfc = 0; | |
786dff00 BJ |
262 | h_nxrec[unit] = dbtofsb(bp->b_blkno); |
263 | state = SOK; | |
264 | } | |
265 | else if(state && err == 0) | |
266 | state = SOK; | |
267 | if(httab.b_errcnt > 4) | |
80e7c811 BJ |
268 | deverror(bp, htp->hter, mbastat); |
269 | HTMBA->mba_cr &= ~MBAIE; | |
270 | htp->htcs1 = DCLR|GO; | |
271 | HTMBA->mba_cr |= MBAIE; | |
786dff00 BJ |
272 | if (state==SIO && ++httab.b_errcnt < 10) { |
273 | httab.b_active = SRETRY; | |
274 | h_blkno[unit]++; | |
80e7c811 BJ |
275 | htp->htfc = -1; |
276 | htp->htcs1 = SREV|GO; | |
786dff00 BJ |
277 | return; |
278 | } | |
279 | if (state!=SOK) { | |
280 | bp->b_flags |= B_ERROR; | |
281 | state = SIO; | |
282 | } | |
80e7c811 BJ |
283 | } else if (htp->htcs1 < 0) { /* SC */ |
284 | if(htp->htds & ERR) { | |
285 | HTMBA->mba_cr &= ~MBAIE; | |
286 | htp->htcs1 = DCLR|GO; | |
287 | HTMBA->mba_cr |= MBAIE; | |
786dff00 BJ |
288 | } |
289 | } | |
290 | switch(state) { | |
291 | case SIO: | |
292 | case SOK: | |
293 | h_blkno[unit]++; | |
294 | ||
295 | case SCOM: | |
296 | httab.b_errcnt = 0; | |
297 | httab.b_actf = bp->av_forw; | |
80e7c811 | 298 | bp->b_resid = - (htp->htfc & 0xffff); |
786dff00 BJ |
299 | if (bp->b_flags & B_READ) |
300 | bp->b_resid += bp->b_bcount; | |
301 | iodone(bp); | |
302 | break; | |
303 | ||
304 | case SRETRY: | |
305 | if((bp->b_flags&B_READ)==0) { | |
306 | httab.b_active = SSFOR; | |
80e7c811 | 307 | htp->htcs1 = ERASE|GO; |
786dff00 BJ |
308 | return; |
309 | } | |
310 | ||
311 | case SSFOR: | |
312 | case SSREV: | |
293c7069 | 313 | #define blk dbtofsb(bp->b_blkno) |
80e7c811 | 314 | if(htp->htds & TM) { |
786dff00 | 315 | if(state == SSREV) { |
80e7c811 | 316 | h_nxrec[unit] = blk - (htp->htfc&0xffff); |
786dff00 BJ |
317 | h_blkno[unit] = h_nxrec[unit]; |
318 | } else { | |
80e7c811 BJ |
319 | h_nxrec[unit] = blk + (htp->htfc&0xffff) - 1; |
320 | h_blkno[unit] = blk + (htp->htfc & 0xffff); | |
786dff00 BJ |
321 | } |
322 | } else | |
293c7069 | 323 | h_blkno[unit] = blk; |
786dff00 | 324 | break; |
f0a3ddbd | 325 | #undef blk |
786dff00 BJ |
326 | |
327 | default: | |
328 | return; | |
329 | } | |
330 | htstart(); | |
331 | } | |
332 | ||
333 | htread(dev) | |
334 | { | |
335 | htphys(dev); | |
336 | physio(htstrategy, &rhtbuf, dev, B_READ, minphys); | |
337 | } | |
338 | ||
339 | htwrite(dev) | |
340 | { | |
341 | htphys(dev); | |
342 | physio(htstrategy, &rhtbuf, dev, B_WRITE, minphys); | |
343 | } | |
344 | ||
345 | htphys(dev) | |
346 | { | |
347 | register unit; | |
348 | daddr_t a; | |
349 | ||
350 | unit = minor(dev) & 03; | |
a5cc519e | 351 | if(unit < NHT) { |
786dff00 BJ |
352 | a = u.u_offset >> 9; |
353 | h_blkno[unit] = dbtofsb(a); | |
354 | h_nxrec[unit] = dbtofsb(a)+1; | |
355 | } | |
356 | } | |
f0a3ddbd BJ |
357 | |
358 | #define HTADDR ((struct device *)(HTPHYSMBA + 0x400)) | |
359 | #define HTMAP ((struct pte *) (HTPHYSMBA + 0x800)) | |
360 | ||
361 | #define DBSIZE 20 | |
362 | ||
363 | twall(start, num) | |
364 | char *start; | |
365 | int num; | |
366 | { | |
367 | int blk; | |
368 | ||
369 | HTADDR->httc = P800; /* set 800 bpi mode */ | |
370 | HTADDR->htcs1 = DCLR | GO; | |
371 | while (num > 0) { | |
372 | blk = num > DBSIZE ? DBSIZE : num; | |
373 | twrite(start, blk); | |
374 | start += blk*NBPG; | |
375 | num -= blk; | |
376 | } | |
377 | } | |
378 | ||
379 | twrite(buf, num) | |
380 | char *buf; | |
381 | { | |
382 | register struct pte *hpte = HTMAP; | |
383 | register int i; | |
384 | ||
385 | twait(); | |
386 | HTADDR->htfc = -(num*NBPG); | |
387 | for (i = 0; i < num; i++) | |
388 | *(int *)hpte++ = (btop(buf)+i) | PG_V; | |
389 | ((struct mba_regs *)PHYSMBA1)->mba_sr = -1; | |
390 | ((struct mba_regs *)PHYSMBA1)->mba_bcr = -(num*NBPG); | |
391 | ((struct mba_regs *)PHYSMBA1)->mba_var = 0; | |
392 | HTADDR->htcs1 = WCOM | GO; | |
393 | } | |
394 | ||
395 | twait() | |
396 | { | |
397 | register s; | |
398 | ||
399 | do | |
400 | s = HTADDR->htds; | |
401 | while ((s & RDY) == 0); | |
402 | } | |
403 | ||
404 | rewind() | |
405 | { | |
406 | ||
407 | twait(); | |
408 | HTADDR->htcs1 = REW | GO; | |
409 | } | |
410 | ||
411 | teof() | |
412 | { | |
413 | ||
414 | twait(); | |
415 | HTADDR->htcs1 = WEOF | GO; | |
416 | } | |
a5cc519e | 417 | #endif |