Annotation of researchv8dc/sys/dev/hp.c, revision 1.1.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.