1 /*
2 * Copyright (c) 1992 OMRON Corporation.
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * OMRON Corporation.
8 *
9 * %sccs.include.redist.c%
10 *
11 * @(#)disklabel.c 8.1 (Berkeley) 06/10/93
12 */
13
14 /*
15 * disklabel.c -- operate disklabel for BSD & OMRON
16 * by A.Fujita, FEB-17-1992
17 */
18
19 #include <sys/param.h>
20 #define DKTYPENAMES
21 #include <sys/disklabel.h>
22 #include <luna68k/stand/saio.h>
23 #include <luna68k/stand/status.h>
24 #include <luna68k/stand/omron_disklabel.h>
25
26 #define LABEL_SIZE BBSIZE
27
28 u_char lbl_buff[LABEL_SIZE];
29
30 u_short
dkcksum(lp)31 dkcksum(lp)
32 register struct disklabel *lp;
33 {
34 register u_short *start, *end;
35 register u_short sum = 0;
36
37 start = (u_short *)lp;
38 end = (u_short *)&lp->d_partitions[lp->d_npartitions];
39 while (start < end)
40 sum ^= *start++;
41 return (sum);
42 }
43
44 int
disklabel(argc,argv)45 disklabel(argc, argv)
46 int argc;
47 char *argv[];
48 {
49 register struct scd_dk_label *omp = (struct scd_dk_label *) lbl_buff;
50 register struct disklabel *bp = (struct disklabel *)omp->dkl_pad;
51 register struct fs *fp = (struct fs *) lbl_buff;
52 register u_short *p;
53 register u_long chksum, count;
54 register char *q;
55 register int i, j;
56
57 if (argc < 2) {
58 printf("This command is required sub command !!\n");
59 return(ST_ERROR);
60 }
61
62 if (!strcmp(argv[1], "help")) {
63 printf("Subcommand of disklabel\n\n");
64 printf("\thelp:\t\tthis command\n");
65 printf("\tread:\t\tread disklabel from scsi_device\n");
66 printf("\twrite:\t\twrite disklabel to scsi_device\n");
67 printf("\tomron:\t\tshow OMRON disklabel infomation\n");
68 printf("\tbsd:\t\tshow BSD disklabel infomation\n");
69 printf("\tcopy:\t\tcopy disklabel infomation from OMRON to BSD\n");
70 printf("\tchecksum:\tdoing checksum\n");
71 printf("\tset:\t\tchange BSD disklabel infomation\n");
72 printf("\n\n");
73 } else if (!strcmp(argv[1], "read")) {
74 if (scsi_read( 0, lbl_buff, LABEL_SIZE)) {
75 printf("Disk Label read done.\n");
76 } else {
77 printf("Disk Label read error !!\n");
78 }
79 } else if (!strcmp(argv[1], "omron")) {
80 i = (int) &omp->dkl_badchk;
81 i -= (int) lbl_buff;
82 printf("Offset = %d\n", i);
83 printf("\n");
84 printf("Checksum of Bad Track:\t0x%x\n", omp->dkl_badchk);
85 printf("Logical Block Total:\t%d(0x%x)\n", omp->dkl_maxblk, omp->dkl_maxblk);
86 printf("Disk Drive Type:\t0x%x\n", omp->dkl_dtype);
87 printf("Number of Disk Drives:\t%d(0x%x)\n", omp->dkl_ndisk, omp->dkl_ndisk);
88 printf("Number of Data Cylinders:\t%d(0x%x)\n", omp->dkl_ncyl, omp->dkl_ncyl);
89 printf("Number of Alternate Cylinders:\t%d(0x%x)\n",
90 omp->dkl_acyl,omp->dkl_acyl);
91 printf("Number of Heads in This Partition:\t%d(0x%x)\n",
92 omp->dkl_nhead, omp->dkl_nhead);
93 printf("Number of 512 byte Sectors per Track:\t%d(0x%x)\n",
94 omp->dkl_nsect, omp->dkl_nsect);
95 printf("Identifies Proper Label Locations:\t0x%x\n",
96 omp->dkl_bhead);
97 printf("Physical Partition Number:\t%d(0x%x)\n",
98 omp->dkl_ppart, omp->dkl_ppart);
99 for (i = 0; i < NLPART; i++)
100 printf("\t%d:\t%d\t%d\n", i,
101 omp->dkl_map[i].dkl_blkno, omp->dkl_map[i].dkl_nblk);
102 printf("Identifies This Label Format:\t0x%x\n", omp->dkl_magic);
103 printf("XOR Checksum of Sector:\t0x%x\n", omp->dkl_cksum);
104 } else if (!strcmp(argv[1], "checksum")) {
105 if (omp->dkl_magic == DKL_MAGIC){
106 /* checksum of disk-label */
107 chksum = 0;
108 count = sizeof(struct scd_dk_label) / sizeof(short int);
109 for (p= (u_short *) lbl_buff; count > 0; count--) {
110 if (count == 1)
111 printf("Check Sum: 0x%x\n", chksum);
112 chksum ^= *p++;
113 }
114
115 printf("dkl_cksum: 0x%x\n", omp->dkl_cksum);
116
117 if (chksum != 0) {
118 printf("OMRON Disklabel check sum error.\n");
119 }
120 } else {
121 printf("OMRON Disklabel not found.\n");
122 }
123 } else if (!strcmp(argv[1], "copy")) {
124 bzero(bp, sizeof(struct disklabel));
125
126 bcopy(lbl_buff, bp->d_typename, 16);
127
128 bp->d_secsize = DEV_BSIZE;
129 bp->d_nsectors = 38;
130 bp->d_ntracks = 12;
131 bp->d_ncylinders = 1076;
132
133 bp->d_type = DTYPE_SCSI;
134
135 bp->d_secpercyl = bp->d_nsectors * bp->d_ntracks;
136 bp->d_secperunit = bp->d_secpercyl * bp->d_ncylinders;
137 bp->d_rpm = 3600;
138 bp->d_interleave = 1;
139 bp->d_trackskew = 0;
140 bp->d_cylskew = 0;
141 bp->d_headswitch = 0;
142 bp->d_trkseek = 0;
143 bp->d_bbsize = BBSIZE;
144 bp->d_sbsize = SBSIZE;
145
146 for (i = 0; i < MAXPARTITIONS; i++) {
147 bp->d_partitions[i].p_size = omp->dkl_map[i].dkl_nblk;
148 bp->d_partitions[i].p_offset = omp->dkl_map[i].dkl_blkno;
149 bp->d_partitions[i].p_fsize = 1024;
150 bp->d_partitions[i].p_frag = 8192 / 1024;
151 bp->d_partitions[i].p_fstype = FS_UNUSED;
152 }
153
154 bp->d_npartitions = MAXPARTITIONS;
155
156 for (i = 0; i < NDDATA; i++) {
157 bp->d_drivedata[i] = 0;
158 }
159
160 bzero(bp->d_packname, 16);
161
162 bp->d_magic = DISKMAGIC;
163 bp->d_magic2 = DISKMAGIC;
164 bp->d_checksum = 0;
165 bp->d_checksum = dkcksum(bp);
166
167 /* restump checksum of OMRON disklabel */
168 chksum = 0;
169 count = sizeof(struct scd_dk_label) / sizeof(short int);
170 for (p= (u_short *) lbl_buff; count > 1; count--) {
171 chksum ^= *p++;
172 }
173 printf("chksum: 0x%x\n", chksum);
174
175 omp->dkl_cksum = chksum;
176 printf("dkl_cksum: 0x%x\n", omp->dkl_cksum);
177 } else if (!strcmp(argv[1], "bsd")) {
178 display(bp);
179 } else if (!strcmp(argv[1], "write")) {
180 if (scsi_write( 0, lbl_buff, LABEL_SIZE)) {
181 printf("Disk Label write done.\n");
182 } else {
183 printf("Disk Label write error !!\n");
184 }
185 } else if (!strcmp(argv[1], "set")) {
186 i = (argv[2])[1] - 'a';
187 for (q = argv[3], j = 0; *q != NULL; q++) {
188 j = (j * 10) + (*q - '0');
189 }
190 switch (*argv[2]) {
191 case 'b':
192 bp->d_partitions[i].p_frag = j / bp->d_partitions[i].p_fsize;
193 break;
194 case 'f': /* fragment size */
195 bp->d_partitions[i].p_fsize = j;
196 break;
197 case 'o': /* offset */
198 bp->d_partitions[i].p_offset = j;
199 omp->dkl_map[i].dkl_blkno = j;
200 break;
201 case 'p': /* size */
202 bp->d_partitions[i].p_size = j;
203 omp->dkl_map[i].dkl_nblk = j;
204 break;
205 case 't': /* FS type */
206 bp->d_partitions[i].p_fstype = j;
207 break;
208 default:
209 break;
210 }
211
212 /* restump checksum of BSD disklabel */
213 bp->d_checksum = 0;
214 bp->d_checksum = dkcksum(bp);
215
216 /* restump checksum of OMRON disklabel */
217 chksum = 0;
218 count = sizeof(struct scd_dk_label) / sizeof(short int);
219 for (p= (u_short *) lbl_buff; count > 1; count--) {
220 chksum ^= *p++;
221 }
222 omp->dkl_cksum = chksum;
223
224 } else if (!strcmp(argv[1], "sb")) {
225 #define BLOCK_SIZE SBSIZE
226
227 printf("checking Super Block: block size = %d bytes, seek amount = 1 blocks\n",
228 BLOCK_SIZE);
229 i = j = 0;
230 while(1) {
231 if (!scsi_read( i, lbl_buff, BLOCK_SIZE))
232 break;
233
234 if (fp->fs_magic == FS_MAGIC) {
235 printf("%d, (%d)\n", i, i - j);
236 j = i;
237 }
238 i++;
239 }
240 } else if (!strcmp(argv[1], "sbcopy")) {
241 if (!scsi_read(32, lbl_buff, BLOCK_SIZE)) {
242 printf("sbcopy: read failed\n");
243 return(ST_ERROR);
244 }
245 if (scsi_write(16, lbl_buff, BLOCK_SIZE)) {
246 printf("sbcopy: copy done\n");
247 } else {
248 printf("sbcopy: write failed\n");
249 }
250 }
251
252 return(ST_NORMAL);
253 }
254
255 int
display(lp)256 display(lp)
257 register struct disklabel *lp;
258 {
259 register int i, j;
260 register struct partition *pp;
261
262 if ((unsigned) lp->d_type < DKMAXTYPES)
263 printf("type: %s\n", dktypenames[lp->d_type]);
264 else
265 printf("type: %d\n", lp->d_type);
266 printf("disk: %s\n", lp->d_typename);
267 printf("label: %s\n", lp->d_packname);
268 printf("flags:");
269 if (lp->d_flags & D_REMOVABLE)
270 printf(" removeable");
271 if (lp->d_flags & D_ECC)
272 printf(" ecc");
273 if (lp->d_flags & D_BADSECT)
274 printf(" badsect");
275 printf("\n");
276 printf("bytes/sector: %d\n", lp->d_secsize);
277 printf("sectors/track: %d\n", lp->d_nsectors);
278 printf("tracks/cylinder: %d\n", lp->d_ntracks);
279 printf("sectors/cylinder: %d\n", lp->d_secpercyl);
280 printf("cylinders: %d\n", lp->d_ncylinders);
281 printf("rpm: %d\n", lp->d_rpm);
282 printf("interleave: %d\n", lp->d_interleave);
283 printf("trackskew: %d\n", lp->d_trackskew);
284 printf("cylinderskew: %d\n", lp->d_cylskew);
285 printf("headswitch: %d\t\t# milliseconds\n", lp->d_headswitch);
286 printf("track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek);
287 printf("drivedata: ");
288 for (i = NDDATA - 1; i >= 0; i--)
289 if (lp->d_drivedata[i])
290 break;
291 if (i < 0)
292 i = 0;
293 for (j = 0; j <= i; j++)
294 printf("%d ", lp->d_drivedata[j]);
295 printf("\n\n%d partitions:\n", lp->d_npartitions);
296 printf("# size offset fstype [fsize bsize cpg]\n");
297 pp = lp->d_partitions;
298 for (i = 0; i < lp->d_npartitions; i++, pp++) {
299 if (pp->p_size) {
300 printf(" %c: %d %d ", 'a' + i,
301 pp->p_size, pp->p_offset);
302 if ((unsigned) pp->p_fstype < FSMAXTYPES)
303 printf("%s", fstypenames[pp->p_fstype]);
304 else
305 printf("%d", pp->p_fstype);
306 switch (pp->p_fstype) {
307
308 case FS_UNUSED: /* XXX */
309 printf(" %d %d %s ",
310 pp->p_fsize, pp->p_fsize * pp->p_frag, "");
311 break;
312
313 case FS_BSDFFS:
314 printf(" %d %d %d ",
315 pp->p_fsize, pp->p_fsize * pp->p_frag,
316 pp->p_cpg);
317 break;
318
319 default:
320 printf("%s", "");
321 break;
322 }
323 printf("\t# (Cyl. %d",
324 pp->p_offset / lp->d_secpercyl);
325 if (pp->p_offset % lp->d_secpercyl)
326 cnputc('*');
327 else
328 cnputc(' ');
329 printf("- %d",
330 (pp->p_offset +
331 pp->p_size + lp->d_secpercyl - 1) /
332 lp->d_secpercyl - 1);
333 if (pp->p_size % lp->d_secpercyl)
334 cnputc('*');
335 printf(")\n");
336 }
337 }
338 }
339