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