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