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

Defined functions

rkattach defined in line 158; used 2 times
rkdgo defined in line 378; used 2 times
rkdump defined in line 728; never used
rkecc defined in line 556; used 3 times
rkintr defined in line 388; used 3 times
rkopen defined in line 174; never used
rkprobe defined in line 120; used 2 times
rkread defined in line 534; never used
rkreset defined in line 664; never used
rksize defined in line 797; never used
rkslave defined in line 135; used 2 times
rkstart defined in line 309; used 3 times
rkstrategy defined in line 185; used 2 times
rkustart defined in line 237; used 4 times
rkwait defined in line 526; used 13 times
rkwatch defined in line 696; used 3 times
rkwrite defined in line 545; never used

Defined variables

brkbuf defined in line 96; used 1 times
hkdriver defined in line 91; used 7 times
rk7_sizes defined in line 62; used 1 times
rk_offset defined in line 109; used 1 times
rk_softc defined in line 54; used 7 times
rkbad defined in line 95; used 2 times
rkbdebug defined in line 17; used 3 times
rkcyl defined in line 94; used 11 times
rkdebug defined in line 14; used 1 times
rkdinfo defined in line 87; used 9 times
rkip defined in line 88; used 3 times
rkminfo defined in line 86; used 4 times
rknosval defined in line 12; used 1 times
rkpip defined in line 11; used 1 times
rkst defined in line 104; used 6 times
rkstd defined in line 90; used 1 times
  • in line 92
rktypes defined in line 83; used 17 times
rkutab defined in line 93; used 5 times
rkwstart defined in line 118; used 2 times
rrkbuf defined in line 114; used 2 times

Defined struct's

rk_softc defined in line 49; used 4 times
rkst defined in line 98; used 12 times
size defined in line 59; used 6 times

Defined macros

DBSIZE defined in line 726; used 2 times
  • in line 772(2)
b_cylin defined in line 116; used 10 times
phys defined in line 743; used 3 times
rkunit defined in line 56; used 11 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2279
Valid CSS Valid XHTML 1.0 Strict