Annotation of 43BSDTahoe/sys/vaxstand/format.c, revision 1.1.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.