Annotation of 43BSDTahoe/sys/vaxstand/format.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980, 1986 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980, 1986 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif /* not lint */
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)format.c   7.4 (Berkeley) 5/27/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: /* 
        !            18:  * Standalone program to do media checking
        !            19:  * and record bad block information on any 
        !            20:  * disk with the appropriate driver and RM03-style headers.
        !            21:  * TODO:
        !            22:  *     add new bad sectors to bad-sector table when formatting by track
        !            23:  *             (rearranging replacements ala bad144 -a)
        !            24:  *     multi-pass format for disks with skip-sector capability
        !            25:  */
        !            26: #include "param.h"
        !            27: #include "fs.h"
        !            28: #include "inode.h"
        !            29: #include "dkbad.h"
        !            30: #include "vmmac.h"
        !            31: #include "disklabel.h"
        !            32: 
        !            33: #include "../vax/cpu.h"
        !            34: #include "../vax/mtpr.h"
        !            35: 
        !            36: #include "saio.h"
        !            37: #include "savax.h"
        !            38: 
        !            39: #define MAXBADDESC     126             /* size of bad block table */
        !            40: #define CHUNK          48              /* max # of sectors/io operation */
        !            41: #define SECTSIZ                512             /* standard sector size */
        !            42: #define HDRSIZ         4               /* number of bytes in sector header */
        !            43: 
        !            44: #define SSERR          0
        !            45: #define BSERR          1
        !            46: 
        !            47: #define SSDEV(fd)      (ioctl((fd), SAIOSSDEV, (char *)0) == 0)
        !            48: #define MAXECCBITS     3
        !            49: 
        !            50: struct sector {
        !            51:        u_short header1;
        !            52:        u_short header2;
        !            53:        char    buf[SECTSIZ];
        !            54: };
        !            55: 
        !            56: struct dkbad dkbad;            /* bad sector table */
        !            57: struct dkbad oldbad;           /* old bad sector table */
        !            58: struct dkbad sstab;            /* skip sector table */
        !            59: 
        !            60: #define        NERRORS         6
        !            61: static char *
        !            62: errornames[NERRORS] = {
        !            63: #define        FE_BSE          0
        !            64:        "Bad sector",
        !            65: #define        FE_WCE          1
        !            66:        "Write check",
        !            67: #define        FE_ECC          2
        !            68:        "Hard ECC",
        !            69: #define        FE_HARD         3
        !            70:        "Other hard",
        !            71: #define        FE_TOTAL        4
        !            72:        "Marked bad",
        !            73: #define        FE_SSE          5
        !            74:        "Skipped",
        !            75: };
        !            76: 
        !            77: int    errors[NERRORS];        /* histogram of errors */
        !            78: int    pattern;
        !            79: int    maxeccbits;
        !            80: 
        !            81: /*
        !            82:  * Purdue/EE severe burnin patterns.
        !            83:  */
        !            84: unsigned short ppat[] = {
        !            85: 0xf00f, 0xec6d, 0031463,0070707,0133333,0155555,0161616,0143434,
        !            86: 0107070,0016161,0034343,0044444,0022222,0111111,0125252, 052525,
        !            87: 0125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252,
        !            88: #ifndef        SHORTPASS
        !            89: 0125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252,
        !            90:  052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525,
        !            91: #endif
        !            92:  052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525
        !            93:  };
        !            94: 
        !            95: #define        NPT     (sizeof (ppat) / sizeof (short))
        !            96: int    maxpass, npat;  /* subscript to ppat[] */
        !            97: int    severe;         /* nz if running "severe" burnin */
        !            98: int    ssdev;                  /* device supports skip sectors */
        !            99: int    startcyl, endcyl, starttrack, endtrack;
        !           100: int    nbads;                  /* subscript for bads */
        !           101: daddr_t        bads[2*MAXBADDESC];     /* Bad blocks accumulated */
        !           102: 
        !           103: char   *malloc();
        !           104: int    qcompar();
        !           105: char   *prompt();
        !           106: daddr_t        badsn();
        !           107: extern int end;
        !           108: 
        !           109: main()
        !           110: {
        !           111:        register struct sector *hdr;
        !           112:        register int sector, sn, i;
        !           113:        struct disklabel dl;
        !           114:        struct sector *bp, *cbp;
        !           115:        int lastsector, tracksize, rtracksize;
        !           116:        int unit, fd, resid, trk, cyl, debug, pass;
        !           117:        char *cp, *rbp, *rcbp;
        !           118: 
        !           119:        printf("Disk format/check utility\n\n");
        !           120: 
        !           121:        /* enable the cache, as every little bit helps */
        !           122:        switch (cpu) {
        !           123:        case VAX_8600:
        !           124:                mtpr(CSWP, 3);
        !           125:                break;
        !           126:        case VAX_8200:
        !           127:        case VAX_750:
        !           128:                mtpr(CADR, 0);
        !           129:                break;
        !           130:        case VAX_780:
        !           131:                mtpr(SBIMT, 0x200000);
        !           132:                break;
        !           133:        }
        !           134: 
        !           135: again:
        !           136:        nbads = 0;
        !           137:        cp = prompt("Enable debugging (0=none, 1=bse, 2=ecc, 3=bse+ecc)? ");
        !           138:        debug = atoi(cp);
        !           139:        if (debug < 0)
        !           140:                debug = 0;
        !           141:        for (i = 0; i < NERRORS; i++)
        !           142:                errors[i] = 0;
        !           143:        fd = getdevice();
        !           144:        ioctl(fd, SAIODEVDATA, &dl);
        !           145:        printf("Device data: #cylinders=%d, #tracks=%d, #sectors=%d\n",
        !           146:            dl.d_ncylinders, dl.d_ntracks, dl.d_nsectors);
        !           147:        ssdev = SSDEV(fd);
        !           148:        if (ssdev) {
        !           149:                ioctl(fd, SAIOSSI, (char *)0);  /* set skip sector inhibit */
        !           150:                dl.d_nsectors++;
        !           151:                dl.d_secpercyl += dl.d_ntracks;
        !           152:                printf("(not counting skip-sector replacement)\n");
        !           153:        }
        !           154:        getrange(&dl);
        !           155:        if (getpattern())
        !           156:                goto again;
        !           157:        printf("Start formatting...make sure the drive is online\n");
        !           158:        ioctl(fd, SAIONOBAD, (char *)0);
        !           159:        ioctl(fd, SAIORETRIES, (char *)0);
        !           160:        ioctl(fd, SAIOECCLIM, (char *)maxeccbits);
        !           161:        ioctl(fd, SAIODEBUG, (char *)debug);
        !           162:        tracksize = sizeof (struct sector) * dl.d_nsectors;
        !           163:        rtracksize = SECTSIZ * dl.d_nsectors;
        !           164:        bp = (struct sector *)malloc(tracksize);
        !           165:        rbp = malloc(rtracksize);
        !           166:        pass = 0;
        !           167:        npat = 0;
        !           168: more:
        !           169:        for (; pass < maxpass; pass++) {
        !           170:                if (severe)
        !           171:                        printf("Begin pass %d\n", pass);
        !           172:                bufinit(bp, tracksize);
        !           173:                if (severe)
        !           174:                        npat++;
        !           175:                /*
        !           176:                 * Begin check, for each track,
        !           177:                 *
        !           178:                 * 1) Write header and test pattern.
        !           179:                 * 2) Read data.  Hardware checks header and data ECC.
        !           180:                 *    Read data (esp on Eagles) is much faster than write check.
        !           181:                 */
        !           182:                sector = ((startcyl * dl.d_ntracks) + starttrack) *
        !           183:                        dl.d_nsectors;
        !           184:                lastsector = ((endcyl * dl.d_ntracks) + endtrack) *
        !           185:                        dl.d_nsectors + dl.d_nsectors;
        !           186:                for ( ; sector < lastsector; sector += dl.d_nsectors) {
        !           187:                        cyl = sector / dl.d_secpercyl;
        !           188:                        trk = ((sector % dl.d_secpercyl) / dl.d_nsectors) << 8;
        !           189:                        for (i = 0, hdr = bp; i < dl.d_nsectors; i++, hdr++) {
        !           190:                                hdr->header1 = cyl | HDR1_FMT22 | HDR1_OKSCT;
        !           191:                                hdr->header2 = trk + i;
        !           192:                        }
        !           193:                        if (sector && (sector % (dl.d_secpercyl * 50)) == 0)
        !           194:                                printf("cylinder %d\n", cyl);
        !           195:                        /*
        !           196:                         * Try and write the headers and data patterns into
        !           197:                         * each sector in the track.  Continue until such
        !           198:                         * we're done, or until there's less than a sector's
        !           199:                         * worth of data to transfer.
        !           200:                         *
        !           201:                         * The lseek call is necessary because of
        !           202:                         * the odd sector size (516 bytes)
        !           203:                         */
        !           204:                        for (resid = tracksize, cbp = bp, sn = sector;;) {
        !           205:                                register int cc;
        !           206: 
        !           207:                                lseek(fd, sn * SECTSIZ, L_SET);
        !           208:                                ioctl(fd, SAIOHDR, (char *)0);
        !           209:                                cc = write(fd, cbp, resid);
        !           210:                                if (cc == resid)
        !           211:                                        break;
        !           212:                                /*
        !           213:                                 * Don't record errors during write,
        !           214:                                 * all errors will be found during
        !           215:                                 * check performed below.
        !           216:                                 */
        !           217:                                sn = iob[fd - 3].i_errblk;
        !           218:                                cbp += sn - sector;
        !           219:                                resid -= (sn - sector) * sizeof (struct sector);
        !           220:                                if (resid < sizeof (struct sector)) 
        !           221:                                        break;
        !           222:                        }
        !           223:                        /*
        !           224:                         * Read test patterns.
        !           225:                         * Retry remainder of track on error until
        !           226:                         * we're done, or until there's less than a
        !           227:                         * sector to verify.
        !           228:                         */
        !           229:                        for (resid = rtracksize, rcbp = rbp, sn = sector;;) {
        !           230:                                register int cc, rsn;
        !           231: 
        !           232:                                lseek(fd, sn * SECTSIZ, L_SET);
        !           233:                                cc = read(fd, rcbp, resid);
        !           234:                                if (cc == resid)
        !           235:                                        break;
        !           236:                                sn = iob[fd-3].i_errblk;
        !           237:                                if (ssdev) {
        !           238:                                        rsn = sn - (sn / dl.d_nsectors);
        !           239:                                        printf("data ");
        !           240:                                } else
        !           241:                                        rsn = sn;
        !           242:                                printf("sector %d, read error\n\n", rsn);
        !           243:                                if (recorderror(fd, sn, &dl) < 0 && pass > 0)
        !           244:                                        goto out;
        !           245:                                /* advance past bad sector */
        !           246:                                sn++;
        !           247:                                resid = rtracksize - ((sn - sector) * SECTSIZ);
        !           248:                                rcbp = rbp + ((sn - sector) * SECTSIZ);
        !           249:                                if (resid < SECTSIZ) 
        !           250:                                        break;
        !           251:                        }
        !           252:                }
        !           253:        }
        !           254:        /*
        !           255:         * Checking finished.
        !           256:         */
        !           257: out:
        !           258:        if (severe && maxpass < NPT) {
        !           259:                cp = prompt("More passes? (0 or number) ");
        !           260:                maxpass = atoi(cp);
        !           261:                if (maxpass > 0) {
        !           262:                        maxpass += pass;
        !           263:                        goto more;
        !           264:                }
        !           265:        }
        !           266:        if (severe && nbads) {
        !           267:                /*
        !           268:                 * Sort bads and insert in bad block table.
        !           269:                 */
        !           270:                qsort(bads, nbads, sizeof (daddr_t), qcompar);
        !           271:                severe = 0;
        !           272:                errno = 0;
        !           273:                for (i = 0; i < nbads; i++)
        !           274:                        recorderror(fd, bads[i], &dl);
        !           275:                severe++;
        !           276:        }
        !           277:        if (errors[FE_TOTAL] || errors[FE_SSE]) {
        !           278:                /* change the headers of all the bad sectors */
        !           279:                writebb(fd, errors[FE_SSE], &sstab, &dl, SSERR);
        !           280:                writebb(fd, errors[FE_TOTAL], &dkbad, &dl, BSERR);
        !           281:        }
        !           282:        if (errors[FE_TOTAL] || errors[FE_SSE]) {
        !           283:                printf("Errors:\n");
        !           284:                for (i = 0; i < NERRORS; i++)
        !           285:                        printf("%s: %d\n", errornames[i], errors[i]);
        !           286:                printf("Total of %d hard errors revectored\n",
        !           287:                        errors[FE_TOTAL] + errors[FE_SSE]);
        !           288:        }
        !           289:        if (endcyl == dl.d_ncylinders - 1 &&
        !           290:            (startcyl < dl.d_ncylinders - 1 || starttrack == 0)) {
        !           291:                while (errors[FE_TOTAL] < MAXBADDESC) {
        !           292:                        int i = errors[FE_TOTAL]++;
        !           293: 
        !           294:                        dkbad.bt_bad[i].bt_cyl = -1;
        !           295:                        dkbad.bt_bad[i].bt_trksec = -1;
        !           296:                }
        !           297:                printf("\nWriting bad sector table at sector #%d\n",
        !           298:                        dl.d_ncylinders * dl.d_secpercyl - dl.d_nsectors);
        !           299:                /* place on disk */
        !           300:                for (i = 0; i < 10 && i < dl.d_nsectors; i += 2) {
        !           301:                        lseek(fd, SECTSIZ * (dl.d_ncylinders *
        !           302:                                dl.d_secpercyl - dl.d_nsectors + i), 0);
        !           303:                        write(fd, &dkbad, sizeof (dkbad));
        !           304:                }
        !           305:        } else if (errors[FE_TOTAL]) {
        !           306:                struct bt_bad *bt;
        !           307: 
        !           308:                printf("New bad sectors (not added to table):\n");
        !           309:                bt = dkbad.bt_bad;
        !           310:                for (i = 0; i < errors[FE_TOTAL]; i++) {
        !           311:                        printf("bn %d (cn=%d, tn=%d, sn=%d)\n", badsn(bt, &dl),
        !           312:                            bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
        !           313:                        bt++;
        !           314:                }
        !           315:        }
        !           316:        printf("Done\n");
        !           317:        ioctl(fd,SAIONOSSI,(char *)0);
        !           318:        close(fd);
        !           319: #ifndef JUSTEXIT
        !           320:        goto again;
        !           321: #endif
        !           322: }
        !           323: 
        !           324: qcompar(l1, l2)
        !           325: register daddr_t *l1, *l2;
        !           326: {
        !           327:        if (*l1 < *l2)
        !           328:                return(-1);
        !           329:        if (*l1 == *l2)
        !           330:                return(0);
        !           331:        return(1);
        !           332: }
        !           333: 
        !           334: daddr_t
        !           335: badsn(bt, lp)
        !           336:        register struct bt_bad *bt;
        !           337:        register struct disklabel *lp;
        !           338: {
        !           339:        register int ssoff = ssdev ? 1 : 0;
        !           340: 
        !           341:        return ((bt->bt_cyl * lp->d_ntracks + (bt->bt_trksec >> 8)) *
        !           342:                (lp->d_nsectors - ssoff) + (bt->bt_trksec & 0xff) - ssoff);
        !           343: }
        !           344: 
        !           345: /*
        !           346:  * Mark the bad/skipped sectors.
        !           347:  * Bad sectors on skip-sector devices are assumed to be skipped also,
        !           348:  * and must be done after the (earlier) first skipped sector.
        !           349:  */
        !           350: writebb(fd, nsects, dbad, lp, sw)
        !           351:        int nsects, fd;
        !           352:        struct dkbad *dbad;
        !           353:        register struct disklabel *lp;
        !           354: {
        !           355:        struct sector bb_buf; /* buffer for one sector plus 4 byte header */
        !           356:        register int i;
        !           357:        int bn, j;
        !           358:        struct bt_bad *btp;
        !           359: 
        !           360:        for (i = 0; i < nsects; i++) {
        !           361:                btp = &dbad->bt_bad[i];
        !           362:                if (sw == BSERR) {
        !           363:                        bb_buf.header1 = HDR1_FMT22|btp->bt_cyl;
        !           364:                        if (ssdev)
        !           365:                                bb_buf.header1 |= HDR1_SSF;
        !           366:                } else
        !           367:                        bb_buf.header1 =
        !           368:                               btp->bt_cyl | HDR1_FMT22 | HDR1_SSF | HDR1_OKSCT;
        !           369:                bb_buf.header2 = btp->bt_trksec;
        !           370:                bn = lp->d_secpercyl * btp->bt_cyl +
        !           371:                     lp->d_nsectors * (btp->bt_trksec >> 8) +
        !           372:                     (btp->bt_trksec & 0xff);
        !           373:                lseek(fd, bn * SECTSIZ, L_SET);
        !           374:                ioctl(fd, SAIOHDR, (char *)0);
        !           375:                write(fd, &bb_buf, sizeof (bb_buf));
        !           376:                /*
        !           377:                 * If skip sector, mark all remaining
        !           378:                 * sectors on the track.
        !           379:                 */
        !           380:                if (sw == SSERR) {
        !           381:                        for (j = (btp->bt_trksec & 0xff) + 1, bn++;
        !           382:                            j < lp->d_nsectors; j++, bn++) {
        !           383:                                bb_buf.header2 = j | (btp->bt_trksec & 0xff00);
        !           384:                                lseek(fd, bn * SECTSIZ, L_SET);
        !           385:                                ioctl(fd, SAIOHDR, (char *)0);
        !           386:                                write(fd, &bb_buf, sizeof (bb_buf));
        !           387:                        }
        !           388:                }
        !           389:        }
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Record an error, and if there's room, put
        !           394:  * it in the appropriate bad sector table.
        !           395:  *
        !           396:  * If severe burnin store block in a list after making sure
        !           397:  * we have not already found it on a prev pass.
        !           398:  */
        !           399: recorderror(fd, bn, lp)
        !           400:        int fd, bn;
        !           401:        register struct disklabel *lp;
        !           402: {
        !           403:        int cn, tn, sn;
        !           404:        register int i;
        !           405: 
        !           406:        if (severe) {
        !           407:                for (i = 0; i < nbads; i++)
        !           408:                        if (bads[i] == bn)
        !           409:                                return(0);      /* bn already flagged */
        !           410:                if (nbads >= (ssdev ? 2 * MAXBADDESC : MAXBADDESC)) {
        !           411:                        printf("Bad sector table full, format terminating\n");
        !           412:                        return(-1);
        !           413:                }
        !           414:                bads[nbads++] = bn;
        !           415:                if (errno < EBSE || errno > EHER)
        !           416:                        return(0);
        !           417:                errno -= EBSE;
        !           418:                errors[errno]++;
        !           419:                return(0);
        !           420:        }
        !           421:        if (errno >= EBSE && errno <= EHER) {
        !           422:                errno -= EBSE;
        !           423:                errors[errno]++;
        !           424:        }
        !           425:        cn = bn / lp->d_secpercyl;
        !           426:        sn = bn % lp->d_secpercyl;
        !           427:        tn = sn / lp->d_nsectors;
        !           428:        sn %= lp->d_nsectors;
        !           429:        if (ssdev) {            /* if drive has skip sector capability */
        !           430:                int ss = errors[FE_SSE];
        !           431: 
        !           432:                if (errors[FE_SSE] >= MAXBADDESC) {
        !           433:                        /* this is bogus, we don't maintain skip sector table */
        !           434:                        printf("Too many skip sector errors\n");
        !           435:                        return(-1);
        !           436:                }
        !           437:                  /* only one skip sector/track */
        !           438:                if (ss == 0 ||
        !           439:                    tn != (sstab.bt_bad[ss - 1].bt_trksec >> 8) ||
        !           440:                    cn != sstab.bt_bad[ss - 1].bt_cyl) {
        !           441:                        /*
        !           442:                         * Don't bother with skipping the extra sector
        !           443:                         * at the end of the track.
        !           444:                         */
        !           445:                        if (sn == lp->d_nsectors - 1)
        !           446:                                return(0);
        !           447:                        sstab.bt_bad[ss].bt_cyl = cn;
        !           448:                        sstab.bt_bad[ss].bt_trksec = (tn<<8) + sn;
        !           449:                        errors[FE_SSE]++;
        !           450:                        return(0);
        !           451:                }
        !           452:        }
        !           453:        if (errors[FE_TOTAL] >= MAXBADDESC) {
        !           454:                printf("Too many bad sectors\n");
        !           455:                return(-1);
        !           456:        }
        !           457:        /* record the bad sector address and continue */
        !           458:        dkbad.bt_bad[errors[FE_TOTAL]].bt_cyl = cn;
        !           459:        dkbad.bt_bad[errors[FE_TOTAL]++].bt_trksec = (tn << 8) + sn;
        !           460:        return(0);
        !           461: }
        !           462: 
        !           463: /*
        !           464:  * Allocate memory on a page-aligned address.
        !           465:  * Round allocated chunk to a page multiple to
        !           466:  * ease next request.
        !           467:  */
        !           468: char *
        !           469: malloc(size)
        !           470:        int size;
        !           471: {
        !           472:        char *result;
        !           473:        static caddr_t last = 0;
        !           474: 
        !           475:        if (last == 0)
        !           476:                last = (caddr_t)(((int)&end + 511) & ~0x1ff);
        !           477:        size = (size + 511) & ~0x1ff;
        !           478:        result = (char *)last;
        !           479:        last += size;
        !           480:        return (result);
        !           481: }
        !           482: 
        !           483: /*
        !           484:  * Prompt and verify a device name from the user.
        !           485:  */
        !           486: getdevice()
        !           487: {
        !           488:        register char *cp;
        !           489:        int fd;
        !           490: 
        !           491: top:
        !           492:        do {
        !           493:                printf(
        !           494:                "Enter device name as \"type(adaptor,controller,drive,0)\"\n");
        !           495:                cp = prompt("Device to format? ");
        !           496:        } while ((fd = open(cp, 2)) < 0);
        !           497:        printf("Formatting %c%c drive %d on controller %d, adaptor %d: ",
        !           498:                cp[0], cp[1], iob[fd - 3].i_unit,
        !           499:                iob[fd - 3].i_ctlr, iob[fd - 3].i_adapt);
        !           500:        cp = prompt("verify (yes/no)? ");
        !           501:        while (*cp != 'y' && *cp != 'n')
        !           502:                cp = prompt("Huh, yes or no? ");
        !           503:        if (*cp == 'y')
        !           504:                return (fd);
        !           505:        goto top;
        !           506: }
        !           507: 
        !           508: /*
        !           509:  * Find range of tracks to format.
        !           510:  */
        !           511: getrange(lp)
        !           512:        register struct disklabel *lp;
        !           513: {
        !           514:        startcyl = getnum("Starting cylinder", 0, lp->d_ncylinders - 1, 0);
        !           515:        starttrack = getnum("Starting track", 0, lp->d_ntracks - 1, 0);
        !           516:        endcyl = getnum("Ending cylinder", 0, lp->d_ncylinders - 1,
        !           517:                lp->d_ncylinders - 1);
        !           518:        endtrack = getnum("Ending track", 0, lp->d_ntracks - 1,
        !           519:                lp->d_ntracks - 1);
        !           520: }
        !           521: 
        !           522: getnum(s, low, high, dflt)
        !           523:        int s, low, high, dflt;
        !           524: {
        !           525:        char buf[132];
        !           526:        u_int val;
        !           527: 
        !           528:        for(;;) {
        !           529:                printf("%s (%d): ", s, dflt);
        !           530:                gets(buf);
        !           531:                if (buf[0] == 0)
        !           532:                        return (dflt);
        !           533:                val = atoi(buf);
        !           534:                if (val >= low && val <= high)
        !           535:                        return ((int)val);
        !           536:                printf("Value must be in range [%d,%d]\n", low, high);
        !           537:        }
        !           538: }
        !           539: 
        !           540: static struct pattern {
        !           541:        long    pa_value;
        !           542:        char    *pa_name;
        !           543: } pat[] = {
        !           544:        { 0xf00ff00f,   "RH750 worst case" },
        !           545:        { 0xec6dec6d,   "media worst case" },
        !           546:        { 0xa5a5a5a5,   "alternate 1's and 0's" },
        !           547:        { 0xFFFFFFFF,   "Severe burnin (up to 48 passes)" },
        !           548:        { 0, 0 },
        !           549: };
        !           550: 
        !           551: getpattern()
        !           552: {
        !           553:        register struct pattern *p;
        !           554:        int npatterns;
        !           555:        char *cp;
        !           556: 
        !           557:        printf("Available test patterns are:\n");
        !           558:        for (p = pat; p->pa_value; p++)
        !           559:                printf("\t%d - (%x) %s\n", (p - pat) + 1,
        !           560:                  p->pa_value & 0xffff, p->pa_name);
        !           561:        npatterns = p - pat;
        !           562:        cp = prompt("Pattern (one of the above, other to restart)? ");
        !           563:        pattern = atoi(cp) - 1;
        !           564:        if (pattern < 0 || pattern >= npatterns)
        !           565:                return(1);
        !           566:        severe = 0;
        !           567:        maxpass = 1;
        !           568:        if (pat[pattern].pa_value == -1) {
        !           569:                severe = 1;
        !           570:                cp = prompt("How many passes (up to 48)? ");
        !           571:                maxpass = atoi(cp);
        !           572:                if (maxpass > NPT)
        !           573:                        maxpass = NPT;
        !           574:        }
        !           575:        maxeccbits = getnum(
        !           576:                "Maximum number of bit errors to allow for soft ECC",
        !           577:                0, 11, MAXECCBITS);
        !           578:        return (0);
        !           579: }
        !           580: 
        !           581: struct xsect {
        !           582:        u_short hd1;
        !           583:        u_short hd2;
        !           584:        long    buf[128];
        !           585: };
        !           586: 
        !           587: /*
        !           588:  * Initialize the buffer with the requested pattern. 
        !           589:  */
        !           590: bufinit(bp, size)
        !           591:        register struct xsect *bp;
        !           592:        int size;
        !           593: {
        !           594:        register struct pattern *pptr;
        !           595:        register long *pp, *last;
        !           596:        register struct xsect *lastbuf;
        !           597:        int patt;
        !           598: 
        !           599:        size /= sizeof (struct sector);
        !           600:        lastbuf = bp + size;
        !           601:        if (severe) {
        !           602:                patt = ppat[npat] | ((long)ppat[npat] << 16);
        !           603:                printf("Write pattern 0x%x\n", patt&0xffff);
        !           604:        } else {
        !           605:                pptr = &pat[pattern];
        !           606:                patt = pptr->pa_value;
        !           607:        }
        !           608:        while (bp < lastbuf) {
        !           609:                last = &bp->buf[128];
        !           610:                for (pp = bp->buf; pp < last; pp++)
        !           611:                        *pp = patt;
        !           612:                bp++;
        !           613:        }
        !           614: }
        !           615: 
        !           616: char *
        !           617: prompt(msg)
        !           618:        char *msg;
        !           619: {
        !           620:        static char buf[132];
        !           621: 
        !           622:        printf("%s", msg);
        !           623:        gets(buf);
        !           624:        return (buf);
        !           625: }

unix.superglobalmegacorp.com

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