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