|
|
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.4 (Berkeley) 5/27/88 ! 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 "dkstat.h" ! 38: #include "cmap.h" ! 39: #include "dkbad.h" ! 40: #include "ioctl.h" ! 41: #include "disklabel.h" ! 42: #include "uio.h" ! 43: #include "kernel.h" ! 44: #include "syslog.h" ! 45: ! 46: #include "../vax/cpu.h" ! 47: #include "ubareg.h" ! 48: #include "ubavar.h" ! 49: #include "rkreg.h" ! 50: ! 51: struct rk_softc { ! 52: int sc_softas; ! 53: int sc_ndrive; ! 54: int sc_wticks; ! 55: int sc_recal; ! 56: } rk_softc[NHK]; ! 57: ! 58: #define rkunit(dev) (minor(dev) >> 3) ! 59: ! 60: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ ! 61: struct size { ! 62: daddr_t nblocks; ! 63: int cyloff; ! 64: } rk7_sizes[8] = { ! 65: 15884, 0, /* A=cyl 0 thru 240 */ ! 66: 10032, 241, /* B=cyl 241 thru 392 */ ! 67: 53790, 0, /* C=cyl 0 thru 814 */ ! 68: 15884, 393, /* D=cyl 393 thru 633 */ ! 69: 0, 0, ! 70: 11792, 634, /* F=cyl 634 thru 814 */ ! 71: 27786, 393, /* G=cyl 393 thru 814, should be 27698 */ ! 72: 0, 0, ! 73: }, rk6_sizes[8] ={ ! 74: 15884, 0, /* A=cyl 0 thru 240 */ ! 75: 11154, 241, /* B=cyl 241 thru 409 */ ! 76: 27126, 0, /* C=cyl 0 thru 410 */ ! 77: 0, 0, ! 78: 0, 0, ! 79: 0, 0, ! 80: 0, 0, ! 81: 0, 0, ! 82: }; ! 83: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ ! 84: ! 85: short rktypes[] = { RK_CDT, 0 }; ! 86: ! 87: int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); ! 88: struct uba_ctlr *rkminfo[NHK]; ! 89: struct uba_device *rkdinfo[NRK]; ! 90: struct uba_device *rkip[NHK][4]; ! 91: ! 92: u_short rkstd[] = { 0777440, 0 }; ! 93: struct uba_driver hkdriver = ! 94: { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; ! 95: struct buf rkutab[NRK]; ! 96: short rkcyl[NRK]; ! 97: struct dkbad rkbad[NRK]; ! 98: struct buf brkbuf[NRK]; ! 99: ! 100: struct rkst { ! 101: short nsect; ! 102: short ntrak; ! 103: short nspc; ! 104: short ncyl; ! 105: struct size *sizes; ! 106: } rkst[] = { ! 107: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, ! 108: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes, ! 109: }; ! 110: ! 111: u_char rk_offset[16] = ! 112: { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800, ! 113: RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0 ! 114: }; ! 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: diskerr(bp, "rk", "hard error", LOG_PRINTF, -1, ! 430: (struct disklabel *)0); ! 431: printf(" cs2=%b ds=%b er=%b\n", ! 432: cs2, RKCS2_BITS, ds, ! 433: RKDS_BITS, er, RKER_BITS); ! 434: bp->b_flags |= B_ERROR; ! 435: sc->sc_recal = 0; ! 436: } else if (er & RKER_BSE) { ! 437: if (rkecc(ui, BSE)) ! 438: return; ! 439: else ! 440: goto hard; ! 441: } else { ! 442: if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) { ! 443: if (rkecc(ui, ECC)) ! 444: return; ! 445: } else ! 446: um->um_tab.b_active = 0; ! 447: } ! 448: if (cs2&RKCS2_MDS) { ! 449: rkaddr->rkcs2 = RKCS2_SCLR; ! 450: goto retry; ! 451: } ! 452: recal = 0; ! 453: if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || ! 454: (um->um_tab.b_errcnt&07) == 4) ! 455: recal = 1; ! 456: rkaddr->rkcs1 = RK_CCLR; ! 457: rkaddr->rkcs2 = ui->ui_slave; ! 458: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 459: rkwait(rkaddr); ! 460: if (recal && um->um_tab.b_active == 0) { ! 461: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO; ! 462: rkcyl[ui->ui_unit] = -1; ! 463: sc->sc_recal = 0; ! 464: goto nextrecal; ! 465: } ! 466: } ! 467: retry: ! 468: switch (sc->sc_recal) { ! 469: ! 470: case 1: ! 471: rkaddr->rkcyl = bp->b_cylin; ! 472: rkcyl[ui->ui_unit] = bp->b_cylin; ! 473: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; ! 474: goto nextrecal; ! 475: case 2: ! 476: if (um->um_tab.b_errcnt < 16 || ! 477: (bp->b_flags&B_READ) == 0) ! 478: goto donerecal; ! 479: rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; ! 480: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO; ! 481: /* fall into ... */ ! 482: nextrecal: ! 483: sc->sc_recal++; ! 484: rkwait(rkaddr); ! 485: um->um_tab.b_active = 1; ! 486: return; ! 487: donerecal: ! 488: case 3: ! 489: sc->sc_recal = 0; ! 490: um->um_tab.b_active = 0; ! 491: break; ! 492: } ! 493: ubadone(um); ! 494: if (um->um_tab.b_active) { ! 495: um->um_tab.b_active = 0; ! 496: um->um_tab.b_errcnt = 0; ! 497: um->um_tab.b_actf = dp->b_forw; ! 498: dp->b_active = 0; ! 499: dp->b_errcnt = 0; ! 500: dp->b_actf = bp->av_forw; ! 501: bp->b_resid = -rkaddr->rkwc * sizeof(short); ! 502: iodone(bp); ! 503: if (dp->b_actf) ! 504: rkustart(ui); ! 505: } ! 506: as &= ~(1<<ui->ui_slave); ! 507: } ! 508: for (unit = 0; as; as >>= 1, unit++) ! 509: if (as & 1) { ! 510: ui = rkip[rk11][unit]; ! 511: if (ui) { ! 512: rkustart(rkip[rk11][unit]); ! 513: } else { ! 514: rkaddr->rkcs1 = RK_CCLR; ! 515: rkaddr->rkcs2 = unit; ! 516: rkaddr->rkcs1 = RK_DCLR|RK_GO; ! 517: rkwait(rkaddr); ! 518: rkaddr->rkcs1 = RK_CCLR; ! 519: } ! 520: } ! 521: if (um->um_tab.b_actf && um->um_tab.b_active == 0) ! 522: rkstart(um); ! 523: if (((rkaddr->rkcs1) & RK_IE) == 0) ! 524: rkaddr->rkcs1 = RK_IE; ! 525: } ! 526: ! 527: rkwait(addr) ! 528: register struct rkdevice *addr; ! 529: { ! 530: ! 531: while ((addr->rkcs1 & RK_CRDY) == 0) ! 532: ; ! 533: } ! 534: ! 535: rkecc(ui, flag) ! 536: register struct uba_device *ui; ! 537: { ! 538: register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; ! 539: register struct buf *bp = rkutab[ui->ui_unit].b_actf; ! 540: register struct uba_ctlr *um = ui->ui_mi; ! 541: register struct rkst *st; ! 542: struct uba_regs *ubp = ui->ui_hd->uh_uba; ! 543: caddr_t addr; ! 544: int reg, npf, o, cmd, ubaddr; ! 545: int bn, cn, tn, sn; ! 546: ! 547: if (flag == CONT) ! 548: npf = bp->b_error; ! 549: else ! 550: npf = btodb(bp->b_bcount + (rk->rkwc * sizeof(short)) + 511); ! 551: reg = btop(um->um_ubinfo&0x3ffff) + npf; ! 552: o = (int)bp->b_un.b_addr & PGOFSET; ! 553: bn = bp->b_blkno; ! 554: st = &rkst[ui->ui_type]; ! 555: cn = bp->b_cylin; ! 556: sn = bn%st->nspc + npf; ! 557: tn = sn/st->nsect; ! 558: sn %= st->nsect; ! 559: cn += tn/st->ntrak; ! 560: tn %= st->ntrak; ! 561: ubapurge(um); ! 562: switch (flag) { ! 563: case ECC: ! 564: { ! 565: register int i; ! 566: int bit, byte, mask; ! 567: ! 568: npf--; ! 569: reg--; ! 570: diskerr(bp, "rk", "soft ecc", LOG_WARNING, npf, ! 571: (struct disklabel *)0); ! 572: addlog("\n"); ! 573: mask = rk->rkec2; ! 574: i = rk->rkec1 - 1; /* -1 makes 0 origin */ ! 575: bit = i&07; ! 576: i = (i&~07)>>3; ! 577: byte = i + o; ! 578: while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) { ! 579: addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ ! 580: (byte & PGOFSET); ! 581: putmemc(addr, getmemc(addr)^(mask<<bit)); ! 582: byte++; ! 583: i++; ! 584: bit -= 8; ! 585: } ! 586: if (rk->rkwc == 0) { ! 587: um->um_tab.b_active = 0; ! 588: return (0); ! 589: } ! 590: npf++; ! 591: reg++; ! 592: break; ! 593: } ! 594: ! 595: case BSE: ! 596: #ifdef RKBDEBUG ! 597: if (rkbdebug) ! 598: printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); ! 599: #endif ! 600: if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) ! 601: return(0); ! 602: bp->b_flags |= B_BAD; ! 603: bp->b_error = npf + 1; ! 604: bn = st->ncyl*st->nspc - st->nsect - 1 - bn; ! 605: cn = bn/st->nspc; ! 606: sn = bn%st->nspc; ! 607: tn = sn/st->nsect; ! 608: sn %= st->nsect; ! 609: #ifdef RKBDEBUG ! 610: if (rkbdebug) ! 611: printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); ! 612: #endif ! 613: rk->rkwc = -(512 / sizeof (short)); ! 614: break; ! 615: ! 616: case CONT: ! 617: #ifdef RKBDEBUG ! 618: if (rkbdebug) ! 619: printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); ! 620: #endif ! 621: bp->b_flags &= ~B_BAD; ! 622: if ((int)dbtob(npf) >= bp->b_bcount) ! 623: return (0); ! 624: rk->rkwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof (short)); ! 625: break; ! 626: } ! 627: rk->rkcs1 = RK_CCLR; ! 628: rk->rkcs2 = ui->ui_slave; ! 629: rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 630: rkwait(rk); ! 631: rk->rkcyl = cn; ! 632: rk->rkda = (tn << 8) | sn; ! 633: ubaddr = (int)ptob(reg) + o; ! 634: rk->rkba = ubaddr; ! 635: cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; ! 636: cmd |= (ubaddr >> 8) & 0x300; ! 637: cmd |= rktypes[ui->ui_type]; ! 638: rk->rkcs1 = cmd; ! 639: um->um_tab.b_active = 2; /* continuing */ ! 640: um->um_tab.b_errcnt = 0; /* error has been corrected */ ! 641: return (1); ! 642: } ! 643: ! 644: rkreset(uban) ! 645: int uban; ! 646: { ! 647: register struct uba_ctlr *um; ! 648: register struct uba_device *ui; ! 649: register rk11, unit; ! 650: ! 651: for (rk11 = 0; rk11 < NHK; rk11++) { ! 652: if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || ! 653: um->um_alive == 0) ! 654: continue; ! 655: printf(" hk%d", rk11); ! 656: um->um_tab.b_active = 0; ! 657: um->um_tab.b_actf = um->um_tab.b_actl = 0; ! 658: rk_softc[um->um_ctlr].sc_recal = 0; ! 659: rk_softc[um->um_ctlr].sc_wticks = 0; ! 660: if (um->um_ubinfo) { ! 661: printf("<%d>", (um->um_ubinfo>>28)&0xf); ! 662: um->um_ubinfo = 0; ! 663: } ! 664: for (unit = 0; unit < NRK; unit++) { ! 665: if ((ui = rkdinfo[unit]) == 0) ! 666: continue; ! 667: if (ui->ui_alive == 0 || ui->ui_mi != um) ! 668: continue; ! 669: rkutab[unit].b_active = 0; ! 670: (void) rkustart(ui); ! 671: } ! 672: (void) rkstart(um); ! 673: } ! 674: } ! 675: ! 676: rkwatch() ! 677: { ! 678: register struct uba_ctlr *um; ! 679: register rk11, unit; ! 680: register struct rk_softc *sc; ! 681: ! 682: timeout(rkwatch, (caddr_t)0, hz); ! 683: for (rk11 = 0; rk11 < NHK; rk11++) { ! 684: um = rkminfo[rk11]; ! 685: if (um == 0 || um->um_alive == 0) ! 686: continue; ! 687: sc = &rk_softc[rk11]; ! 688: if (um->um_tab.b_active == 0) { ! 689: for (unit = 0; unit < NRK; unit++) ! 690: if (rkutab[unit].b_active && ! 691: rkdinfo[unit]->ui_mi == um) ! 692: goto active; ! 693: sc->sc_wticks = 0; ! 694: continue; ! 695: } ! 696: active: ! 697: sc->sc_wticks++; ! 698: if (sc->sc_wticks >= 20) { ! 699: sc->sc_wticks = 0; ! 700: printf("hk%d: lost interrupt\n", rk11); ! 701: ubareset(um->um_ubanum); ! 702: } ! 703: } ! 704: } ! 705: ! 706: #define DBSIZE 20 ! 707: ! 708: rkdump(dev) ! 709: dev_t dev; ! 710: { ! 711: struct rkdevice *rkaddr; ! 712: char *start; ! 713: int num, blk, unit; ! 714: struct size *sizes; ! 715: register struct uba_regs *uba; ! 716: register struct uba_device *ui; ! 717: register short *rp; ! 718: struct rkst *st; ! 719: ! 720: unit = rkunit(dev); ! 721: if (unit >= NRK) ! 722: return (ENXIO); ! 723: #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) ! 724: ui = phys(struct uba_device *, rkdinfo[unit]); ! 725: if (ui->ui_alive == 0) ! 726: return (ENXIO); ! 727: uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; ! 728: ubainit(uba); ! 729: rkaddr = (struct rkdevice *)ui->ui_physaddr; ! 730: num = maxfree; ! 731: start = 0; ! 732: rkaddr->rkcs1 = RK_CCLR; ! 733: rkaddr->rkcs2 = unit; ! 734: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 735: rkwait(rkaddr); ! 736: if ((rkaddr->rkds & RKDS_VV) == 0) { ! 737: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; ! 738: rkwait(rkaddr); ! 739: } ! 740: st = &rkst[ui->ui_type]; ! 741: sizes = phys(struct size *, st->sizes); ! 742: if (dumplo < 0) ! 743: return (EINVAL); ! 744: if (dumplo + num >= sizes[minor(dev)&07].nblocks) ! 745: num = sizes[minor(dev)&07].nblocks - dumplo; ! 746: while (num > 0) { ! 747: register struct pte *io; ! 748: register int i; ! 749: int cn, sn, tn; ! 750: daddr_t bn; ! 751: ! 752: blk = num > DBSIZE ? DBSIZE : num; ! 753: io = uba->uba_map; ! 754: for (i = 0; i < blk; i++) ! 755: *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; ! 756: *(int *)io = 0; ! 757: bn = dumplo + btop(start); ! 758: cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; ! 759: sn = bn%st->nspc; ! 760: tn = sn/st->nsect; ! 761: sn = sn%st->nsect; ! 762: rkaddr->rkcyl = cn; ! 763: rp = (short *) &rkaddr->rkda; ! 764: *rp = (tn << 8) + sn; ! 765: *--rp = 0; ! 766: *--rp = -blk*NBPG / sizeof (short); ! 767: *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; ! 768: rkwait(rkaddr); ! 769: if (rkaddr->rkcs1 & RK_CERR) ! 770: return (EIO); ! 771: start += blk*NBPG; ! 772: num -= blk; ! 773: } ! 774: return (0); ! 775: } ! 776: ! 777: rksize(dev) ! 778: dev_t dev; ! 779: { ! 780: int unit = rkunit(dev); ! 781: struct uba_device *ui; ! 782: struct rkst *st; ! 783: ! 784: if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) ! 785: return (-1); ! 786: st = &rkst[ui->ui_type]; ! 787: return (st->sizes[minor(dev) & 07].nblocks); ! 788: } ! 789: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.