1 /* rk.c 4.38 82/01/17 */ 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 rkintr(0); 122 #endif 123 ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; 124 DELAY(10); 125 ((struct rkdevice *)reg)->rkcs1 = RK_CDT; 126 return (1); 127 } 128 129 rkslave(ui, reg) 130 struct uba_device *ui; 131 caddr_t reg; 132 { 133 register struct rkdevice *rkaddr = (struct rkdevice *)reg; 134 135 ui->ui_type = 0; 136 rkaddr->rkcs1 = RK_CCLR; 137 rkaddr->rkcs2 = ui->ui_slave; 138 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 139 rkwait(rkaddr); 140 DELAY(50); 141 if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) { 142 rkaddr->rkcs1 = RK_CCLR; 143 return (0); 144 } 145 if (rkaddr->rkcs1&RK_CERR && rkaddr->rker&RKER_DTYE) { 146 ui->ui_type = 1; 147 rkaddr->rkcs1 = RK_CCLR; 148 } 149 return (1); 150 } 151 152 rkattach(ui) 153 register struct uba_device *ui; 154 { 155 156 if (rkwstart == 0) { 157 timeout(rkwatch, (caddr_t)0, hz); 158 rkwstart++; 159 } 160 if (ui->ui_dk >= 0) 161 dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256); 162 rkip[ui->ui_ctlr][ui->ui_slave] = ui; 163 rk_softc[ui->ui_ctlr].sc_ndrive++; 164 rkcyl[ui->ui_unit] = -1; 165 ui->ui_flags = 0; 166 } 167 168 rkstrategy(bp) 169 register struct buf *bp; 170 { 171 register struct uba_device *ui; 172 register struct rkst *st; 173 register int unit; 174 register struct buf *dp; 175 int xunit = minor(bp->b_dev) & 07; 176 long bn, sz; 177 int s; 178 179 sz = (bp->b_bcount+511) >> 9; 180 unit = dkunit(bp); 181 if (unit >= NRK) 182 goto bad; 183 ui = rkdinfo[unit]; 184 if (ui == 0 || ui->ui_alive == 0) 185 goto bad; 186 st = &rkst[ui->ui_type]; 187 if (bp->b_blkno < 0 || 188 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 189 goto bad; 190 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 191 s = spl5(); 192 dp = &rkutab[ui->ui_unit]; 193 disksort(dp, bp); 194 if (dp->b_active == 0) { 195 (void) rkustart(ui); 196 bp = &ui->ui_mi->um_tab; 197 if (bp->b_actf && bp->b_active == 0) 198 (void) rkstart(ui->ui_mi); 199 } 200 splx(s); 201 return; 202 203 bad: 204 bp->b_flags |= B_ERROR; 205 iodone(bp); 206 return; 207 } 208 209 rkustart(ui) 210 register struct uba_device *ui; 211 { 212 register struct buf *bp, *dp; 213 register struct uba_ctlr *um; 214 register struct rkdevice *rkaddr; 215 int didie = 0; 216 217 if (ui == 0) 218 return (0); 219 dk_busy &= ~(1<<ui->ui_dk); 220 dp = &rkutab[ui->ui_unit]; 221 um = ui->ui_mi; 222 rkaddr = (struct rkdevice *)um->um_addr; 223 if (um->um_tab.b_active) { 224 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 225 return (0); 226 } 227 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; 228 rkaddr->rkcs2 = ui->ui_slave; 229 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 230 rkwait(rkaddr); 231 if ((bp = dp->b_actf) == NULL) { 232 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 233 rkwait(rkaddr); 234 return (0); 235 } 236 if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { 237 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 238 #ifndef NOBADSECT 239 struct rkst *st = &rkst[ui->ui_type]; 240 struct buf *bbp = &brkbuf[ui->ui_unit]; 241 #endif 242 243 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; 244 ui->ui_flags = 1; 245 #ifndef NOBADSECT 246 bbp->b_flags = B_READ|B_BUSY; 247 bbp->b_dev = bp->b_dev; 248 bbp->b_bcount = 512; 249 bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; 250 bbp->b_blkno = st->ncyl*st->nspc - st->nsect; 251 bbp->b_cylin = st->ncyl - 1; 252 dp->b_actf = bbp; 253 bbp->av_forw = bp; 254 bp = bbp; 255 #endif 256 rkwait(rkaddr); 257 } 258 if (dp->b_active) 259 goto done; 260 dp->b_active = 1; 261 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) 262 goto done; 263 if (rk_softc[um->um_ctlr].sc_ndrive == 1) 264 goto done; 265 if (bp->b_cylin == rkcyl[ui->ui_unit]) 266 goto done; 267 rkaddr->rkcyl = bp->b_cylin; 268 rkcyl[ui->ui_unit] = bp->b_cylin; 269 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 270 didie = 1; 271 if (ui->ui_dk >= 0) { 272 dk_busy |= 1<<ui->ui_dk; 273 dk_seek[ui->ui_dk]++; 274 } 275 goto out; 276 done: 277 if (dp->b_active != 2) { 278 dp->b_forw = NULL; 279 if (um->um_tab.b_actf == NULL) 280 um->um_tab.b_actf = dp; 281 else 282 um->um_tab.b_actl->b_forw = dp; 283 um->um_tab.b_actl = dp; 284 dp->b_active = 2; 285 } 286 out: 287 return (didie); 288 } 289 290 rkstart(um) 291 register struct uba_ctlr *um; 292 { 293 register struct buf *bp, *dp; 294 register struct uba_device *ui; 295 register struct rkdevice *rkaddr; 296 struct rkst *st; 297 daddr_t bn; 298 int sn, tn, cmd; 299 300 loop: 301 if ((dp = um->um_tab.b_actf) == NULL) 302 return (0); 303 if ((bp = dp->b_actf) == NULL) { 304 um->um_tab.b_actf = dp->b_forw; 305 goto loop; 306 } 307 um->um_tab.b_active++; 308 ui = rkdinfo[dkunit(bp)]; 309 bn = dkblock(bp); 310 st = &rkst[ui->ui_type]; 311 sn = bn%st->nspc; 312 tn = sn/st->nsect; 313 sn %= st->nsect; 314 rkaddr = (struct rkdevice *)ui->ui_addr; 315 retry: 316 rkaddr->rkcs1 = RK_CCLR; 317 rkaddr->rkcs2 = ui->ui_slave; 318 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 319 rkwait(rkaddr); 320 if ((rkaddr->rkds&RKDS_SVAL) == 0) { 321 rknosval++; 322 goto nosval; 323 } 324 if (rkaddr->rkds&RKDS_PIP) { 325 rkpip++; 326 goto retry; 327 } 328 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 329 printf("rk%d: not ready", dkunit(bp)); 330 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 331 printf("\n"); 332 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 333 rkwait(rkaddr); 334 rkaddr->rkcs1 = RK_CCLR; 335 rkwait(rkaddr); 336 um->um_tab.b_active = 0; 337 um->um_tab.b_errcnt = 0; 338 dp->b_actf = bp->av_forw; 339 dp->b_active = 0; 340 bp->b_flags |= B_ERROR; 341 iodone(bp); 342 goto loop; 343 } 344 printf(" (came back!)\n"); 345 } 346 nosval: 347 rkaddr->rkcyl = bp->b_cylin; 348 rkcyl[ui->ui_unit] = bp->b_cylin; 349 rkaddr->rkda = (tn << 8) + sn; 350 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 351 if (bp->b_flags & B_READ) 352 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; 353 else 354 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; 355 um->um_cmd = cmd; 356 (void) ubago(ui); 357 return (1); 358 } 359 360 rkdgo(um) 361 register struct uba_ctlr *um; 362 { 363 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 364 365 rkaddr->rkba = um->um_ubinfo; 366 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 367 } 368 369 rkintr(rk11) 370 int rk11; 371 { 372 register struct uba_ctlr *um = rkminfo[rk11]; 373 register struct uba_device *ui; 374 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 375 register struct buf *bp, *dp; 376 int unit; 377 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 378 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 379 int needie = 1; 380 381 sc->sc_wticks = 0; 382 sc->sc_softas = 0; 383 if (um->um_tab.b_active) { 384 dp = um->um_tab.b_actf; 385 bp = dp->b_actf; 386 ui = rkdinfo[dkunit(bp)]; 387 dk_busy &= ~(1 << ui->ui_dk); 388 #ifndef NOBADSECT 389 if (bp->b_flags&B_BAD) 390 if (rkecc(ui, CONT)) 391 return; 392 #endif 393 if (rkaddr->rkcs1 & RK_CERR) { 394 int recal; 395 u_short ds = rkaddr->rkds; 396 u_short cs2 = rkaddr->rkcs2; 397 u_short er = rkaddr->rker; 398 #ifdef RKDEBUG 399 if (rkdebug) { 400 printf("cs2=%b ds=%b er=%b\n", 401 cs2, RKCS2_BITS, ds, 402 RKDS_BITS, er, RKER_BITS); 403 } 404 #endif 405 if (er & RKER_WLE) { 406 printf("rk%d: write locked\n", dkunit(bp)); 407 bp->b_flags |= B_ERROR; 408 } else if (++um->um_tab.b_errcnt > 28 || 409 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 410 hard: 411 harderr(bp, "rk"); 412 printf("cs2=%b ds=%b er=%b\n", 413 cs2, RKCS2_BITS, ds, 414 RKDS_BITS, er, RKER_BITS); 415 bp->b_flags |= B_ERROR; 416 sc->sc_recal = 0; 417 } else if (er & RKER_BSE) { 418 #ifndef NOBADSECT 419 if (rkecc(ui, BSE)) 420 return; 421 else 422 #endif 423 goto hard; 424 } else 425 um->um_tab.b_active = 0; 426 if (cs2&RKCS2_MDS) { 427 rkaddr->rkcs2 = RKCS2_SCLR; 428 goto retry; 429 } 430 recal = 0; 431 if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || 432 (um->um_tab.b_errcnt&07) == 4) 433 recal = 1; 434 if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) 435 if (rkecc(ui, ECC)) 436 return; 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 if (rkustart(ui)) 486 needie = 0; 487 } 488 as &= ~(1<<ui->ui_slave); 489 } 490 for (unit = 0; as; as >>= 1, unit++) 491 if (as & 1) { 492 ui = rkip[rk11][unit]; 493 if (ui) { 494 if (rkustart(rkip[rk11][unit])) 495 needie = 0; 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 if (rkstart(um)) 506 needie = 0; 507 if (needie) 508 rkaddr->rkcs1 = RK_IE; 509 } 510 511 rkwait(addr) 512 register struct rkdevice *addr; 513 { 514 515 while ((addr->rkcs1 & RK_CRDY) == 0) 516 ; 517 } 518 519 rkread(dev) 520 dev_t dev; 521 { 522 register int unit = minor(dev) >> 3; 523 524 if (unit >= NRK) 525 u.u_error = ENXIO; 526 else 527 physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); 528 } 529 530 rkwrite(dev) 531 dev_t dev; 532 { 533 register int unit = minor(dev) >> 3; 534 535 if (unit >= NRK) 536 u.u_error = ENXIO; 537 else 538 physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); 539 } 540 541 rkecc(ui, flag) 542 register struct uba_device *ui; 543 { 544 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 545 register struct buf *bp = rkutab[ui->ui_unit].b_actf; 546 register struct uba_ctlr *um = ui->ui_mi; 547 register struct rkst *st; 548 struct uba_regs *ubp = ui->ui_hd->uh_uba; 549 caddr_t addr; 550 int reg, npf, o, cmd, ubaddr; 551 int bn, cn, tn, sn; 552 553 #ifndef NOBADSECT 554 if (flag == CONT) 555 npf = bp->b_error; 556 else 557 #endif 558 npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount); 559 reg = btop(um->um_ubinfo&0x3ffff) + npf; 560 o = (int)bp->b_un.b_addr & PGOFSET; 561 bn = dkblock(bp); 562 st = &rkst[ui->ui_type]; 563 cn = bp->b_cylin; 564 sn = bn%st->nspc + npf; 565 tn = sn/st->nsect; 566 sn %= st->nsect; 567 cn += tn/st->ntrak; 568 tn %= st->ntrak; 569 ubapurge(um); 570 um->um_tab.b_active++; /* Either complete or continuing... */ 571 switch (flag) { 572 case ECC: 573 { 574 register int i; 575 int bit, byte, mask; 576 577 npf--; 578 reg--; 579 printf("rk%d%c: soft ecc sn%d\n", dkunit(bp), 580 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 581 mask = rk->rkec2; 582 i = rk->rkec1 - 1; /* -1 makes 0 origin */ 583 bit = i&07; 584 i = (i&~07)>>3; 585 byte = i + o; 586 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 587 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 588 (byte & PGOFSET); 589 putmemc(addr, getmemc(addr)^(mask<<bit)); 590 byte++; 591 i++; 592 bit -= 8; 593 } 594 if (rk->rkwc == 0) 595 return (0); 596 npf++; 597 reg++; 598 break; 599 } 600 601 #ifndef NOBADSECT 602 case BSE: 603 #ifdef RKBDEBUG 604 if (rkbdebug) 605 printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 606 #endif 607 if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) 608 return(0); 609 bp->b_flags |= B_BAD; 610 bp->b_error = npf + 1; 611 bn = st->ncyl*st->nspc - st->nsect - 1 - bn; 612 cn = bn/st->nspc; 613 sn = bn%st->nspc; 614 tn = sn/st->nsect; 615 sn %= st->nsect; 616 #ifdef RKBDEBUG 617 if (rkbdebug) 618 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 619 #endif 620 rk->rkwc = -(512 / sizeof (short)); 621 break; 622 623 case CONT: 624 #ifdef RKBDEBUG 625 if (rkbdebug) 626 printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); 627 #endif 628 bp->b_flags &= ~B_BAD; 629 rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short)); 630 if (rk->rkwc == 0) 631 return(0); 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_errcnt = 0; /* error has been corrected */ 648 return (1); 649 } 650 651 rkreset(uban) 652 int uban; 653 { 654 register struct uba_ctlr *um; 655 register struct uba_device *ui; 656 register rk11, unit; 657 658 for (rk11 = 0; rk11 < NHK; rk11++) { 659 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 660 um->um_alive == 0) 661 continue; 662 printf(" hk%d", rk11); 663 um->um_tab.b_active = 0; 664 um->um_tab.b_actf = um->um_tab.b_actl = 0; 665 rk_softc[um->um_ctlr].sc_recal = 0; 666 if (um->um_ubinfo) { 667 printf("<%d>", (um->um_ubinfo>>28)&0xf); 668 ubadone(um); 669 } 670 for (unit = 0; unit < NRK; unit++) { 671 if ((ui = rkdinfo[unit]) == 0) 672 continue; 673 if (ui->ui_alive == 0 || ui->ui_mi != um) 674 continue; 675 rkutab[unit].b_active = 0; 676 (void) rkustart(ui); 677 } 678 (void) rkstart(um); 679 } 680 } 681 682 rkwatch() 683 { 684 register struct uba_ctlr *um; 685 register rk11, unit; 686 register struct rk_softc *sc; 687 688 timeout(rkwatch, (caddr_t)0, hz); 689 for (rk11 = 0; rk11 < NHK; rk11++) { 690 um = rkminfo[rk11]; 691 if (um == 0 || um->um_alive == 0) 692 continue; 693 sc = &rk_softc[rk11]; 694 if (um->um_tab.b_active == 0) { 695 for (unit = 0; unit < NRK; unit++) 696 if (rkutab[unit].b_active && 697 rkdinfo[unit]->ui_mi == um) 698 goto active; 699 sc->sc_wticks = 0; 700 continue; 701 } 702 active: 703 sc->sc_wticks++; 704 if (sc->sc_wticks >= 20) { 705 sc->sc_wticks = 0; 706 printf("hk%d: lost interrupt\n", rk11); 707 ubareset(um->um_ubanum); 708 } 709 } 710 } 711 712 #define DBSIZE 20 713 714 rkdump(dev) 715 dev_t dev; 716 { 717 struct rkdevice *rkaddr; 718 char *start; 719 int num, blk, unit; 720 struct size *sizes; 721 register struct uba_regs *uba; 722 register struct uba_device *ui; 723 register short *rp; 724 struct rkst *st; 725 726 unit = minor(dev) >> 3; 727 if (unit >= NRK) 728 return (ENXIO); 729 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 730 ui = phys(struct uba_device *, rkdinfo[unit]); 731 if (ui->ui_alive == 0) 732 return (ENXIO); 733 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 734 ubainit(uba); 735 rkaddr = (struct rkdevice *)ui->ui_physaddr; 736 num = maxfree; 737 start = 0; 738 rkaddr->rkcs1 = RK_CCLR; 739 rkaddr->rkcs2 = unit; 740 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 741 rkwait(rkaddr); 742 if ((rkaddr->rkds & RKDS_VV) == 0) { 743 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; 744 rkwait(rkaddr); 745 } 746 st = &rkst[ui->ui_type]; 747 sizes = phys(struct size *, st->sizes); 748 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 749 return (EINVAL); 750 while (num > 0) { 751 register struct pte *io; 752 register int i; 753 int cn, sn, tn; 754 daddr_t bn; 755 756 blk = num > DBSIZE ? DBSIZE : num; 757 io = uba->uba_map; 758 for (i = 0; i < blk; i++) 759 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 760 *(int *)io = 0; 761 bn = dumplo + btop(start); 762 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 763 sn = bn%st->nspc; 764 tn = sn/st->nsect; 765 sn = sn%st->nsect; 766 rkaddr->rkcyl = cn; 767 rp = (short *) &rkaddr->rkda; 768 *rp = (tn << 8) + sn; 769 *--rp = 0; 770 *--rp = -blk*NBPG / sizeof (short); 771 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; 772 rkwait(rkaddr); 773 if (rkaddr->rkcs1 & RK_CERR) 774 return (EIO); 775 start += blk*NBPG; 776 num -= blk; 777 } 778 return (0); 779 } 780 #endif 781