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