1: /* 2: * bad144 3: * 4: * This program prints and/or initializes a bad block record for a pack, 5: * in the format used by the DEC standard 144. 6: * 7: * BUGS: 8: * Only reads/writes the first of the bad block record (sector 0 9: * of the last track of the disk); in fact, there are copies 10: * of the information in the first 5 even numbered sectors of this 11: * track, but UNIX uses only the first, and we don't bother with the 12: * others. 13: * 14: * It is preferable to write the bad information with a standard formatter, 15: * but this program will do in a pinch, e.g. if the bad information is 16: * accidentally wiped out this is a much faster way of restoring it than 17: * reformatting. To add a new bad sector the formatter must be used in 18: * general since UNIX doesn't have on-line formatters to write the BSE 19: * error in the header. 20: * 21: * RP07 entry added August 10, 1993 (thanks to Johnny Billquist) - SMS 22: * 23: * lseek() replaced tell() - Jan 21, 1994 - SMS 24: */ 25: #include <sys/param.h> 26: #ifndef BADSECT 27: #define BADSECT 28: #endif !BADSECT 29: #include <sys/types.h> 30: #include <sys/dkbad.h> 31: #include <stdio.h> 32: 33: struct diskinfo { 34: char *di_type; /* type name of disk */ 35: daddr_t di_size; /* size of entire volume in sectors */ 36: int di_nsect; /* sectors per track */ 37: int di_ntrak; /* tracks per cylinder */ 38: } diskinfo[] = { 39: "rk06", 22*3*411L, 22, 3, 40: "rk07", 22*3*815L, 22, 3, 41: "rm02", 32*5*823L, 32, 5, 42: "rm03", 32*5*823L, 32, 5, 43: "rm05", 32*19*823L, 32, 19, 44: "cdc9766", 32*19*823L, 32, 19, 45: "rp04", 22*19*411L, 22, 19, 46: "rp05", 22*19*411L, 22, 19, 47: "rp06", 22*19*815L, 22, 19, 48: "rp07", 50*32*630L, 50, 32, 49: "fuji160", 32*10*823L, 32, 10, 50: "diva", 33*19*815L, 33, 19, 51: "ampex9300", 33*19*815L, 33, 19, 52: "si_eagle", 48*20*842L, 48, 20, 53: 0, 54: }; 55: union { 56: struct dkbad bad; 57: char buf[512]; 58: } dkbad; 59: off_t lseek(); 60: long atol(); 61: 62: main(argc, argv) 63: int argc; 64: char **argv; 65: { 66: register struct diskinfo *di; 67: register struct bt_bad *bt; 68: char name[BUFSIZ]; 69: int i, f, errs; 70: daddr_t bad; 71: int toomany = 0; 72: 73: argc--, argv++; 74: if (argc < 2) { 75: fprintf(stderr, "usage: bad type disk [ snum [ bn ... ] ]\n"); 76: fprintf(stderr, "e.g.: bad rk07 hk0\n"); 77: exit(1); 78: } 79: for (di = diskinfo; di->di_type; di++) 80: if (!strcmp(di->di_type, argv[0])) 81: goto found; 82: fprintf(stderr, "%s: not a known disk type\n", argv[0]); 83: fprintf(stderr, "known types:"); 84: for (di = diskinfo; di->di_type; di++) 85: fprintf(stderr, " %s", di->di_type); 86: fprintf(stderr, "\n"); 87: exit(1); 88: found: 89: sprintf(name, "/dev/r%sh", argv[1]); 90: argc -= 2; 91: argv += 2; 92: if (argc == 0) { 93: f = open(name, 0); 94: if (f < 0) { 95: perror(name); 96: exit(1); 97: } 98: lseek(f, 512 * (di->di_size - di->di_nsect), 0); 99: printf("bad block information at 0x%X in %s:\n", 100: lseek(f,0L,1), name); 101: if (read(f, &dkbad, 512) != 512) { 102: fprintf(stderr, "%s: can't read bad block info (wrong type disk?)\n", name); 103: exit(1); 104: } 105: printf("cartridge serial number: %D(10)\n", dkbad.bad.bt_csn); 106: switch (dkbad.bad.bt_flag) { 107: case -1: 108: printf("alignment cartridge\n"); 109: break; 110: case 0: 111: break; 112: default: 113: printf("bt_flag=%x(16)?\n", dkbad.bad.bt_flag); 114: break; 115: } 116: bt = dkbad.bad.bt_bad; 117: for (i = 0; i < 126; i++) { 118: bad = ((daddr_t)bt->bt_cyl<<16) + bt->bt_trksec; 119: if (bad < 0) 120: break; 121: if (!toomany && i >= MAXBAD) { 122: toomany++; 123: printf("More bad sectors than system supports.\n"); 124: printf("The remainder are not being replaced automatically...\n"); 125: } 126: printf("sn=%D, cn=%d, tn=%d, sn=%d\n", 127: ((daddr_t)bt->bt_cyl*di->di_ntrak + (bt->bt_trksec>>8)) * 128: di->di_nsect + (bt->bt_trksec&0xff), 129: bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff); 130: bt++; 131: } 132: exit (0); 133: } 134: f = open(name, 1); 135: if (f < 0) { 136: perror(name); 137: exit(1); 138: } 139: dkbad.bad.bt_csn = atol(*argv++); 140: argc--; 141: dkbad.bad.bt_mbz = 0; 142: if (argc > 2 * di->di_nsect || argc > MAXBAD) { 143: printf("bad: too many bad sectors specified\n"); 144: if (argc > MAXBAD) 145: printf("system is currently configured for only %d\n", MAXBAD); 146: else 147: printf("limited to %d (only 2 tracks of sectors)\n", 148: 2 * di->di_nsect); 149: if (2 * di->di_nsect > 126) 150: printf("limited to 126 by information format\n"); 151: exit(1); 152: } 153: errs = 0; 154: i = 0; 155: while (argc > 0) { 156: long sn = atol(*argv++); 157: argc--; 158: if (sn < 0 || sn >= di->di_size) { 159: printf("%d: out of range [0,%d) for %s\n", 160: sn, di->di_size, di->di_type); 161: errs++; 162: } 163: dkbad.bad.bt_bad[i].bt_cyl = sn / (di->di_nsect*di->di_ntrak); 164: sn %= (di->di_nsect*di->di_ntrak); 165: dkbad.bad.bt_bad[i].bt_trksec = 166: ((sn/di->di_nsect) << 8) + (sn%di->di_nsect); 167: i++; 168: } 169: while (i < 126) { 170: dkbad.bad.bt_bad[i].bt_trksec = -1; 171: dkbad.bad.bt_bad[i].bt_cyl = -1; 172: i++; 173: } 174: if (errs) 175: exit(1); 176: lseek(f, 512 * (di->di_size - di->di_nsect), 0); 177: if (write(f, (caddr_t)&dkbad, 512) != 512) { 178: perror(name); 179: exit(1); 180: } 181: exit(0); 182: }