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

unix.superglobalmegacorp.com

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