1 #define RKDEBUG 2 #define RKBDEBUG 3 /* rk.c 4.44 82/08/22 */ 4 5 #include "rk.h" 6 #if NHK > 0 7 int rkpip; /* DEBUG */ 8 int rknosval; /* DEBUG */ 9 #ifdef RKDEBUG 10 int rkdebug; 11 #endif 12 #ifdef RKBDEBUG 13 int rkbdebug; 14 #endif 15 /* 16 * RK611/RK0[67] disk driver 17 * 18 * This driver mimics up.c; see it for an explanation of common code. 19 * 20 * TODO: 21 * Learn why we lose an interrupt sometime when spinning drives down 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/pte.h" 30 #include "../h/map.h" 31 #include "../h/vm.h" 32 #include "../h/ubareg.h" 33 #include "../h/ubavar.h" 34 #include "../h/dk.h" 35 #include "../h/cpu.h" 36 #include "../h/cmap.h" 37 #include "../h/dkbad.h" 38 #include "../h/uio.h" 39 40 #include "../h/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 #ifndef NOBADSECT 87 struct dkbad rkbad[NRK]; 88 struct buf brkbuf[NRK]; 89 #endif 90 91 struct rkst { 92 short nsect; 93 short ntrak; 94 short nspc; 95 short ncyl; 96 struct size *sizes; 97 } rkst[] = { 98 NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, 99 NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes, 100 }; 101 102 u_char rk_offset[16] = 103 { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800, 104 RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0 105 }; 106 107 struct buf rrkbuf[NRK]; 108 109 #define b_cylin b_resid 110 111 #ifdef INTRLVE 112 daddr_t dkblock(); 113 #endif 114 115 int rkwstart, rkwatch(); 116 117 rkprobe(reg) 118 caddr_t reg; 119 { 120 register int br, cvec; 121 122 #ifdef lint 123 br = 0; cvec = br; br = cvec; 124 rkintr(0); 125 #endif 126 ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; 127 DELAY(10); 128 ((struct rkdevice *)reg)->rkcs1 = RK_CDT; 129 return (sizeof (struct rkdevice)); 130 } 131 132 rkslave(ui, reg) 133 struct uba_device *ui; 134 caddr_t reg; 135 { 136 register struct rkdevice *rkaddr = (struct rkdevice *)reg; 137 138 ui->ui_type = 0; 139 rkaddr->rkcs1 = RK_CCLR; 140 rkaddr->rkcs2 = ui->ui_slave; 141 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 142 rkwait(rkaddr); 143 DELAY(50); 144 if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) { 145 rkaddr->rkcs1 = RK_CCLR; 146 return (0); 147 } 148 if (rkaddr->rkcs1&RK_CERR && rkaddr->rker&RKER_DTYE) { 149 ui->ui_type = 1; 150 rkaddr->rkcs1 = RK_CCLR; 151 } 152 return (1); 153 } 154 155 rkattach(ui) 156 register struct uba_device *ui; 157 { 158 159 if (rkwstart == 0) { 160 timeout(rkwatch, (caddr_t)0, hz); 161 rkwstart++; 162 } 163 if (ui->ui_dk >= 0) 164 dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256); 165 rkip[ui->ui_ctlr][ui->ui_slave] = ui; 166 rk_softc[ui->ui_ctlr].sc_ndrive++; 167 rkcyl[ui->ui_unit] = -1; 168 ui->ui_flags = 0; 169 } 170 171 rkstrategy(bp) 172 register struct buf *bp; 173 { 174 register struct uba_device *ui; 175 register struct rkst *st; 176 register int unit; 177 register struct buf *dp; 178 int xunit = minor(bp->b_dev) & 07; 179 long bn, sz; 180 int s; 181 182 sz = (bp->b_bcount+511) >> 9; 183 unit = dkunit(bp); 184 if (unit >= NRK) 185 goto bad; 186 ui = rkdinfo[unit]; 187 if (ui == 0 || ui->ui_alive == 0) 188 goto bad; 189 st = &rkst[ui->ui_type]; 190 if (bp->b_blkno < 0 || 191 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 192 goto bad; 193 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 194 s = spl5(); 195 dp = &rkutab[ui->ui_unit]; 196 disksort(dp, bp); 197 if (dp->b_active == 0) { 198 (void) rkustart(ui); 199 bp = &ui->ui_mi->um_tab; 200 if (bp->b_actf && bp->b_active == 0) 201 (void) rkstart(ui->ui_mi); 202 } 203 splx(s); 204 return; 205 206 bad: 207 bp->b_flags |= B_ERROR; 208 iodone(bp); 209 return; 210 } 211 212 rkustart(ui) 213 register struct uba_device *ui; 214 { 215 register struct buf *bp, *dp; 216 register struct uba_ctlr *um; 217 register struct rkdevice *rkaddr; 218 219 if (ui == 0) 220 return; 221 dk_busy &= ~(1<<ui->ui_dk); 222 dp = &rkutab[ui->ui_unit]; 223 um = ui->ui_mi; 224 rkaddr = (struct rkdevice *)um->um_addr; 225 if (um->um_tab.b_active) { 226 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 227 return; 228 } 229 if ((bp = dp->b_actf) == NULL) 230 return; 231 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; 232 rkaddr->rkcs2 = ui->ui_slave; 233 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 234 rkwait(rkaddr); 235 if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { 236 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 237 #ifndef NOBADSECT 238 struct rkst *st = &rkst[ui->ui_type]; 239 struct buf *bbp = &brkbuf[ui->ui_unit]; 240 #endif 241 242 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; 243 ui->ui_flags = 1; 244 #ifndef NOBADSECT 245 bbp->b_flags = B_READ|B_BUSY; 246 bbp->b_dev = bp->b_dev; 247 bbp->b_bcount = 512; 248 bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; 249 bbp->b_blkno = st->ncyl*st->nspc - st->nsect; 250 bbp->b_cylin = st->ncyl - 1; 251 dp->b_actf = bbp; 252 bbp->av_forw = bp; 253 bp = bbp; 254 #endif 255 rkwait(rkaddr); 256 } 257 if (dp->b_active) 258 goto done; 259 dp->b_active = 1; 260 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) 261 goto done; 262 if (rk_softc[um->um_ctlr].sc_ndrive == 1) 263 goto done; 264 if (bp->b_cylin == rkcyl[ui->ui_unit]) 265 goto done; 266 rkaddr->rkcyl = bp->b_cylin; 267 rkcyl[ui->ui_unit] = bp->b_cylin; 268 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 269 if (ui->ui_dk >= 0) { 270 dk_busy |= 1<<ui->ui_dk; 271 dk_seek[ui->ui_dk]++; 272 } 273 goto out; 274 done: 275 if (dp->b_active != 2) { 276 dp->b_forw = NULL; 277 if (um->um_tab.b_actf == NULL) 278 um->um_tab.b_actf = dp; 279 else 280 um->um_tab.b_actl->b_forw = dp; 281 um->um_tab.b_actl = dp; 282 dp->b_active = 2; 283 } 284 out: 285 return; 286 } 287 288 rkstart(um) 289 register struct uba_ctlr *um; 290 { 291 register struct buf *bp, *dp; 292 register struct uba_device *ui; 293 register struct rkdevice *rkaddr; 294 struct rkst *st; 295 daddr_t bn; 296 int sn, tn, cmd; 297 298 loop: 299 if ((dp = um->um_tab.b_actf) == NULL) 300 return; 301 if ((bp = dp->b_actf) == NULL) { 302 um->um_tab.b_actf = dp->b_forw; 303 goto loop; 304 } 305 um->um_tab.b_active++; 306 ui = rkdinfo[dkunit(bp)]; 307 bn = dkblock(bp); 308 st = &rkst[ui->ui_type]; 309 sn = bn%st->nspc; 310 tn = sn/st->nsect; 311 sn %= st->nsect; 312 rkaddr = (struct rkdevice *)ui->ui_addr; 313 retry: 314 rkaddr->rkcs1 = RK_CCLR; 315 rkaddr->rkcs2 = ui->ui_slave; 316 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 317 rkwait(rkaddr); 318 if ((rkaddr->rkds&RKDS_SVAL) == 0) { 319 rknosval++; 320 goto nosval; 321 } 322 if (rkaddr->rkds&RKDS_PIP) { 323 rkpip++; 324 goto retry; 325 } 326 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 327 printf("rk%d: not ready", dkunit(bp)); 328 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 329 printf("\n"); 330 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 331 rkwait(rkaddr); 332 rkaddr->rkcs1 = RK_CCLR; 333 rkwait(rkaddr); 334 um->um_tab.b_active = 0; 335 um->um_tab.b_errcnt = 0; 336 dp->b_actf = bp->av_forw; 337 dp->b_active = 0; 338 bp->b_flags |= B_ERROR; 339 iodone(bp); 340 goto loop; 341 } 342 printf(" (came back!)\n"); 343 } 344 nosval: 345 rkaddr->rkcyl = bp->b_cylin; 346 rkcyl[ui->ui_unit] = bp->b_cylin; 347 rkaddr->rkda = (tn << 8) + sn; 348 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 349 if (bp->b_flags & B_READ) 350 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; 351 else 352 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; 353 um->um_cmd = cmd; 354 (void) ubago(ui); 355 } 356 357 rkdgo(um) 358 register struct uba_ctlr *um; 359 { 360 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 361 362 um->um_tab.b_active = 2; /* should now be 2 */ 363 rkaddr->rkba = um->um_ubinfo; 364 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 365 } 366 367 rkintr(rk11) 368 int rk11; 369 { 370 register struct uba_ctlr *um = rkminfo[rk11]; 371 register struct uba_device *ui; 372 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 373 register struct buf *bp, *dp; 374 int unit; 375 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 376 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 377 int needie = 1; 378 379 sc->sc_wticks = 0; 380 sc->sc_softas = 0; 381 if (um->um_tab.b_active == 2 || sc->sc_recal) { 382 um->um_tab.b_active = 1; 383 dp = um->um_tab.b_actf; 384 bp = dp->b_actf; 385 ui = rkdinfo[dkunit(bp)]; 386 dk_busy &= ~(1 << ui->ui_dk); 387 #ifndef NOBADSECT 388 if (bp->b_flags&B_BAD) 389 if (rkecc(ui, CONT)) 390 return; 391 #endif 392 if (rkaddr->rkcs1 & RK_CERR) { 393 int recal; 394 u_short ds = rkaddr->rkds; 395 u_short cs2 = rkaddr->rkcs2; 396 u_short er = rkaddr->rker; 397 #ifdef RKDEBUG 398 if (rkdebug) { 399 printf("cs2=%b ds=%b er=%b\n", 400 cs2, RKCS2_BITS, ds, 401 RKDS_BITS, er, RKER_BITS); 402 } 403 #endif 404 if (er & RKER_WLE) { 405 printf("rk%d: write locked\n", dkunit(bp)); 406 bp->b_flags |= B_ERROR; 407 } else if (++um->um_tab.b_errcnt > 28 || 408 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 409 hard: 410 harderr(bp, "rk"); 411 printf("cs2=%b ds=%b er=%b\n", 412 cs2, RKCS2_BITS, ds, 413 RKDS_BITS, er, RKER_BITS); 414 bp->b_flags |= B_ERROR; 415 sc->sc_recal = 0; 416 } else if (er & RKER_BSE) { 417 #ifndef NOBADSECT 418 if (rkecc(ui, BSE)) 419 return; 420 else 421 #endif 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 (((needie = 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 u.u_error = ENXIO; 525 else 526 physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio); 527 } 528 529 rkwrite(dev, uio) 530 dev_t dev; 531 struct uio *uio; 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, uio); 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 switch (flag) { 571 case ECC: 572 { 573 register int i; 574 int bit, byte, mask; 575 576 npf--; 577 reg--; 578 printf("rk%d%c: soft ecc sn%d\n", dkunit(bp), 579 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 580 mask = rk->rkec2; 581 i = rk->rkec1 - 1; /* -1 makes 0 origin */ 582 bit = i&07; 583 i = (i&~07)>>3; 584 byte = i + o; 585 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 586 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 587 (byte & PGOFSET); 588 putmemc(addr, getmemc(addr)^(mask<<bit)); 589 byte++; 590 i++; 591 bit -= 8; 592 } 593 if (rk->rkwc == 0) { 594 um->um_tab.b_active = 0; 595 return (0); 596 } 597 npf++; 598 reg++; 599 break; 600 } 601 602 #ifndef NOBADSECT 603 case BSE: 604 #ifdef RKBDEBUG 605 if (rkbdebug) 606 printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 607 #endif 608 if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) 609 return(0); 610 bp->b_flags |= B_BAD; 611 bp->b_error = npf + 1; 612 bn = st->ncyl*st->nspc - st->nsect - 1 - bn; 613 cn = bn/st->nspc; 614 sn = bn%st->nspc; 615 tn = sn/st->nsect; 616 sn %= st->nsect; 617 #ifdef RKBDEBUG 618 if (rkbdebug) 619 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 620 #endif 621 rk->rkwc = -(512 / sizeof (short)); 622 break; 623 624 case CONT: 625 #ifdef RKBDEBUG 626 if (rkbdebug) 627 printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); 628 #endif 629 bp->b_flags &= ~B_BAD; 630 rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short)); 631 if (rk->rkwc == 0) { 632 um->um_tab.b_active = 0; 633 return (0); 634 } 635 break; 636 #endif 637 } 638 rk->rkcs1 = RK_CCLR; 639 rk->rkcs2 = ui->ui_slave; 640 rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 641 rkwait(rk); 642 rk->rkcyl = cn; 643 rk->rkda = (tn << 8) | sn; 644 ubaddr = (int)ptob(reg) + o; 645 rk->rkba = ubaddr; 646 cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; 647 cmd |= (ubaddr >> 8) & 0x300; 648 cmd |= rktypes[ui->ui_type]; 649 rk->rkcs1 = cmd; 650 um->um_tab.b_active = 2; /* continuing */ 651 um->um_tab.b_errcnt = 0; /* error has been corrected */ 652 return (1); 653 } 654 655 rkreset(uban) 656 int uban; 657 { 658 register struct uba_ctlr *um; 659 register struct uba_device *ui; 660 register rk11, unit; 661 662 for (rk11 = 0; rk11 < NHK; rk11++) { 663 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 664 um->um_alive == 0) 665 continue; 666 printf(" hk%d", rk11); 667 um->um_tab.b_active = 0; 668 um->um_tab.b_actf = um->um_tab.b_actl = 0; 669 rk_softc[um->um_ctlr].sc_recal = 0; 670 rk_softc[um->um_ctlr].sc_wticks = 0; 671 if (um->um_ubinfo) { 672 printf("<%d>", (um->um_ubinfo>>28)&0xf); 673 ubadone(um); 674 } 675 for (unit = 0; unit < NRK; unit++) { 676 if ((ui = rkdinfo[unit]) == 0) 677 continue; 678 if (ui->ui_alive == 0 || ui->ui_mi != um) 679 continue; 680 rkutab[unit].b_active = 0; 681 (void) rkustart(ui); 682 } 683 (void) rkstart(um); 684 } 685 } 686 687 rkwatch() 688 { 689 register struct uba_ctlr *um; 690 register rk11, unit; 691 register struct rk_softc *sc; 692 693 timeout(rkwatch, (caddr_t)0, hz); 694 for (rk11 = 0; rk11 < NHK; rk11++) { 695 um = rkminfo[rk11]; 696 if (um == 0 || um->um_alive == 0) 697 continue; 698 sc = &rk_softc[rk11]; 699 if (um->um_tab.b_active == 0) { 700 for (unit = 0; unit < NRK; unit++) 701 if (rkutab[unit].b_active && 702 rkdinfo[unit]->ui_mi == um) 703 goto active; 704 sc->sc_wticks = 0; 705 continue; 706 } 707 active: 708 sc->sc_wticks++; 709 if (sc->sc_wticks >= 20) { 710 sc->sc_wticks = 0; 711 printf("hk%d: lost interrupt\n", rk11); 712 ubareset(um->um_ubanum); 713 } 714 } 715 } 716 717 #define DBSIZE 20 718 719 rkdump(dev) 720 dev_t dev; 721 { 722 struct rkdevice *rkaddr; 723 char *start; 724 int num, blk, unit; 725 struct size *sizes; 726 register struct uba_regs *uba; 727 register struct uba_device *ui; 728 register short *rp; 729 struct rkst *st; 730 731 unit = minor(dev) >> 3; 732 if (unit >= NRK) 733 return (ENXIO); 734 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 735 ui = phys(struct uba_device *, rkdinfo[unit]); 736 if (ui->ui_alive == 0) 737 return (ENXIO); 738 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 739 ubainit(uba); 740 rkaddr = (struct rkdevice *)ui->ui_physaddr; 741 num = maxfree; 742 start = 0; 743 rkaddr->rkcs1 = RK_CCLR; 744 rkaddr->rkcs2 = unit; 745 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 746 rkwait(rkaddr); 747 if ((rkaddr->rkds & RKDS_VV) == 0) { 748 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; 749 rkwait(rkaddr); 750 } 751 st = &rkst[ui->ui_type]; 752 sizes = phys(struct size *, st->sizes); 753 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 754 return (EINVAL); 755 while (num > 0) { 756 register struct pte *io; 757 register int i; 758 int cn, sn, tn; 759 daddr_t bn; 760 761 blk = num > DBSIZE ? DBSIZE : num; 762 io = uba->uba_map; 763 for (i = 0; i < blk; i++) 764 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 765 *(int *)io = 0; 766 bn = dumplo + btop(start); 767 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 768 sn = bn%st->nspc; 769 tn = sn/st->nsect; 770 sn = sn%st->nsect; 771 rkaddr->rkcyl = cn; 772 rp = (short *) &rkaddr->rkda; 773 *rp = (tn << 8) + sn; 774 *--rp = 0; 775 *--rp = -blk*NBPG / sizeof (short); 776 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; 777 rkwait(rkaddr); 778 if (rkaddr->rkcs1 & RK_CERR) 779 return (EIO); 780 start += blk*NBPG; 781 num -= blk; 782 } 783 return (0); 784 } 785 #endif 786