1: #
2: /*
3: */
4:
5: /*
6: * TM 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 tmer;
16: int tmcs;
17: int tmbc;
18: int tmba;
19: int tmdb;
20: int tmrd;
21: };
22:
23: struct devtab tmtab;
24: struct buf rtmbuf;
25:
26: char t_openf[8];
27: char *t_blkno[8];
28: char *t_nxrec[8];
29:
30: #define TMADDR 0172520
31:
32: #define GO 01
33: #define RCOM 02
34: #define WCOM 04
35: #define WEOF 06
36: #define SFORW 010
37: #define SREV 012
38: #define WIRG 014
39: #define REW 016
40: #define DENS 060000 /* 9-channel */
41: #define IENABLE 0100
42: #define CRDY 0200
43: #define GAPSD 010000
44: #define TUR 1
45: #define HARD 0102200 /* ILC, EOT, NXM */
46: #define EOF 0040000
47:
48: #define SSEEK 1
49: #define SIO 2
50:
51: tmopen(dev, flag)
52: {
53: register dminor;
54:
55: dminor = dev.d_minor;
56: if (t_openf[dminor])
57: u.u_error = ENXIO;
58: else {
59: t_openf[dminor]++;
60: t_blkno[dminor] = 0;
61: t_nxrec[dminor] = 65535;
62: }
63: }
64:
65: tmclose(dev, flag)
66: {
67: register int dminor;
68:
69: dminor = dev.d_minor;
70: t_openf[dminor] = 0;
71: if (flag)
72: tcommand(dminor, WEOF);
73: tcommand(dminor, REW);
74: }
75:
76: tcommand(unit, com)
77: {
78: extern lbolt;
79:
80: while (tmtab.d_active || (TMADDR->tmcs & CRDY)==0)
81: sleep(&lbolt, 1);
82: TMADDR->tmcs = DENS|com|GO | (unit<<8);
83: }
84:
85: tmstrategy(abp)
86: struct buf *abp;
87: {
88: register struct buf *bp;
89: register char **p;
90:
91: bp = abp;
92: p = &t_nxrec[bp->b_dev.d_minor];
93: if (*p <= bp->b_blkno) {
94: if (*p < bp->b_blkno) {
95: bp->b_flags =| B_ERROR;
96: iodone(bp);
97: return;
98: }
99: if (bp->b_flags&B_READ) {
100: clrbuf(bp);
101: iodone(bp);
102: return;
103: }
104: }
105: if ((bp->b_flags&B_READ)==0)
106: *p = bp->b_blkno + 1;
107: bp->av_forw = 0;
108: spl5();
109: if (tmtab.d_actf==0)
110: tmtab.d_actf = bp;
111: else
112: tmtab.d_actl->av_forw = bp;
113: tmtab.d_actl = bp;
114: if (tmtab.d_active==0)
115: tmstart();
116: spl0();
117: }
118:
119: tmstart()
120: {
121: register struct buf *bp;
122: register int com;
123: int unit;
124: register char *blkno;
125:
126: loop:
127: if ((bp = tmtab.d_actf) == 0)
128: return;
129: unit = bp->b_dev.d_minor;
130: blkno = t_blkno[unit];
131: if (t_openf[unit] < 0 || (TMADDR->tmcs & CRDY)==0) {
132: bp->b_flags =| B_ERROR;
133: tmtab.d_actf = bp->av_forw;
134: iodone(bp);
135: goto loop;
136: }
137: com = (unit<<8) | ((bp->b_xmem & 03) << 4) | IENABLE|DENS;
138: if (blkno != bp->b_blkno) {
139: tmtab.d_active = SSEEK;
140: if (blkno < bp->b_blkno) {
141: com =| SFORW|GO;
142: TMADDR->tmbc = blkno - bp->b_blkno;
143: } else {
144: if (bp->b_blkno == 0)
145: com =| REW|GO;
146: else {
147: com =| SREV|GO;
148: TMADDR->tmbc = bp->b_blkno - blkno;
149: }
150: }
151: TMADDR->tmcs = com;
152: return;
153: }
154: tmtab.d_active = SIO;
155: TMADDR->tmbc = bp->b_wcount << 1;
156: TMADDR->tmba = bp->b_addr; /* core address */
157: TMADDR->tmcs = com | ((bp->b_flags&B_READ)? RCOM|GO:
158: ((tmtab.d_errcnt)? WIRG|GO: WCOM|GO));
159: }
160:
161: tmintr()
162: {
163: register struct buf *bp;
164: register int unit;
165:
166: if ((bp = tmtab.d_actf)==0)
167: return;
168: unit = bp->b_dev.d_minor;
169: if (TMADDR->tmcs < 0) { /* error bit */
170: /*
171: deverror(bp, TMADDR->tmer);
172: */
173: while(TMADDR->tmrd & GAPSD) ; /* wait for gap shutdown */
174: if ((TMADDR->tmer&(HARD|EOF))==0 && tmtab.d_active==SIO) {
175: if (++tmtab.d_errcnt < 10) {
176: t_blkno[unit]++;
177: tmtab.d_active = 0;
178: tmstart();
179: return;
180: }
181: } else
182: if(bp != &rtmbuf && (TMADDR->tmer&EOF)==0)
183: t_openf[unit] = -1;
184: bp->b_flags =| B_ERROR;
185: tmtab.d_active = SIO;
186: }
187: if (tmtab.d_active == SIO) {
188: tmtab.d_errcnt = 0;
189: t_blkno[unit]++;
190: tmtab.d_actf = bp->av_forw;
191: tmtab.d_active = 0;
192: iodone(bp);
193: bp->b_resid = TMADDR->tmbc;
194: } else
195: t_blkno[unit] = bp->b_blkno;
196: tmstart();
197: }
198:
199: tmread(dev)
200: {
201: tmphys(dev);
202: physio(tmstrategy, &rtmbuf, dev, B_READ);
203: u.u_count = -rtmbuf.b_resid;
204: }
205:
206: tmwrite(dev)
207: {
208: tmphys(dev);
209: physio(tmstrategy, &rtmbuf, dev, B_WRITE);
210: u.u_count = 0;
211: }
212:
213: tmphys(dev)
214: {
215: register unit, a;
216:
217: unit = dev.d_minor;
218: a = lshift(u.u_offset, -9);
219: t_blkno[unit] = a;
220: t_nxrec[unit] = ++a;
221: }
Defined functions
Defined variables
tmtab
defined in line
23; used 20 times
Defined macros
CRDY
defined in line
42; used 2 times
DENS
defined in line
40; used 2 times
EOF
defined in line
46; used 2 times
GAPSD
defined in line
43; used 1 times
GO
defined in line
32; used 7 times
HARD
defined in line
45; used 1 times
RCOM
defined in line
33; used 1 times
REW
defined in line
39; used 2 times
SFORW
defined in line
36; used 1 times
SIO
defined in line
49; used 4 times
SREV
defined in line
37; used 1 times
SSEEK
defined in line
48; used 1 times
TMADDR
defined in line
30; used 14 times
TUR
defined in line
44;
never used
WCOM
defined in line
34; used 1 times
WEOF
defined in line
35; used 1 times
WIRG
defined in line
38; used 1 times