Commit | Line | Data |
---|---|---|
66b4fb09 | 1 | /* rk.c 4.2 %G% */ |
d483c58c | 2 | |
66b4fb09 | 3 | #include "rk.h" |
d483c58c BJ |
4 | #if NRK > 0 |
5 | /* | |
6 | * RK disk 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/user.h" | |
15 | #include "../h/pte.h" | |
16 | #include "../h/map.h" | |
17 | #include "../h/uba.h" | |
18 | #include "../h/dk.h" | |
19 | ||
20 | #define NCYL 815 | |
21 | #define NSECT 22 | |
22 | #define NTRK 3 | |
23 | #define NBLK (NTRK*NSECT*NCYL) | |
24 | ||
25 | /* rkcs1 */ | |
26 | #define CCLR 0100000 /* controller clear */ | |
27 | #define DI 040000 /* drive interrupt */ | |
28 | #define CTO 04000 /* controller timeout */ | |
29 | #define CDT 02000 /* drive type (rk07/rk06) */ | |
30 | #define RDY 0200 /* controller ready */ | |
31 | #define IEN 0100 /* interrupt enable */ | |
32 | ||
33 | ||
34 | /* rkcs2 */ | |
35 | #define DLT 0100000 /* data late */ | |
36 | #define WCE 040000 /* write check */ | |
37 | #define UPE 020000 /* unibus parity */ | |
38 | #define NED 010000 /* non-existant drive */ | |
39 | #define NEM 04000 /* non-existant memory */ | |
40 | #define PGE 02000 /* software error */ | |
41 | #define MDS 01000 /* multiple drive select */ | |
42 | #define UFE 0400 /* unit field error */ | |
43 | #define SCLR 040 /* subsystem clear */ | |
44 | #define cs2abort (NED|NEM|PGE|UFE) | |
45 | ||
46 | /* rkds */ | |
47 | #define SVAL 0100000 /* status valid */ | |
48 | #define CDA 040000 /* current drive attention */ | |
49 | #define PIP 020000 /* positioning in progress */ | |
50 | #define WRL 04000 /* write lock */ | |
51 | #define DDT 0400 /* disk drive type */ | |
52 | #define DRDY 0200 /* drive ready */ | |
53 | #define VV 0100 /* volume valid */ | |
54 | #define DROT 040 /* drive off track */ | |
55 | #define SPLS 020 /* speed loss */ | |
56 | #define ACLO 010 /* ac low */ | |
57 | #define OFFSET 04 /* offset mode */ | |
58 | #define DRA 01 /* drive available */ | |
59 | #define dsabort (ACLO|SPLS) | |
60 | ||
61 | ||
62 | /* commands */ | |
63 | #define SELECT 0 | |
64 | #define PACK 2 | |
65 | #define DCLR 4 | |
66 | #define RESET 012 | |
67 | #define WCOM 022 | |
68 | #define RCOM 020 | |
69 | #define GO 01 | |
70 | #define DRESET 012 | |
71 | ||
72 | struct device | |
73 | { | |
74 | short rkcs1; | |
75 | short rkwc; | |
76 | unsigned short rkba; | |
77 | short rkda; | |
78 | short rkcs2; | |
79 | short rkds; | |
80 | short rker; | |
81 | short rkatt; | |
82 | short rkcyl; | |
83 | short rkdb; | |
84 | short rkmr1; | |
85 | short rkecps; | |
86 | short rkecpt; | |
87 | short rkmr2; | |
88 | short rkmr3; | |
89 | } ; | |
90 | ||
91 | struct buf rktab; | |
92 | struct buf rrkbuf; | |
93 | ||
94 | struct devsize { | |
95 | unsigned int nblocks; | |
96 | int cyloff; | |
97 | } rk_sizes [] ={ | |
98 | 9614, 0, /* 0 - 145 */ | |
99 | 6600, 146, /* 146 - 245 */ | |
100 | 37554, 246, /* 246 - 815 */ | |
101 | 0, 0, | |
102 | 0, 0, | |
103 | 0, 0, | |
104 | 0, 0, | |
105 | 0, 0, | |
106 | }; | |
107 | ||
108 | rkstrategy(bp) | |
109 | register struct buf *bp; | |
110 | { | |
111 | register dn, sz; | |
112 | ||
113 | dn = minor(bp->b_dev); | |
114 | sz = (bp->b_bcount>>9); | |
115 | if (dn > (NRK<<3) || sz+bp->b_blkno >= rk_sizes[dn&07].nblocks) { | |
116 | bp->b_flags |= B_ERROR; | |
117 | iodone(bp); | |
118 | return; | |
119 | } | |
120 | bp->av_forw = (struct buf *)NULL; | |
121 | spl5(); | |
122 | if(rktab.b_actf == NULL) | |
123 | rktab.b_actf = bp; | |
124 | else | |
125 | rktab.b_actl->av_forw = bp; | |
126 | rktab.b_actl = bp; | |
127 | if(rktab.b_active == NULL) | |
128 | rkstart(); | |
129 | spl0(); | |
130 | } | |
131 | ||
132 | int rk_info; | |
133 | int tcn, ttn, tsn; | |
134 | ||
135 | rkstart() | |
136 | { | |
137 | register struct buf *bp; | |
138 | register com; | |
139 | register struct device *rkaddr = RKADDR; | |
140 | daddr_t bn; | |
141 | int dn, cn, sn, tn; | |
142 | ||
143 | if ((bp = rktab.b_actf) == NULL) | |
144 | return; | |
145 | rktab.b_active++; | |
146 | rk_info = ubasetup(bp, 1); | |
147 | bn = bp->b_blkno; | |
148 | dn = minor(bp->b_dev); | |
149 | cn = bn/(NTRK*NSECT); | |
150 | cn += rk_sizes[dn&07].cyloff; | |
151 | dn >>= 3; | |
152 | if (dn != (rkaddr->rkcs2&07)) { | |
153 | rkaddr->rkcs2 = dn; | |
154 | rkaddr->rkcs1 = CDT | GO; | |
155 | while ((rkaddr->rkcs1&RDY)==0) | |
156 | ; | |
157 | } | |
158 | if ((rkaddr->rkds & VV) == 0) { | |
159 | rkaddr->rkcs1 = PACK | CDT | GO; | |
160 | while ((rkaddr->rkcs1&RDY)==0) | |
161 | ; | |
162 | } | |
163 | tn = bn%(NTRK*NSECT); | |
164 | tn = tn/NSECT; | |
165 | sn = bn%NSECT; | |
166 | rkaddr->rkcs2 = dn; | |
167 | rkaddr->rkcyl = cn; | |
168 | rkaddr->rkda = (tn << 8) | sn; | |
169 | ttn = tn; tcn = cn; tsn = sn; | |
170 | rkaddr->rkba = rk_info; | |
171 | rkaddr->rkwc = -(bp->b_bcount>>1); | |
172 | com = ((rk_info &0x30000) >> 8) | CDT | IEN | GO; | |
173 | if(bp->b_flags & B_READ) | |
174 | com |= RCOM; else | |
175 | com |= WCOM; | |
176 | rkaddr->rkcs1 = com; | |
177 | dk_busy |= 1<<DK_N; | |
178 | dk_xfer[DK_N] += 1; | |
179 | com = bp->b_bcount>>6; | |
180 | dk_wds[DK_N] += com; | |
181 | } | |
182 | ||
183 | rkintr() | |
184 | { | |
185 | register struct buf *bp; | |
186 | register d, x; | |
187 | register struct device *rkaddr = RKADDR; | |
188 | int ds, er; | |
189 | ||
190 | if (rktab.b_active == NULL) | |
191 | return; | |
192 | dk_busy &= ~(1<<DK_N); | |
193 | bp = rktab.b_actf; | |
194 | rktab.b_active = NULL; | |
195 | if (rkaddr->rkcs1 < 0) { /* error bit */ | |
196 | d = (minor(bp->b_dev)>>3); | |
197 | x = 1; | |
198 | if (rkaddr->rkcs1&DI) { | |
199 | printf("DI"); | |
200 | } | |
201 | if (rkaddr->rkds&CDA) | |
202 | printf("CDA "); | |
203 | if ((rkaddr->rkds&CDA) || (rkaddr->rkcs1&DI)) { | |
204 | er = (unsigned short)rkaddr->rker; | |
205 | ds = (unsigned short)rkaddr->rkds; | |
206 | rkaddr->rkcs1 = CDT | DCLR | GO; | |
207 | printf("DCLR"); | |
208 | } else { | |
209 | if ((rkaddr->rkds&SVAL)==0) { | |
210 | printf("no SVAL\n"); | |
211 | x = rkselect(rkaddr, d); | |
212 | printf("x = %d\n", x); | |
213 | } | |
214 | er = (unsigned short)rkaddr->rker; | |
215 | ds = (unsigned short)rkaddr->rkds; | |
216 | } | |
217 | if (rkaddr->rkds&dsabort) { | |
218 | printf("rk %d is down\n", d); | |
219 | rktab.b_errcnt = 10; | |
220 | } | |
221 | if (rkaddr->rkcs2&cs2abort) { | |
222 | printf("cs2 abort %o\n", rkaddr->rkcs2); | |
223 | rktab.b_errcnt = 10; | |
224 | } | |
225 | if (rktab.b_errcnt >= 10) { | |
226 | deverror(bp, er, ds); | |
227 | printf("cn %d tn %d sn %d\n", tcn, ttn, tsn); | |
228 | } | |
229 | rkaddr->rkcs1 = CDT | DCLR | GO; | |
230 | while ((rkaddr->rkcs1&RDY)==0) | |
231 | ; | |
232 | rkaddr->rkcs2 = SCLR; | |
233 | while ((rkaddr->rkcs1&RDY)==0) | |
234 | ; | |
235 | if ((x=rkselect(rkaddr, d)) == 0) { | |
236 | printf("after clears\n"); | |
237 | goto bad; | |
238 | } | |
239 | printf("reset\n"); | |
240 | rkaddr->rkcs1 = CDT | RESET | GO; | |
241 | while (rkaddr->rkds & PIP) | |
242 | ; | |
243 | if (++rktab.b_errcnt <= 10) { | |
244 | ubafree(rk_info); | |
245 | rkstart(); | |
246 | return; | |
247 | } | |
248 | bad: | |
249 | bp->b_flags |= B_ERROR; | |
250 | } | |
251 | rktab.b_errcnt = 0; | |
252 | rktab.b_actf = bp->av_forw; | |
253 | bp->b_resid = 0; | |
254 | ubafree(rk_info); | |
255 | iodone(bp); | |
256 | rkstart(); | |
257 | } | |
258 | ||
259 | ||
260 | rkselect(rkaddr, d) | |
261 | register struct device *rkaddr; | |
262 | { | |
263 | rkaddr->rkcs2 = d; | |
264 | rkaddr->rkcs1 = CDT|GO; | |
265 | return(rkwait(rkaddr)); | |
266 | } | |
267 | ||
268 | rkwait(rkaddr) | |
269 | register struct device *rkaddr; | |
270 | { | |
271 | register t; | |
272 | ||
273 | for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--) | |
274 | ; | |
275 | if (t==0) | |
276 | printf("rk not ready\n"); | |
277 | return(t); | |
278 | } | |
279 | ||
280 | rkread(dev) | |
281 | dev_t dev; | |
282 | { | |
283 | ||
284 | physio(rkstrategy, &rrkbuf, dev, B_READ, minphys); | |
285 | } | |
286 | ||
287 | rkwrite(dev) | |
288 | dev_t dev; | |
289 | { | |
290 | ||
291 | physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys); | |
292 | } | |
293 | #endif |