xref: /original-bsd/sys/luna68k/stand/disklabel.c (revision eb9b57b3)
1 /*
2  * Copyright (c) 1992 OMRON Corporation.
3  * Copyright (c) 1992 The Regents of the University of California.
4  * 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	7.1 (Berkeley) 12/13/92
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
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
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
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