1: /*
   2:  * SCCSID: @(#)bads.c	3.1	3/26/87
   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:  * ULTRIX-11 standalone quick disk surface verifer
  25:  *
  26:  * Fred Canter   2/26/83
  27:  * Jerry Brenner 12/16/82
  28:  *
  29:  * Functionality:
  30:  *
  31:  * Scan:
  32:  * This routine prints the contents of the bad sector file
  33:  * on a disk pack, per DEC standard 144.
  34:  * It also scans a selected area for the disk for bad blocks
  35:  * by reading the data, this is a very gross check at best.
  36:  *
  37:  *	This code arbitrarily limits the maximum number of
  38:  *	bad sectors to the sectors per track count of that disk.
  39:  *	e.g. RK06/07  maximum of 22 bad sectors.
  40:  *
  41:  */
  42: 
  43: #include "sa_defs.h"
  44: #include <sys/param.h>
  45: #include <sys/bads.h>
  46: 
  47: /*
  48:  * This programs accesses physical devices only.
  49:  * Must use 512 instead of BSIZE (1024 for new file system).
  50:  * Fred Canter 6/12/85
  51:  */
  52: #undef  BSIZE
  53: #define BSIZE   512
  54: 
  55: /*
  56:  *	BAD144 info for disk bad blocking. A zero entry in
  57:  *	di_size indicates that disk type has no bad blocking.
  58:  */
  59: #define NP  -1
  60: #define HP  1
  61: #define HM  2
  62: #define HJ  3
  63: 
  64: struct dkinfo {
  65:     char    *di_type;   /* type name of disk */
  66:     int di_flag;    /* prtdsk() flags */
  67:     char    *di_name;   /* ULTRIX-11 disk name */
  68:     long    di_size;    /* size of entire volume in blocks */
  69:     int di_nsect;   /* sectors per track */
  70:     int di_ntrak;   /* tracks per cylinder */
  71:     int di_wcpat[2];    /* worst case pattern */
  72: } dkinfo[] = {
  73:     "rk05", 0,  "rk",   4872L,      12, 0, 0, 0,
  74:     "rl01", 0,  "rl",   10240L,     20, 0, 0, 0,
  75:     "rl02", 0,  "rl",   20480L,     20, 0, 0, 0,
  76:     "ml11", NP, "hp",   8192L,      16, 0, 0, 0,
  77:     "ml11_0", HP,   "hp",   8192L,      16, 0, 0, 0,
  78:     "ml11_1", HM,   "hm",   8192L,      16, 0, 0, 0,
  79:     "ml11_2", HJ,   "hj",   8192L,      16, 0, 0, 0,
  80:     "rk06", 0,  "hk",   22L*3L*411L,    22, 3, 0135143, 072307,
  81:     "rk07", 0,  "hk",   22L*3L*815L,    22, 3, 0135143, 072307,
  82:     "rm02", NP, "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  83:     "rm02_0", HP,   "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  84:     "rm02_1", HM,   "hm",   32L*5L*823L,    32, 5, 0165555, 0133333,
  85:     "rm02_2", HJ,   "hj",   32L*5L*823L,    32, 5, 0165555, 0133333,
  86:     "rm03", NP, "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  87:     "rm03_0", HP,   "hp",   32L*5L*823L,    32, 5, 0165555, 0133333,
  88:     "rm03_1", HM,   "hm",   32L*5L*823L,    32, 5, 0165555, 0133333,
  89:     "rm03_2", HJ,   "hj",   32L*5L*823L,    32, 5, 0165555, 0133333,
  90:     "rm05", NP, "hp",   32L*19L*823L,   32, 19, 0165555, 0133333,
  91:     "rm05_0", HP,   "hp",   32L*19L*823L,   32, 19, 0165555, 0133333,
  92:     "rm05_1", HM,   "hm",   32L*19L*823L,   32, 19, 0165555, 0133333,
  93:     "rm05_2", HJ,   "hj",   32L*19L*823L,   32, 19, 0165555, 0133333,
  94:     "rp02", 0,  "rp",   10L*20L*200L,   10, 0, 0, 0,
  95:     "rp03", 0,  "rp",   10L*20L*400L,   10, 0, 0, 0,
  96:     "rp04", NP, "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
  97:     "rp04_0", HP,   "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
  98:     "rp04_1", HM,   "hm",   22L*19L*411L,   22, 19, 0165555, 0133333,
  99:     "rm04_2", HJ,   "hj",   22L*19L*411L,   22, 19, 0165555, 0133333,
 100:     "rp05", NP, "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
 101:     "rp05_0", HP,   "hp",   22L*19L*411L,   22, 19, 0165555, 0133333,
 102:     "rp05_1", HM,   "hm",   22L*19L*411L,   22, 19, 0165555, 0133333,
 103:     "rp05_2", HJ,   "hj",   22L*19L*411L,   22, 19, 0165555, 0133333,
 104:     "rp06", NP, "hp",   22L*19L*815L,   22, 19, 0165555, 0133333,
 105:     "rp06_0", HP,   "hp",   22L*19L*815L,   22, 19, 0165555, 0133333,
 106:     "rp06_1", HM,   "hm",   22L*19L*815L,   22, 19, 0165555, 0133333,
 107:     "rp06_2", HJ,   "hj",   22L*19L*815L,   22, 19, 0165555, 0133333,
 108: /*
 109:  * RA disks can't do full track reads because of buffer size.
 110:  * UDA50 buffering makes < full track reads plenty big enough.
 111:  * # sectors must divide evenly into total disk size
 112:  */
 113:     "ra60", 0,  "ra",   400176L,    28, 0, 0, 0,
 114:     "ra80", 0,  "ra",   236964L,    28, 0, 0, 0,
 115:     "ra81", 0,  "ra",   891072L,    32, 0, 0, 0,
 116:     "rx50", 0,  "rx",   800L,       10, 0, 0, 0,
 117:     "rx33", 0,  "rx",   2400L,      10, 0, 0, 0,
 118:     "rd31", 0,  "rd",   41560L,     20, 0, 0, 0,
 119:     "rd32", 0,  "rd",   83204L,     22, 0, 0, 0,
 120:     "rd51", 0,  "rd",   21600L,     18, 0, 0, 0,
 121:     "rd52", 0,  "rd",   60480L,     18, 0, 0, 0,
 122:     "rd53", 0,  "rd",   138672L,    18, 0, 0, 0,
 123:     "rd54", 0,  "rd",   311200L,    20, 0, 0, 0,
 124:     "rc25", 0,  "rc",   50902L,     31, 0, 0, 0,
 125:     0,
 126: };
 127: 
 128: struct  dkbad dkbad;
 129: struct dkinfo *dip;
 130: struct bt_bad *bt;
 131: int i;
 132: daddr_t bn;
 133: long nblk, nbo;
 134: int fd, rcnt;
 135: long    atol();
 136: char    line[20];
 137: char    fn[30];     /* file spec i.e., hp(0,0) */
 138: char    dt[20]; /* disk type rm03, etc */
 139: char    dn[2];      /* drive number */
 140: struct {
 141:     int t_cn;
 142:     int t_tn;
 143:     int t_sn;
 144: }da;
 145: char    buf[(BSIZE+4)*32];
 146: union {
 147:     long serl;
 148:     int  seri[2];
 149: }dsk;
 150: char    *bblock = "Block	Cyl	Trk	Sec\n";
 151: 
 152: extern int argflag; /* 0=interactive, 1=called by sdload */
 153: 
 154: main()
 155: {
 156:     printf("\n\nQuick Bad Block Scan Program\n");
 157: retry:
 158:     printf("\nDisk type <cr to exit, ? for list of disks>: ");
 159:     gets(dt);
 160:     if(dt[0] == '?'){
 161:         prtdsk();
 162:         goto retry;
 163:     }
 164:     if(strlen(dt) < 1)
 165:         exit(NORMAL);
 166:     for(dip=dkinfo; dip->di_type; dip++)
 167:         if(strcmp(dip->di_type, dt) == 0)
 168:             break;
 169:     if(dip->di_type == 0) {
 170:         printf("\n`%s' not a vaild disk type !\n", dt);
 171: rt_xit:
 172:         if(argflag)
 173:             exit(FATAL);
 174:         else
 175:             goto retry;
 176:     }
 177:     if(dip->di_size == 0L){
 178:         printf("\n`%s' not supported by standalone code !\n", dt);
 179:         goto rt_xit;
 180:     }
 181:     if(dip->di_nsect == 0){
 182:         printf("\n`%s' not supported by Bads !\n", dt);
 183:         goto rt_xit;
 184:     }
 185:     printf("\nUnit number: ");
 186:     gets(dn);
 187:     if((strlen(dn) != 1) || (dn[0] < '0') || (dn[0] > '3')) {
 188:         printf("\nUnits 0 -> 3 only !\n");
 189:         goto rt_xit;
 190:     }
 191:     sprintf(fn, "%s(%s,0)", dip->di_name, dn);
 192:     dskopen(0);
 193:     if(dip->di_ntrak){
 194:         bn = dip->di_size - dip->di_nsect;
 195:         printf("\nPrint bad sector file <[y] or n> ? ");
 196:         gets(line);
 197:         if(line[0] == 'y' || line[0] == '\0')
 198:             if(showbad()) {
 199:                 printf("\n\7\7\7Invalid or No bad sector file.\n");
 200:                 printf("Disk pack must be initialized with\n");
 201:                 printf("DSKINIT before use with ULTRIX-11.\n\n");
 202:                 if(argflag)
 203:                     exit(NO_BBF);
 204:             }
 205:     }
 206:     printf("\nScan disk pack for bad blocks <[y] or n> ? ");
 207:     gets(line);
 208:     if(line[0] == 'y' || line[0] == '\0')
 209:         scanbad();
 210:     close(fd);
 211:     goto retry;
 212: }
 213: 
 214: showbad(){
 215:     if(readbad()){
 216:         return(1);
 217:     }
 218:     dsk.seri[0] = dkbad.bt_csnh;
 219:     dsk.seri[1] = dkbad.bt_csnl;
 220:     printf("Cartridge serial number: %D\n", dsk.serl);
 221:     switch(dkbad.bt_flag) {
 222:         case -1:
 223:             printf("\nAlignment cartridge !\n");
 224:             return(1);
 225:             break;
 226:         case 0:
 227:             break;
 228:         default:
 229:             printf("\nBad sector file flag word = %o\n"
 230:                     , dkbad.bt_flag);
 231:             return(1);
 232:     }
 233:     printf("Block\t  Cyl\t  Trk\t  Sec\n");
 234:     for(i=0; i<(BSIZE/sizeof(long)); i++, bt++) {
 235:         if(bt->bt_cyl == 0177777)
 236:             break;
 237:         if(bt->bt_cyl == 0 && bt->bt_trksec == 0){
 238:             dkbad.bt_mbz = -1;
 239:             printf("Pack has Invalid Bad Sector file\n");
 240:             return(-1);
 241:         }
 242:         bn=((long)bt->bt_cyl *
 243:            (long)dip->di_ntrak+(long)(bt->bt_trksec>>8)) *
 244:            (long)dip->di_nsect + (long)(bt->bt_trksec&0377);
 245:         printf("%D\t  %u\t  %d\t  %d\n", bn, bt->bt_cyl,
 246:             bt->bt_trksec>>8, bt->bt_trksec&0377);
 247:     }
 248:     return(0);
 249: }
 250: 
 251: scanbad(){
 252:     int badcnt, rsize, j;
 253:     long rbn, rrbn;
 254: 
 255:     printf("\nBlock offset: ");
 256:     gets(line);
 257:     if(strlen(line) > 6 || (nbo = atol(line)) < 0 || nbo > dip->di_size){
 258:         printf("\nBad offset !\n");
 259:         return(1);
 260:     }
 261:     printf("\n# of blocks <cr for full pack>: ");
 262:     gets(line);
 263:     if(line[0] == '\0')
 264:         nblk = dip->di_size;
 265:     else
 266:         nblk = atol(line);
 267:     if(nblk <= 0) {
 268:         printf("\nBad # of blocks !\n");
 269:         return(1);
 270:     }
 271:     if((nbo + nblk) > dip->di_size){
 272:         nblk = dip->di_size - nbo;
 273:         printf("Offset + # of blocks too large\n");
 274:         printf("Truncating # of blocks to %D\n", nblk);
 275:     }
 276:     rsize = dip->di_nsect * BSIZE;
 277:     printf("READING\n");
 278:     for(badcnt = bn = 0; bn<nblk;) {
 279:         lseek(fd, (bn+nbo)*BSIZE, 0);
 280:         BAD_CMD->r[0] = BAD_CHK;
 281:         if(rsize <= 0 || rsize > (BSIZE*dip->di_nsect))
 282:             rsize = BSIZE*dip->di_nsect;
 283:         rcnt = read(fd, buf, rsize);
 284:         if(rcnt < 0){
 285:             rbn = bn+nbo;
 286:             if(dip->di_ntrak){
 287:                 btoa(rbn);
 288:                 printf("\n\nFATAL Error at ");
 289:                 printf("Block %D\t cyl %d\t  trk %d\t  sec %d\n"
 290:                    , rbn, da.t_cn, da.t_tn, da.t_sn);
 291:             }
 292:             else {
 293:                 printf("\n\nBAD BLOCK IN CLUSTER: ");
 294:                 printf("finding actual block number\n");
 295:                 rrbn = bn+nbo;
 296:                 for(j=0; ((j*BSIZE)<rsize); j++) {
 297:                     lseek(fd, (long)(rrbn*BSIZE), 0);
 298:                     rcnt = read(fd, (char *)&buf, BSIZE);
 299:                     if(rcnt != BSIZE) {
 300:                         badcnt++;
 301:                         printf("%s%D\t\t\t\t%s", bblock,
 302:                         rrbn,
 303:                         "BAD BLOCK\n");
 304:                     }
 305:                     rrbn++;
 306:                 }
 307:                 goto cont;
 308:             }
 309:             exit(FATAL);
 310:         }
 311:         else if(rcnt !=  rsize){
 312:             badcnt++;
 313:             rbn = (bn+nbo) + (rcnt/BSIZE);
 314:             if(dip->di_ntrak){
 315:                 btoa(rbn);
 316:                 printf("%s%D\t%d\t%d\t%d\t%s"
 317:                 , bblock
 318:                 , rbn, da.t_cn, da.t_tn, da.t_sn
 319:                 ,"BAD BLOCK\n\n");
 320:             }
 321:             else
 322:                 printf("%s%D\t\t\t\t\t%s",bblock, rbn, "BAD BLOCK\n");
 323:             bn = ++rbn - nbo;
 324:             rsize = (dip->di_nsect - ((rcnt/BSIZE)+1))* BSIZE;
 325:         }
 326:         else{
 327:     cont:
 328:             bn += dip->di_nsect;
 329:             bn -= bn%dip->di_nsect;
 330:             rsize = dip->di_nsect * BSIZE;
 331:         }
 332:         if(badcnt >= dip->di_nsect && dip->di_ntrak){
 333:             printf("\n\nTOO MANY BAD BLOCKS ON THIS PACK.\n");
 334:             printf("ONLY %d BAD BLOCKS ALLOWED ON AN %s DISK\n"
 335:                 , dip->di_nsect, dip->di_type);
 336:             printf("DO NOT USE THIS PACK\n");
 337:             exit(FATAL);
 338:         }
 339:     }
 340:     printf("\n%D blocks checked\n", bn);
 341:     printf("%d bad blocks found\n", badcnt);
 342:     if(argflag && badcnt)
 343:         exit(HASBADS);
 344:     else
 345:         return(0);
 346: }
 347: 
 348: btoa(bn)
 349: long bn;
 350: {
 351:     da.t_cn = bn/(dip->di_ntrak*dip->di_nsect);
 352:     da.t_sn = bn%(dip->di_ntrak*dip->di_nsect);
 353:     da.t_tn = da.t_sn/dip->di_nsect;
 354:     da.t_sn = da.t_sn%dip->di_nsect;
 355: }
 356: 
 357: readbad()
 358: {
 359:     int cnt;
 360: 
 361:     dkbad.bt_mbz = -1;
 362:     bn = dip->di_size - dip->di_nsect;  /* first sector of last track */
 363:     for(cnt = 0; cnt < 5; cnt++){
 364:         lseek(fd, BSIZE * bn, 0);
 365:         printf("\nBad sector file at block %D of %s\n", bn, fn);
 366:         if(read(fd, &dkbad, sizeof(struct dkbad))
 367:           != sizeof(struct dkbad)) {
 368:             bn += 2;
 369:             continue;
 370:         }
 371:         break;
 372:     }
 373:     if(cnt >= 5){
 374:         printf("\nCan't read bad sector file for %s unit %s !\n"
 375:         , dip->di_type, dn);
 376:         exit(FATAL);
 377:     }
 378:     bt = dkbad.bt_badb;
 379:     if(dkbad.bt_mbz || (dkbad.bt_csnl == 0 && dkbad.bt_csnh == 0)){
 380:         dkbad.bt_mbz = -1;
 381:         return(1);
 382:     }
 383:     return(0);
 384: }
 385: 
 386: dskopen(mode)
 387: int mode;
 388: {
 389:     if((fd = open(fn, mode)) <= 0) {
 390:         printf("\nCan't open %s !\n", fn);
 391:         exit(FATAL);
 392:     }
 393: }
 394: 
 395: prtdsk()
 396: {
 397:     struct dkinfo *dp;
 398: 
 399:     printf("\nDisk\tULTRIX\tSize in");
 400:     printf("\nName\tName\tBlocks\tComments");
 401:     printf("\n----\t----\t------\t--------");
 402:     for(dp=dkinfo; dp->di_type; dp++){
 403:         if(dp->di_flag == NP)
 404:             continue;
 405:         printf("\n%s\t", dp->di_type);
 406:         printf("%s\t", dp->di_name);
 407:         printf("%D\t", dp->di_size);
 408:         if(dp->di_flag == HP)
 409:             printf("(first  ) RH11/RH70 Controller");
 410:         if(dp->di_flag == HM)
 411:             printf("(second ) RH11/RH70 Controller");
 412:         if(dp->di_flag == HJ)
 413:             printf("(third  ) RH11/RH70 Controller");
 414:     }
 415:     printf("\n");
 416: }

