Annotation of 43BSDReno/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.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.