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