|
|
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.