1/* $NetBSD: disklabel.c,v 1.9 2015/02/14 06:16:29 tsutsui Exp $ */ 2 3/* 4 * Copyright (c) 1992 OMRON Corporation. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * OMRON Corporation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)disklabel.c 8.1 (Berkeley) 6/10/93 38 */ 39/* 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * OMRON Corporation. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)disklabel.c 8.1 (Berkeley) 6/10/93 71 */ 72 73/* 74 * disklabel.c -- operate disklabel for BSD & OMRON 75 * by A.Fujita, FEB-17-1992 76 */ 77 78#include <sys/param.h> 79#define DKTYPENAMES 80#define FSTYPENAMES 81#include <sys/disklabel.h> 82#include <ufs/ffs/fs.h> 83#include <lib/libkern/libkern.h> 84#include <luna68k/stand/boot/samachdep.h> 85#include <luna68k/stand/boot/status.h> 86#include <luna68k/stand/boot/omron_disklabel.h> 87 88static void display(struct disklabel *); 89 90#define SBSIZE SBLOCKSIZE 91#define FS_MAGIC FS_UFS1_MAGIC 92#define LABEL_SIZE BBSIZE 93 94uint8_t lbl_buff[LABEL_SIZE]; 95 96#if 0 97uint16_t 98dkcksum(struct disklabel *lp) 99{ 100 uint16_t *start, *end; 101 uint16_t sum = 0; 102 103 start = (uint16_t *)lp; 104 end = (uint16_t *)&lp->d_partitions[lp->d_npartitions]; 105 while (start < end) 106 sum ^= *start++; 107 return sum; 108} 109#endif 110 111int 112disklabel(int argc, char *argv[]) 113{ 114 struct scd_dk_label *omp = (struct scd_dk_label *)lbl_buff; 115 struct disklabel *bp = (struct disklabel *)&lbl_buff[LABELOFFSET]; 116 struct fs *fp = (struct fs *)lbl_buff; 117 uint16_t *p; 118 u_long chksum, count; 119 char *q; 120 int i, j; 121 122 if (argc < 2) { 123 printf("This command is required sub command !!\n"); 124 return ST_ERROR; 125 } 126 127 if (!strcmp(argv[1], "help")) { 128 printf("Subcommand of disklabel\n\n"); 129 printf("\thelp:\t\tthis command\n"); 130 printf("\tread:\t\tread disklabel from scsi_device\n"); 131 printf("\twrite:\t\twrite disklabel to scsi_device\n"); 132 printf("\tomron:\t\tshow OMRON disklabel information\n"); 133 printf("\tbsd:\t\tshow BSD disklabel information\n"); 134 printf("\tcopy:\t\tcopy disklabel information from OMRON" 135 " to BSD\n"); 136 printf("\tchecksum:\tdoing checksum\n"); 137 printf("\tset:\t\tchange BSD disklabel information\n"); 138 printf("\n\n"); 139 } else if (!strcmp(argv[1], "read")) { 140 if (scsi_read( 0, lbl_buff, LABEL_SIZE)) { 141 printf("Disk Label read done.\n"); 142 } else { 143 printf("Disk Label read error !!\n"); 144 } 145 } else if (!strcmp(argv[1], "omron")) { 146 i = (int)&omp->dkl_badchk; 147 i -= (int)lbl_buff; 148 printf("Offset = %d\n", i); 149 printf("\n"); 150 printf("Checksum of Bad Track:\t0x%x\n", 151 omp->dkl_badchk); 152 printf("Logical Block Total:\t%u(0x%x)\n", 153 omp->dkl_maxblk, omp->dkl_maxblk); 154 printf("Disk Drive Type:\t0x%x\n", 155 omp->dkl_dtype); 156 printf("Number of Disk Drives:\t%d(0x%x)\n", 157 omp->dkl_ndisk, omp->dkl_ndisk); 158 printf("Number of Data Cylinders:\t%d(0x%x)\n", 159 omp->dkl_ncyl, omp->dkl_ncyl); 160 printf("Number of Alternate Cylinders:\t%d(0x%x)\n", 161 omp->dkl_acyl,omp->dkl_acyl); 162 printf("Number of Heads in This Partition:\t%d(0x%x)\n", 163 omp->dkl_nhead, omp->dkl_nhead); 164 printf("Number of 512 byte Sectors per Track:\t%d(0x%x)\n", 165 omp->dkl_nsect, omp->dkl_nsect); 166 printf("Identifies Proper Label Locations:\t0x%x\n", 167 omp->dkl_bhead); 168 printf("Physical Partition Number:\t%d(0x%x)\n", 169 omp->dkl_ppart, omp->dkl_ppart); 170 for (i = 0; i < NLPART; i++) 171 printf("\t%d:\t%d\t%d\n", i, 172 omp->dkl_map[i].dkl_blkno, 173 omp->dkl_map[i].dkl_nblk); 174 printf("Identifies This Label Format:\t0x%x\n", 175 omp->dkl_magic); 176 printf("XOR Checksum of Sector:\t0x%x\n", 177 omp->dkl_cksum); 178 } else if (!strcmp(argv[1], "checksum")) { 179 if (omp->dkl_magic == DKL_MAGIC){ 180 /* checksum of disk-label */ 181 chksum = 0; 182 count = sizeof(struct scd_dk_label) / sizeof(short int); 183 for (p= (uint16_t *)lbl_buff; count > 0; count--) { 184 if (count == 1) 185 printf("Check Sum: 0x%lx\n", chksum); 186 chksum ^= *p++; 187 } 188 189 printf("dkl_cksum: 0x%x\n", omp->dkl_cksum); 190 191 if (chksum != 0) { 192 printf("OMRON Disklabel check sum error.\n"); 193 } 194 } else { 195 printf("OMRON Disklabel not found.\n"); 196 } 197 } else if (!strcmp(argv[1], "copy")) { 198 memset(bp, 0, sizeof(struct disklabel)); 199 200 memcpy(bp->d_typename, lbl_buff, 16); 201 202 bp->d_secsize = DEV_BSIZE; 203 bp->d_nsectors = 38; 204 bp->d_ntracks = 12; 205 bp->d_ncylinders = 1076; 206 207 bp->d_type = DKTYPE_SCSI; 208 209 bp->d_secpercyl = bp->d_nsectors * bp->d_ntracks; 210 bp->d_secperunit = bp->d_secpercyl * bp->d_ncylinders; 211 bp->d_rpm = 3600; 212 bp->d_interleave = 1; 213 bp->d_trackskew = 0; 214 bp->d_cylskew = 0; 215 bp->d_headswitch = 0; 216 bp->d_trkseek = 0; 217 bp->d_bbsize = BBSIZE; 218 bp->d_sbsize = SBSIZE; 219 220 for (i = 0; i < MAXPARTITIONS; i++) { 221 bp->d_partitions[i].p_size = 222 omp->dkl_map[i].dkl_nblk; 223 bp->d_partitions[i].p_offset = 224 omp->dkl_map[i].dkl_blkno; 225 bp->d_partitions[i].p_fsize = 1024; 226 bp->d_partitions[i].p_frag = 8192 / 1024; 227 bp->d_partitions[i].p_fstype = FS_UNUSED; 228 } 229 230 bp->d_npartitions = MAXPARTITIONS; 231 232 for (i = 0; i < NDDATA; i++) { 233 bp->d_drivedata[i] = 0; 234 } 235 236 memset(bp->d_packname, 0, 16); 237 238 bp->d_magic = DISKMAGIC; 239 bp->d_magic2 = DISKMAGIC; 240 bp->d_checksum = 0; 241 bp->d_checksum = dkcksum(bp); 242 243 /* restump checksum of OMRON disklabel */ 244 chksum = 0; 245 count = sizeof(struct scd_dk_label) / sizeof(short int); 246 for (p= (uint16_t *)lbl_buff; count > 1; count--) { 247 chksum ^= *p++; 248 } 249 printf("chksum: 0x%lx\n", chksum); 250 251 omp->dkl_cksum = chksum; 252 printf("dkl_cksum: 0x%x\n", omp->dkl_cksum); 253 } else if (!strcmp(argv[1], "bsd")) { 254 display(bp); 255 } else if (!strcmp(argv[1], "write")) { 256 if (scsi_write( 0, lbl_buff, LABEL_SIZE)) { 257 printf("Disk Label write done.\n"); 258 } else { 259 printf("Disk Label write error !!\n"); 260 } 261 } else if (!strcmp(argv[1], "set")) { 262 i = (argv[2])[1] - 'a'; 263 for (q = argv[3], j = 0; *q != '\0'; q++) { 264 j = (j * 10) + (*q - '0'); 265 } 266 switch (*argv[2]) { 267 case 'b': 268 bp->d_partitions[i].p_frag = 269 j / bp->d_partitions[i].p_fsize; 270 break; 271 case 'f': /* fragment size */ 272 bp->d_partitions[i].p_fsize = j; 273 break; 274 case 'o': /* offset */ 275 bp->d_partitions[i].p_offset = j; 276 omp->dkl_map[i].dkl_blkno = j; 277 break; 278 case 'p': /* size */ 279 bp->d_partitions[i].p_size = j; 280 omp->dkl_map[i].dkl_nblk = j; 281 break; 282 case 't': /* FS type */ 283 bp->d_partitions[i].p_fstype = j; 284 break; 285 default: 286 break; 287 } 288 289 /* restump checksum of BSD disklabel */ 290 bp->d_checksum = 0; 291 bp->d_checksum = dkcksum(bp); 292 293 /* restump checksum of OMRON disklabel */ 294 chksum = 0; 295 count = sizeof(struct scd_dk_label) / sizeof(short int); 296 for (p = (uint16_t *)lbl_buff; count > 1; count--) { 297 chksum ^= *p++; 298 } 299 omp->dkl_cksum = chksum; 300 301 } else if (!strcmp(argv[1], "sb")) { 302#define BLOCK_SIZE SBSIZE 303 304 printf("checking Super Block: block size = %d bytes," 305 " seek amount = 1 blocks\n", BLOCK_SIZE); 306 i = j = 0; 307 for (;;) { 308 if (scsi_read(i, lbl_buff, BLOCK_SIZE) == 0) 309 break; 310 311 if (fp->fs_magic == FS_MAGIC) { 312 printf("%d, (%d)\n", i, i - j); 313 j = i; 314 } 315 i++; 316 } 317 } else if (!strcmp(argv[1], "sbcopy")) { 318 if (scsi_read(32, lbl_buff, BLOCK_SIZE) == 0) { 319 printf("sbcopy: read failed\n"); 320 return ST_ERROR; 321 } 322 if (scsi_write(16, lbl_buff, BLOCK_SIZE) != 0) { 323 printf("sbcopy: copy done\n"); 324 } else { 325 printf("sbcopy: write failed\n"); 326 } 327 } 328 329 return ST_NORMAL; 330} 331 332static void 333display(struct disklabel *lp) 334{ 335 int i, j; 336 struct partition *pp; 337 338 if ((unsigned) lp->d_type < DKMAXTYPES) 339 printf("type: %s\n", dktypenames[lp->d_type]); 340 else 341 printf("type: %d\n", lp->d_type); 342 printf("disk: %s\n", lp->d_typename); 343 printf("label: %s\n", lp->d_packname); 344 printf("flags:"); 345 if (lp->d_flags & D_REMOVABLE) 346 printf(" removeable"); 347 if (lp->d_flags & D_ECC) 348 printf(" ecc"); 349 if (lp->d_flags & D_BADSECT) 350 printf(" badsect"); 351 printf("\n"); 352 printf("bytes/sector: %d\n", lp->d_secsize); 353 printf("sectors/track: %d\n", lp->d_nsectors); 354 printf("tracks/cylinder: %d\n", lp->d_ntracks); 355 printf("sectors/cylinder: %d\n", lp->d_secpercyl); 356 printf("cylinders: %d\n", lp->d_ncylinders); 357 printf("rpm: %d\n", lp->d_rpm); 358 printf("interleave: %d\n", lp->d_interleave); 359 printf("trackskew: %d\n", lp->d_trackskew); 360 printf("cylinderskew: %d\n", lp->d_cylskew); 361 printf("headswitch: %d\t\t# milliseconds\n", lp->d_headswitch); 362 printf("track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek); 363 printf("drivedata: "); 364 for (i = NDDATA - 1; i >= 0; i--) 365 if (lp->d_drivedata[i]) 366 break; 367 if (i < 0) 368 i = 0; 369 for (j = 0; j <= i; j++) 370 printf("%d ", lp->d_drivedata[j]); 371 printf("\n\n%d partitions:\n", lp->d_npartitions); 372 printf("# size offset fstype [fsize bsize cpg]\n"); 373 pp = lp->d_partitions; 374 for (i = 0; i < lp->d_npartitions; i++, pp++) { 375 if (pp->p_size) { 376 printf(" %c: %d %d ", 'a' + i, 377 pp->p_size, pp->p_offset); 378 if ((unsigned) pp->p_fstype < FSMAXTYPES) 379 printf("%s", fstypenames[pp->p_fstype]); 380 else 381 printf("%d", pp->p_fstype); 382 switch (pp->p_fstype) { 383 384 case FS_UNUSED: /* XXX */ 385 printf(" %d %d %s ", 386 pp->p_fsize, pp->p_fsize * pp->p_frag, ""); 387 break; 388 389 case FS_BSDFFS: 390 printf(" %d %d %d ", 391 pp->p_fsize, pp->p_fsize * pp->p_frag, 392 pp->p_cpg); 393 break; 394 395 default: 396 printf("%s", ""); 397 break; 398 } 399 printf("\t# (Cyl. %d", 400 pp->p_offset / lp->d_secpercyl); 401 if (pp->p_offset % lp->d_secpercyl) 402 putchar('*'); 403 else 404 putchar(' '); 405 printf("- %d", 406 (pp->p_offset + 407 pp->p_size + lp->d_secpercyl - 1) / 408 lp->d_secpercyl - 1); 409 if (pp->p_size % lp->d_secpercyl) 410 putchar('*'); 411 printf(")\n"); 412 } 413 } 414} 415