1: /*
2: * TJU16 tape driver
3: */
4:
5: #include "../h/param.h"
6: #include "../h/systm.h"
7: #include "../h/buf.h"
8: #include "../h/conf.h"
9: #include "../h/dir.h"
10: #include "../h/file.h"
11: #include "../h/user.h"
12:
13: struct device
14: {
15: int htcs1;
16: int htwc;
17: caddr_t 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: int htcs3;
31: };
32:
33: struct buf httab;
34: struct buf rhtbuf;
35: struct buf chtbuf;
36:
37: #define NUNIT 1
38: #define INF 1000000
39:
40: char h_flags[NUNIT];
41: char h_openf[NUNIT];
42: daddr_t h_blkno[NUNIT];
43: daddr_t h_nxrec[NUNIT];
44:
45: #define HTADDR ((struct device *)0172440)
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 01300 /* 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 CLR 040 /* controller clear (in cs2) */
75:
76: #define NED 010000
77:
78: #define SIO 1
79: #define SSFOR 2
80: #define SSREV 3
81: #define SRETRY 4
82: #define SCOM 5
83: #define SOK 6
84:
85: #define H_WRITTEN 1
86: htopen(dev, flag)
87: {
88: register unit, ds;
89:
90: httab.b_flags |= B_TAPE;
91: unit = minor(dev) & 077;
92: if (unit >= NUNIT || h_openf[unit]) {
93: u.u_error = ENXIO;
94: return;
95: }
96: h_blkno[unit] = 0;
97: h_nxrec[unit] = INF;
98: h_flags[unit] = 0;
99: ds = hcommand(dev, NOP);
100: if ((ds&MOL)==0 || (flag && (ds&WRL)))
101: u.u_error = ENXIO;
102: if (u.u_error==0)
103: h_openf[unit]++;
104: }
105:
106: htclose(dev, flag)
107: {
108: register int unit;
109:
110: unit = minor(dev) & 077;
111: if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) {
112: hcommand(dev, WEOF);
113: hcommand(dev, WEOF);
114: hcommand(dev, SREV);
115: }
116: if ((minor(dev)&0200) == 0)
117: hcommand(dev, REW);
118: h_openf[unit] = 0;
119: }
120:
121: hcommand(dev, com)
122: {
123: register struct buf *bp;
124:
125: bp = &chtbuf;
126: spl5();
127: while(bp->b_flags&B_BUSY) {
128: bp->b_flags |= B_WANTED;
129: sleep((caddr_t)bp, PRIBIO);
130: }
131: spl0();
132: bp->b_dev = dev;
133: bp->b_resid = com;
134: bp->b_blkno = 0;
135: bp->b_flags = B_BUSY|B_READ;
136: htstrategy(bp);
137: iowait(bp);
138: if(bp->b_flags&B_WANTED)
139: wakeup((caddr_t)bp);
140: bp->b_flags = 0;
141: return(bp->b_resid);
142: }
143:
144: htstrategy(bp)
145: register struct buf *bp;
146: {
147: register daddr_t *p;
148:
149: if(bp != &chtbuf) {
150: p = &h_nxrec[minor(bp->b_dev)&077];
151: if(bp->b_blkno > *p) {
152: bp->b_flags |= B_ERROR;
153: bp->b_error = ENXIO;
154: iodone(bp);
155: return;
156: }
157: if(bp->b_blkno == *p && bp->b_flags&B_READ) {
158: clrbuf(bp);
159: bp->b_resid = bp->b_bcount;
160: iodone(bp);
161: return;
162: }
163: if ((bp->b_flags&B_READ)==0) {
164: *p = bp->b_blkno + 1;
165: h_flags[minor(bp->b_dev)&077] |= H_WRITTEN;
166: }
167: }
168: bp->av_forw = NULL;
169: spl5();
170: if (httab.b_actf == NULL)
171: httab.b_actf = bp;
172: else
173: httab.b_actl->av_forw = bp;
174: httab.b_actl = bp;
175: if (httab.b_active==0)
176: htstart();
177: spl0();
178: }
179:
180: htstart()
181: {
182: register struct buf *bp;
183: register unit, den;
184: daddr_t blkno;
185:
186: loop:
187: if ((bp = httab.b_actf) == NULL)
188: return;
189: unit = minor(bp->b_dev) & 0177;
190: HTADDR->htcs2 = ((unit>>3)&07);
191: den = P1600 | (unit&07);
192: if(unit > 077)
193: den = P800 | (unit&07);
194: if((HTADDR->httc&03777) != den)
195: HTADDR->httc = den;
196: if (HTADDR->htcs2 & NED || (HTADDR->htds&MOL)==0)
197: goto abort;
198: unit &= 077;
199: blkno = h_blkno[unit];
200: if (bp == &chtbuf) {
201: if (bp->b_resid==NOP) {
202: bp->b_resid = HTADDR->htds;
203: goto next;
204: }
205: httab.b_active = SCOM;
206: HTADDR->htfc = 0;
207: HTADDR->htcs1 = bp->b_resid|IENABLE|GO;
208: return;
209: }
210: if (h_openf[unit] < 0 || bp->b_blkno > h_nxrec[unit])
211: goto abort;
212: if (blkno == bp->b_blkno) {
213: httab.b_active = SIO;
214: HTADDR->htba = bp->b_un.b_addr;
215: if(cputype == 70)
216: HTADDR->htbae = bp->b_xmem;
217: HTADDR->htfc = -bp->b_bcount;
218: HTADDR->htwc = -(bp->b_bcount>>1);
219: den = ((bp->b_xmem&3) << 8) | IENABLE | GO;
220: if(bp->b_flags & B_READ)
221: den |= RCOM;
222: else {
223: if(HTADDR->htds & EOT) {
224: bp->b_resid = bp->b_bcount;
225: goto next;
226: }
227: den |= WCOM;
228: }
229: HTADDR->htcs1 = den;
230: } else {
231: if (blkno < bp->b_blkno) {
232: httab.b_active = SSFOR;
233: HTADDR->htfc = blkno - bp->b_blkno;
234: HTADDR->htcs1 = SFORW|IENABLE|GO;
235: } else {
236: httab.b_active = SSREV;
237: HTADDR->htfc = bp->b_blkno - blkno;
238: HTADDR->htcs1 = SREV|IENABLE|GO;
239: }
240: }
241: return;
242:
243: abort:
244: bp->b_flags |= B_ERROR;
245:
246: next:
247: httab.b_actf = bp->av_forw;
248: iodone(bp);
249: goto loop;
250: }
251:
252: htintr()
253: {
254: register struct buf *bp;
255: register int unit, state;
256: int err;
257:
258: if ((bp = httab.b_actf)==NULL)
259: return;
260: unit = minor(bp->b_dev) & 077;
261: state = httab.b_active;
262: httab.b_active = 0;
263: if (HTADDR->htcs1&TRE) {
264: err = HTADDR->hter;
265: if (HTADDR->htcs2&077400 || (err&HARD))
266: state = 0;
267: if (bp == &rhtbuf)
268: err &= ~FCE;
269: if ((bp->b_flags&B_READ) && (HTADDR->htds&PES))
270: err &= ~(CS|COR);
271: if((HTADDR->htds&MOL) == 0) {
272: if(h_openf[unit])
273: h_openf[unit] = -1;
274: }
275: else if(HTADDR->htds&TM) {
276: HTADDR->htwc = -(bp->b_bcount>>1);
277: h_nxrec[unit] = bp->b_blkno;
278: state = SOK;
279: }
280: else if(state && err == 0)
281: state = SOK;
282: if(httab.b_errcnt > 4)
283: deverror(bp, HTADDR->hter, HTADDR->htcs2);
284: htinit();
285: if (state==SIO && ++httab.b_errcnt < 10) {
286: httab.b_active = SRETRY;
287: h_blkno[unit]++;
288: HTADDR->htfc = -1;
289: HTADDR->htcs1 = SREV|IENABLE|GO;
290: return;
291: }
292: if (state!=SOK) {
293: bp->b_flags |= B_ERROR;
294: state = SIO;
295: }
296: } else if (HTADDR->htcs1 < 0) { /* SC */
297: if(HTADDR->htds & ERR)
298: htinit();
299: }
300: switch(state) {
301: case SIO:
302: case SOK:
303: h_blkno[unit]++;
304:
305: case SCOM:
306: httab.b_errcnt = 0;
307: httab.b_actf = bp->av_forw;
308: iodone(bp);
309: bp->b_resid = (-HTADDR->htwc)<<1;
310: break;
311:
312: case SRETRY:
313: if((bp->b_flags&B_READ)==0) {
314: httab.b_active = SSFOR;
315: HTADDR->htcs1 = ERASE|IENABLE|GO;
316: return;
317: }
318:
319: case SSFOR:
320: case SSREV:
321: if(HTADDR->htds & TM) {
322: if(state == SSREV) {
323: h_nxrec[unit] = bp->b_blkno - HTADDR->htfc;
324: h_blkno[unit] = h_nxrec[unit];
325: } else {
326: h_nxrec[unit] = bp->b_blkno + HTADDR->htfc - 1;
327: h_blkno[unit] = h_nxrec[unit]+1;
328: }
329: } else
330: h_blkno[unit] = bp->b_blkno;
331: break;
332:
333: default:
334: return;
335: }
336: htstart();
337: }
338:
339: htinit()
340: {
341: register ocs2;
342: register omttc;
343:
344: omttc = HTADDR->httc & 03777; /* preserve old slave select, dens, format */
345: ocs2 = HTADDR->htcs2 & 07; /* preserve old unit */
346:
347: HTADDR->htcs2 = CLR;
348: HTADDR->htcs2 = ocs2;
349: HTADDR->httc = omttc;
350: HTADDR->htcs1 = DCLR|GO;
351: }
352:
353: htread(dev)
354: {
355: htphys(dev);
356: physio(htstrategy, &rhtbuf, dev, B_READ);
357: }
358:
359: htwrite(dev)
360: {
361: htphys(dev);
362: physio(htstrategy, &rhtbuf, dev, B_WRITE);
363: }
364:
365: htphys(dev)
366: {
367: register unit;
368: daddr_t a;
369:
370: unit = minor(dev) & 077;
371: if(unit < NUNIT) {
372: a = u.u_offset >> 9;
373: h_blkno[unit] = a;
374: h_nxrec[unit] = a+1;
375: }
376: }
Defined functions
Defined variables
httab
defined in line
33; used 21 times
- in line 90,
170-175(5),
187,
205,
213,
232-236(2),
247,
258-262(3),
282-286(3),
306-307(2),
314
Defined struct's
Defined macros
CLR
defined in line
74; used 1 times
COR
defined in line
65; used 1 times
CS
defined in line
64; used 1 times
DCLR
defined in line
56; used 1 times
DRY
defined in line
62;
never used
EOT
defined in line
63; used 1 times
ERASE
defined in line
54; used 1 times
ERR
defined in line
69; used 1 times
FCE
defined in line
70; used 1 times
GO
defined in line
47; used 7 times
HARD
defined in line
72; used 1 times
HTADDR
defined in line
45; used 42 times
- in line 190-196(5),
202-207(3),
214-223(5),
229-238(5),
263-276(7),
283-289(4),
296-297(2),
309,
315,
321-326(3),
344-350(6)
INF
defined in line
38; used 1 times
MOL
defined in line
68; used 3 times
NED
defined in line
76; used 1 times
NOP
defined in line
50; used 2 times
NUNIT
defined in line
37; used 6 times
P1600
defined in line
58; used 1 times
P800
defined in line
57; used 1 times
PES
defined in line
66; used 1 times
RCOM
defined in line
49; used 1 times
RDY
defined in line
60;
never used
REW
defined in line
55; used 1 times
SCOM
defined in line
82; used 1 times
SFORW
defined in line
52; used 1 times
SIO
defined in line
78; used 3 times
SOK
defined in line
83; used 3 times
SREV
defined in line
53; used 3 times
SSFOR
defined in line
79; used 2 times
SSREV
defined in line
80; used 2 times
TM
defined in line
61; used 2 times
TRE
defined in line
71; used 1 times
WCOM
defined in line
48; used 1 times
WEOF
defined in line
51; used 2 times
WRL
defined in line
67; used 1 times