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