1*4c3cdcf0Schristos /* $NetBSD: newdisk.c,v 1.11 2014/03/26 08:17:59 christos Exp $ */
2e958dce7Sisaki
37330ce45Sminoura /*-
47330ce45Sminoura * Copyright (c) 1999 Minoura Makoto
57330ce45Sminoura * All rights reserved.
67330ce45Sminoura *
77330ce45Sminoura * Redistribution and use in source and binary forms, with or without
87330ce45Sminoura * modification, are permitted provided that the following conditions
97330ce45Sminoura * are met:
107330ce45Sminoura * 1. Redistributions of source code must retain the above copyright
117330ce45Sminoura * notice, this list of conditions and the following disclaimer.
127330ce45Sminoura * 2. Redistributions in binary form must reproduce the above copyright
137330ce45Sminoura * notice, this list of conditions and the following disclaimer in the
147330ce45Sminoura * documentation and/or other materials provided with the distribution.
157330ce45Sminoura *
167330ce45Sminoura * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
177330ce45Sminoura * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
187330ce45Sminoura * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
197330ce45Sminoura * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
207330ce45Sminoura * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
217330ce45Sminoura * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
227330ce45Sminoura * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
237330ce45Sminoura * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
247330ce45Sminoura * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
257330ce45Sminoura * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
267330ce45Sminoura */
277330ce45Sminoura
287330ce45Sminoura /*
297330ce45Sminoura * Create the disk mark for x68k SCSI IPL.
307330ce45Sminoura * It used to be a shell/awk script, but is rewritten in order to be fit with
317330ce45Sminoura * the install kernel.
327330ce45Sminoura *
337330ce45Sminoura * Usage: /usr/mdec/newdisk [-vnfc] [-m /usr/mdec/mboot] /dev/rsd?c
347330ce45Sminoura */
357330ce45Sminoura
367330ce45Sminoura #include <stdio.h>
377330ce45Sminoura #include <stdlib.h>
387330ce45Sminoura #include <string.h>
3917739fceStsutsui #include <err.h>
407330ce45Sminoura #include <fcntl.h>
417330ce45Sminoura #include <unistd.h>
427330ce45Sminoura #include <util.h>
437330ce45Sminoura #include <sys/param.h>
447330ce45Sminoura #include <sys/disklabel.h>
457330ce45Sminoura #include <sys/dkio.h>
4617739fceStsutsui #include <sys/ioctl.h>
477330ce45Sminoura
4817739fceStsutsui const char *mboot = MBOOT;
497330ce45Sminoura char dev[MAXPATHLEN];
507330ce45Sminoura char buf[4096 + 1];
517330ce45Sminoura
523e9a8268Sminoura const char copyright[] = "NetBSD/x68k SCSI Primary Boot. ";
537330ce45Sminoura
543e9a8268Sminoura int verbose = 0, dry_run = 0, force = 0, check_only = 0, mark_only = 0;
557330ce45Sminoura
5602cdf4d2Sdsl void usage(void) __attribute__((__noreturn__));
5702cdf4d2Sdsl int main(int, char *[]);
587330ce45Sminoura
591b474f00Smhitch void
usage(void)607330ce45Sminoura usage(void)
617330ce45Sminoura {
627330ce45Sminoura fprintf(stderr,
637330ce45Sminoura "Usage: %s [-v] [-n] [-f] [-c] [-m /usr/mdec/mboot] "
64db48d129Sisaki "/dev/rsdXc\n", getprogname());
657330ce45Sminoura exit(1);
667330ce45Sminoura /* NOTREACHED */
677330ce45Sminoura }
687330ce45Sminoura
697330ce45Sminoura int
main(int argc,char * argv[])7082357f6dSdsl main(int argc, char *argv[])
717330ce45Sminoura {
727330ce45Sminoura int ch;
737330ce45Sminoura int fd;
747330ce45Sminoura struct disklabel label;
757330ce45Sminoura
763e9a8268Sminoura while ((ch = getopt(argc, argv, "vnfcm:p")) != -1) {
777330ce45Sminoura switch (ch) {
787330ce45Sminoura case 'v':
797330ce45Sminoura verbose = 1;
807330ce45Sminoura break;
817330ce45Sminoura case 'n':
827330ce45Sminoura dry_run = 1;
837330ce45Sminoura break;
847330ce45Sminoura case 'f':
857330ce45Sminoura force = 1;
867330ce45Sminoura break;
877330ce45Sminoura case 'c':
887330ce45Sminoura check_only = 1;
897330ce45Sminoura break;
907330ce45Sminoura case 'm':
917330ce45Sminoura mboot = optarg;
927330ce45Sminoura break;
933e9a8268Sminoura case 'p':
943e9a8268Sminoura mark_only = 1;
953e9a8268Sminoura break;
967330ce45Sminoura default:
977330ce45Sminoura usage();
987330ce45Sminoura }
997330ce45Sminoura }
1007330ce45Sminoura argc -= optind;
1017330ce45Sminoura argv += optind;
1027330ce45Sminoura
1037330ce45Sminoura if (argc != 1)
1047330ce45Sminoura usage();
1057330ce45Sminoura
1067330ce45Sminoura fd = opendisk(argv[0], O_RDONLY, dev, MAXPATHLEN, 0);
1077330ce45Sminoura if (fd < 0)
1087330ce45Sminoura err(1, "opening %s", dev);
1097330ce45Sminoura if (access(mboot, R_OK) < 0)
1107330ce45Sminoura err(1, "checking %s", mboot);
1117330ce45Sminoura
1127330ce45Sminoura if (read(fd, buf, 512) < 0)
1137330ce45Sminoura err(1, "reading %s", dev);
114e958dce7Sisaki if (strncmp(buf, "X68SCSI1", 8) == 0 && !force)
115e958dce7Sisaki errx(1, "%s is already marked. "
1164dafb592Sisaki "Use -f to overwrite the existing mark.", dev);
1177330ce45Sminoura if (check_only)
1187330ce45Sminoura return 0;
1197330ce45Sminoura
1207330ce45Sminoura if (verbose)
1217330ce45Sminoura fprintf(stderr, "Inspecting %s... ", dev);
1227330ce45Sminoura
1237330ce45Sminoura if (ioctl(fd, DIOCGDINFO, &label) < 0)
1247330ce45Sminoura err(1, "inspecting %s", dev);
1257330ce45Sminoura close(fd);
1267330ce45Sminoura if (label.d_secsize != 512)
1277330ce45Sminoura errx(1, "This type of disk is not supported by NetBSD.");
1287330ce45Sminoura
1297330ce45Sminoura if (verbose)
130e958dce7Sisaki fprintf(stderr, "total number of sector is %d.\n",
131e958dce7Sisaki label.d_secperunit);
1327330ce45Sminoura
1337330ce45Sminoura if (verbose)
1347330ce45Sminoura fprintf(stderr, "Building disk mark... ");
1357330ce45Sminoura memset(buf, 0, 3072);
1367330ce45Sminoura #define n label.d_secperunit
137*4c3cdcf0Schristos snprintf(buf, sizeof(buf), "X68SCSI1%c%c%c%c%c%c%c%c%s",
1387330ce45Sminoura 2, 0,
1397330ce45Sminoura (n/16777216)%256, (n/65536)%256, (n/256)%256, n%256,
1407330ce45Sminoura 1, 0, copyright);
1417330ce45Sminoura #undef n
1427330ce45Sminoura if (verbose)
1437330ce45Sminoura fprintf(stderr, "done.\n");
1447330ce45Sminoura
1457330ce45Sminoura if (verbose)
1467330ce45Sminoura fprintf(stderr, "Merging %s... ", mboot);
1477330ce45Sminoura fd = open(mboot, O_RDONLY);
1487330ce45Sminoura if (fd < 0)
1497330ce45Sminoura err(1, "opening %s", mboot);
1507330ce45Sminoura if (read(fd, buf+1024, 1024) < 0)
1517330ce45Sminoura err(1, "reading %s", mboot);
1527330ce45Sminoura close(fd);
1537330ce45Sminoura if (verbose)
1547330ce45Sminoura fprintf(stderr, "done.\n");
1557330ce45Sminoura
1563e9a8268Sminoura if (!mark_only) {
1577330ce45Sminoura if (verbose)
158e958dce7Sisaki fprintf(stderr,
159e958dce7Sisaki "Creating an empty partition table... ");
1607330ce45Sminoura #define n (label.d_secperunit/2)
161*4c3cdcf0Schristos snprintf(buf + 2048, sizeof(buf) - 2048,
1627330ce45Sminoura "X68K%c%c%c%c%c%c%c%c%c%c%c%c",
1637330ce45Sminoura 0, 0, 0, 32,
1647330ce45Sminoura (n/16777215)%256, (n/65536)%256, (n/256)%256, n%256,
1657330ce45Sminoura (n/16777215)%256, (n/65536)%256, (n/256)%256, n%256);
1667330ce45Sminoura #undef n
1677330ce45Sminoura if (verbose)
1687330ce45Sminoura fprintf(stderr, "done.\n");
1693e9a8268Sminoura }
1707330ce45Sminoura
1717330ce45Sminoura if (dry_run) {
1727330ce45Sminoura char filename[MAXPATHLEN] = "/tmp/diskmarkXXXXX";
1737330ce45Sminoura fd = mkstemp(filename);
1747330ce45Sminoura if (fd < 0)
1757330ce45Sminoura err(1, "opening %s", filename);
1767330ce45Sminoura if (write(fd, buf, 4096) < 0)
1777330ce45Sminoura err(1, "writing %s", filename);
1787330ce45Sminoura close(fd);
1797330ce45Sminoura fprintf(stderr, "Disk mark is kept in %s.\n", filename);
1807330ce45Sminoura } else {
1817330ce45Sminoura int mode = 1;
1827330ce45Sminoura
1837330ce45Sminoura if (verbose)
1847330ce45Sminoura fprintf(stderr, "Writing... ");
1857330ce45Sminoura fd = open(dev, O_WRONLY);
1867330ce45Sminoura if (fd < 0)
1877330ce45Sminoura err(1, "opening %s", dev);
1887330ce45Sminoura if (ioctl(fd, DIOCWLABEL, (char *)&mode) < 0)
1897330ce45Sminoura err(1, "DIOCWLABEL %s", dev);
1907330ce45Sminoura if (write(fd, buf, 4096) != 4096) {
1917330ce45Sminoura mode = 0;
1927330ce45Sminoura ioctl(fd, DIOCWLABEL, (char *)&mode);
1937330ce45Sminoura err(1, "DIOCWLABEL %s", dev);
1947330ce45Sminoura }
1957330ce45Sminoura ioctl(fd, DIOCWLABEL, (char *)&mode);
1967330ce45Sminoura if (verbose)
1977330ce45Sminoura fprintf(stderr, "done.\n");
1987330ce45Sminoura close(fd);
1997330ce45Sminoura }
2007330ce45Sminoura
2017330ce45Sminoura return 0;
2027330ce45Sminoura }
203