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: }