1: /*
2: * RL disk driver
3: */
4:
5: #define DK_N 2
6: #include "../h/param.h"
7: #include "../h/buf.h"
8: #include "../h/dir.h"
9: #include "../h/user.h"
10: #include "../h/systm.h"
11:
12: #define NRLBLK 10240
13: #define RLCYLSZ 10240
14: #define RLSECSZ 256
15:
16: #define RESET 013
17: #define STAT 03
18: #define GETSTAT 04
19: #define WCOM 012
20: #define RCOM 014
21: #define SEEK 06
22: #define SEEKHI 5
23: #define SEEKLO 1
24: #define RDHDR 010
25: #define IENABLE 0100
26: #define CRDY 0200
27: #define OPI 02000
28: #define CRCERR 04000
29: #define TIMOUT 010000
30: #define NXM 020000
31: #define DE 040000
32:
33: struct device
34: {
35: int rlcs, rlba, rlda, rlmp;
36: };
37:
38: #define RLADDR ((struct device *)0174400)
39: #define RL_CNT 1
40: struct buf rrlbuf;
41: struct buf rltab;
42:
43: struct
44: {
45: int cn[4]; /* location of heads for each drive */
46: int dn; /* drive number */
47: int com; /* read or write command word */
48: int chn; /* cylinder and head number */
49: unsigned int bleft; /* bytes left to be transferred */
50: unsigned int bpart; /* number of bytes transferred */
51: int sn; /* sector number */
52: union {
53: int w[2];
54: long l;
55: } addr; /* address of memory for transfer */
56:
57: } rl = {-1,-1,-1,-1};
58:
59: rlstrategy(bp)
60: register struct buf *bp;
61: {
62: if(bp->b_blkno >= NRLBLK) {
63: if(bp->b_blkno == NRLBLK && bp->b_flags&B_READ)
64: bp->b_resid = bp->b_bcount;
65: else {
66: bp->b_flags |= B_ERROR;
67: bp->b_error = ENXIO;
68: }
69: iodone(bp);
70: return;
71: }
72: bp->av_forw = NULL;
73: spl5();
74: if(rltab.b_actf == NULL)
75: rltab.b_actf = bp;
76: else
77: rltab.b_actl->av_forw = bp;
78: rltab.b_actl = bp;
79: if(rltab.b_active == NULL)
80: rlstart();
81: spl0();
82: }
83:
84: rlstart()
85: {
86:
87: register struct buf *bp;
88:
89: if ((bp = rltab.b_actf) == NULL)
90: return;
91: rltab.b_active++;
92: rl.dn = minor(bp->b_dev);
93: rl.chn = bp->b_blkno/20;
94: rl.sn = (bp->b_blkno%20) << 1;
95: rl.bleft = bp->b_bcount;
96: rl.addr.w[0] = bp->b_xmem & 3;
97: rl.addr.w[1] = (int)bp->b_un.b_addr;
98: rl.com = (rl.dn << 8) | IENABLE;
99: if (bp->b_flags & B_READ)
100: rl.com |= RCOM;
101: else
102: rl.com |= WCOM;
103: rlio();
104: }
105:
106: rlintr()
107: {
108: register struct buf *bp;
109: register struct device *rp;
110: register int status;
111:
112: rp = RLADDR;
113: if (rltab.b_active == NULL) {
114: /*
115: logstray(rp);
116: */
117: return;
118: }
119: bp = rltab.b_actf;
120: dk_busy &= ~(1<<DK_N);
121: if (rp->rlcs < 0) { /* error bit */
122: if (rp->rlcs & 036000) {
123: if(rltab.b_errcnt > 2)
124: deverror(bp, rp->rlcs, rp->rlda);
125: }
126: if (rp->rlcs & 040000) {
127: rp->rlda = STAT;
128: rp->rlcs = (rl.dn << 8) | GETSTAT;
129: while ((rp->rlcs & CRDY) == 0)
130: ;
131: status = rp->rlmp;
132: if(rltab.b_errcnt > 2)
133: deverror(bp, status, rp->rlda);
134: rp->rlda = RESET;
135: rp->rlcs = (rl.dn << 8) | GETSTAT;
136: while ((rp->rlcs & CRDY) == 0)
137: ;
138: if(status & 01000) {
139: rlstart();
140: return;
141: }
142: }
143: if (++rltab.b_errcnt <= 10) {
144: rl.cn[rl.dn] = -1;
145: rlstart();
146: return;
147: }
148: else {
149: bp->b_flags |= B_ERROR;
150: rl.bpart = rl.bleft;
151: }
152: }
153:
154: if ((rl.bleft -= rl.bpart) > 0) {
155: rl.addr.l += rl.bpart;
156: rl.sn=0;
157: rl.chn++;
158: rlio();
159: return;
160: }
161: rltab.b_active = NULL;
162: rltab.b_errcnt = 0;
163: rltab.b_actf = bp->av_forw;
164: bp->b_resid = 0;
165: iodone(bp);
166: rlstart();
167: }
168:
169: rlio()
170: {
171:
172: register struct device *rp;
173: register dif;
174: register int head;
175:
176: rp = RLADDR;
177: dk_busy |= 1<<DK_N;
178: dk_numb[DK_N] += 1;
179: head = rl.bpart>>6;
180: dk_wds[DK_N] += head;
181: if (rl.cn[rl.dn] < 0) {
182: rp->rlcs = (rl.dn << 8) | RDHDR;
183: while ((rp->rlcs&CRDY) == 0)
184: ;
185: rl.cn[rl.dn] = (rp->rlmp&077700) >> 6;
186: }
187: dif =(rl.cn[rl.dn] >> 1) - (rl.chn >>1);
188: head = (rl.chn & 1) << 4;
189: if (dif < 0)
190: rp->rlda = (-dif <<7) | SEEKHI | head;
191: else
192: rp->rlda = (dif << 7) | SEEKLO | head;
193: rp->rlcs = (rl.dn << 8) | SEEK;
194: rl.cn[rl.dn] = rl.chn;
195: if (rl.bleft < (rl.bpart = RLCYLSZ - (rl.sn * RLSECSZ)))
196: rl.bpart = rl.bleft;
197: while ((rp->rlcs&CRDY) == 0)
198: ;
199: rp->rlda = (rl.chn << 6) | rl.sn;
200: rp->rlba = rl.addr.w[1];
201: rp->rlmp = -(rl.bpart >> 1);
202: rp->rlcs = rl.com | rl.addr.w[0] << 4;
203: }
204:
205: rlread(dev)
206: {
207:
208: physio(rlstrategy, &rrlbuf, dev, B_READ);
209: }
210:
211: rlwrite(dev)
212: {
213:
214: physio(rlstrategy, &rrlbuf, dev, B_WRITE);
215: }
Defined functions
rlio
defined in line
169; used 2 times
Defined variables
rltab
defined in line
41; used 15 times
Defined struct's
Defined macros
CRDY
defined in line
26; used 4 times
DE
defined in line
31;
never used
DK_N
defined in line
5; used 4 times
NXM
defined in line
30;
never used
OPI
defined in line
27;
never used
RCOM
defined in line
20; used 1 times
RDHDR
defined in line
24; used 1 times
RESET
defined in line
16; used 1 times
SEEK
defined in line
21; used 1 times
STAT
defined in line
17; used 1 times
WCOM
defined in line
19; used 1 times