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