|
|
1.1 ! root 1: /* rk.c 6.2 83/10/11 */ ! 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: return (0); ! 628: break; ! 629: } ! 630: rk->rkcs1 = RK_CCLR; ! 631: rk->rkcs2 = ui->ui_slave; ! 632: rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 633: rkwait(rk); ! 634: rk->rkcyl = cn; ! 635: rk->rkda = (tn << 8) | sn; ! 636: ubaddr = (int)ptob(reg) + o; ! 637: rk->rkba = ubaddr; ! 638: cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; ! 639: cmd |= (ubaddr >> 8) & 0x300; ! 640: cmd |= rktypes[ui->ui_type]; ! 641: rk->rkcs1 = cmd; ! 642: um->um_tab.b_active = 2; /* continuing */ ! 643: um->um_tab.b_errcnt = 0; /* error has been corrected */ ! 644: return (1); ! 645: } ! 646: ! 647: rkreset(uban) ! 648: int uban; ! 649: { ! 650: register struct uba_ctlr *um; ! 651: register struct uba_device *ui; ! 652: register rk11, unit; ! 653: ! 654: for (rk11 = 0; rk11 < NHK; rk11++) { ! 655: if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || ! 656: um->um_alive == 0) ! 657: continue; ! 658: printf(" hk%d", rk11); ! 659: um->um_tab.b_active = 0; ! 660: um->um_tab.b_actf = um->um_tab.b_actl = 0; ! 661: rk_softc[um->um_ctlr].sc_recal = 0; ! 662: rk_softc[um->um_ctlr].sc_wticks = 0; ! 663: if (um->um_ubinfo) { ! 664: printf("<%d>", (um->um_ubinfo>>28)&0xf); ! 665: um->um_ubinfo = 0; ! 666: } ! 667: for (unit = 0; unit < NRK; unit++) { ! 668: if ((ui = rkdinfo[unit]) == 0) ! 669: continue; ! 670: if (ui->ui_alive == 0 || ui->ui_mi != um) ! 671: continue; ! 672: rkutab[unit].b_active = 0; ! 673: (void) rkustart(ui); ! 674: } ! 675: (void) rkstart(um); ! 676: } ! 677: } ! 678: ! 679: rkwatch() ! 680: { ! 681: register struct uba_ctlr *um; ! 682: register rk11, unit; ! 683: register struct rk_softc *sc; ! 684: ! 685: timeout(rkwatch, (caddr_t)0, hz); ! 686: for (rk11 = 0; rk11 < NHK; rk11++) { ! 687: um = rkminfo[rk11]; ! 688: if (um == 0 || um->um_alive == 0) ! 689: continue; ! 690: sc = &rk_softc[rk11]; ! 691: if (um->um_tab.b_active == 0) { ! 692: for (unit = 0; unit < NRK; unit++) ! 693: if (rkutab[unit].b_active && ! 694: rkdinfo[unit]->ui_mi == um) ! 695: goto active; ! 696: sc->sc_wticks = 0; ! 697: continue; ! 698: } ! 699: active: ! 700: sc->sc_wticks++; ! 701: if (sc->sc_wticks >= 20) { ! 702: sc->sc_wticks = 0; ! 703: printf("hk%d: lost interrupt\n", rk11); ! 704: ubareset(um->um_ubanum); ! 705: } ! 706: } ! 707: } ! 708: ! 709: #define DBSIZE 20 ! 710: ! 711: rkdump(dev) ! 712: dev_t dev; ! 713: { ! 714: struct rkdevice *rkaddr; ! 715: char *start; ! 716: int num, blk, unit; ! 717: struct size *sizes; ! 718: register struct uba_regs *uba; ! 719: register struct uba_device *ui; ! 720: register short *rp; ! 721: struct rkst *st; ! 722: ! 723: unit = minor(dev) >> 3; ! 724: if (unit >= NRK) ! 725: return (ENXIO); ! 726: #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) ! 727: ui = phys(struct uba_device *, rkdinfo[unit]); ! 728: if (ui->ui_alive == 0) ! 729: return (ENXIO); ! 730: uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; ! 731: ubainit(uba); ! 732: rkaddr = (struct rkdevice *)ui->ui_physaddr; ! 733: num = maxfree; ! 734: start = 0; ! 735: rkaddr->rkcs1 = RK_CCLR; ! 736: rkaddr->rkcs2 = unit; ! 737: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 738: rkwait(rkaddr); ! 739: if ((rkaddr->rkds & RKDS_VV) == 0) { ! 740: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; ! 741: rkwait(rkaddr); ! 742: } ! 743: st = &rkst[ui->ui_type]; ! 744: sizes = phys(struct size *, st->sizes); ! 745: if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) ! 746: return (EINVAL); ! 747: while (num > 0) { ! 748: register struct pte *io; ! 749: register int i; ! 750: int cn, sn, tn; ! 751: daddr_t bn; ! 752: ! 753: blk = num > DBSIZE ? DBSIZE : num; ! 754: io = uba->uba_map; ! 755: for (i = 0; i < blk; i++) ! 756: *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; ! 757: *(int *)io = 0; ! 758: bn = dumplo + btop(start); ! 759: cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; ! 760: sn = bn%st->nspc; ! 761: tn = sn/st->nsect; ! 762: sn = sn%st->nsect; ! 763: rkaddr->rkcyl = cn; ! 764: rp = (short *) &rkaddr->rkda; ! 765: *rp = (tn << 8) + sn; ! 766: *--rp = 0; ! 767: *--rp = -blk*NBPG / sizeof (short); ! 768: *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; ! 769: rkwait(rkaddr); ! 770: if (rkaddr->rkcs1 & RK_CERR) ! 771: return (EIO); ! 772: start += blk*NBPG; ! 773: num -= blk; ! 774: } ! 775: return (0); ! 776: } ! 777: ! 778: rksize(dev) ! 779: dev_t dev; ! 780: { ! 781: int unit = minor(dev) >> 3; ! 782: struct uba_device *ui; ! 783: struct rkst *st; ! 784: ! 785: if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) ! 786: return (-1); ! 787: st = &rkst[ui->ui_type]; ! 788: return (st->sizes[minor(dev) & 07].nblocks); ! 789: } ! 790: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.