|
|
1.1 ! root 1: /* rk.c 4.36 81/07/25 */ ! 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 "../h/param.h" ! 22: #include "../h/systm.h" ! 23: #include "../h/buf.h" ! 24: #include "../h/conf.h" ! 25: #include "../h/dir.h" ! 26: #include "../h/user.h" ! 27: #include "../h/pte.h" ! 28: #include "../h/map.h" ! 29: #include "../h/vm.h" ! 30: #include "../h/ubareg.h" ! 31: #include "../h/ubavar.h" ! 32: #include "../h/dk.h" ! 33: #include "../h/cpu.h" ! 34: #include "../h/cmap.h" ! 35: #include "../h/dkbad.h" ! 36: ! 37: #include "../h/rkreg.h" ! 38: ! 39: struct rk_softc { ! 40: int sc_softas; ! 41: int sc_ndrive; ! 42: int sc_wticks; ! 43: int sc_recal; ! 44: } rk_softc[NHK]; ! 45: ! 46: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ ! 47: struct size { ! 48: daddr_t nblocks; ! 49: int cyloff; ! 50: } rk7_sizes[8] ={ ! 51: 15884, 0, /* A=cyl 0 thru 240 */ ! 52: 10032, 241, /* B=cyl 241 thru 392 */ ! 53: 53790, 0, /* C=cyl 0 thru 814 */ ! 54: 0, 0, ! 55: 0, 0, ! 56: 0, 0, ! 57: 27786, 393, /* G=cyl 393 thru 813 */ ! 58: 0, 0, ! 59: }, rk6_sizes[8] ={ ! 60: 15884, 0, /* A=cyl 0 thru 240 */ ! 61: 11154, 241, /* B=cyl 241 thru 409 */ ! 62: 27126, 0, /* C=cyl 0 thru 410 */ ! 63: 0, 0, ! 64: 0, 0, ! 65: 0, 0, ! 66: 0, 0, ! 67: 0, 0, ! 68: }; ! 69: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ ! 70: ! 71: short rktypes[] = { RK_CDT, 0 }; ! 72: ! 73: int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); ! 74: struct uba_ctlr *rkminfo[NHK]; ! 75: struct uba_device *rkdinfo[NRK]; ! 76: struct uba_device *rkip[NHK][4]; ! 77: ! 78: u_short rkstd[] = { 0777440, 0 }; ! 79: struct uba_driver hkdriver = ! 80: { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; ! 81: struct buf rkutab[NRK]; ! 82: short rkcyl[NRK]; ! 83: #ifndef NOBADSECT ! 84: struct dkbad rkbad[NRK]; ! 85: struct buf brkbuf[NRK]; ! 86: #endif ! 87: ! 88: struct rkst { ! 89: short nsect; ! 90: short ntrak; ! 91: short nspc; ! 92: short ncyl; ! 93: struct size *sizes; ! 94: } rkst[] = { ! 95: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, ! 96: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes, ! 97: }; ! 98: ! 99: u_char rk_offset[16] = ! 100: { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800, ! 101: RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0 ! 102: }; ! 103: ! 104: struct buf rrkbuf[NRK]; ! 105: ! 106: #define b_cylin b_resid ! 107: ! 108: #ifdef INTRLVE ! 109: daddr_t dkblock(); ! 110: #endif ! 111: ! 112: int rkwstart, rkwatch(); ! 113: ! 114: rkprobe(reg) ! 115: caddr_t reg; ! 116: { ! 117: register int br, cvec; ! 118: ! 119: #ifdef lint ! 120: br = 0; cvec = br; br = cvec; ! 121: #endif ! 122: ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; ! 123: DELAY(10); ! 124: ((struct rkdevice *)reg)->rkcs1 = RK_CDT; ! 125: return (1); ! 126: } ! 127: ! 128: rkslave(ui, reg) ! 129: struct uba_device *ui; ! 130: caddr_t reg; ! 131: { ! 132: register struct rkdevice *rkaddr = (struct rkdevice *)reg; ! 133: ! 134: ui->ui_type = 0; ! 135: rkaddr->rkcs1 = RK_CCLR; ! 136: rkaddr->rkcs2 = ui->ui_slave; ! 137: rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; ! 138: rkwait(rkaddr); ! 139: DELAY(50); ! 140: if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) { ! 141: rkaddr->rkcs1 = RK_CCLR; ! 142: return (0); ! 143: } ! 144: if (rkaddr->rkcs1&RK_CERR && rkaddr->rker&RKER_DTYE) { ! 145: ui->ui_type = 1; ! 146: rkaddr->rkcs1 = RK_CCLR; ! 147: } ! 148: return (1); ! 149: } ! 150: ! 151: rkattach(ui) ! 152: register struct uba_device *ui; ! 153: { ! 154: ! 155: if (rkwstart == 0) { ! 156: timeout(rkwatch, (caddr_t)0, hz); ! 157: rkwstart++; ! 158: } ! 159: if (ui->ui_dk >= 0) ! 160: dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256); ! 161: rkip[ui->ui_ctlr][ui->ui_slave] = ui; ! 162: rk_softc[ui->ui_ctlr].sc_ndrive++; ! 163: rkcyl[ui->ui_unit] = -1; ! 164: ui->ui_flags = 0; ! 165: } ! 166: ! 167: rkstrategy(bp) ! 168: register struct buf *bp; ! 169: { ! 170: register struct uba_device *ui; ! 171: register struct rkst *st; ! 172: register int unit; ! 173: register struct buf *dp; ! 174: int xunit = minor(bp->b_dev) & 07; ! 175: long bn, sz; ! 176: ! 177: sz = (bp->b_bcount+511) >> 9; ! 178: unit = dkunit(bp); ! 179: if (unit >= NRK) ! 180: goto bad; ! 181: ui = rkdinfo[unit]; ! 182: if (ui == 0 || ui->ui_alive == 0) ! 183: goto bad; ! 184: st = &rkst[ui->ui_type]; ! 185: if (bp->b_blkno < 0 || ! 186: (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) ! 187: goto bad; ! 188: bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; ! 189: (void) spl5(); ! 190: dp = &rkutab[ui->ui_unit]; ! 191: disksort(dp, bp); ! 192: if (dp->b_active == 0) { ! 193: (void) rkustart(ui); ! 194: bp = &ui->ui_mi->um_tab; ! 195: if (bp->b_actf && bp->b_active == 0) ! 196: (void) rkstart(ui->ui_mi); ! 197: } ! 198: (void) spl0(); ! 199: return; ! 200: ! 201: bad: ! 202: bp->b_flags |= B_ERROR; ! 203: iodone(bp); ! 204: return; ! 205: } ! 206: ! 207: rkustart(ui) ! 208: register struct uba_device *ui; ! 209: { ! 210: register struct buf *bp, *dp; ! 211: register struct uba_ctlr *um; ! 212: register struct rkdevice *rkaddr; ! 213: int didie = 0; ! 214: ! 215: if (ui == 0) ! 216: return (0); ! 217: dk_busy &= ~(1<<ui->ui_dk); ! 218: dp = &rkutab[ui->ui_unit]; ! 219: um = ui->ui_mi; ! 220: rkaddr = (struct rkdevice *)um->um_addr; ! 221: if (um->um_tab.b_active) { ! 222: rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; ! 223: return (0); ! 224: } ! 225: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; ! 226: rkaddr->rkcs2 = ui->ui_slave; ! 227: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 228: rkwait(rkaddr); ! 229: if ((bp = dp->b_actf) == NULL) { ! 230: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 231: rkwait(rkaddr); ! 232: return (0); ! 233: } ! 234: if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { ! 235: /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ ! 236: #ifndef NOBADSECT ! 237: struct rkst *st = &rkst[ui->ui_type]; ! 238: struct buf *bbp = &brkbuf[ui->ui_unit]; ! 239: #endif ! 240: ! 241: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; ! 242: ui->ui_flags = 1; ! 243: #ifndef NOBADSECT ! 244: bbp->b_flags = B_READ|B_BUSY; ! 245: bbp->b_dev = bp->b_dev; ! 246: bbp->b_bcount = 512; ! 247: bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; ! 248: bbp->b_blkno = st->ncyl*st->nspc - st->nsect; ! 249: bbp->b_cylin = st->ncyl - 1; ! 250: dp->b_actf = bbp; ! 251: bbp->av_forw = bp; ! 252: bp = bbp; ! 253: #endif ! 254: rkwait(rkaddr); ! 255: } ! 256: if (dp->b_active) ! 257: goto done; ! 258: dp->b_active = 1; ! 259: if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) ! 260: goto done; ! 261: if (rk_softc[um->um_ctlr].sc_ndrive == 1) ! 262: goto done; ! 263: if (bp->b_cylin == rkcyl[ui->ui_unit]) ! 264: goto done; ! 265: rkaddr->rkcyl = bp->b_cylin; ! 266: rkcyl[ui->ui_unit] = bp->b_cylin; ! 267: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; ! 268: didie = 1; ! 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 (didie); ! 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 (0); ! 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: return (1); ! 356: } ! 357: ! 358: rkdgo(um) ! 359: register struct uba_ctlr *um; ! 360: { ! 361: register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; ! 362: ! 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) { ! 382: dp = um->um_tab.b_actf; ! 383: bp = dp->b_actf; ! 384: ui = rkdinfo[dkunit(bp)]; ! 385: dk_busy &= ~(1 << ui->ui_dk); ! 386: #ifndef NOBADSECT ! 387: if (bp->b_flags&B_BAD) ! 388: if (rkecc(ui, CONT)) ! 389: return; ! 390: #endif ! 391: if (rkaddr->rkcs1 & RK_CERR) { ! 392: int recal; ! 393: u_short ds = rkaddr->rkds; ! 394: u_short cs2 = rkaddr->rkcs2; ! 395: u_short er = rkaddr->rker; ! 396: #ifdef RKDEBUG ! 397: if (rkdebug) { ! 398: printf("cs2=%b ds=%b er=%b\n", ! 399: cs2, RKCS2_BITS, ds, ! 400: RKDS_BITS, er, RKER_BITS); ! 401: } ! 402: #endif ! 403: if (er & RKER_WLE) { ! 404: printf("rk%d: write locked\n", dkunit(bp)); ! 405: bp->b_flags |= B_ERROR; ! 406: } else if (++um->um_tab.b_errcnt > 28 || ! 407: ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { ! 408: hard: ! 409: harderr(bp, "rk"); ! 410: printf("cs2=%b ds=%b er=%b\n", ! 411: cs2, RKCS2_BITS, ds, ! 412: RKDS_BITS, er, RKER_BITS); ! 413: bp->b_flags |= B_ERROR; ! 414: sc->sc_recal = 0; ! 415: } else if (er & RKER_BSE) { ! 416: #ifndef NOBADSECT ! 417: if (rkecc(ui, BSE)) ! 418: return; ! 419: else ! 420: #endif ! 421: goto hard; ! 422: } else ! 423: um->um_tab.b_active = 0; ! 424: if (cs2&RKCS2_MDS) { ! 425: rkaddr->rkcs2 = RKCS2_SCLR; ! 426: goto retry; ! 427: } ! 428: recal = 0; ! 429: if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || ! 430: (um->um_tab.b_errcnt&07) == 4) ! 431: recal = 1; ! 432: if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) ! 433: if (rkecc(ui, ECC)) ! 434: return; ! 435: rkaddr->rkcs1 = RK_CCLR; ! 436: rkaddr->rkcs2 = ui->ui_slave; ! 437: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 438: rkwait(rkaddr); ! 439: if (recal && um->um_tab.b_active == 0) { ! 440: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO; ! 441: rkcyl[ui->ui_unit] = -1; ! 442: sc->sc_recal = 0; ! 443: goto nextrecal; ! 444: } ! 445: } ! 446: retry: ! 447: switch (sc->sc_recal) { ! 448: ! 449: case 1: ! 450: rkaddr->rkcyl = bp->b_cylin; ! 451: rkcyl[ui->ui_unit] = bp->b_cylin; ! 452: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; ! 453: goto nextrecal; ! 454: case 2: ! 455: if (um->um_tab.b_errcnt < 16 || ! 456: (bp->b_flags&B_READ) == 0) ! 457: goto donerecal; ! 458: rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; ! 459: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO; ! 460: /* fall into ... */ ! 461: nextrecal: ! 462: sc->sc_recal++; ! 463: rkwait(rkaddr); ! 464: um->um_tab.b_active = 1; ! 465: return; ! 466: donerecal: ! 467: case 3: ! 468: sc->sc_recal = 0; ! 469: um->um_tab.b_active = 0; ! 470: break; ! 471: } ! 472: ubadone(um); ! 473: if (um->um_tab.b_active) { ! 474: um->um_tab.b_active = 0; ! 475: um->um_tab.b_errcnt = 0; ! 476: um->um_tab.b_actf = dp->b_forw; ! 477: dp->b_active = 0; ! 478: dp->b_errcnt = 0; ! 479: dp->b_actf = bp->av_forw; ! 480: bp->b_resid = -rkaddr->rkwc * sizeof(short); ! 481: iodone(bp); ! 482: if (dp->b_actf) ! 483: if (rkustart(ui)) ! 484: needie = 0; ! 485: } ! 486: as &= ~(1<<ui->ui_slave); ! 487: } ! 488: for (unit = 0; as; as >>= 1, unit++) ! 489: if (as & 1) { ! 490: ui = rkip[rk11][unit]; ! 491: if (ui) { ! 492: if (rkustart(rkip[rk11][unit])) ! 493: needie = 0; ! 494: } else { ! 495: rkaddr->rkcs1 = RK_CCLR; ! 496: rkaddr->rkcs2 = unit; ! 497: rkaddr->rkcs1 = RK_DCLR|RK_GO; ! 498: rkwait(rkaddr); ! 499: rkaddr->rkcs1 = RK_CCLR; ! 500: } ! 501: } ! 502: if (um->um_tab.b_actf && um->um_tab.b_active == 0) ! 503: if (rkstart(um)) ! 504: needie = 0; ! 505: if (needie) ! 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) ! 518: dev_t dev; ! 519: { ! 520: register int unit = minor(dev) >> 3; ! 521: ! 522: if (unit >= NRK) ! 523: u.u_error = ENXIO; ! 524: else ! 525: physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); ! 526: } ! 527: ! 528: rkwrite(dev) ! 529: dev_t dev; ! 530: { ! 531: register int unit = minor(dev) >> 3; ! 532: ! 533: if (unit >= NRK) ! 534: u.u_error = ENXIO; ! 535: else ! 536: physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); ! 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: #ifndef NOBADSECT ! 552: if (flag == CONT) ! 553: npf = bp->b_error; ! 554: else ! 555: #endif ! 556: npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount); ! 557: reg = btop(um->um_ubinfo&0x3ffff) + npf; ! 558: o = (int)bp->b_un.b_addr & PGOFSET; ! 559: bn = dkblock(bp); ! 560: st = &rkst[ui->ui_type]; ! 561: cn = bp->b_cylin; ! 562: sn = bn%st->nspc + npf; ! 563: tn = sn/st->nsect; ! 564: sn %= st->nsect; ! 565: cn += tn/st->ntrak; ! 566: tn %= st->ntrak; ! 567: ubapurge(um); ! 568: um->um_tab.b_active++; /* Either complete or continuing... */ ! 569: switch (flag) { ! 570: case ECC: ! 571: { ! 572: register int i; ! 573: int bit, byte, mask; ! 574: ! 575: npf--; ! 576: reg--; ! 577: printf("rk%d%c: soft ecc sn%d\n", dkunit(bp), ! 578: 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); ! 579: mask = rk->rkec2; ! 580: i = rk->rkec1 - 1; /* -1 makes 0 origin */ ! 581: bit = i&07; ! 582: i = (i&~07)>>3; ! 583: byte = i + o; ! 584: while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { ! 585: addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ ! 586: (byte & PGOFSET); ! 587: putmemc(addr, getmemc(addr)^(mask<<bit)); ! 588: byte++; ! 589: i++; ! 590: bit -= 8; ! 591: } ! 592: if (rk->rkwc == 0) ! 593: return (0); ! 594: npf++; ! 595: reg++; ! 596: break; ! 597: } ! 598: ! 599: #ifndef NOBADSECT ! 600: case BSE: ! 601: #ifdef RKBDEBUG ! 602: if (rkbdebug) ! 603: printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); ! 604: #endif ! 605: if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) ! 606: return(0); ! 607: bp->b_flags |= B_BAD; ! 608: bp->b_error = npf + 1; ! 609: bn = st->ncyl*st->nspc - st->nsect - 1 - bn; ! 610: cn = bn/st->nspc; ! 611: sn = bn%st->nspc; ! 612: tn = sn/st->nsect; ! 613: sn %= st->nsect; ! 614: #ifdef RKBDEBUG ! 615: if (rkbdebug) ! 616: printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); ! 617: #endif ! 618: rk->rkwc = -(512 / sizeof (short)); ! 619: break; ! 620: ! 621: case CONT: ! 622: #ifdef RKBDEBUG ! 623: if (rkbdebug) ! 624: printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); ! 625: #endif ! 626: bp->b_flags &= ~B_BAD; ! 627: rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short)); ! 628: if (rk->rkwc == 0) ! 629: return(0); ! 630: break; ! 631: #endif ! 632: } ! 633: rk->rkcs1 = RK_CCLR; ! 634: rk->rkcs2 = ui->ui_slave; ! 635: rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 636: rkwait(rk); ! 637: rk->rkcyl = cn; ! 638: rk->rkda = (tn << 8) | sn; ! 639: ubaddr = (int)ptob(reg) + o; ! 640: rk->rkba = ubaddr; ! 641: cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; ! 642: cmd |= (ubaddr >> 8) & 0x300; ! 643: cmd |= rktypes[ui->ui_type]; ! 644: rk->rkcs1 = cmd; ! 645: um->um_tab.b_errcnt = 0; /* error has been corrected */ ! 646: return (1); ! 647: } ! 648: ! 649: rkreset(uban) ! 650: int uban; ! 651: { ! 652: register struct uba_ctlr *um; ! 653: register struct uba_device *ui; ! 654: register rk11, unit; ! 655: ! 656: for (rk11 = 0; rk11 < NHK; rk11++) { ! 657: if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || ! 658: um->um_alive == 0) ! 659: continue; ! 660: printf(" hk%d", rk11); ! 661: um->um_tab.b_active = 0; ! 662: um->um_tab.b_actf = um->um_tab.b_actl = 0; ! 663: rk_softc[um->um_ctlr].sc_recal = 0; ! 664: if (um->um_ubinfo) { ! 665: printf("<%d>", (um->um_ubinfo>>28)&0xf); ! 666: ubadone(um); ! 667: } ! 668: for (unit = 0; unit < NRK; unit++) { ! 669: if ((ui = rkdinfo[unit]) == 0) ! 670: continue; ! 671: if (ui->ui_alive == 0 || ui->ui_mi != um) ! 672: continue; ! 673: rkutab[unit].b_active = 0; ! 674: (void) rkustart(ui); ! 675: } ! 676: (void) rkstart(um); ! 677: } ! 678: } ! 679: ! 680: rkwatch() ! 681: { ! 682: register struct uba_ctlr *um; ! 683: register rk11, unit; ! 684: register struct rk_softc *sc; ! 685: ! 686: timeout(rkwatch, (caddr_t)0, hz); ! 687: for (rk11 = 0; rk11 < NHK; rk11++) { ! 688: um = rkminfo[rk11]; ! 689: if (um == 0 || um->um_alive == 0) ! 690: continue; ! 691: sc = &rk_softc[rk11]; ! 692: if (um->um_tab.b_active == 0) { ! 693: for (unit = 0; unit < NRK; unit++) ! 694: if (rkutab[unit].b_active && ! 695: rkdinfo[unit]->ui_mi == um) ! 696: goto active; ! 697: sc->sc_wticks = 0; ! 698: continue; ! 699: } ! 700: active: ! 701: sc->sc_wticks++; ! 702: if (sc->sc_wticks >= 20) { ! 703: sc->sc_wticks = 0; ! 704: printf("hk%d: lost interrupt\n", rk11); ! 705: ubareset(um->um_ubanum); ! 706: } ! 707: } ! 708: } ! 709: ! 710: #define DBSIZE 20 ! 711: ! 712: rkdump(dev) ! 713: dev_t dev; ! 714: { ! 715: struct rkdevice *rkaddr; ! 716: char *start; ! 717: int num, blk, unit; ! 718: struct size *sizes; ! 719: register struct uba_regs *uba; ! 720: register struct uba_device *ui; ! 721: register short *rp; ! 722: struct rkst *st; ! 723: ! 724: unit = minor(dev) >> 3; ! 725: if (unit >= NRK) ! 726: return (ENXIO); ! 727: #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) ! 728: ui = phys(struct uba_device *, rkdinfo[unit]); ! 729: if (ui->ui_alive == 0) ! 730: return (ENXIO); ! 731: uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; ! 732: ubainit(uba); ! 733: rkaddr = (struct rkdevice *)ui->ui_physaddr; ! 734: num = maxfree; ! 735: start = 0; ! 736: rkaddr->rkcs1 = RK_CCLR; ! 737: rkaddr->rkcs2 = unit; ! 738: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; ! 739: rkwait(rkaddr); ! 740: if ((rkaddr->rkds & RKDS_VV) == 0) { ! 741: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; ! 742: rkwait(rkaddr); ! 743: } ! 744: st = &rkst[ui->ui_type]; ! 745: sizes = phys(struct size *, st->sizes); ! 746: if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) ! 747: return (EINVAL); ! 748: while (num > 0) { ! 749: register struct pte *io; ! 750: register int i; ! 751: int cn, sn, tn; ! 752: daddr_t bn; ! 753: ! 754: blk = num > DBSIZE ? DBSIZE : num; ! 755: io = uba->uba_map; ! 756: for (i = 0; i < blk; i++) ! 757: *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; ! 758: *(int *)io = 0; ! 759: bn = dumplo + btop(start); ! 760: cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; ! 761: sn = bn%st->nspc; ! 762: tn = sn/st->nsect; ! 763: sn = sn%st->nsect; ! 764: rkaddr->rkcyl = cn; ! 765: rp = (short *) &rkaddr->rkda; ! 766: *rp = (tn << 8) + sn; ! 767: *--rp = 0; ! 768: *--rp = -blk*NBPG / sizeof (short); ! 769: *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; ! 770: rkwait(rkaddr); ! 771: if (rkaddr->rkcs1 & RK_CERR) ! 772: return (EIO); ! 773: start += blk*NBPG; ! 774: num -= blk; ! 775: } ! 776: return (0); ! 777: } ! 778: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.