diff options
Diffstat (limited to 'usr.sbin/fdformat')
-rw-r--r-- | usr.sbin/fdformat/Makefile | 32 | ||||
-rw-r--r-- | usr.sbin/fdformat/fdformat.1 | 128 | ||||
-rw-r--r-- | usr.sbin/fdformat/fdformat.c | 346 |
3 files changed, 506 insertions, 0 deletions
diff --git a/usr.sbin/fdformat/Makefile b/usr.sbin/fdformat/Makefile new file mode 100644 index 000000000000..209af72d124d --- /dev/null +++ b/usr.sbin/fdformat/Makefile @@ -0,0 +1,32 @@ +# Copyright (C) 1993 by Joerg Wunsch, Dresden +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +PROG = fdformat + +# the -I's seem to be confusing, but necessery this way +# (so the right <unistd.h> will be found in /usr/include, and the +# "../i386/isa/ic/nec765.h" included from fdreg.h is accessible, too) +CFLAGS+=-Wall -I/usr/include -I/sys/sys + +.include <bsd.prog.mk> diff --git a/usr.sbin/fdformat/fdformat.1 b/usr.sbin/fdformat/fdformat.1 new file mode 100644 index 000000000000..fce0f7e9bac2 --- /dev/null +++ b/usr.sbin/fdformat/fdformat.1 @@ -0,0 +1,128 @@ +.\" Copyright (C) 1993 by Joerg Wunsch, Dresden +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd September 16, 1993 +.Os FreeBSD +.Dt FDFORMAT 1 +.Sh NAME +.Nm fdformat +.Nd format floppy disks +.Sh SYNOPSIS +.Nm fdformat +.Bq Fl q +.Bq Fl v +.Bq Fl n +.Bq Fl f Ar capacity +.Bq Fl c Ar cyls +.Bq Fl s Ar secs +.Bq Fl h Ar heads +.br +.Bq Fl r Ar rate +.Bq Fl g Ar gap3len +.Bq Fl i Ar intleave +.Bq Fl S Ar secshft +.Bq Fl F Ar fillbyte +.Bq Fl t Ar steps_per_track +.Ar device_name +.Sh DESCRIPTION +.Nm Fdformat +formats a floppy disk at device +.Ar device_name . +.Ar Device_name +should be a character device; it may be given either with a full path +name of a raw device node for a floppy disk drive +.Pq e.\ g. Pa /dev/rfd0 , +or default name in an abbreviated form +.Pq e.\ g. Em fd0 . +In the latter case, the name is constructed by prepending +.Pa /dev/r +and appending an +.Em .capacity +to the +.Ar device_name . +Note that any geometry constraints of the device node +.Pq minor device number +are meaningless, since they're overridden by +.Nm fdformat . +.Pp +The options are as follows: +.Bl -tag -width 10n -offset indent +.It Fl q +supress any normal output from the command, and don't ask the +user for a confirmation whether to format the floppy disk at +.Ar device_name . +.It Fl f Ar capacity +The normal way to specify the desired formatting parameters. +.Ar Capacity +is the number of kilobytes to format. +.It Fl n +Don't verify floppy after formatting. +.It Fl v +Don't format, verify only. +.It Fl c Ar cyls +.It Fl s Ar secs +.It Fl h Ar heads +.It Fl r Ar rate +.It Fl g Ar gap3len +.It Fl i Ar intleave +.It Fl S Ar secshft +.It Fl F Ar fillbyte +.It Fl t Ar steps_per_track +An alternate method to specify the geometry data to write to the floppy disk. +.El + +If the +.Fl q +flag has not been specified, the user is asked for a confirmation +of the intended formatting process. In order to continue, an answer +of +.Dq y +must be given. +.Sh DIAGNOSTICS +If no +.Fl q +has been specified, the current track +.Pq note: not cylinder +number is printed to standard output to inform the user about +the progress of work. +.Pp +An exit status of 0 is returned upon successful operation. Exit status +1 is returned on any errors during floppy formatting, and an exit status +of 2 reflects invalid arguments given to the program (along with an +appropriate information written to diagnostic output). +.Sh BUGS +The only valid interleave factor value is 1. +.Sh SEE ALSO +.Xr fd 4 . +.Sh HISTORY +.Nm Fdformat +has been developed for 386BSD +and upgraded to the new +.Xr fd 4 +floppy disk driver. +.Sh AUTHOR +The program has been contributed by +.if n Joerg Wunsch, +.if t J\(:org Wunsch, +Dresden with changes by Serge Vakulenko and Andrew A. Chernov, Moscow. diff --git a/usr.sbin/fdformat/fdformat.c b/usr.sbin/fdformat/fdformat.c new file mode 100644 index 000000000000..f29013d80ff3 --- /dev/null +++ b/usr.sbin/fdformat/fdformat.c @@ -0,0 +1,346 @@ +/* + * Copyright (C) 1992-1993 by Joerg Wunsch, Dresden + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * FreeBSD: + * format a floppy disk + * + * Added FD_GTYPE ioctl, verifying, proportional indicators. + * Serge Vakulenko, vak@zebub.msk.su + * Sat Dec 18 17:45:47 MSK 1993 + * + * Final adaptation, change format/verify logic, add separate + * format gap/interleave values + * Andrew A. Chernov, ache@astral.msk.su + * Thu Jan 27 00:47:24 MSK 1994 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <strings.h> +#include <ctype.h> + +#include <errno.h> +#include <machine/ioctl_fd.h> +#include <../i386/isa/fdreg.h> /* XXX should be in <machine> dir */ + +static void +format_track(int fd, int cyl, int secs, int head, int rate, + int gaplen, int secsize, int fill) +{ + struct fd_formb f; + register int i; + + f.format_version = FD_FORMAT_VERSION; + f.head = head; + f.cyl = cyl; + f.transfer_rate = rate; + + f.fd_formb_secshift = secsize; + f.fd_formb_nsecs = secs; + f.fd_formb_gaplen = gaplen; + f.fd_formb_fillbyte = fill; + for(i = 0; i < secs; i++) { + f.fd_formb_cylno(i) = cyl; + f.fd_formb_headno(i) = head; + f.fd_formb_secno(i) = i + 1; + f.fd_formb_secsize(i) = secsize; + } + if(ioctl(fd, FD_FORM, (caddr_t)&f) < 0) { + perror("\nfdformat: ioctl(FD_FORM)"); + exit(1); + } +} + +static int +verify_track(int fd, int track, int tracksize) +{ + static char *buf = 0; + static int bufsz = 0; + + if (bufsz < tracksize) { + if (buf) + free (buf); + bufsz = tracksize; + buf = 0; + } + if (! buf) + buf = malloc (bufsz); + if (! buf) { + fprintf (stderr, "\nfdformat: out of memory\n"); + exit (2); + } + if (lseek (fd, (long) track*tracksize, 0) < 0) + return (-1); + if (read (fd, buf, tracksize) != tracksize) + return (-1); + return (0); +} + +static const char * +makename(const char *arg, const char *suffix) +{ + static char namebuff[20]; /* big enough for "/dev/rfd0a"... */ + + memset(namebuff, 0, 20); + if(*arg == '\0') /* ??? */ + return arg; + if(*arg == '/') /* do not convert absolute pathnames */ + return arg; + strcpy(namebuff, "/dev/r"); + strncat(namebuff, arg, 3); + strcat(namebuff, suffix); + return namebuff; +} + +static void +usage () +{ + printf("Usage:\n\tfdformat [-q] [-n | -v] [-f #] [-c #] [-s #] [-h #]\n"); + printf("\t\t [-r #] [-g #] [-i #] [-S #] [-F #] [-t #] devname\n"); + printf("Options:\n"); + printf("\t-q\tsupress any normal output, don't ask for confirmation\n"); + printf("\t-n\tdon't verify floppy after formatting\n"); + printf("\t-v\tdon't format, verify only\n"); + printf("\t-f #\tspecify desired floppy capacity, in kilobytes;\n"); + printf("\t\tvalid choices are 360, 720, 800, 820, 1200, 1440, 1480, 1720\n"); + printf("\tdevname\tthe full name of floppy device or in short form fd0, fd1\n"); + printf("Obscure options:\n"); + printf("\t-c #\tspecify number of cylinders, 40 or 80\n"); + printf("\t-s #\tspecify number of sectors per track, 9, 10, 15 or 18\n"); + printf("\t-h #\tspecify number of floppy heads, 1 or 2\n"); + printf("\t-r #\tspecify data rate, 250, 300 or 500 kbps\n"); + printf("\t-g #\tspecify gap length\n"); + printf("\t-i #\tspecify interleave factor\n"); + printf("\t-S #\tspecify sector size, 0=128, 1=256, 2=512 bytes\n"); + printf("\t-F #\tspecify fill byte\n"); + printf("\t-t #\tnumber of steps per track\n"); + exit(2); +} + +static int +yes () +{ + char reply [256], *p; + + reply[sizeof(reply)-1] = 0; + for (;;) { + fflush(stdout); + if (! fgets (reply, sizeof(reply)-1, stdin)) + return (0); + for (p=reply; *p==' ' || *p=='\t'; ++p) + continue; + if (*p=='y' || *p=='Y') + return (1); + if (*p=='n' || *p=='N' || *p=='\n' || *p=='\r') + return (0); + printf("Answer `yes' or `no': "); + } +} + +int +main(int argc, char **argv) +{ + int format = -1, cyls = -1, secs = -1, heads = -1, intleave = -1; + int rate = -1, gaplen = -1, secsize = -1, steps = -1; + int fill = 0xf6, quiet = 0, verify = 1, verify_only = 0; + int fd, c, track, error, tracks_per_dot, bytes_per_track, errs; + const char *devname, *suffix; + struct fd_type fdt; + + while((c = getopt(argc, argv, "f:c:s:h:r:g:S:F:t:i:qvn")) != -1) + switch(c) { + case 'f': /* format in kilobytes */ + format = atoi(optarg); + break; + + case 'c': /* # of cyls */ + cyls = atoi(optarg); + break; + + case 's': /* # of secs per track */ + secs = atoi(optarg); + break; + + case 'h': /* # of heads */ + heads = atoi(optarg); + break; + + case 'r': /* transfer rate, kilobyte/sec */ + rate = atoi(optarg); + break; + + case 'g': /* length of GAP3 to format with */ + gaplen = atoi(optarg); + break; + + case 'S': /* sector size shift factor (1 << S)*128 */ + secsize = atoi(optarg); + break; + + case 'F': /* fill byte, C-like notation allowed */ + fill = (int)strtol(optarg, (char **)0, 0); + break; + + case 't': /* steps per track */ + steps = atoi(optarg); + break; + + case 'i': /* interleave factor */ + intleave = atoi(optarg); + break; + + case 'q': + quiet = 1; + break; + + case 'n': + verify = 0; + break; + + case 'v': + verify = 1; + verify_only = 1; + break; + + case '?': default: + usage(); + } + + if(optind != argc - 1) + usage(); + + switch(format) { + default: + fprintf(stderr, "fdformat: bad floppy size: %dK\n", format); + exit(2); + case -1: suffix = ""; break; + case 360: suffix = ".360"; break; + case 720: suffix = ".720"; break; + case 800: suffix = ".800"; break; + case 820: suffix = ".820"; break; + case 1200: suffix = ".1200"; break; + case 1440: suffix = ".1440"; break; + case 1480: suffix = ".1480"; break; + case 1720: suffix = ".1720"; break; + } + + devname = makename(argv[optind], suffix); + + if((fd = open(devname, O_RDWR)) < 0) { + perror(devname); + exit(1); + } + + if(ioctl(fd, FD_GTYPE, &fdt) < 0) { + fprintf(stderr, "fdformat: not a floppy disk: %s\n", devname); + exit(1); + } + + switch(rate) { + case -1: break; + case 250: fdt.trans = FDC_250KBPS; break; + case 300: fdt.trans = FDC_300KBPS; break; + case 500: fdt.trans = FDC_500KBPS; break; + default: + fprintf(stderr, "fdformat: invalid transfer rate: %d\n", rate); + exit(2); + } + + if (cyls >= 0) fdt.tracks = cyls; + if (secs >= 0) fdt.sectrac = secs; + if (heads >= 0) fdt.heads = heads; + if (gaplen >= 0) fdt.f_gap = gaplen; + if (secsize >= 0) fdt.secsize = secsize; + if (steps >= 0) fdt.steptrac = steps; + if (intleave >= 0) fdt.f_inter = intleave; + if (fdt.f_inter != 1) { + fprintf(stderr, "fdformat: can't format with interleave != 1 yet\n"); + exit(2); + } + + bytes_per_track = fdt.sectrac * (1<<fdt.secsize) * 128; + tracks_per_dot = fdt.tracks * fdt.heads / 40; + + if (verify_only) { + if(!quiet) + printf("Verify %dK floppy `%s'.\n", + fdt.tracks * fdt.heads * bytes_per_track / 1024, + devname); + } + else if(!quiet) { + printf("Format %dK floppy `%s'? (y/n): ", + fdt.tracks * fdt.heads * bytes_per_track / 1024, + devname); + if(! yes ()) { + printf("Not confirmed.\n"); + return 0; + } + } + + /* + * Formatting. + */ + if(!quiet) { + printf("Processing ----------------------------------------\r"); + printf("Processing "); + fflush(stdout); + } + + error = errs = 0; + + for (track = 0; track < fdt.tracks * fdt.heads; track++) { + if (!verify_only) { + format_track(fd, track / 2, fdt.sectrac, track & 1, + fdt.trans, fdt.f_gap, fdt.secsize, fill); + if(!quiet && !((track + 1) % tracks_per_dot)) { + putchar('F'); + fflush(stdout); + } + } + if (verify) { + if (verify_track(fd, track, bytes_per_track) < 0) + error = errs = 1; + if(!quiet && !((track + 1) % tracks_per_dot)) { + if (!verify_only) + putchar('\b'); + if (error) { + putchar('E'); + error = 0; + } + else + putchar('V'); + fflush(stdout); + } + } + } + if(!quiet) + printf(" done.\n"); + + return errs; +} |