1 1.11 christos /* $NetBSD: newdisk.c,v 1.11 2014/03/26 08:17:59 christos Exp $ */ 2 1.6 isaki 3 1.1 minoura /*- 4 1.1 minoura * Copyright (c) 1999 Minoura Makoto 5 1.1 minoura * All rights reserved. 6 1.1 minoura * 7 1.1 minoura * Redistribution and use in source and binary forms, with or without 8 1.1 minoura * modification, are permitted provided that the following conditions 9 1.1 minoura * are met: 10 1.1 minoura * 1. Redistributions of source code must retain the above copyright 11 1.1 minoura * notice, this list of conditions and the following disclaimer. 12 1.1 minoura * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 minoura * notice, this list of conditions and the following disclaimer in the 14 1.1 minoura * documentation and/or other materials provided with the distribution. 15 1.1 minoura * 16 1.1 minoura * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 minoura * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 minoura * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 minoura * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 minoura * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 minoura * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 minoura * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 minoura * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 minoura * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 minoura * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 minoura */ 27 1.1 minoura 28 1.1 minoura /* 29 1.1 minoura * Create the disk mark for x68k SCSI IPL. 30 1.1 minoura * It used to be a shell/awk script, but is rewritten in order to be fit with 31 1.1 minoura * the install kernel. 32 1.1 minoura * 33 1.1 minoura * Usage: /usr/mdec/newdisk [-vnfc] [-m /usr/mdec/mboot] /dev/rsd?c 34 1.1 minoura */ 35 1.1 minoura 36 1.1 minoura #include <stdio.h> 37 1.1 minoura #include <stdlib.h> 38 1.1 minoura #include <string.h> 39 1.9 tsutsui #include <err.h> 40 1.1 minoura #include <fcntl.h> 41 1.1 minoura #include <unistd.h> 42 1.1 minoura #include <util.h> 43 1.1 minoura #include <sys/param.h> 44 1.1 minoura #include <sys/disklabel.h> 45 1.1 minoura #include <sys/dkio.h> 46 1.9 tsutsui #include <sys/ioctl.h> 47 1.1 minoura 48 1.9 tsutsui const char *mboot = MBOOT; 49 1.1 minoura char dev[MAXPATHLEN]; 50 1.1 minoura char buf[4096 + 1]; 51 1.1 minoura 52 1.2 minoura const char copyright[] = "NetBSD/x68k SCSI Primary Boot. "; 53 1.1 minoura 54 1.2 minoura int verbose = 0, dry_run = 0, force = 0, check_only = 0, mark_only = 0; 55 1.1 minoura 56 1.4 dsl void usage(void) __attribute__((__noreturn__)); 57 1.4 dsl int main(int, char *[]); 58 1.1 minoura 59 1.3 mhitch void 60 1.1 minoura usage(void) 61 1.1 minoura { 62 1.6 isaki fprintf(stderr, 63 1.6 isaki "Usage: %s [-v] [-n] [-f] [-c] [-m /usr/mdec/mboot] " 64 1.7 isaki "/dev/rsdXc\n", getprogname()); 65 1.6 isaki exit(1); 66 1.6 isaki /* NOTREACHED */ 67 1.1 minoura } 68 1.1 minoura 69 1.1 minoura int 70 1.5 dsl main(int argc, char *argv[]) 71 1.1 minoura { 72 1.6 isaki int ch; 73 1.6 isaki int fd; 74 1.6 isaki struct disklabel label; 75 1.6 isaki 76 1.6 isaki while ((ch = getopt(argc, argv, "vnfcm:p")) != -1) { 77 1.6 isaki switch (ch) { 78 1.6 isaki case 'v': 79 1.6 isaki verbose = 1; 80 1.6 isaki break; 81 1.6 isaki case 'n': 82 1.6 isaki dry_run = 1; 83 1.6 isaki break; 84 1.6 isaki case 'f': 85 1.6 isaki force = 1; 86 1.6 isaki break; 87 1.6 isaki case 'c': 88 1.6 isaki check_only = 1; 89 1.6 isaki break; 90 1.6 isaki case 'm': 91 1.6 isaki mboot = optarg; 92 1.6 isaki break; 93 1.6 isaki case 'p': 94 1.6 isaki mark_only = 1; 95 1.6 isaki break; 96 1.6 isaki default: 97 1.6 isaki usage(); 98 1.6 isaki } 99 1.1 minoura } 100 1.6 isaki argc -= optind; 101 1.6 isaki argv += optind; 102 1.6 isaki 103 1.6 isaki if (argc != 1) 104 1.6 isaki usage(); 105 1.6 isaki 106 1.6 isaki fd = opendisk(argv[0], O_RDONLY, dev, MAXPATHLEN, 0); 107 1.6 isaki if (fd < 0) 108 1.6 isaki err(1, "opening %s", dev); 109 1.6 isaki if (access(mboot, R_OK) < 0) 110 1.6 isaki err(1, "checking %s", mboot); 111 1.6 isaki 112 1.6 isaki if (read(fd, buf, 512) < 0) 113 1.6 isaki err(1, "reading %s", dev); 114 1.6 isaki if (strncmp(buf, "X68SCSI1", 8) == 0 && !force) 115 1.6 isaki errx(1, "%s is already marked. " 116 1.8 isaki "Use -f to overwrite the existing mark.", dev); 117 1.6 isaki if (check_only) 118 1.6 isaki return 0; 119 1.1 minoura 120 1.6 isaki if (verbose) 121 1.6 isaki fprintf(stderr, "Inspecting %s... ", dev); 122 1.1 minoura 123 1.6 isaki if (ioctl(fd, DIOCGDINFO, &label) < 0) 124 1.6 isaki err(1, "inspecting %s", dev); 125 1.6 isaki close(fd); 126 1.6 isaki if (label.d_secsize != 512) 127 1.6 isaki errx(1, "This type of disk is not supported by NetBSD."); 128 1.1 minoura 129 1.6 isaki if (verbose) 130 1.6 isaki fprintf(stderr, "total number of sector is %d.\n", 131 1.6 isaki label.d_secperunit); 132 1.1 minoura 133 1.2 minoura if (verbose) 134 1.6 isaki fprintf(stderr, "Building disk mark... "); 135 1.6 isaki memset(buf, 0, 3072); 136 1.6 isaki #define n label.d_secperunit 137 1.11 christos snprintf(buf, sizeof(buf), "X68SCSI1%c%c%c%c%c%c%c%c%s", 138 1.6 isaki 2, 0, 139 1.6 isaki (n/16777216)%256, (n/65536)%256, (n/256)%256, n%256, 140 1.6 isaki 1, 0, copyright); 141 1.1 minoura #undef n 142 1.2 minoura if (verbose) 143 1.6 isaki fprintf(stderr, "done.\n"); 144 1.1 minoura 145 1.6 isaki if (verbose) 146 1.6 isaki fprintf(stderr, "Merging %s... ", mboot); 147 1.6 isaki fd = open(mboot, O_RDONLY); 148 1.1 minoura if (fd < 0) 149 1.6 isaki err(1, "opening %s", mboot); 150 1.6 isaki if (read(fd, buf+1024, 1024) < 0) 151 1.6 isaki err(1, "reading %s", mboot); 152 1.1 minoura close(fd); 153 1.6 isaki if (verbose) 154 1.6 isaki fprintf(stderr, "done.\n"); 155 1.6 isaki 156 1.6 isaki if (!mark_only) { 157 1.6 isaki if (verbose) 158 1.6 isaki fprintf(stderr, 159 1.6 isaki "Creating an empty partition table... "); 160 1.6 isaki #define n (label.d_secperunit/2) 161 1.11 christos snprintf(buf + 2048, sizeof(buf) - 2048, 162 1.6 isaki "X68K%c%c%c%c%c%c%c%c%c%c%c%c", 163 1.6 isaki 0, 0, 0, 32, 164 1.6 isaki (n/16777215)%256, (n/65536)%256, (n/256)%256, n%256, 165 1.6 isaki (n/16777215)%256, (n/65536)%256, (n/256)%256, n%256); 166 1.6 isaki #undef n 167 1.6 isaki if (verbose) 168 1.6 isaki fprintf(stderr, "done.\n"); 169 1.6 isaki } 170 1.1 minoura 171 1.6 isaki if (dry_run) { 172 1.6 isaki char filename[MAXPATHLEN] = "/tmp/diskmarkXXXXX"; 173 1.6 isaki fd = mkstemp(filename); 174 1.6 isaki if (fd < 0) 175 1.6 isaki err(1, "opening %s", filename); 176 1.6 isaki if (write(fd, buf, 4096) < 0) 177 1.6 isaki err(1, "writing %s", filename); 178 1.6 isaki close(fd); 179 1.6 isaki fprintf(stderr, "Disk mark is kept in %s.\n", filename); 180 1.6 isaki } else { 181 1.6 isaki int mode = 1; 182 1.6 isaki 183 1.6 isaki if (verbose) 184 1.6 isaki fprintf(stderr, "Writing... "); 185 1.6 isaki fd = open(dev, O_WRONLY); 186 1.6 isaki if (fd < 0) 187 1.6 isaki err(1, "opening %s", dev); 188 1.6 isaki if (ioctl(fd, DIOCWLABEL, (char *)&mode) < 0) 189 1.6 isaki err(1, "DIOCWLABEL %s", dev); 190 1.6 isaki if (write(fd, buf, 4096) != 4096) { 191 1.6 isaki mode = 0; 192 1.6 isaki ioctl(fd, DIOCWLABEL, (char *)&mode); 193 1.6 isaki err(1, "DIOCWLABEL %s", dev); 194 1.6 isaki } 195 1.6 isaki ioctl(fd, DIOCWLABEL, (char *)&mode); 196 1.6 isaki if (verbose) 197 1.6 isaki fprintf(stderr, "done.\n"); 198 1.6 isaki close(fd); 199 1.1 minoura } 200 1.1 minoura 201 1.6 isaki return 0; 202 1.1 minoura } 203