Annotation of researchv8dc/sys/dev/hp.c, revision 1.1

1.1     ! root        1: /*     hp.c    4.47    82/02/18        */
        !             2: 
        !             3: #ifdef HPDEBUG
        !             4: int    hpdebug;
        !             5: #endif
        !             6: #ifdef HPBDEBUG
        !             7: int    hpbdebug;
        !             8: #endif
        !             9: 
        !            10: #include "hp.h"
        !            11: #if NHP > 0
        !            12: /*
        !            13:  * HP disk driver for RP0x+RMxx+ML11
        !            14:  *
        !            15:  * TODO:
        !            16:  *     check RM80 skip sector handling when ECC's occur later
        !            17:  *     check offset recovery handling
        !            18:  *     see if DCLR and/or RELEASE set attention status
        !            19:  *     print bits of mr && mr2 symbolically
        !            20:  */
        !            21: 
        !            22: #include "../h/param.h"
        !            23: #include "../h/systm.h"
        !            24: #include "../h/dk.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/pte.h"
        !            31: #include "../h/mbareg.h"
        !            32: #include "../h/mbavar.h"
        !            33: #include "../h/mtpr.h"
        !            34: #include "../h/vm.h"
        !            35: #include "../h/cmap.h"
        !            36: #include "../h/dkbad.h"
        !            37: #include "../h/dkio.h"
        !            38: 
        !            39: #include "../h/hpreg.h"
        !            40: 
        !            41: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
        !            42: struct size {
        !            43:        daddr_t nblocks;
        !            44:        int     cyloff;
        !            45: } hp6_sizes[8] = {
        !            46:        15884,  0,              /* A=cyl 0 thru 37 */
        !            47:        33440,  38,             /* B=cyl 38 thru 117 */
        !            48:        340670, 0,              /* C=cyl 0 thru 814 */
        !            49:        0,      0,
        !            50:        0,      0,
        !            51:        0,      0,
        !            52: #ifndef NOBADSECT
        !            53:        291280, 118,            /* G=cyl 118 thru 814 */
        !            54: #else
        !            55:        291346, 118,
        !            56: #endif
        !            57:        0,      0,
        !            58: }, rm3_sizes[8] = {
        !            59:        15884,  0,              /* A=cyl 0 thru 99 */
        !            60:        33440,  100,            /* B=cyl 100 thru 309 */
        !            61:        131680, 0,              /* C=cyl 0 thru 822 */
        !            62:        0,      0,
        !            63:        0,      0,
        !            64:        0,      0,
        !            65: #ifndef NOBADSECT
        !            66:        81984,  310,            /* G=cyl 310 thru 822 */
        !            67: #else
        !            68:        82080,  310,
        !            69: #endif
        !            70:        0,      0,
        !            71: }, rm5_sizes[8] = {
        !            72:        15884,  0,              /* A=cyl 0 thru 26 */
        !            73:        33440,  27,             /* B=cyl 27 thru 81 */
        !            74:        500384, 0,              /* C=cyl 0 thru 822 */
        !            75:        15884,  562,            /* D=cyl 562 thru 588 */
        !            76:        55936,  589,            /* E=cyl 589 thru 680 */
        !            77: #ifndef NOBADSECT
        !            78:        86240,  681,            /* F=cyl 681 thru 822 */
        !            79:        158592, 562,            /* G=cyl 562 thru 822 */
        !            80: #else
        !            81:        86636,  681,
        !            82:        158688, 562,
        !            83: #endif
        !            84:        291346, 82,             /* H=cyl 82 thru 561 */
        !            85: }, rm80_sizes[8] = {
        !            86:        15884,  0,              /* A=cyl 0 thru 36 */
        !            87:        33440,  37,             /* B=cyl 37 thru 114 */
        !            88:        242606, 0,              /* C=cyl 0 thru 558 */
        !            89:        0,      0,
        !            90:        0,      0,
        !            91:        192223, 115,            /* F=cyl 115 thru 558 */
        !            92:        82080,  115,            /* G=cyl 115 thru 304 */
        !            93:        110143, 305,            /* H=cyl 305 thru 558 */
        !            94: }, mfj_sizes[8] = {
        !            95:        10240,  0,              /* A=cyl 0 thru 31 */
        !            96:        20480,  32,             /* B=cyl 32 thru 95 */
        !            97:        232640, 96,             /* C=cyl 96 thru 822 */
        !            98:        0,      0,
        !            99:        0,      0,
        !           100:        0,      0,
        !           101:        0,      0,
        !           102:        0,      0,
        !           103: }, eagle_sizes[8] ={
        !           104:        27520,  0,              /* A=cyl 0 thru 31 */
        !           105:        27520,  32,             /* B=cyl 32 thru 63 */
        !           106:        667360, 64,             /* C=cyl 64 thru 839 */
        !           107:        232640, 64,             /* D=cyl 64 thru 340 (partial) */
        !           108:        232640, 341,            /* E=cyl 341 thru 617 (partial) */
        !           109:        0,      0,
        !           110:        0,      0,
        !           111:        0,      0,
        !           112: /* 48 sector Emulex Eagle */
        !           113: }, eag48_sizes[8] = {  /* cyl 841 used for bad sectors + info */
        !           114: 
        !           115:        45*960,   0,    /* A = cyl 0 thru 44            for /tmp */
        !           116:        64*960,  45,    /* B = cyl 45 thru 108          for swap */
        !           117:        842*960,  0,    /* C = all cyl 0 thru 841       for testing */
        !           118:        244*960,109,    /* D = cyl 109 thru 352         nearly 1/3 */
        !           119:        244*960,353,    /* E = cyl 353 thru 596         nearly 1/3 */
        !           120:        244*960,597,    /* F = cyl 597 thru 840         nearly 1/3 */
        !           121:        0,      0,      /* G = cyl 0 thru 402           nearly 1/2 */
        !           122:        0,      0,      /* H = cyl 438 thru 840         nearly 1/2 */
        !           123: }, hp7_sizes[8] = {
        !           124:        15884,  0,              /* A=cyl 0 thru 9 */
        !           125:        64000,  10,             /* B=cyl 10 thru 49 */
        !           126:        1008000,0,              /* C=cyl 0 thru 629 */
        !           127:        504000, 0,              /* D=cyl 0 thru 314 */
        !           128:        504000, 315,            /* E=cyl 315 thru 629 */
        !           129:        928000, 50,             /* F=cyl 50 thru 629 */
        !           130:        0,      0,
        !           131:        0,      0,
        !           132: };
        !           133: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
        !           134: 
        !           135: #ifndef JONES
        !           136: #define        _hpSDIST        2
        !           137: #define        _hpRDIST        3
        !           138: #else JONES
        !           139: /*
        !           140:        these constants were originally 2 and 3 respectively.  they
        !           141:        have been changed to improve the performance of the eagle
        !           142:        drives with the emulex controller.  to date, 8,9 is better than
        !           143:        2,3.  12,13 did not do any better than 8,9.  changing these
        !           144:        constants changes the lead for all drives using the hp driver
        !           145:        including the rm80.  that's a mistake, but empirically,
        !           146:        changing these to 8,9 did not measurably change rm80
        !           147:        performance.
        !           148: */
        !           149: #define        _hpSDIST        8
        !           150: #define        _hpRDIST        9
        !           151: #endif JONES
        !           152: 
        !           153: int    hpSDIST = _hpSDIST;
        !           154: int    hpRDIST = _hpRDIST;
        !           155: 
        !           156: short  hptypes[] =
        !           157:        { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07,
        !           158:          MBDT_FUJI, MBDT_FUJI, MBDT_FUJI, MBDT_ML11A, MBDT_ML11B, 0 };
        !           159: struct mba_device *hpinfo[NHP];
        !           160: int    hpattach(),hpustart(),hpstart(),hpdtint();
        !           161: struct mba_driver hpdriver =
        !           162:        { hpattach, 0, hpustart, hpstart, hpdtint, 0,
        !           163:          hptypes, "hp", 0, hpinfo };
        !           164: 
        !           165: struct hpst {
        !           166:        short   nsect;
        !           167:        short   ntrak;
        !           168:        short   nspc;
        !           169:        short   ncyl;
        !           170:        struct  size *sizes;
        !           171: } hpst[] = {
        !           172:        32,     5,      32*5,   823,    rm3_sizes,      /* RM03 */
        !           173:        32,     19,     32*19,  823,    rm5_sizes,      /* RM05 */
        !           174:        22,     19,     22*19,  815,    hp6_sizes,      /* RP06 */
        !           175:        31,     14,     31*14,  559,    rm80_sizes,     /* RM80 */
        !           176:        22,     19,     22*19,  411,    hp6_sizes,      /* RP05 */
        !           177:        50,     32,     50*32,  630,    hp7_sizes,      /* RP07 */
        !           178:        /* the following three entries must be contiguous */
        !           179:        32,     10,     32*10,  823,    mfj_sizes,      /* little fujitsu */
        !           180:        43,     20,     43*20,  842,    eagle_sizes,    /* eagle */
        !           181:        48,     20,     48*20,  842,    eag48_sizes,    /* eagle 48 sectors */
        !           182:        1,      1,      1,      1,      0,              /* ML11A */
        !           183:        1,      1,      1,      1,      0,              /* ML11B */
        !           184: };
        !           185: 
        !           186: u_char hp_offset[16] = {
        !           187:     HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
        !           188:     HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800,
        !           189:     HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200,
        !           190:     0, 0, 0, 0,
        !           191: };
        !           192: 
        !           193: struct buf     rhpbuf[NHP];
        !           194: #ifndef NOBADSECT
        !           195: struct buf     bhpbuf[NHP];
        !           196: struct dkbad   hpbad[NHP];
        !           197: #endif
        !           198: char   hpinit[NHP];
        !           199: char   hprecal[NHP];
        !           200: char   hphdr[NHP];
        !           201: daddr_t        mlsize[NHP];
        !           202: 
        !           203: #define        b_cylin b_resid
        !           204:  
        !           205: /* #define ML11 0  to remove ML11 support */
        !           206: #define ML11   0
        !           207: /*#define      ML11    (hptypes[mi->mi_type] == MBDT_ML11A)*/
        !           208: #define        RP06    (hptypes[mi->mi_type] <= MBDT_RP06)
        !           209: #define        RM80    (hptypes[mi->mi_type] == MBDT_RM80)
        !           210: 
        !           211: #ifdef INTRLVE
        !           212: daddr_t dkblock();
        !           213: #endif
        !           214:  
        !           215: int    hpseek;
        !           216: 
        !           217: /*ARGSUSED*/
        !           218: hpattach(mi, slave)
        !           219:        struct mba_device *mi;
        !           220: {
        !           221:        register struct hpst *st = &hpst[mi->mi_type];
        !           222: 
        !           223:        if (hptypes[mi->mi_type] == MBDT_ML11B)
        !           224:                mi->mi_type--;  /* A CHEAT - ML11B D.T. SHOULD == ML11A */
        !           225:        if (ML11) {
        !           226:                register struct hpdevice *hpaddr =
        !           227:                        (struct hpdevice *)mi->mi_drv;
        !           228:                register int trt, sz;
        !           229: 
        !           230:                sz = hpaddr->hpmr & HPMR_SZ;
        !           231:                if ((hpaddr->hpmr & HPMR_ARRTYP) == 0)
        !           232:                        sz >>= 2;
        !           233:                mlsize[mi->mi_unit] = sz;
        !           234:                if (mi->mi_dk >= 0) {
        !           235:                        trt = (hpaddr->hpmr & HPMR_TRT) >> 8;
        !           236:                        dk_mspw[mi->mi_dk] = 1.0 / (1<<(20-trt));
        !           237:                }
        !           238:        } else if (mi->mi_dk >= 0) {
        !           239:                register struct hpdevice *hp;
        !           240:                register int type;
        !           241: 
        !           242:                hp = (struct hpdevice *) mi->mi_drv;
        !           243:                type = hp->hpdt & MBDT_TYPE;
        !           244:                if (type == MBDT_FUJI) {
        !           245:                        short maxtrk, maxsect;
        !           246:                        /*
        !           247:                         *      we have some kind of disk on an Emulex SC750.
        !           248:                         *      We assume it's a little Fuji, and must now check
        !           249:                         *      if it's an Eagle.
        !           250:                         */
        !           251:                        hp->hphr = HPHR_MAXTRK;
        !           252:                        maxtrk = hp->hphr;
        !           253:                        if (maxtrk >= hpst[mi->mi_type].ntrak) {
        !           254:                                mi->mi_type++;
        !           255:                                /* it's an Eagle. now check # of sectors */
        !           256:                                hp->hphr = HPHR_MAXSECT;
        !           257:                                maxsect = hp->hphr;
        !           258:                                if (maxsect > hpst[mi->mi_type].nsect) {
        !           259:                                        printf("%d sectors\n", maxsect);
        !           260:                                        mi->mi_type++;
        !           261:                                }
        !           262:                        }
        !           263:                }
        !           264:                st = &hpst[mi->mi_type];
        !           265:                dk_mspw[mi->mi_dk] = 1.0 / 60 / (st->nsect * 256);
        !           266:        }
        !           267: }
        !           268: 
        !           269: hpstrategy(bp)
        !           270:        register struct buf *bp;
        !           271: {
        !           272:        register struct mba_device *mi;
        !           273:        register struct hpst *st;
        !           274:        register int unit;
        !           275:        long sz, bn;
        !           276:        int xunit = minor(bp->b_dev) & 07;
        !           277:        int s;
        !           278: 
        !           279:        sz = bp->b_bcount;
        !           280:        sz = (sz+511) >> 9;
        !           281:        unit = dkunit(bp);
        !           282:        if (unit >= NHP)
        !           283:                goto bad;
        !           284:        mi = hpinfo[unit];
        !           285:        if (mi == 0 || mi->mi_alive == 0)
        !           286:                goto bad;
        !           287:        st = &hpst[mi->mi_type];
        !           288:        if (ML11) {
        !           289:                if (bp->b_blkno < 0 || dkblock(bp)+sz > mlsize[mi->mi_unit])
        !           290:                        goto bad;
        !           291:                bp->b_cylin = 0;
        !           292:        } else {
        !           293:                if (bp->b_blkno < 0 ||
        !           294:                        (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
        !           295:                        goto bad;
        !           296:                bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
        !           297:        }
        !           298:        s = spl5();
        !           299:        disksort(&mi->mi_tab, bp);
        !           300:        if (mi->mi_tab.b_active == 0)
        !           301:                mbustart(mi);
        !           302:        splx(s);
        !           303:        return;
        !           304: 
        !           305: bad:
        !           306:        bp->b_flags |= B_ERROR;
        !           307:        iodone(bp);
        !           308:        return;
        !           309: }
        !           310: 
        !           311: hpustart(mi)
        !           312:        register struct mba_device *mi;
        !           313: {
        !           314:        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        !           315:        register struct buf *bp = mi->mi_tab.b_actf;
        !           316:        register struct hpst *st = &hpst[mi->mi_type];
        !           317:        daddr_t bn;
        !           318:        int sn, dist;
        !           319: 
        !           320:        hpaddr->hpcs1 = 0;
        !           321:        if ((hpaddr->hpcs1&HP_DVA) == 0)
        !           322:                return (MBU_BUSY);
        !           323:        if ((hpaddr->hpds & HPDS_VV) == 0 || hpinit[mi->mi_unit] == 0) {
        !           324: #ifndef NOBADSECT
        !           325:                struct buf *bbp = &bhpbuf[mi->mi_unit];
        !           326: #endif
        !           327: 
        !           328:                hpinit[mi->mi_unit] = 1;
        !           329:                hpaddr->hpcs1 = HP_DCLR|HP_GO;
        !           330:                if (mi->mi_mba->mba_drv[0].mbd_as & (1<<mi->mi_drive))
        !           331:                        printf("DCLR attn\n");
        !           332:                hpaddr->hpcs1 = HP_PRESET|HP_GO;
        !           333:                if (!ML11)
        !           334:                        hpaddr->hpof = HPOF_FMT22;
        !           335:                mbclrattn(mi);
        !           336: #ifndef NOBADSECT
        !           337:                if (!ML11) {
        !           338:                        bbp->b_flags = B_READ|B_BUSY;
        !           339:                        bbp->b_dev = bp->b_dev;
        !           340:                        bbp->b_bcount = 512;
        !           341:                        bbp->b_un.b_addr = (caddr_t)&hpbad[mi->mi_unit];
        !           342:                        bbp->b_blkno = st->ncyl*st->nspc - st->nsect;
        !           343:                        bbp->b_cylin = st->ncyl - 1;
        !           344:                        mi->mi_tab.b_actf = bbp;
        !           345:                        bbp->av_forw = bp;
        !           346:                        bp = bbp;
        !           347:                }
        !           348: #endif
        !           349:        }
        !           350:        if (mi->mi_tab.b_active || mi->mi_hd->mh_ndrive == 1)
        !           351:                return (MBU_DODATA);
        !           352:        if (ML11)
        !           353:                return (MBU_DODATA);
        !           354:        if ((hpaddr->hpds & HPDS_DREADY) != HPDS_DREADY)
        !           355:                return (MBU_DODATA);
        !           356:        bn = dkblock(bp);
        !           357:        sn = bn%st->nspc;
        !           358:        sn = (sn+st->nsect-hpSDIST)%st->nsect;
        !           359:        if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) {
        !           360:                if (hpseek)
        !           361:                        return (MBU_DODATA);
        !           362:                dist = ((hpaddr->hpla & 0xffff)>>6) - st->nsect + 1;
        !           363:                if (dist < 0)
        !           364:                        dist += st->nsect;
        !           365:                if (dist > st->nsect - hpRDIST)
        !           366:                        return (MBU_DODATA);
        !           367:        } else
        !           368:                hpaddr->hpdc = bp->b_cylin;
        !           369:        if (hpseek)
        !           370:                hpaddr->hpcs1 = HP_SEEK|HP_GO;
        !           371:        else {
        !           372:                hpaddr->hpda = sn;
        !           373:                hpaddr->hpcs1 = HP_SEARCH|HP_GO;
        !           374:        }
        !           375:        return (MBU_STARTED);
        !           376: }
        !           377: 
        !           378: hpstart(mi)
        !           379:        register struct mba_device *mi;
        !           380: {
        !           381:        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        !           382:        register struct buf *bp = mi->mi_tab.b_actf;
        !           383:        register struct hpst *st = &hpst[mi->mi_type];
        !           384:        daddr_t bn;
        !           385:        int sn, tn;
        !           386: 
        !           387:        bn = dkblock(bp);
        !           388:        if (ML11)
        !           389:                hpaddr->hpda = bn;
        !           390:        else {
        !           391:                sn = bn%st->nspc;
        !           392:                tn = sn/st->nsect;
        !           393:                sn %= st->nsect;
        !           394:                hpaddr->hpdc = bp->b_cylin;
        !           395:                hpaddr->hpda = (tn << 8) + sn;
        !           396:        }
        !           397:        if (hphdr[mi->mi_unit]) {
        !           398:                if (bp->b_flags & B_READ)
        !           399:                        return (HP_RHDR|HP_GO);
        !           400:                else
        !           401:                        return (HP_WHDR|HP_GO);
        !           402:        }
        !           403:        return (0);
        !           404: }
        !           405: 
        !           406: hpdtint(mi, mbsr)
        !           407:        register struct mba_device *mi;
        !           408:        int mbsr;
        !           409: {
        !           410:        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        !           411:        register struct buf *bp = mi->mi_tab.b_actf;
        !           412:        register int er1, er2;
        !           413:        int retry = 0;
        !           414: 
        !           415: #ifndef NOBADSECT
        !           416:        if (bp->b_flags&B_BAD) {
        !           417:                if (hpecc(mi, CONT))
        !           418:                        return(MBD_RESTARTED);
        !           419:        }
        !           420: #endif
        !           421:        if (hpaddr->hpds&HPDS_ERR || mbsr&MBSR_EBITS) {
        !           422: #ifdef HPDEBUG
        !           423:                if (hpdebug) {
        !           424:                        int dc = hpaddr->hpdc, da = hpaddr->hpda;
        !           425:                        struct hpst *st = &hpst[mi->mi_type];
        !           426: 
        !           427:                        printf("hperr: bp %x cyl %d blk %d as %o ",
        !           428:                                bp, bp->b_cylin, bp->b_blkno,
        !           429:                                hpaddr->hpas&0xff);
        !           430:                        printf("dc %x da %x\n",dc&0xffff, da&0xffff);
        !           431:                        printf("errcnt %d ", mi->mi_tab.b_errcnt);
        !           432:                        printf("mbsr=%b ", mbsr, mbsr_bits);
        !           433:                        printf("er1=%b er2=%b\n",
        !           434:                            hpaddr->hper1, HPER1_BITS,
        !           435:                            hpaddr->hper2, HPER2_BITS);
        !           436:                        DELAY(1000000);
        !           437:                }
        !           438: #endif
        !           439:                er1 = hpaddr->hper1;
        !           440:                er2 = hpaddr->hper2;
        !           441:                if (er1 & HPER1_HCRC) {
        !           442:                        er1 &= ~(HPER1_HCE|HPER1_FER);
        !           443:                        er2 &= ~HPER2_BSE;
        !           444:                }
        !           445:                if (er1&HPER1_WLE) {
        !           446:                        printf("hp%d: write locked\n", dkunit(bp));
        !           447:                        bp->b_flags |= B_ERROR;
        !           448:                } else if ((er1&0xffff) == HPER1_FER && RP06 &&
        !           449:                    hphdr[mi->mi_unit] == 0) {
        !           450: #ifndef NOBADSECT
        !           451:                        if (hpecc(mi, BSE))
        !           452:                        {
        !           453: #ifdef HPBDEBUG
        !           454:                                if (hpdebug)
        !           455:                                        printf("MBD_RESTARTED\n");
        !           456: #endif
        !           457:                                return(MBD_RESTARTED);
        !           458:                        }
        !           459:                        else
        !           460: #endif
        !           461:                                goto hard;
        !           462:                } else if (++mi->mi_tab.b_errcnt > 27 ||
        !           463:                    mbsr & MBSR_HARD ||
        !           464:                    er1 & HPER1_HARD ||
        !           465:                    hphdr[mi->mi_unit] ||
        !           466:                    (!ML11 && (er2 & HPER2_HARD))) {
        !           467: hard:
        !           468:                        harderr(bp, "hp");
        !           469:                        if (mbsr & (MBSR_EBITS &~ (MBSR_DTABT|MBSR_MBEXC)))
        !           470:                                printf("mbsr=%b ", mbsr, mbsr_bits);
        !           471:                        printf("er1=%b er2=%b",
        !           472:                            hpaddr->hper1, HPER1_BITS,
        !           473:                            hpaddr->hper2, HPER2_BITS);
        !           474:                        if (hpaddr->hpmr)
        !           475:                                printf(" mr=%o", hpaddr->hpmr&0xffff);
        !           476:                        if (hpaddr->hpmr2)
        !           477:                                printf(" mr2=%o", hpaddr->hpmr2&0xffff);
        !           478:                        printf("\n");
        !           479:                        bp->b_flags |= B_ERROR;
        !           480:                        hprecal[mi->mi_unit] = 0;
        !           481:                } else if ((er2 & HPER2_BSE) && !ML11) {
        !           482: #ifndef NOBADSECT
        !           483:                        if (hpecc(mi, BSE))
        !           484:                                return(MBD_RESTARTED);
        !           485:                        else
        !           486: #endif
        !           487:                                goto hard;
        !           488:                } else if (RM80 && er2&HPER2_SSE) {
        !           489:                        (void) hpecc(mi, SSE);
        !           490:                        return (MBD_RESTARTED);
        !           491:                } else if ((er1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) {
        !           492:                        if (hpecc(mi, ECC))
        !           493:                                return (MBD_RESTARTED);
        !           494:                        /* else done */
        !           495:                } else
        !           496:                        retry = 1;
        !           497:                hpaddr->hpcs1 = HP_DCLR|HP_GO;
        !           498:                if (ML11) {
        !           499:                        if (mi->mi_tab.b_errcnt >= 16)
        !           500:                                goto hard;
        !           501:                } else if ((mi->mi_tab.b_errcnt&07) == 4) {
        !           502:                        hpaddr->hpcs1 = HP_RECAL|HP_GO;
        !           503:                        hprecal[mi->mi_unit] = 1;
        !           504:                        return(MBD_RESTARTED);
        !           505:                }
        !           506:                if (retry)
        !           507:                        return (MBD_RETRY);
        !           508:        }
        !           509: #ifdef HPDEBUG
        !           510:        else
        !           511:                if (hpdebug && hprecal[mi->mi_unit]) {
        !           512:                        printf("recal %d ", hprecal[mi->mi_unit]);
        !           513:                        printf("errcnt %d\n", mi->mi_tab.b_errcnt);
        !           514:                        printf("mbsr=%b ", mbsr, mbsr_bits);
        !           515:                        printf("er1=%b er2=%b\n",
        !           516:                            hpaddr->hper1, HPER1_BITS,
        !           517:                            hpaddr->hper2, HPER2_BITS);
        !           518:                }
        !           519: #endif
        !           520:        switch (hprecal[mi->mi_unit]) {
        !           521: 
        !           522:        case 1:
        !           523:                hpaddr->hpdc = bp->b_cylin;
        !           524:                hpaddr->hpcs1 = HP_SEEK|HP_GO;
        !           525:                hprecal[mi->mi_unit]++;
        !           526:                return (MBD_RESTARTED);
        !           527:        case 2:
        !           528:                if (mi->mi_tab.b_errcnt < 16 ||
        !           529:                    (bp->b_flags & B_READ) == 0)
        !           530:                        goto donerecal;
        !           531:                hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22;
        !           532:                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
        !           533:                hprecal[mi->mi_unit]++;
        !           534:                return (MBD_RESTARTED);
        !           535:        donerecal:
        !           536:        case 3:
        !           537:                hprecal[mi->mi_unit] = 0;
        !           538:                return (MBD_RETRY);
        !           539:        }
        !           540:        hphdr[mi->mi_unit] = 0;
        !           541:        bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
        !           542:        if (mi->mi_tab.b_errcnt >= 16) {
        !           543:                /*
        !           544:                 * This is fast and occurs rarely; we don't
        !           545:                 * bother with interrupts.
        !           546:                 */
        !           547:                hpaddr->hpcs1 = HP_RTC|HP_GO;
        !           548:                while (hpaddr->hpds & HPDS_PIP)
        !           549:                        ;
        !           550:                mbclrattn(mi);
        !           551:        }
        !           552:        if (!ML11) {
        !           553:                hpaddr->hpof = HPOF_FMT22;
        !           554:                hpaddr->hpcs1 = HP_RELEASE|HP_GO;
        !           555:        }
        !           556:        return (MBD_DONE);
        !           557: }
        !           558: 
        !           559: hpread(dev)
        !           560:        dev_t dev;
        !           561: {
        !           562:        register int unit = minor(dev) >> 3;
        !           563: 
        !           564:        if (unit >= NHP)
        !           565:                u.u_error = ENXIO;
        !           566:        else
        !           567:                physio(hpstrategy, &rhpbuf[unit], dev, B_READ, minphys);
        !           568: }
        !           569: 
        !           570: hpwrite(dev)
        !           571:        dev_t dev;
        !           572: {
        !           573:        register int unit = minor(dev) >> 3;
        !           574: 
        !           575:        if (unit >= NHP)
        !           576:                u.u_error = ENXIO;
        !           577:        else
        !           578:                physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys);
        !           579: }
        !           580: 
        !           581: /*ARGSUSED*/
        !           582: hpioctl(dev, cmd, addr, flag)
        !           583:        dev_t dev;
        !           584:        int cmd;
        !           585:        caddr_t addr;
        !           586:        int flag;
        !           587: {
        !           588: 
        !           589:        switch (cmd) {
        !           590:        case DKIOCHDR:  /* do header read/write */
        !           591:                if (suser())
        !           592:                        hphdr[minor(dev)>>3] = 1;
        !           593:                return;
        !           594: 
        !           595:        default:
        !           596:                u.u_error = ENXIO;
        !           597:        }
        !           598: }
        !           599: 
        !           600: hpecc(mi, flag)
        !           601:        register struct mba_device *mi;
        !           602:        int flag;
        !           603: {
        !           604:        register struct mba_regs *mbp = mi->mi_mba;
        !           605:        register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv;
        !           606:        register struct buf *bp = mi->mi_tab.b_actf;
        !           607:        register struct hpst *st = &hpst[mi->mi_type];
        !           608:        int npf, o;
        !           609:        int bn, cn, tn, sn;
        !           610:        int bcr;
        !           611:        static nerr;
        !           612: 
        !           613:        bcr = mbp->mba_bcr & 0xffff;
        !           614:        if (bcr)
        !           615:                bcr |= 0xffff0000;              /* sxt */
        !           616: #ifndef NOBADSECT
        !           617:        if (flag == CONT)
        !           618:                npf = bp->b_error;
        !           619:        else
        !           620: #endif
        !           621:                npf = btop(bcr + bp->b_bcount);
        !           622:        o = (int)bp->b_un.b_addr & PGOFSET;
        !           623:        bn = dkblock(bp);
        !           624: #ifdef HPBDEBUG
        !           625:        if (hpbdebug)   
        !           626:        printf("hpecc: mbp->mba_bcr %x bcr %x bp->b_bcount %x bp->b_error %x bn %x npf %x\n",
        !           627:                mbp->mba_bcr, bcr, bp->b_bcount, bp->b_error, bn, npf);
        !           628:        if (hpbdebug)
        !           629:        printf("ber npf: %x\n", ((rp->hpdc & 0xffff) * (st->nspc))
        !           630:                                          + ((((rp->hpda) >> 8) & 0xff) * st->nsect)
        !           631:                                      + ((rp->hpda) & 0xff)
        !           632:                                          - (((st->sizes[minor(bp->b_dev)&07].cyloff) * st->nspc)
        !           633:                                           + 1 + bn));
        !           634: #endif
        !           635:        cn = bp->b_cylin;
        !           636:        sn = bn%(st->nspc) + npf;
        !           637:        tn = sn/st->nsect;
        !           638:        sn %= st->nsect;
        !           639:        cn += tn/st->ntrak;
        !           640:        tn %= st->ntrak;
        !           641:        switch (flag) {
        !           642:        case ECC:
        !           643:                {
        !           644:                register int i;
        !           645:                caddr_t addr;
        !           646:                struct pte mpte;
        !           647:                int bit, byte, mask;
        !           648: 
        !           649:                npf--;          /* because block in error is previous block */
        !           650:                printf("hp%d%c: soft ecc sn%d\n", dkunit(bp),
        !           651:                    'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
        !           652:                nerr++;
        !           653:                if ((nerr%100)==0)
        !           654:                        printf("%d soft errors\n", nerr);
        !           655:                mask = rp->hpec2&0xffff;
        !           656:                i = (rp->hpec1&0xffff) - 1;             /* -1 makes 0 origin */
        !           657:                bit = i&07;
        !           658:                i = (i&~07)>>3;
        !           659:                byte = i + o;
        !           660:                while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
        !           661:                        mpte = mbp->mba_map[npf+btop(byte)];
        !           662:                        addr = ptob(mpte.pg_pfnum) + (byte & PGOFSET);
        !           663:                        putmemc(addr, getmemc(addr)^(mask<<bit));
        !           664:                        byte++;
        !           665:                        i++;
        !           666:                        bit -= 8;
        !           667:                }
        !           668:                if (bcr == 0)
        !           669:                        return (0);
        !           670:                npf++;
        !           671:                break;
        !           672:                }
        !           673: 
        !           674:        case SSE:
        !           675: #ifdef HPBDEBUG
        !           676:                if (hpbdebug)
        !           677:                printf("hpeccSSE\n");
        !           678: #endif
        !           679:                rp->hpof |= HPOF_SSEI;
        !           680:                mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));
        !           681:                break;
        !           682: 
        !           683: #ifndef NOBADSECT
        !           684:        case BSE:
        !           685: #ifdef HPBDEBUG
        !           686:                if (hpbdebug)
        !           687:                printf("hpeccBSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
        !           688: #endif
        !           689:                if ((bn = isbad(&hpbad[mi->mi_unit], cn, tn, sn)) < 0)
        !           690:                        return(0);
        !           691:                bp->b_flags |= B_BAD;
        !           692:                bp->b_error = npf + 1;
        !           693:                bn = st->ncyl*st->nspc - st->nsect - 1 - bn;
        !           694:                cn = bn/st->nspc;
        !           695:                sn = bn%st->nspc;
        !           696:                tn = sn/st->nsect;
        !           697:                sn %= st->nsect;
        !           698:                mbp->mba_bcr = -512;
        !           699: #ifdef HPBDEBUG
        !           700:                if (hpbdebug)
        !           701:                printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
        !           702: #endif
        !           703:                break;
        !           704: 
        !           705:        case CONT:
        !           706: #ifdef HPBDEBUG
        !           707:                if (hpbdebug)
        !           708:                printf("hpecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);
        !           709: #endif
        !           710:                npf = bp->b_error;
        !           711:                bp->b_flags &= ~B_BAD;
        !           712:                mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));
        !           713:                if ((mbp->mba_bcr & 0xffff) == 0)
        !           714:                        return(0);
        !           715:                break;
        !           716: #endif
        !           717:        }
        !           718: #ifdef HPBDEBUG
        !           719:        if (hpbdebug)
        !           720:        printf("hpecc, endcase: bn %d\n",bn);
        !           721: #endif
        !           722:        rp->hpcs1 = HP_DCLR|HP_GO;
        !           723:        if (rp->hpof&HPOF_SSEI)
        !           724:                sn++;
        !           725:        rp->hpdc = cn;
        !           726:        rp->hpda = (tn<<8) + sn;
        !           727:        mbp->mba_sr = -1;
        !           728:        mbp->mba_var = (int)ptob(npf) + o;
        !           729:        rp->hpcs1 = bp->b_flags&B_READ ? HP_RCOM|HP_GO : HP_WCOM|HP_GO;
        !           730:        mi->mi_tab.b_errcnt = 0;        /* error has been corrected */
        !           731:        return (1);
        !           732: }
        !           733: 
        !           734: #define        DBSIZE  20
        !           735: 
        !           736: hpdump(dev)
        !           737:        dev_t dev;
        !           738: {
        !           739:        register struct mba_device *mi;
        !           740:        register struct mba_regs *mba;
        !           741:        struct hpdevice *hpaddr;
        !           742:        char *start;
        !           743:        int num, unit;
        !           744:        register struct hpst *st;
        !           745: 
        !           746:        num = maxfree;
        !           747:        start = 0;
        !           748:        unit = minor(dev) >> 3;
        !           749:        if (unit >= NHP)
        !           750:                return (ENXIO);
        !           751: #define        phys(a,b)       ((b)((int)(a)&0x7fffffff))
        !           752:        mi = phys(hpinfo[unit],struct mba_device *);
        !           753:        if (mi == 0 || mi->mi_alive == 0)
        !           754:                return (ENXIO);
        !           755:        mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
        !           756:        mba->mba_cr = MBCR_INIT;
        !           757:        hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive];
        !           758:        if ((hpaddr->hpds & HPDS_VV) == 0) {
        !           759:                hpaddr->hpcs1 = HP_DCLR|HP_GO;
        !           760:                hpaddr->hpcs1 = HP_PRESET|HP_GO;
        !           761:                hpaddr->hpof = HPOF_FMT22;
        !           762:        }
        !           763:        st = &hpst[mi->mi_type];
        !           764:        if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks)
        !           765:                return (EINVAL);
        !           766:        while (num > 0) {
        !           767:                register struct pte *hpte = mba->mba_map;
        !           768:                register int i;
        !           769:                int blk, cn, sn, tn;
        !           770:                daddr_t bn;
        !           771: 
        !           772:                blk = num > DBSIZE ? DBSIZE : num;
        !           773:                bn = dumplo + btop(start);
        !           774:                cn = bn/st->nspc + st->sizes[minor(dev)&07].cyloff;
        !           775:                sn = bn%st->nspc;
        !           776:                tn = sn/st->nsect;
        !           777:                sn = sn%st->nsect;
        !           778:                hpaddr->hpdc = cn;
        !           779:                hpaddr->hpda = (tn << 8) + sn;
        !           780:                for (i = 0; i < blk; i++)
        !           781:                        *(int *)hpte++ = (btop(start)+i) | PG_V;
        !           782:                mba->mba_sr = -1;
        !           783:                mba->mba_bcr = -(blk*NBPG);
        !           784:                mba->mba_var = 0;
        !           785:                hpaddr->hpcs1 = HP_WCOM | HP_GO;
        !           786:                while ((hpaddr->hpds & HPDS_DRY) == 0)
        !           787:                        ;
        !           788:                if (hpaddr->hpds&HPDS_ERR)
        !           789:                        return (EIO);
        !           790:                start += blk*NBPG;
        !           791:                num -= blk;
        !           792:        }
        !           793:        return (0);
        !           794: }
        !           795: #endif

unix.superglobalmegacorp.com

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