Annotation of 42BSD/sys/vaxuba/rk.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.