typo
[unix-history] / usr / src / sys / vax / uba / rk.c
CommitLineData
299d67ed 1/* rk.c 4.33 81/04/02 */
d483c58c 2
66b4fb09 3#include "rk.h"
872b4e09 4#if NHK > 0
a0eab615
BJ
5int rkpip; /* DEBUG */
6int rknosval; /* DEBUG */
535f6684 7int rkdebug;
d483c58c 8/*
535f6684 9 * RK611/RK0[67] disk driver
9037157b
BJ
10 *
11 * This driver mimics up.c; see it for an explanation of common code.
ed687006 12 *
c9e9b65b 13 * TODO:
777e0613 14 * Learn why we lose an interrupt sometime when spinning drives down
535f6684 15 * Support rk06
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] =
535f6684
BJ
79 { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800,
80 RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0
81 };
0801d37f 82
872b4e09 83struct buf rrkbuf[NRK];
0801d37f
BJ
84
85#define b_cylin b_resid
86
87#ifdef INTRLVE
88daddr_t dkblock();
89#endif
90
91int rkwstart, rkwatch();
92
93rkprobe(reg)
94 caddr_t reg;
95{
96 register int br, cvec;
97
98#ifdef lint
99 br = 0; cvec = br; br = cvec;
100#endif
101 ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY;
102 DELAY(10);
103 ((struct rkdevice *)reg)->rkcs1 = RK_CDT;
104 return (1);
105}
106
107rkslave(ui, reg)
89bd2f01 108 struct uba_device *ui;
0801d37f
BJ
109 caddr_t reg;
110{
111 register struct rkdevice *rkaddr = (struct rkdevice *)reg;
112
28de6ed0 113 rkaddr->rkcs1 = RK_CDT|RK_CCLR;
0801d37f 114 rkaddr->rkcs2 = ui->ui_slave;
29a0409f 115 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
9037157b 116 rkwait(rkaddr);
28de6ed0 117 DELAY(50);
535f6684 118 if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) {
0801d37f
BJ
119 rkaddr->rkcs1 = RK_CDT|RK_CCLR;
120 return (0);
121 }
122 return (1);
123}
d483c58c 124
0801d37f 125rkattach(ui)
89bd2f01 126 register struct uba_device *ui;
0801d37f
BJ
127{
128
129 if (rkwstart == 0) {
7780575a 130 timeout(rkwatch, (caddr_t)0, hz);
0801d37f
BJ
131 rkwstart++;
132 }
133 if (ui->ui_dk >= 0)
7780575a 134 dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256);
0801d37f
BJ
135 rkip[ui->ui_ctlr][ui->ui_slave] = ui;
136 rk_softc[ui->ui_ctlr].sc_ndrive++;
137 rkcyl[ui->ui_unit] = -1;
138}
139
d483c58c 140rkstrategy(bp)
0801d37f 141 register struct buf *bp;
d483c58c 142{
89bd2f01 143 register struct uba_device *ui;
0801d37f
BJ
144 register struct rkst *st;
145 register int unit;
146 register struct buf *dp;
147 int xunit = minor(bp->b_dev) & 07;
148 long bn, sz;
149
150 sz = (bp->b_bcount+511) >> 9;
151 unit = dkunit(bp);
872b4e09 152 if (unit >= NRK)
0801d37f
BJ
153 goto bad;
154 ui = rkdinfo[unit];
155 if (ui == 0 || ui->ui_alive == 0)
156 goto bad;
157 st = &rkst[ui->ui_type];
158 if (bp->b_blkno < 0 ||
159 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
160 goto bad;
161 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
162 (void) spl5();
163 dp = &rkutab[ui->ui_unit];
164 disksort(dp, bp);
165 if (dp->b_active == 0) {
166 (void) rkustart(ui);
167 bp = &ui->ui_mi->um_tab;
168 if (bp->b_actf && bp->b_active == 0)
169 (void) rkstart(ui->ui_mi);
d483c58c 170 }
0801d37f
BJ
171 (void) spl0();
172 return;
173
174bad:
175 bp->b_flags |= B_ERROR;
176 iodone(bp);
177 return;
d483c58c
BJ
178}
179
0801d37f 180rkustart(ui)
89bd2f01 181 register struct uba_device *ui;
0801d37f
BJ
182{
183 register struct buf *bp, *dp;
89bd2f01 184 register struct uba_ctlr *um;
0801d37f 185 register struct rkdevice *rkaddr;
0801d37f
BJ
186 int didie = 0;
187
188 if (ui == 0)
189 return (0);
190 dk_busy &= ~(1<<ui->ui_dk);
191 dp = &rkutab[ui->ui_unit];
0801d37f 192 um = ui->ui_mi;
28de6ed0 193 rkaddr = (struct rkdevice *)um->um_addr;
0801d37f
BJ
194 if (um->um_tab.b_active) {
195 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave;
196 return (0);
197 }
0801d37f
BJ
198 rkaddr->rkcs1 = RK_CDT|RK_CERR;
199 rkaddr->rkcs2 = ui->ui_slave;
29a0409f 200 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
0801d37f 201 rkwait(rkaddr);
736f0c13
BJ
202 if ((bp = dp->b_actf) == NULL) {
203 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
204 rkwait(rkaddr);
205 return (0);
206 }
535f6684 207 if ((rkaddr->rkds & RKDS_VV) == 0) {
0801d37f 208 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
28de6ed0 209 rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO;
0801d37f 210 rkwait(rkaddr);
0801d37f 211 }
736f0c13
BJ
212 if (dp->b_active)
213 goto done;
214 dp->b_active = 1;
535f6684 215 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY)
28de6ed0 216 goto done;
0801d37f
BJ
217 if (rk_softc[um->um_ctlr].sc_ndrive == 1)
218 goto done;
219 if (bp->b_cylin == rkcyl[ui->ui_unit])
220 goto done;
221 rkaddr->rkcyl = bp->b_cylin;
222 rkcyl[ui->ui_unit] = bp->b_cylin;
223 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO;
224 didie = 1;
225 if (ui->ui_dk >= 0) {
226 dk_busy |= 1<<ui->ui_dk;
227 dk_seek[ui->ui_dk]++;
228 }
229 goto out;
230done:
231 if (dp->b_active != 2) {
232 dp->b_forw = NULL;
233 if (um->um_tab.b_actf == NULL)
234 um->um_tab.b_actf = dp;
235 else
236 um->um_tab.b_actl->b_forw = dp;
237 um->um_tab.b_actl = dp;
238 dp->b_active = 2;
239 }
240out:
241 return (didie);
242}
d483c58c 243
0801d37f 244rkstart(um)
89bd2f01 245 register struct uba_ctlr *um;
d483c58c 246{
0801d37f 247 register struct buf *bp, *dp;
89bd2f01 248 register struct uba_device *ui;
0801d37f
BJ
249 register struct rkdevice *rkaddr;
250 struct rkst *st;
d483c58c 251 daddr_t bn;
0801d37f
BJ
252 int sn, tn, cmd;
253
254loop:
255 if ((dp = um->um_tab.b_actf) == NULL)
256 return (0);
257 if ((bp = dp->b_actf) == NULL) {
258 um->um_tab.b_actf = dp->b_forw;
259 goto loop;
d483c58c 260 }
0801d37f
BJ
261 um->um_tab.b_active++;
262 ui = rkdinfo[dkunit(bp)];
263 bn = dkblock(bp);
264 st = &rkst[ui->ui_type];
265 sn = bn%st->nspc;
266 tn = sn/st->nsect;
267 sn %= st->nsect;
268 rkaddr = (struct rkdevice *)ui->ui_addr;
29a0409f 269retry:
0801d37f
BJ
270 rkaddr->rkcs1 = RK_CDT|RK_CERR;
271 rkaddr->rkcs2 = ui->ui_slave;
29a0409f 272 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
0801d37f 273 rkwait(rkaddr);
535f6684 274 if ((rkaddr->rkds&RKDS_SVAL) == 0) {
29a0409f
BJ
275 rknosval++;
276 goto nosval;
277 }
535f6684 278 if (rkaddr->rkds&RKDS_PIP) {
29a0409f
BJ
279 rkpip++;
280 goto retry;
28de6ed0 281 }
535f6684 282 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
68347e63 283 printf("rk%d: not ready", dkunit(bp));
535f6684 284 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
28de6ed0
BJ
285 printf("\n");
286 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
287 rkwait(rkaddr);
288 rkaddr->rkcs1 = RK_CDT|RK_CERR;
289 rkwait(rkaddr);
290 um->um_tab.b_active = 0;
291 um->um_tab.b_errcnt = 0;
292 dp->b_actf = bp->av_forw;
293 dp->b_active = 0;
294 bp->b_flags |= B_ERROR;
295 iodone(bp);
296 goto loop;
297 }
298 printf(" (came back!)\n");
299 }
29a0409f 300nosval:
0801d37f
BJ
301 rkaddr->rkcyl = bp->b_cylin;
302 rkcyl[ui->ui_unit] = bp->b_cylin;
303 rkaddr->rkda = (tn << 8) + sn;
304 rkaddr->rkwc = -bp->b_bcount / sizeof (short);
305 if (bp->b_flags & B_READ)
306 cmd = RK_CDT|RK_IE|RK_READ|RK_GO;
307 else
308 cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO;
309 um->um_cmd = cmd;
a0eab615 310 (void) ubago(ui);
0801d37f 311 return (1);
d483c58c
BJ
312}
313
0801d37f 314rkdgo(um)
89bd2f01 315 register struct uba_ctlr *um;
d483c58c 316{
0801d37f
BJ
317 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
318
319 rkaddr->rkba = um->um_ubinfo;
320 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
321}
322
443c8066 323rkintr(rk11)
0801d37f
BJ
324 int rk11;
325{
89bd2f01
BJ
326 register struct uba_ctlr *um = rkminfo[rk11];
327 register struct uba_device *ui;
0801d37f
BJ
328 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
329 register struct buf *bp, *dp;
330 int unit;
331 struct rk_softc *sc = &rk_softc[um->um_ctlr];
332 int as = (rkaddr->rkatt >> 8) | sc->sc_softas;
333 int needie = 1;
334
335 sc->sc_wticks = 0;
336 sc->sc_softas = 0;
337 if (um->um_tab.b_active) {
338 dp = um->um_tab.b_actf;
339 bp = dp->b_actf;
340 ui = rkdinfo[dkunit(bp)];
341 dk_busy &= ~(1 << ui->ui_dk);
342 if (rkaddr->rkcs1 & RK_CERR) {
343 int recal;
344 u_short ds = rkaddr->rkds;
345 u_short cs2 = rkaddr->rkcs2;
346 u_short er = rkaddr->rker;
535f6684
BJ
347 if (rkdebug) {
348 printf("cs2=%b ds=%b er=%b\n",
349 cs2, RKCS2_BITS, ds,
350 RKDS_BITS, er, RKER_BITS);
351 }
352 if (er & RKER_WLE) {
68347e63 353 printf("rk%d: write locked\n", dkunit(bp));
ed687006
BJ
354 bp->b_flags |= B_ERROR;
355 } else if (++um->um_tab.b_errcnt > 28 ||
736772ef 356 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) {
68347e63
BJ
357 harderr(bp, "rk");
358 printf("cs2=%b ds=%b er=%b\n",
28de6ed0 359 cs2, RKCS2_BITS, ds,
736772ef 360 RKDS_BITS, er, RKER_BITS);
a306546d
BJ
361 bp->b_flags |= B_ERROR;
362 sc->sc_recal = 0;
736772ef 363 } else
0801d37f 364 um->um_tab.b_active = 0;
535f6684
BJ
365 if (cs2&RKCS2_MDS) {
366 rkaddr->rkcs2 = RKCS2_SCLR;
0801d37f
BJ
367 goto retry;
368 }
369 recal = 0;
535f6684 370 if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) ||
0801d37f
BJ
371 (um->um_tab.b_errcnt&07) == 4)
372 recal = 1;
535f6684 373 if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK)
0801d37f
BJ
374 if (rkecc(ui))
375 return;
376 rkaddr->rkcs1 = RK_CDT|RK_CCLR;
377 rkaddr->rkcs2 = ui->ui_slave;
378 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
379 rkwait(rkaddr);
380 if (recal && um->um_tab.b_active == 0) {
381 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO;
382 rkcyl[ui->ui_unit] = -1;
29a0409f
BJ
383 sc->sc_recal = 0;
384 goto nextrecal;
d483c58c 385 }
d483c58c 386 }
0801d37f 387retry:
29a0409f
BJ
388 switch (sc->sc_recal) {
389
390 case 1:
391 rkaddr->rkcyl = bp->b_cylin;
392 rkcyl[ui->ui_unit] = bp->b_cylin;
393 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO;
394 goto nextrecal;
29a0409f
BJ
395 case 2:
396 if (um->um_tab.b_errcnt < 16 ||
6ac24ecd 397 (bp->b_flags&B_READ) == 0)
a6442a2f 398 goto donerecal;
29a0409f
BJ
399 rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017];
400 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_OFFSET|RK_GO;
401 /* fall into ... */
402 nextrecal:
403 sc->sc_recal++;
404 rkwait(rkaddr);
405 um->um_tab.b_active = 1;
406 return;
a6442a2f 407 donerecal:
29a0409f 408 case 3:
0801d37f
BJ
409 sc->sc_recal = 0;
410 um->um_tab.b_active = 0;
29a0409f 411 break;
d483c58c 412 }
0801d37f
BJ
413 if (um->um_tab.b_active) {
414 um->um_tab.b_active = 0;
415 um->um_tab.b_errcnt = 0;
416 um->um_tab.b_actf = dp->b_forw;
417 dp->b_active = 0;
418 dp->b_errcnt = 0;
419 dp->b_actf = bp->av_forw;
420 bp->b_resid = -rkaddr->rkwc * sizeof(short);
421 iodone(bp);
422 if (dp->b_actf)
423 if (rkustart(ui))
424 needie = 0;
d483c58c 425 }
0801d37f 426 as &= ~(1<<ui->ui_slave);
299d67ed 427 ubadone(um);
d483c58c 428 }
0801d37f 429 for (unit = 0; as; as >>= 1, unit++)
89bd2f01
BJ
430 if (as & 1) {
431 ui = rkip[rk11][unit];
432 if (ui) {
433 if (rkustart(rkip[rk11][unit]))
434 needie = 0;
435 } else {
436 rkaddr->rkcs1 = RK_CERR|RK_CDT;
437 rkaddr->rkcs2 = unit;
438 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
439 rkwait(rkaddr);
440 }
441 }
0801d37f
BJ
442 if (um->um_tab.b_actf && um->um_tab.b_active == 0)
443 if (rkstart(um))
444 needie = 0;
445 if (needie)
446 rkaddr->rkcs1 = RK_CDT|RK_IE;
d483c58c
BJ
447}
448
0801d37f
BJ
449rkwait(addr)
450 register struct rkdevice *addr;
451{
452
453 while ((addr->rkcs1 & RK_CRDY) == 0)
454 ;
455}
d483c58c 456
0801d37f
BJ
457rkread(dev)
458 dev_t dev;
d483c58c 459{
0801d37f
BJ
460 register int unit = minor(dev) >> 3;
461
872b4e09 462 if (unit >= NRK)
0801d37f
BJ
463 u.u_error = ENXIO;
464 else
465 physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys);
d483c58c
BJ
466}
467
0801d37f
BJ
468rkwrite(dev)
469 dev_t dev;
d483c58c 470{
0801d37f 471 register int unit = minor(dev) >> 3;
d483c58c 472
872b4e09 473 if (unit >= NRK)
0801d37f
BJ
474 u.u_error = ENXIO;
475 else
476 physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys);
d483c58c
BJ
477}
478
0801d37f 479rkecc(ui)
89bd2f01 480 register struct uba_device *ui;
d483c58c 481{
0801d37f
BJ
482 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr;
483 register struct buf *bp = rkutab[ui->ui_unit].b_actf;
89bd2f01 484 register struct uba_ctlr *um = ui->ui_mi;
0801d37f
BJ
485 register struct rkst *st;
486 struct uba_regs *ubp = ui->ui_hd->uh_uba;
487 register int i;
488 caddr_t addr;
489 int reg, bit, byte, npf, mask, o, cmd, ubaddr;
490 int bn, cn, tn, sn;
d483c58c 491
0801d37f
BJ
492 npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1;
493 reg = btop(um->um_ubinfo&0x3ffff) + npf;
494 o = (int)bp->b_un.b_addr & PGOFSET;
1c509b5e 495 printf("rk%d%c: soft ecc sn%d\n", dkunit(bp),
c9e9b65b 496 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
0801d37f 497 mask = rk->rkec2;
060afaf6 498 ubapurge(um);
0801d37f
BJ
499 i = rk->rkec1 - 1; /* -1 makes 0 origin */
500 bit = i&07;
501 i = (i&~07)>>3;
502 byte = i + o;
503 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
504 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
505 (byte & PGOFSET);
506 putmemc(addr, getmemc(addr)^(mask<<bit));
507 byte++;
508 i++;
509 bit -= 8;
510 }
511 um->um_tab.b_active++; /* Either complete or continuing... */
512 if (rk->rkwc == 0)
513 return (0);
9037157b
BJ
514#ifdef notdef
515 rk->rkcs1 |= RK_GO;
516#else
0801d37f
BJ
517 rk->rkcs1 = RK_CDT|RK_CCLR;
518 rk->rkcs2 = ui->ui_slave;
519 rk->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
520 rkwait(rk);
521 bn = dkblock(bp);
522 st = &rkst[ui->ui_type];
523 cn = bp->b_cylin;
524 sn = bn%st->nspc + npf + 1;
525 tn = sn/st->nsect;
526 sn %= st->nsect;
527 cn += tn/st->ntrak;
528 tn %= st->ntrak;
529 rk->rkcyl = cn;
530 rk->rkda = (tn << 8) | sn;
531 ubaddr = (int)ptob(reg+1) + o;
532 rk->rkba = ubaddr;
533 cmd = (ubaddr >> 8) & 0x300;
534 cmd |= RK_CDT|RK_IE|RK_GO|RK_READ;
535 rk->rkcs1 = cmd;
9037157b 536#endif
0801d37f 537 return (1);
d483c58c
BJ
538}
539
0801d37f 540rkreset(uban)
68347e63 541 int uban;
0801d37f 542{
89bd2f01
BJ
543 register struct uba_ctlr *um;
544 register struct uba_device *ui;
0801d37f 545 register rk11, unit;
0801d37f 546
872b4e09 547 for (rk11 = 0; rk11 < NHK; rk11++) {
0801d37f
BJ
548 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban ||
549 um->um_alive == 0)
550 continue;
68347e63 551 printf(" hk%d", rk11);
0801d37f
BJ
552 um->um_tab.b_active = 0;
553 um->um_tab.b_actf = um->um_tab.b_actl = 0;
554 rk_softc[um->um_ctlr].sc_recal = 0;
555 if (um->um_ubinfo) {
556 printf("<%d>", (um->um_ubinfo>>28)&0xf);
557 ubadone(um);
558 }
872b4e09 559 for (unit = 0; unit < NHK; unit++) {
0801d37f
BJ
560 if ((ui = rkdinfo[unit]) == 0)
561 continue;
562 if (ui->ui_alive == 0)
563 continue;
564 rkutab[unit].b_active = 0;
565 (void) rkustart(ui);
566 }
567 (void) rkstart(um);
568 }
569}
570
0801d37f 571rkwatch()
d483c58c 572{
89bd2f01 573 register struct uba_ctlr *um;
0801d37f
BJ
574 register rk11, unit;
575 register struct rk_softc *sc;
d483c58c 576
7780575a 577 timeout(rkwatch, (caddr_t)0, hz);
872b4e09 578 for (rk11 = 0; rk11 < NHK; rk11++) {
0801d37f
BJ
579 um = rkminfo[rk11];
580 if (um == 0 || um->um_alive == 0)
581 continue;
582 sc = &rk_softc[rk11];
583 if (um->um_tab.b_active == 0) {
872b4e09 584 for (unit = 0; unit < NRK; unit++)
9037157b
BJ
585 if (rkutab[unit].b_active &&
586 rkdinfo[unit]->ui_mi == um)
0801d37f
BJ
587 goto active;
588 sc->sc_wticks = 0;
589 continue;
590 }
591active:
592 sc->sc_wticks++;
593 if (sc->sc_wticks >= 20) {
594 sc->sc_wticks = 0;
68347e63 595 printf("hk%d: lost interrupt\n", rk11);
872b4e09 596 ubareset(um->um_ubanum);
0801d37f
BJ
597 }
598 }
d483c58c 599}
0ff318b2 600
0801d37f
BJ
601#define DBSIZE 20
602
603rkdump(dev)
604 dev_t dev;
0ff318b2 605{
0801d37f
BJ
606 struct rkdevice *rkaddr;
607 char *start;
608 int num, blk, unit;
609 struct size *sizes;
610 register struct uba_regs *uba;
89bd2f01 611 register struct uba_device *ui;
0801d37f
BJ
612 register short *rp;
613 struct rkst *st;
614
615 unit = minor(dev) >> 3;
c9e9b65b
BJ
616 if (unit >= NRK)
617 return (ENXIO);
0801d37f 618#define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
89bd2f01 619 ui = phys(struct uba_device *, rkdinfo[unit]);
c9e9b65b
BJ
620 if (ui->ui_alive == 0)
621 return (ENXIO);
0801d37f 622 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
a53e803c 623 ubainit(uba);
0801d37f
BJ
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);
535f6684 631 if ((rkaddr->rkds & RKDS_VV) == 0) {
0801d37f
BJ
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