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

Defined functions

badsn defined in line 317; used 2 times
bufinit defined in line 577; used 1 times
getdevice defined in line 473; used 1 times
getnum defined in line 510; used 5 times
getpattern defined in line 538; used 1 times
getrange defined in line 501; used 1 times
main defined in line 106; never used
malloc defined in line 455; used 3 times
prompt defined in line 603; used 8 times
qcompar defined in line 307; used 2 times
recorderror defined in line 385; used 2 times
writebb defined in line 336; used 2 times

Defined variables

bads defined in line 98; used 4 times
copyright defined in line 8; never used
dkbad defined in line 53; used 8 times
endcyl defined in line 96; used 3 times
endtrack defined in line 96; used 2 times
errornames defined in line 59; used 1 times
errors defined in line 74; used 22 times
maxeccbits defined in line 76; used 2 times
maxpass defined in line 93; used 9 times
nbads defined in line 97; used 7 times
npat defined in line 93; used 4 times
oldbad defined in line 54; never used
pat defined in line 530; used 5 times
pattern defined in line 75; used 5 times
ppat defined in line 81; used 3 times
sccsid defined in line 14; never used
severe defined in line 94; used 10 times
ssdev defined in line 95; used 7 times
sstab defined in line 55; used 5 times
startcyl defined in line 96; used 3 times
starttrack defined in line 96; used 3 times

Defined struct's

pattern defined in line 527; used 4 times
sector defined in line 47; used 14 times
xsect defined in line 568; used 4 times

Defined macros

BSERR defined in line 42; used 2 times
CHUNK defined in line 37; never used
FE_BSE defined in line 60; never used
FE_ECC defined in line 64; never used
FE_HARD defined in line 66; never used
FE_SSE defined in line 70; used 7 times
FE_TOTAL defined in line 68; used 11 times
FE_WCE defined in line 62; never used
HDRSIZ defined in line 39; never used
MAXBADDESC defined in line 36; used 6 times
MAXECCBITS defined in line 45; used 1 times
NERRORS defined in line 57; used 4 times
NPT defined in line 92; used 3 times
SECTSIZ defined in line 38; used 10 times
SSDEV defined in line 44; used 1 times
SSERR defined in line 41; used 2 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1985
Valid CSS Valid XHTML 1.0 Strict