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