1: /*
   2:  * SCCSID: @(#)dskinit.c	3.0	4/21/86
   3:  */
   4: /*
   5:  *		LICENSED FROM DIGITAL EQUIPMENT CORPORATION
   6:  *			       COPYRIGHT (c)
   7:  *		       DIGITAL EQUIPMENT CORPORATION
   8:  *			  MAYNARD, MASSACHUSETTS
   9:  *			      1985, 1986, 1987
  10:  *			   ALL RIGHTS RESERVED
  11:  *
  12:  *	THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
  13:  *	NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
  14:  *	EQUIPMENT CORPORATION.  DIGITAL MAKES NO REPRESENTATIONS ABOUT
  15:  *	THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS
  16:  *	SUPPLIED "AS IS" WITHOUT EXPRESSED OR IMPLIED WARRANTY.
  17:  *
  18:  *	IF THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR ITS LICENSEES
  19:  *	MODIFY THE SOFTWARE IN A MANNER CREATING DERIVATIVE COPYRIGHT
  20:  *	RIGHTS, APPROPRIATE COPYRIGHT LEGENDS MAY BE PLACED ON THE
  21:  *	DERIVATIVE WORK IN ADDITION TO THAT SET FORTH ABOVE.
  22:  */
  23: 
  24: /*
  25:  * ULTRIX-11 standalone disk surface verifer and formater
  26:  *
  27:  * Fred Canter   11/1/82
  28:  * Jerry Brenner 12/16/82
  29:  * Fred Canter 9/28/85
  30:  *	Changes to allow format of unformatted packs.
  31:  *
  32:  * Functionality:
  33:  *
  34:  * Add:
  35:  * This routine adds an entry to the bad sector file and
  36:  * marks that sector as bad on the disk.
  37:  *
  38:  * Verify:
  39:  * This routine formats (optional), and surface verifies a disk.
  40:  * Up to 8 data patterns are utilized, including the worst
  41:  * case pattern for the disk type.  The current bad sector file,
  42:  * if valid, is used unless otherwise specified.
  43:  *
  44:  * BUGS:
  45:  *	This code arbitrarily limits the maximum number of
  46:  *	bad sectors to the sectors per track count of that disk.
  47:  *	e.g. RK06/07  maximum of 22 bad sectors.
  48:  *
  49:  */
  50: 
  51: #include <sys/param.h>
  52: #include <sys/bads.h>
  53: #include "sa_defs.h"
  54: 
  55: /*
  56:  * This programs accesses physical devices only.
  57:  * Must use 512 instead of BSIZE (1024 for new file system).
  58:  * Fred Canter 6/12/85
  59:  */
  60: #undef  BSIZE
  61: #define BSIZE   512
  62: 
  63: #define READ 1
  64: #define WRITE 0
  65: 
  66: /*
  67:  *	BAD144 info for disk bad blocking. A zero entry in
  68:  *	di_size indicates that disk type has no bad blocking.
  69:  */
  70: 
  71: #define NP  -1
  72: #define HP  1
  73: #define HM  2
  74: #define HJ  3
  75: 
  76: struct dkinfo {
  77:     char    *di_type;   /* type name of disk */
  78:     int di_flag;    /* prtdsk() flags */
  79:     char    *di_name;   /* ULTRIX-11 disk name */
  80:     long    di_size;    /* size of entire volume in blocks */
  81:     int di_nsect;   /* sectors per track */
  82:     int di_ntrak;   /* tracks per cylinder */
  83:     int di_wcpat[2];    /* worst case pattern */
  84: } dkinfo[] = {
  85:     "rk06", 0,  "hk",   22L*3L*411L,    22, 3, 0135143, 072307,
  86:     "rk07", 0,  "hk",   22L*3L*815L,    22, 3, 0135143, 072307,
  87:     "rm02", NP, "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  88:     "rm02_0", HP,   "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  89:     "rm02_1", HM,   "hm",   32L*5L*823L,    32, 5, 0165555, 0133333,
  90:     "rm02_2", HJ,   "hj",   32L*5L*823L,    32, 5, 0165555, 0133333,
  91:     "rm03", NP, "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  92:     "rm03_0", HP,   "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  93:     "rm03_1", HM,   "hm",   32L*5L*823L,    32, 5, 0165555, 0133333,
  94:     "rm03_2", HJ,   "hj",   32L*5L*823L,    32, 5, 0165555, 0133333,
  95:     "rm05", NP, "hp",   32L*19L*823L,   32, 19, 0165555, 0133333,
  96:     "rm05_0", HP,   "hp",   32L*19L*823L,   32, 19, 0165555, 0133333,
  97:     "rm05_1", HM,   "hm",   32L*19L*823L,   32, 19, 0165555, 0133333,
  98:     "rm05_2", HJ,   "hj",   32L*19L*823L,   32, 19, 0165555, 0133333,
  99:     "rp04", NP, "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
 100:     "rp04_0", HP,   "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
 101:     "rp04_1", HM,   "hm",   22L*19L*411L,   22, 19, 0165555, 0133333,
 102:     "rm04_2", HJ,   "hj",   22L*19L*411L,   22, 19, 0165555, 0133333,
 103:     "rp05", NP, "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
 104:     "rp05_0", HP,   "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
 105:     "rp05_1", HM,   "hm",   22L*19L*411L,   22, 19, 0165555, 0133333,
 106:     "rp05_2", HJ,   "hj",   22L*19L*411L,   22, 19, 0165555, 0133333,
 107:     "rp06", NP, "hp",   22L*19L*815L,   22, 19, 0165555, 0133333,
 108:     "rp06_0", HP,   "hp",   22L*19L*815L,   22, 19, 0165555, 0133333,
 109:     "rp06_1", HM,   "hm",   22L*19L*815L,   22, 19, 0165555, 0133333,
 110:     "rp06_2", HJ,   "hj",   22L*19L*815L,   22, 19, 0165555, 0133333,
 111:     0,
 112: };
 113: 
 114: /*
 115:  * Pointer into the argument buffer,
 116:  * used to flush the cartridge serial number
 117:  * if it is not used by DSKINIT.
 118:  * (see prf.c - getchar())
 119:  */
 120: extern char *argp;
 121: struct  dkbad dkbad;
 122: struct dkinfo *dip;
 123: struct bt_bad *bt;
 124: struct bt_bad tbt;
 125: int i, badcnt, csn_used;
 126: long    bn, atob();
 127: long nblk, nbo;
 128: int fd, rcnt;
 129: long    atol();
 130: char    line[20];
 131: char    fn[30];     /* file spec i.e., hp(0,0) */
 132: char    dt[20]; /* disk type rm03, etc */
 133: char    dn[2];      /* drive number */
 134: int dskpat[8][2] = {
 135:     0, 0,
 136:     0125252, 0125252,
 137:     0252525, 0252525,
 138:     0177777, 0177777,
 139:     0, 0,
 140:     0, 0177777,
 141:     0177777, 0,
 142:     1, 1,
 143: };
 144: 
 145: struct hk_fmt {
 146:     int hkcyl;
 147:     int hktrk;
 148:     int hkxor;
 149: };
 150: struct hp_fmt {
 151:     int hpcyl;
 152:     int hptrk;
 153:     long hpkey;
 154:     int hpdat[256];
 155: };
 156: struct hm_fmt {
 157:     int hmcyl;
 158:     int hmtrk;
 159:     int hmdat[256];
 160: };
 161: union {
 162:     long    serl;       /* pack serial number as a long */
 163:     int seri[2];    /* serial number as two int's */
 164: }dsk;
 165: 
 166: long    badbn[64];  /* array to hold bad block numbers */
 167: int newbad;
 168: struct {
 169:     int t_cn;
 170:     int t_tn;
 171:     int t_sn;
 172: }da;
 173: char    buf[(BSIZE+4)*32];
 174: int patbuf[BSIZE/sizeof(int)];
 175: char    *bblock = "Block	Cyl	Trk	Sec\n";
 176: 
 177: int argflag;    /* 0=interactive, 1=called by SDLOAD */
 178: 
 179: main()
 180: {
 181:     printf("\n\nDisk Surface Verify and Format Program\n");
 182: retry:
 183:     printf("\nDisk type <cr to exit, ? for list of disks>: ");
 184:     gets(dt);
 185:     if(dt[0] == '?'){
 186:         prtdsk();
 187:         goto retry;
 188:     }
 189:     if(strlen(dt) < 1)
 190:         exit(NORMAL);
 191:     for(dip=dkinfo; dip->di_type; dip++)
 192:         if(strcmp(dip->di_type, dt) == 0)
 193:             break;
 194:     if(dip->di_type == 0) {
 195:         printf("\n`%s' not a vaild disk type!\n", dt);
 196: rt_xit:
 197:         if(argflag)
 198:             exit(FATAL);
 199:         else
 200:             goto retry;
 201:     }
 202:     if(dip->di_size == 0){
 203:         printf("\n`%s' not supported in standalone mode!\n", dt);
 204:         goto rt_xit;
 205:     }
 206:     if(dip->di_nsect == 0 || dip->di_ntrak == 0){
 207:         printf("\n`%s' : No bad block support!\n", dt);
 208:         goto rt_xit;
 209:     }
 210:     printf("\nUnit number: ");
 211:     gets(dn);
 212:     if((strlen(dn) != 1) || (dn[0] < '0') || (dn[0] > '3')) {
 213:         printf("\nUnits 0 -> 3 only!\n");
 214:         goto rt_xit;
 215:     }
 216:     sprintf(fn, "%s(%s,0)", dip->di_name, dn);
 217:     /* force open, even if driver can't read the bad sector file */
 218:     BAD_CMD->r[0] = BAD_CHK;
 219:     dskopen(0);
 220:     bn = dip->di_size - dip->di_nsect;  /* first sector of last track */
 221: /*
 222:  * MUST always show bad sector file, because
 223:  * that is where we check if the pack is an
 224:  * alignment cartridge and exit if so.
 225: 	printf("\nPrint bad sector file <[y] or n> ? ");
 226: 	gets(line);
 227: 	if(line[0] == 'y' || line[0] == '\0')
 228: */
 229:     if(showbad()) {
 230:         printf("\nPack has invalid or no bad sector file\n");
 231:         if(argflag) /* discard sdload's answer (no question) */
 232:             while(*argp++ != '\r') ;
 233:     } else {    /* ask only if pack has valid bad sector file */
 234:         printf("\n\nEnter additional bad blocks into bad sector ");
 235:         printf("file <y or [n]> ? ");
 236:         gets(line);
 237:         if(line[0] == 'y')
 238:             addbad();
 239:     }
 240:     printf("\n\nInitialize Pack <y or [n]> ? ");
 241:     gets(line);
 242:     if(line[0] == 'y')
 243:         initdsk();
 244:     goto retry;
 245: }
 246: 
 247: showbad(){
 248:     if(readbad()){
 249:         printf("Not a valid bad sector file\n");
 250:         return(1);
 251:     }
 252:     dsk.seri[0] = dkbad.bt_csnh;
 253:     dsk.seri[1] = dkbad.bt_csnl;
 254:     printf("Cartridge serial number: %D\n", dsk.serl);
 255:     switch(dkbad.bt_flag) {
 256:         case -1:
 257:             printf("\nAlignment cartridge!\n");
 258:             exit(FATAL);
 259:         case 0:
 260:             break;
 261:         default:
 262:             printf("\nBad sector file flag word = %o\n"
 263:                     , dkbad.bt_flag);
 264:             return(1);
 265:     }
 266:     printf("Block\t  Cyl\t  Trk\t  Sec\n");
 267:     for(i=0; i<(BSIZE/sizeof(long)); i++, bt++) {
 268:         if(bt->bt_cyl == 0177777)
 269:             break;
 270:         if(bt->bt_cyl == 0 && bt->bt_trksec == 0){
 271:             dkbad.bt_mbz = -1;
 272:             return(-1);
 273:         }
 274:         bn = atob(bt);
 275:         printf("%D\t  %d\t  %d\t  %d\n", bn, bt->bt_cyl,
 276:             bt->bt_trksec>>8, bt->bt_trksec&0377);
 277:     }
 278:     return(0);
 279: }
 280: 
 281: addbad(){
 282:     int chngd, cn, tn, sn, cnt;
 283: 
 284:     for(cnt = 0; cnt < dip->di_nsect; cnt++)
 285:         badbn[cnt] = -1L;
 286:     BAD_CMD->r[0] = BAD_CHK;    /* force open */
 287:     dskopen(2);
 288:     if(readbad()){
 289:         /* Have to initialize bads */
 290:         printf("Not a valid bad sector file\n");
 291:         printf("Please initialize pack first\n");
 292:         return(0);
 293:     }
 294:     if(dkbad.bt_flag == -1 && dkbad.bt_mbz == 0){
 295:         printf("Alignment Cartridge\n");
 296:         return(1);
 297:     }
 298:     printf("Adding to bad sector information\n");
 299:     printf("Format is (cylinder track sector)enter values in decimal <cr to end>\n");
 300:     bt = dkbad.bt_badb;
 301:     for(i = 0; i < 126; i++, bt++){
 302:         tomany(i);
 303:         if(bt->bt_cyl == 0177777 || (bt->bt_cyl == 0
 304:            && bt->bt_trksec == 0))
 305:             break;
 306:     }
 307:     for(chngd = cnt = 0; ;){
 308:         tomany(i);
 309:         gets(line);
 310:         if(line[0] == '\0')
 311:         {
 312:             if(chngd){
 313:                 sortbn(0);
 314:                 setbads();
 315:                 sortbn(1);
 316:                 writbad();
 317:                 dskopen(2);
 318:                 if(strcmp(dip->di_name, "hk") == 0){
 319:                    for(cnt = 0; (bn = badbn[cnt]) > 0L;cnt++){
 320:                     bn = (bn/dip->di_nsect)*dip->di_nsect;
 321:                     lseek(fd, bn*512, 0);
 322:                     write(fd, buf, dip->di_nsect*512);
 323:                    }
 324:                 }
 325:                 showbad();
 326:             }
 327:             else
 328:                 printf("\nBad sector file not changed\n");
 329:             return(0);
 330:         }
 331:         sscanf(line, "%d %d %d", &cn, &tn, &sn);
 332:         if(cn >= dip->di_size/(dip->di_ntrak*dip->di_nsect)
 333:           || tn >= dip->di_ntrak || sn >= dip->di_nsect){
 334:             printf("ERROR in specification. Max of ");
 335:             printf("%o cyls  %o tracks %o sectors\n"
 336:                 , dip->di_size/(dip->di_ntrak*dip->di_nsect)
 337:                 , dip->di_ntrak, dip->di_nsect);
 338:             continue;
 339:         }
 340:         if(chkdup(cn, tn, sn)){
 341:             printf("\nThat sector is already marked bad\n");
 342:             continue;
 343:         }
 344:         chngd++;
 345:         tbt.bt_cyl = cn;
 346:         tbt.bt_trksec = (tn<<8)|sn;
 347:         bn = atob(&tbt);
 348:         badbn[cnt++] = bn;
 349:         i++;
 350:     }
 351: }
 352: 
 353: chkdup(cyl, trk, sec)
 354: int cyl, trk, sec;
 355: {
 356:     register struct bt_bad *bpnt;
 357:     int cnt;
 358: 
 359:     bpnt = dkbad.bt_badb;
 360:     for(cnt = 0; cnt < 126; cnt++, bpnt++){
 361:         if(bpnt->bt_cyl == 0177777)
 362:             break;
 363:         if(bpnt->bt_cyl == cyl
 364:            && bpnt->bt_trksec == ((trk << 8)|sec))
 365:             return(1);
 366:     }
 367:     return(0);
 368: }
 369: 
 370: initdsk(){
 371:     int patcnt, baddat, cnt, cnt1, fmt, chk, chk1;
 372:     int *tbuf;
 373:     unsigned rsize;
 374:     long bbn, tbn, maxbn;
 375: 
 376:     for(cnt = 0; cnt <= dip->di_nsect; cnt++)
 377:         badbn[cnt] = -1;
 378:     printf("Format Disk <y or [n]> ? ");
 379:     gets(line);
 380:     if(line[0] == 'y')
 381:         fmt = 1;
 382:     else
 383:         fmt = 0;
 384:     if(fmt == 1)    /* force open only if formatting */
 385:         BAD_CMD->r[0] = BAD_CHK;
 386:     else
 387:         BAD_CMD->r[0] = 0;
 388:     dskopen(2);
 389:     printf("Use current bad sector file ? <[y] or n> ");
 390:     gets(line);
 391:     csn_used = 0;
 392:     if(line[0] == 'n')
 393:         initbads();
 394:     else if(readbad()){
 395:         printf("Bad Sector file Invalid - Initializing\n");
 396:         csn_used++;
 397:         initbads();
 398:     }
 399:     if(argflag && (csn_used == 0))  /* throw away cartridge SN */
 400:         while(*argp++ != '\r') ;
 401: /*
 402:  * Load all entries in the current bad sector
 403:  * file into badbn[] (flag them as bad blocks) so
 404:  * they will not get lost when the disk is formatted.
 405:  */
 406:     if(fmt) {
 407:         cnt1 = 0;
 408:         for(cnt=0; cnt<126; cnt++) {
 409:             if(dkbad.bt_badb[cnt].bt_cyl == -1)
 410:                 break;
 411:             tbt.bt_cyl = dkbad.bt_badb[cnt].bt_cyl;
 412:             tbt.bt_trksec = dkbad.bt_badb[cnt].bt_trksec;
 413:             badbn[cnt1++] = atob(&tbt);
 414:         }
 415:     }
 416:     while(1){
 417:         printf("\nnumber of patterns <1 to 8> ?");
 418:         gets(line);
 419:         patcnt = atoi(line);
 420:         if((strcmp(dip->di_name, "hk")) == 0
 421:            && (patcnt <= 0 || patcnt > 8) && fmt)
 422:             continue;
 423:         else if(patcnt < 0 || patcnt > 8)
 424:             continue;
 425:         break;
 426:     }
 427:     patcnt--;
 428:     if(fmt != 0){
 429:         if(formatdsk())
 430:             exit(FATAL);
 431:         printf("Format complete\n");
 432:         setbads();
 433:         for(cnt=0; badbn[cnt] != -1; cnt++)
 434:             badbn[cnt] = -1;
 435:     }
 436:     dskpat[0][0] = dip->di_wcpat[0];
 437:     dskpat[0][1] = dip->di_wcpat[1];
 438:     if(fmt)
 439:         maxbn = dip->di_size;
 440:     else
 441:         maxbn = dip->di_size - (dip->di_nsect * 2);
 442:     for(i = patcnt, badcnt = 0; i >= 0 ; i--){
 443:         if(strcmp(dip->di_name, "hk") || i != 0){
 444:             ldbuf(dskpat[i][0],dskpat[i][1], i, 0);
 445:         }
 446:         if(i == 7)
 447:             printf("\nPattern %d = %s", i+1, "Random");
 448:         else{
 449:             printf("\nPattern %d = ", i+1);
 450:             fulprt(dskpat[i][1]);
 451:             fulprt(dskpat[i][0]);
 452:         }
 453:         rsize = BSIZE*dip->di_nsect;
 454:         printf("\nWRITING\n");
 455:         for(bn = 0; bn < maxbn ;){
 456:             if((strcmp(dip->di_name, "hk")) == 0 && i == 0){
 457:                 if((bn/(dip->di_ntrak*dip->di_nsect))&01)
 458:                     /* odd cylinder */
 459:                     ldbuf(dskpat[i][1],dskpat[i][1],i, 0);
 460:                 else
 461:                     /* even cylinder */
 462:                     ldbuf(dskpat[i][0],dskpat[i][0],i, 0);
 463:             }
 464:             lseek(fd, bn * BSIZE, 0);
 465:             BAD_CMD->r[0] = BAD_CHK;
 466:             if(rsize <= 0 || rsize > (BSIZE*dip->di_nsect))
 467:                 rsize = BSIZE * dip->di_nsect;
 468:             rcnt = write(fd, buf, rsize);
 469:             if(rcnt < 0){
 470:                 btoa(bn);
 471:                 printf("\n\nFATAL Error at ");
 472:                 printf("Block %D\t cyl %d\t  trk %d\t  sec %d\n"
 473:                   , bn, da.t_cn, da.t_tn, da.t_sn);
 474:                 exit(FATAL);
 475:             }
 476:             else if(rcnt != rsize){
 477:                 bbn = bn + (rcnt/BSIZE);
 478:                 if(badblk(bbn)){
 479:                     badcnt++;
 480:                     btoa(bbn);
 481:                     btoa(bbn);
 482:                     printf("%s%D\t%d\t%d\t%d\t%s"
 483:                     , bblock
 484:                     , bbn, da.t_cn, da.t_tn, da.t_sn
 485:                     ,"BAD SECTOR - WRITE ERROR\n\n");
 486:                 }
 487:                 rsize = (dip->di_nsect-((rcnt/BSIZE)))* BSIZE;
 488:                 bn = ++bbn;
 489:             }
 490:             else{
 491:                 rsize = BSIZE*dip->di_nsect;
 492:                 bn += dip->di_nsect;
 493:                 bn -= bn%dip->di_nsect;
 494:             }
 495:         }
 496:         rsize = BSIZE*dip->di_nsect;
 497:         printf("\nREADING (with ECC disabled)\n");
 498:         for(bn = 0; bn < maxbn;){
 499:             if((strcmp(dip->di_name, "hk")) == 0 && i == 0){
 500:                 if((bn/(dip->di_ntrak*dip->di_nsect))&01)
 501:                     /* odd cylinder */
 502:                     ldbuf(dskpat[i][1],dskpat[i][1],i, 1);
 503:                 else
 504:                     /* even cylinder */
 505:                     ldbuf(dskpat[i][0],dskpat[i][0],i, 1);
 506:             }
 507:             lseek(fd, bn * BSIZE, 0);
 508:             BAD_CMD->r[0] = BAD_CHK;
 509: /*
 510:  * Fred Canter -- 8/20/85
 511:  *	We want blocks with ECC errors to be revectored,
 512:  *	whether or not we formatted the disk.
 513: 			if(fmt)
 514: */
 515:                 BAD_CMD->r[0] |= BAD_NEC;
 516:             rcnt = read(fd, buf, rsize);
 517:             if(rcnt < 0){
 518:                 btoa(bn);
 519:                 printf("\n\nFATAL Error at ");
 520:                 printf("Block %D\t cyl %d\t  trk %d\t  sec %d\n"
 521:                   , bn, da.t_cn, da.t_tn, da.t_sn);
 522:                 exit(FATAL);
 523:             }
 524:             else if(rcnt != rsize){
 525:                 bbn = bn + (rcnt/BSIZE);
 526:                 if(badblk(bbn)){
 527:                     badcnt++;
 528:                     btoa(bbn);
 529:                     printf("%s%D\t%d\t%d\t%d\t%s"
 530:                     , bblock
 531:                     , bbn, da.t_cn, da.t_tn, da.t_sn
 532:                     ,"BAD SECTOR\n\n");
 533:                 }
 534:                 rsize = (dip->di_nsect-((rcnt/BSIZE)+1))* BSIZE;
 535:                 tbn = ++bbn;
 536:             }
 537:             else{
 538:                 rsize = BSIZE*dip->di_nsect;
 539:                 tbn =  bn + dip->di_nsect;
 540:                 tbn -= tbn%dip->di_nsect;
 541:             }
 542:             for(chk = 0; chk < (rcnt/BSIZE); chk++){
 543:                 baddat = 0;
 544:                 tbuf = buf + (chk*BSIZE);
 545:                 for(chk1=0; chk1<(BSIZE/sizeof(int)); chk1++){
 546:                 if(*tbuf != patbuf[chk1]){
 547:                     bbn = bn + chk;
 548:                     btoa(bbn);
 549:                     printf("%s%D\t%d\t%d\t%d\t%s"
 550:                     , bblock
 551:                     , bbn, da.t_cn, da.t_tn, da.t_sn
 552:                     ,"DATA COMPARE ERROR  ");
 553:                     printf("sb ");
 554:                     fulprt(patbuf[chk1]);
 555:                     printf(" is ");
 556:                     fulprt(*tbuf);
 557:                     printf("\n");
 558:                     if(++baddat > 4)
 559:                     break;
 560:                 }
 561:                 tbuf++;
 562:                 }
 563:                 if(baddat){
 564:                 bbn = bn + chk;
 565:                 if(badblk(bbn)){
 566:                     badcnt++;
 567:                     btoa(bbn);
 568:                     printf("%s%D\t%d\t%d\t%d\t%s"
 569:                     , bblock
 570:                     , bbn, da.t_cn, da.t_tn, da.t_sn
 571:                     ,"BAD SECTOR\n\n");
 572:                 }
 573:                 }
 574:             }
 575:             clrbuf();
 576:             bn = tbn;
 577:         }
 578:     }
 579:     printf("\n\nVerify Complete\n");
 580:     if(badcnt > 0 || newbad || fmt){
 581:         sortbn(0);
 582:         setbads();
 583:         sortbn(1);
 584:         writbad();
 585:     }
 586:     dskopen(2);
 587:     if((strcmp(dip->di_name, "hk")) == 0){
 588:         for(cnt = 0; (bn = badbn[cnt]) > 0L;cnt++){
 589:             bn = (bn/dip->di_nsect)*dip->di_nsect;
 590:             lseek(fd, bn*512, 0);
 591:             write(fd, buf, dip->di_nsect*512);
 592:         }
 593:     }
 594:     if(badcnt > 0)
 595:         printf("%d%sbad blocks found\n"
 596:             , badcnt, newbad?" ":" additional ");
 597:     else
 598:         printf("No%sbad blocks found\n",newbad?" ":" additional ");
 599:     showbad();
 600: }
 601: 
 602: initbads()
 603: {
 604:     register struct bt_bad *pnt;
 605:     int cnt;
 606: 
 607:     newbad++;
 608:     while(1) {
 609:         printf("Cartridge serial number ? ");
 610:         gets(line);
 611:         for(cnt=0; line[cnt]; cnt++)
 612:             if((line[cnt] < '0') || (line[cnt] > '9'))
 613:                 break;
 614:         if(line[cnt] != '\0') {
 615:             printf("\nSerial number - numbers only!\n");
 616:             continue;
 617:         }
 618:         dsk.serl = atol(line);
 619:         if(dsk.serl <= 0L) {
 620:             printf("\nSerial number - must be greater than zero!\n");
 621:             continue;
 622:         }
 623:         break;
 624:     }
 625:     dkbad.bt_csnl = dsk.seri[1];
 626:     dkbad.bt_csnh = dsk.seri[0];
 627:     dkbad.bt_mbz = 0;
 628:     dkbad.bt_flag = 0;
 629:     for(cnt = 0, pnt = dkbad.bt_badb; cnt < 126; cnt++, pnt++)
 630:         pnt->bt_cyl = pnt->bt_trksec = 0177777;
 631: }
 632: 
 633: formatdsk()
 634: {
 635:     struct hk_fmt *whk;
 636:     struct hp_fmt *whp;
 637:     struct hm_fmt *whm;
 638:     int tcnt, scnt, tsize, wsize, rsec;
 639:     long seekpnt;
 640: 
 641:     printf("Begin Format <y or [n]> ? ");
 642:     gets(line);
 643:     if(line[0] != 'y'){
 644:         if(newbad)
 645:             return(1);
 646:         return(0);
 647:     }
 648:     printf("\nFormating %s %s\n", dip->di_type, dn);
 649:     tcnt = 0;
 650:     if(strcmp(dip->di_name, "hk") == 0){
 651:         tsize = dip->di_nsect;
 652:         wsize = tsize * sizeof(struct hk_fmt);
 653:         for(; tcnt < (dip->di_size/tsize); tcnt++){
 654:             whk = buf;
 655:             for(scnt = 0; scnt < tsize; scnt++, whk++){
 656:                 whk->hkcyl = tcnt/dip->di_ntrak;
 657:                 whk->hktrk = (tcnt%dip->di_ntrak)<<5;
 658:                 whk->hktrk |= (scnt&037);
 659:                 whk->hktrk |= 0140000;
 660:                 whk->hkxor = (whk->hkcyl ^ whk->hktrk);
 661:             }
 662:             seekpnt =  (long)tcnt*dip->di_nsect*BSIZE;
 663:             fmtfunc(WRITE, seekpnt, wsize);
 664:         }
 665:     }
 666:     else if(strncmp(dip->di_type, "rm", 2) == 0){
 667:         tsize = dip->di_nsect*sizeof(struct hm_fmt);
 668:         for(; tcnt < (dip->di_size/dip->di_nsect); tcnt++){
 669:             whm = buf;
 670:             for(scnt = 0; scnt < dip->di_nsect; scnt++, whm++){
 671:                 whm->hmcyl = tcnt/dip->di_ntrak;
 672:                 whm->hmtrk = (tcnt%dip->di_ntrak)<<8;
 673:                 whm->hmtrk |= (scnt&037);
 674:                 whm->hmcyl |= 0150000;
 675:             }
 676:             seekpnt =  (long)tcnt*dip->di_nsect*BSIZE;
 677:             fmtfunc(WRITE, seekpnt, tsize);
 678:         }
 679:     }
 680:     else if(strcmp(dip->di_name, "hp") == 0
 681:       || strcmp(dip->di_name, "hm") == 0){
 682:         tsize = dip->di_nsect*sizeof(struct hp_fmt);
 683:         for(; tcnt < (dip->di_size/dip->di_nsect); tcnt++){
 684:             whp = buf;
 685:             for(scnt = 0; scnt < dip->di_nsect; scnt++,whp++){
 686:                 whp->hpcyl = (tcnt/dip->di_ntrak);
 687:                 whp->hptrk = (tcnt%dip->di_ntrak)<<8;
 688:                 whp->hptrk |= (scnt&037);
 689:                 whp->hpcyl |= 010000;
 690:             }
 691:             seekpnt =  (long)tcnt*dip->di_nsect*BSIZE;
 692:             fmtfunc(WRITE, seekpnt, tsize);
 693:         }
 694:     }
 695:     else{
 696:         printf("Cannot format %s's\n", dip->di_type);
 697:         return(1);
 698:     }
 699:     return(0);
 700: }
 701: 
 702: badblk(bbn)
 703: long bbn;
 704: {
 705:     register struct bt_bad *pnt;
 706:     int cnt, cnt1, trksec;
 707: 
 708:     if(bbn >= (dip->di_size - (dip->di_nsect *2))){
 709:         printf("Bad Block %D in Disk Bad Sector Area\n", bbn);
 710:         printf("Pack Unacceptable for ULTRIX-11\n");
 711:         exit(BADPACK);
 712:     }
 713:     btoa(bbn);
 714:     trksec = da.t_tn << 8;
 715:     trksec |= da.t_sn&0377;
 716:     pnt = dkbad.bt_badb;
 717:     for(cnt = 0; cnt < dip->di_nsect; cnt++, pnt++){
 718:         if(pnt->bt_cyl == 0177777)
 719:             break;
 720:         if(pnt->bt_cyl == da.t_cn && pnt->bt_trksec == trksec)
 721:             return(0);
 722:     }
 723:     for(cnt = 0; cnt < dip->di_nsect; cnt++){
 724:         if(badbn[cnt] == bbn)
 725:             return(0);
 726:         if(badbn[cnt] == -1)
 727:             break;
 728:     }
 729:     tomany(cnt);
 730:     badbn[cnt] = bbn;
 731:     return(1);
 732: }
 733: 
 734: clrbuf()
 735: {
 736:     int cnt, *tbuf, pat;
 737: 
 738:     if(patbuf[0] == 0 && patbuf[1] == 0)
 739:         pat = -1;
 740:     else
 741:         pat = 0;
 742:     for(cnt = 0,tbuf = buf;cnt < (sizeof(buf)/sizeof(int));cnt++,tbuf++)
 743:         *tbuf = pat;
 744: }
 745: 
 746: ldbuf(lpat, hpat, flg, patflg)
 747: int lpat, hpat, flg, patflg;
 748: {
 749:     int *rbuf, *tpat;
 750:     int cnt, cnt1;
 751: 
 752:     if(flg == 7)
 753:         srand(1);
 754:     rbuf = patbuf;
 755:     for(cnt = 0; cnt < ((BSIZE/sizeof(int))/2); cnt++) {
 756:         if(flg == 7) {
 757:             *(rbuf++) = rand();
 758:             *(rbuf++) = rand();
 759:         } else {
 760:             *(rbuf++) = lpat;
 761:             *(rbuf++) = hpat;
 762:         }
 763:     }
 764:     if(patflg)
 765:         return;
 766:     for(cnt = 0, rbuf = buf; cnt < dip->di_nsect; cnt++){
 767:         for(cnt1=0, tpat=patbuf; cnt1<(BSIZE/sizeof(int)); cnt1++)
 768:             *(rbuf++) = *(tpat++);
 769:     }
 770: }
 771: 
 772: btoa(bn)
 773: long bn;
 774: {
 775:     da.t_cn = bn/(dip->di_ntrak*dip->di_nsect);
 776:     da.t_sn = bn%(dip->di_ntrak*dip->di_nsect);
 777:     da.t_tn = da.t_sn/dip->di_nsect;
 778:     da.t_sn = da.t_sn%dip->di_nsect;
 779: }
 780: 
 781: readbad()
 782: {
 783:     int cnt;
 784: 
 785:     dkbad.bt_mbz = -1;
 786:     bn = dip->di_size - dip->di_nsect;  /* first sector of last track */
 787:     for(cnt = 0; cnt < 5; cnt++){
 788:         lseek(fd, BSIZE * bn, 0);
 789:         printf("\nBad sector file at block %D of %s\n", bn, fn);
 790:         if(read(fd, &dkbad, sizeof(struct dkbad))
 791:           != sizeof(struct dkbad)) {
 792:             bn += 2;
 793:             continue;
 794:         }
 795:         break;
 796:     }
 797:     if(cnt >= 5){
 798:         printf("\nCan't read bad sector file for %s unit %s!\n",
 799:         dip->di_type, dn);
 800:         printf("\nCAUTION: disk pack probably needs formatting!\n\n");
 801:         dkbad.bt_mbz = -1;  /* force next to fail */
 802:     }
 803:     bt = dkbad.bt_badb;
 804:     if(dkbad.bt_mbz || (dkbad.bt_csnl == 0 && dkbad.bt_csnh == 0)){
 805:         dkbad.bt_mbz = -1;
 806:         return(1);
 807:     }
 808:     return(0);
 809: }
 810: 
 811: writbad()
 812: {
 813:     int cnt;
 814: 
 815:     bn = dip->di_size - dip->di_nsect;
 816:     printf("\nWriting bad sector file");
 817:     printf(" starting at block %D of %s\n", bn, fn);
 818:     for(cnt = 0; cnt < 5; cnt++){
 819:         lseek(fd, BSIZE * bn, 0);
 820:         BAD_CMD->r[0] = BAD_CHK;
 821:         write(fd, &dkbad, 512);
 822:         bn += 2;
 823:     }
 824: }
 825: 
 826: fmtfunc(flag, pnt, size)
 827: int flag;
 828: long pnt;
 829: int size;
 830: {
 831:     int rcnt;
 832: 
 833:     lseek(fd, pnt, 0);
 834:     BAD_CMD->r[0] = BAD_FMT;
 835:     if(flag == WRITE){
 836:         if((rcnt = write(fd, buf, size)) != size){
 837:             printf("FATAL: write format returned ");
 838:             printf("%d  should be %d\n", rcnt , size);
 839:             exit(FATAL);
 840:         }
 841:     }
 842:     else
 843:         if((rcnt = read(fd, buf, size)) != size){
 844:             printf("FATAL: read format returned ");
 845:             printf("%d  should be %d\n", rcnt , size);
 846:             exit(FATAL);
 847:         }
 848: }
 849: 
 850: dskopen(mode)
 851: int mode;
 852: {
 853:     if(fd > 0)
 854:         close(fd);
 855:     if((fd = open(fn, mode)) <= 0) {
 856:         printf("\nCan't open %s!\n", fn);
 857:         exit(FATAL);
 858:     }
 859: }
 860: 
 861: tomany(num)
 862: int num;
 863: {
 864:     if(num > dip->di_nsect){
 865:         printf("\nToo many bad blocks. Do not use this Pack\n");
 866:         exit(BADPACK);
 867:     }
 868: }
 869: 
 870: fulprt(val)
 871: int val;
 872: {
 873:     int cnt, cnv;
 874:     char c;
 875: 
 876:     for(cnt = 5; cnt >= 0; cnt--){
 877:         cnv = val&(07<<(cnt*3));
 878:         if(cnt == 5)
 879:             c = ((cnv>>1)&~0100000)>>14;
 880:         else
 881:             c = cnv>>(cnt*3);
 882:         printf("%c",c+060);
 883:     }
 884: }
 885: 
 886: long atob(bt)
 887: struct bt_bad *bt;
 888: {
 889:     long blkn;
 890: 
 891:     blkn = (long)bt->bt_cyl * (long)(dip->di_ntrak * dip->di_nsect);
 892:     blkn += (long)((bt->bt_trksec >> 8) * dip->di_nsect);
 893:     blkn += ((long)bt->bt_trksec & 0377);
 894:     return(blkn);
 895: }
 896: 
 897: sortbn(merge)
 898: {
 899:     long lbn, tbn[64];
 900:     int max, cnt, cnt1, li;
 901:     struct bt_bad *pt;
 902: 
 903:     for(cnt = 0; cnt < 64; cnt++)
 904:         tbn[cnt] = -1L;
 905:     if(merge)
 906:         for(cnt = 0, pt = dkbad.bt_badb; ;cnt++, pt++){
 907:             if(pt->bt_cyl == 0177777)
 908:                 break;
 909:             tbn[cnt] = atob(pt);
 910:         }
 911:     else
 912:         cnt = 0;
 913:     for(cnt1 = 0; badbn[cnt1] != -1L; cnt1++){
 914:         tbn[cnt] = badbn[cnt1];
 915:         cnt++;
 916:     }
 917:     max = cnt;
 918:     cnt = cnt1 = 0;
 919:     for(lbn = tbn[0], li = 0; cnt < max; ){
 920:         if(lbn == 0 && tbn[cnt1] > 0){
 921:             lbn = tbn[cnt1];
 922:             li = cnt1;
 923:         }
 924:         if(tbn[cnt1] == 0L){
 925:             cnt1++;
 926:             continue;
 927:         }
 928:         if(tbn[cnt1] == -1L && lbn > 0){
 929:             badbn[cnt] = tbn[li];
 930:             cnt++;
 931:             tbn[li] = 0L;
 932:             cnt1 = 0;
 933:             lbn = 0;
 934:             continue;
 935:         }
 936:         if(tbn[cnt1] == -1L)
 937:             break;
 938:         if(tbn[cnt1] < lbn){
 939:             li = cnt1;
 940:             lbn = tbn[cnt1];
 941:         }
 942:         cnt1++;
 943:     }
 944:     badbn[cnt] = -1L;
 945:     if(merge){
 946:         for(cnt = 0, pt = dkbad.bt_badb; ;cnt++, pt++){
 947:             if(badbn[cnt] == -1L)
 948:                 break;
 949:             btoa(badbn[cnt]);
 950:             pt->bt_cyl = da.t_cn;
 951:             pt->bt_trksec = da.t_tn << 8;
 952:             pt->bt_trksec |= da.t_sn&0377;
 953:         }
 954:         for(;cnt < 126; cnt++, pt++)
 955:             pt->bt_cyl = pt->bt_trksec = 0177777;
 956:     }
 957: }
 958: 
 959: setbads()
 960: {
 961:     struct hk_fmt *whk;
 962:     struct hp_fmt *whp;
 963:     struct hm_fmt *whm;
 964:     int cnt, tcnt, scnt, tsize, wsize, csec;
 965:     int found;
 966:     long seekpnt, bbn;
 967:     struct {
 968:         int cylnum;
 969:         int trksecnum;
 970:     }dskadr;
 971: 
 972:     if(strcmp(dip->di_name, "hk") == 0){
 973:         tsize = dip->di_nsect;
 974:         wsize = tsize * sizeof(struct hk_fmt);
 975:         for(cnt = 0; badbn[cnt] != -1; ){
 976:             tcnt = badbn[cnt]/tsize;
 977:             seekpnt =  (long)tcnt*dip->di_nsect*BSIZE;
 978:             fmtfunc(READ, seekpnt, wsize);
 979:             whk = buf;
 980:             found = 0;
 981:             for(scnt = 0; scnt < dip->di_nsect; scnt++, whk++){
 982:                 dskadr.cylnum = whk->hkcyl;
 983:                 dskadr.trksecnum = (whk->hktrk&0340)<<3;
 984:                 dskadr.trksecnum |= whk->hktrk&037;
 985:                 if((bbn = atob(&dskadr)) == badbn[cnt]){
 986:                     found++;
 987:                     whk->hktrk &= ~040000;
 988:                     whk->hkxor = (whk->hkcyl ^ whk->hktrk);
 989:                     btoa(bbn);
 990:                     prtvec(bbn);
 991:                     if(badbn[++cnt] == -1)
 992:                         break;
 993:                 }
 994:             }
 995:             if(found == 0) {
 996:                 printf("\nBad block not found in sector headers!\n");
 997:                 exit(BADPACK);
 998:             }
 999:             fmtfunc(WRITE, seekpnt, wsize);
1000:         }
1001:     }
1002:     else if(strncmp(dip->di_type, "rm", 2) == 0){
1003:         tsize = sizeof(struct hm_fmt);
1004:         for(cnt = 0; badbn[cnt] != -1; cnt++){
1005:             seekpnt =  (long)(badbn[cnt]*BSIZE);
1006:             fmtfunc(READ, seekpnt, tsize);
1007:             whm = buf;
1008:             if((whm->hmcyl & 0140000) != 0140000)
1009:                 continue;
1010:             whm->hmcyl &= ~040000;
1011:             btoa(badbn[cnt]);
1012:             prtvec(badbn[cnt]);
1013:             fmtfunc(WRITE, seekpnt, tsize);
1014:         }
1015:     }
1016:     else if(strcmp(dip->di_name, "hp") == 0
1017:       || strcmp(dip->di_name, "hm") == 0){
1018:         tsize = sizeof(struct hp_fmt);
1019:         for(cnt = 0; badbn[cnt] != -1; cnt++){
1020:             seekpnt =  (long)(badbn[cnt]*BSIZE);
1021:             fmtfunc(READ, seekpnt, tsize);
1022:             whp = buf;
1023:             if((whp->hpcyl & 010000) == 0)
1024:                 continue;
1025:             whp->hpcyl &= ~010000;
1026:             btoa(badbn[cnt]);
1027:             prtvec(badbn[cnt]);
1028:             fmtfunc(WRITE, seekpnt, tsize);
1029:         }
1030:     }
1031: }
1032: 
1033: prtvec(bbn)
1034: long bbn;
1035: {
1036:     printf("Revectoring block #%D", bbn);
1037:     printf("  cyl = %d  trk = %d  sec = %d\n"
1038:         ,da.t_cn, da.t_tn, da.t_sn);
1039: }
1040: 
1041: prtdsk()
1042: {
1043:     struct dkinfo *dp;
1044: 
1045:     printf("\nDisk\tULTRIX\tSize in");
1046:     printf("\nName\tName\tBlocks\tComments");
1047:     printf("\n----\t----\t------\t--------");
1048:     for(dp=dkinfo; dp->di_type; dp++){
1049:         if(dp->di_flag == NP)
1050:             continue;
1051:         printf("\n%s\t", dp->di_type);
1052:         printf("%s\t", dp->di_name);
1053:         printf("%D\t", dp->di_size);
1054:         if(dp->di_flag == HP)
1055:             printf("(first  ) RH11/RH70 Controller");
1056:         if(dp->di_flag == HM)
1057:             printf("(second ) RH11/RH70 Controller");
1058:         if(dp->di_flag == HJ)
1059:             printf("(third  ) RH11/RH70 Controller");
1060:     }
1061:     printf("\n");
1062: }

