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:
14: struct {
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:
32: struct devtab httab;
33: struct buf rhtbuf;
34:
35: #define NUNIT 8
36:
37: char h_openf[NUNIT];
38: char *h_blkno[NUNIT];
39: char *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:
64: htopen(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:
79: htclose(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:
92: hcommand(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:
111: htstrategy(abp)
112: struct 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:
145: htstart()
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:
186: htintr()
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:
226: htread(dev)
227: {
228: htphys(dev);
229: physio(htstrategy, &rhtbuf, dev, B_READ);
230: u.u_count = -rhtbuf.b_resid;
231: }
232:
233: htwrite(dev)
234: {
235: htphys(dev);
236: physio(htstrategy, &rhtbuf, dev, B_WRITE);
237: u.u_count = 0;
238: }
239:
240: htphys(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: }
Defined functions
Defined variables
httab
defined in line
32; used 19 times
Defined macros
CLR
defined in line
50; used 1 times
CRDY
defined in line
54; used 2 times
DRY
defined in line
56; used 2 times
EOF
defined in line
55; used 1 times
ERASE
defined in line
48;
never used
ERR
defined in line
59; used 2 times
GO
defined in line
43; used 5 times
HTADDR
defined in line
41; used 23 times
MOL
defined in line
57; used 2 times
NOP
defined in line
44; used 1 times
NUNIT
defined in line
35; used 4 times
P1600
defined in line
52; used 2 times
P800
defined in line
51; used 2 times
PIP
defined in line
58; used 1 times
REW
defined in line
49; used 2 times
SFORW
defined in line
46; used 1 times
SIO
defined in line
62; used 4 times
SREV
defined in line
47; used 1 times
SSEEK
defined in line
61; used 1 times
WEOF
defined in line
45; used 2 times