1 /* rk.c 4.54 83/05/18 */ 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 "../machine/pte.h" 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/map.h" 30 #include "../h/vm.h" 31 #include "../h/dk.h" 32 #include "../h/cmap.h" 33 #include "../h/dkbad.h" 34 #include "../h/uio.h" 35 #include "../h/kernel.h" 36 37 #include "../vax/cpu.h" 38 #include "../vaxuba/ubareg.h" 39 #include "../vaxuba/ubavar.h" 40 #include "../vaxuba/rkreg.h" 41 42 struct rk_softc { 43 int sc_softas; 44 int sc_ndrive; 45 int sc_wticks; 46 int sc_recal; 47 } rk_softc[NHK]; 48 49 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 50 struct size { 51 daddr_t nblocks; 52 int cyloff; 53 } rk7_sizes[8] ={ 54 15884, 0, /* A=cyl 0 thru 240 */ 55 10032, 241, /* B=cyl 241 thru 392 */ 56 53790, 0, /* C=cyl 0 thru 814 */ 57 0, 0, 58 0, 0, 59 0, 0, 60 27786, 393, /* G=cyl 393 thru 813 */ 61 0, 0, 62 }, rk6_sizes[8] ={ 63 15884, 0, /* A=cyl 0 thru 240 */ 64 11154, 241, /* B=cyl 241 thru 409 */ 65 27126, 0, /* C=cyl 0 thru 410 */ 66 0, 0, 67 0, 0, 68 0, 0, 69 0, 0, 70 0, 0, 71 }; 72 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 73 74 short rktypes[] = { RK_CDT, 0 }; 75 76 int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); 77 struct uba_ctlr *rkminfo[NHK]; 78 struct uba_device *rkdinfo[NRK]; 79 struct uba_device *rkip[NHK][4]; 80 81 u_short rkstd[] = { 0777440, 0 }; 82 struct uba_driver hkdriver = 83 { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; 84 struct buf rkutab[NRK]; 85 short rkcyl[NRK]; 86 struct dkbad rkbad[NRK]; 87 struct buf brkbuf[NRK]; 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 rkopen(dev) 170 dev_t dev; 171 { 172 register int unit = minor(dev) >> 3; 173 register struct uba_device *ui; 174 175 if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) 176 return (ENXIO); 177 return (0); 178 } 179 180 rkstrategy(bp) 181 register struct buf *bp; 182 { 183 register struct uba_device *ui; 184 register struct rkst *st; 185 register int unit; 186 register struct buf *dp; 187 int xunit = minor(bp->b_dev) & 07; 188 long bn, sz; 189 int s; 190 191 sz = (bp->b_bcount+511) >> 9; 192 unit = dkunit(bp); 193 if (unit >= NRK) 194 goto bad; 195 ui = rkdinfo[unit]; 196 if (ui == 0 || ui->ui_alive == 0) 197 goto bad; 198 st = &rkst[ui->ui_type]; 199 if (bp->b_blkno < 0 || 200 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 201 goto bad; 202 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 203 s = spl5(); 204 dp = &rkutab[ui->ui_unit]; 205 disksort(dp, bp); 206 if (dp->b_active == 0) { 207 (void) rkustart(ui); 208 bp = &ui->ui_mi->um_tab; 209 if (bp->b_actf && bp->b_active == 0) 210 (void) rkstart(ui->ui_mi); 211 } 212 splx(s); 213 return; 214 215 bad: 216 bp->b_flags |= B_ERROR; 217 iodone(bp); 218 return; 219 } 220 221 rkustart(ui) 222 register struct uba_device *ui; 223 { 224 register struct buf *bp, *dp; 225 register struct uba_ctlr *um; 226 register struct rkdevice *rkaddr; 227 228 if (ui == 0) 229 return; 230 dk_busy &= ~(1<<ui->ui_dk); 231 dp = &rkutab[ui->ui_unit]; 232 um = ui->ui_mi; 233 rkaddr = (struct rkdevice *)um->um_addr; 234 if (um->um_tab.b_active) { 235 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 236 return; 237 } 238 if ((bp = dp->b_actf) == NULL) 239 return; 240 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; 241 rkaddr->rkcs2 = ui->ui_slave; 242 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 243 rkwait(rkaddr); 244 if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { 245 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 246 struct rkst *st = &rkst[ui->ui_type]; 247 struct buf *bbp = &brkbuf[ui->ui_unit]; 248 249 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; 250 ui->ui_flags = 1; 251 bbp->b_flags = B_READ|B_BUSY; 252 bbp->b_dev = bp->b_dev; 253 bbp->b_bcount = 512; 254 bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; 255 bbp->b_blkno = st->ncyl*st->nspc - st->nsect; 256 bbp->b_cylin = st->ncyl - 1; 257 dp->b_actf = bbp; 258 bbp->av_forw = bp; 259 bp = bbp; 260 rkwait(rkaddr); 261 } 262 if (dp->b_active) 263 goto done; 264 dp->b_active = 1; 265 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) 266 goto done; 267 if (rk_softc[um->um_ctlr].sc_ndrive == 1) 268 goto done; 269 if (bp->b_cylin == rkcyl[ui->ui_unit]) 270 goto done; 271 rkaddr->rkcyl = bp->b_cylin; 272 rkcyl[ui->ui_unit] = bp->b_cylin; 273 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 274 if (ui->ui_dk >= 0) { 275 dk_busy |= 1<<ui->ui_dk; 276 dk_seek[ui->ui_dk]++; 277 } 278 goto out; 279 done: 280 if (dp->b_active != 2) { 281 dp->b_forw = NULL; 282 if (um->um_tab.b_actf == NULL) 283 um->um_tab.b_actf = dp; 284 else 285 um->um_tab.b_actl->b_forw = dp; 286 um->um_tab.b_actl = dp; 287 dp->b_active = 2; 288 } 289 out: 290 return; 291 } 292 293 rkstart(um) 294 register struct uba_ctlr *um; 295 { 296 register struct buf *bp, *dp; 297 register struct uba_device *ui; 298 register struct rkdevice *rkaddr; 299 struct rkst *st; 300 daddr_t bn; 301 int sn, tn, cmd; 302 303 loop: 304 if ((dp = um->um_tab.b_actf) == NULL) 305 return; 306 if ((bp = dp->b_actf) == NULL) { 307 um->um_tab.b_actf = dp->b_forw; 308 goto loop; 309 } 310 um->um_tab.b_active++; 311 ui = rkdinfo[dkunit(bp)]; 312 bn = dkblock(bp); 313 st = &rkst[ui->ui_type]; 314 sn = bn%st->nspc; 315 tn = sn/st->nsect; 316 sn %= st->nsect; 317 rkaddr = (struct rkdevice *)ui->ui_addr; 318 retry: 319 rkaddr->rkcs1 = RK_CCLR; 320 rkaddr->rkcs2 = ui->ui_slave; 321 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 322 rkwait(rkaddr); 323 if ((rkaddr->rkds&RKDS_SVAL) == 0) { 324 rknosval++; 325 goto nosval; 326 } 327 if (rkaddr->rkds&RKDS_PIP) { 328 rkpip++; 329 goto retry; 330 } 331 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 332 printf("rk%d: not ready", dkunit(bp)); 333 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 334 printf("\n"); 335 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 336 rkwait(rkaddr); 337 rkaddr->rkcs1 = RK_CCLR; 338 rkwait(rkaddr); 339 um->um_tab.b_active = 0; 340 um->um_tab.b_errcnt = 0; 341 dp->b_actf = bp->av_forw; 342 dp->b_active = 0; 343 bp->b_flags |= B_ERROR; 344 iodone(bp); 345 goto loop; 346 } 347 printf(" (came back!)\n"); 348 } 349 nosval: 350 rkaddr->rkcyl = bp->b_cylin; 351 rkcyl[ui->ui_unit] = bp->b_cylin; 352 rkaddr->rkda = (tn << 8) + sn; 353 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 354 if (bp->b_flags & B_READ) 355 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; 356 else 357 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; 358 um->um_cmd = cmd; 359 (void) ubago(ui); 360 } 361 362 rkdgo(um) 363 register struct uba_ctlr *um; 364 { 365 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 366 367 um->um_tab.b_active = 2; /* should now be 2 */ 368 rkaddr->rkba = um->um_ubinfo; 369 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 370 } 371 372 rkintr(rk11) 373 int rk11; 374 { 375 register struct uba_ctlr *um = rkminfo[rk11]; 376 register struct uba_device *ui; 377 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 378 register struct buf *bp, *dp; 379 int unit; 380 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 381 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 382 383 sc->sc_wticks = 0; 384 sc->sc_softas = 0; 385 if (um->um_tab.b_active == 2 || sc->sc_recal) { 386 um->um_tab.b_active = 1; 387 dp = um->um_tab.b_actf; 388 bp = dp->b_actf; 389 ui = rkdinfo[dkunit(bp)]; 390 dk_busy &= ~(1 << ui->ui_dk); 391 if (bp->b_flags&B_BAD) 392 if (rkecc(ui, CONT)) 393 return; 394 if (rkaddr->rkcs1 & RK_CERR) { 395 int recal; 396 u_short ds = rkaddr->rkds; 397 u_short cs2 = rkaddr->rkcs2; 398 u_short er = rkaddr->rker; 399 #ifdef RKDEBUG 400 if (rkdebug) { 401 printf("cs2=%b ds=%b er=%b\n", 402 cs2, RKCS2_BITS, ds, 403 RKDS_BITS, er, RKER_BITS); 404 } 405 #endif 406 if (er & RKER_WLE) { 407 printf("rk%d: write locked\n", dkunit(bp)); 408 bp->b_flags |= B_ERROR; 409 } else if (++um->um_tab.b_errcnt > 28 || 410 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 411 hard: 412 harderr(bp, "rk"); 413 printf("cs2=%b ds=%b er=%b\n", 414 cs2, RKCS2_BITS, ds, 415 RKDS_BITS, er, RKER_BITS); 416 bp->b_flags |= B_ERROR; 417 sc->sc_recal = 0; 418 } else if (er & RKER_BSE) { 419 if (rkecc(ui, BSE)) 420 return; 421 else 422 goto hard; 423 } else { 424 if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) { 425 if (rkecc(ui, ECC)) 426 return; 427 } else 428 um->um_tab.b_active = 0; 429 } 430 if (cs2&RKCS2_MDS) { 431 rkaddr->rkcs2 = RKCS2_SCLR; 432 goto retry; 433 } 434 recal = 0; 435 if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || 436 (um->um_tab.b_errcnt&07) == 4) 437 recal = 1; 438 rkaddr->rkcs1 = RK_CCLR; 439 rkaddr->rkcs2 = ui->ui_slave; 440 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 441 rkwait(rkaddr); 442 if (recal && um->um_tab.b_active == 0) { 443 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO; 444 rkcyl[ui->ui_unit] = -1; 445 sc->sc_recal = 0; 446 goto nextrecal; 447 } 448 } 449 retry: 450 switch (sc->sc_recal) { 451 452 case 1: 453 rkaddr->rkcyl = bp->b_cylin; 454 rkcyl[ui->ui_unit] = bp->b_cylin; 455 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 456 goto nextrecal; 457 case 2: 458 if (um->um_tab.b_errcnt < 16 || 459 (bp->b_flags&B_READ) == 0) 460 goto donerecal; 461 rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; 462 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO; 463 /* fall into ... */ 464 nextrecal: 465 sc->sc_recal++; 466 rkwait(rkaddr); 467 um->um_tab.b_active = 1; 468 return; 469 donerecal: 470 case 3: 471 sc->sc_recal = 0; 472 um->um_tab.b_active = 0; 473 break; 474 } 475 ubadone(um); 476 if (um->um_tab.b_active) { 477 um->um_tab.b_active = 0; 478 um->um_tab.b_errcnt = 0; 479 um->um_tab.b_actf = dp->b_forw; 480 dp->b_active = 0; 481 dp->b_errcnt = 0; 482 dp->b_actf = bp->av_forw; 483 bp->b_resid = -rkaddr->rkwc * sizeof(short); 484 iodone(bp); 485 if (dp->b_actf) 486 rkustart(ui); 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 rkustart(rkip[rk11][unit]); 495 } else { 496 rkaddr->rkcs1 = RK_CCLR; 497 rkaddr->rkcs2 = unit; 498 rkaddr->rkcs1 = RK_DCLR|RK_GO; 499 rkwait(rkaddr); 500 rkaddr->rkcs1 = RK_CCLR; 501 } 502 } 503 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 504 rkstart(um); 505 if (((rkaddr->rkcs1) & RK_IE) == 0) 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, uio) 518 dev_t dev; 519 struct uio *uio; 520 { 521 register int unit = minor(dev) >> 3; 522 523 if (unit >= NRK) 524 return (ENXIO); 525 return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio)); 526 } 527 528 rkwrite(dev, uio) 529 dev_t dev; 530 struct uio *uio; 531 { 532 register int unit = minor(dev) >> 3; 533 534 if (unit >= NRK) 535 return (ENXIO); 536 return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio)); 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 if (flag == CONT) 552 npf = bp->b_error; 553 else 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 case BSE: 599 #ifdef RKBDEBUG 600 if (rkbdebug) 601 printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 602 #endif 603 if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) 604 return(0); 605 bp->b_flags |= B_BAD; 606 bp->b_error = npf + 1; 607 bn = st->ncyl*st->nspc - st->nsect - 1 - bn; 608 cn = bn/st->nspc; 609 sn = bn%st->nspc; 610 tn = sn/st->nsect; 611 sn %= st->nsect; 612 #ifdef RKBDEBUG 613 if (rkbdebug) 614 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 615 #endif 616 rk->rkwc = -(512 / sizeof (short)); 617 break; 618 619 case CONT: 620 #ifdef RKBDEBUG 621 if (rkbdebug) 622 printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); 623 #endif 624 bp->b_flags &= ~B_BAD; 625 rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short)); 626 if (rk->rkwc == 0) { 627 um->um_tab.b_active = 0; 628 return (0); 629 } 630 break; 631 } 632 rk->rkcs1 = RK_CCLR; 633 rk->rkcs2 = ui->ui_slave; 634 rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 635 rkwait(rk); 636 rk->rkcyl = cn; 637 rk->rkda = (tn << 8) | sn; 638 ubaddr = (int)ptob(reg) + o; 639 rk->rkba = ubaddr; 640 cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; 641 cmd |= (ubaddr >> 8) & 0x300; 642 cmd |= rktypes[ui->ui_type]; 643 rk->rkcs1 = cmd; 644 um->um_tab.b_active = 2; /* continuing */ 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 rk_softc[um->um_ctlr].sc_wticks = 0; 665 if (um->um_ubinfo) { 666 printf("<%d>", (um->um_ubinfo>>28)&0xf); 667 um->um_ubinfo = 0; 668 } 669 for (unit = 0; unit < NRK; unit++) { 670 if ((ui = rkdinfo[unit]) == 0) 671 continue; 672 if (ui->ui_alive == 0 || ui->ui_mi != um) 673 continue; 674 rkutab[unit].b_active = 0; 675 (void) rkustart(ui); 676 } 677 (void) rkstart(um); 678 } 679 } 680 681 rkwatch() 682 { 683 register struct uba_ctlr *um; 684 register rk11, unit; 685 register struct rk_softc *sc; 686 687 timeout(rkwatch, (caddr_t)0, hz); 688 for (rk11 = 0; rk11 < NHK; rk11++) { 689 um = rkminfo[rk11]; 690 if (um == 0 || um->um_alive == 0) 691 continue; 692 sc = &rk_softc[rk11]; 693 if (um->um_tab.b_active == 0) { 694 for (unit = 0; unit < NRK; unit++) 695 if (rkutab[unit].b_active && 696 rkdinfo[unit]->ui_mi == um) 697 goto active; 698 sc->sc_wticks = 0; 699 continue; 700 } 701 active: 702 sc->sc_wticks++; 703 if (sc->sc_wticks >= 20) { 704 sc->sc_wticks = 0; 705 printf("hk%d: lost interrupt\n", rk11); 706 ubareset(um->um_ubanum); 707 } 708 } 709 } 710 711 #define DBSIZE 20 712 713 rkdump(dev) 714 dev_t dev; 715 { 716 struct rkdevice *rkaddr; 717 char *start; 718 int num, blk, unit; 719 struct size *sizes; 720 register struct uba_regs *uba; 721 register struct uba_device *ui; 722 register short *rp; 723 struct rkst *st; 724 725 unit = minor(dev) >> 3; 726 if (unit >= NRK) 727 return (ENXIO); 728 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 729 ui = phys(struct uba_device *, rkdinfo[unit]); 730 if (ui->ui_alive == 0) 731 return (ENXIO); 732 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 733 ubainit(uba); 734 rkaddr = (struct rkdevice *)ui->ui_physaddr; 735 num = maxfree; 736 start = 0; 737 rkaddr->rkcs1 = RK_CCLR; 738 rkaddr->rkcs2 = unit; 739 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 740 rkwait(rkaddr); 741 if ((rkaddr->rkds & RKDS_VV) == 0) { 742 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; 743 rkwait(rkaddr); 744 } 745 st = &rkst[ui->ui_type]; 746 sizes = phys(struct size *, st->sizes); 747 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 748 return (EINVAL); 749 while (num > 0) { 750 register struct pte *io; 751 register int i; 752 int cn, sn, tn; 753 daddr_t bn; 754 755 blk = num > DBSIZE ? DBSIZE : num; 756 io = uba->uba_map; 757 for (i = 0; i < blk; i++) 758 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 759 *(int *)io = 0; 760 bn = dumplo + btop(start); 761 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 762 sn = bn%st->nspc; 763 tn = sn/st->nsect; 764 sn = sn%st->nsect; 765 rkaddr->rkcyl = cn; 766 rp = (short *) &rkaddr->rkda; 767 *rp = (tn << 8) + sn; 768 *--rp = 0; 769 *--rp = -blk*NBPG / sizeof (short); 770 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; 771 rkwait(rkaddr); 772 if (rkaddr->rkcs1 & RK_CERR) 773 return (EIO); 774 start += blk*NBPG; 775 num -= blk; 776 } 777 return (0); 778 } 779 780 rksize(dev) 781 dev_t dev; 782 { 783 int unit = minor(dev) >> 3; 784 struct uba_device *ui; 785 struct rkst *st; 786 787 if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) 788 return (-1); 789 st = &rkst[ui->ui_type]; 790 return (st->sizes[minor(dev) & 07].nblocks); 791 } 792 #endif 793