Annotation of 41BSD/4.0.upgrade/sys/dev/rk.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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