1 #define RKDEBUG 2 #define RKBDEBUG 3 /* rk.c 4.41 82/06/14 */ 4 5 #include "rk.h" 6 #if NHK > 0 7 int rkpip; /* DEBUG */ 8 int rknosval; /* DEBUG */ 9 #ifdef RKDEBUG 10 int rkdebug; 11 #endif 12 #ifdef RKBDEBUG 13 int rkbdebug; 14 #endif 15 /* 16 * RK611/RK0[67] disk driver 17 * 18 * This driver mimics up.c; see it for an explanation of common code. 19 * 20 * TODO: 21 * Learn why we lose an interrupt sometime when spinning drives down 22 */ 23 #include "../h/param.h" 24 #include "../h/systm.h" 25 #include "../h/buf.h" 26 #include "../h/conf.h" 27 #include "../h/dir.h" 28 #include "../h/user.h" 29 #include "../h/pte.h" 30 #include "../h/map.h" 31 #include "../h/vm.h" 32 #include "../h/ubareg.h" 33 #include "../h/ubavar.h" 34 #include "../h/dk.h" 35 #include "../h/cpu.h" 36 #include "../h/cmap.h" 37 #include "../h/dkbad.h" 38 39 #include "../h/rkreg.h" 40 41 struct rk_softc { 42 int sc_softas; 43 int sc_ndrive; 44 int sc_wticks; 45 int sc_recal; 46 } rk_softc[NHK]; 47 48 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 49 struct size { 50 daddr_t nblocks; 51 int cyloff; 52 } rk7_sizes[8] ={ 53 15884, 0, /* A=cyl 0 thru 240 */ 54 10032, 241, /* B=cyl 241 thru 392 */ 55 53790, 0, /* C=cyl 0 thru 814 */ 56 0, 0, 57 0, 0, 58 0, 0, 59 27786, 393, /* G=cyl 393 thru 813 */ 60 0, 0, 61 }, rk6_sizes[8] ={ 62 15884, 0, /* A=cyl 0 thru 240 */ 63 11154, 241, /* B=cyl 241 thru 409 */ 64 27126, 0, /* C=cyl 0 thru 410 */ 65 0, 0, 66 0, 0, 67 0, 0, 68 0, 0, 69 0, 0, 70 }; 71 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 72 73 short rktypes[] = { RK_CDT, 0 }; 74 75 int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); 76 struct uba_ctlr *rkminfo[NHK]; 77 struct uba_device *rkdinfo[NRK]; 78 struct uba_device *rkip[NHK][4]; 79 80 u_short rkstd[] = { 0777440, 0 }; 81 struct uba_driver hkdriver = 82 { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; 83 struct buf rkutab[NRK]; 84 short rkcyl[NRK]; 85 #ifndef NOBADSECT 86 struct dkbad rkbad[NRK]; 87 struct buf brkbuf[NRK]; 88 #endif 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 (1); 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 rkstrategy(bp) 171 register struct buf *bp; 172 { 173 register struct uba_device *ui; 174 register struct rkst *st; 175 register int unit; 176 register struct buf *dp; 177 int xunit = minor(bp->b_dev) & 07; 178 long bn, sz; 179 int s; 180 181 sz = (bp->b_bcount+511) >> 9; 182 unit = dkunit(bp); 183 if (unit >= NRK) 184 goto bad; 185 ui = rkdinfo[unit]; 186 if (ui == 0 || ui->ui_alive == 0) 187 goto bad; 188 st = &rkst[ui->ui_type]; 189 if (bp->b_blkno < 0 || 190 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 191 goto bad; 192 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 193 s = spl5(); 194 dp = &rkutab[ui->ui_unit]; 195 disksort(dp, bp); 196 if (dp->b_active == 0) { 197 (void) rkustart(ui); 198 bp = &ui->ui_mi->um_tab; 199 if (bp->b_actf && bp->b_active == 0) 200 (void) rkstart(ui->ui_mi); 201 } 202 splx(s); 203 return; 204 205 bad: 206 bp->b_flags |= B_ERROR; 207 iodone(bp); 208 return; 209 } 210 211 rkustart(ui) 212 register struct uba_device *ui; 213 { 214 register struct buf *bp, *dp; 215 register struct uba_ctlr *um; 216 register struct rkdevice *rkaddr; 217 218 if (ui == 0) 219 return; 220 dk_busy &= ~(1<<ui->ui_dk); 221 dp = &rkutab[ui->ui_unit]; 222 um = ui->ui_mi; 223 rkaddr = (struct rkdevice *)um->um_addr; 224 if (um->um_tab.b_active) { 225 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 226 return; 227 } 228 if ((bp = dp->b_actf) == NULL) 229 return; 230 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; 231 rkaddr->rkcs2 = ui->ui_slave; 232 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 233 rkwait(rkaddr); 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 if (ui->ui_dk >= 0) { 269 dk_busy |= 1<<ui->ui_dk; 270 dk_seek[ui->ui_dk]++; 271 } 272 goto out; 273 done: 274 if (dp->b_active != 2) { 275 dp->b_forw = NULL; 276 if (um->um_tab.b_actf == NULL) 277 um->um_tab.b_actf = dp; 278 else 279 um->um_tab.b_actl->b_forw = dp; 280 um->um_tab.b_actl = dp; 281 dp->b_active = 2; 282 } 283 out: 284 return; 285 } 286 287 rkstart(um) 288 register struct uba_ctlr *um; 289 { 290 register struct buf *bp, *dp; 291 register struct uba_device *ui; 292 register struct rkdevice *rkaddr; 293 struct rkst *st; 294 daddr_t bn; 295 int sn, tn, cmd; 296 297 loop: 298 if ((dp = um->um_tab.b_actf) == NULL) 299 return; 300 if ((bp = dp->b_actf) == NULL) { 301 um->um_tab.b_actf = dp->b_forw; 302 goto loop; 303 } 304 um->um_tab.b_active++; 305 ui = rkdinfo[dkunit(bp)]; 306 bn = dkblock(bp); 307 st = &rkst[ui->ui_type]; 308 sn = bn%st->nspc; 309 tn = sn/st->nsect; 310 sn %= st->nsect; 311 rkaddr = (struct rkdevice *)ui->ui_addr; 312 retry: 313 rkaddr->rkcs1 = RK_CCLR; 314 rkaddr->rkcs2 = ui->ui_slave; 315 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 316 rkwait(rkaddr); 317 if ((rkaddr->rkds&RKDS_SVAL) == 0) { 318 rknosval++; 319 goto nosval; 320 } 321 if (rkaddr->rkds&RKDS_PIP) { 322 rkpip++; 323 goto retry; 324 } 325 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 326 printf("rk%d: not ready", dkunit(bp)); 327 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 328 printf("\n"); 329 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 330 rkwait(rkaddr); 331 rkaddr->rkcs1 = RK_CCLR; 332 rkwait(rkaddr); 333 um->um_tab.b_active = 0; 334 um->um_tab.b_errcnt = 0; 335 dp->b_actf = bp->av_forw; 336 dp->b_active = 0; 337 bp->b_flags |= B_ERROR; 338 iodone(bp); 339 goto loop; 340 } 341 printf(" (came back!)\n"); 342 } 343 nosval: 344 rkaddr->rkcyl = bp->b_cylin; 345 rkcyl[ui->ui_unit] = bp->b_cylin; 346 rkaddr->rkda = (tn << 8) + sn; 347 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 348 if (bp->b_flags & B_READ) 349 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; 350 else 351 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; 352 um->um_cmd = cmd; 353 (void) ubago(ui); 354 } 355 356 rkdgo(um) 357 register struct uba_ctlr *um; 358 { 359 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 360 361 um->um_tab.b_active = 2; /* should now be 2 */ 362 rkaddr->rkba = um->um_ubinfo; 363 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 364 } 365 366 rkintr(rk11) 367 int rk11; 368 { 369 register struct uba_ctlr *um = rkminfo[rk11]; 370 register struct uba_device *ui; 371 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 372 register struct buf *bp, *dp; 373 int unit; 374 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 375 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 376 int needie = 1; 377 378 sc->sc_wticks = 0; 379 sc->sc_softas = 0; 380 if (um->um_tab.b_active == 2 || sc->sc_recal) { 381 um->um_tab.b_active = 1; 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 if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) { 424 if (rkecc(ui, ECC)) 425 return; 426 } else 427 um->um_tab.b_active = 0; 428 } 429 if (cs2&RKCS2_MDS) { 430 rkaddr->rkcs2 = RKCS2_SCLR; 431 goto retry; 432 } 433 recal = 0; 434 if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || 435 (um->um_tab.b_errcnt&07) == 4) 436 recal = 1; 437 rkaddr->rkcs1 = RK_CCLR; 438 rkaddr->rkcs2 = ui->ui_slave; 439 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 440 rkwait(rkaddr); 441 if (recal && um->um_tab.b_active == 0) { 442 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO; 443 rkcyl[ui->ui_unit] = -1; 444 sc->sc_recal = 0; 445 goto nextrecal; 446 } 447 } 448 retry: 449 switch (sc->sc_recal) { 450 451 case 1: 452 rkaddr->rkcyl = bp->b_cylin; 453 rkcyl[ui->ui_unit] = bp->b_cylin; 454 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 455 goto nextrecal; 456 case 2: 457 if (um->um_tab.b_errcnt < 16 || 458 (bp->b_flags&B_READ) == 0) 459 goto donerecal; 460 rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; 461 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO; 462 /* fall into ... */ 463 nextrecal: 464 sc->sc_recal++; 465 rkwait(rkaddr); 466 um->um_tab.b_active = 1; 467 return; 468 donerecal: 469 case 3: 470 sc->sc_recal = 0; 471 um->um_tab.b_active = 0; 472 break; 473 } 474 ubadone(um); 475 if (um->um_tab.b_active) { 476 um->um_tab.b_active = 0; 477 um->um_tab.b_errcnt = 0; 478 um->um_tab.b_actf = dp->b_forw; 479 dp->b_active = 0; 480 dp->b_errcnt = 0; 481 dp->b_actf = bp->av_forw; 482 bp->b_resid = -rkaddr->rkwc * sizeof(short); 483 iodone(bp); 484 if (dp->b_actf) 485 rkustart(ui); 486 } 487 as &= ~(1<<ui->ui_slave); 488 } 489 for (unit = 0; as; as >>= 1, unit++) 490 if (as & 1) { 491 ui = rkip[rk11][unit]; 492 if (ui) { 493 rkustart(rkip[rk11][unit]); 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 rkstart(um); 504 if (((needie = rkaddr->rkcs1) & RK_IE) == 0) 505 rkaddr->rkcs1 = RK_IE; 506 } 507 508 rkwait(addr) 509 register struct rkdevice *addr; 510 { 511 512 while ((addr->rkcs1 & RK_CRDY) == 0) 513 ; 514 } 515 516 rkread(dev) 517 dev_t dev; 518 { 519 register int unit = minor(dev) >> 3; 520 521 if (unit >= NRK) 522 u.u_error = ENXIO; 523 else 524 physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); 525 } 526 527 rkwrite(dev) 528 dev_t dev; 529 { 530 register int unit = minor(dev) >> 3; 531 532 if (unit >= NRK) 533 u.u_error = ENXIO; 534 else 535 physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); 536 } 537 538 rkecc(ui, flag) 539 register struct uba_device *ui; 540 { 541 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 542 register struct buf *bp = rkutab[ui->ui_unit].b_actf; 543 register struct uba_ctlr *um = ui->ui_mi; 544 register struct rkst *st; 545 struct uba_regs *ubp = ui->ui_hd->uh_uba; 546 caddr_t addr; 547 int reg, npf, o, cmd, ubaddr; 548 int bn, cn, tn, sn; 549 550 #ifndef NOBADSECT 551 if (flag == CONT) 552 npf = bp->b_error; 553 else 554 #endif 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 printf("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 #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 um->um_tab.b_active = 0; 630 return (0); 631 } 632 break; 633 #endif 634 } 635 rk->rkcs1 = RK_CCLR; 636 rk->rkcs2 = ui->ui_slave; 637 rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 638 rkwait(rk); 639 rk->rkcyl = cn; 640 rk->rkda = (tn << 8) | sn; 641 ubaddr = (int)ptob(reg) + o; 642 rk->rkba = ubaddr; 643 cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; 644 cmd |= (ubaddr >> 8) & 0x300; 645 cmd |= rktypes[ui->ui_type]; 646 rk->rkcs1 = cmd; 647 um->um_tab.b_active = 2; /* continuing */ 648 um->um_tab.b_errcnt = 0; /* error has been corrected */ 649 return (1); 650 } 651 652 rkreset(uban) 653 int uban; 654 { 655 register struct uba_ctlr *um; 656 register struct uba_device *ui; 657 register rk11, unit; 658 659 for (rk11 = 0; rk11 < NHK; rk11++) { 660 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 661 um->um_alive == 0) 662 continue; 663 printf(" hk%d", rk11); 664 um->um_tab.b_active = 0; 665 um->um_tab.b_actf = um->um_tab.b_actl = 0; 666 rk_softc[um->um_ctlr].sc_recal = 0; 667 rk_softc[um->um_ctlr].sc_wticks = 0; 668 if (um->um_ubinfo) { 669 printf("<%d>", (um->um_ubinfo>>28)&0xf); 670 ubadone(um); 671 } 672 for (unit = 0; unit < NRK; unit++) { 673 if ((ui = rkdinfo[unit]) == 0) 674 continue; 675 if (ui->ui_alive == 0 || ui->ui_mi != um) 676 continue; 677 rkutab[unit].b_active = 0; 678 (void) rkustart(ui); 679 } 680 (void) rkstart(um); 681 } 682 } 683 684 rkwatch() 685 { 686 register struct uba_ctlr *um; 687 register rk11, unit; 688 register struct rk_softc *sc; 689 690 timeout(rkwatch, (caddr_t)0, hz); 691 for (rk11 = 0; rk11 < NHK; rk11++) { 692 um = rkminfo[rk11]; 693 if (um == 0 || um->um_alive == 0) 694 continue; 695 sc = &rk_softc[rk11]; 696 if (um->um_tab.b_active == 0) { 697 for (unit = 0; unit < NRK; unit++) 698 if (rkutab[unit].b_active && 699 rkdinfo[unit]->ui_mi == um) 700 goto active; 701 sc->sc_wticks = 0; 702 continue; 703 } 704 active: 705 sc->sc_wticks++; 706 if (sc->sc_wticks >= 20) { 707 sc->sc_wticks = 0; 708 printf("hk%d: lost interrupt\n", rk11); 709 ubareset(um->um_ubanum); 710 } 711 } 712 } 713 714 #define DBSIZE 20 715 716 rkdump(dev) 717 dev_t dev; 718 { 719 struct rkdevice *rkaddr; 720 char *start; 721 int num, blk, unit; 722 struct size *sizes; 723 register struct uba_regs *uba; 724 register struct uba_device *ui; 725 register short *rp; 726 struct rkst *st; 727 728 unit = minor(dev) >> 3; 729 if (unit >= NRK) 730 return (ENXIO); 731 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 732 ui = phys(struct uba_device *, rkdinfo[unit]); 733 if (ui->ui_alive == 0) 734 return (ENXIO); 735 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 736 ubainit(uba); 737 rkaddr = (struct rkdevice *)ui->ui_physaddr; 738 num = maxfree; 739 start = 0; 740 rkaddr->rkcs1 = RK_CCLR; 741 rkaddr->rkcs2 = unit; 742 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 743 rkwait(rkaddr); 744 if ((rkaddr->rkds & RKDS_VV) == 0) { 745 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; 746 rkwait(rkaddr); 747 } 748 st = &rkst[ui->ui_type]; 749 sizes = phys(struct size *, st->sizes); 750 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 751 return (EINVAL); 752 while (num > 0) { 753 register struct pte *io; 754 register int i; 755 int cn, sn, tn; 756 daddr_t bn; 757 758 blk = num > DBSIZE ? DBSIZE : num; 759 io = uba->uba_map; 760 for (i = 0; i < blk; i++) 761 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 762 *(int *)io = 0; 763 bn = dumplo + btop(start); 764 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 765 sn = bn%st->nspc; 766 tn = sn/st->nsect; 767 sn = sn%st->nsect; 768 rkaddr->rkcyl = cn; 769 rp = (short *) &rkaddr->rkda; 770 *rp = (tn << 8) + sn; 771 *--rp = 0; 772 *--rp = -blk*NBPG / sizeof (short); 773 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; 774 rkwait(rkaddr); 775 if (rkaddr->rkcs1 & RK_CERR) 776 return (EIO); 777 start += blk*NBPG; 778 num -= blk; 779 } 780 return (0); 781 } 782 #endif 783