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