Defined functions

addbad defined in line 281; used 1 times
atob defined in line 886; used 6 times
badblk defined in line 702; used 3 times
btoa defined in line 772; used 12 times
chkdup defined in line 353; used 1 times
clrbuf defined in line 734; used 1 times
dskopen defined in line 850; used 5 times
fmtfunc defined in line 826; used 9 times
formatdsk defined in line 633; used 1 times
fulprt defined in line 870; used 4 times
initbads defined in line 602; used 2 times
initdsk defined in line 370; used 1 times
ldbuf defined in line 746; used 5 times
main defined in line 179; never used
prtdsk defined in line 1041; used 1 times
prtvec defined in line 1033; used 3 times
readbad defined in line 781; used 3 times
setbads defined in line 959; used 3 times
showbad defined in line 247; used 3 times
sortbn defined in line 897; used 4 times
tomany defined in line 861; used 3 times
writbad defined in line 811; used 2 times

Defined variables

argflag defined in line 177; used 11 times
badbn defined in line 166; used 29 times
badcnt defined in line 125; used 7 times
bblock defined in line 175; used 4 times
bn defined in line 126; used 47 times
bt defined in line 123; used 19 times
buf defined in line 173; used 16 times
csn_used defined in line 125; used 3 times
dip defined in line 122; used 108 times
dkbad defined in line 121; used 29 times
dkinfo defined in line 84; used 2 times
dn defined in line 133; used 7 times
dskpat defined in line 134; used 14 times
dt defined in line 132; used 7 times
fd defined in line 128; used 18 times
fn defined in line 131; used 5 times
i defined in line 125; used 35 times
line defined in line 130; used 21 times
nblk defined in line 127; never used
nbo defined in line 127; never used
newbad defined in line 167; used 5 times
patbuf defined in line 174; used 6 times
rcnt defined in line 128; used 16 times
tbt defined in line 124; used 6 times

Defined struct's

dkinfo defined in line 76; used 4 times
hk_fmt defined in line 145; used 8 times
hm_fmt defined in line 156; used 8 times
hp_fmt defined in line 150; used 8 times

Defined macros

BSIZE defined in line 61; used 31 times
HJ defined in line 74; used 7 times
HM defined in line 73; used 7 times
HP defined in line 72; used 7 times
NP defined in line 71; used 7 times
READ defined in line 63; used 3 times
WRITE defined in line 64; used 7 times
Last modified: 1992-12-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2202
Valid CSS Valid XHTML 1.0 Strict