Defined functions

btoa defined in line 348; used 2 times
dskopen defined in line 386; used 1 times
main defined in line 154; never used
prtdsk defined in line 395; used 1 times
readbad defined in line 357; used 1 times
scanbad defined in line 251; used 1 times
showbad defined in line 214; used 1 times

Defined variables

bblock defined in line 150; used 3 times
bn defined in line 132; used 22 times
bt defined in line 130; used 11 times
buf defined in line 145; used 2 times
dip defined in line 129; used 39 times
dkbad defined in line 128; used 12 times
dkinfo defined in line 72; used 2 times
dn defined in line 139; used 6 times
dt defined in line 138; used 7 times
fd defined in line 134; used 8 times
fn defined in line 137; used 4 times
i defined in line 131; used 3 times
  • in line 234(3)
line defined in line 136; used 12 times
nblk defined in line 133; used 7 times
nbo defined in line 133; used 9 times
rcnt defined in line 134; used 7 times

Defined struct's

dkinfo defined in line 64; used 4 times

Defined macros

BSIZE defined in line 53; used 16 times
HJ defined in line 62; used 8 times
HM defined in line 61; used 8 times
HP defined in line 60; used 8 times
NP defined in line 59; used 8 times
Last modified: 1992-12-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3821
Valid CSS Valid XHTML 1.0 Strict