Commit | Line | Data |
---|---|---|
736772ef | 1 | /* rk.c 4.11 %G% */ |
d483c58c | 2 | |
66b4fb09 | 3 | #include "rk.h" |
872b4e09 | 4 | #if NHK > 0 |
9037157b | 5 | int rkflags,rkerrs; /* GROT */ |
d483c58c | 6 | /* |
0801d37f | 7 | * RK11/RK07 disk driver |
9037157b BJ |
8 | * |
9 | * This driver mimics up.c; see it for an explanation of common code. | |
d483c58c | 10 | */ |
0801d37f | 11 | #define DELAY(i) { register int j; j = i; while (--j > 0); } |
d483c58c BJ |
12 | #include "../h/param.h" |
13 | #include "../h/systm.h" | |
14 | #include "../h/buf.h" | |
15 | #include "../h/conf.h" | |
16 | #include "../h/dir.h" | |
17 | #include "../h/user.h" | |
18 | #include "../h/pte.h" | |
19 | #include "../h/map.h" | |
0801d37f | 20 | #include "../h/vm.h" |
d483c58c BJ |
21 | #include "../h/uba.h" |
22 | #include "../h/dk.h" | |
0801d37f BJ |
23 | #include "../h/cpu.h" |
24 | #include "../h/cmap.h" | |
25 | ||
26 | #include "../h/rkreg.h" | |
d483c58c | 27 | |
0801d37f BJ |
28 | struct rk_softc { |
29 | int sc_softas; | |
30 | int sc_ndrive; | |
31 | int sc_wticks; | |
32 | int sc_recal; | |
872b4e09 | 33 | } rk_softc[NHK]; |
0801d37f BJ |
34 | |
35 | /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ | |
36 | struct size | |
d483c58c | 37 | { |
0801d37f | 38 | daddr_t nblocks; |
d483c58c | 39 | int cyloff; |
0801d37f BJ |
40 | } rk7_sizes[] ={ |
41 | 15884, 0, /* A=cyl 0 thru 240 */ | |
22717fbb BJ |
42 | 10032, 241, /* B=cyl 241 thru 392 */ |
43 | 53790, 0, /* C=cyl 0 thru 814 */ | |
d483c58c BJ |
44 | 0, 0, |
45 | 0, 0, | |
46 | 0, 0, | |
0801d37f | 47 | 27786, 393, /* G=cyl 393 thru 813 */ |
d483c58c | 48 | 0, 0, |
d483c58c | 49 | }; |
0801d37f BJ |
50 | /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ |
51 | ||
52 | int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); | |
872b4e09 BJ |
53 | struct uba_minfo *rkminfo[NHK]; |
54 | struct uba_dinfo *rkdinfo[NRK]; | |
55 | struct uba_dinfo *rkip[NHK][4]; | |
0801d37f BJ |
56 | |
57 | u_short rkstd[] = { 0777440, 0 }; | |
58 | struct uba_driver hkdriver = | |
9037157b | 59 | { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; |
872b4e09 BJ |
60 | struct buf rkutab[NRK]; |
61 | short rkcyl[NRK]; | |
0801d37f BJ |
62 | |
63 | struct rkst { | |
64 | short nsect; | |
65 | short ntrak; | |
66 | short nspc; | |
67 | short ncyl; | |
68 | struct size *sizes; | |
69 | } rkst[] = { | |
70 | NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, | |
71 | }; | |
72 | ||
73 | u_char rk_offset[16] = | |
74 | { P400,M400,P400,M400,P800,M800,P800,M800,P1200,M1200,P1200,M1200,0,0,0,0 }; | |
75 | ||
872b4e09 | 76 | struct buf rrkbuf[NRK]; |
0801d37f BJ |
77 | |
78 | #define b_cylin b_resid | |
79 | ||
80 | #ifdef INTRLVE | |
81 | daddr_t dkblock(); | |
82 | #endif | |
83 | ||
84 | int rkwstart, rkwatch(); | |
85 | ||
86 | rkprobe(reg) | |
87 | caddr_t reg; | |
88 | { | |
89 | register int br, cvec; | |
90 | ||
91 | #ifdef lint | |
92 | br = 0; cvec = br; br = cvec; | |
93 | #endif | |
94 | ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; | |
95 | DELAY(10); | |
96 | ((struct rkdevice *)reg)->rkcs1 = RK_CDT; | |
97 | return (1); | |
98 | } | |
99 | ||
100 | rkslave(ui, reg) | |
101 | struct uba_dinfo *ui; | |
102 | caddr_t reg; | |
103 | { | |
104 | register struct rkdevice *rkaddr = (struct rkdevice *)reg; | |
105 | ||
106 | rkaddr->rkcs1 = RK_CDT; | |
107 | rkaddr->rkcs2 = ui->ui_slave; | |
9037157b BJ |
108 | rkwait(rkaddr); |
109 | /* SHOULD TRY THIS BY PULLING A PLUG */ | |
110 | /* A DELAY OR SOMETHING MAY BE NEEDED */ | |
0801d37f BJ |
111 | if (rkaddr->rkcs2&RK_NED) { |
112 | rkaddr->rkcs1 = RK_CDT|RK_CCLR; | |
113 | return (0); | |
114 | } | |
115 | return (1); | |
116 | } | |
d483c58c | 117 | |
0801d37f BJ |
118 | rkattach(ui) |
119 | register struct uba_dinfo *ui; | |
120 | { | |
121 | ||
122 | if (rkwstart == 0) { | |
123 | timeout(rkwatch, (caddr_t)0, HZ); | |
124 | rkwstart++; | |
125 | } | |
126 | if (ui->ui_dk >= 0) | |
127 | dk_mspw[ui->ui_dk] = 1.0 / (HZ * NRKSECT * 256); | |
128 | rkip[ui->ui_ctlr][ui->ui_slave] = ui; | |
129 | rk_softc[ui->ui_ctlr].sc_ndrive++; | |
130 | rkcyl[ui->ui_unit] = -1; | |
131 | } | |
132 | ||
d483c58c | 133 | rkstrategy(bp) |
0801d37f | 134 | register struct buf *bp; |
d483c58c | 135 | { |
0801d37f BJ |
136 | register struct uba_dinfo *ui; |
137 | register struct rkst *st; | |
138 | register int unit; | |
139 | register struct buf *dp; | |
140 | int xunit = minor(bp->b_dev) & 07; | |
141 | long bn, sz; | |
142 | ||
143 | sz = (bp->b_bcount+511) >> 9; | |
144 | unit = dkunit(bp); | |
872b4e09 | 145 | if (unit >= NRK) |
0801d37f BJ |
146 | goto bad; |
147 | ui = rkdinfo[unit]; | |
148 | if (ui == 0 || ui->ui_alive == 0) | |
149 | goto bad; | |
150 | st = &rkst[ui->ui_type]; | |
151 | if (bp->b_blkno < 0 || | |
152 | (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) | |
153 | goto bad; | |
154 | bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; | |
155 | (void) spl5(); | |
156 | dp = &rkutab[ui->ui_unit]; | |
157 | disksort(dp, bp); | |
158 | if (dp->b_active == 0) { | |
159 | (void) rkustart(ui); | |
160 | bp = &ui->ui_mi->um_tab; | |
161 | if (bp->b_actf && bp->b_active == 0) | |
162 | (void) rkstart(ui->ui_mi); | |
d483c58c | 163 | } |
0801d37f BJ |
164 | (void) spl0(); |
165 | return; | |
166 | ||
167 | bad: | |
168 | bp->b_flags |= B_ERROR; | |
169 | iodone(bp); | |
170 | return; | |
d483c58c BJ |
171 | } |
172 | ||
0801d37f BJ |
173 | rkustart(ui) |
174 | register struct uba_dinfo *ui; | |
175 | { | |
176 | register struct buf *bp, *dp; | |
177 | register struct uba_minfo *um; | |
178 | register struct rkdevice *rkaddr; | |
179 | register struct rkst *st; | |
180 | daddr_t bn; | |
181 | int sn, csn; | |
182 | int didie = 0; | |
183 | ||
184 | if (ui == 0) | |
185 | return (0); | |
186 | dk_busy &= ~(1<<ui->ui_dk); | |
187 | dp = &rkutab[ui->ui_unit]; | |
188 | if ((bp = dp->b_actf) == NULL) | |
189 | goto out; | |
190 | um = ui->ui_mi; | |
191 | if (um->um_tab.b_active) { | |
192 | rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; | |
193 | return (0); | |
194 | } | |
195 | rkaddr = (struct rkdevice *)um->um_addr; | |
196 | rkaddr->rkcs1 = RK_CDT|RK_CERR; | |
197 | rkaddr->rkcs2 = ui->ui_slave; | |
198 | rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; | |
199 | rkwait(rkaddr); | |
200 | if (dp->b_active) | |
201 | goto done; | |
202 | dp->b_active = 1; | |
203 | if ((rkaddr->rkds & RK_VV) == 0) { | |
204 | /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ | |
205 | rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; | |
206 | rkwait(rkaddr); | |
207 | didie = 1; | |
208 | } | |
209 | if (rk_softc[um->um_ctlr].sc_ndrive == 1) | |
210 | goto done; | |
211 | if (bp->b_cylin == rkcyl[ui->ui_unit]) | |
212 | goto done; | |
213 | rkaddr->rkcyl = bp->b_cylin; | |
214 | rkcyl[ui->ui_unit] = bp->b_cylin; | |
215 | rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO; | |
216 | didie = 1; | |
217 | if (ui->ui_dk >= 0) { | |
218 | dk_busy |= 1<<ui->ui_dk; | |
219 | dk_seek[ui->ui_dk]++; | |
220 | } | |
221 | goto out; | |
222 | done: | |
223 | if (dp->b_active != 2) { | |
224 | dp->b_forw = NULL; | |
225 | if (um->um_tab.b_actf == NULL) | |
226 | um->um_tab.b_actf = dp; | |
227 | else | |
228 | um->um_tab.b_actl->b_forw = dp; | |
229 | um->um_tab.b_actl = dp; | |
230 | dp->b_active = 2; | |
231 | } | |
232 | out: | |
233 | return (didie); | |
234 | } | |
d483c58c | 235 | |
0801d37f BJ |
236 | rkstart(um) |
237 | register struct uba_minfo *um; | |
d483c58c | 238 | { |
0801d37f BJ |
239 | register struct buf *bp, *dp; |
240 | register struct uba_dinfo *ui; | |
241 | register struct rkdevice *rkaddr; | |
242 | struct rkst *st; | |
d483c58c | 243 | daddr_t bn; |
0801d37f BJ |
244 | int sn, tn, cmd; |
245 | ||
246 | loop: | |
247 | if ((dp = um->um_tab.b_actf) == NULL) | |
248 | return (0); | |
249 | if ((bp = dp->b_actf) == NULL) { | |
250 | um->um_tab.b_actf = dp->b_forw; | |
251 | goto loop; | |
d483c58c | 252 | } |
0801d37f BJ |
253 | um->um_tab.b_active++; |
254 | ui = rkdinfo[dkunit(bp)]; | |
255 | bn = dkblock(bp); | |
256 | st = &rkst[ui->ui_type]; | |
257 | sn = bn%st->nspc; | |
258 | tn = sn/st->nsect; | |
259 | sn %= st->nsect; | |
260 | rkaddr = (struct rkdevice *)ui->ui_addr; | |
261 | rkaddr->rkcs1 = RK_CDT|RK_CERR; | |
262 | rkaddr->rkcs2 = ui->ui_slave; | |
263 | rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; | |
264 | rkwait(rkaddr); | |
265 | if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) { | |
266 | rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; | |
267 | rkaddr->rkcs1 = RK_CDT|RK_OFFSET|RK_GO; | |
268 | rkwait(rkaddr); | |
d483c58c | 269 | } |
0801d37f BJ |
270 | rkaddr->rkcyl = bp->b_cylin; |
271 | rkcyl[ui->ui_unit] = bp->b_cylin; | |
272 | rkaddr->rkda = (tn << 8) + sn; | |
273 | rkaddr->rkwc = -bp->b_bcount / sizeof (short); | |
274 | if (bp->b_flags & B_READ) | |
275 | cmd = RK_CDT|RK_IE|RK_READ|RK_GO; | |
276 | else | |
277 | cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO; | |
278 | um->um_cmd = cmd; | |
279 | ubago(ui); | |
280 | return (1); | |
d483c58c BJ |
281 | } |
282 | ||
0801d37f BJ |
283 | rkdgo(um) |
284 | register struct uba_minfo *um; | |
d483c58c | 285 | { |
0801d37f BJ |
286 | register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; |
287 | ||
288 | rkaddr->rkba = um->um_ubinfo; | |
289 | rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); | |
290 | } | |
291 | ||
292 | hkintr(rk11) | |
293 | int rk11; | |
294 | { | |
295 | register struct uba_minfo *um = rkminfo[rk11]; | |
296 | register struct uba_dinfo *ui; | |
297 | register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; | |
298 | register struct buf *bp, *dp; | |
299 | int unit; | |
300 | struct rk_softc *sc = &rk_softc[um->um_ctlr]; | |
301 | int as = (rkaddr->rkatt >> 8) | sc->sc_softas; | |
302 | int needie = 1; | |
303 | ||
304 | sc->sc_wticks = 0; | |
305 | sc->sc_softas = 0; | |
306 | if (um->um_tab.b_active) { | |
307 | dp = um->um_tab.b_actf; | |
308 | bp = dp->b_actf; | |
309 | ui = rkdinfo[dkunit(bp)]; | |
310 | dk_busy &= ~(1 << ui->ui_dk); | |
311 | if (rkaddr->rkcs1 & RK_CERR) { | |
312 | int recal; | |
313 | u_short ds = rkaddr->rkds; | |
314 | u_short cs2 = rkaddr->rkcs2; | |
315 | u_short er = rkaddr->rker; | |
316 | if (sc->sc_recal) | |
317 | printf("recal CERR\n"); | |
9037157b BJ |
318 | rkerrs++; /* GROT */ |
319 | if (rkflags&1) /* GROT */ | |
320 | printf("%d ds %o cs2 %o er %o\n", /* GROT */ | |
321 | um->um_tab.b_errcnt, ds, cs2, er); /* GROT */ | |
0801d37f BJ |
322 | if (er & RK_WLE) |
323 | printf("rk%d is write locked\n", dkunit(bp)); | |
9037157b BJ |
324 | /* THIS DOESN'T SEEM TO HAPPEN */ |
325 | /* OR WAS SOMETHING BROKEN WHEN WE TRIED */ | |
326 | /* SPINNING A DRIVE DOWN ? */ | |
0801d37f BJ |
327 | if (ds & RKDS_HARD) |
328 | printf("rk%d is down\n", dkunit(bp)); | |
329 | if (++um->um_tab.b_errcnt > 28 || | |
736772ef | 330 | ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { |
0801d37f | 331 | bp->b_flags |= B_ERROR; |
736772ef BJ |
332 | harderr(bp); |
333 | printf("rk%d cs2 %b ds %b er %b\n", | |
334 | dkunit(bp), cs2, RKCS2_BITS, ds, | |
335 | RKDS_BITS, er, RKER_BITS); | |
336 | } else | |
0801d37f | 337 | um->um_tab.b_active = 0; |
0801d37f BJ |
338 | if (cs2&RK_MDS) { |
339 | rkaddr->rkcs2 = RK_SCLR; | |
340 | goto retry; | |
341 | } | |
342 | recal = 0; | |
343 | if (ds&RK_DROT || er&(RK_OPI|RK_SKI|RK_UNS) || | |
344 | (um->um_tab.b_errcnt&07) == 4) | |
345 | recal = 1; | |
346 | if ((er & (RK_DCK|RK_ECH)) == RK_DCK) | |
347 | if (rkecc(ui)) | |
348 | return; | |
349 | rkaddr->rkcs1 = RK_CDT|RK_CCLR; | |
350 | rkaddr->rkcs2 = ui->ui_slave; | |
351 | rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; | |
352 | rkwait(rkaddr); | |
353 | if (recal && um->um_tab.b_active == 0) { | |
354 | rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO; | |
355 | rkcyl[ui->ui_unit] = -1; | |
356 | rkwait(rkaddr); | |
357 | um->um_tab.b_active = 1; | |
358 | sc->sc_recal = 1; | |
359 | return; | |
d483c58c | 360 | } |
d483c58c | 361 | } |
0801d37f BJ |
362 | retry: |
363 | if (sc->sc_recal) { | |
364 | sc->sc_recal = 0; | |
365 | um->um_tab.b_active = 0; | |
d483c58c | 366 | } |
0801d37f BJ |
367 | ubadone(um); |
368 | if (um->um_tab.b_active) { | |
369 | um->um_tab.b_active = 0; | |
370 | um->um_tab.b_errcnt = 0; | |
371 | um->um_tab.b_actf = dp->b_forw; | |
372 | dp->b_active = 0; | |
373 | dp->b_errcnt = 0; | |
374 | dp->b_actf = bp->av_forw; | |
375 | bp->b_resid = -rkaddr->rkwc * sizeof(short); | |
376 | iodone(bp); | |
377 | if (dp->b_actf) | |
378 | if (rkustart(ui)) | |
379 | needie = 0; | |
d483c58c | 380 | } |
0801d37f | 381 | as &= ~(1<<ui->ui_slave); |
d483c58c | 382 | } |
0801d37f BJ |
383 | for (unit = 0; as; as >>= 1, unit++) |
384 | if (as & 1) | |
385 | if (rkustart(rkip[rk11][unit])) | |
386 | needie = 0; | |
387 | if (um->um_tab.b_actf && um->um_tab.b_active == 0) | |
388 | if (rkstart(um)) | |
389 | needie = 0; | |
390 | if (needie) | |
391 | rkaddr->rkcs1 = RK_CDT|RK_IE; | |
d483c58c BJ |
392 | } |
393 | ||
0801d37f BJ |
394 | rkwait(addr) |
395 | register struct rkdevice *addr; | |
396 | { | |
397 | ||
398 | while ((addr->rkcs1 & RK_CRDY) == 0) | |
399 | ; | |
400 | } | |
d483c58c | 401 | |
0801d37f BJ |
402 | rkread(dev) |
403 | dev_t dev; | |
d483c58c | 404 | { |
0801d37f BJ |
405 | register int unit = minor(dev) >> 3; |
406 | ||
872b4e09 | 407 | if (unit >= NRK) |
0801d37f BJ |
408 | u.u_error = ENXIO; |
409 | else | |
410 | physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); | |
d483c58c BJ |
411 | } |
412 | ||
0801d37f BJ |
413 | rkwrite(dev) |
414 | dev_t dev; | |
d483c58c | 415 | { |
0801d37f | 416 | register int unit = minor(dev) >> 3; |
d483c58c | 417 | |
872b4e09 | 418 | if (unit >= NRK) |
0801d37f BJ |
419 | u.u_error = ENXIO; |
420 | else | |
421 | physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); | |
d483c58c BJ |
422 | } |
423 | ||
0801d37f BJ |
424 | rkecc(ui) |
425 | register struct uba_dinfo *ui; | |
d483c58c | 426 | { |
0801d37f BJ |
427 | register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; |
428 | register struct buf *bp = rkutab[ui->ui_unit].b_actf; | |
429 | register struct uba_minfo *um = ui->ui_mi; | |
430 | register struct rkst *st; | |
431 | struct uba_regs *ubp = ui->ui_hd->uh_uba; | |
432 | register int i; | |
433 | caddr_t addr; | |
434 | int reg, bit, byte, npf, mask, o, cmd, ubaddr; | |
435 | int bn, cn, tn, sn; | |
d483c58c | 436 | |
0801d37f BJ |
437 | npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1; |
438 | reg = btop(um->um_ubinfo&0x3ffff) + npf; | |
439 | o = (int)bp->b_un.b_addr & PGOFSET; | |
440 | printf("%D ", bp->b_blkno+npf); | |
441 | prdev("ECC", bp->b_dev); | |
442 | mask = rk->rkec2; | |
443 | if (mask == 0) { | |
444 | rk->rkatt = 0; | |
445 | return (0); | |
446 | } | |
447 | ubp->uba_dpr[(um->um_ubinfo>>28)&0x0f] |= UBA_BNE; | |
448 | i = rk->rkec1 - 1; /* -1 makes 0 origin */ | |
22717fbb | 449 | printf("mask %x pos %x\n", mask, i+1); |
0801d37f BJ |
450 | bit = i&07; |
451 | i = (i&~07)>>3; | |
452 | byte = i + o; | |
453 | while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { | |
454 | addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ | |
455 | (byte & PGOFSET); | |
456 | putmemc(addr, getmemc(addr)^(mask<<bit)); | |
457 | byte++; | |
458 | i++; | |
459 | bit -= 8; | |
460 | } | |
461 | um->um_tab.b_active++; /* Either complete or continuing... */ | |
462 | if (rk->rkwc == 0) | |
463 | return (0); | |
9037157b BJ |
464 | #ifdef notdef |
465 | rk->rkcs1 |= RK_GO; | |
466 | #else | |
0801d37f BJ |
467 | rk->rkcs1 = RK_CDT|RK_CCLR; |
468 | rk->rkcs2 = ui->ui_slave; | |
469 | rk->rkcs1 = RK_CDT|RK_DCLR|RK_GO; | |
470 | rkwait(rk); | |
471 | bn = dkblock(bp); | |
472 | st = &rkst[ui->ui_type]; | |
473 | cn = bp->b_cylin; | |
474 | sn = bn%st->nspc + npf + 1; | |
475 | tn = sn/st->nsect; | |
476 | sn %= st->nsect; | |
477 | cn += tn/st->ntrak; | |
478 | tn %= st->ntrak; | |
479 | rk->rkcyl = cn; | |
480 | rk->rkda = (tn << 8) | sn; | |
481 | ubaddr = (int)ptob(reg+1) + o; | |
482 | rk->rkba = ubaddr; | |
483 | cmd = (ubaddr >> 8) & 0x300; | |
484 | cmd |= RK_CDT|RK_IE|RK_GO|RK_READ; | |
485 | rk->rkcs1 = cmd; | |
9037157b | 486 | #endif |
0801d37f | 487 | return (1); |
d483c58c BJ |
488 | } |
489 | ||
0801d37f BJ |
490 | rkreset(uban) |
491 | { | |
492 | register struct uba_minfo *um; | |
493 | register struct uba_dinfo *ui; | |
494 | register rk11, unit; | |
495 | int any = 0; | |
496 | ||
872b4e09 | 497 | for (rk11 = 0; rk11 < NHK; rk11++) { |
0801d37f BJ |
498 | if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || |
499 | um->um_alive == 0) | |
500 | continue; | |
501 | if (any == 0) { | |
502 | printf(" rk"); | |
503 | any++; | |
504 | } | |
505 | um->um_tab.b_active = 0; | |
506 | um->um_tab.b_actf = um->um_tab.b_actl = 0; | |
507 | rk_softc[um->um_ctlr].sc_recal = 0; | |
508 | if (um->um_ubinfo) { | |
509 | printf("<%d>", (um->um_ubinfo>>28)&0xf); | |
510 | ubadone(um); | |
511 | } | |
872b4e09 | 512 | for (unit = 0; unit < NHK; unit++) { |
0801d37f BJ |
513 | if ((ui = rkdinfo[unit]) == 0) |
514 | continue; | |
515 | if (ui->ui_alive == 0) | |
516 | continue; | |
517 | rkutab[unit].b_active = 0; | |
518 | (void) rkustart(ui); | |
519 | } | |
520 | (void) rkstart(um); | |
521 | } | |
522 | } | |
523 | ||
0801d37f | 524 | rkwatch() |
d483c58c | 525 | { |
0801d37f BJ |
526 | register struct uba_minfo *um; |
527 | register rk11, unit; | |
528 | register struct rk_softc *sc; | |
d483c58c | 529 | |
0801d37f | 530 | timeout(rkwatch, (caddr_t)0, HZ); |
872b4e09 | 531 | for (rk11 = 0; rk11 < NHK; rk11++) { |
0801d37f BJ |
532 | um = rkminfo[rk11]; |
533 | if (um == 0 || um->um_alive == 0) | |
534 | continue; | |
535 | sc = &rk_softc[rk11]; | |
536 | if (um->um_tab.b_active == 0) { | |
872b4e09 | 537 | for (unit = 0; unit < NRK; unit++) |
9037157b BJ |
538 | if (rkutab[unit].b_active && |
539 | rkdinfo[unit]->ui_mi == um) | |
0801d37f BJ |
540 | goto active; |
541 | sc->sc_wticks = 0; | |
542 | continue; | |
543 | } | |
544 | active: | |
545 | sc->sc_wticks++; | |
546 | if (sc->sc_wticks >= 20) { | |
547 | sc->sc_wticks = 0; | |
872b4e09 BJ |
548 | printf("LOST rkintr "); |
549 | ubareset(um->um_ubanum); | |
0801d37f BJ |
550 | } |
551 | } | |
d483c58c | 552 | } |
0ff318b2 | 553 | |
0801d37f BJ |
554 | #define DBSIZE 20 |
555 | ||
556 | rkdump(dev) | |
557 | dev_t dev; | |
0ff318b2 | 558 | { |
0801d37f BJ |
559 | struct rkdevice *rkaddr; |
560 | char *start; | |
561 | int num, blk, unit; | |
562 | struct size *sizes; | |
563 | register struct uba_regs *uba; | |
564 | register struct uba_dinfo *ui; | |
565 | register short *rp; | |
566 | struct rkst *st; | |
567 | ||
568 | unit = minor(dev) >> 3; | |
872b4e09 | 569 | if (unit >= NRK) { |
0801d37f BJ |
570 | printf("bad unit\n"); |
571 | return (-1); | |
572 | } | |
573 | #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) | |
574 | ui = phys(struct uba_dinfo *, rkdinfo[unit]); | |
575 | if (ui->ui_alive == 0) { | |
576 | printf("dna\n"); | |
577 | return(-1); | |
578 | } | |
579 | uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; | |
580 | #if VAX780 | |
581 | if (cpu == VAX_780) | |
582 | ubainit(uba); | |
583 | #endif | |
584 | rkaddr = (struct rkdevice *)ui->ui_physaddr; | |
585 | num = maxfree; | |
586 | start = 0; | |
587 | rkaddr->rkcs1 = RK_CDT|RK_CERR; | |
588 | rkaddr->rkcs2 = unit; | |
589 | rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; | |
590 | rkwait(rkaddr); | |
591 | if ((rkaddr->rkds & RK_VV) == 0) { | |
592 | rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; | |
593 | rkwait(rkaddr); | |
594 | } | |
595 | st = &rkst[ui->ui_type]; | |
596 | sizes = phys(struct size *, st->sizes); | |
597 | if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) { | |
598 | printf("oor\n"); | |
599 | return (-1); | |
600 | } | |
601 | while (num > 0) { | |
602 | register struct pte *io; | |
603 | register int i; | |
604 | int cn, sn, tn; | |
605 | daddr_t bn; | |
0ff318b2 | 606 | |
0801d37f BJ |
607 | blk = num > DBSIZE ? DBSIZE : num; |
608 | io = uba->uba_map; | |
609 | for (i = 0; i < blk; i++) | |
610 | *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV; | |
611 | *(int *)io = 0; | |
612 | bn = dumplo + btop(start); | |
613 | cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; | |
614 | sn = bn%st->nspc; | |
615 | tn = sn/st->nsect; | |
616 | sn = sn%st->nsect; | |
617 | rkaddr->rkcyl = cn; | |
618 | rp = (short *) &rkaddr->rkda; | |
619 | *rp = (tn << 8) + sn; | |
620 | *--rp = 0; | |
621 | *--rp = -blk*NBPG / sizeof (short); | |
622 | *--rp = RK_CDT|RK_GO|RK_WRITE; | |
623 | rkwait(rkaddr); | |
624 | if (rkaddr->rkcs1 & RK_CERR) { | |
625 | printf("rk dump dsk err: (%d,%d,%d) cs1=%x, ds=%x, er1=%x\n", | |
626 | cn, tn, sn, | |
627 | rkaddr->rkcs1&0xffff, rkaddr->rkds&0xffff, | |
628 | rkaddr->rker&0xffff); | |
629 | return (-1); | |
630 | } | |
631 | start += blk*NBPG; | |
632 | num -= blk; | |
633 | } | |
634 | return (0); | |
0ff318b2 | 635 | } |
d483c58c | 636 | #endif |