1 /*
2 * Copyright (c) 1982, 1986 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6 * @(#)rk.c 7.9 (Berkeley) 12/16/90
7 */
8
9 #include "rk.h"
10 #if NHK > 0
11 int rkpip; /* DEBUG */
12 int rknosval; /* DEBUG */
13 #ifdef RKDEBUG
14 int rkdebug;
15 #endif
16 #ifdef RKBDEBUG
17 int rkbdebug;
18 #endif
19 /*
20 * RK611/RK0[67] disk driver
21 *
22 * This driver mimics up.c; see it for an explanation of common code.
23 *
24 * TODO:
25 * Learn why we lose an interrupt sometime when spinning drives down
26 */
27 #include "../include/pte.h"
28
29 #include "sys/param.h"
30 #include "sys/systm.h"
31 #include "sys/buf.h"
32 #include "sys/conf.h"
33 #include "sys/user.h"
34 #include "sys/map.h"
35 #include "sys/vm.h"
36 #include "sys/dkstat.h"
37 #include "sys/cmap.h"
38 #include "sys/dkbad.h"
39 #include "sys/ioctl.h"
40 #include "sys/disklabel.h"
41 #include "sys/uio.h"
42 #include "sys/kernel.h"
43 #include "sys/syslog.h"
44
45 #include "../include/cpu.h"
46 #include "ubareg.h"
47 #include "ubavar.h"
48 #include "rkreg.h"
49
50 struct rk_softc {
51 int sc_softas;
52 int sc_ndrive;
53 int sc_wticks;
54 int sc_recal;
55 } rk_softc[NHK];
56
57 #define rkunit(dev) (minor(dev) >> 3)
58
59 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
60 struct size {
61 daddr_t nblocks;
62 int cyloff;
63 } rk7_sizes[8] = {
64 15884, 0, /* A=cyl 0 thru 240 */
65 10032, 241, /* B=cyl 241 thru 392 */
66 53790, 0, /* C=cyl 0 thru 814 */
67 15884, 393, /* D=cyl 393 thru 633 */
68 0, 0,
69 11792, 634, /* F=cyl 634 thru 814 */
70 27786, 393, /* G=cyl 393 thru 814, should be 27698 */
71 0, 0,
72 }, rk6_sizes[8] ={
73 15884, 0, /* A=cyl 0 thru 240 */
74 11154, 241, /* B=cyl 241 thru 409 */
75 27126, 0, /* C=cyl 0 thru 410 */
76 0, 0,
77 0, 0,
78 0, 0,
79 0, 0,
80 0, 0,
81 };
82 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
83
84 short rktypes[] = { RK_CDT, 0 };
85
86 int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr();
87 struct uba_ctlr *rkminfo[NHK];
88 struct uba_device *rkdinfo[NRK];
89 struct uba_device *rkip[NHK][4];
90
91 u_short rkstd[] = { 0777440, 0 };
92 struct uba_driver hkdriver =
93 { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 };
94 struct buf rkutab[NRK];
95 short rkcyl[NRK];
96 struct dkbad rkbad[NRK];
97 struct buf brkbuf[NRK];
98
99 struct rkst {
100 short nsect;
101 short ntrak;
102 short nspc;
103 short ncyl;
104 struct size *sizes;
105 } rkst[] = {
106 NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes,
107 NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes,
108 };
109
110 u_char rk_offset[16] =
111 { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800,
112 RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0
113 };
114
115 #define b_cylin b_resid
116
117 int rkwstart, rkwatch();
118
rkprobe(reg)119 rkprobe(reg)
120 caddr_t reg;
121 {
122 register int br, cvec;
123
124 #ifdef lint
125 br = 0; cvec = br; br = cvec;
126 rkintr(0);
127 #endif
128 ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY;
129 DELAY(10);
130 ((struct rkdevice *)reg)->rkcs1 = RK_CDT;
131 return (sizeof (struct rkdevice));
132 }
133
134 rkslave(ui, reg)
135 struct uba_device *ui;
136 caddr_t reg;
137 {
138 register struct rkdevice *rkaddr = (struct rkdevice *)reg;
139
140 ui->ui_type = 0;
141 rkaddr->rkcs1 = RK_CCLR;
142 rkaddr->rkcs2 = ui->ui_slave;
143 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
144 rkwait(rkaddr);
145 DELAY(50);
146 if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) {
147 rkaddr->rkcs1 = RK_CCLR;
148 return (0);
149 }
150 if (rkaddr->rkcs1&RK_CERR && rkaddr->rker&RKER_DTYE) {
151 ui->ui_type = 1;
152 rkaddr->rkcs1 = RK_CCLR;
153 }
154 return (1);
155 }
156
rkattach(ui)157 rkattach(ui)
158 register struct uba_device *ui;
159 {
160
161 if (rkwstart == 0) {
162 timeout(rkwatch, (caddr_t)0, hz);
163 rkwstart++;
164 }
165 if (ui->ui_dk >= 0)
166 dk_wpms[ui->ui_dk] = (60 * NRKSECT * 256);
167 rkip[ui->ui_ctlr][ui->ui_slave] = ui;
168 rk_softc[ui->ui_ctlr].sc_ndrive++;
169 rkcyl[ui->ui_unit] = -1;
170 ui->ui_flags = 0;
171 }
172
rkopen(dev)173 rkopen(dev)
174 dev_t dev;
175 {
176 register int unit = rkunit(dev);
177 register struct uba_device *ui;
178
179 if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0)
180 return (ENXIO);
181 return (0);
182 }
183
rkstrategy(bp)184 rkstrategy(bp)
185 register struct buf *bp;
186 {
187 register struct uba_device *ui;
188 register struct rkst *st;
189 register int unit;
190 register struct buf *dp;
191 int xunit = minor(bp->b_dev) & 07;
192 long bn, sz;
193 int s;
194
195 sz = (bp->b_bcount+511) >> 9;
196 unit = rkunit(bp->b_dev);
197 if (unit >= NRK) {
198 bp->b_error = ENXIO;
199 goto bad;
200 }
201 ui = rkdinfo[unit];
202 if (ui == 0 || ui->ui_alive == 0) {
203 bp->b_error = ENXIO;
204 goto bad;
205 }
206 st = &rkst[ui->ui_type];
207 if (bp->b_blkno < 0 ||
208 (bn = bp->b_blkno)+sz > st->sizes[xunit].nblocks) {
209 if (bp->b_blkno == st->sizes[xunit].nblocks) {
210 bp->b_resid = bp->b_bcount;
211 goto done;
212 }
213 bp->b_error = EINVAL;
214 goto bad;
215 }
216 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
217 s = spl5();
218 dp = &rkutab[ui->ui_unit];
219 disksort(dp, bp);
220 if (dp->b_active == 0) {
221 (void) rkustart(ui);
222 bp = &ui->ui_mi->um_tab;
223 if (bp->b_actf && bp->b_active == 0)
224 (void) rkstart(ui->ui_mi);
225 }
226 splx(s);
227 return;
228
229 bad:
230 bp->b_flags |= B_ERROR;
231 done:
232 iodone(bp);
233 return;
234 }
235
rkustart(ui)236 rkustart(ui)
237 register struct uba_device *ui;
238 {
239 register struct buf *bp, *dp;
240 register struct uba_ctlr *um;
241 register struct rkdevice *rkaddr;
242
243 if (ui == 0)
244 return;
245 dk_busy &= ~(1<<ui->ui_dk);
246 dp = &rkutab[ui->ui_unit];
247 um = ui->ui_mi;
248 rkaddr = (struct rkdevice *)um->um_addr;
249 if (um->um_tab.b_active) {
250 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave;
251 return;
252 }
253 if ((bp = dp->b_actf) == NULL)
254 return;
255 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR;
256 rkaddr->rkcs2 = ui->ui_slave;
257 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
258 rkwait(rkaddr);
259 if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) {
260 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
261 struct rkst *st = &rkst[ui->ui_type];
262 struct buf *bbp = &brkbuf[ui->ui_unit];
263
264 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO;
265 ui->ui_flags = 1;
266 bbp->b_flags = B_READ|B_BUSY;
267 bbp->b_dev = bp->b_dev;
268 bbp->b_bcount = 512;
269 bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit];
270 bbp->b_blkno = st->ncyl*st->nspc - st->nsect;
271 bbp->b_cylin = st->ncyl - 1;
272 dp->b_actf = bbp;
273 bbp->av_forw = bp;
274 bp = bbp;
275 rkwait(rkaddr);
276 }
277 if (dp->b_active)
278 goto done;
279 dp->b_active = 1;
280 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY)
281 goto done;
282 if (rk_softc[um->um_ctlr].sc_ndrive == 1)
283 goto done;
284 if (bp->b_cylin == rkcyl[ui->ui_unit])
285 goto done;
286 rkaddr->rkcyl = bp->b_cylin;
287 rkcyl[ui->ui_unit] = bp->b_cylin;
288 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO;
289 if (ui->ui_dk >= 0) {
290 dk_busy |= 1<<ui->ui_dk;
291 dk_seek[ui->ui_dk]++;
292 }
293 goto out;
294 done:
295 if (dp->b_active != 2) {
296 dp->b_forw = NULL;
297 if (um->um_tab.b_actf == NULL)
298 um->um_tab.b_actf = dp;
299 else
300 um->um_tab.b_actl->b_forw = dp;
301 um->um_tab.b_actl = dp;
302 dp->b_active = 2;
303 }
304 out:
305 return;
306 }
307
rkstart(um)308 rkstart(um)
309 register struct uba_ctlr *um;
310 {
311 register struct buf *bp, *dp;
312 register struct uba_device *ui;
313 register struct rkdevice *rkaddr;
314 struct rkst *st;
315 daddr_t bn;
316 int sn, tn, cmd;
317
318 loop:
319 if ((dp = um->um_tab.b_actf) == NULL)
320 return;
321 if ((bp = dp->b_actf) == NULL) {
322 um->um_tab.b_actf = dp->b_forw;
323 goto loop;
324 }
325 um->um_tab.b_active++;
326 ui = rkdinfo[rkunit(bp->b_dev)];
327 bn = bp->b_blkno;
328 st = &rkst[ui->ui_type];
329 sn = bn%st->nspc;
330 tn = sn/st->nsect;
331 sn %= st->nsect;
332 rkaddr = (struct rkdevice *)ui->ui_addr;
333 retry:
334 rkaddr->rkcs1 = RK_CCLR;
335 rkaddr->rkcs2 = ui->ui_slave;
336 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
337 rkwait(rkaddr);
338 if ((rkaddr->rkds&RKDS_SVAL) == 0) {
339 rknosval++;
340 goto nosval;
341 }
342 if (rkaddr->rkds&RKDS_PIP) {
343 rkpip++;
344 goto retry;
345 }
346 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
347 printf("rk%d: not ready", rkunit(bp->b_dev));
348 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
349 printf("\n");
350 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
351 rkwait(rkaddr);
352 rkaddr->rkcs1 = RK_CCLR;
353 rkwait(rkaddr);
354 um->um_tab.b_active = 0;
355 um->um_tab.b_errcnt = 0;
356 dp->b_actf = bp->av_forw;
357 dp->b_active = 0;
358 bp->b_flags |= B_ERROR;
359 iodone(bp);
360 goto loop;
361 }
362 printf(" (came back!)\n");
363 }
364 nosval:
365 rkaddr->rkcyl = bp->b_cylin;
366 rkcyl[ui->ui_unit] = bp->b_cylin;
367 rkaddr->rkda = (tn << 8) + sn;
368 rkaddr->rkwc = -bp->b_bcount / sizeof (short);
369 if (bp->b_flags & B_READ)
370 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO;
371 else
372 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO;
373 um->um_cmd = cmd;
374 (void) ubago(ui);
375 }
376
rkdgo(um)377 rkdgo(um)
378 register struct uba_ctlr *um;
379 {
380 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
381
382 um->um_tab.b_active = 2; /* should now be 2 */
383 rkaddr->rkba = um->um_ubinfo;
384 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
385 }
386
rkintr(rk11)387 rkintr(rk11)
388 int rk11;
389 {
390 register struct uba_ctlr *um = rkminfo[rk11];
391 register struct uba_device *ui;
392 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
393 register struct buf *bp, *dp;
394 int unit;
395 struct rk_softc *sc = &rk_softc[um->um_ctlr];
396 int as = (rkaddr->rkatt >> 8) | sc->sc_softas;
397
398 sc->sc_wticks = 0;
399 sc->sc_softas = 0;
400 if (um->um_tab.b_active == 2 || sc->sc_recal) {
401 um->um_tab.b_active = 1;
402 dp = um->um_tab.b_actf;
403 bp = dp->b_actf;
404 ui = rkdinfo[rkunit(bp->b_dev)];
405 dk_busy &= ~(1 << ui->ui_dk);
406 if (bp->b_flags&B_BAD)
407 if (rkecc(ui, CONT))
408 return;
409 if (rkaddr->rkcs1 & RK_CERR) {
410 int recal;
411 u_short ds = rkaddr->rkds;
412 u_short cs2 = rkaddr->rkcs2;
413 u_short er = rkaddr->rker;
414 #ifdef RKDEBUG
415 if (rkdebug) {
416 printf("cs2=%b ds=%b er=%b\n",
417 cs2, RKCS2_BITS, ds,
418 RKDS_BITS, er, RKER_BITS);
419 }
420 #endif
421 if (er & RKER_WLE) {
422 printf("rk%d: write locked\n",
423 rkunit(bp->b_dev));
424 bp->b_flags |= B_ERROR;
425 } else if (++um->um_tab.b_errcnt > 28 ||
426 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) {
427 hard:
428 diskerr(bp, "rk", "hard error", LOG_PRINTF, -1,
429 (struct disklabel *)0);
430 printf(" cs2=%b ds=%b er=%b\n",
431 cs2, RKCS2_BITS, ds,
432 RKDS_BITS, er, RKER_BITS);
433 bp->b_flags |= B_ERROR;
434 sc->sc_recal = 0;
435 } else if (er & RKER_BSE) {
436 if (rkecc(ui, BSE))
437 return;
438 else
439 goto hard;
440 } else {
441 if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) {
442 if (rkecc(ui, ECC))
443 return;
444 } else
445 um->um_tab.b_active = 0;
446 }
447 if (cs2&RKCS2_MDS) {
448 rkaddr->rkcs2 = RKCS2_SCLR;
449 goto retry;
450 }
451 recal = 0;
452 if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) ||
453 (um->um_tab.b_errcnt&07) == 4)
454 recal = 1;
455 rkaddr->rkcs1 = RK_CCLR;
456 rkaddr->rkcs2 = ui->ui_slave;
457 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
458 rkwait(rkaddr);
459 if (recal && um->um_tab.b_active == 0) {
460 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO;
461 rkcyl[ui->ui_unit] = -1;
462 sc->sc_recal = 0;
463 goto nextrecal;
464 }
465 }
466 retry:
467 switch (sc->sc_recal) {
468
469 case 1:
470 rkaddr->rkcyl = bp->b_cylin;
471 rkcyl[ui->ui_unit] = bp->b_cylin;
472 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO;
473 goto nextrecal;
474 case 2:
475 if (um->um_tab.b_errcnt < 16 ||
476 (bp->b_flags&B_READ) == 0)
477 goto donerecal;
478 rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017];
479 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO;
480 /* fall into ... */
481 nextrecal:
482 sc->sc_recal++;
483 rkwait(rkaddr);
484 um->um_tab.b_active = 1;
485 return;
486 donerecal:
487 case 3:
488 sc->sc_recal = 0;
489 um->um_tab.b_active = 0;
490 break;
491 }
492 ubadone(um);
493 if (um->um_tab.b_active) {
494 um->um_tab.b_active = 0;
495 um->um_tab.b_errcnt = 0;
496 um->um_tab.b_actf = dp->b_forw;
497 dp->b_active = 0;
498 dp->b_errcnt = 0;
499 dp->b_actf = bp->av_forw;
500 bp->b_resid = -rkaddr->rkwc * sizeof(short);
501 iodone(bp);
502 if (dp->b_actf)
503 rkustart(ui);
504 }
505 as &= ~(1<<ui->ui_slave);
506 }
507 for (unit = 0; as; as >>= 1, unit++)
508 if (as & 1) {
509 ui = rkip[rk11][unit];
510 if (ui) {
511 rkustart(rkip[rk11][unit]);
512 } else {
513 rkaddr->rkcs1 = RK_CCLR;
514 rkaddr->rkcs2 = unit;
515 rkaddr->rkcs1 = RK_DCLR|RK_GO;
516 rkwait(rkaddr);
517 rkaddr->rkcs1 = RK_CCLR;
518 }
519 }
520 if (um->um_tab.b_actf && um->um_tab.b_active == 0)
521 rkstart(um);
522 if (((rkaddr->rkcs1) & RK_IE) == 0)
523 rkaddr->rkcs1 = RK_IE;
524 }
525
rkwait(addr)526 rkwait(addr)
527 register struct rkdevice *addr;
528 {
529
530 while ((addr->rkcs1 & RK_CRDY) == 0)
531 ;
532 }
533
rkecc(ui,flag)534 rkecc(ui, flag)
535 register struct uba_device *ui;
536 {
537 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr;
538 register struct buf *bp = rkutab[ui->ui_unit].b_actf;
539 register struct uba_ctlr *um = ui->ui_mi;
540 register struct rkst *st;
541 struct uba_regs *ubp = ui->ui_hd->uh_uba;
542 caddr_t addr;
543 int reg, npf, o, cmd, ubaddr;
544 int bn, cn, tn, sn;
545
546 if (flag == CONT)
547 npf = bp->b_error;
548 else
549 npf = btodb(bp->b_bcount + (rk->rkwc * sizeof(short)) + 511);
550 reg = btop(UBAI_ADDR(um->um_ubinfo)) + npf;
551 o = (int)bp->b_un.b_addr & PGOFSET;
552 bn = bp->b_blkno;
553 st = &rkst[ui->ui_type];
554 cn = bp->b_cylin;
555 sn = bn%st->nspc + npf;
556 tn = sn/st->nsect;
557 sn %= st->nsect;
558 cn += tn/st->ntrak;
559 tn %= st->ntrak;
560 ubapurge(um);
561 switch (flag) {
562 case ECC:
563 {
564 register int i;
565 int bit, byte, mask;
566
567 npf--;
568 reg--;
569 diskerr(bp, "rk", "soft ecc", LOG_WARNING, npf,
570 (struct disklabel *)0);
571 addlog("\n");
572 mask = rk->rkec2;
573 i = rk->rkec1 - 1; /* -1 makes 0 origin */
574 bit = i&07;
575 i = (i&~07)>>3;
576 byte = i + o;
577 while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) {
578 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
579 (byte & PGOFSET);
580 putmemc(addr, getmemc(addr)^(mask<<bit));
581 byte++;
582 i++;
583 bit -= 8;
584 }
585 if (rk->rkwc == 0) {
586 um->um_tab.b_active = 0;
587 return (0);
588 }
589 npf++;
590 reg++;
591 break;
592 }
593
594 case BSE:
595 #ifdef RKBDEBUG
596 if (rkbdebug)
597 printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
598 #endif
599 if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0)
600 return(0);
601 bp->b_flags |= B_BAD;
602 bp->b_error = npf + 1;
603 bn = st->ncyl*st->nspc - st->nsect - 1 - bn;
604 cn = bn/st->nspc;
605 sn = bn%st->nspc;
606 tn = sn/st->nsect;
607 sn %= st->nsect;
608 #ifdef RKBDEBUG
609 if (rkbdebug)
610 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
611 #endif
612 rk->rkwc = -(512 / sizeof (short));
613 break;
614
615 case CONT:
616 #ifdef RKBDEBUG
617 if (rkbdebug)
618 printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);
619 #endif
620 bp->b_flags &= ~B_BAD;
621 if ((int)dbtob(npf) >= bp->b_bcount)
622 return (0);
623 rk->rkwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof (short));
624 break;
625 }
626 rk->rkcs1 = RK_CCLR;
627 rk->rkcs2 = ui->ui_slave;
628 rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
629 rkwait(rk);
630 rk->rkcyl = cn;
631 rk->rkda = (tn << 8) | sn;
632 ubaddr = (int)ptob(reg) + o;
633 rk->rkba = ubaddr;
634 cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO;
635 cmd |= (ubaddr >> 8) & 0x300;
636 cmd |= rktypes[ui->ui_type];
637 rk->rkcs1 = cmd;
638 um->um_tab.b_active = 2; /* continuing */
639 um->um_tab.b_errcnt = 0; /* error has been corrected */
640 return (1);
641 }
642
rkreset(uban)643 rkreset(uban)
644 int uban;
645 {
646 register struct uba_ctlr *um;
647 register struct uba_device *ui;
648 register rk11, unit;
649
650 for (rk11 = 0; rk11 < NHK; rk11++) {
651 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban ||
652 um->um_alive == 0)
653 continue;
654 printf(" hk%d", rk11);
655 um->um_tab.b_active = 0;
656 um->um_tab.b_actf = um->um_tab.b_actl = 0;
657 rk_softc[um->um_ctlr].sc_recal = 0;
658 rk_softc[um->um_ctlr].sc_wticks = 0;
659 if (um->um_ubinfo) {
660 printf("<%d>", (um->um_ubinfo>>28)&0xf);
661 um->um_ubinfo = 0;
662 }
663 for (unit = 0; unit < NRK; unit++) {
664 if ((ui = rkdinfo[unit]) == 0)
665 continue;
666 if (ui->ui_alive == 0 || ui->ui_mi != um)
667 continue;
668 rkutab[unit].b_active = 0;
669 (void) rkustart(ui);
670 }
671 (void) rkstart(um);
672 }
673 }
674
rkwatch()675 rkwatch()
676 {
677 register struct uba_ctlr *um;
678 register rk11, unit;
679 register struct rk_softc *sc;
680
681 timeout(rkwatch, (caddr_t)0, hz);
682 for (rk11 = 0; rk11 < NHK; rk11++) {
683 um = rkminfo[rk11];
684 if (um == 0 || um->um_alive == 0)
685 continue;
686 sc = &rk_softc[rk11];
687 if (um->um_tab.b_active == 0) {
688 for (unit = 0; unit < NRK; unit++)
689 if (rkutab[unit].b_active &&
690 rkdinfo[unit]->ui_mi == um)
691 goto active;
692 sc->sc_wticks = 0;
693 continue;
694 }
695 active:
696 sc->sc_wticks++;
697 if (sc->sc_wticks >= 20) {
698 sc->sc_wticks = 0;
699 printf("hk%d: lost interrupt\n", rk11);
700 ubareset(um->um_ubanum);
701 }
702 }
703 }
704
705 #define DBSIZE 20
706
rkdump(dev)707 rkdump(dev)
708 dev_t dev;
709 {
710 struct rkdevice *rkaddr;
711 char *start;
712 int num, blk, unit;
713 struct size *sizes;
714 register struct uba_regs *uba;
715 register struct uba_device *ui;
716 register short *rp;
717 struct rkst *st;
718
719 unit = rkunit(dev);
720 if (unit >= NRK)
721 return (ENXIO);
722 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
723 ui = phys(struct uba_device *, rkdinfo[unit]);
724 if (ui->ui_alive == 0)
725 return (ENXIO);
726 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
727 ubainit(uba);
728 rkaddr = (struct rkdevice *)ui->ui_physaddr;
729 num = maxfree;
730 start = 0;
731 rkaddr->rkcs1 = RK_CCLR;
732 rkaddr->rkcs2 = unit;
733 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
734 rkwait(rkaddr);
735 if ((rkaddr->rkds & RKDS_VV) == 0) {
736 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO;
737 rkwait(rkaddr);
738 }
739 st = &rkst[ui->ui_type];
740 sizes = phys(struct size *, st->sizes);
741 if (dumplo < 0)
742 return (EINVAL);
743 if (dumplo + num >= sizes[minor(dev)&07].nblocks)
744 num = sizes[minor(dev)&07].nblocks - dumplo;
745 while (num > 0) {
746 register struct pte *io;
747 register int i;
748 int cn, sn, tn;
749 daddr_t bn;
750
751 blk = num > DBSIZE ? DBSIZE : num;
752 io = uba->uba_map;
753 for (i = 0; i < blk; i++)
754 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV;
755 *(int *)io = 0;
756 bn = dumplo + btop(start);
757 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
758 sn = bn%st->nspc;
759 tn = sn/st->nsect;
760 sn = sn%st->nsect;
761 rkaddr->rkcyl = cn;
762 rp = (short *) &rkaddr->rkda;
763 *rp = (tn << 8) + sn;
764 *--rp = 0;
765 *--rp = -blk*NBPG / sizeof (short);
766 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE;
767 rkwait(rkaddr);
768 if (rkaddr->rkcs1 & RK_CERR)
769 return (EIO);
770 start += blk*NBPG;
771 num -= blk;
772 }
773 return (0);
774 }
775
rksize(dev)776 rksize(dev)
777 dev_t dev;
778 {
779 int unit = rkunit(dev);
780 struct uba_device *ui;
781 struct rkst *st;
782
783 if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0)
784 return (-1);
785 st = &rkst[ui->ui_type];
786 return (st->sizes[minor(dev) & 07].nblocks);
787 }
788 #endif
789