|
|
1.1 root 1: /* ht.c 4.2 11/10/80 */
2:
3: #include "../conf/ht.h"
4: #if NHT > 0
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"
17: #include "../h/pte.h"
18: #include "../h/mba.h"
19:
20: struct device
21: {
22: int htcs1;
23: int htds;
24: int hter;
25: int htmr;
26: int htas;
27: int htfc;
28: int htdt;
29: int htck;
30: int htsn;
31: int httc;
32: };
33:
34: struct buf httab;
35: struct buf rhtbuf;
36: struct buf chtbuf;
37:
38: #define INF 1000000
39:
40: char h_openf[NHT];
41: daddr_t h_blkno[NHT];
42: char h_flags[NHT];
43: daddr_t h_nxrec[NHT];
44:
45: #define GO 01
46: #define WCOM 060
47: #define RCOM 070
48: #define NOP 0
49: #define WEOF 026
50: #define SFORW 030
51: #define SREV 032
52: #define ERASE 024
53: #define REW 06
54: #define DCLR 010
55: #define P800 01700 /* 800 + pdp11 mode */
56: #define P1600 02300 /* 1600 + pdp11 mode */
57: #define IENABLE 0100
58: #define RDY 0200
59: #define TM 04
60: #define DRY 0200
61: #define EOT 02000
62: #define CS 02000
63: #define COR 0100000
64: #define PES 040
65: #define WRL 04000
66: #define MOL 010000
67: #define ERR 040000
68: #define FCE 01000
69: #define TRE 040000
70: #define HARD 064023 /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */
71:
72: #define SIO 1
73: #define SSFOR 2
74: #define SSREV 3
75: #define SRETRY 4
76: #define SCOM 5
77: #define SOK 6
78:
79: #define H_WRITTEN 1
80:
81: htopen(dev, flag)
82: {
83: register unit, ds;
84:
85: if ((mbaact&(1<<HTMBANUM)) == 0)
86: mbainit(HTMBANUM);
87: httab.b_flags |= B_TAPE;
88: unit = minor(dev) & 03;
89: if (unit >= NHT || h_openf[unit]) {
90: u.u_error = ENXIO;
91: return;
92: }
93: h_blkno[unit] = 0;
94: h_nxrec[unit] = INF;
95: h_flags[unit] = 0;
96: ds = hcommand(dev, NOP);
97: if ((ds&MOL)==0 || (flag && (ds&WRL)))
98: u.u_error = ENXIO;
99: if (u.u_error==0)
100: h_openf[unit]++;
101: }
102:
103: htclose(dev, flag)
104: {
105: register int unit;
106:
107: unit = minor(dev) & 03;
108: if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) {
109: (void) hcommand(dev, WEOF);
110: (void) hcommand(dev, WEOF);
111: (void) hcommand(dev, SREV);
112: }
113: if((minor(dev)&4) == 0) /* no 4 -> rewind */
114: (void) hcommand(dev, REW);
115: h_openf[unit] = 0;
116: }
117:
118: hcommand(dev, com)
119: {
120: register struct buf *bp;
121:
122: bp = &chtbuf;
123: (void) spl5();
124: while(bp->b_flags&B_BUSY) {
125: bp->b_flags |= B_WANTED;
126: sleep((caddr_t)bp, PRIBIO);
127: }
128: (void) spl0();
129: bp->b_dev = dev;
130: bp->b_resid = com;
131: bp->b_blkno = 0;
132: bp->b_flags = B_BUSY|B_READ;
133: htstrategy(bp);
134: iowait(bp);
135: if(bp->b_flags&B_WANTED)
136: wakeup((caddr_t)bp);
137: bp->b_flags = 0;
138: return(bp->b_resid);
139: }
140:
141: htstrategy(bp)
142: register struct buf *bp;
143: {
144: register daddr_t *p;
145:
146: if(bp != &chtbuf) {
147: p = &h_nxrec[minor(bp->b_dev)&03];
148: if(dbtofsb(bp->b_blkno) > *p) {
149: bp->b_flags |= B_ERROR;
150: bp->b_error = ENXIO;
151: iodone(bp);
152: return;
153: }
154: if(dbtofsb(bp->b_blkno) == *p && bp->b_flags&B_READ) {
155: bp->b_resid = bp->b_bcount;
156: clrbuf(bp);
157: iodone(bp);
158: return;
159: }
160: if ((bp->b_flags&B_READ)==0) {
161: *p = dbtofsb(bp->b_blkno) + 1;
162: h_flags[minor(bp->b_dev)&03] |= H_WRITTEN;
163: }
164: }
165: bp->av_forw = NULL;
166: (void) spl5();
167: if (httab.b_actf == NULL)
168: httab.b_actf = bp;
169: else
170: httab.b_actl->av_forw = bp;
171: httab.b_actl = bp;
172: if (httab.b_active==0)
173: htstart();
174: (void) spl0();
175: }
176:
177: htstart()
178: {
179: register struct buf *bp;
180: register unit, den;
181: daddr_t blkno;
182: register struct device *htp = mbadev(HTMBA,0);
183:
184: loop:
185: if ((bp = httab.b_actf) == NULL)
186: return;
187: unit = minor(bp->b_dev);
188: den = P800 | (unit&03);
189: if(unit >= 8)
190: den = P1600 | (unit&03);
191: if((htp->httc&03777) != den)
192: htp->httc = den;
193: unit &= 03;
194: blkno = h_blkno[unit];
195: if (bp == &chtbuf) {
196: if (bp->b_resid==NOP) {
197: bp->b_resid = htp->htds & 0xffff;
198: goto next;
199: }
200: httab.b_active = SCOM;
201: htp->htfc = 0;
202: htp->htcs1 = bp->b_resid|GO;
203: return;
204: }
205: if (h_openf[unit] < 0 || dbtofsb(bp->b_blkno) > h_nxrec[unit])
206: goto abort;
207: if (blkno == dbtofsb(bp->b_blkno)) {
208: httab.b_active = SIO;
209: htp->htfc = -bp->b_bcount;
210: mbastart(bp, (int *)htp);
211: } else {
212: if (blkno < dbtofsb(bp->b_blkno)) {
213: httab.b_active = SSFOR;
214: htp->htfc = blkno - dbtofsb(bp->b_blkno);
215: htp->htcs1 = SFORW|GO;
216: } else {
217: httab.b_active = SSREV;
218: htp->htfc = dbtofsb(bp->b_blkno) - blkno;
219: htp->htcs1 = SREV|GO;
220: }
221: }
222: return;
223:
224: abort:
225: bp->b_flags |= B_ERROR;
226:
227: next:
228: httab.b_actf = bp->av_forw;
229: iodone(bp);
230: goto loop;
231: }
232:
233: /*ARGSUSED*/
234: htintr(mbastat, as)
235: {
236: register struct buf *bp;
237: register int unit, state;
238: int err;
239: register struct device *htp = mbadev(HTMBA,0);
240:
241: if ((bp = httab.b_actf)==NULL)
242: return;
243: unit = minor(bp->b_dev) & 03;
244: state = httab.b_active;
245: httab.b_active = 0;
246: if (htp->htds&(ERR|EOT|TM) || mbastat & MBAEBITS) {
247: err = htp->hter & 0xffff;
248: if ((mbastat & MBAEBITS) || (err&HARD))
249: state = 0;
250: if (bp == &rhtbuf)
251: err &= ~FCE;
252: if ((bp->b_flags&B_READ) && (htp->htds&PES))
253: err &= ~(CS|COR);
254: if(htp->htds&EOT || (htp->htds&MOL)==0) {
255: if(h_openf[unit])
256: h_openf[unit] = -1;
257: }
258: else if(htp->htds&TM) {
259: htp->htfc = 0;
260: h_nxrec[unit] = dbtofsb(bp->b_blkno);
261: state = SOK;
262: }
263: else if(state && err == 0)
264: state = SOK;
265: if(httab.b_errcnt > 4)
266: deverror(bp, htp->hter, mbastat);
267: HTMBA->mba_cr &= ~MBAIE;
268: htp->htcs1 = DCLR|GO;
269: HTMBA->mba_cr |= MBAIE;
270: if (state==SIO && ++httab.b_errcnt < 10) {
271: httab.b_active = SRETRY;
272: h_blkno[unit]++;
273: htp->htfc = -1;
274: htp->htcs1 = SREV|GO;
275: return;
276: }
277: if (state!=SOK) {
278: bp->b_flags |= B_ERROR;
279: state = SIO;
280: }
281: } else if (htp->htcs1 < 0) { /* SC */
282: if(htp->htds & ERR) {
283: HTMBA->mba_cr &= ~MBAIE;
284: htp->htcs1 = DCLR|GO;
285: HTMBA->mba_cr |= MBAIE;
286: }
287: }
288: switch(state) {
289: case SIO:
290: case SOK:
291: h_blkno[unit]++;
292:
293: case SCOM:
294: httab.b_errcnt = 0;
295: httab.b_actf = bp->av_forw;
296: bp->b_resid = - (htp->htfc & 0xffff);
297: if (bp->b_flags & B_READ)
298: bp->b_resid += bp->b_bcount;
299: iodone(bp);
300: break;
301:
302: case SRETRY:
303: if((bp->b_flags&B_READ)==0) {
304: httab.b_active = SSFOR;
305: htp->htcs1 = ERASE|GO;
306: return;
307: }
308:
309: case SSFOR:
310: case SSREV:
311: #define blk dbtofsb(bp->b_blkno)
312: if(htp->htds & TM) {
313: if(state == SSREV) {
314: h_nxrec[unit] = blk - (htp->htfc&0xffff);
315: h_blkno[unit] = h_nxrec[unit];
316: } else {
317: h_nxrec[unit] = blk + (htp->htfc&0xffff) - 1;
318: h_blkno[unit] = blk + (htp->htfc & 0xffff);
319: }
320: } else
321: h_blkno[unit] = blk;
322: break;
323:
324: default:
325: return;
326: }
327: htstart();
328: }
329:
330: htread(dev)
331: {
332: htphys(dev);
333: physio(htstrategy, &rhtbuf, dev, B_READ, minphys);
334: }
335:
336: htwrite(dev)
337: {
338: htphys(dev);
339: physio(htstrategy, &rhtbuf, dev, B_WRITE, minphys);
340: }
341:
342: htphys(dev)
343: {
344: register unit;
345: daddr_t a;
346:
347: unit = minor(dev) & 03;
348: if(unit < NHT) {
349: a = u.u_offset >> 9;
350: h_blkno[unit] = dbtofsb(a);
351: h_nxrec[unit] = dbtofsb(a)+1;
352: }
353: }
354: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.