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