1 /* rk.c 4.39 82/03/29 */ 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 216 if (ui == 0) 217 return; 218 dk_busy &= ~(1<<ui->ui_dk); 219 dp = &rkutab[ui->ui_unit]; 220 um = ui->ui_mi; 221 rkaddr = (struct rkdevice *)um->um_addr; 222 if (um->um_tab.b_active) { 223 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 224 return; 225 } 226 if ((bp = dp->b_actf) == NULL) 227 return; 228 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; 229 rkaddr->rkcs2 = ui->ui_slave; 230 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 231 rkwait(rkaddr); 232 if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { 233 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 234 #ifndef NOBADSECT 235 struct rkst *st = &rkst[ui->ui_type]; 236 struct buf *bbp = &brkbuf[ui->ui_unit]; 237 #endif 238 239 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; 240 ui->ui_flags = 1; 241 #ifndef NOBADSECT 242 bbp->b_flags = B_READ|B_BUSY; 243 bbp->b_dev = bp->b_dev; 244 bbp->b_bcount = 512; 245 bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; 246 bbp->b_blkno = st->ncyl*st->nspc - st->nsect; 247 bbp->b_cylin = st->ncyl - 1; 248 dp->b_actf = bbp; 249 bbp->av_forw = bp; 250 bp = bbp; 251 #endif 252 rkwait(rkaddr); 253 } 254 if (dp->b_active) 255 goto done; 256 dp->b_active = 1; 257 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) 258 goto done; 259 if (rk_softc[um->um_ctlr].sc_ndrive == 1) 260 goto done; 261 if (bp->b_cylin == rkcyl[ui->ui_unit]) 262 goto done; 263 rkaddr->rkcyl = bp->b_cylin; 264 rkcyl[ui->ui_unit] = bp->b_cylin; 265 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 266 if (ui->ui_dk >= 0) { 267 dk_busy |= 1<<ui->ui_dk; 268 dk_seek[ui->ui_dk]++; 269 } 270 goto out; 271 done: 272 if (dp->b_active != 2) { 273 dp->b_forw = NULL; 274 if (um->um_tab.b_actf == NULL) 275 um->um_tab.b_actf = dp; 276 else 277 um->um_tab.b_actl->b_forw = dp; 278 um->um_tab.b_actl = dp; 279 dp->b_active = 2; 280 } 281 out: 282 return; 283 } 284 285 rkstart(um) 286 register struct uba_ctlr *um; 287 { 288 register struct buf *bp, *dp; 289 register struct uba_device *ui; 290 register struct rkdevice *rkaddr; 291 struct rkst *st; 292 daddr_t bn; 293 int sn, tn, cmd; 294 295 loop: 296 if ((dp = um->um_tab.b_actf) == NULL) 297 return; 298 if ((bp = dp->b_actf) == NULL) { 299 um->um_tab.b_actf = dp->b_forw; 300 goto loop; 301 } 302 um->um_tab.b_active++; 303 ui = rkdinfo[dkunit(bp)]; 304 bn = dkblock(bp); 305 st = &rkst[ui->ui_type]; 306 sn = bn%st->nspc; 307 tn = sn/st->nsect; 308 sn %= st->nsect; 309 rkaddr = (struct rkdevice *)ui->ui_addr; 310 retry: 311 rkaddr->rkcs1 = RK_CCLR; 312 rkaddr->rkcs2 = ui->ui_slave; 313 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 314 rkwait(rkaddr); 315 if ((rkaddr->rkds&RKDS_SVAL) == 0) { 316 rknosval++; 317 goto nosval; 318 } 319 if (rkaddr->rkds&RKDS_PIP) { 320 rkpip++; 321 goto retry; 322 } 323 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 324 printf("rk%d: not ready", dkunit(bp)); 325 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 326 printf("\n"); 327 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 328 rkwait(rkaddr); 329 rkaddr->rkcs1 = RK_CCLR; 330 rkwait(rkaddr); 331 um->um_tab.b_active = 0; 332 um->um_tab.b_errcnt = 0; 333 dp->b_actf = bp->av_forw; 334 dp->b_active = 0; 335 bp->b_flags |= B_ERROR; 336 iodone(bp); 337 goto loop; 338 } 339 printf(" (came back!)\n"); 340 } 341 nosval: 342 rkaddr->rkcyl = bp->b_cylin; 343 rkcyl[ui->ui_unit] = bp->b_cylin; 344 rkaddr->rkda = (tn << 8) + sn; 345 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 346 if (bp->b_flags & B_READ) 347 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; 348 else 349 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; 350 um->um_cmd = cmd; 351 (void) ubago(ui); 352 } 353 354 rkdgo(um) 355 register struct uba_ctlr *um; 356 { 357 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 358 359 um->um_tab.b_active++; /* should now be 2 */ 360 rkaddr->rkba = um->um_ubinfo; 361 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 362 } 363 364 rkintr(rk11) 365 int rk11; 366 { 367 register struct uba_ctlr *um = rkminfo[rk11]; 368 register struct uba_device *ui; 369 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 370 register struct buf *bp, *dp; 371 int unit; 372 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 373 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 374 int needie = 1; 375 376 sc->sc_wticks = 0; 377 sc->sc_softas = 0; 378 if (um->um_tab.b_active == 2 || sc->sc_recal) { 379 dp = um->um_tab.b_actf; 380 bp = dp->b_actf; 381 ui = rkdinfo[dkunit(bp)]; 382 dk_busy &= ~(1 << ui->ui_dk); 383 #ifndef NOBADSECT 384 if (bp->b_flags&B_BAD) 385 if (rkecc(ui, CONT)) 386 return; 387 #endif 388 if (rkaddr->rkcs1 & RK_CERR) { 389 int recal; 390 u_short ds = rkaddr->rkds; 391 u_short cs2 = rkaddr->rkcs2; 392 u_short er = rkaddr->rker; 393 #ifdef RKDEBUG 394 if (rkdebug) { 395 printf("cs2=%b ds=%b er=%b\n", 396 cs2, RKCS2_BITS, ds, 397 RKDS_BITS, er, RKER_BITS); 398 } 399 #endif 400 if (er & RKER_WLE) { 401 printf("rk%d: write locked\n", dkunit(bp)); 402 bp->b_flags |= B_ERROR; 403 } else if (++um->um_tab.b_errcnt > 28 || 404 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 405 hard: 406 harderr(bp, "rk"); 407 printf("cs2=%b ds=%b er=%b\n", 408 cs2, RKCS2_BITS, ds, 409 RKDS_BITS, er, RKER_BITS); 410 bp->b_flags |= B_ERROR; 411 sc->sc_recal = 0; 412 } else if (er & RKER_BSE) { 413 #ifndef NOBADSECT 414 if (rkecc(ui, BSE)) 415 return; 416 else 417 #endif 418 goto hard; 419 } else 420 um->um_tab.b_active = 0; 421 if (cs2&RKCS2_MDS) { 422 rkaddr->rkcs2 = RKCS2_SCLR; 423 goto retry; 424 } 425 recal = 0; 426 if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || 427 (um->um_tab.b_errcnt&07) == 4) 428 recal = 1; 429 if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) 430 if (rkecc(ui, ECC)) 431 return; 432 rkaddr->rkcs1 = RK_CCLR; 433 rkaddr->rkcs2 = ui->ui_slave; 434 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 435 rkwait(rkaddr); 436 if (recal && um->um_tab.b_active == 0) { 437 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO; 438 rkcyl[ui->ui_unit] = -1; 439 sc->sc_recal = 0; 440 goto nextrecal; 441 } 442 } 443 retry: 444 switch (sc->sc_recal) { 445 446 case 1: 447 rkaddr->rkcyl = bp->b_cylin; 448 rkcyl[ui->ui_unit] = bp->b_cylin; 449 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 450 goto nextrecal; 451 case 2: 452 if (um->um_tab.b_errcnt < 16 || 453 (bp->b_flags&B_READ) == 0) 454 goto donerecal; 455 rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; 456 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO; 457 /* fall into ... */ 458 nextrecal: 459 sc->sc_recal++; 460 rkwait(rkaddr); 461 um->um_tab.b_active = 1; 462 return; 463 donerecal: 464 case 3: 465 sc->sc_recal = 0; 466 um->um_tab.b_active = 0; 467 break; 468 } 469 ubadone(um); 470 if (um->um_tab.b_active) { 471 um->um_tab.b_active = 0; 472 um->um_tab.b_errcnt = 0; 473 um->um_tab.b_actf = dp->b_forw; 474 dp->b_active = 0; 475 dp->b_errcnt = 0; 476 dp->b_actf = bp->av_forw; 477 bp->b_resid = -rkaddr->rkwc * sizeof(short); 478 iodone(bp); 479 if (dp->b_actf) 480 rkustart(ui); 481 } 482 as &= ~(1<<ui->ui_slave); 483 } 484 for (unit = 0; as; as >>= 1, unit++) 485 if (as & 1) { 486 ui = rkip[rk11][unit]; 487 if (ui) { 488 rkustart(rkip[rk11][unit]); 489 } else { 490 rkaddr->rkcs1 = RK_CCLR; 491 rkaddr->rkcs2 = unit; 492 rkaddr->rkcs1 = RK_DCLR|RK_GO; 493 rkwait(rkaddr); 494 rkaddr->rkcs1 = RK_CCLR; 495 } 496 } 497 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 498 rkstart(um); 499 if (((needie = rkaddr->rkcs1) & RK_IE) == 0) 500 rkaddr->rkcs1 = RK_IE; 501 } 502 503 rkwait(addr) 504 register struct rkdevice *addr; 505 { 506 507 while ((addr->rkcs1 & RK_CRDY) == 0) 508 ; 509 } 510 511 rkread(dev) 512 dev_t dev; 513 { 514 register int unit = minor(dev) >> 3; 515 516 if (unit >= NRK) 517 u.u_error = ENXIO; 518 else 519 physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); 520 } 521 522 rkwrite(dev) 523 dev_t dev; 524 { 525 register int unit = minor(dev) >> 3; 526 527 if (unit >= NRK) 528 u.u_error = ENXIO; 529 else 530 physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); 531 } 532 533 rkecc(ui, flag) 534 register struct uba_device *ui; 535 { 536 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 537 register struct buf *bp = rkutab[ui->ui_unit].b_actf; 538 register struct uba_ctlr *um = ui->ui_mi; 539 register struct rkst *st; 540 struct uba_regs *ubp = ui->ui_hd->uh_uba; 541 caddr_t addr; 542 int reg, npf, o, cmd, ubaddr; 543 int bn, cn, tn, sn; 544 545 #ifndef NOBADSECT 546 if (flag == CONT) 547 npf = bp->b_error; 548 else 549 #endif 550 npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount); 551 reg = btop(um->um_ubinfo&0x3ffff) + npf; 552 o = (int)bp->b_un.b_addr & PGOFSET; 553 bn = dkblock(bp); 554 st = &rkst[ui->ui_type]; 555 cn = bp->b_cylin; 556 sn = bn%st->nspc + npf; 557 tn = sn/st->nsect; 558 sn %= st->nsect; 559 cn += tn/st->ntrak; 560 tn %= st->ntrak; 561 ubapurge(um); 562 um->um_tab.b_active = 2; /* Either complete or continuing... */ 563 switch (flag) { 564 case ECC: 565 { 566 register int i; 567 int bit, byte, mask; 568 569 npf--; 570 reg--; 571 printf("rk%d%c: soft ecc sn%d\n", dkunit(bp), 572 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 573 mask = rk->rkec2; 574 i = rk->rkec1 - 1; /* -1 makes 0 origin */ 575 bit = i&07; 576 i = (i&~07)>>3; 577 byte = i + o; 578 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 579 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 580 (byte & PGOFSET); 581 putmemc(addr, getmemc(addr)^(mask<<bit)); 582 byte++; 583 i++; 584 bit -= 8; 585 } 586 if (rk->rkwc == 0) 587 return (0); 588 npf++; 589 reg++; 590 break; 591 } 592 593 #ifndef NOBADSECT 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 rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short)); 622 if (rk->rkwc == 0) 623 return(0); 624 break; 625 #endif 626 } 627 rk->rkcs1 = RK_CCLR; 628 rk->rkcs2 = ui->ui_slave; 629 rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 630 rkwait(rk); 631 rk->rkcyl = cn; 632 rk->rkda = (tn << 8) | sn; 633 ubaddr = (int)ptob(reg) + o; 634 rk->rkba = ubaddr; 635 cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; 636 cmd |= (ubaddr >> 8) & 0x300; 637 cmd |= rktypes[ui->ui_type]; 638 rk->rkcs1 = cmd; 639 um->um_tab.b_errcnt = 0; /* error has been corrected */ 640 return (1); 641 } 642 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 ubadone(um); 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 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 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 = minor(dev) >> 3; 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 || dumplo + num >= sizes[minor(dev)&07].nblocks) 742 return (EINVAL); 743 while (num > 0) { 744 register struct pte *io; 745 register int i; 746 int cn, sn, tn; 747 daddr_t bn; 748 749 blk = num > DBSIZE ? DBSIZE : num; 750 io = uba->uba_map; 751 for (i = 0; i < blk; i++) 752 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 753 *(int *)io = 0; 754 bn = dumplo + btop(start); 755 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 756 sn = bn%st->nspc; 757 tn = sn/st->nsect; 758 sn = sn%st->nsect; 759 rkaddr->rkcyl = cn; 760 rp = (short *) &rkaddr->rkda; 761 *rp = (tn << 8) + sn; 762 *--rp = 0; 763 *--rp = -blk*NBPG / sizeof (short); 764 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; 765 rkwait(rkaddr); 766 if (rkaddr->rkcs1 & RK_CERR) 767 return (EIO); 768 start += blk*NBPG; 769 num -= blk; 770 } 771 return (0); 772 } 773 #endif 774