|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)bad144.c 4.7 (Berkeley) 83/07/27"; ! 3: #endif ! 4: ! 5: /* ! 6: * bad144 ! 7: * ! 8: * This program prints and/or initializes a bad block record for a pack, ! 9: * in the format used by the DEC standard 144. ! 10: * ! 11: * BUGS: ! 12: * Only reads/writes the first of the bad block record (sector 0 ! 13: * of the last track of the disk); in fact, there are copies ! 14: * of the information in the first 5 even numbered sectors of this ! 15: * track, but UNIX uses only the first, and we don't bother with the ! 16: * others. ! 17: * ! 18: * It is preferable to write the bad information with a standard formatter, ! 19: * but this program will do in a pinch, e.g. if the bad information is ! 20: * accidentally wiped out this is a much faster way of restoring it than ! 21: * reformatting. ! 22: * ! 23: * RP06 sectors are marked as bad by inverting the format bit in the ! 24: * header; on other drives the BSE bit is set. ! 25: */ ! 26: #include <sys/types.h> ! 27: #include <sys/dkbad.h> ! 28: #include <sys/ioctl.h> ! 29: #include <sys/file.h> ! 30: #include <machine/dkio.h> ! 31: ! 32: #include <stdio.h> ! 33: #include <disktab.h> ! 34: ! 35: int fflag; ! 36: struct dkbad dkbad; ! 37: ! 38: main(argc, argv) ! 39: int argc; ! 40: char *argv[]; ! 41: { ! 42: register struct bt_bad *bt; ! 43: register struct disktab *dp; ! 44: char name[BUFSIZ]; ! 45: int size, i, f, bad, oldbad, errs; ! 46: ! 47: argc--, argv++; ! 48: if (argc > 0 && strcmp(*argv, "-f") == 0) { ! 49: argc--, argv++; ! 50: fflag++; ! 51: } ! 52: if (argc < 2) { ! 53: fprintf(stderr, ! 54: "usage: bad144 [ -f ] type disk [ snum [ bn ... ] ]\n"); ! 55: fprintf(stderr, "e.g.: bad144 rk07 hk0\n"); ! 56: exit(1); ! 57: } ! 58: dp = getdiskbyname(argv[0]); ! 59: if (dp == NULL) { ! 60: fprintf(stderr, "%s: unknown disk type\n", argv[0]); ! 61: exit(1); ! 62: } ! 63: sprintf(name, "/dev/r%sc", argv[1]); ! 64: argc -= 2; ! 65: argv += 2; ! 66: size = dp->d_nsectors * dp->d_ntracks * dp->d_ncylinders; ! 67: if (argc == 0) { ! 68: f = open(name, O_RDONLY); ! 69: if (f < 0) ! 70: Perror(name); ! 71: if (lseek(f, dp->d_secsize*(size-dp->d_nsectors), L_SET) < 0) ! 72: Perror("lseek"); ! 73: printf("bad block information at sector %d in %s:\n", ! 74: tell(f)/512, name); ! 75: if (read(f, &dkbad, sizeof (struct dkbad)) != ! 76: sizeof (struct dkbad)) { ! 77: fprintf("bad144: %s: can't read bad block info\n"); ! 78: exit(1); ! 79: } ! 80: printf("cartidge serial number: %d(10)\n", dkbad.bt_csn); ! 81: switch (dkbad.bt_flag) { ! 82: ! 83: case -1: ! 84: printf("alignment cartridge\n"); ! 85: break; ! 86: ! 87: case 0: ! 88: break; ! 89: ! 90: default: ! 91: printf("bt_flag=%x(16)?\n", dkbad.bt_flag); ! 92: break; ! 93: } ! 94: oldbad = 0; ! 95: bt = dkbad.bt_bad; ! 96: for (i = 0; i < 128; i++) { ! 97: bad = (bt->bt_cyl<<16) + bt->bt_trksec; ! 98: if (bad < 0) ! 99: break; ! 100: printf("sn=%d, cn=%d, tn=%d, sn=%d\n", ! 101: (bt->bt_cyl*dp->d_ntracks + (bt->bt_trksec>>8)) * ! 102: dp->d_nsectors + (bt->bt_trksec&0xff), ! 103: bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff); ! 104: bt++; ! 105: } ! 106: exit(0); ! 107: } ! 108: f = open(name, 1 + fflag); ! 109: if (f < 0) ! 110: Perror(name); ! 111: dkbad.bt_csn = atoi(*argv++); ! 112: argc--; ! 113: dkbad.bt_mbz = 0; ! 114: if (argc > 126) { ! 115: printf("bad144: too many bad sectors specified\n"); ! 116: printf("limited to 126 by information format\n"); ! 117: exit(1); ! 118: } ! 119: errs = 0; ! 120: i = 0; ! 121: while (argc > 0) { ! 122: int sn = atoi(*argv++); ! 123: ! 124: argc--; ! 125: if (sn < 0 || sn >= size) { ! 126: printf("%d: out of range [0,%d) for %s\n", ! 127: sn, size, dp->d_name); ! 128: errs++; ! 129: } ! 130: dkbad.bt_bad[i].bt_cyl = sn / (dp->d_nsectors*dp->d_ntracks); ! 131: sn %= (dp->d_nsectors*dp->d_ntracks); ! 132: dkbad.bt_bad[i].bt_trksec = ! 133: ((sn/dp->d_nsectors) << 8) + (sn%dp->d_nsectors); ! 134: i++; ! 135: } ! 136: while (i < 126) { ! 137: dkbad.bt_bad[i].bt_trksec = -1; ! 138: dkbad.bt_bad[i].bt_cyl = -1; ! 139: i++; ! 140: } ! 141: if (errs) ! 142: exit(1); ! 143: if (lseek(f, dp->d_secsize * (size - dp->d_nsectors), L_SET) < 0) ! 144: Perror("lseek"); ! 145: if (write(f, (caddr_t)&dkbad, sizeof (dkbad)) != sizeof (dkbad)) ! 146: Perror(name); ! 147: if (fflag) ! 148: for (i = 0, bt = dkbad.bt_bad; i < 126; i++, bt++) { ! 149: daddr_t bn; ! 150: ! 151: bad = (bt->bt_cyl<<16) + bt->bt_trksec; ! 152: if (bad < 0) ! 153: break; ! 154: bn = (bt->bt_cyl * dp->d_ntracks + ! 155: (bt->bt_trksec >> 8)) * ! 156: dp->d_nsectors + (bt->bt_trksec & 0xff); ! 157: format(f, dp, bn); ! 158: } ! 159: exit(0); ! 160: } ! 161: ! 162: struct rp06hdr { ! 163: short h_cyl; ! 164: short h_trksec; ! 165: short h_key1; ! 166: short h_key2; ! 167: char h_data[512]; ! 168: #define RP06_FMT 010000 /* 1 == 16 bit, 0 == 18 bit */ ! 169: }; ! 170: ! 171: /* ! 172: * Most massbus and unibus drives ! 173: * have headers of this form ! 174: */ ! 175: struct hpuphdr { ! 176: u_short hpup_cyl; ! 177: u_short hpup_trksec; ! 178: char hpup_data[512]; ! 179: #define HPUP_OKSECT 0xc000 /* this normally means sector is good */ ! 180: }; ! 181: ! 182: struct formats { ! 183: char *f_name; /* disk name */ ! 184: int f_bufsize; /* size of sector + header */ ! 185: int f_bic; /* value to bic in hpup_cyl */ ! 186: int (*f_routine)(); /* routine for special handling */ ! 187: } formats[] = { ! 188: { "rp06", sizeof (struct rp06hdr), RP06_FMT, 0 }, ! 189: { "eagle", sizeof (struct hpuphdr), HPUP_OKSECT, 0 }, ! 190: { "capricorn", sizeof (struct hpuphdr), HPUP_OKSECT, 0 }, ! 191: { 0, 0, 0, 0 } ! 192: }; ! 193: ! 194: format(fd, dp, blk) ! 195: int fd; ! 196: struct disktab *dp; ! 197: daddr_t blk; ! 198: { ! 199: register struct formats *fp; ! 200: char *buf, *malloc(); ! 201: ! 202: for (fp = formats; fp->f_name; fp++) ! 203: if (strcmp(dp->d_name, fp->f_name) == 0) ! 204: break; ! 205: if (fp->f_name == 0) { ! 206: fprintf(stderr, "bad144: don't know how to format %s disks\n", ! 207: dp->d_name); ! 208: exit(2); ! 209: } ! 210: buf = malloc(fp->f_bufsize); ! 211: if (buf == NULL) { ! 212: fprintf(stderr, "bad144: can't allocate sector buffer\n"); ! 213: exit(3); ! 214: } ! 215: /* ! 216: * Here we do the actual formatting. All we really ! 217: * do is rewrite the sector header and flag the bad sector ! 218: * according to the format table description. If a special ! 219: * purpose format routine is specified, we allow it to ! 220: * process the sector as well. ! 221: */ ! 222: if (lseek(fd, (long)blk * 512, L_SET) < 0) ! 223: Perror("lseek"); ! 224: if (ioctl(fd, DKIOCHDR, 0) < 0) ! 225: Perror("ioctl"); ! 226: read(fd, buf, fp->f_bufsize); ! 227: if (fp->f_bic) { ! 228: struct hpuphdr *xp = (struct hpuphdr *)buf; ! 229: ! 230: xp->hpup_cyl &= ~fp->f_bic; ! 231: } ! 232: if (fp->f_routine) ! 233: (*fp->f_routine)(fp, dp, blk, buf); ! 234: if (lseek(fd, (long)blk * 512, L_SET) < 0) ! 235: Perror("lseek"); ! 236: if (ioctl(fd, DKIOCHDR, 0) < 0) ! 237: Perror("ioctl"); ! 238: if (write(fd, buf, fp->f_bufsize) != fp->f_bufsize) ! 239: Perror("write"); ! 240: } ! 241: ! 242: Perror(op) ! 243: char *op; ! 244: { ! 245: ! 246: fprintf(stderr, "bad144: "); perror(op); ! 247: exit(4); ! 248: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.