diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..900040b --- /dev/null +++ b/Changelog @@ -0,0 +1,10 @@ +970516 5.2 Released +970516 Fixed sunsite location in doc. +970430 Fixed typoes in doc about autodetection. +970428 Fixed manpage installation +970427 5.1 Released. These repeated complaints about yylineno not + defined start getting annoying ;-) +970426 More Makefile fixes. Added note to doc about Alpha site +970422 Various Makefile fixes +970421 Lex yylineno fixes +970419 5.0 Released diff --git a/FAQ b/FAQ deleted file mode 100644 index 80fef19..0000000 --- a/FAQ +++ /dev/null @@ -1,408 +0,0 @@ - FLOPPY FREQUENTLY ASKED QUESTIONS (Last updated on 29 April 1996) - ================================================================= - - This FAQ is regularly updated in the directory -ftp.imag.fr:pub/Linux/ZLIBC/floppy/FAQ. - You find alpha releases of fdutils in the directory -ftp.imag.fr:pub/Linux/ZLIBC/fdutils . They are named -fdu.taz or fdu4.2-.diff.gz - - Most of the floppy utilities mentioned in this FAQ can be found in -this package. For others, consult the lsm or archie. - - You may find ALPHA patches of the driver itself in -ftp.imag.fr:pub/Linux/ZLIBC/floppy/ALPHA. These patches are named -fdp-.diff.gz - - If after some testing these patches prove to be sufficiently stable, -they'll move into ftp.imag.fr:pub/Linux/ZLIBC/floppy/BETA. Minor -patches which don't affect existing functionality go directly to BETA. - - You may find quick&dirty fixes to the driver in -ftp.imag.fr:pub/Linux/ZLIBC/QDF. These patches are named -fdp-.diff - These patches fix only the most obvious problems, or introduce -trivial enhancements. The main objective is to keep these patches -small and local, in order to keep the probability of introducing new -problems as small as possible. However, they may not attack the root -of the problem but only cure the symptoms. This directory contains a -RELEASES file describing the features of these patches. - - The ALPHA, BETA and QDF directories are removed, and replaced by a -README file when they get empty due to integration of the patches into -the stock kernel. You may still find patches to old kernels in -ftp.imag.fr:pub/Linux/ZLIBC/obsolete - - -1. How do I access floppy drives in Linux? - - Either use mtools or mount the disk. Mtools can be found at: - - ftp.imag.fr:pub/Linux/ZLIBC/mtools/mtools-2.5.4.src.tar.gz - sunsite.unc.edu:/pub/Linux/system/utils/disk-management/mtools-2.5.4.src.tar.gz tsx-11.mit.edu:/pub/linux/sources/usr.bin/mtools-2.5.4.src.tar.gz - - It is a collection of utilities to access DOS disks. These utilities -behave mostly like their DOS counterparts, i.e. mdir is like dir, -mcopy is like copy, etc. Specifics are in the manpages - - To mount a disk on /mnt, use the following command lines: - mount -t msdos /dev/fd0 /mnt - - The directory /mnt must already exist: mkdir /mnt . - - -2. How should I report bugs? - - If you have a question or a bug report about the floppy driver, mail -me at Alain.Knaff@inrialpes.fr. If you post to the news, use -preferably one of the groups comp.os.linux.help (for questions) or -comp.os.linux.hardware (for bug reports). As the volume in these -groups is rather high, be sure to include the word "floppy" (or -"FLOPPY") in the subject line. - - a. In case of a kernel panic, or OOPS, please note the EIP, and the -values on the stack (some of these are the calling functions). Then -look up those values in your zSystem.map (or System.map) - b. In case of a lock-up (operation never completes), try to figure -out what operations are needed to reproduce it. (If you don't succeed -in reproducing it, please mention the floppy operations you remember.) - c. If you can't access a disk, include the output of -floppycontrol -pP --printfdcstate into your bug report. - d. If something weird happens during boot (lock-up, no floppy drives -accessible, trouble with unrelated hardware), include a listing of the -messages at boot. (You can obtain this with dmesg. If the boot doesn't -complete only note the most important messages down [few lines before -the crash, and floppy related lines]). - e. In case of I/O errors, first switch the error reporting threshold -to 0. If that doesn't yield any more error messages, switch on full -debugging with 'floppycontrol --debug' and 'floppycontrol --reporting -0'. Note that floppycontrol --debug generates a *huge* -output. Thus, try first with --reporting. - Please not also that both commands are drive specific, and that the -default drive is /dev/fd0. So, if you experience a problem on -/dev/fd1, use floppycontrol --debug -d/dev/fd1 . - Then include the kernel messages as well as the application messages -with your bug report. If you're using xwindows, you won't see the -kernel messages appear in your xterm window. Use dmesg to get -them. dmesg includes all messages since boot (or as many as fit in the -buffer, if there are too many messages). - Do also a dmesg before executing the command, in order to find out -which messages were triggered by the command. Alternatively, you may -get the printk module from -ftp.imag.fr:pub/Linux/ZLIBC/misc/printk.tgz. This module allows you to -insert "comments" into the stream of console messages. - f. Be aware that after a crash, no user program runs, not even -syslog. If you direct your kernel messages only to syslog, you may -see nothing at all in the log file after rebooting. Thus, I recommend -directing the messages also to the console, and noting them down. If -there are more than a few lines, note only the last few lines, and the -addresses of EIP and the stack trace, if applicable. Obviously, this -only applies when investigating bugs which lead to a crash. If no -crash happens (like for instance read errors), syslog is actually an -useful and beneficial feature, as it is able to keep far more messages -than fit into dmesg's buffer. - g. If you have other patches in the kernel, report them (especially -ftape). If it is easy enough to undo these other patches, please try -whether the problem happens without them. - h. Be sure to include _complete_ command lines of the floppy commands -which led to the problem, as well as a history of the disk changes. - i. Is the problem repeatable? - j. If you notice that the problem is very time dependent, try to find -out if there is any correlation between the occurrence of the problem, -and the state of the drive LED. - k. If the problem is that the drive becomes inaccessible, but -everything else just works fine, try to find out the following: - - Are all floppy drives inaccessible? - - Does the drive LED stay on? - - Does the drive make any noises? - - Do all floppy related commands fail, or only those that try to -actually read or write to the drive. In particular, what does -floppycontrol -P do? - l. Give some description of your computer! Is it a Laptop? A -particularly slow computer (386 SX)? PCI based? - - m. If you can't supply all these items, go ahead anyways, I want just -to make sure you aren't forgetting anything. - - -3. I can't fdformat the new formats. - - Fdformat is considered obsolete. Use superformat instead. - - -4. Mtools says "12 bit FAT on a: sure?" when trying to access an ED disk. -(or a similar message when formatting a disk) - - Some ED disks use 16 bit FATS. The FAT type (12 or 16 bit) is described -in the configuration file (/etc/mtools or ~/.mtoolsrc). It is the first -number. Example: -A /dev/fd0 12 0 0 0 - ^^ 12 bit FAT - 12 means 12 bit FAT - 16 means 16 bit FAT - 0 means "use whatever is appropriate" --12 means 12 bit FAT, even if it looks fishy --16 means 16 bit FAT, even if it looks fishy - - CAUTION: If you have an /etc/mtools file AND an ~/.mtoolsrc file, the -~/.mtoolsrc file overrides /etc/mtools. The home directory used for -~/.mtoolsrc is $HOME, if that is undefined, it is derived from -$LOGNAME, and if that's undefined too, it is derived from getlogin, -and finally from getuid. - There are also compiled-in defaults, which are used if neither -/etc/mtools, nor ~/.mtoolsrc are found. - - -5. Mtools says "fat_read: Wrong FAT encoding %d %d?\n" when accessing a -disk formatted with the old mtools. - - mtools does some sanity checks on the size of the -FAT. Unfortunately, these are too strict for certain disks formatted -with the old mtools, and for hard disk partitions formatted by DOS -6, and probably for other conditions as well. Define the environment -variable MTOOLS_FAT_COMPATIBILITY to override this check. -(to do this, type "setenv MTOOLS_FAT_COMPATIBILITY 1" in csh or tcsh, -and "export MTOOLS_FAT_COMPATIBILITY=1" in sh/bash/zsh/...) - - -7. How should I describe the new 2m formats in /etc/mtools? - - Support for both disk drives a: and b: for all formats (except Xdf) is -already built into the new version of mtools (2.5.4, and later -3.0). Definitions for new drive letters no longer override these -default definitions. - - Just for the record, here are definitions to mimic the standard -behavior: - drive a: file="/dev/fd0" - drive b: file="/dev/fd1" - - -8. How should I describe the Xdf formats in /etc/mtools? - - The following /etc/mtools lines allow to access all disks, including -Xdf: - drive a: file="/dev/fd0" use_xdf=1 - drive b: file="/dev/fd1" use_xdf=1 - - However, the use_xdf flag slightly slows down initial access to non -Xdf disks. - -9. Which minor device number should I use for 2m formats? - - 2m formats don't have a minor number associated with them, they can -only be accessed using the "generic format" devices (i.e. /dev/fd0, -/dev/fd1). - - -10. I have an IBM thinkpad :-( - - Don't panic. Add the line 'floppy=thinkpad' to your lilo boot -parameters. This can be entered at the lilo prompt after the name of -the kernel image. It can also be specified in the lilo.conf file, by -adding the following line: - append = "floppy=thinkpad" - - With some IBM thinkpads, it's also possible to make their floppy -drive work by toggling the "FLOPPY" option in CMOS from "auto" to -"on". However, apparently this CMOS option is not available on all -models. - - On some models, both options may be required, on others, none are -required. - - -11. Is it possible to compile the floppy driver as a module? - - The floppy driver can be compiled as a module with kernels more -recent than 1.3.4 - - -12. What are the minor device numbers for the floppy device nodes - - The major device number for the floppy drives is 2. The minor device -number is calculated using the following formula: - minor_device = format_nr * 4 + 128 * fdc_nr + unit_nr - (fdc_nr identifies the floppy disk controller, and unit_nr identifies -which drive on the floppy disk controller to be used) format_nr -identifies the format (see the README file in fdutils for more -details). If format_nr is 0, the device is an autodetection device. - Use the MAKEFLOPPIES script included in the fdutils package to -automatically create the needed devices. - - -13. What are the recommended names for the floppy device nodes - - Floppy drives are named fd - - Drive_nr identifies the drive. It ranges from 0 to 3 for drives -connected to the first controller, and from 4 to 7 for drives -connected to the second controller. - - Type is the type of the drive or media. The exact meaning of this -(drive or media) is still being discussed. Traditionally, this letter -described the type of the drive (density, 5 1/4 or 3 1/2). Lower case -letters described 5 1/4 drives, and upper case letters describe 3 1/2 -drives. h or H meant high density drives, d or D meant double density -drives. - Initially this letter described the type of the *drive* and not the -type of the media in the drive. For instance, a format meant for -accessing 720k double density disks in a high density drive was called -h720k and not d720k. The reason for this is that for 5 1/4 drives the -parameters for accessing a disk do not only depend on the format of -the disk, but also on the drive type. The format of the disk is -already implied by the capacity, and so the type letter is used to -describe the type of the *drive*. - However, this dependency on the drive type only exists for 5 1/4 -drives. For 3 1/2 drives, this is not needed, and as 3 1/2 drives are -more frequent, people started forgetting about this, and understood -that the letter described the *media* format. When support for extra -density drives was added to the kernel, people still used the name -H1440 for accessing high density disks using their extra density -drive. By the way, several distribution use this scheme. - In order to calm down the confusion, we propose to make the type -letter again describe the type of the *drive*. However, all 3 1/2 -drives are now described by a unique type letter: "u". This means -universal (one letter fits all 3 1/2 formats). Moreover the u -resembles the Greek letter mu, as in microfloppy. - So the recommended name for a device node allowing to read 1440K -disks in a 3 1/2 drive (no matter its density) is called u1440. Note -that this is now lowercase. - However, this new convention is still subject to discussion. - - Capacity is the capacity of the media in K bytes. Fortunately, this -leads to no ambiguity. - - Example: - A device node allowing to use 720K 5 1/4 floppies in a high density -drive connected as first unit to the second controller is called - /dev/fd4h720 - - Right now, MAKEFLOPPIES supports all three conventions (media, drive, -and "u"), you may chose amongst them using command line switches. - - -14. My drive doesn't detect disk changes / When I type mdir a:, I get -the directory listing of the previous disk. - - This means that there is a problem with the disk change line. This -problem may have several reasons: - a. The disk change line is near the edge of the cable, and is the -first line to suffer if the cable is not inserted straight. Press -gently on the connectors of your floppy disk cable, in order to ensure -that all wires make contact. - b. Because the disk change line is near the edge of the cable, it is -also the first line to suffer if the cable is damaged. If necessary, -buy a new cable, they cost less than five dollars. - c. On some drives, the disk change line may be chosen by jumper. Make -sure that your floppy controller board and your drive agree which line -is the disk change line. The usual location is line 34. - d. Some older drives don't support the disk change line at all. In -this case, you have to configure the floppy driver to work around the -problem. Use 'floppycontrol --broken_dcl' to do this. Now the floppy -driver assumes that the disk is changed whenever the device node is -closed and then re-opened. This is less efficient, as it results in -many useless cache flushes, so use it only if you really need it. This -command has to be issued after each reboot, so I suggest you put it -into your /etc/rc files. - - -15. I get "No such device or address" errors for various floppy -related commands. - - This message may mean one of several things: - 1. No floppy driver is compiled into the kernel, and no floppy -module is inserted. Kerneld may fail to automatically insert the -floppy module when you upgraded your kernel without upgrading the -module and moving it to a place where kerneld finds it. - 2. The drive doesn't exist (mistyped drive name?) - 3. No disk is in the drive. - 4. A problem with the disk change line: The disk change line is not -only used to detect disk changes, but also to tell whether there is a -disk in the drive at all.) See question 13 for fixes for disk change -line problem. - 5. The floppy geometry is unknown for the getfdprm or fdformat -programs. If you format a disk, rather use superformat. - - -16. I have a HP Omnibook 6000 :( - - These laptops are supplied with a floppy-drive & fdc combo which -doesn't support DMA :( - Upgrade to at least 1.3.92 and add 'floppy=nodma' to your Lilo -command line. The driver is not yet tested. - - -17. I can't get my floppy drive going, is there another method to -install? - - You may also install via hard disk and initrd. You need a big enough -hard disk to do this (and it takes a little bit more time than the -usual method). The following method presumes that it is possible to -access the disk using DOS, and that you are using a kernel which is -more recent than 1.3.73. You also need a version of loadlin-1.6 more -recent than 1.6 - 1. Leave a small DOS partition (with enough spare space to hold the -tar files from a few install disks). The bigger that partition is, the -less come and goes from DOS are needed later. However, the bigger it -is, the less space is available for Linux itself. - 2. On a desktop computer, using Linux, make a filesystem on a -smallish spare partition (for instance on your swap partition). This -filesystem should contain the files usually found on the install root -disks. Add a '/linuxrc' file which contains the following lines: -#!/bin/sh -. etc/rc -/bin/sh - - 3. On the desktop computer, unmount the filesystem, and dd it to a -file. Compress the file, and copy it to a floppy disk. - 4. Copy it to the Laptops hard disks. - - 5. Copy the tar files from the first few install disks to the laptops -hard disk. - 6. Use loadlin to boot Linux on the laptop (use the umsdos fs as -root). - 7. Start installation (tell the install program to look for the -tar files on your hard disk). - 8. If the first few files are installed, move back to DOS to erase -the tar files which you already unpacked, and copy the next ones. - 9. reboot Linux. -10. repeat until all is installed. -11. After installation, it is wise to leave that DOS partition, in -case you need to bring more files later. - - Steps 5 to 10 may be skipped if your laptop has a CD-ROM drive :-) - - -18. Is it possible to use two floppy disk controllers under Linux? - - YES. To use both controllers, boot the kernel with the lilo parameter -'floppy=two_fdc'. This parameter can be given on the lilo prompt, just after -the name of the kernel. It can also be specified in the /etc/lilo.conf file -by adding: - append = "floppy=two_fdc" - It is assumed that your second controller lives at 0x370. If it uses -another I/O base-address, change this address in the floppy.c. The -drives on the second controller use the minor device numbers 128-131 -for the generic device, and 132-255 for the fixed geometry device. The -following formula gives the minor number: minor = fdc * 128 + geometry -* 4 + unit . See the README file in fdutils for more details - - -19. Is it possible to boot off these special format disks? - - Yes. There is a lilo patch which allows to boot off these disks at -ftp.imag.fr:pub/Linux/ZLIBC/floppy/misc/lilo18dev.diff.gz It allows to -boot from ED disks and from disks with more sectors than usual (up to -21 on a HD disk). However, 2m and Xdf disks are still unbootable. - - -20. I get "Unable to allocate DMA memory" messages when trying to use -the floppy. - - This happens whenever the memory is too scarce to allocate the floppy -driver's DMA buffer. It is possible to use the floppy driver without -DMA, and in that case, the floppy driver uses vmalloc'ed memory, which -is more readily available. Upgrade to at least 1.3.97 and use the -floppy=nodma boot flag. If you use the floppy driver as a module, set -the environment variable 'floppy' to 'dma'. diff --git a/FINETUNING b/FINETUNING deleted file mode 100644 index f5fa27e..0000000 --- a/FINETUNING +++ /dev/null @@ -1,73 +0,0 @@ - This file contains several hints to fine tune the floppy driver. Most -tuning is done by floppycontrol. These tuning commands have to be -issued after each reboot, so I suggest that you put these commands -into your /etc/rc file [exact name is system dependent], once you have -found a suitable setting. Read also the floppycontrol manpage for more -info. All floppycontrol commands also have a drive parameter (not -listed below). I.e. in order to chose a null select delay for drive -one, use 'floppycontrol --select_delay 0 /dev/fd1'. Some of these -options may not yet be available with the mainline kernel. In that -case, get the alpha or beta patches from -ftp.imag.fr:pub/Linux/ZLIBC/floppy/ALPHA/fdp1.1.??-????.diff.gz - - 1. IBM thinkpads. These notebooks use an inverted convention for the -disk change line. Use 'floppycontrol --inverted_dcl' to use the floppy -drive on these machines. - - 2. Broken disk change line. If your drive fails to notice disk -changes, or notices disk changes where there aren't any, set this flag -with 'floppycontrol --broken_dcl'. If you have dcl problems, but don't -have any under DOS or with pre-1.1.41 kernels, mail me. - - 3. Autodetection. The autodetection sequence is the order in which the -different formats are probed. You may change this sequence with -floppycontrol --autodetect . Sequence is a comma separated -list of format indexes. No space should occur in this list. - I suggest you put those formats you most frequently use near the -beginning of the list. However, certain constraints should be -respected: - a. formats which only differ in the number of tracks cannot be -distinguished by autodetection. - b. if you have two formats which only differ in the number of -sectors, you have to put the format with most sectors as first into -the list, and add the read-track flag to this format. Indeed, a format -with too many sectors always fits. (the t flag is set for a given -format by typing a t after its index, such as in - 'floppycontrol --autodetect 7,4t,25,22,21,31' ) - - 4. Speeding up concurrent access. If the select_delay of all drives -is 0, the floppy driver probes all other drives for disk change during -an access. This speeds up buffer io to these other drives. By default, -the select_delay is not zero, because certain Dutch drives need it -that way. Most modern drives however can do with a select delay of -zero. Use 'floppycontrol --select_delay 0' on all drives. If after -setting this delay to zero, your drives fails to detect disk changes, -or complains wrongly about absent or changed disks, set the select -delay back to 2. - - 5. Silent disk change line clearing. If you have sufficiently recent -drives, you may switch this on with 'floppycontrol --silent_dcl_clear'. - On most drives, the disk change line can only be cleared by seeking -the drive head. The line has to be cleared before each access in order -to be able to detect further disk changes. On most drives, this line -can also be cleared by seeking the drive to track -1. This is silent. -Don't enable this if you also use ftape, because tape drives might -understand this as a tape command. - Now try this experiment: mdir a: , change the disk, and type again -mdir a: . If for the second time your drive still makes noise, disable -the feature with 'floppycontrol --noisy_dcl_clear'. Disable it also if -your drives complains wrongly about absent or changed disks. - - 6. Spin down time. If you often do several floppy commands in a row -(such as mcopy immediately after mdir), and if you type slowly, it -might be interesting to increase the spindown delay to make sure the -motor is still spinning for the next command. Do this with -'floppycontrol --spindown 1000'. (The spindown delay is expressed in -units of 1/100 seconds.) If you also use ftape, don't use a high -value, as the floppy driver locks the fdc while the floppy is still -spinning. - - 7. Timeout. If you have many formats in your autodetection list, I -recommend setting the timeout to a higher value with - 'floppycontrol --timeout 1000'. (The timeout is expressed in units of -1/100 seconds.) diff --git a/INSTALL b/INSTALL index e2698f5..18d232e 100644 --- a/INSTALL +++ b/INSTALL @@ -3,9 +3,10 @@ Installation: 1. First untar the package. - 2. Compile the utilities: - cd src - make + 2. Run ./configure + + 3. Compile the utilities: + make 3. Run the MAKEFLOPPIES script to create the device files: cd /dev @@ -15,7 +16,7 @@ Installation: I you have any questions, feel free to ask! 5. You might also want to get a recent version of mtools (later than -2.5.4) +3.0) A. Knaff - ( Alain.Knaff@inrialpes.fr ) + ( Alain.Knaff@poboxes.com ) diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..027d8fb --- /dev/null +++ b/Makefile.in @@ -0,0 +1,36 @@ +@SET_MAKE@ + +all: compile comp.doc +install: install.prog install.doc +clean: clean.prog clean.doc + +compile: + $(MAKE) -C src all + +install.prog: compile + $(MAKE) -C src install.bin install.conf + +comp.doc: + $(MAKE) -C doc all + +install.doc: doc + $(MAKE) -C doc install + +clean.doc: + $(MAKE) -C doc clean + +clean.prog: + $(MAKE) -C src clean + +info: + $(MAKE) -C doc info + +html: + $(MAKE) -C doc html + +dvi: + $(MAKE) -C doc dvi + + +install.info: + $(MAKE) -C doc install-info diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 0000000..97b12de --- /dev/null +++ b/acconfig.h @@ -0,0 +1,7 @@ + +/***** begin user configuration section *****/ + +/* Define this if you fdmount to be usable only by the 'floppy' group */ +#undef FLOPPY_ONLY + + diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..74605b6 --- /dev/null +++ b/config.guess @@ -0,0 +1,693 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-cbm-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-atari-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-sun-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-apple-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >dummy.c + int main (argc, argv) int argc; char **argv; { + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + ${CC-cc} dummy.c -o dummy \ + && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp3[0-9][05]:OpenBSD:*:*) + echo m68k-hp-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo i386-pc-cygwin32 + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin32 + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then + echo "${UNAME_MACHINE}-pc-linux" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then + echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then + echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then + echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then + echo "powerpc-unknown-linux-gnu" ; exit 0 + elif test "${UNAME_MACHINE}" = "alpha" ; then + echo alpha-unknown-linux-gnu ; exit 0 + elif test "${UNAME_MACHINE}" = "sparc" ; then + echo sparc-unknown-linux-gnu ; exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us + # useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout. + test ! -d /usr/lib/ldscripts/. \ + && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + # Determine whether the default compiler is a.out or elf + cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..430e160 --- /dev/null +++ b/config.h.in @@ -0,0 +1,16 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define this if you fdmount to be usable only by the 'floppy' group */ +#undef FLOPPY_ONLY + +/* Define if you have the header file. */ +#undef HAVE_LINUX_EXT_FS_H + +/* Define if you have the header file. */ +#undef HAVE_LINUX_XIA_FS diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..22eb93d --- /dev/null +++ b/config.sub @@ -0,0 +1,927 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \ + | arme[lb] | pyramid \ + | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ + | alpha | we32k | ns16k | clipper | i370 | sh \ + | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \ + | pdp11 | mips64el | mips64orion | mips64orionel \ + | sparc | sparclet | sparclite | sparc64) + basic_machine=$basic_machine-unknown + ;; + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[3456]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ + | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ + | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ + | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ + | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* | f301-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigados) + basic_machine=m68k-cbm + os=-amigados + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[3456]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[3456]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[3456]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[3456]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5) + basic_machine=i586-intel + ;; + pentiumpro | p6) + basic_machine=i686-intel + ;; + pentium-* | p5-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + k5) + # We don't have specific support for AMD's K5 yet, so just call it a Pentium + basic_machine=i586-amd + ;; + nexen) + # We don't have specific support for Nexgen yet, so just call it a Pentium + basic_machine=i586-nexgen + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + basic_machine=mips-mips + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware* | svr4*) + os=-sysv4 + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -linux-gnu* | -uxpv*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigados + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100755 index 0000000..9a9e408 --- /dev/null +++ b/configure @@ -0,0 +1,1568 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-fdmount-floppy-only support for OS/2 extended density format disks" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=src/floppycontrol.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:527: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:557: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:586: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + ac_prog_rejected=no + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:634: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:668: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:673: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:697: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:725: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:746: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:763: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 +echo "configure:787: checking whether ${CC-cc} needs -traditional" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_pattern="Autoconf.*'x'" + cat > conftest.$ac_ext < +Autoconf TIOCGETP +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +else + rm -rf conftest* + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat > conftest.$ac_ext < +Autoconf TCGETA +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi + +echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:862: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:912: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:961: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`$ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`$ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:982: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`$ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:1000: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`$ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:1024: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:1078: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:1099: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <&6 +echo "configure:1143: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1153: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +# Check whether --enable-fdmount-floppy-only or --disable-fdmount-floppy-only was given. +if test "${enable_fdmount_floppy_only+set}" = set; then + enableval="$enable_fdmount_floppy_only" + if test x$enableval = xyes; then + cat >> confdefs.h <<\EOF +#define FLOPPY_ONLY 1 +EOF + +fi +else + cat >> confdefs.h <<\EOF +#define FLOPPY_ONLY 1 +EOF + +fi + + + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile src/Makefile doc/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@LN_S@%$LN_S%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..dedbeaa --- /dev/null +++ b/configure.in @@ -0,0 +1,31 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src/floppycontrol.c) + +AC_CONFIG_HEADER(config.h) +AC_PROG_MAKE_SET + +dnl Checks for compiler +AC_PROG_CC +AC_PROG_GCC_TRADITIONAL +AC_PROG_INSTALL +AC_PROG_LN_S + +dnl Check for Systems +AC_CANONICAL_SYSTEM + +AC_C_CONST +AC_C_INLINE + +AC_CHECK_HEADERS(linux/ext_fs.h linux/xia_fs.h) + +dnl Make fdmount accessible by the floppy group only +undefine([fdmount-floppy-only])dnl +AC_ARG_ENABLE(fdmount-floppy-only, +[ --enable-fdmount-floppy-only Make fdmount accessible to the "floppy" group only], +[if test x$enableval = xyes; then + AC_DEFINE(FLOPPY_ONLY) +fi],AC_DEFINE(FLOPPY_ONLY)) + + + +AC_OUTPUT(Makefile src/Makefile doc/Makefile) diff --git a/doc/FAQ.html b/doc/FAQ.html new file mode 100644 index 0000000..5da012f --- /dev/null +++ b/doc/FAQ.html @@ -0,0 +1,499 @@ + + + + Frequently asked question about the Linux floppy driver + + + +

Frequently asked question about the Linux floppy driver

+ + +Most of the floppy utilities mentioned in this FAQ can be found in the +fdutils package. For others, +consult the lsm or archie. Alpha releases of fdutils are named +fduday month.taz or fdu5.0-day month.diff.gz + + + +
+ + +

How do I access floppy drives in Linux?

+ + Either use mtools or mount the disk. Mtools can be found at
sunsite + and tsx-11 + + It is a collection of utilities to access DOS disks. These utilities +behave mostly like their DOS counterparts, i.e. mdir is like dir, +mcopy is like copy, etc. Specifics are in the manpages.

+ + To mount a disk on /mnt, use the following command lines:

+

 mount -t msdos /dev/fd0 /mnt
+
+ + The directory /mnt must already exist: +
 mkdir /mnt
+
+ + +

How should I report bugs?

+ + If you have a question or a bug report about the floppy driver, mail +me at Alain.Knaff @ poboxes.com . If you post to the news, use +preferably one of the groups comp.os.linux.help (for questions) or +comp.os.linux.hardware (for bug reports). As the volume in these +groups is rather high, be sure to include the word "floppy" (or +"FLOPPY") in the subject line.

+ +

+ + +

I can't fdformat the new formats.

+ + Fdformat is considered obsolete. Use superformat instead.

+ + +

Mtools says "12 bit FAT on a: sure?" when trying to access an ED disk (or a similar message) when formatting a disk

+ + Some ED (extra density) disks use 16 bit FATS. The FAT type (12 or 16 + bit) is described in the configuration file (/etc/mtools or + ~/.mtoolsrc). It is the first number. Example: + +
A /dev/fd0 12 0 0 0
+           ^^ 12 bit FAT
+
+ +
+ + + + + + + + + +
12means12 bit FAT
16means16 bit FAT
0means"use whatever is appropriate"
-12means12 bit FAT, even if it looks fishy
-16means16 bit FAT, even if it looks fishy

+ + CAUTION: If you have an /etc/mtools file AND an ~/.mtoolsrc file, the +~/.mtoolsrc file overrides /etc/mtools. The home directory used for +~/.mtoolsrc is $HOME, if that is undefined, it is derived from +$LOGNAME, and if that's undefined too, it is derived from getlogin, +and finally from getuid.

+ There are also compiled-in defaults, which are used if neither +/etc/mtools, nor ~/.mtoolsrc are found.

+ + +

Mtools says "fat_read: Wrong FAT encoding 12 16?" (or similar) when accessing a disk formatted with the old mtools.

+ + mtools does some sanity checks on the size of the +FAT. Unfortunately, these are too strict for certain disks formatted +with the old mtools, and for hard disk partitions formatted by DOS +6, and probably for other conditions as well. Define the environment +variable MTOOLS_FAT_COMPATIBILITY to override this check.

+(to do this, type + +

 setenv MTOOLS_FAT_COMPATIBILITY 1
+ +in csh or tcsh, and + +
 export MTOOLS_FAT_COMPATIBILITY=1
+ +in sh/bash/zsh/...)

+ + +

How should I describe the new 2m formats in /etc/mtools?

+ +Support for both disk drives a: and b: for all formats (except Xdf) is +already built into the new version of mtools (3.0). Definitions for +new drive letters no longer override these default definitions.

+ + Just for the record, here are definitions to mimic the standard +behavior: +

 drive a: file="/dev/fd0"
+ drive b: file="/dev/fd1"
+
+ +
+

How should I describe the Xdf formats in /etc/mtools?

+ + The following /etc/mtools lines allow to access all disks, including +Xdf: +
 drive a: file="/dev/fd0" use_xdf=1
+ drive b: file="/dev/fd1" use_xdf=1
+
+ + However, the use_xdf flag slightly slows down initial access to non +Xdf disks.

+ + +

Which minor device number should I use for 2m formats?

+ + 2m formats don't have a minor number associated with them, they can +only be accessed using the "generic format" devices (i.e. /dev/fd0, +/dev/fd1).

+ + +

I have an IBM Thinkpad :-(

+ + Don't panic. Add the line 'floppy=thinkpad' to your lilo boot +parameters. This can be entered at the lilo prompt after the name of +the kernel image. It can also be specified in the lilo.conf file, by +adding the following line: +
 append = "floppy=thinkpad"
+
+ + With some IBM thinkpads, it's also possible to make their floppy +drive work by toggling the "FLOPPY" option in CMOS from "auto" to +"on". However, apparently this CMOS option is not available on all +models.

+ + On some models, both options may be required, on others, none are +required.

+ + More info about IBM Tinkpads on Linux can be found here. + + +

What are the minor device numbers for the floppy device nodes?

+ + The major device number for the floppy drives is 2. The minor device +number is calculated using the following formula: +
    minor_device = format_nr * 4 + 128 * fdc_nr + unit_nr
+
+ (fdc_nr identifies the floppy disk controller, and unit_nr identifies +which drive on the floppy disk controller to be used) format_nr +identifies the format (see the README file in fdutils for more +details). If format_nr is 0, the device is an autodetection device. + Use the MAKEFLOPPIES script included in the fdutils package to +automatically create the needed devices.

+ + +

What are the recommended names for the floppy device nodes?

+ + Floppy drives are named + fd drive_nr type max_capacity.

+ +Drive_nr identifies the drive. It ranges from 0 to 3 for +drives connected to the first controller, and from 4 to 7 for drives +connected to the second controller.

+ +Type is the type of the drive or media. The exact meaning of +this (drive or media) is still being discussed. Traditionally, this +letter described the type of the drive (density, 5 1/4 or 3 +1/2). Lower case letters described 5 1/4 drives, and upper case +letters describe 3 1/2 drives. h or H meant high density drives, d or +D meant double density drives.

Initially this letter described the +type of the drive and not the type of the media in the +drive. For instance, a format meant for accessing 720k double density +disks in a high density drive was called h720k and not d720k. The +reason for this is that for 5 1/4 drives the parameters for accessing +a disk do not only depend on the format of the disk, but also on the +drive type. The format of the disk is already implied by the capacity, +and so the type letter is used to describe the type of the +drive.

However, this dependency on the drive type only +exists for 5 1/4 drives. For 3 1/2 drives, this is not needed, and as +3 1/2 drives are more frequent, people started forgetting about this, +and understood that the letter described the media +format. When support for extra density drives was added to the kernel, +people still used the name H1440 for accessing high density disks +using their extra density drive. By the way, several distribution use +this scheme.

In order to calm down the confusion, we propose to +make the type letter again describe the type of the +drive. However, all 3 1/2 drives are now described by a +unique type letter: "u". This means universal (one letter fits all 3 +1/2 formats). Moreover the u resembles the Greek letter mu, as in +microfloppy.

So the recommended name for a device node allowing to +read 1440K disks in a 3 1/2 drive (no matter its density) is called +u1440. Note that this is now lowercase.

However, this new +convention is still subject to discussion.

+ + Capacity is the capacity of the media in K bytes. Fortunately, this +leads to no ambiguity.

+ + Example:

+ A device node allowing to use 720K 5 1/4 floppies in a high density +drive connected as first unit to the second controller is called + /dev/fd4h720 + + Right now, MAKEFLOPPIES supports all three conventions (media, drive, +and "u"), you may chose amongst them using command line switches.

+ + +14. My drive doesn't detect disk changes / When I type mdir a:, I get +the directory listing of the previous disk. + + This means that there is a problem with the disk change line. This +problem may have several reasons:

+ a. The disk change line is near the edge of the cable, and is the +first line to suffer if the cable is not inserted straight. Press +gently on the connectors of your floppy disk cable, in order to ensure +that all wires make contact.

+ b. Because the disk change line is near the edge of the cable, it is +also the first line to suffer if the cable is damaged. If necessary, +buy a new cable, they cost less than five dollars.

+ c. On some drives, the disk change line may be chosen by jumper. Make +sure that your floppy controller board and your drive agree which line +is the disk change line. The usual location is line 34.

+ d. Some older drives don't support the disk change line at all. In +this case, you have to configure the floppy driver to work around the +problem. Use 'floppycontrol --broken_dcl' to do this. Now the floppy +driver assumes that the disk is changed whenever the device node is +closed and then re-opened. This is less efficient, as it results in +many useless cache flushes, so use it only if you really need it. This +command has to be issued after each reboot, so I suggest you put it +into your /etc/rc files.

+ + +

I get "No such device or address" errors for various floppy related commands.

+ + This message can mean one of several things:

+ +

  • No floppy driver is compiled into the kernel, and no floppy +module is inserted. Kerneld may fail to automatically insert the +floppy module when you upgraded your kernel without upgrading the +module and moving it to a place where kerneld finds it. +
  • The drive doesn't exist (mistyped drive name?) +
  • No disk is in the drive. +
  • A problem with the disk change line: The disk change line is not +only used to detect disk changes, but also to tell whether there is a +disk in the drive at all.) See question 13 for fixes for disk change +line problem. +
  • The floppy geometry is unknown for the getfdprm or fdformat +programs. If you format a disk, rather use superformat. + + + +

    I have a HP Omnibook 6000 :(

    + +These laptops are supplied with a floppy-drive & fdc combo which +doesn't support DMA :( Just add floppy=nodma to your Lilo +command line. + +More info about the Omnibook and linux can be found
    here. + + +

    I can't get my floppy drive going, is there another method to install?

    + +You may also install via hard disk and initrd. You need a big enough +hard disk to do this (and it takes a little bit more time than the +usual method). The following method presumes that it is possible to +access the disk using DOS, and that you are using a kernel which is +more recent than 1.3.73. You also need a version of loadlin more +recent than 1.6.

    +

      +
    1. Leave a small DOS partition (with enough spare space to hold the +tar files from a few install disks). The bigger that partition is, the +less come and goes from DOS are needed later. However, the bigger it +is, the less space is available for Linux itself. +
    2. On a desktop computer, using Linux, make a filesystem on a +smallish spare partition (for instance on your swap partition). This +filesystem should contain the files usually found on the install root +disks. Add a '/linuxrc' file which contains the following lines: +
      #!/bin/sh
      +. etc/rc
      +/bin/sh
      +
      +
    3. On the desktop computer, unmount the filesystem, and dd it to a +file. Compress the file, and copy it to a floppy disk. +
    4. Copy it to the Laptops hard disks. + +
    5. Copy the tar files from the first few install disks to the laptops +hard disk. +
    6. Use loadlin to boot Linux on the laptop (use the umsdos fs as +root). +
    7. Start installation (tell the install program to look for the +tar files on your hard disk). +
    8. If the first few files are installed, move back to DOS to erase +the tar files which you already unpacked, and copy the next ones. +
    9. reboot Linux. +
    10. repeat until all is installed. +
    11. After installation, it is wise to leave that DOS partition, in +case you need to bring more files later. +
    + + Steps 5 to 10 may be skipped if your laptop has a CD-ROM drive :-) + +
    +

    Is it possible to use two floppy disk controllers under Linux?

    + + YES. To use both controllers, boot the kernel with the lilo parameter +'floppy=two_fdc'. This parameter can be given on the lilo prompt, just after +the name of the kernel. It can also be specified in the /etc/lilo.conf file +by adding the following line: +
     append = "floppy=two_fdc"

    + It is assumed that your second controller lives at 0x370. If it uses +another I/O base-address, change this address in the floppy.c. The +drives on the second controller use the minor device numbers 128-131 +for the generic device, and 132-255 for the fixed geometry device. The +following formula gives the minor number: + +

    	minor = fdc * 128 + geometry * 4 + unit 
    + + See the README file in fdutils for more details. + +
    +

    Is it possible to boot off these special format disks?

    + +Yes. Make sure you have a version of lilo more recent than v18, and +put the following line into your /etc/lilo.defines before compiling +it: + +
     -DXL_SECS=44
    +
    + + This enables Lilo to boot from disks with up to 44 sectors (i.e. more +than you'll ever see :-) ) It allows to boot from ED disks and from +disks with more sectors than usual (up to 21 on a HD disk, 42 on an ED +disk). However, 2m and Xdf disks cannot be booted using this method. + +
    +

    I get "Unable to allocate DMA memory" messages when trying to use + the floppy.

    + +This happens whenever the memory is too scarce to allocate the floppy +driver's DMA buffer. It is possible to use the floppy driver without +DMA, and in that case, the floppy driver uses vmalloc'ed memory, which +is more readily available. In order to disable DMA, use the +floppy=nodma boot flag. If you use the floppy driver as a +module, set the environment variable 'floppy' to 'dma'. + +
    +

    I have a Micron Millenia Transport.

    + +Apparently, these laptops are supplied with a floppy controller which +doesn't support the fifo.

    Switch off the FIFO by adding +floppy=nofifo to your Lilo command line.

    + +


    + + + +Last modified: Sat Apr 19 10:13:07 MET DST + + + + diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..abded68 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,133 @@ +MAKEINFO = makeinfo +TEXI2DVI = texi2dvi +TEXI2HTML = texi2html + +top_srcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +infodir = @infodir@ +mandir = @mandir@ +infodir = @infodir@ +sysconfdir = @sysconfdir@ + +mandir1 = $(mandir)/man1 +mandir4 = $(mandir)/man4 +mandir8 = $(mandir)/man8 + +MANPAGES1 = diskd.1 fdrawcmd.1 getfdprm.1 superformat.1 diskseekd.1 \ + floppycontrol.1 makefloppies.1 xdfcopy.1 fdmount.1 \ + floppymeter.1 setfdprm.1 + +MANPAGES4 = fd.4 +MANPERM = 644 +UID = root +GID = root + +INSTALL = @INSTALL@ +INSTALL_DATA= @INSTALL_DATA@ + +CC = @CC@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ + +all: fdutils.info fdutils.dvi + +TEXISRC = \ +acronyms.texi fdrawcmd.texi ioctl.texi superformat.texi \ +autodetect.texi fdutils.texi lilo.texi tips.texi \ +commands.texi floppycontrol.texi location.texi utilities.texi \ +diskd.texi floppymeter.texi makefloppies.texi xdfcopy.texi \ +diskseekd.texi formatlist.texi moredata.texi \ +fdmount.texi getfdprm.texi setfdprm.texi + + +html: Fdutils.html + +dvi: fdutils.dvi + +info: fdutils.info + +%.info: $(TEXISRC) + $(MAKEINFO) -I @srcdir@ @srcdir@/fdutils.texi + + +%.dvi: $(TEXISRC) + $(TEXI2DVI) @srcdir@/fdutils.texi + +clean: + rm -f fdutils.aux fdutils.cp fdutils.cps fdutils.dvi fdutils.fn + rm -f fdutils.log fdutils.pg fdutils.ps fdutils.toc fdutils.tp + rm -f fdutils.ky fdutils.vr fdutils.info fdutils.pgs + rm -f fdutils.info-1 fdutils.info-2 fdutils.info-3 + + + +%.html: Fdutils.texi + $(TEXI2HTML) $< + +Fdutils.texi: $(TEXISRC) texi-linearize + texi-linearize $(srcdir) fdutils.texi > $@ + +Fdutils.texi: $(TEXISRC) + + +# Don't cd, to avoid breaking install-sh references. +install.info: info + $(top_srcdir)/mkinstalldirs $(infodir) + if test -f fdutils.info; then \ + for i in fdutils.info*; do \ + $(INSTALL_DATA) $$i $(infodir)/$$i; \ + done; \ + else \ + for i in $(srcdir)/fdutils.info*; do \ + $(INSTALL_DATA) $$i $(infodir)/`echo $$i | sed 's|^$(srcdir)/||'`; \ + done; \ + fi + + +install.man: + for i in $(MANPAGES1); do \ + install -c -m $(MANPERM) -o $(UID) -g $(GID) \ + $(srcdir)/$$i $(mandir1)/$$i; \ + done + + for i in $(MANPAGES4); do \ + install -c -m $(MANPERM) -o $(UID) -g $(GID) \ + $(srcdir)/$$i $(mandir4)/$$i; \ + done + +# for i in $(MANPAGES8); do \ +# install -c -m $(MANPERM) -o $(UID) -g $(GID) \ +# $(srcdir)/$$i $(mandir8)/$$i; \ +# done + + ( cd $(mandir1); \ + ln -sf fdmount.1 $(mandir1)/fdumount.1; \ + ln -sf fdmount.1 $(mandir1)/fdlist.1; \ + ln -sf fdmount.1 $(mandir1)/fdmountd.1; \ + ln -sf xdfcopy.1 $(mandir1)/xdfformat.1 \ + ) + +install.zman: + for i in $(MANPAGES1); do \ + gzip < $(srcdir)/$$i >_; \ + install -c -m $(MANPERM) -o $(UID) -g $(GID) \ + _ $(mandir1)/$$i.gz; \ + done + for i in $(MANPAGES4); do \ + gzip < $(srcdir)/$$i >_; \ + install -c -m $(MANPERM) -o $(UID) -g $(GID) \ + _ $(mandir4)/$$i.gz; \ + done + for i in $(MANPAGES8); do \ + gzip < $(srcdir)/$$i >_; \ + install -c -m $(MANPERM) -o $(UID) -g $(GID) \ + _ $(mandir8)/$$i.gz; \ + done + rm _ + +install: install.man install.info diff --git a/README b/doc/README similarity index 96% rename from README rename to doc/README index 224b2f5..edf7283 100644 --- a/README +++ b/doc/README @@ -78,9 +78,8 @@ of tracks according to the boot sector of the disk. Mtools 2.5 and up are ok. This doesn't obviously work with disks containing something else than a MSDOS filesystem. - After recompiling your kernel and rebooting, you can use a few more -minor device numbers for disks with the new formats. The minor device -number for the floppy devices is calculated as follows: + The minor device number for the floppy devices is calculated as +follows: minor_device = format_nr * 4 + 128 * fdc_nr + unit_nr (fdc_nr identifies the floppy disk controller, and unit_nr identifies which drive on the floppy disk controller to be used) @@ -125,6 +124,10 @@ in the table in floppy.c. Valid numbers and formats are: 30 800kB, 3.5" DD drive 31 1600kB, 3.5" HD drive + This table lists first the format_nr (0-31) used to compute the minor +number, then the capacity of the format (360kb - 3200kb), and then the +type of the drive in which this format is used. + The formats 0..8 are the standard PC formats, 9 is apparently needed for certain weird CompaQ computers. The remaining formats are extended capacity formats. Some of them have been taken from Heiko Schroeder's @@ -390,8 +393,9 @@ THIS MANPAGE CAREFULLY. IMPROPER USAGE MAY LEAD TO DATA LOSS. There are man pages for mtools (in mtools/) and the utilities (in utils/) included. There's also a FAQ list. It is regularily updated on -ftp.imag.fr:pub/ZLIBC/fdutils/ALPHA. In the same directory, you can -find alpha versions of fdutils too. (They are named fduddmm.taz, where -dd stands for the day and mm for the month. I'll only leave these for -a limited time, and then move them into an old directory, or remove -them.) +http://www.club.innet.lu/~year3160/floppy/FAQ.html . You can find +alpha versions of fdutils on +http://www.club.innet.lu/~year3160/fdutils . (They are named +fduddmm.taz, where dd stands for the day and mm for the month. I'll +only leave these for a limited time, and then move them into an old +directory, or remove them.) diff --git a/doc/acronyms.texi b/doc/acronyms.texi new file mode 100644 index 0000000..eb67eb8 --- /dev/null +++ b/doc/acronyms.texi @@ -0,0 +1,144 @@ +@node Acronyms, Interesting formats, Compile-time configuration, Top +@appendix Acronyms + +@table @emph + +@item SD (Single density) +Single density disks use a data transfer rate of 125 kb/s and are no +longer in use today, because of their low capacity. + +@item DD (Double density) +Double density disks normally hold 360KB (5 1/4) or 720KB (3 1/2) of +data per disk. + +Double density disks have only a hole on one side (for write +protection). + +Double density uses a data transfer rate of 250 kb/s or 300 kb/s +depending on the drive type: 5 1/4 high density drives use 300 kb/s when +writing to a double density diskm 250 kb/s is used in all other +circumstances. The reason why double density disks in high density +drives need a higher data transfer rate is because these drives rotate +faster (360 rpm instead of 300 rpm). + +@item HD (High density) +High density disks normally hold 1200KB (5 1/4) or 1440KB (3 1/2) of +data per disk. High density 3 1/2 disks are marked as such by the +presence of a second square hole, just opposed to the write protect +hole. 3 1/2 high density disks are the most commonly used type of disks +today. + + +@item QD (Quad density) +Quad density is a hybrid between double and high density. It only +exists for 5 1/4 disks, and holds 720KB of data. It can be obtained by +formatting DD disks in a HD drive. QD uses double density for the +density along the tracks (data transfer rate), and high density for the +density perpendicular to the tracks (spacing between tracks, and thus +number of tracks). This came to existence because these two aspects are +limited by two different factors: the density along the track is limited +by the quality of the media, whereas the density perpendicular to the +tracks is mainly limited by the drive mechanism (this density, expressed +in bits per inch comes nowhere near the limits of the media, even with +HD). Thus quad density is an easy way to double the capacity of an +ordinary double density disk, just by formatting it in a HD drive. + +@item ED (Extra density) +Extra density refers to a disk density that can normally hold 2880KB of +data per disk. Extra density disks only exist as 3 1/2 disks. ED disks +are marked with a second squared hole opposed to the square hole, which +is a little bit closer to the middle of the edge than that of HD disks. +This format never really took off, because it only was released when +storage media with a much higher capacity, such as CD-Roms, tapes and +Zip disks became popular. + +ED uses a data transfer rate of 250 kb/s. + +@item DS (Double sided) +Self explanatory. + +@item SS (Single sided) +Self explanatory + +@item MSS (Mixed size sectors) +Mixed sector size formats are formats which use sectors of several +different sizes on a single track. @xref{Mixed size sectors} for +details. + +@item 2M (2 Megabytes) +2M is a high capacity format developped by Ciriaco de Celis. The basic +principle is the same as MSS: mix sectors of several sizes on a same +track, in order to minimize both slack space and header overhead. 2M is +different from MSS in that it uses a normal 18 sector format on its +first track. @xref{2M} for details. + +@item rpm (Rotations per minute) +All 3 1/2 drives and 5 1/4 DD drives run at 300 rotations per minute, +whereas 5 1/4 HD drives run at 360 rotations per minute. + +@item rps (Rotations per second) +See above. + + +@item tpi (tracks per inch) +Expresses how close cylinders are to each other. Usually, 5 1/4 double +density disks have 48 tpi, whereas 5 1/4 high density and quad density +disks have 96 tpi. 3 1/2 disks use 135.5 tpi. + +@item XDF (eXtended Density Format) +XDF is a disk format used for the OS/2 distribution disks. Its +operating systems are similar to 2M and MSS disk, but it is faster due +to a more creative arrangement of sectors. @xref{XDF} for details. + +@item XXDF (eXtended XDF) +XXDF is an Linux enhancement for XDF. It can store 1992 KB of data on an +ED disk instead of just 1840 available with the regular XDF +format. @xref{XXDF} for details. + +@item MFM (Multi Frequency Modulation) +MFM is a low level encoding of disk data. It is used for DD, HD and ED +disks, i.e. virtually all disks that are available today. The PC +hardware can only read MFM and FM disks. The doc at: +@example +ftp://cantor.informatik.rwth-aachen.de/pub/linux/floppy.ps +@end example +contains more detailed information about FM and MFM encoding. + +@item FM (Frequency modulation) +FM is a low level encoding of disk data. It was used for SD disks, and +is now considered to be obsolete. The doc at: +@example +ftp://cantor.informatik.rwth-aachen.de/pub/linux/floppy.ps +@end example +contains more detailed information about FM and MFM encoding. + +@item kb (kilobit) +1000 bits + +@item kb/s (kilobit per second) +We express the raw data throughput to and from the disk in this unit, +which is also used in the documentation of the floppy disk controller. + +@item B +Byte. A byte is 8 bits, and is the smallest individually addressable +unit of data. + +@item KB (K-Byte) +1024 bytes. Sometimes also noted K. + +@item KB/s (K-Byte) +We express the usable data throughput to and from the disk in KB/s. +Roughly, 1 KB/s = 8 kb/s. However, the usable data throughput is always +lower than the raw throughput due to header overhead, interleaving and +seek overhead. + +@item MB (Megabyte) +Initially, 1 megabyte was 1024*1024 bytes (i.e. 1048576 bytes). However, +when talking of floppy disk capacity, we understand it as 1000KB, that +is 1000*1024 bytes, i.e. 1024000 bytes. + +@item MB/s (million bytes per second) +We express (high) raw data throughput to and from the disk in kb/s, +which is also used in the documentation of the floppy disk controller. + +@end table diff --git a/doc/autodetect.texi b/doc/autodetect.texi new file mode 100644 index 0000000..f9b4acb --- /dev/null +++ b/doc/autodetect.texi @@ -0,0 +1,94 @@ +@node Autodetection, Boottime configuration, Extended formats, Top +@chapter How autodetection works +@cindex autodetection +@cindex format +@cindex recognize a disk + +The principle of autodetection is rather simple. When a floppy disk is +first accessed, and its geometry is not yet known, the floppy driver +tries out a list of up to 8 geometries (format descriptions) until one +is found that matches (i.e. that makes it possible to read the first +sector or track). This list of geometries is called the +@emph{autodetection list}. There is one autodetection list per drive +type (as indicated in the cmos). + +The autodetection list doesn't contain the geometry descriptions +themselves, but rather references to entries in the @emph{geometry list} +(@pxref{geometry list}). Each list may contain up to 8 such references. +Each reference can be tagged with a @code{t} flag. If this tag is set, +the floppy driver tries to read the whole track when trying out that +description; if it is not set, it only tries to read the boot sector. + +Reading the whole track is useful to distinguish among geometries which +differ only in the amount of sectors per track. In order to do this, +put the geometry with the most sectors first in the list, and set its +@code{t} tag. Use the @code{t} tag only in this case, as it makes +autodetection slower. + +Autodetection cannot distinguish between geometries that only differ in +the number of heads or in the number of tracks. + +Autodetection is meant to supply only a first approximation of the +actual format of the disk. It supplies enough information to enable a +program such as @code{mtools} to read the boot sector, which contains +the exact information. @code{Mtools} then uses the information +contained in the boot sector to set the exact geometry. + +The autodetection list is set using the following command: +@example +floppycontrol --autodetect @var{list} +@end example + +@section Example + +The following example restores the default autodetection sequence for a +3 1/2 ED drive: + +@example +floppycontrol --autodetect 7,8,4,25,28,22,31,21 +@end example + +The following example changes this sequence, so as to add the 1680KB +format (number 11). As only 8 formats are allowed in the autodetection +list, we have to dump one entry (we chose the last, which is numbered +21). The 1680KB format is identical with the default 1440KB format +except for the number of sectors. Thus we must read the whole track in +order to distinguish it from the 18 sector format (@code{t} flag). +Furthermore, the the 1680KB sector format should be detected first, as +an 21 sector disk would also matches the standard format with its 18 +sectors. + +@example +floppycontrol --autodetect 11t,7,8,4,25,28,22,31 +@end example + +The following example attempts to autodetect CBM 1581 disks along with +the more usual formats. CBM 1581 disks are not among the predefined +formats. Thus we first have to pick one of the predefined formats and +change it so it fits our needs. We may for example pick one of the +rarely used 5 1/4 formats, such as h880, which bears number 20). We +first make a device node bearing the requested number (so that we have a +filename to pass to setfdprm), then we chmod it so it becomes accessible +to mortal users, finally we configure the geometry of the new node, and +enter it into the autodetection list. We place it at the 4th position, +just behind the usual ED, HD and DD formats, and before the more exotic +extended formats. Indeed, formats which are nearer to the head of the +list are autodetected faster, and hence more commonly used formats +should be put nearer to the beginning @footnote{except of course if +several formats only differ in the number of sectors per track, in which +case the formats with the most sectors should come first}. + +@example +mknod /dev/fd0cbm1581 b 2 80 +chmod 666 /dev/fd0cbm1581 +setfdprm /dev/fd0cbm1581 DD DS sect=10 cyl=80 swapsides +floppycontrol --autodetect 7,8,4,20,25,28,22,31 +@end example + + +Some formats use more than 80 tracks. It is not possible for the kernel +to autodetect the number of tracks in a reasonable time, so you have to +use a sufficiently recent version of mtools to set the number of tracks +according to the boot sector of the disk. Mtools 3.0 and up are ok. This +doesn't obviously work with disks containing something else than a +MS-DOS filesystem. diff --git a/doc/cleanup b/doc/cleanup new file mode 100755 index 0000000..ff63bc9 --- /dev/null +++ b/doc/cleanup @@ -0,0 +1,5 @@ +#!/bin/sh + +rm -f fdutils.aux fdutils.cp fdutils.cps fdutils.dvi fdutils.fn fdutils.ky +rm -f fdutils.log fdutils.pg fdutils.ps fdutils.toc fdutils.tp fdutils.vr +rm -f fdutils.info* diff --git a/doc/cmdname b/doc/cmdname new file mode 100644 index 0000000..702519e --- /dev/null +++ b/doc/cmdname @@ -0,0 +1,12 @@ +diskd - disk daemon; wait for disk to be inserted +diskseek, diskseekd - disk seek daemon; simulates Messy Dos' drive cleaning effect +fd - floppy disk device +fdmount - Floppy disk mount utility +fdrawcmd - send raw commands to the floppy disk controller +floppycontrol - floppy driver configuration utility +floppymeter - measure raw capacity and exact rotation speed of floppy drive +getfdprm - print the current format information +MAKEFLOPPIES - Creates the default floppy device nodes. +setfdprm - sets user-provided floppy disk parameters +superformat - format floppies +xdfcopy - Program to copy and format Xdf disks in Linux diff --git a/doc/commands.texi b/doc/commands.texi new file mode 100644 index 0000000..597b4ad --- /dev/null +++ b/doc/commands.texi @@ -0,0 +1,35 @@ +@node Commands, Compile-time configuration, Floppy ioctls, Top +@chapter Command list +@cindex Command list +@cindex List of available commands + +This section describes the available fdutils commands, and the command +line parameters that each of them accepts. + +@menu +* diskd:: detect a disk change and execute a command +* diskseekd:: seeks the drive from time to time to shake of the + dust +* fdmount:: automatically mounts and unmounts floppy disks +* fdrawcmd:: send raw commands to the floppy disk controller +* floppycontrol:: configure the floppy driver +* floppymeter:: measures characteristic parameters of a floppy drive +* getfdprm:: print current geometry parameters +* makefloppies:: makes the floppy device entries +* superformat:: formats high capacity disks +* setfdprm:: changes the current and permanent geometry + parameters +* xdfcopy:: copies and formats XDF disks +@end menu + +@include diskd.texi +@include diskseekd.texi +@include fdmount.texi +@include fdrawcmd.texi +@include floppycontrol.texi +@include floppymeter.texi +@include getfdprm.texi +@include makefloppies.texi +@include setfdprm.texi +@include superformat.texi +@include xdfcopy.texi diff --git a/doc/configure.texi b/doc/configure.texi new file mode 100644 index 0000000..8d686bd --- /dev/null +++ b/doc/configure.texi @@ -0,0 +1,35 @@ +@node Compile-time configuration, Acronyms, Commands, Top +@chapter Compile-time configuration via GNU autoconf +@cindex configure options +@cindex compile-time configuration + +Before it can be compiled, fdutils must be configured using the GNU +autoconf script @code{./configure}. In most circumstances, running +@code{./configure} without any parameters is enough. However, you may +customize fdutils using various options to @code{./configure}. The +following options are supported: +@table @code + +@item --prefix @var{directory} +Prefix used for any directories used by fdutils. By default, this is +@file{/usr/local}. Fdutils is installed in @file{$prefix/lib}, looks for +its system wide configuration file in @file{$prefix/etc}. Man pages are +installed in @file{$prefix/man}, info pages in @file{$prefix/info} etc. + +@item --sysconfdir @var{directory} +Directory containing the system-wide configuration files such as +@file{mediaprm} and @file{driveprm}. By default, this is derived from +@code{prefix} (see above). N.B. For backward compatibility reasons, the +old-style floppy parameter file @file{fdprm} is always in @file{/etc}, +regardless of the setting for @code{sysconfdir} + +@item --enable-fdmount-floppy-only +Allows usage of the @code{fdmount} program only to members of the group +@code{floppy} + +@end table + +In addition to the above-listed options, the other standard GNU autoconf +options apply. Type @code{./configure --help} to get a complete list of +these. + diff --git a/doc/diskd.1 b/doc/diskd.1 new file mode 100644 index 0000000..1545cbb --- /dev/null +++ b/doc/diskd.1 @@ -0,0 +1,132 @@ +.TH diskd 1 "19apr97" fdutils-5.0 +.SH Name +diskd - disk daemon; wait for disk to be inserted +'\" t +.de TQ +.br +.ns +.TP \\$1 +.. + +.tr \(is' +.tr \(if` +.tr \(pd" + +.SH Note +This manpage has been automatically generated from fdutils's texinfo +documentation. However, this process is only approximative, and some +items, such as crossreferences, footnotes and indices are lost in this +translation process. Indeed, this items have no appropriate +representation in the manpage format. Moreover, only the items specific +to each command have been translated, and the general information about +fdutils has been dropped in the manpage version. Thus I strongly advise +you to use the original texinfo doc. +.TP +* \ \ +To generate a printable copy from the texinfo doc, run the following +commands: + +.nf +.ft 3 +.in +0.3i + ./configure; make dvi; dvips fdutils.dvi +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +* \ \ +To generate a html copy, run: + +.nf +.ft 3 +.in +0.3i + ./configure; make html +.fi +.in -0.3i +.ft R +.lp + +\&\fRA premade html can be found at: +\&\fR\&\f(CW\(ifhttp://linux.wauug.org/pub/knaff/fdutils\(is\fR +.TP +* \ \ +To generate an info copy (browsable using emacs' info mode), run: + +.nf +.ft 3 +.in +0.3i + ./configure; make info +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The texinfo doc looks most pretty when printed or as html. Indeed, in +the info version certain examples are difficult to read due to the +quoting conventions used in info. +.SH Description +.iX "p diskd" +.PP +The diskd command has the following syntax: +.PP + +.nf +.ft 3 +.in +0.3i +\&\fR\&\f(CWdiskd [\fR\&\f(CW-d \fIdrive\fR\&\f(CW] [\fR\&\f(CW-i \fImsdosfiles\fR\&\f(CW] [\fR\&\f(CW-e \fIcommand\fR\&\f(CW] +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +Diskd waits for a disk to be inserted into a given \fIdrive\fR, and then +either executes the \fIcommand\fR or exits. This program can be used to +automatically mount a disk as soon as it is inserted. +.PP +.SH Warning +.PP +This program works by switching the motor on for a very short +interval, and then seeking to track -1. This might damage hardware in +the long run. Amigas, which also use these techniques, are known for +having problems with their disk drives no longer spinning up properly +after a few month of usage. +.PP +.SH Options +.TP +\&\fR\&\f(CW-d\ \fIdrive\fR\&\f(CW\fR\ +Selects the drive to observe for disk insertion. By default, drive 0 +(\fR\&\f(CW/dev/fd0\fR) is observed. +.TP +\&\fR\&\f(CW-i\ \fIinterval\fR\&\f(CW\fR\ +Selects the polling interval. The interval is given in tenths of +seconds. Default is 10 (one second). +.TP +\&\fR\&\f(CW-e\ \fIcommand\fR\&\f(CW\fR\ +Gives the command to be executed when a disk is inserted. If no +command is given the program simply exits. Typically, the command +mounts the disk. It can be a shell scripts which probes for several +filesystems and disk geometries until it succeeds. +.PP +.SH Bugs +.IP +.TP +* \ \ +Automatic unmounting cannot yet be handled. It is indeed not enough to +scan for disk removal, because when the disk is removed, it is already +too late: There might be some buffers needing flushing. However, the +\&\fR\&\f(CWfdmountd\fR program allows automatic unmounting by using the +\&\fR\&\f(CWSYNC\fR mount options, which switches off write buffering +(see section fdmount). +.TP +* \ \ +The drive motor is running all the time, and on some computers, the +drive led flickers at each time the drive is polled. +.SH See Also +Fdutils' texinfo doc diff --git a/doc/diskd.texi b/doc/diskd.texi new file mode 100644 index 0000000..f39c37d --- /dev/null +++ b/doc/diskd.texi @@ -0,0 +1,55 @@ +@node diskd, diskseekd, Commands, Commands +@section diskd +@pindex diskd + +The diskd command has the following syntax: + +@example +@code{diskd} [@code{-d} @var{drive}] [@code{-i} @var{msdosfiles}] [@code{-e} @var{command}] +@end example + +Diskd waits for a disk to be inserted into a given @var{drive}, and then +either executes the @var{command} or exits. This program can be used to +automatically mount a disk as soon as it is inserted. + +@subsection Warning + +This program works by switching the motor on for a very short +interval, and then seeking to track -1. This might damage hardware in +the long run. Amigas, which also use these techniques, are known for +having problems with their disk drives no longer spinning up properly +after a few month of usage. + +@subsection Options + +@table @code +@item -d @var{drive} +Selects the drive to observe for disk insertion. By default, drive 0 +(@code{/dev/fd0}) is observed. +@item -i @var{interval} +Selects the polling interval. The interval is given in tenths of +seconds. Default is 10 (one second). +@item -e @var{command} +Gives the command to be executed when a disk is inserted. If no +command is given the program simply exits. Typically, the command +mounts the disk. It can be a shell scripts which probes for several +filesystems and disk geometries until it succeeds. +@end table + +@subsection Bugs + + +@itemize @bullet + +@item +Automatic unmounting cannot yet be handled. It is indeed not enough to +scan for disk removal, because when the disk is removed, it is already +too late: There might be some buffers needing flushing. However, the +@code{fdmountd} program allows automatic unmounting by using the +@code{SYNC} mount options, which switches off write buffering +(@pxref{fdmount}). + +@item +The drive motor is running all the time, and on some computers, the +drive led flickers at each time the drive is polled. +@end itemize diff --git a/doc/diskseekd.1 b/doc/diskseekd.1 new file mode 100644 index 0000000..cc0db21 --- /dev/null +++ b/doc/diskseekd.1 @@ -0,0 +1,124 @@ +.TH diskseekd 1 "19apr97" fdutils-5.0 +.SH Name +diskseek, diskseekd - disk seek daemon; simulates Messy Dos' drive cleaning effect +'\" t +.de TQ +.br +.ns +.TP \\$1 +.. + +.tr \(is' +.tr \(if` +.tr \(pd" + +.SH Note +This manpage has been automatically generated from fdutils's texinfo +documentation. However, this process is only approximative, and some +items, such as crossreferences, footnotes and indices are lost in this +translation process. Indeed, this items have no appropriate +representation in the manpage format. Moreover, only the items specific +to each command have been translated, and the general information about +fdutils has been dropped in the manpage version. Thus I strongly advise +you to use the original texinfo doc. +.TP +* \ \ +To generate a printable copy from the texinfo doc, run the following +commands: + +.nf +.ft 3 +.in +0.3i + ./configure; make dvi; dvips fdutils.dvi +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +* \ \ +To generate a html copy, run: + +.nf +.ft 3 +.in +0.3i + ./configure; make html +.fi +.in -0.3i +.ft R +.lp + +\&\fRA premade html can be found at: +\&\fR\&\f(CW\(ifhttp://linux.wauug.org/pub/knaff/fdutils\(is\fR +.TP +* \ \ +To generate an info copy (browsable using emacs' info mode), run: + +.nf +.ft 3 +.in +0.3i + ./configure; make info +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The texinfo doc looks most pretty when printed or as html. Indeed, in +the info version certain examples are difficult to read due to the +quoting conventions used in info. +.SH Description +.iX "p diskseekd" +.iX "c dust (shaking it off from a drive)" +.iX "c shaking off dust from a drive" +.PP +Several people have noticed that Linux has a bad tendency of killing +floppy drives. These failures remained completely mysterious, until +somebody noticed that they were due to huge layers of dust accumulating +in the floppy drives. This cannot happen under Messy Dos, because this +excuse for an operating system is so unstable that it crashes roughly +every 20 minutes (actually less if you are running Windows). When +rebooting, the BIOS seeks the drive, and by doing this, it shakes the +dust out of the drive mechanism. \fR\&\f(CWdiskseekd\fR simulates this effect +by seeking the drive periodically. If it is called as \fR\&\f(CWdiskseek\fR, +the drive is seeked only once. +.PP +.SH Options +.PP +The syntax for \fR\&\f(CWdiskseekd\fR is as follows: + +.nf +.ft 3 +.in +0.3i +\&\fR\&\f(CWdiskseekd [\fR\&\f(CW-d \fIdrive\fR\&\f(CW] [\fR\&\f(CW-i \fIinterval\fR\&\f(CW] [\fR\&\f(CW-p \fIpidfile\fR\&\f(CW] +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +\&\fR\&\f(CW-d\ \fIdrive\fR\&\f(CW\fR\ +Selects the drive to seek. By default, drive 0 (\fR\&\f(CW\(if/dev/fd0\(is\fR) is seeked. +.TP +\&\fR\&\f(CW-i\ \fIinterval\fR\&\f(CW\fR\ +Selects the cleaning interval, in seconds. If the interval is 0, a +single seek is done. This is useful when calling diskseek from a +crontab. The default is 1000 seconds (about 16 minutes) for +\&\fR\&\f(CWdiskseekd\fR and 0 for \fR\&\f(CWdiskseek\fR. +.TP +\&\fR\&\f(CW-p\ \fIpidfile\fR\&\f(CW\fR\ +Stores the process id of the diskseekd daemon into \fIpidfile\fR instead +of the default \fR\&\f(CW\(if/var/run/diskseekd.pid\(is\fR. +.PP +.SH Bugs +.TP +1.\ +Other aspects of Messy Dos' flakiness are not simulated. +.TP +2.\ +This section lacks a few smileys. +.SH See Also +Fdutils' texinfo doc diff --git a/doc/diskseekd.texi b/doc/diskseekd.texi new file mode 100644 index 0000000..85a5633 --- /dev/null +++ b/doc/diskseekd.texi @@ -0,0 +1,47 @@ +@node diskseekd, fdmount, diskd, Commands +@section diskseekd +@pindex diskseekd +@cindex dust (shaking it off from a drive) +@cindex shaking off dust from a drive + +Several people have noticed that Linux has a bad tendency of killing +floppy drives. These failures remained completely mysterious, until +somebody noticed that they were due to huge layers of dust accumulating +in the floppy drives. This cannot happen under Messy Dos, because this +excuse for an operating system is so unstable that it crashes roughly +every 20 minutes (actually less if you are running Windows). When +rebooting, the BIOS seeks the drive, and by doing this, it shakes the +dust out of the drive mechanism. @code{diskseekd} simulates this effect +by seeking the drive periodically. If it is called as @code{diskseek}, +the drive is seeked only once. + +@subsection Options + +The syntax for @code{diskseekd} is as follows: +@example +@code{diskseekd} [@code{-d} @var{drive}] [@code{-i} @var{interval}] [@code{-p} @var{pidfile}] +@end example + +@table @code +@item -d @var{drive} +Selects the drive to seek. By default, drive 0 (@file{/dev/fd0}) is seeked. + +@item -i @var{interval} +Selects the cleaning interval, in seconds. If the interval is 0, a +single seek is done. This is useful when calling diskseek from a +crontab. The default is 1000 seconds (about 16 minutes) for +@code{diskseekd} and 0 for @code{diskseek}. + +@item -p @var{pidfile} +Stores the process id of the diskseekd daemon into @var{pidfile} instead +of the default @file{/var/run/diskseekd.pid}. +@end table + +@subsection Bugs + +@enumerate +@item +Other aspects of Messy Dos' flakiness are not simulated. +@item +This section lacks a few smileys. +@end enumerate diff --git a/doc/driveprm.texi b/doc/driveprm.texi new file mode 100644 index 0000000..a3f376c --- /dev/null +++ b/doc/driveprm.texi @@ -0,0 +1,127 @@ +@node Drive descriptions, Extended formats, Media description, Top +@chapter Drive descriptions + +Unlike earlyer version, fdutils-5.0 separates drive descriptions and +media description. For more details on this separation, +@pxref{Introduction}. Drive descriptions are used to describe the +hardware characteristics of a drive, such as their maximal density, +their rotation speed, their form factor, etc. + +@menu +* Syntax of a drive description :: What to put into a drive description +* Drive definition file :: Where drive definitions are stored +@end menu + +@node Syntax of a drive description, Drive definition file, Drive descriptions, Drive descriptions +@section Syntax + +A drive description is a series of @emph{variable=value} and +@emph{selector} clauses. + +@menu +* Density :: The maximal available density on the drive +* Form factor :: Whether this drive is a 3 1/2", 5 1/4" or 8" drive +* Cmos code :: Sums up both density and form factor +* Other parameters :: Rotation speed and tracks per inch +@end menu + +@node Density, Form factor, Syntax of a drive description, Syntax of a drive description +@subsection Density + +The density of a drive is the highest media density that it supports. +Density is one of @code{sd}, @code{dd}, @code{qd}, @code{hd} or +@code{ed}. Usually, you do not need to specify this parameter, as it +can be derived from the drives CMOS code. + + +@node Form factor, Cmos code, Density, Syntax of a drive description +@subsection Form factor + +The form factor of a drive describes the physical dimensions of the +media it accepts. It is one of @code{3.5}, @code{5.25} or @code{8}. +Usually, you do not need to specify this parameter, as it can be derived +from the drives CMOS code. + +@node Cmos code, Other parameters, Form factor, Syntax of a drive description +@subsection Cmos code + +The PC Bios already knows on its own about the most common drive types. +These are named by an integer from 1 to 6, according to the following +table. +@example +0 no drive installed +1 5.25 DD +2 5.25 HD +3 3.5 DD +4 3.5 HD +5 3.5 ED +6 3.5 ED +@end example + +As you see 3.5 ED drives have two possible codes. Some BIOSes use 5, +others use 6. The reason for this is that initially 5 was intended for +floppy tape drives, and only 6 was for 3.5 ED drives. However, some +BIOS manufacturers didn't know about this convention, and used 5 for the +then "new" 3.5 ED drives. + +Usually, you do not need to specify this parameter, as it can be read +from the physical CMOS of your PC. This parameter may be useful if your +BIOS does not store the drive's CMOS code at the expected place, or if +you have more than two drives. + +@node Other parameters, , Cmos code, Syntax of a drive description +@subsection Other parameters + +@table @code +@item deviation=@var{deviation} +Tells how much more/less raw capacity the drive has than the standard. +Due to slightly different rotation speeds @footnote{drives do not always +rotate at exactly 5 or 6 rotations per second, but some may be slightly +faster or slightly slower than spec} and to slightly different data +transfer rates, the raw capacity per track can vary slightly. For +normal formats, these small deviations from the prescribed raw capacity +is not harmful, as these have plenty of safety margins built in. +However, the new extra capacity formats are affected by this, as they +try to squeeze every available raw byte out of the disk. + +Deviation is expressed in ppm. Positive values mean a higher raw +capacity than normal, and negative values mean a lower raw capacity than +normal. The deviation can be measured using the @code{floppymeter} +program. + +@item rpm=@var{rotation_speed} + +Prescribed rotation speed of the drive, expressed in rotations per +minute. This is 360 for 5 1/4 HD drives, and 300 for all other commonly +available drive types. Usually, you do not need to specify this +parameter, as it can be derived from the drive's CMOS code. It is +useful however for single density drives or other drives not commonly +found on a PC. Usually, you do not to specify this parameter, as it can +be derived from the drive's form factor and maximal density. + +@item tpi=@var{cylinder_density} + +This parameter is only meaningful for 5 1/4 drives. It expresses +whether the drive is able to use 80 tracks (@code{tpi=96}) or only 40 +(@code{tpi=48}). Usually, you do not to specify this parameter, as it +can be derived from the drive's maximal density: quad density and high +density drives are 96 tpi, whereas double density drives are 48 tpi. + +@end table + + +@node Drive definition file, , Syntax of a drive description, Drive descriptions +@section The drive definition file in @file{/usr/local/etc/fddriveprm} + +@file{/usr/local/etc/fddriveprm} @footnote{The actual location of this +file depends on the value of the @code{sysconfdir} compile time +configuration variable (@pxref{Compile-time configuration} for details)} +contains a dictionary of commonly used media descriptions. Each +description is identified by a name, which can then be used by setfdprm +or superformat to refer to it, instead of an explicit description. + +Each definition starts with @code{"drive}@emph{number}@code{":}, +followed by the actual description. Definitions may be spread over +several lines, for better readability. The file may contain comments, +which start with # and stop at the end of the line. + diff --git a/src/fd.4 b/doc/fd.4 similarity index 97% rename from src/fd.4 rename to doc/fd.4 index 7af92d4..2b85f65 100644 --- a/src/fd.4 +++ b/doc/fd.4 @@ -2,7 +2,7 @@ .\"{{{}}} .\"{{{ Notes .\" Copyright (c) 1993 Michael Haardt (michael@cantor.informatik.rwth-aachen.de) -.\" and 1994,1995 Alain Knaff (Alain.Knaff@inrialpes.fr) +.\" and 1994,1995, 1997 Alain Knaff (Alain.Knaff@poboxes.com) .\" .\" This is free documentation; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License as @@ -25,7 +25,7 @@ .\" USA. .\"}}} .\"{{{ Title -.TH FD 4 "January 29, 1995" "Linux" "Special files" +.TH FD 4 "March 15, 1997" "Linux" "Special files" .\"}}} .\"{{{ Name .SH NAME @@ -252,7 +252,7 @@ be common with older 8 inch floppies. .\"}}} .\"{{{ Authors .SH AUTHORS -Alain Knaff (Alain.Knaff@inrialpes.fr), David Niemi +Alain Knaff (Alain.Knaff@poboxes.com), David Niemi (niemidc@erols.com), Bill Broadhurst (bbroad@netcom.com). .\"}}} .\"{{{ See also @@ -263,5 +263,5 @@ Alain Knaff (Alain.Knaff@inrialpes.fr), David Niemi .BR getfdprm (1), .BR superformat (1), .BR mount (8), -.BR setfdprm (8) +.BR setfdprm (1) .\"}}} diff --git a/doc/fdmount.1 b/doc/fdmount.1 new file mode 100644 index 0000000..1c9da9c --- /dev/null +++ b/doc/fdmount.1 @@ -0,0 +1,339 @@ +.TH fdmount 1 "19apr97" fdutils-5.0 +.SH Name +fdmount - Floppy disk mount utility +'\" t +.de TQ +.br +.ns +.TP \\$1 +.. + +.tr \(is' +.tr \(if` +.tr \(pd" + +.SH Note +This manpage has been automatically generated from fdutils's texinfo +documentation. However, this process is only approximative, and some +items, such as crossreferences, footnotes and indices are lost in this +translation process. Indeed, this items have no appropriate +representation in the manpage format. Moreover, only the items specific +to each command have been translated, and the general information about +fdutils has been dropped in the manpage version. Thus I strongly advise +you to use the original texinfo doc. +.TP +* \ \ +To generate a printable copy from the texinfo doc, run the following +commands: + +.nf +.ft 3 +.in +0.3i + ./configure; make dvi; dvips fdutils.dvi +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +* \ \ +To generate a html copy, run: + +.nf +.ft 3 +.in +0.3i + ./configure; make html +.fi +.in -0.3i +.ft R +.lp + +\&\fRA premade html can be found at: +\&\fR\&\f(CW\(ifhttp://linux.wauug.org/pub/knaff/fdutils\(is\fR +.TP +* \ \ +To generate an info copy (browsable using emacs' info mode), run: + +.nf +.ft 3 +.in +0.3i + ./configure; make info +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The texinfo doc looks most pretty when printed or as html. Indeed, in +the info version certain examples are difficult to read due to the +quoting conventions used in info. +.SH Description +.iX "p fdmount" +.iX "p fdmountd" +.iX "p fdlist" +.iX "p fdumount" +.iX "c automounting" +.PP + +.nf +.ft 3 +.in +0.3i +\&\fR\&\f(CWfdmount [\fR\&\f(CW-l] [\fR\&\f(CW--list] [\fR\&\f(CW-d] [\fR\&\f(CW--daemon] [\fR\&\f(CW--detach] +[\fR\&\f(CW-i \fIinterval\fR\&\f(CW] [\fR\&\f(CW--interval \fIinterval\fR\&\f(CW] [\fR\&\f(CW-o \fImount-options\fR\&\f(CW] +[\fR\&\f(CW-r] [\fR\&\f(CW-readonly] [\fR\&\f(CW-s] [\fR\&\f(CW--sync] [\fR\&\f(CW--nosync] [\fR\&\f(CW--nodev] +[\fR\&\f(CW--nosuid] [\fR\&\f(CW--noexec] [\fR\&\f(CW-f] [\fR\&\f(CW--force] [\fR\&\f(CW-h] [\fR\&\f(CW--help] +[\fIdrivename\fR\&\f(CW] [\fImountpoint\fR\&\f(CW [\fImountpoint\fR\&\f(CW]] +\&\& +\&\fR\&\f(CWfdumount [\fR\&\f(CW-f] [\fR\&\f(CW--force] [\fIdrivename\fR\&\f(CW] +\&\& +\&\fR\&\f(CWfdlist +\&\& +\&\fR\&\f(CWfdmountd [\fR\&\f(CW-i \fIinterval\fR\&\f(CW] [\fR\&\f(CW--interval \fIinterval\fR\&\f(CW] [\fR\&\f(CW-r] +[\fR\&\f(CW-readonly] [\fR\&\f(CW-s] [\fR\&\f(CW--sync] [\fR\&\f(CW--nosync] [\fR\&\f(CW--nodev] +[\fR\&\f(CW--nosuid] [\fR\&\f(CW--noexec] [\fR\&\f(CW--help] [\fIdrivename\fR\&\f(CW] [\fImountpoint\fR\&\f(CW]] +\&\& +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The \fR\&\f(CWfdmount\fR program mounts a floppy disk in the specified +drive. It tries to figure out the exact format and filesystem type of +the disk from data in the disk's boot sector or super block and the +auto-detected track layout. +.PP +Currently, fdmount supports the filesystems \fR\&\f(CWminix\fR, \fR\&\f(CWext\fR, +\&\fR\&\f(CWext2\fR, \fR\&\f(CWxia\fR, and \fR\&\f(CWmsdos\fR, and includes special support +for disks formatted by the \fR\&\f(CW2M\fR utility for MS-DOS. +.PP +It also checks whether the disk is write protected, in which case +it is mounted read-only. +.PP +The symbolic \fIdrivename\fR is (currently) one of \fR\&\f(CW\(iffd[0-7]\(is\fR, +corresponding to the special device files \fR\&\f(CW\(if/dev/fd[0-7]\(is\fR. If +\&\fIdrivename\fR is not specified, \fR\&\f(CW\(iffd0\(is\fR is assumed. +.PP +The disk is mounted on the directory \fImountpoint\fR, if specified, or +on \fR\&\f(CW\(if/fd[0-7]\(is\fR. In either case, the mount point must be an +existing, writable directory. +.PP +.SH Options +.IP +.TP +\&\fR\&\f(CW-l\ \fI--list\fR\&\f(CW\fR\ +List all known drives with their symbolic name, type, and mount +status. +.TP +\&\fR\&\f(CW-d\ \fI--daemon\fR\&\f(CW\fR\ +Run in daemon mode (see below). +.TP +\&\fR\&\f(CW--detach\fR\ +Runs daemon in background, and detaches it from its tty. Messages +produced after the fork are logged to syslog. +.TP +\&\fR\&\f(CW-p\ \fIfile\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--pidfile\ \fIfile\fR\&\f(CW\fR +.IP +Dumps the process id of the daemon to +\&\fIfile\fR. This makes killing the daemon easier: +\&\fR\&\f(CWkill -9 `cat \fIfile\fR\&\f(CW`\fR +.TP +\&\fR\&\f(CW-i\ \fIinterval\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--interval\ \fIinterval\fR\&\f(CW\fR +Set the polling interval for daemon mode. The unit for \fIinterval\fR is +0.1 seconds, the default value is 10 (i.e. 1 second). +.TP +\&\fR\&\f(CW-o\ \fIoptions\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--options\ \fIoptions\fR\&\f(CW\fR +Sets filesystem-specific options. So far, these are only available for +DOS and Ext2 disks. The following DOS options are supported: +\&\fR\&\f(CWcheck\fR, \fR\&\f(CWconv\fR, \fR\&\f(CWdotsOK\fR, \fR\&\f(CWdebug\fR, \fR\&\f(CWfat\fR, +\&\fR\&\f(CWquiet\fR, \fR\&\f(CWblocksize\fR. The following Ext2 options are +supported: \fR\&\f(CWcheck\fR, \fR\&\f(CWerrors\fR, \fR\&\f(CWgrpid\fR, \fR\&\f(CWbsdgroups\fR, +\&\fR\&\f(CWnogrpid\fR, \fR\&\f(CWsysvgroups\fR, \fR\&\f(CWbsddf\fR, \fR\&\f(CWminixdf\fR, +\&\fR\&\f(CWresgid\fR, \fR\&\f(CWdebug\fR, \fR\&\f(CWnocheck\fR. When running as a daemon, +options not applying to the disk that is inserted (because of its +filesystem type) are not passed to mount. +.TP +\&\fR\&\f(CW-r\ \fI--readonly\fR\&\f(CW\fR\ +Mount the disk read-only. This is automatically assumed if the +disk is write protected. +.TP +\&\fR\&\f(CW-s\ \fI--sync\fR\&\f(CW\fR\ +Mount with the \fR\&\f(CWSYNC\fR option. +.TP +\&\fR\&\f(CW--nosync\fR\ +Mounts without the \fR\&\f(CWSYNC\fR option, even when running as daemon. +.TP +\&\fR\&\f(CW--nodev\fR\ +Mount with the \fR\&\f(CWNODEV\fR option. Ignored for \fR\&\f(CWmsdos\fR +filesystems, otherwise always set for non-root users. +.TP +\&\fR\&\f(CW--nosuid\fR\ +Mount with the \fR\&\f(CWNOSUID\fR option. Ignored for \fR\&\f(CWmsdos\fR +filesystems, otherwise always set for non-root users. +.TP +\&\fR\&\f(CW--noexec\fR\ +Mount with the \fR\&\f(CWNOEXEC\fR option. +.TP +\&\fR\&\f(CW-f\ \fI--force\fR\&\f(CW\fR\ +Attempt a mount or unmount operation even \fR\&\f(CW\(if/etc/mtab\(is\fR says that +the drive is already mounted, or not mounted, respectively. +This option is useful if \fR\&\f(CW\(if/etc/mtab\(is\fR got out of sync with the +actual state for some reason. +.TP +\&\fR\&\f(CW-h\ \fI--help\fR\&\f(CW\fR\ +Show short parameter description +.PP +.SH Security +.PP +When mounting on the default mount point, the mount points' owner is set +to the current user, and the access flags according to the user's umask. +For a specified mountpoint, owner and permissions are left +unchanged. Default mount points are called \fR\&\f(CW/fd0\fR, \fR\&\f(CW/fd1\fR, +\&\&... , \fR\&\f(CW/fd7\fR. +.PP +The user running fdmount must have read access to the floppy device for +read only mounts, and read/write access for read/write mounts. +.PP +Fdmount can be run suid root, allowing users to mount floppy +disks. The following restrictions are placed upon non-root +users: +.TP +* \ \ +If a mountpoint is specified explicitly, it must be owned by the user. +.TP +* \ \ +A user may only unmount a disk if the mount point is owned by the user, +or if it the disk has been mounted by the same user. +.TP +* \ \ +Non-msdos disks are automatically mounted with the \fR\&\f(CWnodev\fR and +\&\fR\&\f(CWnosuid\fR flags set. +.PP +However, \fBdo not rely on fdmount being secure at the moment\fR. +.PP +.SH Daemon\ mode +.PP +In daemon mode, the specified drive is periodically checked and if a +disk is inserted, it is automatically mounted. +.PP +When the disk is removed, it is automatically unmounted. However, it is +recommended to unmount the disk manually \fIbefore\fR removing it. In +order to limit corruption, disks are mounted with the SYNC option when +running in daemon mode, unless the \fR\&\f(CW--nosync\fR flag is given. +.PP +Note that this mode has some potential drawbacks: +.TP +* \ \ +Some floppy drives have to move the drive head physically in order to +reset the disk change signal. It is strongly recommended not to use +daemon mode with these drives. See section floppycontrol for details. +.TP +* \ \ +If a disk does not contain a filesystem (e.g. a tar archive), +the mount attempt may slow down initial access. +.TP +* \ \ +As fdmount cannot identify the user trying to use the disk drive, +there is no way to protect privacy. Disks are always mounted with +public access permissions set. +.PP +.SH Diagnostics +.IP +.TP +\&\fR\&\f(CWerror\ opening\ device\ \fIname\fR\&\f(CW\fR\ +.TP +\&\fR\&\f(CWerror\ reading\ boot/super\ block\fR\ +fdmount failed to read the first 1K of the disk. The disk might be +damaged, unformatted, or it may have a format wich is unsupported by the +FDC or the Linux kernel. +.TP +\&\fR\&\f(CWunknown\ filesystem\ type\fR\ +No magic number of any of the supported filesystems (see above) +could be identified. +.TP +\&\fR\&\f(CWsorry,\ can\(fmt\ figure\ out\ format\ (\fIfs\fR\&\f(CW\ filesystem)\fR\ +The size of the filesystem on the disk is incompatible with +the track layout detected by the kernel and an integer number of +tracks. This may occur if the filesystem uses only part of the +disk, or the track layout was detected incorrectly by the kernel. +.TP +\&\fR\&\f(CWfailed\ to\ mount\ \fIfs>\ >$outfile +echo .TH\ $command\ 1\ \"$date\" $package >$outfile +echo .SH Name >>$outfile +grep -i $command cmdname >>$outfile +#echo ".SH Description" >>$outfile + + +# -e "1,/^@node $command/d" \ +# -e "/^@node [^,]*, [^,]*, $command, Commands$/,/^@bye/d" \ +# -e "/^@node [^,]*, [^,]*, Commands/,/^@bye/d" \ + +cat man-warning.texi $texifile | + sed \ + -e 's/^@section/@chapter/' \ + -e 's/^@subs/@s/' \ + -e 's/^@chapter.*$/@chapter Description/' \ + -e 's/^@section/@chapter/' \ + -e 's/^@subs/@s/' \ + -e 's/^@c xMANoptions/@chapter Options/' \ + -e "s/^@c MAN/@MAN/" | + texi2roff -ma | + sed -f strip-pp.sed >>$outfile +echo ".SH See Also" >>$outfile +echo "Fdutils' texinfo doc" >>$outfile +} + + +extract diskd +extract diskseekd +extract fdmount +extract fdrawcmd +extract floppycontrol +extract floppymeter +extract getfdprm +extract makefloppies +extract setfdprm +extract superformat +extract xdfcopy diff --git a/doc/moredata.texi b/doc/moredata.texi new file mode 100644 index 0000000..e85119d --- /dev/null +++ b/doc/moredata.texi @@ -0,0 +1,544 @@ +@node Extended formats, Autodetection, Drive descriptions, Top +@chapter Storing more data on a floppy disk +@cindex extended formats +@cindex high capacity formats +@cindex formatting disks + +This section describes the techniques that are used by Linux' floppy +driver and superformat to store more data than usual on a floppy disk. + +Each section contains a description of the technique used, lists the +usages of the disks formatted using this technique (whether they are +bootable, whether they are accessible on MS-DOS and for which kind of +filesystems they are suitable) and finishes with a table listing the +most interesting formats which can be obtained by the described +technique. + +The table lists for each format the media type it is used for, the total +capacity which can be achieved, the throughput for large reads or writes +and the media description for these disks. This description can the be +used with superformat to make such disks, or with setfdprm to configure +the drive to read/write to them. Some formats (the XDF and XXDF +formats) cannot be accessed directly, and thus there is no media +description for them. For these, we indicate a formatting command used +to make these disks. The formatting command assume that the disk is in +the first drive (@code{/dev/fd0}). Substitute @code{/dev/fd1} if you +want to format XDF or XXDF disks in the second drive. + + +@menu +* More sectors:: Using more sectors per track by packing them + close together +* Interleave:: Use interleave to pack the sectors even closer + together +* Sector skewing:: Speeding up multi-track reads +* More cylinders:: Use up to 83 cylinders +* Larger sectors:: Minimize per byte overhead by using larger sectors +* Mixed size sectors:: Minimize slack by using several sector sizes + in a same track +* Smart use of the dtr:: How to get more out of your disk by playing games + with the data transfer rate +* 2M:: Make autodetection easyer by using a readable + first track +* XDF:: Fast high capacity formats +* XXDF:: Fast formats with even higher capacity +@end menu + +@node More sectors, Interleave, Extended formats, Extended formats +@section More sectors per cylinder +@cindex more sectors per track +@cindex sectors per track + +The official formats used by MS-DOS and other operating systems are +generally very conservative. It is often possible to fit more sectors +on each track than the default by simply reducing the size of the gap +between tracks and/or the size of the leftover space at the end of the +disk. + +For example, a 3 1/2 disk has a raw track capacity of around 12500 +bytes. The raw capacity of a floppy disk is not rigorously constant +among different boxes, because both the data transfer rate of the floppy +controller, and the rotation speed of the drive are subject to small +variations. In order to account for these, we have to use a safety +margin, and we only use up 12450 bytes of the 12500 bytes that are +theoretically available. + +A sector contains a header of 62 bytes and 512 bytes of data. A +minimum gap of about 45 bytes should be used in order to leave enough +time to the floppy controller to "rest" between reading two successive +sectors. In total, 619 bytes per sector are thus needed. + +This shows that we can fit 12450 / 619 = 20 sectors per track. + +@strong{Usage:} These disks are bootable by Lilo, and can be read in +MS-DOS using numerous shareware utilities such as @code{vgacopy}, or +@code{fdformat} or many others. Check your nearest Simtel mirror. + +With dos6, you don't need any add-on utilities, just put the following +line in your @code{config.sys}: + +@example +drivparm=/d:0 /f:7 /h:2 /s:21 /t:82 + ^ ^ \______________/ + | | | + drive number | max geometry + | + drive type, consult the dos help system for details +@end example + +@strong{Interesting Formats:} + +@example +density tot. cap. throughput media description +5 1/4 DD 800KB 30KB/s dd sect=10 +3 1/2 DD 800KB 25KB/s dd sect=10 +3 1/2 HD 1600KB 50KB/s hd sect=21 +3 1/2 ED 3200KB 100KB/s ed sect=42 +@end example + +The @code{--dd}, @code{--hd} and @code{--ed} options describe the +density of the media to be formatted (double density, high density or +extra density). + +The @code{-s} options describes the number of 512 byte sectors per +track. + +@node Interleave, Sector skewing, More sectors, Extended formats +@section Using interleave +@cindex interleave + +After having read a sector, the floppy controller needs to "rest" for a +short time. This time is used to compute checksums, to reset internal +circuitry, etc. During this time, the floppy disk continues to rotate, +and the "rest" time thusly translates to a certain minimal gap size. If +a smaller gap is used, the next sector header flies by the read-write +head before the floppy controller is ready again to pick up the data. +Thus, it has to wait until the next disk rotation until that sector +comes back again. This leads to an unacceptably low throughput, as now +the system can only read one sector per rotation instead of all sectors +in one rotation. If we want to use smaller gaps, we have thus to use +@emph{sector interleaving}. This technique consists in arranging the +sectors in a way such that the next logical sector does not immediately +follow the current sector, but instead another sector is inserted +between two successive sectors. Instead of having the following order: +@example +1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 +@end example + +we would use the following order: + +@example +1,12,2,13,3,14,4,15,5,16,6,17,7,18,8,19,9,20,10,21,11, +@end example + +This new order allows the floppy controller to rest during the whole +time that sector 12 flies by between reading sector 1 and 2. This +technique still cuts throughput in half, because two rotations are +needed (one for reading sectors 1 to 11, and the second to read sectors +12 to 21). However, this is far better than the 21 rotations which +would be needed without interleave. + +This technique allows us to use a gap size of just 1, and thus fit 21 +sectors on one track. + + +@strong{Usage:} Once formatted, interleaved disks can be used in a +similar way to disks which have simply more tracks. They can be +accessed using @code{vgacopy} in Dos, you can boot from them using Lilo, +and you may install any filesystem on them. + + +@strong{Interesting Formats:} + +@example +density tot. cap. throughput media description +5 1/4 HD 1440KB 27KB/s hd sect=18 +3 1/2 HD 1680KB 26KB/s hd sect=21 +3 1/2 ED 3360KB 52KB/s ed sect=42 +@end example + +You don't need to tell @code{superformat} to use interleaving, it +figures out by itself when interleaving is needed. You don't need to +tell @code{setfdprm} either that a disk is interleaved, as this +information is not needed to read the disk + +@node Sector skewing, More cylinders, Interleave, Extended formats +@section Sector skewing +@cindex sector skewing +@cindex skewing + +Sector skewing is a technique that allows bigger throughputs. It does +not increase the capacity of the disk. Sector skewing is only relevant +during formatting. Sector skewed disks are indistinguishable from +non-skewed disk by software, except for a different throughput. + +The principle of sector skewing is to start each track a little bit +later than the previous one, i.e. the first logical sector of the second +cylinder would for exemple lie near the sixth logical sector of the +first cylinder. This is done in order to account for the time needed to +seek the drive head from the first cylinder to the second. Without +skewing, the first sector would already have passed the drive head after +seeking, and we would need to wait for a whole rotation for it to come +back again. + +By default, superformat applies appropriate skewing to all formats, and +the listed throughput values refer to skewed disks. It is possible to +provide different values for the skew using the @code{--head_skew} and +@code{--track_skew} parameters. @code{head_skew} refers to the offset +between both sides of the same cylinder, and @code{track_skew} refers to +the offset of two consecutive cylinders. 0 means no skew. + +@node More cylinders, Larger sectors, Sector skewing, Extended formats +@section More Cylinders +@cindex more cylinder +@cindex cylinders +@cindex tracks +@cindex 83 cylinders + +Many nominally 40-cylinders or 80-cylinder drives are capable of more +cylinders, usually 41 and 83 respectively. These can be used to get +extra capacity. However, not all drives can seek to these unofficial +extra cylinders, and even on drives which can, these extra cylinders +tend to be less reliable. + +@strong{WARNING}: Although most drives are able to use 83 cylinders, +some may not. If your drive is making strange noises while accessing +these tracks. + + +Although most drives support more than 80 tracks, I have heard rumors +that some do not, and repeatedly trying to read beyond track 80 might be +damaging to them. In order to know wether your drive supports more than +eighty tracks, first set the number of allowed tracks to 82. (using +@code{floppycontrol --cylinders 82 -d }@var{drive}) + +Then format a disk with a 82 track format (for example +@file{/dev/fd0H1722}), and copy on or several files to the disk until +there are less than 18 KB of free space on the disk. Then eject and +reinsert the disk, and compare the files on the disk with the +originals. If they are the same, your drive does support 82 tracks. If +so, you might want to go further and try with 83 cylinders: +@file{/dev/fd0H1743}) +This single experience should not damage the drive, although repeating +it many times may be dangerous. + +If you do have a drive which supports more than 80 cylinders, you have +to call @code{floppycontrol --cylinders 82 @var{drive}} before you can +use the extra cylinders. You may put this line into your +@file{/etc/rc.local}, so that the driver is automatically configured for +the addition cylinder after each boot. + +If on the other hand your drive doesn't support more than 80 tracks, +you should remove the entries for formats 13-19 from your @file{/dev} +directory after running @code{MAKEFLOPPIES}, and you should call +@code{floppycontrol --cylinder 80 @var{drive}} from your +@file{/etc/rc.local} (or @code{floppycontrol --cylinder 40 @var{drive}} +for 5 1/4 DD drives). + +By default, 83 cylinder are enabled for any high density and double +density drives. 3 1/2 double density drives have 80 cylinders enables, +and 5 1/4 double density drives have 40 enabled. + +@strong{Usage:} These disks can be booted from using LILO, and can be +accessed in MS-DOS using @code{vgacopy}. + + +@strong{Interesting Formats:} + +All formats presented in the two previous sections may be amended to use +83 cylinders instead of 80. Just add the @code{cyl=83} to the format +description for superformat. Using more cylinders has no effect on the +throughput. + +@example +density tot. cap. throughput media description +5 1/4 HD 1494KB 27KB/s hd sect=18 cyl=83 +3 1/2 HD 1743KB 26KB/s hd sect=21 cyl=83 +3 1/2 ED 3486KB 52KB/s ed sect=42 cyl=83 +@end example + +@node Larger sectors, Mixed size sectors, More cylinders, Extended formats +@section Larger sectors +@cindex larger sectors + +The floppy controller allows us to use larger sectors than the default +size of 512 bytes. All powers of two larger than 256 bytes are +acceptable sector sizes. Large sectors have the same header and gap +sizes than smaller sectors, thus the overhead per byte of data is +smaller. A little calculation shows this: A 1024 byte sector takes up +at least 1024+62+1 = 1087 raw bytes. You can fit eleven sectors of this +size into a 12450 byte track. This represents 11KB of data per track, +versus the 10.5KB only that can be achieved with 512 byte sectors. + +@strong{Usage:} MS-DOS and other operating systems cannot normally read +these formats. Lilo is not yet able to boot from this kind of disks. + +@strong{Performance:} When any portion of one of these larger sectors is +read, the entire sector must be read. When any portion of such a sector +is written to, the entire sector must be read, and then written back +with just the necessary portion modified. Both of these circumstances +can entail worse performance than are listed in this table for small +reads and (especially) small writes. + +@strong{Interesting Formats:} + +@example +density tot. cap. throughput media description +5 1/4 HD 1440KB 30KB/s dd sect=9 ssize=1KB +3 1/2 HD 1760KB 55KB/s hd sect=11 ssize=1KB +3 1/2 ED 3520KB 110KB/s ed sect=11 ssize=2KB +@end example + +The @code{ssize} parameter of the format description indicates the +sector size to be used. + +@node Mixed size sectors, Smart use of the dtr, Larger sectors, Extended formats +@section Mixed sector size (MSS) formats +@cindex MSS +@cindex 2M (mixed sector sizes) +@cindex XDF (mixed sector sizes) + +Using larger sectors has the disadvantage that the granularity is +larger. For example, when using 4096 byte sectors, there is enough +space to fit two sectors in a track of 12450 bytes raw capacity, but not +three. However, the two sector format leaves plenty of space available +(4132 bytes), in which smaller sectors would fit. For example, these +4142 raw bytes can be put to good use by filling them with a 2 KB sector +(2048+62), plus an 1 KB sector (1024+62) and a 512 byte sector, leaving +still 362 bytes for gaps. + +Mixed sector size formats take advantage of this by using sectors of +several different sizes on a same track. This way, a maximum capacity +of 12KB per track, distributed in one 8k sector and one 4k sector can be +achieved. + + +@strong{Usage:} There is no known MS-DOS utility which can read basic +MSS disks. Lilo is not yet able to boot from this kind of disks. + +@strong{Performance:} As any format with larger sectors, the performance +for small reads and writes is worse due to the larger granularity. + + +@strong{Interesting Formats:} + +@example +density tot. cap. throughput media description +3 1/2 DD 880KB 28KB/s hd tracksize=11b mss +5 1/4 HD 1600KB 30KB/s hd tracksize=10KB mss +3 1/2 DD 880KB 28KB/s hd tracksize=11b mss +3 1/2 HD 1840KB 28KB/s hd tracksize=23b mss +3 1/2 HD 1920KB 30KB/s hd tracksize=12KB mss +3 1/2 ED 3680KB 56KB/s ed tracksize=23KB mss +3 1/2 ED 3840KB 60KB/s ed tracksize=24KB mss +@end example + +For MSS formats, the system figures out the most efficient repartition +of sector sizes by itself. You do not need to describe the number of +sectors and their size. For MSS disks, the capacity of one track is +described directly, using the @code{tracksize} parameter. + +The @code{1920KB} and @code{3840KB} formats may be unreliable on some +computers. + + +@node Smart use of the dtr, 2M, Mixed size sectors, Extended formats +@section Smart use of the data transfer rate + +Due to different drive rotations speeds, 5 1/4 double density disks and +3 1/2 double density disks are accessed using different raw data +transfer rates (300 kb/s for the faster spinning 5 1/4 disks, and only +250 kb/s for the slower spinning 3 1/2 disks). The method described in +this section consists in using the faster data transfer rate intended +for 5 1/4 disks on 3 1/2 disks, and thus boost the raw capacity per +track of these disks. This is possible because 300 kb/s is still low +enough not to excede the specification of the disk surface of a double +density disk (which 500 kb/s would). + + +@strong{Usage: this method is only available for 3 1/2 double density +disks. The disk obtained cannot be booted from by LILO, and are +inaccessible from MS-DOS.} + +The following table shows the media description for a format using this +method in conjuncion with the previous methods: +@example +density tot. cap. throughput media description +3 1/2 DD 1120KB 17KB/s qd tracksize=7KB mss +@end example + +We use the @code{QD} density selector to describe this particular DTR +set-up, although the acronym @code{QD} is already taken to name 96tpi +double density 5 1/4 disks. However, as this dtr trickery is only +meaningful for 3 1/2, we hope that there will be no ambiguity. + + +@node 2M, XDF, Smart use of the dtr, Extended formats +@section 2M formats +@cindex MSS (2M) +@cindex Mixed sector size formats (2M) +@cindex 2M + +2M formats use a standard geometry (18 normal sized sectors) on the +first side of the first cylinder, and an MSS geometry on the rest of the +disk. They are inspired for Ciriaco Garcia de Celis' 2M utility for +MS-DOS. + +The advantage of 2M disks over simple MSS disks is twofold: +@itemize @bullet +@item +They can be accessed from DOS +@item +They do not need an autodetect entry, as the boot sector is readable +using a standard geometry. Mtools can then use the information +contained in the boot sector to configure the floppy driver to read the +rest of the disk. +@end itemize + + +Although 2m disk have less sectors on the first track than on the +others, the Linux floppy driver, and 2M's low level floppy access +routines pretend that it contains the same number of sectors. The +missing sectors are called phantom sectors. Writes to these sectors are +ignored, and reads return random data. In order to make up for this, 2M +and mtools pretend that there is a duplicate FAT in the missing sectors, +which is simulated by using data from the first (real) FAT. Thus 2M +disks work fine for their intended purpose, which is to hold an MS-DOS +filesystem. @strong{Never use 2M disks for anything other than a MS-DOS +filesystem. For example, never make an ext2 filesystem on a 2M disk. +If you need a high capacity ext2 filesystem (or minix fs, raw tar or +cpio archive), use the corresponding MSS format instead} + + +@strong{Usage:} 2M disks are not bootable by LILO. They can be accessed +in MS-DOS using the 2M utility. 2M can be found at +ftp://FTP.Coast.NET/SimTel/msdos/diskutil/2m30.zip or at any other +simtel mirror. @strong{2M disks are not suitable for non MS-DOS +filesystems}. + +@strong{Performance:} Just as with MSS disks, performance is bad for +small reads and writes. + +To describe a 2M format, add the keyword @code{2m} to its media +description: +@example +density tot. cap. throughput media description +3 1/2 HD 1840KB 28KB/s hd tracksize=23b mss 2m +@end example + + + +@node XDF, XXDF, 2M, Extended formats +@section XDF formats +@cindex MSS (XDF) +@cindex Mixed sector size formats (XDF) +@cindex XDF +@cindex OS/2 (XDF) + +XDF is the format used for OS/2 installation floppies. + +Just like 2M, XDF uses mixed sector sizes on "generic tracks". The +first cylinder uses 512 byte sectors. + +However, for XDF disks, the logical order of the sectors on a given +track, and their physical order is not the same. This allows a faster +access, in a similar way that interleaving does for disk with normal +sized sectors and too small gaps. XDF's sector arrangement allows it to +read sectors alternatively from both sides, i.e. the first sector from +side 0, the second from side 1, and the third from side 0 again. This +differs from the usualy formats, where first the entire side 0 is read, +and then the entire side 1. This technique allows to read both sides of +a disk in roughly three rotations. + +The following example illustrates how this is done. In our example we +use the XDF format used for 3 1/2 HD disks, which contains one 8KB +sector, one 2KB sector, one 1KB sector, and one 512 byte sector per +track. The upper line represents the sectors on side 0, and the lower +line represents the sectors on side 1. Different numbers represent +different sectors. Repeated identical numbers represent a single larger +sector. As the disk is circular, some sectors wrap around at the end: +we find parts of the 8KB sector, represented by 6, both at the beginning +and at the end of each track. + +@example +position:| 1 2 5 4 + | 1234567890123456789012345678901234567890 + |========================================== +side 0: | 6633332244444446666666666666666666666666 +side 1: | 6666444444422333366666666666666666666666 + +2 512 byte sector +3 1KB sector +4 2KB sector +6 8KB sector +@end example + +When reading a track, sectors are read in the following order: +@example +sector id head position at start position at end +---------------------------------------------------------- + 3 0 3 7 + 4 0 9 16 + 6 1 18 5 (1st wrap around) + 2 0 7 9 + 2 1 12 14 + 6 0 16 3 (2nd wrap around) + 4 1 5 12 + 3 1 14 18 +@end example + +We notice that the start of each sector happens at least 2 units of +position (around 300 bytes), after the end of the previously read +sector, thus allowing the floppy disk controller sufficient time to +rest. Moreover, we notice two wrap-arounds, yielding three rotations to +read the whole cylinder (the third rotation is due to the fact that we +stop at a higher position than we started, and that we also need to +allow some time for seeking to the next track). + +MSS or 2M formats of the same capacity nead at least 2 rotations per +side (i.e. 4 per track), yielding a lower throughput. + +@strong{Usage:} XDF disks are not bootable by LILO. They can be +accessed from MS-DOS and OS/2 using @code{xdfcopy.exe} or +@code{xdf.com}. They are only suitable for MS-DOS filesystems. The +floppy driver has no direct support for this format yet, but +@code{mtools} is able to read them using the @code{FDRAWCMD} ioctl. + +@strong{Interesting Formats:} + +@example +density tot. cap. throughput formatting command +5 1/4 HD 1600KB 46KB/s xdfcopy -0 /dev/fd0 +3 1/2 HD 1840KB 38KB/s xdfcopy -1 /dev/fd0 +3 1/2 ED 3840KB 102KB/s xdfcopy -2 /dev/fd0 +@end example + +The options @code{-1}, @code{-2} and @code{-3} descibre one out of the +five formats understoood by @code{xdfcopy} (3 XDF formats and 2 XDF +formats). + +@node XXDF,, XDF, Extended formats +@section XXDF formats +@cindex MSS (XXDF) +@cindex Mixed sector size formats (XXDF) +@cindex XXDF + +These use the simple principle as XDF, but use a higher geometry. No +new principle is used, these formats are simply more daring (smaller +gaps, and smaller margin at the end of the sector). + +@strong{Usage:} XXDF disks are not bootable by LILO, and can't be +accessed by MS-DOS. They are only suitable for MS-DOS filesystems. The +floppy driver has no direct support for this format yet, but +@code{mtools} is able to read them using the @code{FDRAWCMD} ioctl. Due +to their smaller tolerances, XXDF formats may not work on all +drives. Problems may also occur if you write to XXDF disks using a +different drive than the one you used to format the disk. + +@strong{Interesting Formats:} + +@example +density tot. cap. throughput formatting command +3 1/2 HD 1920KB 45KB/s xdfcopy -3 /dev/fd0 +3 1/2 ED 3840KB 90KB/s xdfcopy -4 /dev/fd0 +@end example diff --git a/doc/setfdprm.1 b/doc/setfdprm.1 new file mode 100644 index 0000000..8e20a61 --- /dev/null +++ b/doc/setfdprm.1 @@ -0,0 +1,131 @@ +.TH setfdprm 1 "19apr97" fdutils-5.0 +.SH Name +setfdprm - sets user-provided floppy disk parameters +'\" t +.de TQ +.br +.ns +.TP \\$1 +.. + +.tr \(is' +.tr \(if` +.tr \(pd" + +.SH Note +This manpage has been automatically generated from fdutils's texinfo +documentation. However, this process is only approximative, and some +items, such as crossreferences, footnotes and indices are lost in this +translation process. Indeed, this items have no appropriate +representation in the manpage format. Moreover, only the items specific +to each command have been translated, and the general information about +fdutils has been dropped in the manpage version. Thus I strongly advise +you to use the original texinfo doc. +.TP +* \ \ +To generate a printable copy from the texinfo doc, run the following +commands: + +.nf +.ft 3 +.in +0.3i + ./configure; make dvi; dvips fdutils.dvi +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +* \ \ +To generate a html copy, run: + +.nf +.ft 3 +.in +0.3i + ./configure; make html +.fi +.in -0.3i +.ft R +.lp + +\&\fRA premade html can be found at: +\&\fR\&\f(CW\(ifhttp://linux.wauug.org/pub/knaff/fdutils\(is\fR +.TP +* \ \ +To generate an info copy (browsable using emacs' info mode), run: + +.nf +.ft 3 +.in +0.3i + ./configure; make info +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The texinfo doc looks most pretty when printed or as html. Indeed, in +the info version certain examples are difficult to read due to the +quoting conventions used in info. +.SH Description +.iX "p setfdprm" +.iX "c setting the geometry information" +.iX "c geometry information (setting)" +.PP + +.nf +.ft 3 +.in +0.3i +\&\fR\&\f(CWsetfdprm [\fR\&\f(CW-p] \fIdevice\fR\&\f(CW \fImedia-description\fR\&\f(CW +\&\& +\&\fR\&\f(CWsetfdprm [\fR\&\f(CW-c | \fR\&\f(CW-y | \fR\&\f(CW-n] \fIdevice\fR\&\f(CW +\&\& +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +\&\fR\&\f(CWsetfdprm\fR is a utility that can be used to load disk parameters +into the auto-detecting floppy devices and "fixed parameter" floppy +devices, to clear old parameter sets and to disable or enable diagnostic +messages. These parameters are derived from a media-description, +see section Media description for more details. +.PP +Without any options, \fR\&\f(CWsetfdprm\fR loads the \fIdevice\fR (for example +\&\fR\&\f(CW\(if/dev/fd0\(is\fR or \fR\&\f(CW\(if/dev/fd1\(is\fR) with a new parameter set with the +\&\fIname\fR entry found in \fR\&\f(CW\(if/etc/fdprm\(is\fR (usually named 360/360, +etc.). For autodetecting floppy devices, these parameters stay in +effect until the media is changed. For "fixed parameter" devices, they +stay in effect until they are changed again. +.PP +\&\fR\&\f(CWSetfdprm\fR can also be used by the superuser to redefine the +default formats. +.PP +.SH Options +.IP +.TP +\&\fR\&\f(CW-p\ \fIdevice\ name\fR\&\f(CW\fR\ +Permanently loads a new parameter set for the specified auto-configuring +floppy device for the configuration with \fIname\fR in +\&\fR\&\f(CW\(if/etc/fdprm\(is\fR. Alternatively, the parameters can be given directly +from the command line. +.TP +\&\fR\&\f(CW-c\ \fIdevice\fR\&\f(CW\fR\ +Clears the parameter set of the specified auto-configuring floppy device. +.TP +\&\fR\&\f(CW-y\ \fIdevice\fR\&\f(CW\fR\ +Enables format detection messages for the specified auto-configuring floppy +device. +.TP +\&\fR\&\f(CW-n\ \fIdevice\fR\&\f(CW\fR\ +Disables format detection messages for the specified auto-configuring +floppy device. +.PP +.SH Bugs +This documentation is grossly incomplete. +.SH See Also +Fdutils' texinfo doc diff --git a/doc/setfdprm.texi b/doc/setfdprm.texi new file mode 100644 index 0000000..5c3755e --- /dev/null +++ b/doc/setfdprm.texi @@ -0,0 +1,54 @@ +@node setfdprm, superformat, makefloppies, Commands +@section setfdprm +@pindex setfdprm +@cindex setting the geometry information +@cindex geometry information (setting) + +@example +@code{setfdprm} [@code{-p}] @var{device} @var{media-description} + +@code{setfdprm} [@code{-c} | @code{-y} | @code{-n}] @var{device} + +@end example + +@code{setfdprm} is a utility that can be used to load disk parameters +into the auto-detecting floppy devices and "fixed parameter" floppy +devices, to clear old parameter sets and to disable or enable diagnostic +messages. These parameters are derived from a media-description, +@pxref{Media description} for more details. + +Without any options, @code{setfdprm} loads the @var{device} (for example +@file{/dev/fd0} or @file{/dev/fd1}) with a new parameter set with the +@var{name} entry found in @file{/etc/fdprm} (usually named 360/360, +etc.). For autodetecting floppy devices, these parameters stay in +effect until the media is changed. For "fixed parameter" devices, they +stay in effect until they are changed again. + +@code{Setfdprm} can also be used by the superuser to redefine the +default formats. + +@subsection Options + +@table @code + +@item -p @var{device name} +Permanently loads a new parameter set for the specified auto-configuring +floppy device for the configuration with @var{name} in +@file{/etc/fdprm}. Alternatively, the parameters can be given directly +from the command line. + +@item -c @var{device} +Clears the parameter set of the specified auto-configuring floppy device. + +@item -y @var{device} +Enables format detection messages for the specified auto-configuring floppy +device. + +@item -n @var{device} +Disables format detection messages for the specified auto-configuring +floppy device. + +@end table + +@subsection Bugs +This documentation is grossly incomplete. diff --git a/doc/strip-pp.sed b/doc/strip-pp.sed new file mode 100644 index 0000000..56fb2c1 --- /dev/null +++ b/doc/strip-pp.sed @@ -0,0 +1,4 @@ +:1 +/^\.[IP]P$/N +s/^\.[IP]P\n\(\.[ITP]P\)$/\1/ +/^\.PP$/b1 diff --git a/doc/superformat.1 b/doc/superformat.1 new file mode 100644 index 0000000..f2185d5 --- /dev/null +++ b/doc/superformat.1 @@ -0,0 +1,399 @@ +.TH superformat 1 "19apr97" fdutils-5.0 +.SH Name +superformat - format floppies +'\" t +.de TQ +.br +.ns +.TP \\$1 +.. + +.tr \(is' +.tr \(if` +.tr \(pd" + +.SH Note +This manpage has been automatically generated from fdutils's texinfo +documentation. However, this process is only approximative, and some +items, such as crossreferences, footnotes and indices are lost in this +translation process. Indeed, this items have no appropriate +representation in the manpage format. Moreover, only the items specific +to each command have been translated, and the general information about +fdutils has been dropped in the manpage version. Thus I strongly advise +you to use the original texinfo doc. +.TP +* \ \ +To generate a printable copy from the texinfo doc, run the following +commands: + +.nf +.ft 3 +.in +0.3i + ./configure; make dvi; dvips fdutils.dvi +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +* \ \ +To generate a html copy, run: + +.nf +.ft 3 +.in +0.3i + ./configure; make html +.fi +.in -0.3i +.ft R +.lp + +\&\fRA premade html can be found at: +\&\fR\&\f(CW\(ifhttp://linux.wauug.org/pub/knaff/fdutils\(is\fR +.TP +* \ \ +To generate an info copy (browsable using emacs' info mode), run: + +.nf +.ft 3 +.in +0.3i + ./configure; make info +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The texinfo doc looks most pretty when printed or as html. Indeed, in +the info version certain examples are difficult to read due to the +quoting conventions used in info. +.SH Description +.iX "p superformat" +.iX "c formatting disks (non XDF)" +.PP + +.nf +.ft 3 +.in +0.3i +\&\fR\&\f(CWsuperformat [\fR\&\f(CW-D \fIdos-drive\fR\&\f(CW] [\fR\&\f(CW-v \fIverbosity-level\fR\&\f(CW] [\fR\&\f(CW-b \fIbegin-track\fR\&\f(CW] +[\fR\&\f(CW-e \fIend-track\fR\&\f(CW] [\fR\&\f(CW--dosverify] [\fR\&\f(CW--noverify] [\fR\&\f(CW--verify_later] +[\fR\&\f(CW-G \fIformat-gap\fR\&\f(CW] [\fR\&\f(CW-F \fIfinal-gap\fR\&\f(CW] [\fR\&\f(CW-i \fIinterleave\fR\&\f(CW] [\fR\&\f(CW-c \fIchunksize\fR\&\f(CW] +[\fR\&\f(CW-g \fIgap\fR\&\f(CW] [\fR\&\f(CW--absolute-skew \fIabsolute-skew\fR\&\f(CW] [\fR\&\f(CW--head-skew \fIhead-skew\fR\&\f(CW] +[\fR\&\f(CW--track-skew \fItrack-skew\fR\&\f(CW] [\fR\&\f(CW--biggest-last] \fIdrive\fR\&\f(CW [\fImedia-description\fR\&\f(CW] +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +\&\fR\&\f(CWsuperformat\fR is used to format disks with a capacity of up to +1992K HD or 3984K ED. See section Extended formats for a detailed +description of these formats. See section Media description for a detailed +description of the syntax for the media description. If no media +description is given, superformat formats a disk in the highest +available density for that drive, using standard parameters (i.e. no +extra capacity formats). +.PP +When the disk is formatted, \fR\&\f(CWsuperformat\fR automatically invokes +\&\fR\&\f(CWmformat\fR in order to put an MS-DOS filesystem on it. You may +ignore this filesystem, if you don't need it. +.PP +Supeformat allows to format 2m formats. Be aware, however, that these +\&\fR\&\f(CW2m\fR formats were specifically designed to hold an MS-DOS +filesystem, and that they take advantage of the fact that the MS-DOS +filesystem uses redundant sectors on the first track (the FAT, which is +represented twice). The second copy of the FAT is \fInot\fR represented +on the disk. +.PP +High capacity formats are sensitive to the exact rotation speed of the +drive and the resulting difference in raw capacity. That's why +\&\fR\&\f(CWsuperformat\fR performs a measurement of the disks raw capacity +before proceeding with the formatting. This measurement is rather time +consuming, and can be avoided by storing the relative deviation of the +drive capacity into the drive definition file file. See section Drive +descriptions for more details on this file. The line to be inserted +into the drive definition file is printed by superformat after +performing its measurement. However, this line depends on the drive and +the controller. Do not copy it to other computers. Remove it before +installing another drive or upgrade your floppy controller. Swap the +drive numbers if you swap the drives in your computer. +.PP +.SH Common\ Options +Many options have a long and a short form. +.TP +\&\fR\&\f(CW-h\fR\ +.TQ +\&\fR\&\f(CW--help\fR +Print the help. +.TP +\&\fR\&\f(CW-D\ \fIdrive\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--dosdrive\ \fIdos-drive\fR\&\f(CW\fR +Selects DOS drive letter for \fR\&\f(CWmformat\fR (for example \fR\&\f(CWa:\fR or +\&\fR\&\f(CWb:\fR). The colon may be omitted. The default is derived from the +minor device number. If the drive letter cannot be guessed, and is not +given on the command line, \fR\&\f(CWmformat\fR is skipped. +.TP +\&\fR\&\f(CW-v\ \fIverbosity-level\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--verbosity\ \fIverbosity-level\fR\&\f(CW\fR +Sets the verbosity level. 1 prints a dot for each formatted track. 2 +prints a changing sign for each formatted track (- for formatting the +first head, = for formatting the second head, x for verifying the +first head, and + for verifying the second head). 3 prints a complete +line listing head and track. 6 and 9 print debugging information. +.TP +\&\fR\&\f(CW-B\fR\ +.TQ +\&\fR\&\f(CW--dosverify\fR +Verifies the disk using the \fR\&\f(CWmbadblocks\fR program. +\&\fR\&\f(CWmbadblocks\fR marks the bad sectors as bad in the FAT. The +advantage of this is that disks which are only partially bad can still +be used for MS-DOS filesystems. +.TP +\&\fR\&\f(CW-V\fR\ +.TQ +\&\fR\&\f(CW--verify_later\fR +Verifies the whole disk at the end of the formatting process instead +of at each track. Verifying the disk at each track has the advantage +of detecting errors early on. +.TP +\&\fR\&\f(CW-f\fR\ +.TQ +\&\fR\&\f(CW--noverify\fR +Skips the verification altogether. +.PP +.SH Advanced\ Options +Usually, superformat uses sensible default values for these options, +which you normally don't need to override. They are intended for expert +users. Most of them should only be needed in cases where the hardware +or superformat itself has bugs. +.IP +.TP +\&\fR\&\f(CW-b\ \fIbegin-track\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--begin_track\ \ \fIbegin-track\fR\&\f(CW\fR +Describes the track where to begin formatting. This is useful if the +previous formatting failed halfway through. The default is 0. +.TP +\&\fR\&\f(CW-e\ \fIend-track\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--end_track\ \fIend-track\fR\&\f(CW\fR +Describes where to stop formatting. \fIend_track\fR is the last track to +be formatted plus one. This is mainly useful for testing purposes. By +default, this is the same as the total number of tracks. When the +formatting stops, the final skew is displayed (to be used as absolute +skew when you'll continue). +.TP +\&\fR\&\f(CW-S\ \fIsizecode\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--sizecode\ \fIsizecode\fR\&\f(CW\fR +Set the sector size to be used. The sector size is 128 * (2 ^ +\&\fIsizecode\fR). Sector sizes below 512 bytes are not supported, thus +sizecode must be at least 2. By default 512 is assumed, unless you ask +for more sectors than would fit with 512 bytes. +.TP +\&\fR\&\f(CW--stretch\ \fIstretch\fR\&\f(CW\fR\ +Set the stretch factor. The stretch factor describes how many physical +tracks to skip to get to the next logical track (2 ^ \fIstretch\fR). On +double density 5 1/4 disks, the tracks are further apart from each +other. +.TP +\&\fR\&\f(CW-G\ \fIfmt-gap\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--format_gap\ \fIfmt-gap\fR\&\f(CW\fR +Set the formatting gap. The formatting gap tells how far the sectors +are away from each other. By default, this is chosen so as to evenly +distribute the sectors along the track. +.TP +\&\fR\&\f(CW-F\ \fIfinal-gap\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--final_gap\ \fIfinal-gap\fR\&\f(CW\fR +Set the formatting gap to be used after the last sector. +.TP +\&\fR\&\f(CW-i\ \fIinterleave\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--interleave\ \fIinterleave\fR\&\f(CW\fR +Set the sector interleave factor. +.TP +\&\fR\&\f(CW-c\ \fIchunksize\fR\&\f(CW\fR\ +.TQ +\&\fR\&\f(CW--chunksize\ \fIchunksize\fR\&\f(CW\fR +Set the size of the chunks. The chunks are small auxiliary sectors +used during formatting. They are used to handle heterogeneous sector +sizes (i.e. not all sectors have the same size) and negative +formatting gaps. +.TP +\&\fR\&\f(CW--biggest-last\fR\ +For MSS formats, make sure that the biggest sector is last on the track. +This makes the format more reliable on drives which are out of spec. +.PP +.SH Sector\ skewing\ options +.PP +In order to maximize the user data transfer rate, the sectors are +arranged in such a way that sector 1 of the new track/head comes under +the head at the very moment when the drive is ready to read from that +track, after having read the previous track. Thus the first sector of +the second track is not necessarily near the first sector of the first +track. The skew value describes for each track how far sector number +1 is away from the index mark. This skew value changes for each head +and track. The amount of this change depends on how fast the disk +spins, and on how much time is needed to change the head or the track. +.TP +\&\fR\&\f(CW--absolute_skew\ \fIabsolute-skew\fR\&\f(CW\fR\ +Set the absolute skew. (The skew value used for the first formatted +track) +.TP +\&\fR\&\f(CW--head_skew\ \fIhead-skew\fR\&\f(CW\fR\ +Set the head skew. (The skew added for passing from head 0 to head 1) +.TP +\&\fR\&\f(CW--track_skew\ \fItrack-skew\fR\&\f(CW\fR\ +Set the track skew. (The skew added for seeking to the next track) +.PP +Example: (absolute skew=3, head skew=1, track skew=2) +.PP + +.nf +.ft 3 +.in +0.3i +track 0 head 0: 4,5,6,1,2,3 (skew=3) +track 0 head 1: 3,4,5,6,1,2 (skew=4) +\&\& +track 1 head 0: 1,2,3,4,5,6 (skew=0) +track 1 head 1: 6,1,2,3,4,5 (skew=1) +\&\& +track 2 head 0: 4,5,6,1,2,3 (skew=3) +track 2 head 1: 3,4,5,6,1,2 (skew=4) +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +.SH Examples +In all the examples of this section, we assume that drive 0 is a 3 1/2 +and drive 1 a 5 1/4. +.PP +The following example shows how to format a 1440K disk in drive 0: + +.nf +.ft 3 +.in +0.3i +superformat /dev/fd0 hd +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The following example shows how to format a 1200K disk in drive 1: + +.nf +.ft 3 +.in +0.3i +superformat /dev/fd1 hd +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The following example shows how to format a 1440K disk in drive 1: + +.nf +.ft 3 +.in +0.3i +superformat /dev/fd1 hd sect=18 +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The following example shows how to format a 720K disk in drive 0: + +.nf +.ft 3 +.in +0.3i +superformat /dev/fd0 dd +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The following example shows how to format a 1743K disk in drive 0 (83 +cylinders times 21 sectors): + +.nf +.ft 3 +.in +0.3i +superformat /dev/fd0 sect=21 cyl=83 +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The following example shows how to format a 1992K disk in drive 0 (83 +cylinders times 2 heads times 12 KB per track) + +.nf +.ft 3 +.in +0.3i +superformat /dev/fd0 tracksize=12KB cyl=83 mss +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The following example shows how to format a 1840K disk in drive 0. It +will have 5 2048-byte sectors, one 1024-byte sector, and one 512-byte +sector per track: + +.nf +.ft 3 +.in +0.3i +superformat /dev/fd0 tracksize=23b mss 2m ssize=2KB +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +All these formats can be autodetected by mtools, using the floppy +driver's default settings. +.PP +.SH Troubleshooting +.TP +\&\fR\&\f(CWFDC\ busy,\ sleeping\ for\ a\ second\fR\ +When another program accesses a disk drive on the same controller as the +one being formatted, \fR\&\f(CWsuperformat\fR has to wait until the other +access is finished. If this happens, check whether any other program +accesses a drive (or whether a drive is mounted), kill that program (or +unmount the drive), and the format should proceed normally. +.TP +\&\fR\&\f(CWI/O\ errors\ during\ verification\fR\ +Your drive may be too far out of tolerance, and you may thus need to +supply a margin parameter. Run \fR\&\f(CWfloppymeter\fR (see section floppymeter) +to find out an appropriate value for this parameter, and add the +suggested \fR\&\f(CWmargin\fR parameter to the command line +.PP +.SH Bugs +Opening up new window while \fR\&\f(CWsuperformat\fR is running produces +overrun errors. These errors are benign, as the failed operation is +automatically retried until it succeeds. +.SH See Also +Fdutils' texinfo doc diff --git a/doc/superformat.texi b/doc/superformat.texi new file mode 100644 index 0000000..e80b4a0 --- /dev/null +++ b/doc/superformat.texi @@ -0,0 +1,277 @@ +@node superformat, xdfcopy, setfdprm, Commands +@section superformat +@pindex superformat +@cindex formatting disks (non XDF) + +@example +@code{superformat} [@code{-D} @var{dos-drive}] [@code{-v} @var{verbosity-level}] [@code{-b} @var{begin-track}] +[@code{-e} @var{end-track}] [@code{--dosverify}] [@code{--noverify}] [@code{--verify_later}] +[@code{-G} @var{format-gap}] [@code{-F} @var{final-gap}] [@code{-i} @var{interleave}] [@code{-c} @var{chunksize}] +[@code{-g} @var{gap}] [@code{--absolute-skew} @var{absolute-skew}] [@code{--head-skew} @var{head-skew}] +[@code{--track-skew} @var{track-skew}] [@code{--biggest-last}] @var{drive} [@var{media-description}] +@end example + +@code{superformat} is used to format disks with a capacity of up to +1992K HD or 3984K ED. @xref{Extended formats} for a detailed +description of these formats. @xref{Media description} for a detailed +description of the syntax for the media description. If no media +description is given, superformat formats a disk in the highest +available density for that drive, using standard parameters (i.e. no +extra capacity formats). + +When the disk is formatted, @code{superformat} automatically invokes +@code{mformat} in order to put an MS-DOS filesystem on it. You may +ignore this filesystem, if you don't need it. + +Supeformat allows to format 2m formats. Be aware, however, that these +@code{2m} formats were specifically designed to hold an MS-DOS +filesystem, and that they take advantage of the fact that the MS-DOS +filesystem uses redundant sectors on the first track (the FAT, which is +represented twice). The second copy of the FAT is @emph{not} represented +on the disk. + +High capacity formats are sensitive to the exact rotation speed of the +drive and the resulting difference in raw capacity. That's why +@code{superformat} performs a measurement of the disks raw capacity +before proceeding with the formatting. This measurement is rather time +consuming, and can be avoided by storing the relative deviation of the +drive capacity into the drive definition file file. @xref{Drive +descriptions} for more details on this file. The line to be inserted +into the drive definition file is printed by superformat after +performing its measurement. However, this line depends on the drive and +the controller. Do not copy it to other computers. Remove it before +installing another drive or upgrade your floppy controller. Swap the +drive numbers if you swap the drives in your computer. + +@menu +* Common options:: The most frequently used options +* Advanced options:: For experts +* Sector skewing options:: Optimizing throughput by creatively + arranging the sectors +* Examples:: Some example command lines +* Troubleshooting:: Most common failure modes +* Superformat bugs:: Nobody is perfect +@end menu + +@node Common options, Advanced options, superformat, superformat +@subsection Common Options +Many options have a long and a short form. + +@table @code +@item -h +@itemx --help +Print the help. + +@item -D @var{drive} +@itemx --dosdrive @var{dos-drive} +Selects DOS drive letter for @code{mformat} (for example @code{a:} or +@code{b:}). The colon may be omitted. The default is derived from the +minor device number. If the drive letter cannot be guessed, and is not +given on the command line, @code{mformat} is skipped. + +@item -v @var{verbosity-level} +@itemx --verbosity @var{verbosity-level} +Sets the verbosity level. 1 prints a dot for each formatted track. 2 +prints a changing sign for each formatted track (- for formatting the +first head, = for formatting the second head, x for verifying the +first head, and + for verifying the second head). 3 prints a complete +line listing head and track. 6 and 9 print debugging information. + +@item -B +@itemx --dosverify +Verifies the disk using the @code{mbadblocks} program. +@code{mbadblocks} marks the bad sectors as bad in the FAT. The +advantage of this is that disks which are only partially bad can still +be used for MS-DOS filesystems. + +@item -V +@itemx --verify_later +Verifies the whole disk at the end of the formatting process instead +of at each track. Verifying the disk at each track has the advantage +of detecting errors early on. + +@item -f +@itemx --noverify +Skips the verification altogether. + +@end table + +@node Advanced options, Sector skewing options, Common options, superformat +@subsection Advanced Options +Usually, superformat uses sensible default values for these options, +which you normally don't need to override. They are intended for expert +users. Most of them should only be needed in cases where the hardware +or superformat itself has bugs. + +@table @code + +@item -b @var{begin-track} +@itemx --begin_track @var{begin-track} +Describes the track where to begin formatting. This is useful if the +previous formatting failed halfway through. The default is 0. + +@item -e @var{end-track} +@itemx --end_track @var{end-track} +Describes where to stop formatting. @var{end_track} is the last track to +be formatted plus one. This is mainly useful for testing purposes. By +default, this is the same as the total number of tracks. When the +formatting stops, the final skew is displayed (to be used as absolute +skew when you'll continue). + +@item -S @var{sizecode} +@itemx --sizecode @var{sizecode} +Set the sector size to be used. The sector size is 128 * (2 ^ +@var{sizecode}). Sector sizes below 512 bytes are not supported, thus +sizecode must be at least 2. By default 512 is assumed, unless you ask +for more sectors than would fit with 512 bytes. + +@item --stretch @var{stretch} +Set the stretch factor. The stretch factor describes how many physical +tracks to skip to get to the next logical track (2 ^ @var{stretch}). On +double density 5 1/4 disks, the tracks are further apart from each +other. + +@item -G @var{fmt-gap} +@itemx --format_gap @var{fmt-gap} +Set the formatting gap. The formatting gap tells how far the sectors +are away from each other. By default, this is chosen so as to evenly +distribute the sectors along the track. + +@item -F @var{final-gap} +@itemx --final_gap @var{final-gap} +Set the formatting gap to be used after the last sector. + +@item -i @var{interleave} +@itemx --interleave @var{interleave} +Set the sector interleave factor. + +@item -c @var{chunksize} +@itemx --chunksize @var{chunksize} +Set the size of the chunks. The chunks are small auxiliary sectors +used during formatting. They are used to handle heterogeneous sector +sizes (i.e. not all sectors have the same size) and negative +formatting gaps. + +@item --biggest-last +For MSS formats, make sure that the biggest sector is last on the track. +This makes the format more reliable on drives which are out of spec. + +@end table + +@node Sector skewing options, Examples, Advanced options, superformat +@subsection Sector skewing options + +In order to maximize the user data transfer rate, the sectors are +arranged in such a way that sector 1 of the new track/head comes under +the head at the very moment when the drive is ready to read from that +track, after having read the previous track. Thus the first sector of +the second track is not necessarily near the first sector of the first +track. The skew value describes for each track how far sector number +1 is away from the index mark. This skew value changes for each head +and track. The amount of this change depends on how fast the disk +spins, and on how much time is needed to change the head or the track. + +@table @code +@item --absolute_skew @var{absolute-skew} +Set the absolute skew. (The skew value used for the first formatted +track) + +@item --head_skew @var{head-skew} +Set the head skew. (The skew added for passing from head 0 to head 1) + +@item --track_skew @var{track-skew} +Set the track skew. (The skew added for seeking to the next track) +@end table + +Example: (absolute skew=3, head skew=1, track skew=2) + +@example +track 0 head 0: 4,5,6,1,2,3 (skew=3) +track 0 head 1: 3,4,5,6,1,2 (skew=4) + +track 1 head 0: 1,2,3,4,5,6 (skew=0) +track 1 head 1: 6,1,2,3,4,5 (skew=1) + +track 2 head 0: 4,5,6,1,2,3 (skew=3) +track 2 head 1: 3,4,5,6,1,2 (skew=4) +@end example + +@node Examples, Troubleshooting, Sector skewing options, superformat +@subsection Examples +In all the examples of this section, we assume that drive 0 is a 3 1/2 +and drive 1 a 5 1/4. + + +The following example shows how to format a 1440K disk in drive 0: +@example +superformat /dev/fd0 hd +@end example + + +The following example shows how to format a 1200K disk in drive 1: +@example +superformat /dev/fd1 hd +@end example + + +The following example shows how to format a 1440K disk in drive 1: +@example +superformat /dev/fd1 hd sect=18 +@end example + + +The following example shows how to format a 720K disk in drive 0: +@example +superformat /dev/fd0 dd +@end example + + +The following example shows how to format a 1743K disk in drive 0 (83 +cylinders times 21 sectors): +@example +superformat /dev/fd0 sect=21 cyl=83 +@end example + + +The following example shows how to format a 1992K disk in drive 0 (83 +cylinders times 2 heads times 12 KB per track) +@example +superformat /dev/fd0 tracksize=12KB cyl=83 mss +@end example + + +The following example shows how to format a 1840K disk in drive 0. It +will have 5 2048-byte sectors, one 1024-byte sector, and one 512-byte +sector per track: +@example +superformat /dev/fd0 tracksize=23b mss 2m ssize=2KB +@end example + + +All these formats can be autodetected by mtools, using the floppy +driver's default settings. + +@node Troubleshooting, Superformat bugs, Examples, superformat +@subsection Troubleshooting + +@table @code +@item FDC busy, sleeping for a second +When another program accesses a disk drive on the same controller as the +one being formatted, @code{superformat} has to wait until the other +access is finished. If this happens, check whether any other program +accesses a drive (or whether a drive is mounted), kill that program (or +unmount the drive), and the format should proceed normally. + +@item I/O errors during verification +Your drive may be too far out of tolerance, and you may thus need to +supply a margin parameter. Run @code{floppymeter} (@pxref{floppymeter}) +to find out an appropriate value for this parameter, and add the +suggested @code{margin} parameter to the command line + +@end table + +@node Superformat bugs, , Troubleshooting, superformat +@subsection Bugs +Opening up new window while @code{superformat} is running produces +overrun errors. These errors are benign, as the failed operation is +automatically retried until it succeeds. diff --git a/doc/texi-linearize.c b/doc/texi-linearize.c new file mode 100644 index 0000000..db336be --- /dev/null +++ b/doc/texi-linearize.c @@ -0,0 +1,56 @@ +#include +#include + + +FILE *my_open(char *directory, char *file) +{ + char path[8192]; + FILE *r; + + strcpy(path, directory); + strcat(path,"/"); + strcat(path, file); + + r= fopen(path, "r"); + if(r == NULL) { + fprintf(stderr,"Could not open %s\n", path); + perror("open"); + exit(1); + } + return r; +} + +int main(int argc, char **argv) +{ + FILE *stack[256]; + int sp; + char line[4096]; + char *directory; + + sp = 0; + + if(argc < 3) { + fprintf(stderr,"Usage: %s directory root texi file\n", argv[0]); + exit(1); + } + + directory = argv[1]; + + stack[sp++] = my_open(directory, argv[2]); + while(sp) { + if(fgets(line, 4095, stack[sp-1]) ) { + line[strlen(line)-1]='\0'; + if(!strncmp(line, "@input", 6)) { + stack[sp++] = my_open(directory, line+7); + continue; + } + if(!strncmp(line, "@include", 8)) { + stack[sp++] = my_open(directory, line+9); + continue; + } + puts(line); + } else + sp--; + } + exit(0); +} diff --git a/doc/tips.texi b/doc/tips.texi new file mode 100644 index 0000000..bc67125 --- /dev/null +++ b/doc/tips.texi @@ -0,0 +1,272 @@ +@node Basic usage, Device numbers, Location, Top +@chapter Basic usage + +This chapter describes basic usage of floppies, and gives a few simple +tips for using floppies under Linux. + +@menu +* Disk organisation :: How a disk is organized, high-level and low-level + formats +* File systems :: Which file systems does Linux support +* Device names :: How floppy drives are named +* Identifying disks :: How to identify a disk +* Nickel tours :: Short summaries of the various storage methods +* New features :: New features of the kernel, mtools, and fdutils +@end menu + +@node Disk organisation, File systems, Basic usage, Basic usage +@section How disks are organized +@cindex low level format +@cindex format (low level vs. high level) +@cindex high level format + +All floppies have two levels of @emph{formatting}, both of which must be +known in order to read them. The first is the @emph{binary} or +@emph{sector} level format, which is how raw data is stored on the disk. +The second is a higher level organization, often called a @emph{file +system}, which allows multiple files to be conveniently stored on the +disk. + +For example, a typical 1.44MB disk contains a low-level format, with 18 +sectors per track, 80 tracks, and two sides (or heads); each sector can +hold 512 bytes of data for a total of 1474560 bytes (or 1440 KB). When +used under MS-DOS, this floppy would have a small portion of the disk +used to keep track of files on the disk (including a bootsector, file +allocation tables, directories, etc.). + +The floppy driver generally takes care of reading the binary, or +low-level format. It can often "guess" the low-level disk geometry +needed to read the disk. This is called autodetection +(@pxref{Autodetection}). If the driver can't autodetect the disk +(e.g. if it is in an unusual format) you can tell the driver what the +geometry is either by using the @code{setfdprm} (@pxref{setfdprm}) +utility or by using a fixed geometry device device +(e.g. @file{/dev/fd0H1440}). + +Under Linux, many different file systems from many sources can be used. +Some of these file systems are interpreted via a utility program (for +example @code{mtools} for using disks with an MS-DOS file system). Many +file systems can alternatively be "mounted" to appear in the UNIX +directory structure until subsequently being unmounted; this is usually +implemented by having the kernel itself interpret the file system on the +disk. + +@node File systems, Device names, Disk organisation, Basic usage +@section File systems supported by Linux +@cindex supported file systems +@cindex file systems supported by linux + +The following file systems are supported: + +@table @strong +@item OS/2 HPFS: +read-only support (mount/kernel) +@item Mac HPFS 1.44MB: +read-only (xhfs utility) +@item MS-DOS: +read, write, format (mtools utility @emph{and} mount/kernel) +@item tar, cpio: +compatible with many variations of UNIX (tar, cpio utilities) +@item System V, minix, xia, ext, ext2: +(mount/kernel) +@item pure binary disk access: +no file system (any program, usually dd, cat, and cp) +@end table + +@node Device names, Identifying disks, File systems, Basic usage +@section What's in a name +@cindex floppy device name +@cindex file name of floppy devices +@cindex name of floppy devices + +The following figure shows the meaning of the different parts of the +name of a floppy device: + +@example + +--------------- /dev: directory for devices + | +------------- fd: floppy disk device prefix + | | +------------ 0: floppy drive #0 (A:) (0-1 typical, 0-7 + | | | possible) + | | |+-- 3.5" drive: (use d for 5.25" double density drives, and + | | || h for 5.25" high density drives, + | | || u for 3.5" drive of any density) + | | || +---- 1440: Capacity (in KB) of format (usually between + | | || | 360 and 3920) +/dev/fd0u1440 +@end example + + +@node Identifying disks, Nickel tours, Device names, Basic usage +@section What to do if you get an unidentified floppy disk +@cindex indentifying unknown disks + +@example +dd if=/dev/fd0 of=/tmp/foo count=1 + # If it works: +getfdprm # This will report what geometry the disk has +file /tmp/foo # This may indicate the type of file system +mdir a: # Check for an MS-DOS file system +tar tvf /dev/fd0 # Check for a tar archive +cpio -itv < /dev/fd0 # Check for a cpio archive +e2fsck /dev/fd0 # Check for an "ext2" file system + # If it doesn't work: + # Try the above dd command using various /dev/fd0* devices +@end example + +@node Nickel tours, New features, Identifying disks, Basic usage +@section Nickel tours +@cindex nickel tours + +@menu +* Mtools :: Access MS-Dos disks from Unix +* Tar :: Tarring files directly to floppy disks +* CPIO :: Another archive format +* Ext2 :: Seconded Extended File System +@end menu + +@node Mtools, Tar, Nickel tours, Nickel tours +@subsection mtools +@cindex mtools (nickel tour) + +@example +mdir a: # Read directory of MS-DOS disk in drive A: +mcopy /tmp/foo\* a: # Copy files beginning with foo in /tmp to A: +mcopy a:\* . # Copy all files from A: to current directory +mformat a: # Add MS-DOS file system to formatted disk +@end example + +@node Tar, CPIO, Mtools, Nickel tours +@subsection Tar (Tape ARchive) +@cindex tar + +@example +tar tvf /dev/fd0 # Read directory of tar archive in + # drive A: +tar cvf /dev/fd0 foo1 foo2 # Write foo1 and foo2 to A: in tar + # format foo1/foo2 can be entire + # directory trees +tar xvfp /dev/fd0 # extract entire tar archive in + # drive A: +@end example + +Tar is not a file system. Only low-level format (@code{superformat}, +@pxref{superformat}) are needed to prepare a disk to accept a tar +archive. + +@node CPIO, Ext2, Tar, Nickel tours +@subsection CPIO (CoPy In/Out) +@cindex CPIO + +@example +cpio -itv < /dev/fd0 # Read directory of cpio archive in A: +find foo1 foo2 -print | cpio -ov < /dev/fd0 + # Write foo1/foo2 to A: + # foo1/foo2 can be entire directory trees +cpio -idumv < /dev/fd0 # extract entire CPIO archive in drive A: +@end example + +Note: blocks reported are in 512-byte units (due to UNIX System V +heritage). Cpio is not a file system. Only low-level format (fdformat +or superformat (@pxref{superformat}) needed. + +@node Ext2,, CPIO, Nickel tours +@section Ext2 (Second Extended File System) +@cindex Ext2 + +@example +mke2fs /dev/fd0 1440 # Makes an ext2 filesystem of 1440 + # block on A: +mke2fs -c /dev/fd0 1440 # Same as above, but tests floppy first +e2fsck /dev/fd0 # Tests filesystem integrity. (like + # chkdsk in Dos) +e2fsck -p /dev/fd0 # Repairs filesystem. (like chkdsk /f + # in Dos) +mount -t ext2 /dev/fd0 /mnt # Mounts the disk in A: on /mnt. + # The directory /mnt must already exist +umount /mnt # Unmounts /mnt. No process should + # have its working directory in /mnt + # No process should have open files in + # /mnt +@end example + +Note: don't use ext2 on 2m disks +On some systems @code{mke2fs} is also called mkfs.ext2, and e2fsck is also +called fsck.ext2 + +@node New features,, Nickel tours, Basic usage +@section New Features of 1.2+ kernels +@cindex New features + +@menu +* kernel :: New kernel features since 1.2.0 +* mtools :: New mtools features since mtools-3.0 +* fdutils :: Utilities contained in the fdutils package +@end menu + +@node kernel, mtools, New features, New features +@subsection New features of 1.2+ kernels +@cindex Kernel (new features) + +@itemize @bullet +@item +Faster and more comprehensive automatic sensing of floppy formats +@item +Second Floppy Disk Controller (FDC) supported +@item +DOS fdformat-style formats (up to 21 sectors on HD 3.5" disk) +@item +DOS 2m-style formats (up to 24 sectors equivalent on HD 3.5" disk) +@item +non-DOS 2m-inspired formats +@item +Several long-standing bugs fixed +@item +More exact detection of FDC type +@item +More exact detection of floppy drives +@end itemize + +@node mtools, fdutils, kernel, New features +@subsection New features of mtools-3.0 +@cindex Mtools (new features) + +@itemize @bullet +@item +Support for new floppy formats (fdformat, 2m, 2m-like, ED) +@item +2.88MB (Extra Density) floppies supported +@item +More friendly syntax (e.g. "mcopy a:", "mmove") +@item +Improved mmount +@item +16-bit FATs (needed for some ED formats) +@item +Automatically sets disk geometry for Linux +@item +Several bug fixes +@end itemize + +NOTE: Mtools has no longer maintained by its original maintainer Emmet +P. Gray after 2.0.7. + +@node fdutils,, mtools, New features +@subsection New Utilities +@cindex Fdutils (brief list of supplied utilities) + +@itemize @bullet +@item +@code{superformat} (replaces fdformat; up to 3.84 MB floppies, faster, +calls mformat) + +@item +new @code{getfdprm}/@code{setfdprm} + +@item +@code{fdrawcmd} (allows user-mode programs to do low-level floppy +actions) @code{floppycontrol} (general-purpose floppy driver +configuration utility) + +@item +@code{MAKEFLOPPIES} (makes floppy devices) +@end itemize diff --git a/doc/utilities.texi b/doc/utilities.texi new file mode 100644 index 0000000..571e546 --- /dev/null +++ b/doc/utilities.texi @@ -0,0 +1,70 @@ +@node Utilities +@chapter Included utilities + +The following utilities are included in the fdutils package + +@table @code +@item floppycontrol + +This program sets the various error tresholds (error reporting, +operation abortion, and read track), prints out drive drive types, and +flushes buffers. There is a -h help option. +This program provides examples on how to use the new ioctl's. + +To compile this program just type make in the util directory. + +See also the included manpage. (in the utils directory) + +@item MAKEFLOPPIES +This shell script creates the new floppy block +device files. It uses the floppycontrol program to translate the +minor device numbers into meaningful names. It also uses these names +to decide wether to create a given block device file or not, depending +on the type of the physical drive (for instance, for a 3 1/2 drive, +the formats corresponding to a 5 1/4 drive are not created). +If you have more than two floppy drives, the kernel cannot find out +the types of these additional drives, and you need to specify them +with the environmental variables FD2 and FD3. The following types are +available: H1440 ( HD 3''1/2), h1200 (HD 5''1/4), D720 (DD 3''1/2) and +d360 (DD 5''1/4). +Sample command line: +@example + FD2=1.44M FD3=1.2M MAKEFLOPPIES +@end example + +The names of the device are a letter describing the _drive_ types, +followed by a letter describing the size of the _format_. +The letters are +@table @code +@item E +3.5" ED drive +@item H +3.5" HD drive +@item D +3.5" DD drive +@item h +5.25" HD drive +@item d +5.25" DD drive +@end table + +Example: @file{h360} is a device for accessing a @file{360KB} disk in a +@file{5.25" HD} drive. + +This convention is the same as used by Slackware and the @code{MAKEDEV} +script, except for the ED drives (which are named @code{H2880} by +@code{MAKEDEV}, and don't yet exist in Slackware) + +@strong{Important}: The @code{MAKEFLOPPIES} script needs the +floppycontrol program on the search @code{PATH}. + +@item Setfdprm +This program is used to set the media parameters for a drive. + +@item Superformat +This program is used to format floppy disks. The old fdformat doesn't +work for disks with bigger sectors. WARNING: DO READ THIS MANPAGE +CAREFULLY. IMPROPER USAGE MAY LEAD TO DATA LOSS. + +@item Others: see the manpages +@end table diff --git a/doc/xdfcopy.1 b/doc/xdfcopy.1 new file mode 100644 index 0000000..cf12583 --- /dev/null +++ b/doc/xdfcopy.1 @@ -0,0 +1,189 @@ +.TH xdfcopy 1 "19apr97" fdutils-5.0 +.SH Name +xdfcopy - Program to copy and format Xdf disks in Linux +'\" t +.de TQ +.br +.ns +.TP \\$1 +.. + +.tr \(is' +.tr \(if` +.tr \(pd" + +.SH Note +This manpage has been automatically generated from fdutils's texinfo +documentation. However, this process is only approximative, and some +items, such as crossreferences, footnotes and indices are lost in this +translation process. Indeed, this items have no appropriate +representation in the manpage format. Moreover, only the items specific +to each command have been translated, and the general information about +fdutils has been dropped in the manpage version. Thus I strongly advise +you to use the original texinfo doc. +.TP +* \ \ +To generate a printable copy from the texinfo doc, run the following +commands: + +.nf +.ft 3 +.in +0.3i + ./configure; make dvi; dvips fdutils.dvi +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +* \ \ +To generate a html copy, run: + +.nf +.ft 3 +.in +0.3i + ./configure; make html +.fi +.in -0.3i +.ft R +.lp + +\&\fRA premade html can be found at: +\&\fR\&\f(CW\(ifhttp://linux.wauug.org/pub/knaff/fdutils\(is\fR +.TP +* \ \ +To generate an info copy (browsable using emacs' info mode), run: + +.nf +.ft 3 +.in +0.3i + ./configure; make info +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +The texinfo doc looks most pretty when printed or as html. Indeed, in +the info version certain examples are difficult to read due to the +quoting conventions used in info. +.SH Description +.iX "p xdfcopy" +.iX "c XDF (formatting and copying disks)" +.iX "c formatting XDF disks" +.PP + +.nf +.ft 3 +.in +0.3i +\&\fR\&\f(CWxdfcopy [\fR\&\f(CW-\fIformat-id\fR\&\f(CW] [\fR\&\f(CW-d] [\fR\&\f(CW-n] [\fR\&\f(CW-h \fIhead-skew\fR\&\f(CW] [\fR\&\f(CW-t \fIcylinder-skew\fR\&\f(CW] [\fR\&\f(CW-T +\&\fIend-cylinder\fR\&\f(CW] [\fIsource\fR\&\f(CW] \fItarget\fR\&\f(CW +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.PP +\&\fR\&\f(CWXdfcopy\fR is a utility to copy and format XDF disks. XDF (eXtended +Density Format) is a format used by OS/2 which can hold 1840KB of data +(on a 3 1/2 high density disk). Its advantage over 2m formats is that it +is faster: 38KB/s. Because of this fast speed, I extended the XDF +standard to higher capacities (1992KB) with a transfer rate of 45KB/s. I +called the new formats XXDF. +.PP +This program works best with kernels newer than 2.0.0. +.PP +If both source and target are given, xdfcopy copies the disk image from +file to floppy disk or vice-versa. When copying to a floppy disk, the +disk is first formatted, unless the \fR\&\f(CW-n\fR option is given. +.PP +If no source is given, the target is only formatted. In this case, the +target must be a floppy drive. +.PP +.SH Options +.PP +.SS Selecting\ a\ format +.PP +Formats are selected by the format_id. The following formats are understood: +.IP +.TP +\&\fR\&\f(CW0\fR\ +Formats a 5 1/4 XDF disk (1520 KB, 45.6 KB/s). +.TP +\&\fR\&\f(CW1\fR\ +Formats a 3 1/2 high density XDF disk (1840 KB, 38.3 KB/s). +.TP +\&\fR\&\f(CW2\fR\ +Formats a 3 1/2 extra density XDF disk (3680 KB, 102 KB/s) +.TP +\&\fR\&\f(CW3\fR\ +Formats a 3 1/2 high density XXDF disk (1920 KB, 45 KB/s) +.TP +\&\fR\&\f(CW4\fR\ +Formats a 3 1/2 extra density XXDF disk (3840 KB, 90 KB/s) +.PP +.SH Misc\ options +.TP +\&\fR\&\f(CW-D\ \fIdosdrive\fR\&\f(CW\fR\ +Describes the DOS drive letter for mformat. If this option is given, an +MS-DOS filesystem is automatically installed on the disk after the +low-level format is complete. In order for this to work, the drive has +to be configured to accept the 23x2x80 geometry in your /etc/mtools or +your ~/.mtoolsrc file. Moreover, this only works with a version of +mtools that is more recent than 3.0. +.IP +Example of a working mtoolsrc line: + +.nf +.ft 3 +.in +0.3i +A /dev/fd0 0 0 0 0 +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.IP +Examples of a non-working mtoolsrc line: + +.nf +.ft 3 +.in +0.3i +A /dev/fd0 12 80 2 18 +.fi +.in -0.3i +.ft R +.lp + +\&\fR +.TP +\&\fR\&\f(CW-n\fR\ +Don't format the disk before copying the disk image to the disk. +.PP +.SH Options\ for\ power\ users +.IP +.TP +\&\fR\&\f(CW-t\ \fIcylinder\ skew\fR\&\f(CW\fR\ +Uses a different track skew than the default (14). For more details on +skews, see section superformat. In this version of xdfcopy, the \fR\&\f(CW-t\fR +parameter is ignored. +.TP +\&\fR\&\f(CW-h\ \fIhead\ skew\fR\&\f(CW\fR\ +Uses a different head skew than the default (0) In this version, this +parameter is ignored +.TP +\&\fR\&\f(CW-d\fR\ +Debugging. For each read or write operation, the time it took to +complete the operation is printed (in milliseconds). This can be used +to optimize the skews. +.TP +\&\fR\&\f(CW-T\ \fIend-cylinders\fR\&\f(CW\fR\ +Tells how many cylinders to format. With the XXDF formats, it is +actually possible to format up to 83 cylinders, yielding a format of +up to 1992KB on a 3 1/2 high density disk. +.SH See Also +Fdutils' texinfo doc diff --git a/doc/xdfcopy.texi b/doc/xdfcopy.texi new file mode 100644 index 0000000..adfb20d --- /dev/null +++ b/doc/xdfcopy.texi @@ -0,0 +1,102 @@ +@node xdfcopy, , superformat, Commands +@section xdfcopy +@pindex xdfcopy +@cindex XDF (formatting and copying disks) +@cindex formatting XDF disks + +@example +@code{xdfcopy} [@code{-}@var{format-id}] [@code{-d}] [@code{-n}] [@code{-h} @var{head-skew}] [@code{-t} @var{cylinder-skew}] [@code{-T} +@var{end-cylinder}] [@var{source}] @var{target} +@end example + + +@code{Xdfcopy} is a utility to copy and format XDF disks. XDF (eXtended +Density Format) is a format used by OS/2 which can hold 1840KB of data +(on a 3 1/2 high density disk). Its advantage over 2m formats is that it +is faster: 38KB/s. Because of this fast speed, I extended the XDF +standard to higher capacities (1992KB) with a transfer rate of 45KB/s. I +called the new formats XXDF. + +This program works best with kernels newer than 2.0.0. + +If both source and target are given, xdfcopy copies the disk image from +file to floppy disk or vice-versa. When copying to a floppy disk, the +disk is first formatted, unless the @code{-n} option is given. + +If no source is given, the target is only formatted. In this case, the +target must be a floppy drive. + +@subsection Options + +@subsubsection Selecting a format + +Formats are selected by the format_id. The following formats are understood: + +@table @code + +@item 0 +Formats a 5 1/4 XDF disk (1520 KB, 45.6 KB/s). + +@item 1 +Formats a 3 1/2 high density XDF disk (1840 KB, 38.3 KB/s). + +@item 2 +Formats a 3 1/2 extra density XDF disk (3680 KB, 102 KB/s) + +@item 3 +Formats a 3 1/2 high density XXDF disk (1920 KB, 45 KB/s) + +@item 4 +Formats a 3 1/2 extra density XXDF disk (3840 KB, 90 KB/s) +@end table + +@subsection Misc options + +@table @code +@item -D @var{dosdrive} +Describes the DOS drive letter for mformat. If this option is given, an +MS-DOS filesystem is automatically installed on the disk after the +low-level format is complete. In order for this to work, the drive has +to be configured to accept the 23x2x80 geometry in your /etc/mtools or +your ~/.mtoolsrc file. Moreover, this only works with a version of +mtools that is more recent than 3.0. + +Example of a working mtoolsrc line: +@example +A /dev/fd0 0 0 0 0 +@end example + +Examples of a non-working mtoolsrc line: +@example +A /dev/fd0 12 80 2 18 +@end example + +@item -n +Don't format the disk before copying the disk image to the disk. + +@end table + +@subsection Options for power users + +@table @code + +@item -t @var{cylinder skew} +Uses a different track skew than the default (14). For more details on +skews, @pxref{superformat}. In this version of xdfcopy, the @code{-t} +parameter is ignored. + +@item -h @var{head skew} +Uses a different head skew than the default (0) In this version, this +parameter is ignored + +@item -d +Debugging. For each read or write operation, the time it took to +complete the operation is printed (in milliseconds). This can be used +to optimize the skews. + +@item -T @var{end-cylinders} +Tells how many cylinders to format. With the XXDF formats, it is +actually possible to format up to 83 cylinders, yielding a format of +up to 1992KB on a 3 1/2 high density disk. + +@end table diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..89fc9b0 --- /dev/null +++ b/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..0801ec2 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,32 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Last modified: 1994-03-25 +# Public domain + +errstatus=0 + +for file in ${1+"$@"} ; do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d in ${1+"$@"} ; do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "$pathcomp" || errstatus=$? + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/src/MAKEFLOPPIES b/src/MAKEFLOPPIES index e8b872f..efacd38 100755 --- a/src/MAKEFLOPPIES +++ b/src/MAKEFLOPPIES @@ -97,6 +97,7 @@ cmosid () # main() +PERMISSION=666 while [ $# -ge 1 -o -n "${REMAINDER}" ]; do if [ -n "$REMAINDER" ]; then ## Continue processing options stuck together @@ -144,6 +145,9 @@ while [ $# -ge 1 -o -n "${REMAINDER}" ]; do [vV]) VERBOSE=yes ;; + ## Allow access only for group floppy + [gG]) PERMISSION=660 ;; + *) echo "$0: unrecognized argument \"$ARG\"." >&2 USAGE=yes ;; @@ -159,6 +163,7 @@ if [ -n "$USAGE" ]; then -d Name devices for drive type -m Name devices for media type -u Use the same letter (u) for all 3 1/2 devices + -g Allow access only for group floppy -v Verbose ' >&2 exit 1 @@ -209,7 +214,7 @@ for DRIVE in $DRIVES; do if [ -z "$DRYRUN" ]; then mknod "$FILE" b "$MAJOR" "$BASENUMBER" chown root.floppy "$FILE" - chmod 666 "$FILE" + chmod ${PERMISSION} "$FILE" fi if [ -n "$VERBOSE" -o -n "$DRYRUN" ]; then echo mknod "$FILE" b "$MAJOR" "$BASENUMBER" @@ -233,7 +238,7 @@ for DRIVE in $DRIVES; do if [ -z "$DRYRUN" ]; then mknod "${FILE}${NAME}" b "$MAJOR" "$MINOR" chown root.floppy "${FILE}${NAME}" - chmod 666 "${FILE}${NAME}" + chmod ${PERMISSION} "${FILE}${NAME}" fi if [ -n "$VERBOSE" -o -n "$DRYRUN" ]; then echo mknod "${FILE}${NAME}" b "$MAJOR" "$MINOR" diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index fb9a0b2..0000000 --- a/src/Makefile +++ /dev/null @@ -1,112 +0,0 @@ -# Define PIDFILE if you want to have the pid of the diskseekd stored -# somewhere on the filesystem. You'll get a (very) little shell -# script diskseek.sh that uses this to connect with the daemon -# when the disk should be cleaned by hand. In that case it's a replacement -# for diskseek. If you don't want to have this feature, don't define it. -# -DEFINES=-DPIDFILE=\"/var/run/diskseekd.pid\" - -CC=gcc -OBJECTS=enh_options.o floppycontrol.o superformat.o -SOURCES=enh_options.c floppycontrol.o superformat.c -MANPAGES1=diskd.1 diskseekd.1 fdrawcmd.1 floppycontrol.1 getfdprm.1 \ -makefloppies.1 superformat.1 xdfcopy.1 fdmount.1 -MANPAGES4=fd.4 -MANPAGES8=setfdprm.8 -CFLAGS=-O4 -fno-strength-reduce -Wall $(DEFINES) -LDFLAGS=-s -#CFLAGS=-O4 -g -Wall $(DEFINES) -#LDFLAGS=-N - -DESTDIR= -MANDIR=${DESTDIR}/usr/man -MANDIR1=$(MANDIR)/man1 -MANDIR4=$(MANDIR)/man4 -MANDIR8=$(MANDIR)/man8 -SBIN=${DESTDIR}/usr/sbin -BIN=${DESTDIR}/usr/bin -PERM=755 -SPERM=4750 -#we only people in group floppy to run priviledged programs -MANPERM=644 -UID = root -GID = floppy -INSTALL = install - -all: floppycontrol getfdprm setfdprm fdrawcmd \ -superformat xdfcopy fdmount diskseekd diskd - -floppycontrol.o getfdprm setfdprm: /usr/include/linux/fd.h -diskseekd.o superformat.o fdrawcmd.o: /usr/include/linux/fd.h \ - /usr/include/linux/fdreg.h - -floppycontrol: enh_options.o floppycontrol.o - ${CC} $(LDFLAGS) -o floppycontrol enh_options.o floppycontrol.o - -diskd: enh_options.o diskd.o - ${CC} $(LDFLAGS) -o diskd enh_options.o diskd.o - -diskseekd: enh_options.o diskseekd.o - ${CC} $(LDFLAGS) -o diskseekd enh_options.o diskseekd.o - -diskseek: diskseekd - ln -s diskseekd diskseek - -superformat: message_seen enh_options.o superformat.o - ${CC} $(LDFLAGS) -o superformat enh_options.o superformat.o - -fdrawcmd: fdrawcmd.o - ${CC} $(LDFLAGS) -o fdrawcmd fdrawcmd.o - -getfdprm: getfdprm.o - ${CC} $(LDFLAGS) -o getfdprm getfdprm.o - -setfdprm: setfdprm.c - ${CC} $(LDFLAGS) $(CFLAGS) -o setfdprm setfdprm.c - -clean: - -rm -f *~ *.orig *.o a.out core 2>/dev/null - -spotless: clean - -rm -f floppycontrol superformat getfdprm fdrawcmd diskseekd diskd \ - diskseek diskd_old setfdprm xdfcopy fdmount 2>/dev/null - -message_seen: - @cat message - @read a - @touch message_seen - -install: install.bin install.man - @grep -q '^floppy:' /etc/group \ - || echo 'Add a group "floppy" to /etc/group.' - -install.bin: all - install -c -m $(PERM) -o $(UID) -g $(GID) MAKEFLOPPIES $(SBIN) - install -c -s -m $(PERM) -o $(UID) -g $(GID) floppycontrol $(BIN) - install -c -s -m $(PERM) -o $(UID) -g $(GID) getfdprm $(BIN) - install -c -s -m $(PERM) -o $(UID) -g $(GID) setfdprm $(BIN) - install -c -s -m $(PERM) -o $(UID) -g $(GID) fdrawcmd $(BIN) - install -c -s -m $(PERM) -o $(UID) -g $(GID) superformat $(BIN) - install -c -s -m $(PERM) -o $(UID) -g $(GID) xdfcopy $(BIN) - install -c -s -m $(SPERM) -o $(UID) -g $(GID) fdmount $(BIN) - install -c -s -m $(SPERM) -o $(UID) -g $(GID) fdmount $(BIN)/fdumount - ( cd $(BIN); \ - ln -sf xdfcopy $(BIN)/xdfformat; \ - ln -sf fdmount $(BIN)/fdumount; \ - ln -sf fdmount $(BIN)/fdlist; \ - ln -sf fdmount $(BIN)/fdmountd ) - -install.man: - install -c -m $(MANPERM) -o $(UID) -g $(GID) $(MANPAGES1) $(MANDIR1) - install -c -m $(MANPERM) -o $(UID) -g $(GID) $(MANPAGES4) $(MANDIR4) - install -c -m $(MANPERM) -o $(UID) -g $(GID) $(MANPAGES8) $(MANDIR8) - ( cd $(MANDIR1); \ - ln -sf fdmount.1 $(MANDIR1)/fdumount.1; \ - ln -sf fdmount.1 $(MANDIR1)/fdlist.1; \ - ln -sf fdmount.1 $(MANDIR1)/fdmountd.1; \ - ln -sf xdfcopy.1 $(MANDIR1)/xdfformat.1 ) - -install.zman: - for i in $(MANPAGES1); do gzip < $$i >_; install -c -m $(MANPERM) -o $(UID) -g $(GID) _ $(MANDIR1).Z/$$i; done - for i in $(MANPAGES4); do gzip < $$i >_; install -c -m $(MANPERM) -o $(UID) -g $(GID) _ $(MANDIR4).Z/$$i; done - for i in $(MANPAGES8); do gzip < $$i >_; install -c -m $(MANPERM) -o $(UID) -g $(GID) _ $(MANDIR8).Z/$$i; done diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..bdac270 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,138 @@ +# Define PIDFILE if you want to have the pid of the diskseekd stored +# somewhere on the filesystem. You'll get a (very) little shell +# script diskseek.sh that uses this to connect with the daemon +# when the disk should be cleaned by hand. In that case it's a replacement +# for diskseek. If you don't want to have this feature, don't define it. +# + + +top_srcdir=@top_srcdir@ +srcdir=@srcdir@ +VPATH=@srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +infodir = @infodir@ +mandir = @mandir@ +infodir = @infodir@ +sysconfdir = @sysconfdir@ + +CC = @CC@ +PID = -DPIDFILE=\"@localstatedir@/run/diskseekd.pid\" +DEFINES = $(DEFINES) $(PID) -DSYSCONFDIR=\"@sysconfdir@\" +DEFS = @DEFS@ -DSYSCONFDIR=\"@sysconfdir@\" +CPPFLAGS = -I. -I@srcdir@ @CPPFLAGS@ $(DEFS) +CFLAGS = -Wall @CFLAGS@ + +LDFLAGS = @LDFLAGS@ +LIBS = -L. -lfdutils @LIBS@ +SHLIB = @SHLIB@ +MACHDEPLIBS = @MACHDEPLIBS@ +LN_S = @LN_S@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + + + +OBJECTS=enh_options.o floppycontrol.o superformat.o +SOURCES=enh_options.c floppycontrol.o superformat.c +MANPAGES1=diskd.1 diskseekd.1 fdrawcmd.1 floppycontrol.1 getfdprm.1 \ +makefloppies.1 superformat.1 xdfcopy.1 fdmount.1 +MANPAGES4=fd.4 +MANPAGES8=setfdprm.8 + + + +PERM=755 +SPERM=4750 +#we only people in group floppy to run priviledged programs +MANPERM = 644 +UID = root +GID = floppy + + + +all: floppycontrol getfdprm setfdprm fdrawcmd \ +superformat xdfcopy fdmount diskseekd diskd floppymeter convertfdprm + + +LIBFILES=lex.mediaprm.o lex.driveprm.o mediaprm.o driveprm.o parse.o \ + oldfdprm.o enh_options.o measure.o printfdprm.o calc-format.o \ + misc.o skews.o + +lex.%.c: %.lex + lex -P$* $< + +libfdutils.a: libfdutils.a($(LIBFILES)) + ranlib libfdutils.a + +floppycontrol.o getfdprm setfdprm: /usr/include/linux/fd.h +diskseekd.o superformat.o fdrawcmd.o: /usr/include/linux/fd.h \ + /usr/include/linux/fdreg.h + +convertfdprm: convert.o libfdutils.a + ${CC} $(LDFLAGS) -o $@ $< $(LIBS) + +floppycontrol: floppycontrol.o libfdutils.a + ${CC} $(LDFLAGS) -o $@ $< $(LIBS) + +diskd: diskd.o libfdutils.a + ${CC} $(LDFLAGS) -o $@ $< $(LIBS) + +diskseekd: diskseekd.o libfdutils.a + ${CC} $(LDFLAGS) -o $@ $< $(LIBS) + +diskseek: diskseekd + ln -s diskseekd diskseek + +superformat: superformat.o libfdutils.a + ${CC} $(LDFLAGS) -o $@ $< $(LIBS) + +floppymeter: floppymeter.o libfdutils.a + ${CC} ${LDFLAFS} -o $@ $< $(LIBS) + +fdrawcmd: fdrawcmd.o + ${CC} $(LDFLAGS) -o $@ $< $(LIBS) + +getfdprm: getfdprm.o libfdutils.a + ${CC} $(LDFLAGS) -o $@ $< $(LIBS) + +setfdprm: setfdprm.c libfdutils.a + ${CC} $(LDFLAGS) $(CFLAGS) -o $@ $< $(LIBS) + +clean: + -rm -f *~ *.orig *.o a.out *.a lex.*.c core 2>/dev/null + +spotless: clean + -rm -f floppycontrol superformat getfdprm fdrawcmd diskseekd diskd \ + diskseek diskd_old setfdprm xdfcopy fdmount 2>/dev/null + +install: install.bin install.conf + @grep -q '^floppy:' /etc/group \ + || echo 'Add a group "floppy" to /etc/group.' + + +install.conf: + if [ ! -f $(sysconfdir)/mediaprm ] ; then \ + cp $(srcdir)/mediaprm $(sysconfdir) ; \ + fi + +install.bin: all + $(INSTALL) -c -m $(PERM) -o $(UID) -g $(GID) $(srcdir)/MAKEFLOPPIES $(bindir) + $(INSTALL) -c -s -m $(PERM) -o $(UID) -g $(GID) floppycontrol $(bindir) + $(INSTALL) -c -s -m $(PERM) -o $(UID) -g $(GID) floppymeter $(bindir) + $(INSTALL) -c -s -m $(PERM) -o $(UID) -g $(GID) getfdprm $(bindir) + $(INSTALL) -c -s -m $(PERM) -o $(UID) -g $(GID) setfdprm $(bindir) + $(INSTALL) -c -s -m $(PERM) -o $(UID) -g $(GID) fdrawcmd $(bindir) + $(INSTALL) -c -s -m $(PERM) -o $(UID) -g $(GID) superformat $(bindir) + $(INSTALL) -c -s -m $(PERM) -o $(UID) -g $(GID) xdfcopy $(bindir) + $(INSTALL) -c -s -m $(SPERM) -o $(UID) -g $(GID) fdmount $(bindir) + $(INSTALL) -c -s -m $(SPERM) -o $(UID) -g $(GID) fdmount $(bindir)/fdumount + ( cd $(bindir); \ + ln -sf xdfcopy $(bindir)/xdfformat; \ + ln -sf fdmount $(bindir)/fdumount; \ + ln -sf fdmount $(bindir)/fdlist; \ + ln -sf fdmount $(bindir)/fdmountd ) diff --git a/src/SIR b/src/SIR new file mode 100644 index 0000000..ae4916b --- /dev/null +++ b/src/SIR @@ -0,0 +1,5 @@ +* BUG: chunksize setting ignored +* ENHANCE: use smaller chunksizes spontaneously (ok) maxchunksize +* ENHANCE: print elapsed time for read. +* ENHANCE: optionnally limit to one sequence (with biggest sector last) +* ENHANCE: accept geometry in one string diff --git a/src/calc-format.c b/src/calc-format.c new file mode 100644 index 0000000..0e345e6 --- /dev/null +++ b/src/calc-format.c @@ -0,0 +1,515 @@ +#include +#include +#include "superformat.h" +#include "fdutils.h" + +#define GAP_DIVISOR (128*128) + +#define GAPSIZE(j) (( (128<= 0 && fd->last_sect[j] <= i; j--); + return j; +} + + +static inline int firstSector(struct params *fd, int i) +{ + if(i>=MAX_SIZECODE-1) + return 1; + else + return fd->last_sect[i+1]; +} + +static inline int lastSector(struct params *fd, int i) +{ + return fd->last_sect[i]; +} + +static inline int nrSectorsForSize(struct params *fd, int i) +{ + return lastSector(fd, i) - firstSector(fd, i); +} + + +static inline int isMultisize(struct params *fd) +{ + int i, n; + + n = 0; + for(i = 1; i < MAX_SIZECODE; i++) { + if(nrSectorsForSize(fd, i)) + n++; + } + return n > 1; +} + +static int compute_tot_size(struct params *fd, + int chunksize, + int gap, + int tailsize) +{ + int i, nr; + + fd->nssect = 0; + fd->actual_interleave = 1; + for(i= 0; i < MAX_SIZECODE; i++){ + nr = nrSectorsForSize(fd, i); + fd->nssect += chunks_in_sect(fd, i, gap, chunksize) * nr; + if(nr && GAPSIZE(i) < 34) + fd->actual_interleave = 2; + } + + if (tailsize >= 0) + return (fd->nssect - + chunks_in_sect(fd, tailsize, gap, chunksize)) * + chunksize + SSIZE(tailsize); + else + return fd->nssect * chunksize; +} + +/* find out how many sectors of each size there are */ +static void compute_sizes(struct params *fd, + int remaining, /* bytes per track */ + int max_sizecode) /* size of biggest sector used */ +{ + int cur_sector; + int sizes; /* number of different sizes found along the track */ + int i; + int nr_sectors; + + cur_sector = 1; + sizes=0; + for (i=MAX_SIZECODE-1; i>=0; --i) { + if(i > max_sizecode) + nr_sectors = 0; + else { + nr_sectors = remaining >> (i+7); + remaining -= nr_sectors << (i+7); + } + cur_sector += nr_sectors; + fd->last_sect[i] = cur_sector; + if(nr_sectors) + sizes++; + } + fd->dsect = cur_sector-1; /* number of data sectors */ + if(sizes > 1) + fd->need_init = 1; + + if (remaining) { + fprintf(stderr,"Internal error: remaining not 0\n"); + abort(); + } +} + +static int compute_gap(struct params *fd, int track_size) +{ + int gap; + + gap = (fd->raw_capacity-track_size)*track_size/GAP_DIVISOR-header_size; + if (gap > 0x6c * 32) + /* kludge to allow to format at least the usual + * formats on out of tolerance drives */ + gap = 0x6c * 32; + if (gap < 0) + gap = 0; + return gap; +} + +/* + * Determine the chunk size for disks which have same sized sectors. + * We do this by dividing the sector size through ever increasing + * divisors. t_chunksize = ceil( sector_size / divisor ) + * We skip divisors yielding unreachable chunk sizes. + */ + +static int compute_chunk_size_for_monosize(struct params *fd, + int gap, + int tailsize) +{ + int min_chunksize; /* minimal chunk size reached so far */ + int t_chunksize; /* tentative chunk size */ + int ceiling; /* maximal divisor */ + int t_sect_size; /* tentative sector size */ + int min_sect_size=0; /* actual sector size */ + int sector_size; + int chunks_per_sect; + int i; + + sector_size = SSIZE(sizeOfSector(fd,1)); + min_chunksize = 0; + ceiling = sector_size /( 129 + header_size); + for(i= 1; i <= ceiling; i++ ){ + t_chunksize = (sector_size - 1)/i + 1; + + /* unreachable chunk sizes */ + if (((t_chunksize-header_size-1) & 511) > 255 && + t_chunksize > 768 + header_size) + continue; + + chunks_per_sect = (sector_size - 1)/t_chunksize + 1; + t_sect_size = chunks_per_sect * t_chunksize; + + /* find the smallest sector size */ + if (!min_chunksize || t_sect_size < min_sect_size ){ + min_sect_size = t_sect_size; + min_chunksize = t_chunksize; + } + if (t_sect_size == sector_size) + break; + } + if(min_chunksize != sector_size) + fd->need_init = 1; + return min_chunksize; +} + + +static int compute_chunk_size_for_multisize(struct params *fd, + int gap, + int tailsize) +{ + int t_chunksize; + int tot_size; + int min_chunksize; + int i; + int min_tot_size = 0; + + min_chunksize = 0; + fd->need_init = 1; + for(t_chunksize = fd->max_chunksize; + t_chunksize > 128+header_size; + t_chunksize--){ + for(i=0; i < MAX_SIZECODE; i++ ){ + if(t_chunksize<(128<= 6) + printf("%d chasing %d\n", + t_chunksize, min_chunksize); +#endif + min_tot_size = tot_size; + min_chunksize = t_chunksize; + } + } + return min_chunksize; +} + + + +static void compute_chunk_size(struct params *fd, + int gap, + int tailsize) + +{ + if (isMultisize(fd)) + fd->chunksize = compute_chunk_size_for_multisize(fd, gap, + tailsize); + else + fd->chunksize = compute_chunk_size_for_monosize(fd, gap, + tailsize); +} + + +/* convert chunksize to sizecode/fmt_gap pair */ +static void convert_chunksize(struct params *fd) +{ + int i; + + + for (i=0; i < MAX_SIZECODE; ++i) { + if (fd->chunksize < (128 << i) + header_size + 1) { + fprintf(stderr,"Bad chunksize %d\n", fd->chunksize); + exit(1); + } + if (fd->chunksize <= (128 << i) + 256 + header_size) { + fd->sizecode = i; + fd->fmt_gap = fd->chunksize - (128 << i) - header_size; + break; + } + } + if (i == MAX_SIZECODE){ + fprintf(stderr,"Chunksize %d too big\n", fd->chunksize ); + exit(1); + } +} + + + +/* + * calculate the ordering of the sectors along the track in such + * a way that the last one is sector number + */ +static void calc_sequence(struct params *fd, int tailsect) +{ + int sec_id, cur_sector, i; + + fd->sequence = SafeNewArray(fd->dsect,struct fparm2); + cur_sector = fd->dsect-1; + + /* construct the sequence while working backwards. cur_sector + * points to the place where the next sector will be placed. + * We place it, then move circularily backwards placing more + * and more sectors */ + sec_id = tailsect; + fd->rotations = 0; + for(i=0; i < fd->dsect; + i++, cur_sector -= fd->actual_interleave, sec_id--) { + if (sec_id == 0) + sec_id = fd->dsect; + + if ( cur_sector < 0) { + cur_sector += fd->dsect; + if(sec_id != fd->dsect) + fd->rotations++; + } + + /* slot occupied, look elsewhere */ + while(fd->sequence[cur_sector].sect ){ + cur_sector--; + if ( cur_sector < 0 ) { + cur_sector += fd->dsect; + if(sec_id != fd->dsect) + fd->rotations++; + } + } + + /* place the sector */ + fd->sequence[cur_sector].sect = sec_id; + fd->sequence[cur_sector].size = sizeOfSector(fd, sec_id); + } + + /* handle wrap-around between tailsect and tailsect+1 */ + if(tailsect != fd->dsect) { + /* always add one rotation, because tailsect+1 cannot be + * at the last position, thus is necessarily earlyer */ + fd->rotations++; + + if(fd->actual_interleave == 2 && + cur_sector + fd->actual_interleave == 1) + /* if we use interleave, and the last sector was + * placed at the first last position, add one + * extra rotation for tailsect+1 following tailsect + * too closely */ + fd->rotations++; + } +} + + +/* given the sequence, calculate the exact placement of the sectors */ +static void calc_placement(struct params *fd, int gap) +{ + int cur_sector, i, max_offset; + int track_end=0; + int final_slack; /* slack space extending from data start of last + * sector on the track to fd->raw_capacity mark */ + + /* now compute the placement in terms of small sectors */ + cur_sector = 0; + for(i=0; i< fd->dsect; i++){ + fd->sequence[i].offset = cur_sector; + max_offset = cur_sector; + + /* offset of the starting sector */ + if ( fd->sequence[i].sect == 1 ) + fd->min = cur_sector * fd->chunksize; + + /* offset of the end of the of the highest sector */ + if (fd->sequence[i].sect == fd->dsect) + track_end = cur_sector * fd->chunksize + + header_size + index_size + + SSIZE(fd->sequence[i].size); + + if(i == fd->dsect - 1) + break; + + cur_sector += chunks_in_sect(fd, + fd->sequence[i].size, + gap, fd->chunksize); + } + final_slack = fd->raw_capacity - cur_sector * fd->chunksize - + header_size - index_size - 1; + if(final_slack < 0) { + fprintf(stderr, + "Internal error, negative final slack %d\n", + final_slack); + abort(); + } + fd->max = fd->min + final_slack; + + fd->length = fd->rotations * fd->raw_capacity + track_end - fd->min; + if(fd->length < 0) { + fprintf(stderr, + "Internal error, negative track length %d %d %d\n", + fd->length, track_end, fd->min); + abort(); + exit(1); + } + + + /* this format accepts any offsets ranging from fd->min to fd->max. + * After this track, the current offset will be: + * fd->track_end + initial_offset - fd->min + */ +} + + +static int compute_chunks_per_sect(struct params *fd, + int tracksize, + int sizecode, + int *gap, + int mask, + int tailsize) +{ + int tot_size; + + if (! (mask & SET_FMTGAP)) + *gap = compute_gap(fd, tracksize); + while(1) { + compute_chunk_size(fd, *gap, tailsize); + tot_size=compute_tot_size(fd, fd->chunksize, *gap, tailsize); + if(fd->raw_capacity >= tot_size) + /* enough space available, ok */ + break; + if ((mask & SET_FMTGAP) || *gap <= 0) + /* does not fit on disk */ + return -1; + + *gap -= (tot_size-fd->raw_capacity) * GAP_DIVISOR / tracksize; + if (*gap < 0) + *gap = 0; + } + + convert_chunksize(fd); + + if (mask & SET_INTERLEAVE) + fd->actual_interleave = fd->preset_interleave; + + if(verbosity >= 9) { + printf("%d raw bytes per cylinder\n", tot_size ); + printf("%d final gap\n", + fd->raw_capacity - tot_size ); + } + return 0; +} + +static void compute_sector_sequence(struct params *fd, int tailsect, int gap) +{ + calc_sequence(fd, tailsect); + calc_placement(fd, gap); + + if (verbosity >= 9) + printf("chunksize=%d\n", fd->chunksize); +} + + +static void compute_all_sequences_for_size(struct params *fd, + int *offset, + int tracksize, + int sizecode, + int gap, + int mask, + int tailsize) +{ + int base = *offset; + int i; + + /* no sectors of this size */ + if(!nrSectorsForSize(fd, tailsize)) + return; + + fd[*offset] = fd[0]; + if(compute_chunks_per_sect(fd + *offset, tracksize, sizecode, + &gap, /* gap. expressed in 1/256 bytes */ + mask, tailsize) < 0) { + /* not enough raw space for this arrangement */ + return; + } + + for(i = firstSector(fd, tailsize); + i < lastSector(fd, tailsize); + i++) { + fd[*offset] = fd[base]; + compute_sector_sequence(fd+*offset, i, gap); + (*offset)++; + } +} + + + +int compute_all_sequences(struct params *fd, + int tracksize, + int sizecode, + int gap, + int mask, + int biggest_last) +{ + int offset, i; + + compute_sizes(fd, sectors*512,sizecode); + + offset = 0; + for(i=MAX_SIZECODE - 1 ; i >= 0; i--) { + compute_all_sequences_for_size(fd, &offset, tracksize, + sizecode, gap, mask, i); + if(biggest_last && offset) + break; + } + + if(! offset){ + fprintf(stderr, + "Not enough raw space on this disk for this format\n"); + exit(1); + } + return offset; +} + + + +void compute_track0_sequence(struct params *fd) +{ + int i; + int sectors; + + sectors= fd->nssect = fd->dsect; + + fd->length = fd->raw_capacity; + fd->chunksize = 0x6c + 574; + + fd->need_init = 0; + fd->sequence = SafeNewArray(fd->dsect,struct fparm2); + + fd->sizecode = 2; + if ( fd->rate & 0x40 ) + fd->fmt_gap = 0x54; + else + fd->fmt_gap = 0x6c; + fd->min = 0; + + for(i=0; isequence[i].sect = i+1; + fd->sequence[i].size = 2; + fd->sequence[i].offset = i; + } +} diff --git a/src/convert.c b/src/convert.c new file mode 100644 index 0000000..7730f20 --- /dev/null +++ b/src/convert.c @@ -0,0 +1,83 @@ +/* setfdprm.c - Sets user-provided floppy disk parameters, re-activates + autodetection and switches diagnostic messages. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "oldfdprm.h" +#include "printfdprm.h" + +#define FDPRMFILE "/etc/fdprm" +#define MAXLINE 200 + +static int col = 0; + +static int cpm=1; +level_t level = LEV_NONE; + +static void print_token(char *fmt, int param) +{ + char buffer[50]; + int l; + + sprintf(buffer, fmt, param); + l = strlen(buffer); + + if(l + col > 70) { + printf("\n"); + col = 1; + } + printf(" %s", buffer); + col += l+1; +} + + +static void _print_params(char *name, char *comment, struct floppy_struct *ft) +{ + printf("\n\"%s\":", name); + if(comment) + printf(" #%s", comment); + else + printf("\n"); + col = 0; + print_params(0, ft, level, cpm, print_token); +} + +static void usage(char *name) +{ +} + + +void main(int argc,char **argv) +{ + struct floppy_struct ft; + char *name = argv[0]; + + + if (argc > 1 && *argv[1] == '-') { + switch (argv[1][1]) { + case 'e': + level = LEV_EXPL; + break; + case 'm': + level = LEV_MOST; + break; + case 'a': + level = LEV_ALL; + break; + default: + usage(name); + } + argc--; + argv++; + } + + scan_fdprm(stdin, 0, &ft, _print_params); + exit(0); +} diff --git a/src/diskd.1 b/src/diskd.1 deleted file mode 100644 index 1329bf6..0000000 --- a/src/diskd.1 +++ /dev/null @@ -1,62 +0,0 @@ -.TH DISKD 1 "5mar1995" "fdutils" "fdutils" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -diskd \- disk daemon; wait for disk to be inserted -.SH SYNOPSIS -.hy 0 -.na -.B diskd -[\fB\-d \fIdrive\fR] -[\fB\-i \fIinterval\fR] -[\fB\-e \fIcommand\fR] -.ad b -.hy 1 -.SH DESCRIPTION -Diskd waits for a disk to be inserted into a given -.I drive\c -, and then either executes the -.I command -or exits. This program can be used to automatically mount a disk as -soon as it is inserted. -.SH WARNING -This program works by switching the motor on for a very short -interval, and then seeking to track -1. This might damage hardware in -the long run. Amiga disk drives are known to have difficulties to -start up after a while. (Amigas also use this technique to -automatically mount disks as soon as they are inserted. -.SH OPTIONS -.TP -.BI "-d " "drive" -Selects the drive to observe for disk insertion. By default, drive 0 -.RI ( /dev/fd0 ) -is observed. -.TP -.BI "-i " "interval" -Selects the polling interval. The interval is given in tenths of -seconds. Default is 10 (one second). -.TP -.BI "-e " "command" -Gives the command to be executed when a disk is inserted. If no -command is given the program simply exits. Typically, the command -mounts the disk. It can be a shell scripts which probes for several -filesystems and disk geometries until it succeeds. -.SH BUGS -Automatic unmounting cannot yet be handled. It is indeed not enough -to scan for disk removal, because that would be too late: There might -be some buffers needing flushing. -.PP -The drive motor is running all the time, and on some computers, the -drive led flickers at each time the drive is polled. -.SH FILES -/dev/fd* - Floppy devices -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr -.SH SEE ALSO -.BR superformat (1), -.BR getfdprm (1), -.BR floppycontrol (1), -.BR fdrawcmd (1) diff --git a/src/diskseekd.1 b/src/diskseekd.1 deleted file mode 100644 index 0cbef25..0000000 --- a/src/diskseekd.1 +++ /dev/null @@ -1,66 +0,0 @@ -.TH DISKD 1 "17nov1995" "fdutils" "fdutils" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -diskseek, diskseekd \- disk seek daemon; simulates Messy Dos' drive cleaning effect -.SH SYNOPSIS -.hy 0 -.na -.B diskseekd -[\fB\-d \fIdrive\fR] -[\fB\-i \fIinterval\fR] -[\fB\-p \fIpidfile\fR] -.ad b -.hy 1 -.SH DESCRIPTION -Several people have noticed that Linux has a bad tendency of killing -floppy drives. These failures remained completely mysterious, until -somebody noticed that they were due to huge layers of dust -accumulating in the floppy drives. This cannot happen under Messy Dos, -because this excuse for an operating system is so unstable that it -crashes roughly every 20 minutes (less when you are running -Windows). When rebooting, the BIOS seeks the drive, and by doing this, -it shakes the dust out of the drive mechanism. -.PP -.B diskseekd -simulates this effect by seeking the drive periodically. If it is -called as -.BR diskseek , -the drive is seeked only once. -.SH OPTIONS -.TP -.BI "-d " "drive" -Selects the drive to seek. By default, drive 0 -.RI ( /dev/fd0 ) -is seeked. -.TP -.BI "-i " "interval" -Selects the cleaning interval, in -seconds. -If the interval is 0, a single -seek is done. This is useful when calling diskseek from a crontab. -The default is 1000 seconds (about 16 minutes) for -.B diskseekd -and 0 for -.BR diskseek . -.TP -.BI "-p " "pidfile" -Stores the process id of the diskseekd daemon into -.I pidfile -instead of the default -.IR /var/run/diskseekd.pid . -.SH BUGS -1. Other aspects of Messy Dos' flakiness are not simulated. -2. This manpage lacks a few smileys. -.SH FILES -/dev/fd* - Floppy devices -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr -.SH SEE ALSO -.BR superformat (1), -.BR getfdprm (1), -.BR floppycontrol (1), -.BR fdrawcmd (1) diff --git a/src/diskseekd.c b/src/diskseekd.c index 0c205f3..9b0409e 100644 --- a/src/diskseekd.c +++ b/src/diskseekd.c @@ -14,6 +14,7 @@ #include #include "enh_options.h" #include +#include int eioctl(int fd, int command,void * param, char *emsg) { @@ -33,7 +34,7 @@ int eioctl(int fd, int command,void * param, char *emsg) void dummy(int dummy) {} -void main(int argc, char **argv) +int main(int argc, char **argv) { int mask=0; int fd=-2; @@ -159,4 +160,5 @@ void main(int argc, char **argv) exit(1); } } + return 0; } diff --git a/src/driveprm.c b/src/driveprm.c new file mode 100644 index 0000000..b6905f7 --- /dev/null +++ b/src/driveprm.c @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include +#include +#include +#include "parse.h" +#include "driveprm.h" +#include "driveprmP.h" + +typedef drive_field_t field_t; + +static int TPI, RPM, DEVIATION, FF, DENSITY, CMOS; + +#define F_CMOS FE__CMOS,&CMOS +#define F_TPI FE__TPI,&TPI +#define F_FF FE__FF,&FF +#define F_RPM FE__RPM,&RPM +#define F_DEVIATION FE__DEVIATION,&DEVIATION +#define F_DENSITY FE__DENSITY,&DENSITY + +drivetypedesc_t cmos_types[]= { + { 0, FF_UNKNOWN, DENS_UNKNOWN, 0, 0 }, + { 1, FF_525, DENS_DD, 48, 300, 0 }, + { 2, FF_525, DENS_HD, 96, 360, 0 }, + { 3, FF_35, DENS_DD, 0, 300, 0 }, + { 4, FF_35, DENS_HD, 0, 300, 0 }, + { 5, FF_35, DENS_ED, 0, 300, 0 }, + { 6, FF_35, DENS_ED, 0, 300, 0 } +}; + +static keyword_t ids[]= { + { "cmos", F_CMOS, 0}, + { "tpi", F_TPI, 0 }, + + { "rpm", F_RPM, 0}, + { "deviation", F_DEVIATION, 0}, + + { "sd", F_DENSITY, DENS_SD }, + { "dd", F_DENSITY, DENS_DD }, + { "qd", F_DENSITY, DENS_QD }, + { "hd", F_DENSITY, DENS_HD }, + { "ed", F_DENSITY, DENS_ED }, + + { "5.25", F_FF, FF_525 }, + { "3.5", F_FF, FF_35 }, + { "8", F_FF, FF_8 } +}; + +static int mask; + +#define ISSET(x) ((mask) & ( 1 << FE__##x)) + +static void compute_params(drivedesc_t *drive) +{ + /* initialize out array */ + drive->type.cmos = 0; + + drive->type.ff = FF_UNKNOWN; + drive->type.max_density = DENS_UNKNOWN; + + drive->type.tpi = 0; + drive->type.rpm = 0; + drive->type.deviation = 0; + + if(!ISSET(CMOS)) { + if(ISSET(FF) && ISSET(DENSITY)) { + switch(DENSITY) { + case DENS_DD: + if(FF == FF_525) + CMOS = 1; + else + CMOS = 3; + break; + case DENS_HD: + switch(FF) { + case FF_525: + CMOS = 2; + break; + case FF_35: + CMOS = 4; + break; + } + break; + case DENS_ED: + switch(FF) { + case FF_35: + CMOS = 6; + break; + } + break; + } + } else { + CMOS = drive->drvprm.cmos; + if (CMOS < 1 || CMOS > 6) + CMOS = 4; + } + } + + if(CMOS) { + if(CMOS > 6 || CMOS < 1) { + fprintf(stderr, "Bad cmos code %d\n", CMOS); + exit(1); + } + drive->type = cmos_types[CMOS]; + } + + if(ISSET(RPM)) + drive->type.rpm = RPM; + + if(ISSET(TPI)) + drive->type.tpi = TPI; + + if(ISSET(FF)) + drive->type.ff = FF; + + if(ISSET(DENSITY)) + drive->type.max_density = DENSITY; + + if(ISSET(RPM)) + drive->type.rpm = RPM; + + if(ISSET(DEVIATION)) + drive->type.deviation = DEVIATION; + + drive->mask = mask; +} + +static int getdrivenum(int fd, struct stat *buf) +{ + int num; + + if (fstat (fd, buf) < 0) { + perror("Can't fstat drive"); + exit(1); + } + + if (!S_ISBLK(buf->st_mode) || + MAJOR(buf->st_rdev) != FLOPPY_MAJOR) { + fprintf(stderr,"Not a floppy drive\n"); + exit(1); + } + + num = MINOR( buf->st_rdev ); + return (num & 3) + ((num & 0x80) >> 5); +} + + +/* ========================================= * + * Routines called by other parts of fdutils * + * ========================================= */ + +int parse_driveprm(int fd, drivedesc_t *drive) +{ + int found; + + drive->drivenum = getdrivenum(fd, &drive->buf); + if(drive->drivenum < 0) + return -1; + + ioctl(fd, FDRESET, FD_RESET_IF_RAWCMD); + if (ioctl(fd, FDGETDRVPRM, & drive->drvprm ) < 0 ){ + perror("get drive characteristics"); + exit(1); + } + + zero_all(ids, &mask); + driveprmin = fopen(DRIVEPRMFILE, "r"); + + if(driveprmin) { + /* if the file doesn't exist, infer all info from the cmos type + * stored in the floppy driver */ + found = 0; + driveprmlex(drive->drivenum, ids, sizeof(ids)/sizeof(ids[0]), + &mask, &found); + if(!found) + zero_all(ids, &mask); + } + compute_params(drive); + return 0; +} diff --git a/src/driveprm.h b/src/driveprm.h new file mode 100644 index 0000000..cf21c4c --- /dev/null +++ b/src/driveprm.h @@ -0,0 +1,51 @@ +#ifndef DRIVEPRM_H +#define DRIVEPRM_H + +#define DRIVEPRMFILE SYSCONFDIR "/driveprm" + +#include +#include + +/* different densities */ +typedef enum +{ + DENS_UNKNOWN, DENS_SD, DENS_DD, DENS_QD, DENS_HD, DENS_ED +} density_t; + + +/* various drive form factors */ +typedef enum +{ + FF_UNKNOWN, FF_35, FF_525, FF_8 +} ff_t; + +typedef struct { + int cmos; + ff_t ff; + density_t max_density; /* maximal supported density */ + int tpi; + int rpm; + int deviation; +} drivetypedesc_t; + +/* drive descriptor */ +typedef struct { + drivetypedesc_t type; + int drivenum; /* the drive number [0-7] */ + struct stat buf; + struct floppy_drive_params drvprm; + int mask; +} drivedesc_t; + +int parse_driveprm(int fd, drivedesc_t *drive); + +typedef enum { + FE__UNKNOWN, + FE__CMOS, + FE__TPI, + FE__FF, + FE__RPM, + FE__DEVIATION, + FE__DENSITY, +} drive_field_t; +#endif diff --git a/src/driveprm.lex b/src/driveprm.lex new file mode 100644 index 0000000..5c68c8f --- /dev/null +++ b/src/driveprm.lex @@ -0,0 +1,59 @@ +%{ +#include +#include +#include "parse.h" +#include "driveprmP.h" +#include "driveprm.h" +static int lineno; +static int col; +%} + +%option noyywrap + +vid [A-Za-z_][A-Za-z0-9_]* +number (0x[a-zA-Z0-9]+|-?[0-9]+)(KB|s)? + +%% +\n { col = 0; lineno++;} +[ \t] col++; +#.*\n { col = 0; lineno++;} +drive[0-7]: { + col += yyleng; + if(*found) return 0; + _zero_all(ids, size, mask); + + yytext[yyleng-1]='\0'; + if(yytext[5] - '0' == drivenum) + *found = 1; +} + +3.5 | +5.25 | +8 | +ss | +SS | +ds | +DS | +sd | +SD | +dd | +DD | +qd | +QD | +hd | +HD | +ed | +ED | +{vid}={number} { + col += yyleng; + _set_int(yytext, ids, size, mask); +} + +[^\t \n][^\t =\n]* { + fprintf(stderr, + "Syntaxx error in " DRIVEPRMFILE + " at line %d col %d: %s unexpected\n", + lineno + 1, col + 1, yytext_ptr); + return 1; +} +%% diff --git a/src/driveprmP.h b/src/driveprmP.h new file mode 100644 index 0000000..c0f4d4c --- /dev/null +++ b/src/driveprmP.h @@ -0,0 +1,6 @@ +extern FILE *driveprmin; + +#define YY_DECL int driveprmlex(int drivenum, struct keyword_l *ids, int size, \ + int *mask, int *found) + +YY_DECL; diff --git a/src/fdmount.1 b/src/fdmount.1 deleted file mode 100644 index 48df29c..0000000 --- a/src/fdmount.1 +++ /dev/null @@ -1,382 +0,0 @@ -.TH FDMOUNT 1 "12nov1995" "fdutils" "fdutils" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -fdmount \- Floppy disk mount utility -.SH SYNOPSIS -.hy 0 -.na - -.B fdmount -.RB "[\|" \-l "\|]" -.RB "[\|" \-\-list "\|]" -.RB "[\|" \-d "\|]" -.RB "[\|" \-\-daemon "\|]" -.RB "[\|" \-\-detach "\|]" -.RB "[\|" \-i -.I interval -.RB "\|]" -.RB "[\|" \-\-interval -.I interval -.RB "\|]" -.RB "[\|" \-o -.I options -.RB "\|]" -.RB "[\|" \-r "\|]" -.RB "[\|" \-\-readonly "\|]" -.RB "[\|" \-s "\|]" -.RB "[\|" \-\-sync "\|]" -.RB "[\|" \-\-nosync "\|]" -.RB "[\|" \-\-nodev "\|]" -.RB "[\|" \-\-nosuid "\|]" -.RB "[\|" \-\-noexec "\|]" -.RB "[\|" \-f "\|]" -.RB "[\|" \-\-force "\|]" -.RB "[\|" \-h "\|]" -.RB "[\|" \-\-help "\|]" -.RI "[\|" drivename -.RI "[\|" mountpoint "\|]" -.RI "\|]" - -.B fdumount -.RB "[\|" \-f "\|]" -.RB "[\|" \-\-force "\|]" -.RI "[\|" drivename "\|]" - -.B fdlist - -.B fdmountd -.RB "[\|" \-i -.I interval -.RB "\|]" -.RB "[\|" \-\-interval -.I interval -.RB "\|]" -.RB "[\|" \-r "\|]" -.RB "[\|" \-\-readonly "\|]" -.RB "[\|" \-s "\|]" -.RB "[\|" \-\-sync "\|]" -.RB "[\|" \-\-nodev "\|]" -.RB "[\|" \-\-nosuid "\|]" -.RB "[\|" \-\-noexec "\|]" -.RI "[\|" drivename -.RI "[\|" mountpoint "\|]" -.RI "\|]" - -.ad b -.hy 1 - -.SH DESCRIPTION -The -.B fdmount -program mounts a floppy disk in the specified drive. It tries to -figure out the exact format and filesystem type of the disk from -data in the disk's boot sector or super block and the auto-detected -track layout. - -Currently, fdmount supports the filesystems -.I minix, ext, ext2, xia, -and -.I msdos, -and includes special support for disks formatted by the ms\-dos -.I 2M -utility. - -It also checks whether the disk is write protected, in which case -it is mounted read\-only. - -The symbolic -.I drivename -is (currently) one of -.B fd[0\-7], -corresponding to the special device files -.B /dev/fd[0\-7]. If -.I drivename -is not specified, fd0 is assumed. - -The disk is mounted on the directory -.I mountpoint, -if specified, or on -.B /fd[0\-7]. -In either case, the mount point must be an existing, writable -directory. - -.SH OPTIONS - -.TP -.B \-l \-\-list -List all known drives with their symbolic name, type, and mount -status. - -.TP -.B \-d \-\-daemon -Run in daemon mode (see below). - -.TP -.B \-\-detach -Runs daemon in background, and detaches it from its tty. Messages -produced after the fork are logged to syslog. - -.TP -.BI "\-p \-\-pidfile " file -Dumps the process id of the daemon to -.I file\c -\&. This makes killing the daemon easier: -.B kill -9 `cat file` - -.TP -.BI "\-i \-\-interval " "interval" -Set the polling interval for daemon mode. Unit is 0.1 seconds, default -is 10 (1 second). - -.TP -.BI "\-o \-\-options " "options" -Sets filesystem-specific options. So far, these are only available for -DOS and Ext2 disks. The following DOS options are supported: -.B check, conv, dotsOK, debug, fat, quiet, blocksize\c -\&. -The following Ext2 options are supported: -.B check, errors, grpid, bsdgroups, nogrpid, sysvgroups, bsddf, -.B minixdf, resgid, debug, nocheck -\&. -When running as a daemon, options not applying to the disk that is -inserted (because of its filesystem type) are not passed to mount. - -.TP -.B \-r \-\-readonly -Mount the disk read\-only. This is automatically assumed if the -disk is write protected. - -.TP -.B \-s \-\-sync -Mount with the SYNC option. - -.TP -.B \-\-nosync -Mounts without the SYNC option, even when not running as daemon. - -.TP -.B \-\-nodev -Mount with the NODEV option. Ignored for -.I msdos -filesystems, otherwise always set for non\-root users. - -.TP -.B \-\-nosuid -Mount with the NOSUID option. Ignored for -.I msdos -filesystems, otherwise always set for non\-root users. - -.TP -.B \-\-noexec -Mount with the NOEXEC option. - -.TP -.B \-f \-\-force -Attempt a mount or unmount operation even /etc/mtab says that -the drive is already mounted, or not mounted, respectively. -This option is useful if /etc/mtab got out of sync with the -actual state for some reason. - -.TP -.B \-h \-\-help -Show short parameter description - -.SH SECURITY - -When mounting on the default mount point, the mount points' owner -is set to the current user, and the access flags according to the -user's -.I umask. -For a specified -.I mountpoint, -owner and permissions are left unchanged. Default mount points are -called /fd0, /fd1, ... , /fd7 . - -The user running fdmount must have read access to the floppy device -for read only mounts, and read/write access for read/write mounts. - -Fdmount can be run suid root, allowing users to mount floppy -disks. The following restrictions are placed upon non\-root -users: - -If a -.I mountpoint -is specified explicitly, it must be owned by the user. - -A user may only unmount a disk if the mount point is owned by the -user, or if it the disk has been mounted by the same user. - -non-msdos disks are automatically mounted with the -.I nodev -and -.I nosuid -flags set. - -However, -.B Do not rely on fdmount being secure at the moment. - -.SH DAEMON MODE - -In daemon mode, the specified drive is -periodically checked and if a disk is inserted, it is -automatically mounted. - -When the disk is removed, it is automatically unmounted. -However, it is recommended to unmount the disk manually -.I before -removing it. In order to limit corruption, disks are mounted -with the SYNC option when running in daemon mode, unless the -.BI \-\-nosync -flag is given. - -Note that this mode has some potential drawbacks: - -Some floppy drives have to move the drive head physically -in order to reset the disk change signal. It is strongly -recommended not to use daemon mode with these drives. -Refer to the -.I floppycontrol(1) -documentation for details. - -It is not possible to specify special options, like -.BI \-\-readonly, -to modify the mount process. - -If a disk does not contain a filesystem (e.g. a tar archive), -the mount attempt may slow down initial access. - -As fdmount cannot identify the user trying to use the disk drive, -there is no way to protect privacy. Disks are always mounted with -public access permissions set. - -.SH DIAGNOSTICS - -.TP -.B error opening device - -.TP -.B error reading boot/super block -fdmount failed to read the first 1K of the disk. The disk might -be damaged, unformatted, or have a format unsupported by the -FDC/Linux kernel. - -.TP -.B unknown filesystem type -No magic number of any of the supported filesystems (see above) -could be identified. - -.TP -.B sorry, can't figure out format ( filesystem) -The size of the filesystem on the disk is incompatible with -the track layout detected by the kernel and an integer number of -tracks. This may occur if the filesystem uses only part of the -disk, or the track layout was detected incorrectly by the kernel. - -.TP -.B failed to mount K\-disk -The actual -.B mount(2) -system call failed. - -.TP -.B failed to unmount -The actual -.B unmount(2) -system call failed. - -.TP -.B cannot create lock file /etc/mtab~ -If -.BI /etc/mtab~ -exists, you should probably delete it. Otherwise, check -permissions. - -.TP -.B Can't access -Most probably, the default or specified mount point does not exist. -Use mkdir. - -.TP -.B is not a directory - -.TP -.B not owner of -Non\-root users must own the directory specified as mount point. -(This does not apply for the default mount points, /fd[0\-3].) - -.TP -.B No write permission to -Non\-root users must have write permission on the mount point -directory. - -.TP -.B Not owner of mounted directory: UID= -Non\-root users cannot unmount if the mount point is owned -(i.e. the disk was mounted) by another user. - -.TP -.B invalid drive name -Valid drive names are -.B fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7 - -.TP -.B drive does not exist -The drive does not exist physically, is unknown to the Linux -kernel, or is an unknown type. - -.TP -.B Drive is mounted already -Trying to mount a drive which appears to be mounted already. -Use the -.B \-\-force -option if you think this is wrong. - -.TP -.B Drive is not mounted -Trying to unmount a drive which does not appear to be mounted. -Use the -.B \-\-force -option if you think this is wrong. - -.TP -.B ioctl(...) failed -If this occurs with -.BI FDGETDRVTYP -or -.BI FDGETDRVSTAT, -you should probably update your Linux kernel. - -.TP -.B mounted K\-disk () -Success message. - -.SH BUGS - -chown() fails for non\-msdos filesystems mounted read\-only, so -the mount point may have the wrong owner. - -Fdmount should be more flexible about drive names and default -mount points (currently hard coded). - -Probably not very secure yet (when running suid root). -Untested with ext and xia filesystems. - -Can't specify filesystem type and disk layout explicitly. - -In daemon mode, the drive light stays on all the time. - -.SH FILES -/dev/fd[0\-7] \- Floppy devices - -/etc/mtab \- Mounted filesystems table - -.SH AUTHORS -Rainer Zimmermann, zimmerm@mathematik.uni\-marburg.de -Alain Knaff, Alain.Knaff@inrialpes.fr - -.SH SEE ALSO -mount(1), mmount(1), superformat(1), floppycontrol(1), setfdprm(1) diff --git a/src/fdmount.c b/src/fdmount.c index 50ef890..dbbc6d0 100644 --- a/src/fdmount.c +++ b/src/fdmount.c @@ -1,3 +1,4 @@ +#include "../config.h" #include #include #include @@ -14,10 +15,21 @@ #include #include #include + +#ifdef HAVE_LINUX_EXT_FS_H #include +#endif + #include + +#ifdef HAVE_LINUX_XIA_FS_H #include +#endif + #include +#include +#include + #define USE_2M #include "msdos_fs.h" @@ -438,6 +450,7 @@ int id_fstype(byte *super, fmt_descr *fmt) { return T_EXT2; } +#ifdef EXT_SUPER_MAGIC /* look for ext filesystem */ if (ext->s_magic==EXT_SUPER_MAGIC) @@ -445,7 +458,9 @@ int id_fstype(byte *super, fmt_descr *fmt) { fmt->totsect=ext->s_nzones * (2<s_log_zone_size); return T_EXT; } +#endif +#ifdef _XIAFS_SUPER_MAGIC /* look for xia filesystem */ if (xia->s_magic==_XIAFS_SUPER_MAGIC) @@ -453,7 +468,7 @@ int id_fstype(byte *super, fmt_descr *fmt) { fmt->totsect=xia->s_nzones * xia->s_zone_size/512; return T_XIA; } - +#endif /* add more format types here ... */ /* look for MS-DOG filesystem @@ -1037,6 +1052,10 @@ int main(int argc, char **argv) opt_noexec=0,opt_nodev=0,opt_nosuid=0; int mountflags=0; char *opt_pidfile="/var/run/fdmount.pid"; +#if FLOPPY_ONLY + gid_t groups[NGROUPS_MAX]; + int not_allowed = 1, ngroups; +#endif static struct option longopt[] = { { "silent", 0, &opt_silent, 1 }, @@ -1067,6 +1086,19 @@ int main(int argc, char **argv) opt_daemon=(strcmp(progname,"fdmountd")==0); opt_list =(strcmp(progname,"fdlist")==0); +#if FLOPPY_ONLY + if ((ngroups = getgroups (NGROUPS_MAX, groups)) != -1) { + int i; + struct group *gr; + + for (i = 0; not_allowed && i < ngroups; i++) + if ((gr = getgrgid (groups[i]))) + not_allowed = strcmp (gr -> gr_name, "floppy"); + } + if (not_allowed) + die("Must be member of group floppy"); +#endif + if (geteuid()!=0) die("Must run with EUID=root"); ruid = getuid(); diff --git a/src/fdrawcmd.1 b/src/fdrawcmd.1 deleted file mode 100644 index a4eba84..0000000 --- a/src/fdrawcmd.1 +++ /dev/null @@ -1,272 +0,0 @@ -.TH FDRAWCMD 1 "27apr1995" "fdutils" "fdutils" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -fdrawcmd \- send raw commands to the floppy disk controller -.SH SYNOPSIS -.hy 0 -.na -.B rawcmd -[\fBdrive=\fIdrive\fR] -[\fBrate=\fIrate\fR] -[\fBlength=\fIlength\fR] -[\fBrepeat=\fIcount\fR] -[\fRseek=\fIphysical_track\fR] -.I command -[\fIparameters\fR...] -[\fImode\fR] -.ad b -.hy 1 -.SH DESCRIPTION -.B fdrawcmd -is used to send raw commands to the floppy disk controller, after -having selected a given drive. You must have write permission to the -selected drive. -.PP -When writing to a disk, data is read from stdin; when reading, data -is printed to stdout. Diagnostic messages, return values from the -controller, and the value of the disk change line after the command are -printed to stderr. -.SH OPTIONS -All numbers may be given in octal (0209), decimal (137), or hexadecimal -(0x89). -.TP -.BI "drive=" "drive" -Selects the drive. The default is drive 0 -.RI ( /dev/fd0 ). -.TP -.BI "rate=" "rate" -Selects the data transfer rate. Use 0 for high density disks, 1 for -double density 5\ 1/4 disks (or 2 Mbps tapes, if the appropriate rate -table is selected), and 2 for double density 3\ 1/2 disks. -.TP -.BI "length=" "length" -Describes the length of the transferred data for commands reading from -and writing to the disk. The default is to continue until EOF. -.TP -.BI "repeat=" "count" -Repeat the command -.I count -times. This only works correctly for commands which don't do any data -transfer. -.TP -.I "command" -The name of the command to send. -.I command -may be a spelled out name (like -.B read -or -.BR write ), -or a number. A named command has already a mode, whereas for a -number the mode parameter should be described using the appropriate -option. -.TP -.I "parameter" -The parameter for the command. -.TP -.I "mode" -Various flags or'ed together describing the properties of the command. -.SH COMMANDS -The description of the various floppy commands given in this manpage -is very sketchy. For more details get the 82078 spec sheet which can -be found at -.B http://www-techdoc.intel.com/docs/periph/fd_contr/datasheets/\c -\&. Look for the chapter -.B "COMMAND SET/DESCRIPTIONS"\c -\&. Older FDCs only support a subset of the commands described -therein, but the syntax for the commands that do exist is the same. -.SS Commands available on all FDCs -.TP -.BI read " drivesel track head sector sizecode sect_per_track rw_gap sizecode2" -Reads -.I length -bytes of data from the disk. -.I drivesel -is the drive selector. Bit 0 and 1 describe the drive, and bit 2 describes -the head. The remaining parameters give the track, head (yes, again), -sector, size of the sector (128 * 2 ^ \fIsizecode\fR), sectors per track -(used to switch to the second head when the first side has been read), -and size of the read-write gap. -.I sizecode2 -should be 0xff. -.B read -returns -.I ST0 ST1 ST2 -and -.I track head sector sizecode -of the next sector to be read; see -.IR /usr/include/linux/fdreg.h . -.TP -.BI write " drivesel track head sector sizecode sect_per_track rw_gap sizecode" -Analogous to -.BR read . -.TP -.BI sense " drivesel" -Returns the third status byte -.RI ( ST3 ). -.TP -.BI recalibrate " drivesel" -Recalibrates the drive and returns -.IR "ST0 ST1" . -.TP -.BI seek " drivesel track" -Moves the head to -.I track -and returns -.IR "ST0 ST1" . -.TP -.BI specify " drivesel spec1 spec2" -Specify various parameters to the drive. -.TP -.BI format " drivesel sizecode sect_per_track fmt_gap fmt_fill" -Formats the track. The new sectors are filled with -.IR fmt_fill . -The header information comes from the input, which is made up of -.I track head sector sizecode -quadruples. The -.I sizecode -parameter from the command line is used to describe the actual size of -the sectors, and the -.I sizecode -from the input is used to write into the header. However, the first -write to these sectors will use the header information, and might -overwrite the following sectors if the -.I sizecode -parameter from the command line was too small. -.TP -.BI readid " drivesel" -reads the first sector header that comes and returns -.I ST0 ST1 ST2 -and -.I track head sector sizecode -of the encountered header. -.SS Commands available on 82072 and later -.TP -.BI dumpregs -Prints the contents of the FDCs registers, if supported. -.SS Commands available on 82072A and later -.TP -.BI configure " conf1 conf2 conf3" -Configures FIFO operation. -.SS Commands available on 82077 and later -.TP -.BI version -Echoes 0x90 if the FDC is more recent than 82072A, and 0x80 otherwise -.TP -.BI perpendicular " rate" -Sets the perpendicular mode. Use 0 for normal, 2 for 500Kbps -perpendicular, and 3 for 1Mbps perpendicular. -.TP -.BI seek_out " drivesel n" -does a relative seek of -.I n -tracks towards track 0. -.TP -.BI seek_in " drivesel n" -does a relative seek of -.I n -tracks towards the high numbered track. -.SS Commands available on 82077AA and later -.TP -.BI lock -Locks the FIFO configuration, so that it survives a FDC software reset. -.TP -.BI unlock -Unlock the FIFO configuration -.SS Commands available on 82078 -.TP -.BI partid -echoes a byte describing the type of the FDC in the 3 high bits, and -the stepping in the three low bits. -.TP -.BI powerdown " powerconf" -configures automatic power down of the FDC. The old configuration is echoed -.TP -.BI option " iso" -enables/disables ISO formats. Odd values of -.I iso -enable these formats, whereas even values disable them. ISO formats -don't have index headers, and thus allow to fit slightly more data on -a disk. -.TP -.BI save -prints out 16 internal registers of the FDC. -.TP -.BI restore " r1 r2 r3 ... r16" -restores the 16 internal registers of the FDC. -.TP -.BI format_n_write " drivesel sizecode sect_per_track fmt_gap fmt_fill" -formats the track and writes initial data to it. The input data is -made up of a sequence of headers (4 bytes) and data: -.I header1 data1 header2 sector2 ... headern sectorn -.TP -.BI drivespec " dspec1 dspec2 ... specn terminator" -chooses rate tables for various drives. Each dspec byte describes one -drive. Bits 0 and 1 say which drive is described. Bits 2 and 3 -describe the rate table. Only tables 0 and 2 are interesting. Both -tables only differ in the meaning og rate 1. For table 0 (the default) -rate 0 is 300 Kbps (used for 5 1/4 DD disks), whereas for table 1 it -is 2 Mbps (used for fast floppy tape drives). Bit 4 is the -precompensation table select bit. It should be set to 0. Bit 5-7 -should be zero as well. The -.I terminator -byte ends the -.B drivespec -command. It is either 0xc0 or 0x80. If it is 0xc0, no result phase -follows; if it is 0x80, the current data rate table configuration -for the four drives is echoed. -.SH MODES -The mode option is only needed when you describe the command as a -numerical value. Some mode names are also valid command names. They -are considered as command name if the command name has not yet been -given, and as mode name otherwise. If you give a command name and an -explicit mode, both the implicit flags of the command name, and the -explicit mode are or'ed together. Several modes may be or'ed together -too. -.TP -.B read -Read data from disk using DMA. -.TP -.B write -Write data to the disk. -.TP -.B intr -Wait for an interrupt. -.TP -.B spin -wait for the disk to spin up -.TP -.B need_seek -Seeks the drives head to the correct track (as given by the seek -parameter) before sending the command. -.TP -.B disk -Aborts the operation if no disk is in the drive. This only works if -need_seek is also chosen. -.TP -.B no_motor -Don't switch on the drive motor while issuing the command -.TP -.B no_motor_after -Switch off the motor immediately after the command returns. -.SH RESET -.B fdrawcmd -opens the device node with the -.B NDELAY -flag. This means that -the driver should not try to autodetect the disk type (it might not be -formatted), and that it should not reset the FDC. If a reset was -needed, the command simply fails. If that happens, execute -.BR "floppycontrol --resetnow 0" , -and try again. -.SH FILES -/dev/fd* - Floppy devices -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr -.SH SEE ALSO -.BR superformat (1), -.BR getfdprm (1), -.BR floppycontrol (1) diff --git a/src/fdrawcmd.c b/src/fdrawcmd.c index b3372ca..3cf60ae 100644 --- a/src/fdrawcmd.c +++ b/src/fdrawcmd.c @@ -145,7 +145,8 @@ void main(int argc, char **argv) struct floppy_raw_cmd *results=0; long long *times=0; long long *timesb4=0; - + int fm_mode = 0; + char *eptr; char buffer[ 512 * 2 * 24 ]; raw_cmd.length= 512 * 2 * 24; @@ -157,8 +158,19 @@ void main(int argc, char **argv) drive="/dev/fd0"; - if (( s=getenv("length") ) || (s = getenv("LENGTH")) ) - raw_cmd.length= strtoul( s,0,0); + if (( s=getenv("length") ) || (s = getenv("LENGTH")) ) { + raw_cmd.length= strtoul( s,& eptr, 0); + switch(*eptr) { + case 'b': + raw_cmd.length *= 512; + break; + case 'k': + case 'K': + raw_cmd.length *= 1024; + break; + } + } + if ((s = getenv("rate") ) || (s = getenv("RATE")) ) raw_cmd.rate = strtoul( s,0,0); @@ -182,12 +194,21 @@ void main(int argc, char **argv) if ( !cmd || r_flags == 0 ) r_flags |= flags; if ( raw_cmd.cmd_count == 0 ) - raw_cmd.cmd[raw_cmd.cmd_count++] = cmd; - continue; + raw_cmd.cmd[raw_cmd.cmd_count++] = cmd; + continue; } if ( strncmp( "length=", *argv, 7 ) == 0 ){ - raw_cmd.length= strtoul( (*argv)+7,0,0); + raw_cmd.length= strtoul( (*argv)+7,&eptr, 0); + switch(*eptr) { + case 'b': + raw_cmd.length *= 512; + break; + case 'k': + case 'K': + raw_cmd.length *= 1024; + break; + } continue; } @@ -226,6 +247,12 @@ void main(int argc, char **argv) continue; } + if ( strcmp( "fm", *argv) == 0){ + fm_mode = 1; + continue; + } + + if ( strcmp( "short", *argv) == 0){ do_short = 1; continue; @@ -252,6 +279,9 @@ void main(int argc, char **argv) raw_cmd.cmd[raw_cmd.cmd_count++] = cmd; } + + if(fm_mode) + raw_cmd.cmd[0] &= ~0x40; if ( r_flags & FD_RAW_WRITE ){ size = 0; @@ -285,7 +315,6 @@ void main(int argc, char **argv) exit(1); } } - *drive = '\0'; } if (do_buffer){ diff --git a/src/fdutils.h b/src/fdutils.h new file mode 100644 index 0000000..3797e1e --- /dev/null +++ b/src/fdutils.h @@ -0,0 +1,24 @@ +#include +/* This file contains common structures understood by several of the + * fdutils + */ + +/* format map */ +typedef struct format_map { + unsigned char cylinder; + unsigned char head; + unsigned char sector; + unsigned char size; +} format_map_t; + +void readid(int fd, int dn, int rate, int cylinder); +int measure_raw_capacity(int fd, int dn, int rate, + int cylinder, int warmup, int verbosity); + +#define NewArray(n,type) ((type *)(calloc((n), sizeof(type)))) +#define New(type) ((type *)(malloc(sizeof(type)))) + +#define SafeNewArray(n,type) ((type *)(safe_calloc((n), sizeof(type)))) +#define SafeNew(type) ((type *)(safe_malloc(sizeof(type)))) +void *safe_malloc(size_t size); +void *safe_calloc(size_t nmemb, size_t size); diff --git a/src/floppycontrol.1 b/src/floppycontrol.1 deleted file mode 100644 index 4ea3ffa..0000000 --- a/src/floppycontrol.1 +++ /dev/null @@ -1,473 +0,0 @@ -.TH FLOPPYCONTROL 1 "17nov1995" "fdutils4" "fdutils4" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -floppycontrol \- floppy driver configuration utility -.SH SYNOPSIS -.hy 0 -.na -.B floppycontrol -[\fB\-p\fR] -[\fB\-\-pollstate\fR] -[\fB\-\-printfdstate\fR] -[\fB\-a\ \fIoperation-abort-threshold\fR] -[\fB\-c\ \fIread-track-threshold\fR] -[\fB\-r\ \fIrecalibrate-threshold\fR] -[\fB\-R\ \fIreset-threshold\fR] -[\fB\-e\ \fIreporting-threshold\fR] -[\fB\-f\fR] -[\fB\-x\fR] -[\fB\-d\ \fIdrive\fR] -[\fB\-F\fR] -[\fB\-T\fR] -[\fB\-\-resetnow \fIcondition\fR] -[\fB\-\-debug\fR] -[\fB\-\-nodebug\fR] -[\fB\-\-messages\fR] -[\fB\-\-nomessages\fR] -[\fB\-\-broken_dcl\fR] -[\fB\-\-working_dcl\fR] -[\fB\-\-inverted_dcl\fR] -[\fB\-\-no_inverted_dcl\fR] -[\fB\-\-silent_dcl_clear\fR] -[\fB\-\-noisy_dcl_clear\fR] -[\fB\-c\ \fIcmos-type\fR] -[\fB\-\-hlt \fIhlt\fR] -[\fB\-\-hut \fIhut\fR] -[\fB\-\-srt \fIsrt\fR] -[\fB\-o\ \fIspindown\fR] -[\fB\-u\ \fIspinup\fR] -[\fB\-s\ \fIselect-delay\fR] -[\fB\-\-rps \fIrotations-per-second\fR] -[\fB\-O\ \fIspindown-offset\fR] -[\fB\-\-track \fImax-tracks\fR] -[\fB\-\-timeout \fIseconds\fR] -[\fB\-C\ \fIcheck-interval\fR] -[\fB\-n\ \fInative-format\fR] -[\fB\-\-autodetect \fIautodetection-sequence\fR] -[\fB\-P\fR] -[\fB\-\-clrwerror\fR] -[\fB\-\-printwerror\fR] -[\fB\-h\fR] -.ad b -.hy 1 -.SH DESCRIPTION -.B floppycontrol -program is used to configure the floppy driver. -.SH OPTIONS -Many options have a long and a short form. -.TP -.B \-h \-\-help -Print a help screen. -.TP -.BI "\-d " "drive" " \-\-drive" " drive" -Selects the drive to configure. The default is drive 0 -.RI ( /dev/fd0 ). -.TP -.B \-f " \-\-flush" -Flushes (throws away) the dirty data buffers associated with this drive. -.B \-x " \-\-eject" -Ejects the disk out of the drive (Sparc). The dirty buffers are first -committed to disk before ejecting it. Fails if the disk is mounted. -.B \-F " \-\-formatend" -Issues an end format ioctl. This might be needed after exiting a -formatting program in an unclean way. -.B superformat -is not subject to this. -.TP -.BI "\-\-resetnow" " condition" -Resets the FDC under -.I condition . -0 resets the FDC only if a reset is needed anyways, 1 resets the FDC -also if a raw command has been performed since the last reset, and 2 resets -the FDC unconditionally. -.SH ERROR HANDLING OPTIONS -The following options are used to configure the behavior of the -floppy driver in case of read/write errors. They may be used by any -user who has write privileges for the drive. Whenever the floppy -driver encounters an error, a retry counter is incremented, and if -this value is bigger than certain thresholds, certain actions -(described below) are performed before retrying, or the sectors are -read in a different way. The counter is reset when the read or write -finally succeeds, or when the driver gives up. -.TP -.BI "\-a " "operation_abort_trshld" " \-\-abort" " operation_abort_trshld" -Tell the floppy driver to stop trying to read/write a sector after -.I operation_abort_trshld -retries, and signal the I/O error to the user. -.TP -.BI "\-t " "read_track_trshld" " \-\-readtrack" " read_track_trshld" -Tell the floppy driver to switch from track-reading mode to -sector-at-a-time-mode after -.I read_track_trshld -retries. -.TP -.BI "\-r " "recalibrate_trshld" " \-\-recalibrate" " recalibrate_trshld" -Tell the floppy driver to recalibrate the drive after -.I recalibrate_trshld -retries. -.TP -.BI "\-R " "reset\_treshold" " \-\-reset" " reset_threshold" -Tell the floppy driver to reset the controller after -.I reset\_threshold -retries. After a controller reset, all drives are recalibrated too. -.TP -.BI "\-e " "error_report_trshld" " \-\-reporting" " error_report_trshld" -Tell the floppy driver to start printing error messages to the console -after -.I error_report_trshld -retries. -.SH PRINTING OPTIONS -.TP -.B "\-T" " \-\-type" -Print out the drive name. This is used by the -.BR MAKEFLOPPIES (8) -script. The drive name is a letter (describing the drive type) followed by -the capacity of the format in bytes. The letter is E for 3.5 ED drives, -H for 3.5 HD drives, D for 3.5 DD drives, h for 5.25 HD drives and d for -5.25 DD drives. The drive type letter corresponds to the oldest drive -type supporting this format (not necessarily the type of this drive -instance.) For the generic format nodes (/dev/fd0 et al.) the name of -"native format" of the drive is printed, and for the default formats, -If a generic format has been redefined, its name becomes "(null)". -.TP -.B "\-p" " \-\-print" -Prints out the current drive configuration. The names of the various -fields are the same as the name of the option to set them. -.TP -.B "\-P" " \-\-printstate" -Prints out the cached internal state of the driver. The first line lists -various attributes about the disk: -.BR "drive present" , -.BR "disk present" , -and -.BR "disk writable" . -These are only updated when the drive is accessed. -.sp 1 -.B spinup -is the time when the motor became switched on for the last time. -.sp 1 -.B select -is the time when the drive became selected for the last time -.sp 1 -.B first_read -is the time when the first read request after the last spin up -completed. -.sp 1 -.B probed_fmt -is the the index of the autodetected format in the autodetection -sequence for this drive. -.sp 1 -.B track -is the track where the drive currently sits. --1 means that the driver doesn't know, but the controller does (a seek -command must be issued). --2 means that the controller doesn't know either, but is sure that it -not beyond the 80th track. The drive needs a recalibration. --3 means that the head may be beyond the 80th track. The drive needs -two successive recalibrations, because at each recalibration, the -controller only issues 80 move head commands to the drive. -.sp 1 -.B maxblock -is the highest block number that has been read. -.B maxtrack -is a boolean which is set when a sector that is not on track 0/head 0 has -been read. These are used for smart invalidation of the buffer cache -on geometry change. The buffer cache of the drive is only invalidated -on geometry change when this change actually implies that a block that -has already been read changes position. This optimization is useful for -mtools which changes the geometry after reading the boot sector. -.sp 1 -.B generation -is roughly the number of disk changes noticed since boot. Disk changes -are noticed if the disk is actually changed, or if a flush command is -issued and for both cases if any I/O to/from the disk occurs. (i.e. if -you insert several disks, but don't do any I/O to them, the generation -number stays the same.) -.sp 1 -.B refs -is number of open file descriptors for this drive. It is always at -least one, because floppycontrol's file descriptor is counted too. -.sp 1 -.B device -is format type (as derived from the minor device number) which is -currently being used. -.sp 1 -.B last_checked -is date (in jiffies) when the drive was last checked for a disk -change, and a disk was actually in the drive. -.TP -.B "\-\-pollstate" -Polls the drive and then prints out the internal state of the -driver. -.RB ( \-\-printstate -only prints out the cached information without actually polling the -drive for a disk change.) -.TP -.B "\-\-printfdcstate" -Prints out the state of the controller where the target drive is -attached to. -.sp 1 -.B spec1 -and -.B spec2 -are the current values of those registers. -.sp 1 -.B rate -is current data transfer rate -.sp 1 -.B rawcmd -is true if a raw command has been executed since the last reset. If this -is the case, a reset will be triggered when a drive on the same FDC is -next opened. -.sp 1 -.B dor -is the value of the digital output register. The 4 high bits are a bit -mask describing which drives are spinning, the 2 low bits describe the -selected drive, bit 2 is used to reset the FDC, and bit 3 describes -whether this FDC has hold of the interrupt and the DMA. If you have two -FDCs, bit 3 is only set on one of them. -.sp 1 -.B version -is the version of the FDC. See -.I linux/include/linux/fdreg.h -for a listing of the FDC version numbers. -.sp 1 -.B reset -is true if a reset needs to be issued to the FDC before processing the -next request. -.sp 1 -.B need_configure -is true if this FDC needs configuration by the -.B FD_CONFIGURE -command. -.sp 1 -.B has_fifo -is set if the FDC understands the -.B FD_CONFIGURE -command. -.sp 1 -.B perp_mode -describes the perpendicular mode of this FDC. 0 is non-perpendicular mode, -2 is HD perpendicular mode, 3 is ED perpendicular mode, and 1 is unknown. -.sp 1 -.B address -is the address of the first I/O port of the FDC. Normally, this is -0x3f0 for the first FDC and 0x370 for the second. -.SH PRIVILEGED CONFIGURATION -Only the superuser may set the following parameters: -.TP -.BI "\-A " "autodetect_seq" " \-\-autodetect" " autodetect_seq" -Set the autodetection sequence. The autodetection sequence is a -comma-separated list of at most eight format descriptors. Each format -descriptor is a format number optionally followed by the letter -.B t . -For drive 0, the format number is the minor device number divided by 4. -.sp 1 -This sequence is used by to find out the format of a newly inserted -disk. The formats are tried one after the other, and the first -matching format is retained. To test the format, the driver tries to -read the first sector on the first track on the first head when -.B t -is not given, or the whole first track when -.B t -is given. Thus, autodetection cannot detect the number of -tracks. However, this information is contained in the boot sector, -which is now accessible. The boot sector can then be used by mtools to -configure the correct number of tracks. -.sp 1 -Example: -.B 7,4,20t,21 -means to try out the formats whose minor device numbers are 28 (1.44M), -16 (720k) , 80 (1.82M), and 84 (1.99M), in this order. For the 1.82M -format, try to read the whole track at once. -.sp 1 -Reading the whole track at once allows you to distinguish between two -formats which differ only in the number of sectors. (The format with the -most sectors must be tried first.) With the new -.BR mtools , -it is no longer necessary to make this distinction, because -.B mtools -can now figure out the number of sectors by looking at the boot sector. -.sp 1 -Reading the whole track at once may also speed up the first read by -200 milliseconds. However, if you try to read a disk which has less -sectors than the format, you lose some time. -.sp 1 -I suggest that you put the most often used format in the first place -(barring other constraints), as each format that is tried out takes -400 milliseconds. -.TP -.BI "\-\-tracks" " max_tracks" -Set the maximal numbers of physical tracks that this drive may -handle. If you have a drive which is only able to handle 80 tracks -(making strange noises when you try to format or read a disk with more -than 80 tracks), use this option to prevent unprivileged users of -damaging your drive by repeatedly reading disks with more than 80 -tracks. -.sp 1 -If you trust your users and your disks, you don't need this. With most -drives you don't need to worry anyways. -.TP -.B \-\-debug -Switch debugging output on. The debugging information includes timing -information. This option might be useful to fine-tune the timing -options for your local setups. (But for most normal purposes, the -default values are good enough.) -.TP -.B \-\-nodebug -Switch debugging output off. -.TP -.B \-\-messages -Print informational messages after autodetection, geometry parameter -clearing and dma over/underruns. -.TP -.B \-\-nomessages -Don't print informational messages after these events. -.TP -.B \-\-broken_dcl -Assumes that the disk change line off the drive is broken. Disk -changes are assumed to happen whenever the device node is first -opened. The physical disk change line is ignored. -.sp 1 -Use this option if disk changes are either not detected at all, or if -disk changes are detected when the disk was not changed. If this -option fixes the problem, I'd recommend checking the floppy cable and -the drive jumpers. Apparently the disk change line is near the edge of -the cable, and is the first line to suffer if the cable is not -inserted straight, or if it is damaged. On some drives, the disk -change line may be chosen by jumper. Make sure that your floppy -controller board and your drive agree which line is the disk change -line. If everything seems right with the jumpers and the cables, or if -the drive is known not to support the disk change line, leave this -option on. -.TP -.B \-\-working_dcl -Assumes that the disk change line works all right. Switching from -broken to working may lead to unexpected results after the first disk -change. -.TP -.B \-\-inverted_dcl -Assumes that this disk drives uses an inverted disk change -line. Apparently this is the case for IBM thinkpads. -.TP -.B \-\-no_inverted_dcl -Assumes that this drive follows the standard convention for the disk -change line. -.TP -.B \-\-noisy_dcl_clear -Switches off silent disk change line clearing for this drive. -.TP -.BI "\-c" "cmos_type" " \-\-cmos" " cmos_type" -Set the CMOS type of the floppy drive. This is useful if for some -reason the real CMOS type is wrong, or if you have more than two drives. -(It is impossible to specify the types for more than two drives in the -"real" CMOS.) Right now, this CMOS parameter is not yet used by the -kernel, except for feeding it back to other applications (for instance -.BR superformat (1)). -.TP -.BI "\-n" "native_format" " \-\-native_format" " native_format" -Set the native format of this drive. The native format of a drive is -the highest standard format available for this drive. (Example: For -a 5 1/4 HD drive it is the usual 1200K format.) This is format is used -to make up the format name for the generic device (which is the name -of the native format). This drive name is used by the -.BR MAKEFLOPPIES (8) -script. -.TP -.BI "\-\-hlt" " hlt" -Set the head load time (in microseconds) for this floppy drive. -.TP -.BI "\-\-hut" " hut" -Set the head unload time (in microseconds) for this floppy drive. -.TP -.BI "\-\-srt" " srt" -Set the step rate (in microseconds) for this floppy drive. -.TP -.BI "\-i" "sector_interleave" " \-\-interleave" " sector_interleave" -Set the number of sectors beyond which sector interleaving will be used. -This option will only be used by the -.B FDFMTTRK -ioctl. The old -.BR fdformat (1) -uses this, but -.BR superformat (1) -does not. -.SH TIMING PARAMETERS - To set these parameters, you need superuser privileges. All times are in -tick units (10 milliseconds). -.TP -.BI "\-u" "spinup\-time" " \-\-spinup" " spinup_time" -Set the spinup time of the floppy drive. In order to do read or write -to the floppy disk, it must spin. It takes a certain time for the -motor to reach enough speed to read or write. This parameter describes -this time. The floppy driver doesn't try to access the drive before -the spinup time has elapsed. With modern controllers, you may set this time -to zero, as the controller itself enforces the right delay. -.TP -.BI "\-o" "spindown\-time" " \-\-spindown" " spindown_time" -Set the spindown time of this floppy drive. The motor is not stopped -immediately after the operation completes, because there might be more -operations following. The spindown time is the time the driver waits -before switching off the motor. -.TP -.BI "\-O" "spindown\-offset" " \-\-spindown_offset" " spindown_offset" -Set the spindown offset of this floppy drive. This parameter is used -to set the position in which the disk stops. This is useful to -minimize the next access time. (If the first sector is just near the -head at the very moment at which the disk has reached enough speed, -you win 200 milliseconds against the most unfavorable situation). -.sp 1 -This is done by clocking the time where the first I/O request -completes, and using this time to calculate the current position of -the disk. This mechanism is not 100% reliable (If it fails, you may lose -200 milliseconds). -.TP -.BI "\-s" "select_delay" " \-\-select_delay" " select_delay" -Set the select delay of this floppy drive. This is the delay that the -driver waits after selecting the drive and issuing the first command to -it. For modern controllers/drives, you may set this to zero. -.TP -.BI "\-C" "check\-interval" " \-\-checkfreq" " check_interval" -Set the maximal disk change check interval. If a read or write to -the device is issued, and disk change has not been checked for a -longer time than this interval, it is checked now. -.SH WRITE ERROR REPORTING -Due to the buffer cache, write errors cannot always be reported to -the writing user program as soon as the write system call returns. -Indeed the actual writing may actually take place much later. If a -write error is encountered, the floppy driver stores information about -it in its per drive write error structure. This write error structure -stays until explicitly cleared. -.TP -.B \-\-clrwerror -Clears the write error structure. -.TP -.B \-\-printwerror -Prints the contents of the write error structure. -.B write_errors -is a count of how many write errors have occurred since the structure was last -cleared. -.B badness -is the maximal number of retries that were needed to complete an -operation (reads, writes and formats). -.B first_error_sector -is where the first (chronologically) write error occurred. -.B first_error_generation -is the disk generation in which did the first write error occurred. -.B last_error_sector -and -.B last_error_generation -are similar. -.SH FILES -/dev/fd* - Floppy devices -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr -.SH SEE ALSO -.BR superformat (1), -.BR getfdprm (1), -.BR fdrawcmd (1), -.BR mtools (1) diff --git a/src/floppycontrol.c b/src/floppycontrol.c index 1d6aa62..9cb71bf 100644 --- a/src/floppycontrol.c +++ b/src/floppycontrol.c @@ -169,9 +169,13 @@ struct enh_options optable[] = { (void *) &dpr.spindown_offset, "set spindown offset (decides in which position the disk stops)" }, +{'\0', "cylinders", 1, EO_TYPE_BYTE | EO_TYPE_DELAYED, 0, SET_DPR, + (void *) &dpr.tracks, + "set maximal number of cylinders" }, + {'\0', "tracks", 1, EO_TYPE_BYTE | EO_TYPE_DELAYED, 0, SET_DPR, (void *) &dpr.tracks, - "set maximal number of tracks" }, + "obsolete (same as --cylinders)" }, {'\0', "timeout", 1, EO_TYPE_LONG | EO_TYPE_DELAYED, 0, SET_DPR, (void *) &dpr.timeout, @@ -389,9 +393,9 @@ void main( int argc, char **argv) printf("select= %ld\n", drivstat.select_date); printf("first_read= %ld\n", drivstat.first_read_date); printf("probed_fmt= %d\n", drivstat.probed_format); - printf("track= %d\n", drivstat.track); + printf("cylinder= %d\n", drivstat.track); printf("maxblock= %d\n", drivstat.maxblock); - printf("maxtrack= %d\n", drivstat.maxtrack); + printf("maxcylinder= %d\n", drivstat.maxtrack); printf("generation= %d\n", drivstat.generation); printf("keep data= %d\n", drivstat.keep_data); printf("refs= %d\n", drivstat.fd_ref); diff --git a/src/floppymeter.c b/src/floppymeter.c new file mode 100644 index 0000000..4ec2d45 --- /dev/null +++ b/src/floppymeter.c @@ -0,0 +1,296 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "enh_options.h" +#include "fdutils.h" +#include "driveprm.h" + +#define NON_INTERACTIVE 1 + +long long gettime(void) +{ + struct timeval tv; + int ret; + + ret = gettimeofday(&tv, 0); + if ( ret < 0 ){ + perror("get time of day\n"); + exit(1); + } + + return ( (long long) tv.tv_usec + ( (long long) tv.tv_sec ) * 1000000LL); +} + +int dtr[4] = { 500000, 300000, 250000, 1000000 }; + +struct { + int time_per_rot; /* nominal time per rotation */ + int sp_offset; + int rate[3]; +} cmos_table[]= { + { 0, 0, { 0x100, 0x100, 0x100} }, /* no drive */ + { 200000, 0, { 0x002, 0x100, 0x100} }, /* 5 1/4 DD */ + { 200000, 0, { 0x002, 0x100, 0x100} }, /* 3 1/2 DD */ + { 166666, 0, { 0x001, 0x000, 0x100} }, /* 5 1/4 HD */ + { 200000, 0, { 0x002, 0x000, 0x100} }, /* 3 1/2 HD */ + { 200000, 0, { 0x002, 0x000, 0x043} }, /* 3 1/2 ED */ + { 200000, 0, { 0x002, 0x000, 0x043} } /* 3 1/2 ED */ +}; + + +struct reg { + long long time; + int rot; +}; + + +int sliding_avg(struct reg *reg, int n) +{ + int i; + long long sum_x, sum_y, sum_xy, sum_x2, sum2_x; + + sum_x = sum_y = sum_xy = sum_x2 = 0; + for(i=0; i> 5); + + if(ioctl(fd, FDGETDRVPRM, &dpr) < 0) { + perror("get drive parameter"); + exit(1); + } + + if(dpr.cmos < 1 || dpr.cmos > 6) { + fprintf(stderr, "Bad cmos type\n"); + exit(1); + } + + if(density == 3) { + do { + density--; + rate = cmos_table[(int) dpr.cmos].rate[density]; + } while(rate >= 256); + } else + rate = cmos_table[(int) dpr.cmos].rate[density]; + if(rate >= 256) { + fprintf(stderr,"density not supported by this drive\n"); + exit(1); + } + + /* measure its capacity */ + measure_raw_capacity(fd, dn, rate, + cylinder, warmup, !(mask & NON_INTERACTIVE)); + + readid(fd, dn, rate, cylinder); + base_time = last_time = gettime(); + missed = rot = 0; + avg = cmos_table[(int)dpr.cmos].time_per_rot; + reg = (struct reg *) calloc(window, sizeof(struct reg)); + for(j=0; j avg * 3 / 2) { + /* if it takes unusually long, we may have missed one rotation */ + rot += (time - last_time - avg / 2) / avg; + missed += (time - last_time - avg / 2) / avg; + } + + last_time = time; + reg[j].time = time; + reg[j].rot = rot; + + sum_x += rot; + sum_y += time; + sum_xy += rot * time; + sum_x2 += rot * rot; + sum2_x = sum_x * sum_x; + n++; + + avg = ((n*sum_xy - sum_x*sum_y) / (n*sum_x2 - sum2_x)); + if(!(mask & NON_INTERACTIVE)){ + fprintf(stderr,"|%6d |%8d |%8d |%3d |\r", + rot, (int)avg, sliding_avg(reg,window), missed); + fflush(stderr); + } + j++; + if(j>=window) + j=0; + } + if(!(mask & NON_INTERACTIVE)) { + fprintf(stderr,"\n"); + fprintf(stderr, + "|___________|___________|___________|_________|\n"); + } + + cap = measure_raw_capacity(fd, dn, rate, + cylinder, 0, !(mask & NON_INTERACTIVE)); + + shall_time = cmos_table[(int)dpr.cmos].time_per_rot; + shall_cap = dtr[rate] * 2 * shall_time / 1000000LL; + + printf("\n"); + printf("capacity=%d half bits (should be %d half bits)\n", cap, + (int) shall_cap); + printf("time_per_rotation=%d microseconds (should be %d)\n", (int) avg, + (int) shall_time); + my_dtr = ((long long)cap) * 500000 / avg; + printf("data transfer rate=%d bits per second (should be %d)\n", + (int) my_dtr, dtr[rate]); + printf("\n"); + printf("deviation on capacity: %+d ppm\n", + (int) ((cap - shall_cap) * 1000000 / shall_cap)); + printf("deviation on time_per_rotation: %+d ppm\n", + (int) ((avg - shall_time) * 1000000 / shall_time)); + printf("deviation on data transfer rate: %+d ppm\n", + (int) ((my_dtr - dtr[rate]) * 1000000 / dtr[rate])); + + printf("\nInsert the following line to your " DRIVEPRMFILE " file:\n"); + printf("drive%d: deviation=%d\n\n", + dn, (int) ((cap - shall_cap) * 1000000 / shall_cap )); + +#if 0 + margin = (shall_cap - cap + 15)/10; + if(margin > 0) + printf("recommended margin: %d\n", margin); +#endif + exit(0); +} diff --git a/src/getfdprm.1 b/src/getfdprm.1 deleted file mode 100644 index f8d8503..0000000 --- a/src/getfdprm.1 +++ /dev/null @@ -1,34 +0,0 @@ -.TH GETFDPRM 1 "21jan1996" "fdutils" "fdutils" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -getfdprm \- print the current format information -.SH SYNOPSIS -.hy 0 -.na -.B getfdprm -.RI [ drive ] -.ad b -.hy 1 -.SH DESCRIPTION -.B getfdprm -prints the current format information for -.IR drive . -This information can be set using -.BR setfdprm (8) , -which is part of most Linux distributions. -.BR Setfdprm -can now be used by the superuser to redefine the default -formats. -.SH FILES -/dev/fd* - Floppy devices -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr -.SH SEE ALSO -.BR superformat (1), -.BR floppycontrol (1), -.BR fdrawcmd (1), -.BR setfdprm (8) diff --git a/src/getfdprm.c b/src/getfdprm.c index 6dd1026..d8b5752 100644 --- a/src/getfdprm.c +++ b/src/getfdprm.c @@ -1,10 +1,4 @@ -#include -#include -#include -#include -#include -#include #include #include @@ -12,51 +6,89 @@ #include #include #include +#include "driveprm.h" +#include "printfdprm.h" + struct floppy_struct floppy_type; extern int errno; -void main(int argc,char **argv) +void usage(char *name) __attribute__((noreturn)); +void usage(char *name) { - int fd; - - char *name; - - if ( argc == 1 ) - name = "/dev/fd0" ; - else - name = argv[1]; - - - fd=open(name,3); - if ( fd < 0 ) - fd=open(name,O_RDONLY); - if ( fd < 0 ){ - perror("open"); - exit(1); - } - - if(ioctl(fd,FDGETPRM,&floppy_type)<0){ - perror(""); - exit(1); - } - - printf("%4d %2d %d %2d %d 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", - floppy_type.size, - floppy_type.sect, - floppy_type.head, - floppy_type.track, - floppy_type.stretch, - floppy_type.gap, - floppy_type.rate, - floppy_type.spec1, - floppy_type.fmt_gap); - close(fd); + fprintf(stderr,"Usage: %s\n", name); + exit(1); } +static void myprintf(char *fmt, int value) +{ + printf(fmt, value); + putchar(' '); +} - - - - - +void main(int argc,char **argv) +{ + int fd; + char *name; + level_t level; + drivedesc_t drivedesc; + + level = LEV_NONE; + if (argc > 1 && *argv[1] == '-') { + switch (argv[1][1]) { + case 'e': + level = LEV_EXPL; + break; + case 'm': + level = LEV_MOST; + break; + case 'a': + level = LEV_ALL; + break; + case 'o': + level = LEV_OLD; + break; + default: + usage(argv[0]); + } + argc--; + argv++; + } + + if ( argc == 1 ) + name = "/dev/fd0" ; + else + name = argv[1]; + + fd=open(name,3); + if ( fd < 0 ) + fd=open(name,O_RDONLY); + if ( fd < 0 ){ + perror("open"); + exit(1); + } + + if(ioctl(fd,FDGETPRM,&floppy_type)<0){ + perror("get geometry parameters"); + exit(1); + } + + if(level == LEV_OLD) { + printf("%4d %2d %d %2d %d 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + floppy_type.size, + floppy_type.sect, + floppy_type.head, + floppy_type.track, + floppy_type.stretch, + floppy_type.gap, + floppy_type.rate, + floppy_type.spec1, + floppy_type.fmt_gap); + } else { + parse_driveprm(fd, &drivedesc); + print_params(&drivedesc, &floppy_type, level, 0, + (void(*)(char *,int))myprintf); + } + close(fd); + exit(0); +} diff --git a/src/makefloppies.1 b/src/makefloppies.1 deleted file mode 100644 index 3b8ead2..0000000 --- a/src/makefloppies.1 +++ /dev/null @@ -1,78 +0,0 @@ -.TH MAKEFLOPPIES 1 "8jan1995" "fdutils4" "fdutils4" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -MAKEFLOPPIES \- Creates the default floppy device nodes. -.SH SYNOPSIS -.hy 0 -.na -.B MAKEFLOPPIES -.RB "[\|" \-t "\|]" -.RB "[\|" \-l "\|]" -.RB "[\|" \-v "\|]" -.RB "[\|" \-n "\|]" -.RB "[\|" drives "\|]" -.ad b -.hy 1 -.SH DESCRIPTION - -The MAKEFLOPPIES shell script creates the new floppy block device -files. It uses the floppycontrol program to translate the minor -device numbers into meaningful names. It also uses these names to -decide whether to create a given block device file or not, depending on -the type of the physical drive (for instance, for a 3 1/2 drive, the -formats corresponding to a 5 1/4 drive are not created). - -If you have more than two floppy drives, you need to tell the kernel -the CMOS types of those additional drives using the -.B floppy=\c -.I drive\c -,\c -.I type\c -.B ,CMOS -lilo option. - -If the -.B drives -parameter is given, only the device nodes for the listed drives are -made. By default, all eight drives are tried. - -MAKEFLOPPIES does not work if you redefine your default formats. - -.B CAUTION: -MAKEFLOPPIES removes already existing floppy device nodes. - -.SH OPTIONS - -.TP -.B \-t -Name devices for drive type, not floppy type (e.g. fd0H720) - -.TP -.B \-l -Local. Creates device nodes in the local directory, not /dev - -.TP -.B \-v -Verbose - -.TP -.B \-n -Dry run. (just report what would be done, do not do anything) - -.SH BUGS -The Makefloppies script does not work on redefined default formats, -because it is impossible to give new names to these formats. In -that case, you need to create the additional devices manually. - -.SH FILES -/dev/fd* - Floppy devices - -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr - -.SH SEE ALSO -superformat(1), rawcmd(1), floppycontrol(1), mtools(1), setfdprm(8) diff --git a/src/measure.c b/src/measure.c new file mode 100644 index 0000000..a83204c --- /dev/null +++ b/src/measure.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "enh_options.h" +#include "fdutils.h" + +static struct { + unsigned char value; + int offset; +} byte_tab[16]= { + { 0x03, 0 }, + { 0x7c, 0 }, + { 0x81, 0 }, + { 0x3e, 0 }, + { 0xc0, 0 }, + { 0x1f, 0 }, + { 0x60, 0 }, + { 0x8f, 1 }, + { 0x30, 1 }, + { 0xc7, 1 }, + { 0x18, 1 }, + { 0xe3, 1 }, + { 0x0c, 1 }, + { 0xf1, 1 }, + { 0x06, 1 }, + { 0xf8, 1 } +}; + +static int read_track(int fd, int dn, int rate, int cylinder) +{ + struct floppy_raw_cmd raw_cmd; + int tmp; + + unsigned char buffer[32*1024]; + unsigned char c; + int ptr; + int i; + + raw_cmd.cmd_count = 9; + raw_cmd.cmd[0] = FD_READ; /* format command */ + raw_cmd.cmd[1] = dn /* drive */; + raw_cmd.cmd[2] = 0; /* cylinder */ + raw_cmd.cmd[3] = 0; /* head */ + raw_cmd.cmd[4] = 1; /* sector */ + raw_cmd.cmd[5] = 8; /* sizecode */ + raw_cmd.cmd[6] = 1; /* sect per track */ + raw_cmd.cmd[7] = 0x1b; /* gap */ + raw_cmd.cmd[8] = 0xff; /* sizecode2 */ + raw_cmd.data = buffer; + raw_cmd.length = 32 * 1024; + raw_cmd.flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK | + FD_RAW_READ; + raw_cmd.rate = rate; + raw_cmd.track = cylinder; + + tmp = ioctl(fd, FDRAWCMD, & raw_cmd); + if ( tmp < 0 ){ + perror("read"); + exit(1); + } + + ptr = 514; + /* we look first for the place where the 0x4e's are going to stop */ + while(buffer[ptr] == 0x4e) + ptr += 256; + ptr -= 240; + while(buffer[ptr] == 0x4e) + ptr += 16; + ptr -= 15; + while(buffer[ptr] == 0x4e) + ptr ++; + /* we have now found the first byte after wrap-around */ + + /* jump immediately to the supposed beginning */ + ptr += 210; + c = buffer[ptr]; + while(buffer[ptr] == c) + ptr--; + for(i=0; i<16; i++) { + if(byte_tab[i].value == c) { + ptr -= byte_tab[i].offset; + return ptr * 16 + i; + } + } + return ptr * 16; +} + + +static void m_format_track(int fd, int dn, int rate, int cylinder) +{ + struct floppy_raw_cmd raw_cmd; + int tmp; + format_map_t format_map[1] = { + { 0, 0, 1, 8 } + }; + + raw_cmd.cmd_count = 6; + raw_cmd.cmd[0] = FD_FORMAT; /* format command */ + raw_cmd.cmd[1] = dn /* drive */; + raw_cmd.cmd[2] = 2; /* sizecode used for formatting */ + raw_cmd.cmd[3] = 1; /* sectors per track */ + raw_cmd.cmd[4] = 255; /* gap. unimportant anyways */ + raw_cmd.cmd[5] = 3; + raw_cmd.data = format_map; + raw_cmd.length = sizeof(format_map); + raw_cmd.flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK | + FD_RAW_WRITE; + raw_cmd.rate = rate; + raw_cmd.track = cylinder; + + tmp = ioctl(fd, FDRAWCMD, & raw_cmd); + if ( tmp < 0 ){ + perror("format"); + exit(1); + } +} + + +void readid(int fd, int dn, int rate, int cylinder) +{ + struct floppy_raw_cmd raw_cmd; + int tmp; + + raw_cmd.cmd_count = 2; + raw_cmd.cmd[0] = FD_READID; /* format command */ + raw_cmd.cmd[1] = dn /* drive */; + raw_cmd.flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK; + raw_cmd.rate = rate; + raw_cmd.track = cylinder; + + tmp = ioctl( fd, FDRAWCMD, & raw_cmd ); + if ( tmp < 0 ){ + perror("readid"); + exit(1); + } +} + + +int measure_raw_capacity(int fd, int dn, int rate, + int cylinder, int warmup, int verbosity) +{ + int cap, min, ctr; + + if(warmup) + /* first formatting, so that we have sth to read during the + * warmup cycles */ + m_format_track(fd, dn, rate, cylinder); + + m_format_track(fd, dn, rate, cylinder); + min = cap = read_track(fd, dn, rate, cylinder); + ctr = 0; + while(ctr < 10) { + m_format_track(fd, dn, rate, cylinder); + cap = read_track(fd, dn, rate, cylinder); + if(cap < min) { + min = cap; + ctr = 0; + } else + ctr++; + if(verbosity) + fprintf(stderr,"warmup cycle: %3d %6d %6d\r", ctr, + cap, min); + + } + if(verbosity) + fprintf(stderr," \r"); + return min; +} diff --git a/src/mediaprm b/src/mediaprm new file mode 100644 index 0000000..1070d36 --- /dev/null +++ b/src/mediaprm @@ -0,0 +1,786 @@ +# /etc/fdprm - floppy disk parameter table + +######################################################################## +# Standard linux disk formats. Names are of the form +# actual media capacity/maximum drive capacity +# (Note: although 5.25" HD drives can format disks at 1.44M, they're listed +# as 1200 because that's the common maximum size.) + +# size sec/t hds trk stre gap rate spec1 fmt_gap + +"360/360": + DS DD sect=9 + +"1200/1200": + DS HD sect=15 + +"360/720": + SS DD sect=9 + +"720/720": + DS DD sect=9 + +"360/1200": + DS DD sect=9 + +"720/1200": + DS QD sect=9 + +"1440/1440": + DS HD sect=18 + +"2880/2880": + DS ED sect=36 + +"2880/2880": + DS ED sect=36 + +"2880/2880": + DS ED sect=36 + +"1440/1200": + DS HD sect=18 + +"1680/1440": + DS HD sect=21 + +"410/1200": + DS DD sect=10 cyl=41 + +"820/1440": + DS DD sect=10 cyl=82 + +"1476/1200": + DS HD sect=18 cyl=82 + +"1722/1440": + DS HD sect=21 cyl=82 + +"420/1200": + DS DD sect=10 cyl=42 + +"830/1440": + DS DD sect=10 cyl=83 + +"1494/1200": + DS HD sect=18 cyl=83 + +"1743/1440": + DS HD sect=21 cyl=83 + +"1743/1440": + DS HD sect=21 cyl=83 + +"880/1200": + DS QD tracksize=11b ssize=1KB + +"1040/720": + DS QD sect=13 + +"1120/720": + DS QD tracksize=7KB mss + +"1600/1200": + DS HD tracksize=10KB mss + +"1760/1440": + DS HD sect=11 ssize=1KB + +"1920/1440": + DS HD tracksize=12KB mss + +"3200/2880": + DS ED sect=5 ssize=4KB + +"3520/2880": + DS ED tracksize=22KB ssize=4KB + +"3840/2880": + DS ED sect=3 ssize=8KB + +"3840/2880": + DS ED sect=3 ssize=8KB + +"1840/1440": + DS HD tracksize=23b ssize=2KB + +"800/720": + DS DD sect=10 + +"1600/1440": + DS HD sect=20 + +######################################################################## +# CP/M formats +# +# the name is constructed as CODsize, where COD identifies the +# brand of the computer having formatted the disk + +# Generic CP/M - SSSD 8" + +"GEN250": + SS DD sect=24 dtr=0 fm=1 cyl=77 ssize=128 + +# ABC-80 - SSDD 48 tpi 5.25" + +"ABC160": + SS DD sect=16 ssize=256 + +# Actrix (Access Matrix) - SSDD 48 tpi 5.25" + +"ACT180": + SS DD sect=9 + +# Adler Textriter - SSDD 48 tpi 5.25" + +"ADL160": + SS DD sect=16 ssize=256 + +# Advanced Digital Super 6 - SSDD 48 tpi 5.25" + +"ADV160": + SS DD sect=4 ssize=1KB + +# Advanced Digital Super 6 - DSDD 96 tpi 5.25" + +"ADV640": + DS QD sect=4 ssize=1KB + +# Altos Series 5 - DSDD 96 tpi 5.25" + +"ALT720": + DS QD sect=9 + +# Amigo - SSDD 48 tpi 5.25" + +"AMI200": + SS DD sect=10 + +# Ampro - SSDD 48 tpi 5.25" + +"AMP200": + SS DD sect=10 + +# Ampro - SSDD 96 tpi 5.25" + +"AMP400": + SS QD sect=5 ssize=1KB + +# Amstrad PCW8256 - DSDD 96 tpi 5.25" + +"AMS720": + DS QD sect=9 + +# Archive I - SSDD 96 tpi 5.25" + +"ARC400": + SS QD sect=5 ssize=1KB + +# Archive II & III - DSDD 96 tpi 5.25" + +"ARC800": + DS QD sect=5 ssize=1KB + +# Arisia - SSDD 48 tpi 5.25" + +"ARI180": + SS DD sect=18 ssize=256 + +# ATR-8000 - SSDD 48 tpi 5.25" + +"ATR200": + SS DD sect=5 ssize=1KB + +# Beehive - DSDD 48 tpi 5.25" + +"BEE400": + DS DD sect=10 + +# Bitelex - SSDD 48 tpi 5.25" + +"BIT160": + SS DD sect=16 ssize=256 + +# BMC IF800 Model 20 - DSDD 48 tpi 5.25" + +"BMC400": + DS DD sect=10 + +# Burr-Brown - DSDD 48 tpi 5.25" + +"BUR360": + DS DD sect=18 ssize=256 + +# Cal-PC - DSDD 48 tpi 5.25" + +"CAL400": + DS DD sect=5 ssize=1KB + +# Cashcom 100 - DSDD 96 tpi 5.25" + +"CAS640": + DS QD sect=4 ssize=1KB + +# CDI-5000 - DSDD 48 tpi 5.25" + +"CDI400": + DS DD sect=5 ssize=1KB + +# CMC Supersystem 2 - DSDD 96 tpi 5.25" + +"CMC800": + DS QD sect=5 ssize=1KB + +# Coleco ADAM, 40 track - SSDD 48 tpi 5.25" + +"COL160": + SS DD sect=8 + +# Compugraphic MCS-5 - SSDD 48 tpi 5.25" + +"COM160": + SS DD sect=16 ssize=256 + +# Compupro (Viasyn) (1024 bytes/sector) - DSDD 96 tpi 5.25" + +"COM800": + DS QD sect=5 ssize=1KB + +# Cromemco CDOS - SSSD 48 tpi 5.25" + +"CRO80": + SS SD sect=16 dtr=1 fm=1 ssize=128 + +# Cromemco CDOS - SSDD 48 tpi 5.25" + +"CRO200": + SS DD sect=10 + +# Cromemco CP/M - SSDD 48 tpi 5.25" + +"CRO200": + SS DD sect=10 + +# C/WP Cortex - SSDD 48 tpi 5.25" + +"CWP200": + SS DD sect=10 + +# Cykey - DSDD 48 tpi 5.25" + +"CYK320": + DS DD sect=16 ssize=256 + +# DEC DECMate II - SSDD 96 tpi 5.25" + +"DEC400": + SS QD sect=10 + +# DEC Rainbow - SSDD 96 tpi 5.25" + +"DEC180": + SS DD sect=9 + +# DEC VT-180 - SSDD 48 tpi 5.25" + +"DEC180": + SS DD sect=9 + +# Direct 1025 - DSDD 48 tpi 5.25" + +"DIR320": + DS DD sect=16 ssize=256 + +# Discovery - DSDD 96 tpi 5.25" + +"DIS640": + DS QD sect=8 + +# Eagle II - SSDD 96 tpi 5.25" + +"EAG400": + SS QD sect=5 ssize=1KB + +# Epson QX-10 - DSDD 48 tpi 5.25" + +"EPS400": + DS DD sect=10 + +# Epson QX-10 (256 bytes/sector) - DSDD 48 tpi 5.25" + +"EPS320": + DS DD sect=16 ssize=256 + +# Epson PX-8 - DSDD 3.5" + +"EPS320": + DS DD sect=8 + +# Ericsson DTC - SSDD 96 tpi 5.25" + +"ERI320": + SS QD sect=16 ssize=256 + +# Ericsson Step One - DSDD 96 tpi 5.25" + +"ERI720": + DS QD sect=9 + +# Florida Graphics - DSDD 96 tpi 5.25" + +"FLO640": + DS QD sect=16 ssize=256 + +# Formula 1 - DSDD 48 tpi 5.25" + +"FOR360": + DS DD sect=18 ssize=256 + +# Fujitsu Micro 16 - DSDD 48 tpi 5.25" + +"FUJ320": + DS DD sect=16 ssize=256 + +# Fujitsu Micro 8 - DSDD 48 tpi 5.25" + +"FUJ320": + DS DD sect=16 ssize=256 + +# HCL System 2 - DSDD 96 tpi 5.25" + +"HCL800": + DS QD sect=5 ssize=1KB + +# Heath H89, Magnolia CP/M - SSDD 48 tpi 5.25" + +"HEA180": + SS DD sect=9 + +# Heurikon MLZ-91A - DSDD 96 tpi 5.25" + +"HEU640": + DS QD sect=16 ssize=256 + +# IBM PC, CP/M-86 - SSDD 48 tpi 5.25" + +"IBM160": + SS DD sect=8 + +# IMS 5000 - SSDD 48 tpi 5.25" + +"IMS160": + SS DD sect=16 ssize=256 + +# IMS 5000 TurboDOS - DSDD 96 tpi 5.25" + +"IMS800": + DS QD sect=5 ssize=1KB + +# Intel iPDS 100 - DSDD 96 tpi 5.25" + +"INT640": + DS QD sect=16 ssize=256 + +# Insight Enterprises - DSDD 48 tpi 5.25" + +"INS320": + DS DD sect=16 ssize=256 + +# Ithaca Intersystems - SSDD 96 tpi 5.25" + +"ITH360": + SS QD sect=18 ssize=256 + +# Jet-80 - DSDD 48 tpi 5.25" + +"JET400": + DS DD sect=5 ssize=1KB + +# Lexoriter - SSDD 48 tpi 5.25" + +"LEX160": + SS DD sect=16 ssize=256 + +# LNW 2 - SSDD 48 tpi 5.25" + +"LNW180": + SS DD sect=18 ssize=256 + +# Macsym 150 - SSDD 96 tpi 5.25" + +"MAC320": + SS QD sect=8 + +# Magic - DSDD 48 tpi 5.25" + +"MAG400": + DS DD sect=10 + +# MAI Basic Four - DSDD 96 tpi 5.25" + +"MAI640": + DS QD sect=16 ssize=256 + +# Micron Quark - DSDD 48 tpi 5.25" + +"MIC320": + DS DD sect=4 ssize=1KB + +# Monroe 8800 Series - SSDD 96 tpi 5.25" + +"MON320": + SS QD sect=16 ssize=256 + +# Morrow MD2 - SSDD 48 tpi 5.25" + +"MOR200": + SS DD sect=5 ssize=1KB + +# Morrow MD3, 5, 11, 16, 34 - DSDD 48 tpi 5.25" + +"MOR400": + DS DD sect=5 ssize=1KB + +# Morrow TurboDOS - DSDD 48 tpi 5.25" + +"MOR320": + DS DD sect=4 ssize=1KB + +# NCR FirstStep - DSDD 96 tpi 5.25" + +"NCR640": + DS QD sect=16 ssize=256 + +# NEC PC-8001A - SSDD 48 tpi 5.25" + +"NEC160": + SS DD sect=16 ssize=256 + +# NEC PC 8801A/8831A - DSDD 48 tpi 5.25" + +"NEC320": + DS DD sect=8 + +# NEC PC 8500/8431A, Starlet - DSDD 3.5" + +"NEC320": + SS QD sect=16 ssize=256 + +# Nixdorf 8810/30 - DSDD 96 tpi 5.25" + +"NIX800": + DS QD sect=10 + +# OKI IF800 Model 20 - DSDD 48 tpi 5.25" + +"OKI400": + DS DD sect=10 + +# Olivetti ETV300 - SSDD 48 tpi 5.25" + +"OLI180": + SS DD sect=18 ssize=256 + +# Olivetti M20 - DSDD 48 tpi 5.25" + +"OLI320": + DS DD sect=16 ssize=256 + +# Olivetti 250 - SSDD 3.5" + +"OLI320": + SS QD sect=16 ssize=256 + +# Olympia EX-100 - DSDD 48 tpi 5.25" + +"OLY360": + DS DD sect=9 + +# Olympia ETX II - SSDD 48 tpi 5.25" + +"OLY180": + SS DD sect=9 + +# Osborne 1 - SSSD 48 tpi 5.25" + +"OSB100": + SS SD sect=10 dtr=1 fm=1 ssize=256 + +# Osborne 1 - SSDD 48 tpi 5.25" + +"OSB200": + SS DD sect=5 ssize=1KB + +# Osborne Executive - SSDD 48 tpi 5.25" + +"OSB200": + SS DD sect=5 ssize=1KB + +# Osborne 1 + Osmosis - DSDD 96 tpi 5.25" + +"OSB400": + DS DD sect=10 + +# Osborne Vixen - DSDD 48 tpi 5.25" + +"OSB400": + DS DD sect=5 ssize=1KB + +# Osborne Executive w/Z3 - DSDD 96 tpi 5.25" + +"OSB800": + DS QD sect=5 ssize=1KB + +# OSM Zeus 4 - DSDD 96 tpi 5.25" + +"OSM640": + DS QD sect=8 + +# Panasonic KX-E828 - DSDD 48 tpi 5.25" + +"PAN320": + DS DD sect=16 ssize=256 + +# Pegasus Data Logger - DSDD 48 tpi 5.25" + +"PEG360": + DS DD sect=9 + +# Philips PC-2010 - SSDD 48 tpi 5.25" + +"PHI160": + SS DD sect=16 ssize=256 + +# Philips PC-3000 - 3004 - SSDD 96 tpi 5.25" + +"PHI320": + SS QD sect=16 ssize=256 + +# Pied Piper - DSDD 96 tpi 5.25" + +"PIE800": + DS QD sect=10 + +# PMC Micromate - DSDD 48 tpi 5.25" + +"PMC400": + DS DD sect=5 ssize=1KB + +# Proglas 770KB - DSDD 96 tpi 5.25" + +"PRO800": + DS QD sect=10 + +# Royal Alphatronic - DSDD 48 tpi 5.25" + +"ROY320": + DS DD sect=16 ssize=256 + +# Sage IV - DSDD 96 tpi 5.25" + +"SAG640": + DS QD sect=8 + +# Sanyo MBC-1000, MBC-1150 - DSDD 48 tpi 5.25" + +"SAN320": + DS DD sect=16 ssize=256 + +# Sanyo MBC-1250 - DSDD 96 tpi 5.25" + +"SAN640": + DS QD sect=16 ssize=256 + +# Seequa Chameleon - SSDD 48 tpi 5.25" + +"SEE160": + SS DD sect=8 + +# Seiko - DSDD 96 tpi 5.25" + +"SEI640": + DS QD sect=16 ssize=256 + +# Siemens PG-685 - DSDD 96 tpi 5.25" + +"SIE720": + DS QD sect=9 + +# Siemens PG-675 DSDD 48 tpi 5.25" + +"SIE360": + DS DD sect=9 + +# Siemens PG-635 DSDD 3.5" + +"SIE720": + DS QD sect=9 + +# Sorbus TurboDOS - 5.25" DSHD (or 8" DSDD) + +"SOR1232": + DS HD sect=8 cyl=77 ssize=1KB + +# Sperry UTS 30, UTS 5000 - DSDD 96 tpi 5.25" + +"SPE720": + DS QD sect=9 + +# Superbrain JR - SSDD 48 tpi 5.25" + +"SUP175": + SS DD sect=10 cyl=35 + +# Superbrain 40 track - SSDD 48 tpi 5.25" + +"SUP200": + SS DD sect=10 + +# Systel 2 - SSDD 48 tpi 5.25" + +"SYS180": + SS DD sect=9 + +# Systel 3 - DSDD 48 tpi 5.25" + +"SYS360": + DS DD sect=9 + +# Televideo 801, 806 - DSDD 48 tpi 5.25" + +"TEL360": + DS DD sect=18 ssize=256 + +# Televideo 1603 - DSDD 96 tpi 5.25" + +"TEL720": + DS QD sect=9 + +# TI Professional, CP/M-86 - SSDD 48 tpi 5.25" + +"TI1160": + SS DD sect=8 + +# Toshiba T100, T200 - DSDD 48 tpi 5.25" + +"TOS320": + DS DD sect=16 ssize=256 + +# TRS-80 Model 1, Omikron CP/M - SSSD 48 tpi 5.25" + +"TRS0": + SS SD sect=16 dtr=1 fm=1 cyl=0 ssize=128 + +# TRS-80 Model 1, Color Power II - SSDD 48 tpi 5.25" + +"TRS180": + SS DD sect=18 ssize=256 + +# TRS-80, MM CP/M - SSDD 48 tpi 5.25" + +"TRS200": + SS DD sect=10 + +# TRS-80 Model 4, MT CP/M - SSDD 48 tpi 5.25" + +"TRS180": + SS DD sect=18 ssize=256 + +# TRS-80 Model 4, MT CP/M - DSDD 48 tpi 5.25" + +"TRS360": + DS DD sect=18 ssize=256 + +# TRS-80 Model 4 - SSDD 48 tpi 5.25" + +"TRS160": + SS DD sect=8 + +# Visual 1050 - SSDD 96 tpi 5.25" + +"VIS400": + SS QD sect=10 + +# Wangwriter - DSDD 48 tpi 5.25" + +"WAN320": + DS DD sect=16 ssize=256 + +# Wave Mate Bullet - SSDD 48 tpi 5.25" + +"WAV200": + SS DD sect=5 ssize=1KB + +# Xerox 820 - SSSD 48 tpi 5.25" + +"XER80": + SS SD sect=16 dtr=1 fm=1 ssize=128 + +# Xerox 820 II - SSDD 48 tpi 5.25" + +"XER160": + SS DD sect=16 ssize=256 + +# Zenith Z-37 Disk - SSSD 48 tpi 5.25" + +"ZEN100": + SS SD sect=10 dtr=1 fm=1 ssize=256 + +# Zenith Z-37 Disk - DSDD 96 tpi 5.25" + +"ZEN640": + DS QD sect=16 ssize=256 + +# Zenith Z89, Heath H89 - DSDD 48 tpi 5.25" + +"ZEN320": + DS DD sect=16 ssize=256 + +# Zenith Z89, Heath H89 - DSDD 96 tpi 5.25" + +"ZEN640": + DS QD sect=16 ssize=256 + +# Zenith Z90 - SSDD 48 tpi 5.25" + +"ZEN160": + SS DD sect=16 ssize=256 + +# Zenith Z90 - DSDD 48 tpi 5.25" + +"ZEN320": + DS DD sect=16 ssize=256 + +# Zenith Z-100 - SSDD 48 tpi 5.25" + +"ZEN160": + SS DD sect=8 + +# Zenith Z-100 - DSDD 48 tpi 5.25" + +"ZEN320": + DS DD sect=8 + + + +######################################################################## +# Other interesting formats, please contribute ;-) +# + +# Commodore 1581 (the 3 1/2 drive of the Commodore 128) +"CBM1581": + DS DD sect=10 swapsides + +# Color computer, sides 1 and 2 +"COCO1": + SS DD sect=18 cyl=35 ssize=256 + +"COCO2": + SS DD sect=18 cyl=35 ssize=256 + +# TO7 (Thomson), sides 1 and 2 +"TO7-1" + SS DD sect=16 ssize=256 + +"TO7-2" + SS DD sect=16 ssize=256 swapsides diff --git a/src/mediaprm.c b/src/mediaprm.c new file mode 100644 index 0000000..cbfbe07 --- /dev/null +++ b/src/mediaprm.c @@ -0,0 +1,303 @@ +#include +#include +#include +#include +#include "parse.h" +#include "mediaprmP.h" +#include "driveprm.h" +#include "mediaprm.h" + +typedef enum +{ + FE_UNKNOWN, + FE_SIZE, + FE_SECT, + FE_VSECT, + FE_HEAD, + FE_CYL, + + /* the stretch byte */ + FE_TPI, + FE_STRETCH, + FE_SWAPSIDES, + + FE_GAP, + + FE_FM, + FE_PERP, + FE_SSIZE, + FE_2M, + FE_DTR, + + FE_SPEC1, /* spec1, obsolete */ + FE_FMT_GAP, + + FE_DENSITY, +} field_t; + +static int SIZE, SECT, VSECT, HEAD, CYL, TPI, STRETCH, SWAPSIDES, GAP, FM; +static int PERP, SSIZE, _2M, DTR, SPEC1, FMT_GAP, DENSITY; +static int ssize; + +#define F_SIZE FE_SIZE,&SIZE +#define F_SECT FE_SECT,&SECT +#define F_VSECT FE_VSECT,&VSECT +#define F_HEAD FE_HEAD,&HEAD +#define F_CYL FE_CYL,&CYL + +#define F_TPI FE_TPI,&TPI +#define F_STRETCH FE_STRETCH,&STRETCH +#define F_SWAPSIDES FE_SWAPSIDES,&SWAPSIDES + +#define F_GAP FE_GAP,&GAP + +#define F_FM FE_FM,&FM +#define F_PERP FE_PERP,&PERP +#define F_SSIZE FE_SSIZE,&SSIZE +#define F_2M FE_2M,&_2M +#define F_DTR FE_DTR,&DTR + +#define F_SPEC1 FE_SPEC1,&SPEC1 +#define F_FMT_GAP FE_FMT_GAP,&FMT_GAP + +#define F_DENSITY FE_DENSITY,&DENSITY + +static int mask; + +static keyword_t ids[]= { + { "size", F_SIZE, 0 }, + { "sect", F_SECT, 0}, + { "vsect", F_VSECT, 0}, + { "tracksize", F_VSECT, 0}, + { "head", F_HEAD, 0}, + { "ss", F_HEAD, 1}, + { "ds", F_HEAD, 2}, + { "cyl", F_CYL, 0}, + + { "tpi", F_TPI, 0 }, + { "stretch", F_STRETCH, 0 }, + + { "swapsides", F_SWAPSIDES, 1}, + + { "gap", F_GAP, 0}, + + { "fm", F_FM, 1}, + { "perp", F_PERP, 0}, + { "ssize", F_SSIZE, 0}, + { "2m", F_2M, 1}, + { "dtr", F_DTR, 0}, + + { "mss", F_SSIZE, 16384 }, + { "sd", F_DENSITY, DENS_SD }, + { "dd", F_DENSITY, DENS_DD }, + { "qd", F_DENSITY, DENS_QD }, + { "hd", F_DENSITY, DENS_HD }, + { "ed", F_DENSITY, DENS_ED }, + + { "spec1", F_SPEC1, 0}, + { "fmt_gap", F_FMT_GAP, 0} +}; + + +struct +{ + int dtr; /* dtr, as it would be in a 3 1/2 or DD drive */ + int fm; /* fm mode */ + int perp; /* perp mode */ + int tpi; + int capacity[4]; /* capacity per track */ +} dens_tab[] = { + { 0, 0, 0, 0}, /* none */ + {2, 1, 0, 48, { 2500, 2500, 2500, 2500} }, /* SD */ + {2, 0, 0, 48, { 6250, 6250, 6250, 6250} }, /* DD */ + {1, 0, 0, 96, { 6250, 7500, 6250, 0} }, /* QD */ + {0, 0, 0, 96, {12500,12500,10416, 0} }, /* HD */ + {3, 0, 1, 96, {25000,25000, 0, 0} } /* ED */ +}; + +int gap[4] = { 0x1b, 0x23, 0x2a, 0x1b }; + +static inline void set_field(field_t slot, int *var, int value) +{ + if( !(mask & (1 << slot))) + *var = value; +} + +static void compute_params(drivedesc_t *drvprm, + struct floppy_struct *medprm) +{ + int r, capacity, mysize; + int header_size, fmt_gap; + + set_field(F_DENSITY, drvprm->type.max_density); + + r = dens_tab[DENSITY].dtr; + if(r == 2 && drvprm->type.rpm == 360) + r = 1; + + capacity = dens_tab[DENSITY].capacity[drvprm->type.ff]; + + set_field(F_DTR, r); + + set_field(F_GAP, gap[DTR]); + + set_field(F_FM, dens_tab[DENSITY].fm); + set_field(F_PERP, dens_tab[DENSITY].perp); + + set_field(F_HEAD, 2); + + /* 5 1/4 drives have two different cylinder densities */ + if(drvprm->type.ff == FF_525) { + if(DENSITY == DENS_DD) + /* double density disks are 48 TPI */ + set_field(F_TPI, 48); + else + set_field(F_TPI, 96); + + if(mask & (1 << FE_CYL)) { + /* we know the number of cylinders, try to infer + * cylinder density from there */ + if(CYL < 50) + set_field(F_TPI, 48); + if(CYL > 70) + set_field(F_TPI, 96); + } + + if(drvprm->type.tpi == 96 && TPI == 48) + set_field(F_STRETCH, 1); + else + set_field(F_STRETCH, 0); + + /* if, on the other hand, we know TPI, but not the number of + * cylinders, infer in the other direction */ + if(TPI == 48) + set_field(F_CYL, 40); + else + set_field(F_CYL, 80); + } else { + set_field(F_STRETCH, 0); + set_field(F_CYL, 80); + } + + if(PERP) + header_size = 81; + else + header_size = 62; + + switch(capacity) { + case 25000: + set_field(F_SECT, 36); + break; + case 12500: + set_field(F_SECT, 18); + break; + case 10416: + set_field(F_SECT, 15); + break; + case 6250: + set_field(F_SECT, 9); + break; + default: + set_field(F_SECT, capacity / (SSIZE + header_size + 1)); + } + + set_field(F_SSIZE, 512); + set_field(F_VSECT, SECT * SSIZE); + set_field(F_SIZE, HEAD * CYL * VSECT / 512); + + if(mask & ( 1 << FE_SSIZE) ) { + mysize = 128; + for(ssize = 0; ssize < 8 ; ssize++) { + if(mysize == SSIZE) + break; + mysize += mysize; + } + if(ssize == 8) { + fprintf(stderr,"Bad sector size\n"); + exit(1); + } + ssize = (ssize + 6) % 8; + } else + ssize = 0; + + if(VSECT && VSECT >= SSIZE) { + fmt_gap = (capacity * 199 / 200 / (VSECT / SSIZE)) - + SSIZE - header_size; + if(fmt_gap < 1) + fmt_gap = 1; + if(fmt_gap > 0x6c) + fmt_gap = 0x6c; + set_field(F_FMT_GAP, fmt_gap); + } + set_field(F_2M,0); + + medprm->size = SIZE; + medprm->sect = VSECT / 512; + medprm->head = HEAD; + medprm->track = CYL; + medprm->stretch = STRETCH | (SWAPSIDES << 1); + medprm->gap = GAP; + medprm->rate = (FM<<7) | (PERP<<6) | (ssize<<3) | (_2M<<2) | DTR; + medprm->spec1 = SPEC1; + medprm->fmt_gap = FMT_GAP; +} + + +/* ========================================= * + * Routines called by other parts of fdutils * + * ========================================= */ + + +static int parse_indirect(int argc, char **argv, + drivedesc_t *drvprm, + struct floppy_struct *medprm) +{ + int found; + + if(argc != 1) + return 2; /* more than one parameter */ + mediaprmin = fopen(MEDIAPRMFILE, "r"); + if(!mediaprmin) + return 2; /* no file */ + + zero_all(ids, &mask); + + found = 0; + mediaprmlex(argv[0], ids, sizeof(ids)/sizeof(ids[0]), &mask, &found); + if(!found) + return 1; + compute_params(drvprm, medprm); + return 0; +} + +static int parse_direct(int argc, char **argv, + drivedesc_t *drvprm, + struct floppy_struct *medprm) +{ + int i,r; + mask = 0; + zero_all(ids, &mask); + for(i=0; i +#include +#include "parse.h" +#include "mediaprmP.h" +#include "mediaprm.h" +static int lineno; +static int col; +%} + +%option noyywrap +%option pointer + +fid [^\"]+ +vid [A-Za-z_][A-Za-z0-9_]* +number (0x[a-zA-Z0-9]+|-?[0-9]+)(KB|k|b)? + +%% +\n { col = 0; lineno++; } +[ \t] { col++;} +#.*\n { col = 0; lineno++;} +\042{fid}\042: { + col += yyleng; + if(*found) return 0; + _zero_all(ids, size, mask); + + yytext[yyleng-2]='\0'; + if(!strcasecmp(yytext+1, name)) + *found = 1; +} + +alias=\042{fid}\042 { + col += yyleng; + yytext[yyleng-1]='\0'; + if(!strcasecmp(yytext+7, name)) + *found = 1; +} + +swapsides | +mss | +2m | +2M | +ss | +SS | +ds | +DS | +sd | +SD | +dd | +DD | +qd | +QD | +hd | +HD | +ed | +ED | +{vid}={number} { + col += yyleng; + _set_int(yytext, ids, size, mask); +} + +[^\t \n][^\t =\n]* { + yytext[yyleng-1]='\0'; + fprintf(stderr, + "Syntax error in " MEDIAPRMFILE + " at line %d col %d: %s unexpected\n", + lineno+1, col+1, yytext_ptr); + return 1; +} +%% + diff --git a/src/mediaprmP.h b/src/mediaprmP.h new file mode 100644 index 0000000..9aca367 --- /dev/null +++ b/src/mediaprmP.h @@ -0,0 +1,12 @@ +void mediaprm_match(char *name, int mode); +void mediaprm_init_search(char *name); +void mediaprm_stop_if_found(void); +int mediaprm_set_int(char *name); +void mediaprm_zero_all(void); + +extern FILE *mediaprmin; + +#define YY_DECL int mediaprmlex(char *name, struct keyword_l *ids, int size, \ + int *mask, int *found) + +YY_DECL; diff --git a/src/message_seen b/src/message_seen new file mode 100644 index 0000000..e69de29 diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..abd2618 --- /dev/null +++ b/src/misc.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include "fdutils.h" + + +void *safe_calloc(size_t nmemb, size_t size) +{ + void *ptr; + + ptr = calloc(nmemb, size); + if(!ptr) { + fprintf(stderr,"Out of memory error\n"); + exit(1); + } + return ptr; +} + + +void *safe_malloc(size_t size) +{ + void *ptr; + + ptr = malloc(size); + + if(!ptr) { + fprintf(stderr,"Out of memory error\n"); + exit(1); + } + return ptr; +} diff --git a/src/oldfdprm.c b/src/oldfdprm.c new file mode 100644 index 0000000..6e27660 --- /dev/null +++ b/src/oldfdprm.c @@ -0,0 +1,111 @@ +/* setfdprm.c - Sets user-provided floppy disk parameters, re-activates + autodetection and switches diagnostic messages. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "oldfdprm.h" + +#define FDPRMFILE "/etc/fdprm" +#define MAXLINE 200 + + +static unsigned long convert(char *arg, int *error) +{ + unsigned long result; + char *end; + + result = strtoul(arg,&end,0); + if (!*end) + return result; + *error = 1; + return 0; +} + +static int set_params(char **params, struct floppy_struct *ft) +{ + int error; + + error = 0; + ft->size = convert(params[0],&error); + ft->sect = convert(params[1],&error); + ft->head = convert(params[2],&error); + ft->track = convert(params[3],&error); + ft->stretch = convert(params[4],&error); + ft->gap = convert(params[5],&error); + ft->rate = convert(params[6],&error); + ft->spec1 = convert(params[7],&error); + ft->fmt_gap = convert(params[8],&error); + return error; +} + +int scan_fdprm(FILE *file, char *name, struct floppy_struct *ft, + void (*callback)(char *name, char *comment, + struct floppy_struct *ft)) +{ + char line[MAXLINE+2],this[MAXLINE+2],param[9][MAXLINE+2]; + char *params[9],*start; + char *comment; + int i, lineno; + + lineno = 0; + while (fgets(line,MAXLINE,file)) { + lineno++; + for (start = line; *start == ' ' || *start == '\t'; start++); + if (!*start || *start == '\n' || *start == '#') { + /* comment line, print as is */ + if(!name) + printf("%s", line); + continue; + } + + comment = strchr(start, '#'); + if(comment) { + *comment='\0'; + comment++; + } + if (sscanf(start,"%s %s %s %s %s %s %s %s %s %s",this,param[0], + param[1],param[2],param[3],param[4],param[5],param[6], + param[7],param[8]) != 10) { + fprintf(stderr,"Syntax error in line %d: '%s'\n", + lineno, line); + exit(1); + } + for(i=0;i<9;i++) + params[i]=param[i]; + if(!name || !strcmp(this,name) ) { + i=set_params(params, ft); + if(name) + return 0; + else + callback(this, comment, ft); + } + } + return 1; +} + + +int parse_fdprm(int argc, char **argv, struct floppy_struct *ft) +{ + FILE *f; + int r; + switch(argc) { + case 1: + /* indirect */ + if ((f = fopen(FDPRMFILE,"r")) == NULL) + return 1; + r = scan_fdprm(f, argv[0], ft,0); + fclose(f); + return r; + case 9: + return set_params(argv, ft); + default: + return 1; + } +} diff --git a/src/oldfdprm.h b/src/oldfdprm.h new file mode 100644 index 0000000..bdea783 --- /dev/null +++ b/src/oldfdprm.h @@ -0,0 +1,3 @@ +int scan_fdprm(FILE *f, char *name, struct floppy_struct *ft, + void (*callback)(char *, char *, struct floppy_struct *)); +int parse_fdprm(int argc, char **argv, struct floppy_struct *ft); diff --git a/src/params.h.in b/src/params.h.in new file mode 100644 index 0000000..bd235a2 --- /dev/null +++ b/src/params.h.in @@ -0,0 +1,2 @@ + +#define MEDIAPRMFILE SYSCONFDIR "/mediaprm" diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..f96c56f --- /dev/null +++ b/src/parse.c @@ -0,0 +1,55 @@ +#include +#include +#include "parse.h" + +int _set_int(char *name, keyword_t *ids, int size, int *mask) +{ + int i, slot; + char *ptr; + int *var; + + ptr = strchr(name,'='); + if(ptr) { + *ptr = '\0'; + ptr++; + } + + for(i=0; i +#include "printfdprm.h" + + +void print_params(drivedesc_t *drivedesc, + struct floppy_struct *ft, + level_t level, int cpm, + void (*print)(char *,int)) +{ + int ssize, r, perp_ref, need_dtr, need_fm, need_tpi; + ff_t formFactor; + + if(drivedesc) + formFactor = drivedesc->type.ff; + else + formFactor = FF_UNKNOWN; + + need_dtr = 0; + need_fm = 0; + need_tpi = 0; + + switch(ft->head) { + case 1: + print("SS",0); + break; + case 2: + print("DS",0); + break; + } + perp_ref = 0; + switch(r = ft->rate & 0x83) { + case 0: + print("HD",0); + break; + case 0x80: + need_tpi = need_fm = need_dtr = 1; + print("DD", 0); /* 8 " DD */ + break; + case 1: + case 2: + switch(formFactor) { + case FF_35: + if(r == 1) + /* modified double-density + * format with slightly higher + * DTR */ + print("QD",0); + else + print("DD",0); + break; + case FF_525: + if(ft->track >= 60) + print("QD",0); + else + print("DD",0); + break; + default: + /* we do not not the drive type. + * Guesswork */ + if(ft->track <= 60) + /* this covers any 40 track + * formats */ + print("DD",0); + else if(r == 1) + /* this covers the special + * density 3 1/2 format, as + * well as the quad density + * 5 1/4 format */ + print("QD",0); + else + /* this leaves norma 3 1/2 DD */ + print("DD",0); + break; + } + break; + case 3: + perp_ref = 0x40; + print("ED",0); + break; + default: + need_tpi = need_fm = need_dtr = 1; + print("SD",0); + break; + } + + switch(formFactor) { + /* TPI is only meaningful for 5 1/4 drives. As other + * drives have different physical sizes, the numbers of + * 48 or 96 would be inappropriate anyways: use stretch in + * that case */ + case FF_525: + if(level >= LEV_ALL) { + if(ft->track <= 60) + print("tpi=48",0); + else + print("tpi=96",0); + } + break; + case FF_UNKNOWN: + if(level >= LEV_ALL && ft->track <= 60) + print("tpi=48",0); + break; + default: + if(level >= LEV_ALL || ft->stretch) + print("stretch=%d", ft->stretch); + break; + } + + if(level >= LEV_ALL || ft->size != ft->sect * ft->head * ft->track) + print("size=%d", ft->size); + + ssize = (((ft->rate & 0x38) >> 3) + 2) % 8; + if(ssize == 2) + print("sect=%d", ft->sect); + else { + if( (ft->sect << 2) % (1 << ssize) == 0) + print("sect=%d", ft->sect << 2 >> ssize); + else { + if(ft->sect % 2) + print("tracksize=%db", ft->sect); + else + print("tracksize=%dKB", ft->sect / 2); + + } + } + + if(level >= LEV_EXPL || need_dtr) + print("dtr=%d", ft->rate & 3); + + if(level >= LEV_EXPL || perp_ref != (ft->rate & 0x40)) + print("perp=%d", (ft->rate & 0x40) >> 6); + + if(level >= LEV_EXPL || need_fm) + print("fm=%d", (ft->rate & 0x80) >> 7); + + if(level >= LEV_EXPL || (ft->track != 80 && ft->track != 40)) + print("track=%d", ft->track); + +#ifdef FD_SWAPSIDES + if(ft->stretch & FD_SWAPSIDES) + print("swapsides",0); +#endif + + if(ft->rate & FD_2M) + print("2M",0); + + if(level < LEV_ALL && + ft->sect * 4 < (2 << ssize) && ft->sect * 4 % (1 << ssize)) + print("mss", 0); + else { + if(ssize < 2) + print("ssize=%d", 128 << ssize); + else if(ssize > 2) + print("ssize=%dKB", 1 << (ssize-3)); + else if(level >= LEV_ALL) + print("ssize=512", 0); + } + + /* useless stuff */ + if(level >= LEV_MOST) { + print("gap=0x%02x", (unsigned char) ft->gap); + print("fmt_gap=0x%02x", (unsigned char) ft->fmt_gap); + } + + if(level >= LEV_ALL) + print("spec1=0x%02x", (unsigned char) ft->spec1); + printf("\n"); +} diff --git a/src/printfdprm.h b/src/printfdprm.h new file mode 100644 index 0000000..1c6ed4e --- /dev/null +++ b/src/printfdprm.h @@ -0,0 +1,18 @@ +#ifndef PRINTFDPRM_H +#define PRINTFDPRM_H + +#include "driveprm.h" + +typedef enum { + LEV_NONE, + LEV_EXPL, + LEV_MOST, + LEV_ALL, + LEV_OLD +} level_t; + +void print_params(drivedesc_t *drivedesc, + struct floppy_struct *ft, + level_t level, int cpm, + void (*print)(char *,int)); +#endif diff --git a/src/setfdprm.8 b/src/setfdprm.8 deleted file mode 100644 index f8743df..0000000 --- a/src/setfdprm.8 +++ /dev/null @@ -1,68 +0,0 @@ -.\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu) -.\" May be distributed under the GNU General Public License -.TH SETFDPRM 8 "20 November 1993" "Linux 0.99" "Linux Programmer's Manual" -.SH NAME -setfdprm \- sets user-provided floppy disk parameters -.SH SYNOPSIS -.B "setfdprm [ \-p ]" -device name -.br -.B "setfdprm [ \-p ]" -device size sectors heads tracks stretch gap rate spec1 fmt_gap -.br -.B "setfdprm [ \-c ]" -device -.br -.B "setfdprm [ \-y ]" -device -.br -.B "setfdprm [ \-n ]" -device -.SH DESCRIPTION -.B setfdprm -is a utility that can be used to load disk parameters into the -auto-detecting floppy devices and "fixed parameter" floppy devices, to -clear old parameter sets and to disable or enable diagnostic messages. - -Without any options, -.B setfdprm -loads the -.I device -(usually -.I /dev/fd0 -or -.IR /dev/fd1 ) -with a new parameter set with the -.I name -entry found in -.I /etc/fdprm -(usually named 360/360, etc.). For autodetecting floppy devices, -these parameters stay in effect until the media is changed. For "fixed -parameter" devices, they stay in effect until they are changed again. -.OPTIONS -.TP -.BI \-p " device name" -Permanently loads a new parameter set for the specified auto-configuring -floppy device for the configuration with -.I name -in -.IR /etc/fdprm . -Alternatively, the parameters can be given directly from the command line. -.TP -.BI \-c " device" -Clears the parameter set of the specified auto-configuring floppy device. -.TP -.BI -y " device" -Enables format detection messages for the specified auto-configuring floppy -device. -.TP -.BI -n " device" -Disables format detection messages for the specified auto-configuring -floppy device. -.SH BUGS -This documentation is grossly incomplete. -.SH FILES -.I /etc/fdprm -.SH AUTHOR -Werner Almesberger (almesber@nessie.cs.id.ethz.ch) -Alain Knaff (Alain.Knaff@inrialpes.fr) diff --git a/src/setfdprm.c b/src/setfdprm.c index 983acf5..1841a19 100644 --- a/src/setfdprm.c +++ b/src/setfdprm.c @@ -10,142 +10,81 @@ #include #include #include +#include "enh_options.h" +#include "mediaprm.h" +#include "driveprm.h" +#include "oldfdprm.h" + +int mcmd = 0; +int cmd = FDSETPRM; + +struct enh_options optable[] = { + { 'c', "clear", 0, EO_TYPE_NONE, FDCLRPRM, 0, &cmd, + "clear the geometry parameters" }, + { 'p', "permanent", 0, EO_TYPE_NONE, FDCLRPRM, 0, &cmd, + "set the geometry parameters permanently" }, + { 'y', "message-on", 0, EO_TYPE_NONE, FDMSGON, 0, &mcmd, + "switch messages on" }, + { 'n', "message-off", 0, EO_TYPE_NONE, FDMSGOFF, 0, &mcmd, + "switch messages off" }, + { '\0', 0 } +}; -#define FDPRMFILE "/etc/fdprm" -#define MAXLINE 200 - - -static int convert(char *arg) -{ - long result; - char *end; - - result = strtol(arg,&end,0); - if (!*end) return (int) result; - fprintf(stderr,"Invalid number: %s\n",arg); - exit(1); -} - - -static void cmd_without_param(int cmd,int fd) -{ - if (ioctl(fd,cmd,NULL) >= 0) exit(0); - perror("ioctl"); - exit(1); -} - - -static void set_params(int cmd,int fd,char **params) -{ - struct floppy_struct ft; - - ft.size = convert(params[0]); - ft.sect = convert(params[1]); - ft.head = convert(params[2]); - ft.track = convert(params[3]); - ft.stretch = convert(params[4]); - ft.gap = convert(params[5]); - ft.rate = convert(params[6]); - ft.spec1 = convert(params[7]); - ft.fmt_gap = convert(params[8]); - ft.name = NULL; - if (ioctl(fd,cmd,&ft) >= 0) exit(0); - perror("ioctl"); - exit(1); -} - - -static void find_params(int cmd,int fd,char *name) +void main(int argc,char **argv) { - FILE *file; - char line[MAXLINE+2],this[MAXLINE+2],param[9][MAXLINE+2]; - char *params[9],*start; - int count; - - if ((file = fopen(FDPRMFILE,"r")) == NULL) { - perror(FDPRMFILE); - exit(1); - } - while (fgets(line,MAXLINE,file)) { - for (start = line; *start == ' ' || *start == '\t'; start++); - if (*start && *start != '\n' && *start != '#') { - if (sscanf(start,"%s %s %s %s %s %s %s %s %s %s",this,param[0], - param[1],param[2],param[3],param[4],param[5],param[6],param[7], - param[8]) != 10) { - fprintf(stderr,"Syntax error: '%s'\n",line); + int cmd,fd,c; + char *name; + drivedesc_t drivedesc; + struct floppy_struct medprm; + int have_fmt = 0; + char *userparams="drive [geometry]"; + int mask; + + name = argv[0]; + if (argc < 3) + print_usage(name, optable, userparams); + cmd = FDSETPRM; + mcmd = 0; + while((c=getopt_enh(argc, argv, optable, 0, &mask, userparams)) != EOF){ + if(c == '?') { + fprintf(stderr,"exiting\n"); + exit(1); + } + printf("unhandled option %d\n", c); exit(1); - } - if (!strcmp(this,name)) { - for (count = 0; count < 9; count++) - params[count] = param[count]; - set_params(cmd,fd,params); - } } - } - fprintf(stderr,"No such parameter set: '%s'\n",name); - exit(1); -} - -static void usage(char *name) -{ - char *this; - - if ((this = strrchr(name,'/'))) name = this+1; - fprintf(stderr,"usage: %s [ -p ] dev name\n",name); - fprintf(stderr," %s [ -p ] dev size sect heads tracks stretch \ -gap rate spec1 fmt_gap\n",name); -#ifdef FDMEDCNG - fprintf(stderr," %s [ -c | -y | -n | -d ] dev\n",name); -#else - fprintf(stderr," %s [ -c | -y | -n ] dev\n",name); -#endif - exit(1); -} + argv += optind; + argc -= optind; + if ((fd = open(argv[0],3)) < 0) { /* 3 == no access at all */ + perror(argv[0]); + exit(1); + } + argv++; + argc--; + parse_driveprm(fd, &drivedesc); + + if(argc) { + if(parse_mediaprm(argc, argv, &drivedesc, &medprm) && + parse_fdprm(argc, argv, &medprm)) { + print_usage(name, optable, userparams); + exit(1); + } + have_fmt = 1; + } -void main(int argc,char **argv) -{ - int cmd,fd; - char *name; + if(mcmd && ioctl(fd, cmd) < 0) { + perror("message ioctl"); + exit(1); + } - name = argv[0]; - if (argc < 3) usage(name); - cmd = FDSETPRM; - if (*argv[1] == '-') { - switch (argv[1][1]) { - case 'c': - cmd = FDCLRPRM; - break; - case 'p': - cmd = FDDEFPRM; - break; - case 'y': - cmd = FDMSGON; - break; - case 'n': - cmd = FDMSGOFF; - break; -#ifdef FDMEDCNG - case 'd': - cmd = FDMEDCNG; - break; -#endif - default: - usage(name); + if(have_fmt || cmd == FDCLRPRM) { + if(ioctl(fd, cmd, &medprm) < 0) { + perror("geometry ioctl"); + exit(1); + } } - argc--; - argv++; - } - if ((fd = open(argv[1],3)) < 0) { /* 3 == no access at all */ - perror(argv[1]); - exit(1); - } - if (cmd != FDSETPRM && cmd != FDDEFPRM) { - if (argc != 2) usage(name); - cmd_without_param(cmd,fd); - } - if (argc != 11 && argc != 3) usage(name); - if (argc == 11) set_params(cmd,fd,&argv[2]); - else find_params(cmd,fd,argv[2]); + + exit(0); } diff --git a/src/skews.c b/src/skews.c new file mode 100644 index 0000000..b991abe --- /dev/null +++ b/src/skews.c @@ -0,0 +1,89 @@ +#include +#include +#include "fdutils.h" +#include "superformat.h" + + +/* computes the position at the end of this track */ +static inline int calc_end_offset(struct params *f, int cur_pos, int *lskew) +{ + int sector_skew, byte_skew; + + if(cur_pos < f->min) { + /* the current skew is smaller than the extend that this + * sequence can handle. Wait until its beginning */ + *lskew = 0; + return f->min + f->length; + } + + sector_skew = (cur_pos - f->min + f->chunksize - 1) / f->chunksize; + byte_skew = f->min + sector_skew * f->chunksize; + + if(byte_skew >= f->max) { + /* the current skew is larger than the extend that this + * sequence can handle. Wait until its next beginning */ + *lskew = 0; + return f->min + f->length + f->raw_capacity; + } + + *lskew = sector_skew; + return byte_skew + f->length; +} + + +static inline void pick_best(struct params *f, int n, + int *min, /* skew in bytes */ + int *lskew, /* skew in sectors */ + int *min_index) +{ + int i,new, t_lskew; + int cur_pos = *min; + + for(i = 0 ; i < n; i++) { + new = calc_end_offset(f+i, cur_pos, &t_lskew); + if(i == 0 || new < *min) { + *min = new; + *lskew = t_lskew; + *min_index = i; + } + } +} + + +/* calc_skews. Fill skew table for use in formatting */ +int calc_skews(struct params *fd0, struct params *fd, int n) +{ + int cylinder, head; + struct params *f = NULL; + int cur_skew, next_cylinder_skew; + int ind, rots; + + /* Amount to advance skew considering head skew already added in */ + next_cylinder_skew = cylinder_skew - head_skew; + cur_skew = absolute_skew; + + rots = 0; + for (cylinder=begin_cylinder; cylinder <= end_cylinder; ++cylinder) { + for (head=0; head < heads; ++head) { + if (!head && !cylinder && use_2m) + f = fd0; + else + f = fd; + cur_skew = cur_skew % f->raw_capacity; + pick_best(f, n, &cur_skew, + &lskews[cylinder][head], + &findex[cylinder][head]); + + rots += cur_skew / f->raw_capacity; + ind = findex[cylinder][head]; + if(lskews[cylinder][head] * fd[ind].chunksize > + fd->raw_capacity){ + fprintf(stderr,"Skew too big\n"); + abort(); + } + cur_skew += head_skew; + } + cur_skew += next_cylinder_skew; + } + return 0; +} /* End calc_skews */ diff --git a/src/superformat.1 b/src/superformat.1 deleted file mode 100644 index 10045bb..0000000 --- a/src/superformat.1 +++ /dev/null @@ -1,372 +0,0 @@ -.TH SUPERFORMAT 1 "17nov1995" "fdutils" "fdutils" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -superformat \- format floppies -.SH SYNOPSIS -.hy 0 -.na -.B superformat -\fB\-d\ \fIdrive\fR -[\fB\-D\ \fIdos-drive\fR] -[\fB\-\-dd\fR] -[\fB\-\-hd\fR] -[\fB\-\-2m\fR] -[\fB\-\-no2m\fR] -[\fB\-s\ \fIsectors\fR] -[\fB\-H\ \fIheads\fR] -[\fB\-t\ \fItracks\fR] -[\fB\-v\ \fIverbosity-level\fR] -[\fB\-b\ \fIbegin-track\fR] -[\fB\-e\ \fIend-track\fR] -[\fB\-\-dosverify\fR] -[\fB\-\-noverify\fR] -[\fB\-\-verify_later\fR] -[\fB\-S\ \fIsizecode\fR] -[\fB\-G\ \fIformat-gap\fR] -[\fB\-F\ \fIfinal-gap\fR] -[\fB\-i\ \fIinterleave\fR] -[\fB\-c\ \fIchunksize\fR] -[\fB\-g\ \fIgap\fR] -[\fB\-r\ \fIrate\fR] -[\fB\-\-absolute-skew\ \fIabsolute-skew\fR] -[\fB\-\-head-skew\ \fIhead-skew\fR] -[\fB\-\-track-skew\ \fItrack-skew\fR] -[\fB\-\-stretch\ \fIstretch-factor\fR] -[\fB\-m\ \fImargin\fR] -.ad b -.hy 1 -.SH DESCRIPTION -.B superformat -is used to format disks with a capacity of up -to 1992K HD or 3984K ED. When the disk is formatted, -.BR mformat (1) -is automatically called to put an msdos filesystem on it. You may ignore -this filesystem, if you don't need it. Be aware, however, that the -.B \-\-2m -formats were specifically designed to hold an msdos filesystem, and -take advantage from the fact that the msdos filesystem uses redundant -sectors on the first track (the FAT, which is represented twice). The -second copy of the FAT is \fInot\fR represented on the disk. -.SH OPTIONS -Many options have a long and a short form. -.TP -.B \-h \-\-help -Print the help. -.TP -.BI "\-d" " drive" " \-\-drive" " drive" -Selects the drive to format. The default is drive 0 -.RI ( /dev/fd0 ). -.TP -.BI "\-D" " drive" " \-\-dosdrive" " dos\-drive" -Selects DOS drive letter for -.BR mformat (1). -.RI ( a: -or -.IR b: ). -The colon may be omitted. The default is derived from the minor device -number. If the drive letter cannot be guessed, and is not given on the -command line, -.BR mformat -is skipped. -.TP -.BI "\-v" " verbosity\-level" " \-\-verbosity" " verbosity\-level" -Sets the verbosity level. 1 prints a dot for each formatted track. 2 -prints a changing sign for each formatted track (- for formatting the -first head, = for formatting the second head, x for verifying the -first head, and + for verifying the second head). 3 prints a complete -line listing head and track. 6 and 9 print debugging information. -.TP -.B "\-\-dd" -Format a double density disk. -.TP -.B "\-\-hd" -Format a high density disk. -.TP -.B "\-2" " \-\-2m" -Format a high capacity disk readable by the -.B 2mf -program. -.I "Only use these disks for MS\-DOS filesystems." -This option is automatically selected when you attempt to format a disk -with bigger sectors than usual. If you don't want this (for reliability -reasons), use the -.B \-\-no2m -option. -.TP -.B "\-1" " \-\-no2m" -Don't use 2m format. -.TP -.BI "\-t" " tracks" " \-\-tracks" " tracks" -Describes the number of tracks. Default is 40 or 80, depending on the -drive type or the density. -.TP -.BI "\-H" " heads" " \-\-heads" " heads" -Describes the number of heads. Default is 2. -.TP -.BI "\-s" " sectors" " \-\-sectors" " sectors" -Describe the number sectors. -.I sectors -is not the number of physical (big) sectors, but rather the number of -equivalent 512-byte sectors. If you ask for more sectors than fit on -the disk, -.B superformat -groups them automatically into bigger sectors (as long as this is -possible), unless you also specify the -.B sizecode -option. -.TP -.B "\-B" " \-\-dosverify" -Verifies the disk using the -.BR mbadblocks (1) -program. -.B mbadblocks -marks the bad sectors as bad in the FAT. The advantage of this is -that disks which are only partially bad can still be used for MS\-DOS -filesystems. -.TP -.B "\-V" " \-\-verify_later" -Verifies the whole disk at the end of the formatting process instead -of at each track. Verifying the disk at each track has the advantage -of detecting errors early on. -.TP -.B "\-f" " \-\-noverify" -Skips the verification altogether. -.SH ADVANCED OPTIONS -These options have sensible default values, so normally you won't -need to set them manually. -.TP -.BI "\-b" " begin_track" " \-\-begin_track" " begin_track" -Describes the track where to begin formatting. This is useful if the -previous formatting failed halfway through. The default is 0. -.TP -.BI "\-e" " end_track" " \-\-end_track" " end_track" -Describes where to stop formatting. -.B end_track -is the last track to be formatted plus one. This is mainly useful for -testing purposes. By default, this is the same as the total number of -tracks. When the formatting stops, the final skew is displayed (to be -used as absolute skew when you'll continue). -.TP -.BI "\-S" " sizecode" " \-\-sizecode" " sizecode" -Set the sector size to be used. The sector size is 128 * 2 ^ -.IR sizecode . -Sector sizes below 512 bytes are not supported, thus sizecode must be at -least 2. By default 512 is assumed, unless you ask for more sectors than -would fit with 512 bytes. -.TP -.BI "\-\-stretch" " stretch" -Set the stretch factor. The stretch factor describes how many physical -tracks to skip to get to the next logical track (2 ^ -.IR stretch ). -On double density 5\(14 disks, the tracks are further apart from each -other. -.TP -.BI "\-G" " fmt_gap" " \-\-format_gap" " fmt_gap" -Set the formatting gap. The formatting gap tells how far the sectors -are away from each other. By default, this is chosen so as to evenly -distribute the sectors around the circle. -.TP -.BI "\-F" " final_gap" " \-\-final_gap" " final_gap" -Set the formatting gap to be used after the last sector. -.TP -.BI "\-i" " interleave" " \-\-interleave" " interleave" -Set the sector interleave factor. -.TP -.BI "\-c" " chunksize" " \-\-chunksize" " chunksize" -Set the size of the chunks. The chunks are small auxiliary sectors -used during formatting. They are used to handle heterogeneous sector -sizes (i.e. not all sectors have the same size) and negative -formatting gaps. -.TP -.BI "\-r" " rate" " \-\-rate" " rate" -Set the raw data transfer rate (which is smaller for double density -disks than for high density disks). -.TP -.BI "\-g" " gap" " \-\-gap" " gap" -Set the read/write gap. -.TP -.BI "\-m" " margin" " \-\-margin" " margin" -Changes the number of bytes left at the end of the physical track. By -default, this is 35. Setting this to a smaller value may make disk -accesses unbearably slow. -.SH SECTOR SKEWING -In order to maximize the user data transfer rate, the sectors are -arranged in such a way that sector 1 of the new track/head comes under -the head at the very moment when the drive is ready to read from that -track, after having read the previous track. Thus the first sector of -the second track is not necessarily near the first sector of the first -track. The skew value describes for each track how far sector number -1 is away from the index mark. This skew value changes for each head -and track. The amount of this change depends on how fast the disk -spins, and on how much time is needed to change the head or the track. -.TP -.BI "\-\-absolute_skew" " absolute_skew" -Set the absolute skew. (The skew value used for the first formatted -track) -.TP -.BI "\-\-head_skew" " head_skew" -Set the head skew. (The skew added for passing from head 0 to head 1) -.TP -.BI "\-\-track_skew" " track_skew" -Set the track skew. (The skew added for seeking to the next track) -.PP -Example: (absolute skew=3, head skew=1, track skew=2) -.nf -track 0 head 0: 4,5,6,1,2,3, (skew=3) -track 0 head 1: 3,4,5,6,1,2, (skew=4) -.sp 1 -track 1 head 0: 1,2,3,4,5,6, (skew=0) -track 1 head 0: 6,1,2,3,4,5 (skew=1) -.sp 1 -track 2 head 0: 4,5,6,1,2,3, (skew=3) -track 2 head 0: 3,4,5,6,1,2, (skew=4) -.fi -.SH EXAMPLES -Assume that drive 0 is a 3\(12 and drive 1 a 5\(14. -.TP -.B superformat -Format 1440K disk in drive 0. -.TP -.B superformat \-d /dev/fd1 -Format a 1200K disk in drive 1. -.TP -.B superformat \-d /dev/fd1 -s 18 -Format a 1440K disk in drive 1. -.TP -.B superformat \-\-dd -Format a 720K disk in drive 0. -.TP -.B superformat \-s21 \-t83 -Format a 1743K disk in drive 0 (83 tracks times 21 sectors). -.TP -.B superformat \-s24 \-t83 -Format a 1992K disk in drive 0 (83 tracks times 24 "sectors"). -There won't be 24 physical 512-byte sectors on the disk, but rather -one 8192-byte sector and a 4096-byte sector. -.B superformat -will figure -out that this is the only format which fits, with that many "sectors". -24 sectors is the absolute maximum, and might not work everywhere. -.TP -.B superformat \-s23 \-\-2m -Format a 1840K disk in drive 0. It will have 5 2048-byte sectors, -one 1024-byte sector, and one 512-byte sector per track. -.PP -All these formats can be autodetected by mtools, using the floppy driver's -default settings. -.SH THE FORMATS -For this discussion, let's assume you are using high density 3\(12 -disks. Formats can be distinguished by the number of sectors, the -size of these sectors and the number of tracks. Normally, you need not -indicate the size of the sectors; -.B superformat -figures this out for you. -.SS More Sectors -With -.BR superformat , -it is possible to put more sectors than usual on the disk, just by -squeezing them closer together. However, for none of the formats is a -bigger byte density used; i.e. within a sector, each byte takes as much -space as with the normal format. Only the gaps between the sectors have -become smaller. Formats of up to 20 sectors (17 on a 5\(14 disk) can -be obtained. These formats are as fast and as reliable as the standard -format. These formats can be read under MS DOS with various shareware -utilities, and on SunOS with the -.B mtools -included in this package (define -.BR -DSPARC_ODD ). -.SS Sector Interleaving -It is possible to fit 21 sectors (or 18 with a 5\(14 drive) on one -track by making the gaps between the sectors even smaller. With this -format, the sectors are so close together that the floppy controller -is still processing the previous sector when it reaches the header of -the next sector. Thus it misses the next sector, and must wait for one -more turn, until it shows up again. That's 200 milliseconds per turn, -and this would add up to 4.4 seconds for all sectors! To avoid this, -sectors are interleaved, i.e. the second sector does not immediately -follow the first one. You get: -.nf - 1,11,2,12,3,13,4,14,5,15,6,16,7,17,8,18,9,19,10,20 -.fi -Now, the disk is only twice slower instead of 22 times slower. -.PP -Interleave is also handled automatically by -.BR superformat . -.PP -Although this format is twice as slow as the previous formats, it is as -reliable, and can also be read under MS DOS and SunOS. -.SS Bigger Sectors -By making bigger sectors, i.e., grouping smaller logical sectors in -one big sector, more data fits on the disk, because less space is -taken up by the sector headers. (The header of a big sector takes as -much space than the header of a small sector, but there are less of -them.) -.B superformat -automatically groups sectors together when needed. -The format with 11 1024-byte sectors is again as fast as the standard -format. However, it is less reliable, because a failure is likely to -erase a whole sector. So, instead of losing 512 bytes at once (normal -sector size), you might lose 1024 byte at once. The biggest format -that you can obtain with this method has the equivalent of 11264 byte -per track, split up in 11 sectors of 1024 bytes each. Unfortunately, -these formats can't be read neither under MS\-DOS nor under SunOS. -.SS Mixing Sector Sizes on the Same Track -It is possible to to put sectors of different sizes on one track. -The biggest format that you can obtain with this method has the -equivalent of 12288 byte per track, split up in a 8192 byte sector and -a 4096 byte sector. Mixing sector sizes does not introduce a new -unreliability. -.SS 2M Formats -These formats are essentially the same as the big sector formats, but -their first track is formatted using 18 normal sized sectors. These -disks can be read and written with the 2m20 utility under DOS. These -disks store only one physical copy of the FAT, and might be less -reliable for this reason. If you lose this only copy of the FAT, -there is no backup, as is the case on normal disks. -.PP -Only one FAT is stored because the first track appears to have 18 -sectors to to the applications, and the second copy of the FAT would -fall into the missing sectors. That's also the reason why you -shouldn't use these formats to store anything else than a DOS -filesystem. -.PP -The 2m option is automatically selected for disks which have a bigger -sector size than usual. If you don't want this (for reliability reasons), -select the -.B \-\-no2m -option. -.PP -The advantage of 2m is that it makes autodetection easier. The first -track can be read using the usual parameters, and its boot sector -contains the necessary information needed to read the other sectors. -Thus, autodetection only needs to probe for the standard formats (one -for ED, one for HD and one for DD). One of these formats allows to -read the boot sector, and mtools uses the information contained therein -to access the rest of the disk. -.SH DIAGNOSTICS -.TP -.B "FDC busy, sleeping for a second" -When another program accesses a disk drive on the same controller as -the one being formatted, -.B superformat -has to wait until the other access is finished. If this happens, -check whether any other program accesses a drive (or whether a drive -is mounted), kill that program (or unmount the drive), and the format -should proceed normally. -.SH BUGS -Opening up new window while superformat is running produces overrun -errors. Those are however detected, and the operation is retried. -.SH FILES -/dev/fd* - Floppy devices -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr -.SH SEE ALSO -.BR fdrawcmd (1), -.BR floppycontrol (1), -.BR getfdprm (1), -.BR mtools (1), -.BR xdfcopy (1) diff --git a/src/superformat.c b/src/superformat.c index 794f1e2..1242baa 100644 --- a/src/superformat.c +++ b/src/superformat.c @@ -22,8 +22,8 @@ 940710 AK Fixed support for 300Kbps 3.5" DD disks without 2m Todo: -- Allow reversing track order, or perhaps have option to try as many - tracks as happen to work (as in 2m). Currently, if too many tracks +- Allow reversing cylinder order, or perhaps have option to try as many + cylinders as happen to work (as in 2m). Currently, if too many cylinders are attempted it won't fail until the very end */ @@ -39,101 +39,43 @@ #include #include #include +#include #include "enh_options.h" +#include "mediaprm.h" +#include "fdutils.h" +#include "oldfdprm.h" +#include "superformat.h" -#define SET_SOFTGAP 0x1 -#define SET_ENDTRACK 0x2 -#define SET_CHUNKSIZE 0x4 -#define SET_SECTORS 0x8 -#define SET_INTERLEAVE 0x10 -#define SET_FMTGAP 0x20 -#define SET_RATE 0x40 -#define SET_SIZECODE 0x80 -#define SET_TRACKS 0x100 -#define SET_STRETCH 0x200 -#define SET_FINALGAP 0x400 -#define SET_DOSDRIVE 0x800 -#define SET_2M 0x1000 -#define SET_VERBOSITY 0x2000 -#define SET_MARGIN 0x4000 - -#define MAX_SIZECODE 8 - -#define DO_DEBUG 1 -#define ALSKEW 4 - -int margin=36; int fm_mode=0; -#define MAX_SECTORS 50 -/* int skew; */ - -struct fparm { - unsigned char track,head,sect,size; -}; - -struct fparm2 { - unsigned char sect, size, offset; -}; - -#define NO_DENSITY -1 -#define DOUBLE_DENSITY 0 -#define HIGH_DENSITY 1 -#define EXTRA_DENSITY 2 struct defaults { char density; struct { int sect; int rate; - } fmt[3]; + } fmt[6]; } drive_defaults[] = { -{ 0, { {0, 0}, {0, 0} }}, -{ DOUBLE_DENSITY, { {9, 2}, {0, 0}, {0, 0} } }, -{ HIGH_DENSITY, { {9, 1}, {15, 0}, {0, 0} } }, -{ DOUBLE_DENSITY, { {9, 2}, {0, 0}, {0, 0} } }, -{ HIGH_DENSITY, { {9, 2}, {18, 0}, {0, 0} } }, -{ EXTRA_DENSITY, { {9, 2}, {18, 0}, {36, 0x43} } }, -{ EXTRA_DENSITY, { {9, 2}, {18, 0}, {36, 0x43} } } }; +{ DENS_UNKNOWN, { {0, 0}, {0, 0} }}, +{ DENS_DD, { {0, 0}, { 0, 0}, {9, 2}, { 0, 0}, {0, 0}, {0, 0} } }, +{ DENS_HD, { {0, 0}, { 0, 0}, {9, 1}, { 0, 0}, {15, 0}, {0, 0} } }, +{ DENS_DD, { {0, 0}, { 0, 0}, {9, 2}, { 0, 0}, {0, 0}, {0, 0} } }, +{ DENS_HD, { {0, 0}, { 0, 0}, {9, 2}, { 0, 0}, {18, 0}, {0, 0} } }, +{ DENS_ED, { {0, 0}, { 0, 0}, {9, 2}, { 0, 0}, {18, 0}, {36, 0x43} } }, +{ DENS_ED, { {0, 0}, { 0, 0}, {9, 2}, { 0, 0}, {18, 0}, {36, 0x43} } } }; int header_size=62; int index_size=146; -struct params { - char *name; /* the name of the drive */ - int fd; /* the open file descriptor */ - int drive; /* the drive number */ - int sizecode; - int rate; - int gap; - unsigned int fmt_gap; - int use_2mf; - struct fparm2 *sequence; - int last_sect[MAX_SIZECODE]; - int nssect; /* number of small sectors */ - int dsect; /* number of data sectors */ - int need_init; /* does this track need initialization ? */ - int raw_capacity; /* raw capacity of one track inbytes */ - struct floppy_drive_params drvprm; - int chunksize; /* used for re-aligning skew */ - int track_end; /* "" */ - int flags; - int finalgap; - int multi; /* multiple formats */ - int min; - int max; -}; char floppy_buffer[24 * 512]; -char verbosity = 3; +int verbosity = 3; static char noverify = 0; static char dosverify = 0; static char verify_later = 0; short stretch; -int tracks, heads, sectors; -int begin_track, end_track; -int head_skew=1024, track_skew=1536, absolute_skew=0; -char use_2m=0; -#define MAX_TRACKS 85 -#define MAX_HEADS 2 +int cylinders, heads, sectors; +int begin_cylinder, end_cylinder; +int head_skew=1024, cylinder_skew=1536, absolute_skew=0; +int use_2m=0; int lskews[MAX_TRACKS][MAX_HEADS] = {{0}}; int findex[MAX_TRACKS][MAX_HEADS] = {{0}}; int mask= 0; @@ -182,7 +124,7 @@ int send_cmd(int fd,struct floppy_raw_cmd *raw_cmd, char *message) goto repeat; } perror(message); -#ifdef 0 +#if 0 printf("the final skew is %d\n", skew ); #endif exit(1); @@ -218,7 +160,7 @@ int send_cmd(int fd,struct floppy_raw_cmd *raw_cmd, char *message) if ( (code & ( 1 << i )) && error_msg[i]) fprintf(stderr,"%s\n", error_msg[i]); } - printf("track=%d head=%d sector=%d size=%d\n", + printf("cylinder=%d head=%d sector=%d size=%d\n", raw_cmd->reply[3], raw_cmd->reply[4], raw_cmd->reply[5], @@ -239,139 +181,36 @@ int send_cmd(int fd,struct floppy_raw_cmd *raw_cmd, char *message) return 0; } -int floppy_read(struct params *fd, void *data, int track, int head, int sectors) +int floppy_read(struct params *fd, void *data, int cylinder, int head, int sectors) { - int n; - if (lseek(fd->fd, (track * heads + head) * sectors * 512, + int n,m; + if (lseek(fd->fd, (cylinder * heads + head) * sectors * 512, SEEK_SET) < 0) { perror("lseek"); return -1; } - n=read(fd->fd, data, sectors * 512); - if ( n < 0 ) - perror("read"); - if ( n == sectors * 512) - return n; - else - return -1; -} - -void calc_multi_skew(struct params *f, int track, int head, int skew, - int *lskew, int *index) -{ - int j; - - for (j=0; ; ++j) { - if (j == f[0].dsect ) { - j = 0; - skew -= f[0].raw_capacity; - } - - if ( f[j].min * f[j].chunksize >= f[j].max ) - continue; - - if (skew < f[j].min * f[j].chunksize){ - skew = f[j].min * f[j].chunksize; - break; - } - skew = skew + f[j].chunksize - 1; - skew -= skew % f[j].chunksize; - if (skew <= f[j].max){ - if (f[j].flags & ALSKEW ) - continue; - else - break; - } - } - f += j; - if (verbosity == 9) - printf("format #%d\n", j); - *index=j; - if (f->multi && (skew < f->min * f->chunksize || skew >= f->max) ){ - printf("%d %d %d\n",f->min * f->chunksize, skew, f->max); - exit(1); - } - *lskew = skew / f->chunksize; - *lskew = (*lskew + f->nssect - f->min) % f->nssect; - if (f->multi && (skew < f->min * f->chunksize || - skew >= f->max) ){ - printf("%d %d %d\n", - f->min * f->chunksize, skew, f->max); - exit(1); - } -} - -void calc_mono_ski(struct params *f, - int track, int head, int skew, int *lskew) -{ - int i, track_end, curoffset, maxoffset, aligned; - - track_end = (f->raw_capacity- header_size- index_size- 1) /f->chunksize; - *lskew = (skew + f->chunksize - 1) / f->chunksize; - - i=aligned=maxoffset=0; - while(1){ - if ( i == f->dsect ){ - if ( aligned || ! (f->flags & ALSKEW) ) - return; - *lskew += f->nssect - maxoffset; - i=0; + m = sectors * 512; + while(m>0) { + /* read until we have read everything we should */ + n=read(fd->fd, data, m); + if ( n < 0 ) { + perror("read"); + return -1; } - curoffset = (f->sequence[i].offset + *lskew) % f->nssect; - if(curoffset > track_end){ - *lskew = f->nssect - f->sequence[i].offset; - maxoffset=0; - aligned = 0; - i=0; + if(n== 0) { + fprintf(stderr, "Error, %d bytes remaining\n", m); + return -1; } - if (curoffset == 0 ) - aligned=1; - if( curoffset > maxoffset) - maxoffset = curoffset; - i++; + m -= n; } + return 0; } -/* calc_skews. Fill skew table for use in formatting */ -int calc_skews(struct params *fd0, struct params *fd) -{ - int track, head; - struct params *f = NULL; - int skew, next_track_skew; - - /* Amount to advance skew considering head skew already added in */ - next_track_skew = track_skew - head_skew; - skew = absolute_skew; - - for (track=begin_track; track <= end_track; ++track) { - for (head=0; head < heads; ++head) { - if (!head && !track && use_2m) - f = fd0; - else - f = fd; - skew = skew % f->raw_capacity; - if ( f->multi){ - calc_multi_skew(f, track, head, skew, - &lskews[track][head], - &findex[track][head]); - f += findex[track][head]; - } else { - calc_mono_ski(f, track, head, skew, - &lskews[track][head]); - findex[track][head]=0; - } - skew = (lskews[track][head] + f->track_end) * - f->chunksize + head_skew; - } - skew += next_track_skew; - } - return 0; -} /* End calc_skews */ /* format_track. Does the formatting proper */ -int format_track(struct params *fd, int track, int head) +int format_track(struct params *fd, int cylinder, int head) { - struct fparm *data; + format_map_t *data; struct floppy_raw_cmd raw_cmd; int offset; int i; @@ -380,33 +219,29 @@ int format_track(struct params *fd, int track, int head) int skew; int retries; - data = (struct fparm *) floppy_buffer; + data = (format_map_t *) floppy_buffer; /* place "fill" sectors */ for (i=0; inssect*2+1; ++i){ - data[i].sect = 128+i; + data[i].sector = 128+i; data[i].size = /*fd->sizecode*/7; - data[i].track = track; + data[i].cylinder = cylinder; data[i].head = head; } - fd += findex[track][head]; - skew = (fd->min + lskews[track][head]) * fd->chunksize; - if (fd->multi && (skew < fd->min * fd->chunksize || - skew >= fd->max) ){ - printf("%d %d %d\n", - fd->min * fd->chunksize, skew, fd->max); - exit(1); - } + fd += findex[cylinder][head]; + skew = fd->min + lskews[cylinder][head] * fd->chunksize; + assert(skew >= fd->min); + assert(skew < fd->max); /* place data sectors */ nssect = 0; for (i=0; idsect; ++i){ - offset = fd->sequence[i].offset + lskews[track][head]; + offset = fd->sequence[i].offset + lskews[cylinder][head]; offset = offset % fd->nssect; - data[offset].sect = fd->sequence[i].sect; + data[offset].sector = fd->sequence[i].sect; data[offset].size = fd->sequence[i].size; - data[offset].track = track; + data[offset].cylinder = cylinder; data[offset].head = head; if ( offset >= nssect ) nssect = offset+1; @@ -423,13 +258,13 @@ int format_track(struct params *fd, int track, int head) printf("chunksize=%d\n", fd->chunksize); printf("sectors=%d\n", nssect); for (i=0; idrive & 3); @@ -439,7 +274,7 @@ int format_track(struct params *fd, int track, int head) raw_cmd.cmd[5] = 0; raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK; - raw_cmd.track = track << stretch; + raw_cmd.track = cylinder << stretch; raw_cmd.rate = fd->rate & 0x43; /* first pass */ @@ -465,7 +300,7 @@ int format_track(struct params *fd, int track, int head) raw_cmd.cmd_count = 9; raw_cmd.cmd[0] = FD_WRITE & ~fm_mode; raw_cmd.cmd[1] = head << 2 | ( fd->drive & 3); - raw_cmd.cmd[2] = track; + raw_cmd.cmd[2] = cylinder; raw_cmd.cmd[3] = head; raw_cmd.cmd[4] = cur_sector; raw_cmd.cmd[5] = i; @@ -492,8 +327,6 @@ int format_track(struct params *fd, int track, int head) if ( !retries && (raw_cmd.reply[1] & ST1_ND) ){ cur_sector = raw_cmd.reply[5]; retries++; - printf("twaddle!\n"); - ioctl(fd->fd, FDTWADDLE); goto retry; } return -1; @@ -502,389 +335,9 @@ int format_track(struct params *fd, int track, int head) return 0; } -#define SSIZE(j) ( ( 128 << (j) ) + header_size + soft_gap ) -#define FSIZE(j) ( ( 128 << (j) ) + header_size + final_gap ) -int compute_chunk_size(int chunksize, - int sizecode, - int *chunks_in_sect, - int soft_gap, - int final_gap, - int tailsize, - int use_multiformat, - struct params *fd) -{ - int cur_sector; - int j; - int minsize=0; - - fd->nssect = 0; - cur_sector = 1; - for(j= sizecode; j>=0; j--){ - chunks_in_sect[j] = (SSIZE(j)-1) / chunksize + 1; - fd->nssect +=chunks_in_sect[j] * (fd->last_sect[j] -cur_sector); - if ( fd->last_sect[j] != cur_sector) - minsize = j; - cur_sector = fd->last_sect[j]; - } - - /* account for last sector */ - fd->nssect -= chunks_in_sect[minsize]; - chunks_in_sect[MAX_SIZECODE] = (FSIZE(minsize)-1)/chunksize+1; - fd->nssect += chunks_in_sect[MAX_SIZECODE]; - - if ( use_multiformat){ - if (tailsize == minsize) - return (fd->nssect - chunks_in_sect[MAX_SIZECODE])* - chunksize + FSIZE(tailsize); - else - return (fd->nssect - chunks_in_sect[tailsize])* - chunksize + SSIZE(tailsize); - } else - return fd->nssect * chunksize; -} - -void compute_sector_sequence(int sectors, - int chunksize, - int *sizecode, - int interleave, - int soft_gap, - int final_gap, - int mask, - int use_2m, - int tailsect, - struct params *fd) -{ - int remaining; - int cur_sector; - int nr_sectors; - int chunks_in_sect[MAX_SIZECODE + 1]; - int i,j; - int multisize; /* several sizes on same tracks */ - int tot_size; - int min_tot_size = 0; - int t_chunksize; - int ceiling; - int tailsize = 2; /* size of last sector before index mark */ - int use_multiformat; - int max_offset; - - repeat: - multisize=0; - fd->need_init = 1; - - /* parameter checking */ - - /* distribution of sector sizes */ - for(i=0; i< MAX_SIZECODE; ++i) - fd->last_sect[i] = 0; - remaining = sectors; - cur_sector = 1; - - use_multiformat = 1; - i = tailsect; - for (j=*sizecode; j>=0; --j) { - nr_sectors = remaining << 2 >> j; - remaining -= nr_sectors << j >> 2; - cur_sector += nr_sectors; - fd->last_sect[j] = cur_sector; - if (nr_sectors > 1) - use_multiformat = 0; - if (nr_sectors == 1 && --i == 0) - tailsize = j; - if (remaining) - multisize = 1; - else if (nr_sectors) { - if (tailsect==0 || use_multiformat==0) - tailsize = j; - } - } - - fd->dsect = cur_sector-1; /* number of data sectors */ - if (remaining) { - fprintf(stderr,"Internal error: remaining not 0\n"); -#ifdef 0 - printf("the final skew is %d\n", skew ); -#endif - exit(1); - } - - /* default gap */ - if (! (mask & SET_FMTGAP)) { - soft_gap = (fd->raw_capacity-sectors*512-margin)/fd->dsect - - header_size; - if (soft_gap > 255) - soft_gap = 255; - repeat_2: - if (soft_gap < 1 && - !(mask & SET_SIZECODE) && - (sectors >= (1 << ( (*sizecode)-1))) && - fd->last_sect[*sizecode] > 2 && - (sectors % ( 1 << ( (*sizecode)-1)) == 0 || - use_2m || !(mask & SET_2M))) { - (*sizecode)++; - goto repeat; - } - if (soft_gap < -4) - soft_gap = -4; - } - - - if ( ! (mask & SET_FINALGAP )) - final_gap = soft_gap; - - repeat_3: - /* default chunksize */ - if ( ! ( mask & SET_CHUNKSIZE )){ - /* get a default chunksize */ - if (! *sizecode || - (!multisize && soft_gap > 0 && soft_gap <= 256)){ - chunksize = SSIZE(*sizecode); - } else if ( !multisize ) { - chunksize = 0; - ceiling = SSIZE(*sizecode)/( 129 + header_size); - for(i= 1; i <= ceiling; i++ ){ - t_chunksize = (SSIZE(*sizecode) - 1) / i +1; - - /* bad chunk sizes */ - if (((t_chunksize-header_size-1) & 511) > 255 && - t_chunksize > 768 + header_size) - continue; - - j = (SSIZE(*sizecode) - 1)/t_chunksize + 1; - tot_size = j * t_chunksize; - if ( !chunksize || tot_size < min_tot_size ){ - min_tot_size = tot_size; - chunksize = t_chunksize; - } - if ( tot_size == SSIZE(*sizecode) ) - break; - } - } else { - chunksize = 0; - for (t_chunksize= SSIZE((*sizecode)-1); - t_chunksize>128+header_size; - t_chunksize--) { - for(j=0; j < MAX_SIZECODE; j++ ){ - if(t_chunksize<(128<= 6) - printf("%d chasing %d\n", - t_chunksize, chunksize); -#endif - min_tot_size = tot_size; - chunksize = t_chunksize; - } - } - } - } - - tot_size=compute_chunk_size(chunksize, *sizecode, chunks_in_sect, - soft_gap, final_gap, tailsize, - use_multiformat, fd); - - if (fd->raw_capacity - tot_size < margin) { - if (! (mask & SET_FINALGAP) && - (final_gap > soft_gap || final_gap > 1)) { - final_gap-=(margin+1-fd->raw_capacity+tot_size)/2; - if (final_gap < 1 && soft_gap > 1) - final_gap = 1; - goto repeat_3; - } - - if (! (mask & SET_FMTGAP) && - soft_gap > - 4) { - soft_gap -= (margin-fd->raw_capacity+tot_size) / - fd->dsect/2+1; - if ( soft_gap < final_gap ) - final_gap = soft_gap; - goto repeat_2; - } - - if (!(mask & SET_SIZECODE) && - (sectors >= (1 << ( (*sizecode)-1))) && - fd->last_sect[*sizecode] > 2) { - ++(*sizecode); - goto repeat; - } - } - - if (tot_size > fd->raw_capacity) { - fprintf(stderr,"Too many sectors for this disk\n"); - exit(1); - } - - /* convert chunksize to sizecode/fmt_gap pair */ - for (j=0; j < MAX_SIZECODE; ++j) { - if (chunksize < (128 << j) + header_size + 1) { - fprintf(stderr,"Bad chunksize %d\n", chunksize); -#ifdef 0 - printf("the final skew is %d\n", skew ); -#endif - exit(1); - } - if (chunksize <= (128 << j) + 256 + header_size) { - fd->sizecode = j; - fd->fmt_gap = chunksize - (128 << j) - header_size; - break; - } - } - if ( j == MAX_SIZECODE ){ - fprintf(stderr,"Chunksize %d too big\n", chunksize ); -#ifdef 0 - printf("the final skew is %d\n", skew ); -#endif - exit(1); - } - - /* default interleave */ - if ( ! (mask & SET_INTERLEAVE) ){ - if ( soft_gap < 32 ) - interleave = 2; - else - interleave = 1; - } - - /* sector sequence, using interleave */ - fd->sequence =(struct fparm2 *) calloc(fd->dsect,sizeof(struct fparm2)); - if ( fd->sequence == 0 ){ - fprintf(stderr,"Out of memory\n"); -#ifdef 0 - printf("the final skew is %d\n", skew ); -#endif - exit(1); - } - for(i=0; i< fd->dsect; i++) - fd->sequence[i].sect=0; - cur_sector = fd->dsect-1; - if (!use_multiformat) - tailsect=fd->dsect-1; - i = tailsect; - while(1){ - if ( i == 0 ) - i = fd->dsect; - if ( cur_sector < 0) - cur_sector += fd->dsect; - while(fd->sequence[cur_sector].sect ){ - cur_sector--; - if ( cur_sector < 0 ) - cur_sector += fd->dsect; - } - fd->sequence[cur_sector].sect = i; - j = (*sizecode); - while( fd->last_sect[j] <= i ) - j--; - fd->sequence[cur_sector].size = j; - cur_sector -= interleave; - - i--; - if ( (i-tailsect) % fd->dsect == 0 ) - break; - } - - /* now compute the placement in terms of small sectors */ - cur_sector = 0; - max_offset = 0; - for(i=0; i< fd->dsect; i++){ - fd->sequence[i].offset = cur_sector; - if ( cur_sector > max_offset ) - max_offset = cur_sector; - if ( fd->sequence[i].sect == 1 ) - fd->min = fd->sequence[i].offset; - if ( fd->sequence[i].sect == fd->dsect) - cur_sector += chunks_in_sect[MAX_SIZECODE]; - else - cur_sector += chunks_in_sect[ fd->sequence[i].size ]; - if (fd->sequence[i].sect == fd->dsect) - fd->track_end = cur_sector; - } -#if 0 - fd->max = fd->min + chunks_in_sect[tailsize]-2; -#else - fd->max = fd->raw_capacity + (fd->min - max_offset) * chunksize - - header_size - index_size - 1 ; -#endif - if (verbosity == 9){ - printf("chunksize=%d\n", chunksize); - printf("%d raw bytes per track\n", tot_size ); - printf("%d final gap\n", - fd->raw_capacity - tot_size ); - } - fd->chunksize = chunksize; - - if ( !multisize && (*sizecode) == fd->sizecode ) - fd->need_init = 0; - if ( use_multiformat ) - fd->multi = multisize; - else - fd->multi = 0; -} - - -void compute_track0_sequence(struct params *fd) -{ - int i; - int sectors; - - sectors= fd->nssect = fd->dsect; - - fd->track_end = 0; - fd->chunksize = 0x6c + 574; - - fd->need_init = 0; - fd->sequence =(struct fparm2 *) calloc(fd->dsect,sizeof(struct fparm2)); - if ( fd->sequence == 0 ){ - fprintf(stderr,"Out of memory\n"); -#ifdef 0 - printf("the final skew is %d\n", skew ); -#endif - exit(1); - } - - fd->sizecode = 2; - if ( fd->rate & 0x40 ) - fd->fmt_gap = 0x54; - else - fd->fmt_gap = 0x6c; - fd->min = 0; - - for(i=0; isequence[i].sect = i+1; - fd->sequence[i].size = 2; - fd->sequence[i].offset = i; - } -} - -int compar(const void *a, const void *b) -{ - const struct params *ap, *bp; - ap = (const struct params *)a; - bp = (const struct params *)b; - if (ap->min < bp->min) - return -1; - if (ap->min == bp->min) - return 0; - return 1; -} -void print_formatting(int track, int head) +void print_formatting(int cylinder, int head) { switch(verbosity) { case 0: @@ -904,24 +357,24 @@ void print_formatting(int track, int head) break; case 3: case 4: - printf("\rFormatting track %2d, head %d ", - track, head); + printf("\rFormatting cylinder %2d, head %d ", + cylinder, head); fflush(stdout); break; default: - printf("formatting track %d, head %d\n", - track, head); + printf("formatting cylinder %d, head %d\n", + cylinder, head); break; } } -void print_verifying(int track, int head) +void print_verifying(int cylinder, int head) { if (verbosity >= 5) { - printf("verifying track %d head %d\n", - track, head); + printf("verifying cylinder %d head %d\n", + cylinder, head); } else if (verbosity >= 3) { - printf("\r Verifying track %2d, head %d ", track, head); + printf("\r Verifying cylinder %2d, head %d ", cylinder, head); fflush(stdout); } else if (verbosity == 2) { if (!verify_later && !dosverify) { @@ -939,22 +392,38 @@ void print_verifying(int track, int head) } } + +void old_parameters() +{ + + + +} + +#define DRIVE_DEFAULTS (drive_defaults[drivedesc.type.cmos]) + void main(int argc, char **argv) { + int nseqs; /* number of sequences used */ char env_buffer[10]; struct floppy_struct parameters; struct params fd[MAX_SECTORS], fd0; - struct stat buf; int ch,i; - short cmos; - short density=-1; + short density = DENS_UNKNOWN; + char drivename[10]; - int track, head, interleave; - int soft_gap; + int have_geom = 0; + int margin=50; + int deviation=-3100; + int warmup = 40; /* number of warmup rotations for measurement */ + + int cylinder, head, interleave; + int gap; int final_gap; int chunksize; int sizecode=2; int error; + int biggest_last = 0; char command_buffer[80]; char twom_buffer[6]; char *progname=argv[0]; @@ -963,46 +432,15 @@ void main(int argc, char **argv) int n,rsize; char *verify_buffer = NULL; char dosdrive; + drivedesc_t drivedesc; + struct floppy_struct geometry; + int max_chunksize = 128*128+62+256; struct enh_options optable[] = { - { 'd', "drive", 1, EO_TYPE_STRING, O_RDWR, 0, - (void *) &fd[0].name, - "set the target drive (mandatory parameter)" }, - { 'D', "dosdrive", 1, EO_TYPE_CHAR, 0, SET_DOSDRIVE, (void *) &dosdrive, "set the dos drive" }, - { 's', "sectors", 1, EO_TYPE_LONG, 0, SET_SECTORS, - (void *) §ors, - "set number of sectors" }, - - { 'H', "heads", 1, EO_TYPE_LONG, 0, 0, - (void *) &heads, - "set the number of heads" }, - - { 't', "tracks", 1, EO_TYPE_LONG, 0, SET_TRACKS, - (void *) &tracks, - "set the number of tracks" }, - - { '\0', "fm", 0, EO_TYPE_SHORT, 0x40, 0, - (void *) &fm_mode, - "chose fm mode" }, - - - { '\0', "dd", 0, EO_TYPE_SHORT, DOUBLE_DENSITY, 0, - (void *) &density, - "chose low density" }, - - - { '\0', "hd", 0, EO_TYPE_SHORT, HIGH_DENSITY, 0, - (void *) &density, - "chose high density" }, - - { '\0', "ed", 0, EO_TYPE_SHORT, EXTRA_DENSITY, 0, - (void *) &density, - "chose extra density" }, - { 'v', "verbosity", 1, EO_TYPE_LONG, 0, 0, (void *) &verbosity, "set verbosity level" }, @@ -1019,20 +457,16 @@ void main(int argc, char **argv) (void *) &verify_later, "verify floppy after all formatting is done" }, - { 'b', "begin_track", 1, EO_TYPE_LONG, 0, 0, - (void *) &begin_track, - "set track where to begin formatting" }, + { 'b', "begin_cylinder", 1, EO_TYPE_LONG, 0, 0, + (void *) &begin_cylinder, + "set cylinder where to begin formatting" }, - { 'e', "end_track", 1, EO_TYPE_LONG, 0, SET_ENDTRACK, - (void *) &end_track, - "set track where to end formatting" }, - - { 'S', "sizecode", 1, EO_TYPE_LONG, 0, SET_SIZECODE, - (void *) &sizecode, - "set the size code of the data sectors. The size code describes the size of the sector, according to the formula size=128< 1){ - print_usage(progname,optable, ""); - exit(1); - } - if(argc) + if(argc) { fd[0].name = argv[0]; - - if (! fd[0].name){ - fprintf(stderr,"Which drive?\n"); - print_usage(progname,optable, ""); - exit(1); + argc--; + argv++; } - - fd[0].fd = open(fd[0].name, O_RDWR | O_NDELAY | O_EXCL); - /* we open the disk wronly/rdwr in order to check write protect */ - if (fd[0].fd < 0) { - perror("open"); - exit(1); - } - ioctl(fd[0].fd, FDRESET, FD_RESET_IF_RAWCMD); - if (fstat (fd[0].fd, &buf) < 0) { - perror("fstat"); - exit(1); - } - if (MAJOR(buf.st_rdev) != FLOPPY_MAJOR) { - fprintf(stderr,"%s is not a floppy drive\n", fd[0].name); + if (! fd[0].name){ + fprintf(stderr,"Which drive?\n"); + print_usage(progname,optable, ""); exit(1); } - fd[0].drive = MINOR( buf.st_rdev ); - fd[0].drive = (fd[0].drive & 3) + ((fd[0].drive & 0x80) >> 5); - if (ioctl(fd[0].fd, FDGETDRVPRM, & fd[0].drvprm ) < 0 ){ - perror("get drive characteristics"); - exit(1); - } - cmos = fd[0].drvprm.cmos; - if (cmos < 1 || cmos > 6) - cmos = 4; - - /* density */ - if ( (mask & SET_SECTORS ) && density == NO_DENSITY ){ - if ( sectors < 15 ) - density = DOUBLE_DENSITY; - else if ( sectors < 25 ) - density = HIGH_DENSITY; - else - density = EXTRA_DENSITY; - } - if (density == NO_DENSITY) { - density = drive_defaults[cmos].density; - if ( mask & SET_RATE ){ - for (i=0; i< density; ++i) { - if(fd[0].rate == drive_defaults[cmos].fmt[i].rate) - density=i; + while(1) { + fd[0].fd = open(fd[0].name, O_RDWR | O_NDELAY | O_EXCL); + + /* we open the disk wronly/rdwr in order to check write + * protect */ + if (fd[0].fd < 0) { + perror("open"); + exit(1); + } + + if(parse_driveprm(fd[0].fd, &drivedesc)) + exit(1); + + fd[0].drive = drivedesc.drivenum; + fd[0].drvprm = drivedesc.drvprm; + + if(MINOR(drivedesc.buf.st_rdev) & 0x7c) { + if(fd[0].name == drivename) { + fprintf(stderr, + "%s has bad minor/major numbers\n", + fd[0].name); + exit(1); } + /* this is not a generic format device. Close it, + * and open the proper device instead */ + if(argc == 0) + ioctl(fd[0].fd, FDGETPRM, &geometry); + have_geom = 1; + close(fd[0].fd); + sprintf(drivename,"/dev/fd%d", fd[0].drive); + fd[0].name = drivename; + continue; } + break; + } + + + + + if(have_geom || + !parse_mediaprm(argc, argv, &drivedesc, &geometry) || + !parse_fdprm(argc-2, argv+2, &geometry)) { + if(argc > 0) + have_geom = 1; } else { - if (drive_defaults[cmos].fmt[density].sect == 0) { + fprintf(stderr,"Syntax error in format description\n"); + exit(1); + } + + + if(have_geom) { + if(mask & (SET_SECTORS | SET_CYLINDERS | + SET_HEADS | SET_SIZECODE | SET_2M | SET_RATE)) { fprintf(stderr, - "Density %d not supported drive type %d\n", - density, cmos); + "Cannot mix old style and new style geometry spec\n"); exit(1); } - } - /* rate */ - if (! ( mask & SET_RATE)) - fd[0].rate = drive_defaults[cmos].fmt[density].rate; + sectors = geometry.sect; + cylinders = geometry.track; + heads = geometry.head; + + fd[0].rate = geometry.rate & 0x43; + sizecode = (((geometry.rate & 0x38) >> 3) + 2) % 8; + use_2m = (geometry.rate >> 2) & 1; + switch(fd[0].rate) { + case 0x43: + density = DENS_ED; + break; + case 0x2: + case 0x1: + density = DENS_DD; + break; + case 0: + density = DENS_HD; + break; + } + stretch = geometry.stretch & 1; + + mask |= SET_SECTORS | SET_CYLINDERS | + SET_SIZECODE | SET_2M | SET_RATE; + } else { + /* density */ + if ( (mask & SET_SECTORS ) && density == DENS_UNKNOWN){ + if ( sectors < 15 ) + density = DENS_DD; + else if ( sectors < 25 ) + density = DENS_HD; + else + density = DENS_ED; + } + if (density == DENS_UNKNOWN) { + density = DRIVE_DEFAULTS.density; + if ( mask & SET_RATE ){ + for (i=0; i< density; ++i) { + if(fd[0].rate == + DRIVE_DEFAULTS.fmt[i].rate) + density=i; + } + } + } else { + if (DRIVE_DEFAULTS.fmt[density].sect == 0) { + fprintf(stderr, + "Density %d not supported drive type %d\n", + density, drivedesc.type.cmos); + exit(1); + } + } + + /* rate */ + if (! ( mask & SET_RATE)) + fd[0].rate = DRIVE_DEFAULTS.fmt[density].rate; + + /* number of sectors */ + if (! (mask & SET_SECTORS)) + sectors =DRIVE_DEFAULTS.fmt[density].sect; + if (! (mask & SET_CYLINDERS)) { + if (fd[0].drvprm.tracks >= 80) + cylinders = 80; + else + cylinders = 40; + } + + if ( ! ( mask & SET_STRETCH )){ + if ( cylinders + cylinders < fd[0].drvprm.tracks) + stretch = 1; + else + stretch = 0; + } + } + + if (cylinders > fd[0].drvprm.tracks) { + fprintf(stderr,"too many cylinder for this drive\n"); + print_usage(progname,optable,""); + exit(1); + } - /* number of sectors */ - if (! (mask & SET_SECTORS)) - sectors =drive_defaults[cmos].fmt[density].sect; + if (! (mask & SET_ENDTRACK ) || end_cylinder > cylinders) + end_cylinder = cylinders; + if(begin_cylinder >= end_cylinder) { + fprintf(stderr,"begin cylinder >= end cylinder\n"); + exit(1); + } fd0 = fd[0]; repeat: - /* capacity */ - if (sectors >= 12 && fd[0].rate == 2) + /* capacity */ + if (!have_geom && sectors >= 12 && fd[0].rate == 2) fd[0].rate = 1; switch(fd[0].rate & 0x3) { case 0: @@ -1224,41 +793,66 @@ void main(int argc, char **argv) header_size = 81; else header_size = 62; - if ( ! (mask & SET_MARGIN)) { - if (fd[0].rate & 0x40) - margin = 72; - else - margin = 45; /*36;*/ - } - - fd0.raw_capacity = fd[0].raw_capacity ; - if (verbosity == 9) - printf("rate=%d density=%d sectors=%d capacity=%d\n", - fd[0].rate, density, sectors, fd[0].raw_capacity); + if(! (mask & (SET_DEVIATION | SET_MARGIN)) && + (drivedesc.mask & (1 << FE__DEVIATION))) { + deviation = drivedesc.type.deviation; + mask |= SET_DEVIATION; + } - fd0.multi=0; - fd[0].multi = 1; + if(mask & SET_DEVIATION) { + mask &= ~SET_MARGIN; + fd[0].raw_capacity += fd[0].raw_capacity * deviation / 1000000; + } else if (mask & SET_MARGIN) { + fd[0].raw_capacity -= margin; + } else { + int old_capacity = fd[0].raw_capacity; - compute_sector_sequence(sectors, chunksize, &sizecode, - interleave, soft_gap, final_gap, mask, - use_2m, 1, fd); + printf("old capacity=%d\n", old_capacity); - if (fd->multi) { - if (fd[0].dsect > MAX_SECTORS) { - fprintf(stderr,"Internal error, too many data sectors for multiformat\n"); - exit(1); + if(verbosity) { + fprintf(stderr,"Measuring drive %d's raw capacity\n", + fd[0].drive); } - for (i=2; i <= fd[0].dsect; ++i) { - fd[i-1] = fd[0]; - compute_sector_sequence(sectors, chunksize, &sizecode, - interleave, soft_gap, - final_gap, mask | SET_SIZECODE, - use_2m, i, fd+(i-1)); + /* neither a deviation nor a margin have been given */ + fd[0].raw_capacity = measure_raw_capacity(fd[0].fd, + fd[0].drive, + fd[0].rate, + begin_cylinder, + warmup, + verbosity) / 16; + if(verbosity) { + fprintf(stderr, + "In order to avoid this time consuming " + "measurement in the future, add the following " + "line to " DRIVEPRMFILE + " :\ndrive%d: deviation=%d\n", + fd[0].drive, + (fd[0].raw_capacity-old_capacity)*1000000/ + old_capacity); + fprintf(stderr, + "CAUTION: this line is drive and controller" + "specific. Remove it before installing a new" + "drive %d or floppy controller\n\n", + fd[0].drive); } - qsort( fd, fd[0].dsect, sizeof(struct params), compar); } + /* FIXME. Why is this needed? */ + fd[0].raw_capacity -= 30; + + fd0.raw_capacity = fd[0].raw_capacity ; + + if (verbosity == 9) + printf("rate=%d density=%d sectors=%d capacity=%d\n", + fd[0].rate, density, sectors, fd[0].raw_capacity); + + fd->chunksize = chunksize; + fd->max_chunksize = max_chunksize; + fd->preset_interleave = interleave; + nseqs = compute_all_sequences(fd, sectors * 512, sizecode, + gap, mask, biggest_last); + /* print all the stuff out */ if (verbosity == 9) { for (i=0; i= 80) - tracks = 80; - else - tracks = 40; - } - - if (tracks > fd[0].drvprm.tracks) { - fprintf(stderr,"too many track for this drive\n"); - print_usage(progname,optable,""); - exit(1); - } - - if ( ! ( mask & SET_STRETCH )){ - if ( tracks + tracks < fd[0].drvprm.tracks ) - stretch = 1; - else - stretch = 0; - - } - - if (! (mask & SET_ENDTRACK ) || end_track > tracks) - end_track = tracks; - parameters.sect = sectors; parameters.head = heads; - parameters.track = tracks; - parameters.size = tracks * heads * sectors; + parameters.track = cylinders; + parameters.size = cylinders * heads * sectors; parameters.stretch = stretch; parameters.gap = fd[0].gap; if ( !use_2m) @@ -1343,7 +913,7 @@ void main(int argc, char **argv) exit(1); } - calc_skews(&fd0, fd); + calc_skews(&fd0, fd, nseqs); if (!verify_later && !dosverify) { ioctl(fd[0].fd, FDFLUSH ); @@ -1356,50 +926,43 @@ void main(int argc, char **argv) retries=0; /*ioctl(fd[0].fd, FDRESET, FD_RESET_IF_RAWCMD);*/ - for (track=begin_track; track= 2) exit(1); #if 0 - if(seek_floppy( fd, track << stretch)) + if(seek_floppy( fd, cylinder << stretch)) exit(1); #endif for (head=0; head> (sizecode - 2), */ - tracks, heads, sizecode, twom_buffer, dosdrive); + cylinders, heads, sizecode, twom_buffer, dosdrive); if (verbosity >= 3) { printf("\n%s\n", command_buffer); } @@ -1463,16 +1026,17 @@ void main(int argc, char **argv) printf("out of memory error\n"); exit(1); } - lseek(fd[0].fd, 512 * begin_track * heads, SEEK_SET ); - for (track=begin_track; track ]0;~/floppy/fdutils/src>  + +Script done on Wed Apr 23 21:54:33 1997 diff --git a/src/xdfcopy.1 b/src/xdfcopy.1 deleted file mode 100644 index f25b18c..0000000 --- a/src/xdfcopy.1 +++ /dev/null @@ -1,100 +0,0 @@ -.TH XDFCOPY 1 "11nov1995" "fdutils" "fdutils" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -xdfcopy \- Program to copy and format Xdf disks in Linux -.SH SYNOPSIS -.hy 0 -.na -.B xdfcopy -.RB "[\|" \-D \c -.I dos\-drive\c -\&\|] -.RB "[\|" \-d "\|]" -.RB "[\|" \-n "\|]" -.RB "[\|" \-h \c -.I head_skew\c -\&\|] -.RB "[\|" \-t \c -.I track_skew\c -\&\|] -.RI "[\|" source "\|]" -.I target -.ad b -.hy 1 -.SH DESCRIPTION - -Xdfcopy is a utility to copy and format Xdf disks. Xdf is a format -used by OS/2 which can hold 1756k of data. Its advantage over 2m -formats is that it's access is faster. - -This program only works with kernels newer than 1.3.40. (If there's -sufficient interest, I'll include a program working with older kernels -in the next release) - -If both source and target are given, xdfcopy copies the disk image -from file to floppy disk or vice-versa. When copying to a floppy disk, -the disk is first formatted, unless the -.B \-n -option is given. - -If no source is given, the target is formatted. In this case, the -target must be a floppy drive. - -.SH OPTIONS - -.TP -.BI "\-D" "dosdrive" -Describes the DOS drive letter for mformat. If this option is given, -an msdos filesystem is automatically installed on the disk after the -low-level format is complete. In order for this to work, the drive has -to be configured to accept the 23x2x80 geometry in your /etc/mtools or -your ~/.mtoolsrc file. Moreover, this only works with a version of -mtools that is more recent than 2.5.4. - Example of working mtoolsrc lines: - A /dev/fd0 0 0 0 0 - A /dev/fd0 12 80 2 23 - -The former is preferable, as it matches any format. The latter -matches -.B only -23 sector formats (such as Xdf and certain 2m formats). - - Examples of a non-working mtoolsrc line: - A /dev/fd0 12 80 2 18 - - -.TP -.B \-n -Don't format the disk before copying the disk image to the disk. - - -.SH OPTIONS FOR POWER USERS - -.TP -.BI "\-t" "track skew" -Uses a different track skew than the default (14). For more details on -skews, see the superformat manpage. - -.TP -.BI "\-h" "head skew" -Uses a different head skew than the default (0) - -.TP -.B \-d -Debugging. For each read or write operation, the time it took to -complete the operation is printed (in milliseconds). This can be used -to optimize the skews. - -.SH FILES -/dev/fd* - Floppy devices - -.SH AUTHOR -Alain Knaff, Alain.Knaff@inrialpes.fr - -.SH SEE ALSO -fdrawcmd(1), getfdprm(1), mtools(1), floppycontrol(1), superformat(1) - diff --git a/src/xdfcopy.c b/src/xdfcopy.c index b2ed1d6..c5d9635 100644 --- a/src/xdfcopy.c +++ b/src/xdfcopy.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include "fdutils.h" #ifdef FD_RAW_MORE @@ -47,94 +49,129 @@ char *error_msg[22]={ enum dir { READ_, WRITE_ } ; -int send_cmd(int fd,struct floppy_raw_cmd *raw_cmd, char *message) +static int curcylinder = -1; + +int interpret_errors(struct floppy_raw_cmd *raw_cmd, int probe_only) { - int i,j; - int code; - static int curtrack = -1; - - for (j=0; j<4; j++){ - if ( raw_cmd->track == curtrack && - !(raw_cmd->flags & FD_RAW_WRITE)) - raw_cmd->flags &= ~FD_RAW_NEED_SEEK; - if ( ioctl( fd, FDRAWCMD, raw_cmd) < 0 ){ - curtrack = -1; - if ( errno == EBUSY ){ - i--; - fprintf(stderr,"\nFDC busy, sleeping for a second\n"); - sleep(1); - continue; - } - if ( errno == EIO ){ - fprintf(stderr,"\nresetting controller\n"); - if(ioctl(fd, FDRESET, 2) < 0){ - perror("reset"); - exit(1); - } - continue; - } - perror(message); - exit(1); - } + int i,k; + int code; + + k = 0; + do { + if ( raw_cmd[k].reply_count ){ + switch( raw_cmd[k].reply[0] & 0xc0 ){ + case 0x40: + if(probe_only) + return -2; + curcylinder = -1; + fprintf(stderr, + "\nerror during command execution\n"); + if ( raw_cmd[k].reply[1] & ST1_WP ){ + fprintf(stderr, + "The disk is write protected\n"); + exit(1); + } + fprintf(stderr," "); + for (i=0; i< raw_cmd[k].cmd_count; i++) + fprintf(stderr,"%2.2x ", + (int)raw_cmd[k].cmd[i] ); + printf("\n"); + for (i=0; i< raw_cmd[k].reply_count; i++) + fprintf(stderr,"%2.2x ", + (int)raw_cmd[k].reply[i] ); + fprintf(stderr,"\n"); + code = (raw_cmd[k].reply[0] <<16) + + (raw_cmd[k].reply[1] << 8) + + raw_cmd[k].reply[2]; + for(i=0; i<22; i++){ + if ( (code & ( 1 << i )) && + error_msg[i]) + fprintf(stderr, "%s\n", + error_msg[i]); + } + sleep(4); + return k; + case 0x80: + curcylinder = -1; + fprintf(stderr, + "\ninvalid command given\n"); + return 1; + case 0xc0: + curcylinder = -1; + fprintf(stderr, + "\nabnormal termination caused by polling\n"); + return 0; + case 0: + if (raw_cmd[k].flags & FD_RAW_NEED_SEEK) + curcylinder = raw_cmd[k].track; + /* OK */ + } + } else { + fprintf(stderr,"\nNull reply from FDC\n"); + return 1; + } + k++; + } while(raw_cmd[k-1].flags & FD_RAW_MORE); + return -1; +} - if ( raw_cmd->reply_count ){ - switch( raw_cmd->reply[0] & 0xc0 ){ - case 0x40: - curtrack = -1; - fprintf(stderr,"\nerror during command execution\n"); - if ( raw_cmd->reply[1] & ST1_WP ){ - fprintf(stderr,"The disk is write protected\n"); - exit(1); - } - fprintf(stderr," "); - for (i=0; i< raw_cmd->cmd_count; i++) - fprintf(stderr,"%2.2x ", (int)raw_cmd->cmd[i] ); - printf("\n"); - for (i=0; i< raw_cmd->reply_count; i++) - fprintf(stderr,"%2.2x ", (int)raw_cmd->reply[i] ); - fprintf(stderr,"\n"); - code = (raw_cmd->reply[0] <<16) + - (raw_cmd->reply[1] << 8) + - raw_cmd->reply[2]; - for(i=0; i<22; i++){ - if ( (code & ( 1 << i )) && error_msg[i]) - fprintf(stderr,"%s\n", error_msg[i]); +int send_cmd(int fd,struct floppy_raw_cmd *raw_cmd, char *message, int probe_only) +{ + int i,j,k; + + for (j=0; j<4; j++){ + if ( raw_cmd->track == curcylinder && + !(raw_cmd->flags & FD_RAW_WRITE)) + raw_cmd->flags &= ~FD_RAW_NEED_SEEK; + if ( ioctl( fd, FDRAWCMD, raw_cmd) < 0 ){ + curcylinder = -1; + if (errno == EBUSY){ + i--; + fprintf(stderr, + "\nFDC busy, sleeping for a second\n"); + sleep(1); + continue; + } + if (errno == EIO){ + fprintf(stderr,"\nresetting controller\n"); + if(ioctl(fd, FDRESET, 2) < 0){ + perror("reset"); + exit(1); + } + continue; + } + perror(message); + exit(1); + } + + + k = interpret_errors(raw_cmd, probe_only); + switch(k) { + case -2: + return 1; + case -1: + return 0; + } + raw_cmd += k; } - sleep(4); - continue; - case 0x80: - curtrack = -1; - fprintf(stderr,"\ninvalid command given\n"); - continue; - case 0xc0: - curtrack = -1; - fprintf(stderr,"\nabnormal termination caused by polling\n"); - continue; - case 0: - if (raw_cmd->flags & FD_RAW_NEED_SEEK) - curtrack = raw_cmd->track; - /* OK */ - return 0; - } - } else - fprintf(stderr,"\nNull reply from FDC\n"); - } - fprintf(stderr,"\nToo many errors, giving up\n"); - exit(1); + fprintf(stderr,"\nToo many errors, giving up\n"); + exit(1); } int readwrite_sectors(int fd, /* file descriptor */ int drive, enum dir direction, - int track, int head, int sector, int size, /* address */ + int cylinder, int head, + int sector, int size, /* address */ char *data, int bytes, - struct floppy_raw_cmd *raw_cmd) + struct floppy_raw_cmd *raw_cmd, + int rate) { raw_cmd->data = data; raw_cmd->length = bytes; - raw_cmd->rate = 0; + raw_cmd->rate = rate; raw_cmd->flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK | FD_RAW_MORE; @@ -150,7 +187,7 @@ int readwrite_sectors(int fd, /* file descriptor */ raw_cmd->cmd[1] = (drive & 3) | (head << 2); - raw_cmd->cmd[2] = track; + raw_cmd->cmd[2] = cylinder; raw_cmd->cmd[3] = head; raw_cmd->cmd[4] = sector; raw_cmd->cmd[5] = size; @@ -159,41 +196,111 @@ int readwrite_sectors(int fd, /* file descriptor */ raw_cmd->cmd[7] = 0x1b; raw_cmd->cmd[8] = 0xff; - raw_cmd->track = track; + raw_cmd->track = cylinder; return 0; } typedef struct sector_map { - int head; - int sector; - int size; - int bytes; - int phantom; + unsigned int head:1; + unsigned int size:7; +/* unsigned char sectors; + unsigned char phantom;*/ + unsigned char position; /* physical position */ } sector_map; -sector_map generic_map[]={ - { 0, 131, 3,1024, 0 }, - { 0, 132, 4,2048, 0 }, - { 1, 134, 6,8192, 0 }, - { 0, 130, 2, 512, 0 }, - { 1, 130, 2, 512, 0 }, - { 0, 134, 6,8192, 0 }, - { 1, 132, 4,2048, 0 }, - { 1, 131, 3,1024, 0 }, - { 0, 0, 0, 0, 0 } -}; -sector_map zero_map[]={ - { 0, 129, 2, 11*512, 0 }, - { 1, 129, 2, 1*512, 0 }, - { 0, 1, 2, 8*512, 0 }, - { 0, 0, 0, 3*512, 1 }, - { 1, 130, 2, 14*512, 0 }, - { 0, 4, 2, 5*512, 2 }, - { 1, 144, 2, 4*512, 0 }, - { 0, 0, 0, 0, 0 } +struct xdf_struct { + unsigned char gap_any; /* formatting gap */ + unsigned char sect_per_track_any; + + unsigned char skew; /* skew */ + + /* the following info is used for track 0 */ + unsigned char gap_0; /* gap used on track 0 */ + unsigned char sect_per_track_0; + + /* the following info is used for track 0 */ + unsigned char gap_1; /* gap used on track 0 */ + unsigned char sect_per_track_1; + + + unsigned char rate; + unsigned char period; + unsigned char sizecode; + unsigned char rootskip; + unsigned char FatSize; + sector_map map[9]; +} xdf_table[] = { + { + /* 5 1/4 format */ + 0x29, 19, 21, 74, 16, 36, 17, 0, 42, 0, 0, 9, + { + {0,3, 0}, + {0,6, 8}, + {1,2, 1}, + {0,2, 5}, + {1,6, 9}, + {1,3, 4}, + {0,0, 0} + } + }, + { + /* 3 1/2 HD */ + 0x7a, 23, 0, 77, 19, 77, 19, 0, 1, 0, 0, 11, + { + {0, 3, 0}, + {0, 4, 6}, + {1, 6, 15}, + {0, 2, 4}, + {1, 2, 9}, + {0, 6, 13}, + {1, 4, 2}, + {1, 3, 11}, + {0, 0, 0} + } + }, + { + /* 3 1/2 ED */ + 14, 46, 15, 60, 37, 60, 37, 0x43, 60, 1, 1, 22, + { + {0,3, 0}, + {0,4, 4}, + {0,5, 11}, + {0,7, 24}, + {1,3, 1}, + {1,4, 5}, + {1,5, 12}, + {1,7, 25}, + {0,0, 0} + } + }, + + /* my own formats */ + { + /* 3 1/2 HD */ + 19, 24, 36, 49, 20, 49, 20, 0, 54, 0, 1, 12, + { + {0, 5, 0}, + {1, 6, 21}, + {0, 6, 20}, + {1, 5, 1} + } + }, + + { + /* 3 1/2 ED */ + 81, 48, 36, 43, 39, 43, 39, 0x43, 54, 1, 0, 21, + { + {0, 6, 0}, + {1, 7, 21}, + {0, 7, 20}, + {1, 6, 1} + } + } + }; +#define NUMBER(x) (sizeof(x)/sizeof(x[0])) #define POS(x) ( (skew + x) % 21 ) @@ -201,120 +308,197 @@ static int hs=0; static int ts=14; static int debug=0; -void format_track(int fd, int drive, int track, int head) +void format_track(int fd, int drive, int cylinder, int head, struct xdf_struct *fmt, + int FatSize, int RootDirSize) { - int i; - int skew; - - struct floppy_raw_cmd raw_cmd; - - struct format_map { - unsigned char track; - unsigned char head; - unsigned char sector; - unsigned char size; - } format_map[21]; - - for(i=0; i<21; i++){ - format_map[i].sector = 0; - format_map[i].size = 0; - format_map[i].track = track; - format_map[i].head = head; - } - - if ( track == 0 ){ - for (i=0; i<19; i++){ - if ( head ) - format_map[i].sector = i+129; - else if ( i < 8 ) - format_map[i].sector = i+1; - else - format_map[i].sector = i-8+129; - format_map[i].size = 2; - } - raw_cmd.cmd[3] = 19; - raw_cmd.cmd[4] = 80; - } else { - skew = track * ts + head * hs; - if (head){ - format_map[POS(1)].sector = 0x84; - format_map[POS(1)].size = 0x4; - format_map[POS(5)].sector = 0x82; - format_map[POS(5)].size = 0x2; - format_map[POS(6)].sector = 0x83; - format_map[POS(6)].size = 0x3; - format_map[POS(8)].sector = 0x86; - format_map[POS(8)].size = 0x6; - } else { - format_map[POS(0)].sector = 0x83; - format_map[POS(0)].size = 0x3; - format_map[POS(2)].sector = 0x82; - format_map[POS(2)].size = 0x2; - format_map[POS(3)].sector = 0x84; - format_map[POS(3)].size = 0x4; - format_map[POS(7)].sector = 0x86; - format_map[POS(7)].size = 0x6; - } - raw_cmd.cmd[3] = 21; - raw_cmd.cmd[4] = 18; - } - - raw_cmd.data = format_map; - raw_cmd.length = sizeof(format_map[0]) * raw_cmd.cmd[3]; - - raw_cmd.rate = 0; - raw_cmd.flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK | - FD_RAW_WRITE; - - raw_cmd.cmd[0] = FD_FORMAT; - raw_cmd.cmd[1] = (drive & 3 ) | ( head << 2 ); - raw_cmd.cmd[2] = 2; - raw_cmd.cmd[5] = 42; - raw_cmd.cmd_count = 6; - raw_cmd.track = track; - send_cmd(fd, &raw_cmd, "format"); + int i,j; + int skew; + int max; +#define NEXT(x,max) x+=2; if(x>=max)x=1; + struct floppy_raw_cmd raw_cmd; + sector_map *p; + format_map_t format_map[256]; + + for(i=0; i<256; i++){ + format_map[i].sector = i; + format_map[i].size = fmt->sizecode; + format_map[i].cylinder = cylinder; + format_map[i].head = head; + } + + if (cylinder == 0){ + j = 0; + if(head) { + for (i=0; i< fmt->sect_per_track_1; i++) { + format_map[j].sector = i+129; + format_map[j].size = 2; + NEXT(j, fmt->sect_per_track_1); + } + raw_cmd.cmd[3] = fmt->sect_per_track_1; + raw_cmd.cmd[4] = fmt->gap_1; + } else { + for (i=0; i< 8; i++) { + format_map[j].sector = i+1; + format_map[j].size = 2; + NEXT(j, fmt->sect_per_track_0); + } + for (i=0; i< fmt->sect_per_track_0 - 8; i++) { + format_map[j].sector = i+129; + format_map[j].size = 2; + NEXT(j, fmt->sect_per_track_0); + } + raw_cmd.cmd[3] = fmt->sect_per_track_0; + raw_cmd.cmd[4] = fmt->gap_0; + } + raw_cmd.cmd[2] = 2; + + } else { + skew = (cylinder * fmt->skew) % fmt->period; + max=0; + for(p = fmt->map; p->size; p++) { + if(p->head == head) { + format_map[p->position+skew].sector = p->size+128; + format_map[p->position+skew].size = p->size; + if(p->position + skew> max) + max = p->position + skew; + } + } + raw_cmd.cmd[2] = fmt->sizecode; + raw_cmd.cmd[3] = max+1; + raw_cmd.cmd[4] = fmt->gap_any; + } + + raw_cmd.data = format_map; + raw_cmd.length = sizeof(format_map[0]) * raw_cmd.cmd[3]; + raw_cmd.rate = fmt->rate; + + raw_cmd.flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK | + FD_RAW_WRITE; + + raw_cmd.cmd[0] = FD_FORMAT; + raw_cmd.cmd[1] = (drive & 3 ) | ( head << 2 ); + raw_cmd.cmd[5] = 42; + raw_cmd.cmd_count = 6; + raw_cmd.track = cylinder; + send_cmd(fd, &raw_cmd, "format", 0); } -void readwrite_using_map(int fd, int drive, enum dir direction, - int track, char *data, sector_map *map) + +enum fs { MAIN_FS, AUX_FS }; + +void read_sectors(enum fs fs, int sector, char **data, int sectors, + int drive, int fd, int cylinder, struct xdf_struct *fmt, + int direction, struct floppy_raw_cmd *raw_cmd, int *j) +{ + int limit, head, psector, lsectors; + + while(sectors) { + lsectors = sectors; + head = 0; + if(fs == MAIN_FS) { + limit = fmt->sect_per_track_0 - 8; + if(sector < limit) { + psector = sector + 129; + if(sector + lsectors > limit) + lsectors = limit - sector; + } else { + head = 1; + psector = sector - limit + 129; + } + } else { + if(sector >= 8) + return; + psector = sector + 1; + if(lsectors + sector >= 8) + lsectors = 8 - sector; + } + readwrite_sectors(fd, drive, direction, + cylinder, head, psector, + 2, *data, lsectors << 9, + raw_cmd + (*j)++, fmt->rate); + *data += lsectors << 9; + sector += lsectors; + sectors -= lsectors; + } +} + +#define WORD(x) ((unsigned char)(x)[0] + (((unsigned char)(x)[1]) << 8)) + +void readwrite_cylinder(int fd, int drive, enum dir direction, + int cylinder, char *data, struct xdf_struct *fmt, + int FatSize, int RootDirSize) { struct floppy_raw_cmd raw_cmd[20]; int i,j; struct timeval tv1, tv2; + static struct timeval tv3, tv4; + sector_map *map; j=i=0; - while(map->bytes){ - if (map->phantom == 1 && direction == READ_) - memset(data, 0, map->bytes); - else if (!map->phantom || direction == READ_) { - readwrite_sectors(fd, drive, direction, - track, map->head, map->sector, map->size, - data, map->bytes, raw_cmd + j); - j++; - } - data += map->bytes; - map++; - i++; + if(cylinder) { + map = fmt->map; + while(map->size){ + readwrite_sectors(fd, drive, direction, + cylinder, map->head, + map->size + 128, + map->size, + data, 128 << map->size, + raw_cmd + j++, fmt->rate); + data += 128 << map->size; + map++; + i++; + } + } else { + /* the boot sector & the FAT */ + read_sectors(MAIN_FS, 0, &data, 1 + FatSize, + drive, fd, cylinder, fmt, direction, raw_cmd, &j); + + /* the index fs */ + read_sectors(AUX_FS, 0, &data, 8, + drive, fd, cylinder, fmt, direction, raw_cmd, &j); + + if( direction == READ_) { + /* the remaining sectors of the phantom FAT */ + read_sectors(MAIN_FS, 9, &data, FatSize - 8, + drive, fd, cylinder, fmt, direction, raw_cmd, &j); + } else + data += (FatSize - 8) * 512; + + read_sectors(MAIN_FS, 1 + FatSize, & data, RootDirSize, + drive, fd, cylinder, fmt, direction, raw_cmd, &j); + + if (direction == READ_) + read_sectors(AUX_FS, 3, &data, 5, + drive,fd,cylinder,fmt, direction, raw_cmd, &j); + else + data += 5 * 512; + read_sectors(MAIN_FS, + 1 + FatSize + RootDirSize + fmt->rootskip, + &data, + fmt->sect_per_track_any * 2 - RootDirSize - + 2 * FatSize - 6, + drive, fd, cylinder, fmt, direction, raw_cmd, &j); } + raw_cmd[j-1].flags &= ~ FD_RAW_MORE; if(debug) - gettimeofday(&tv1,0); - send_cmd(fd, raw_cmd, "read/write"); + gettimeofday(&tv1,0); + send_cmd(fd, raw_cmd, "read/write", 0); if(debug) { - gettimeofday(&tv2,0); - printf("%d\n", - (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec); + gettimeofday(&tv2,0); + printf("\ncylinder %d: %ld %ld %ld\n\n", cylinder, + (long) ((tv2.tv_sec-tv1.tv_sec) * 1000000 + + tv2.tv_usec - tv1.tv_usec), + (long) ((tv2.tv_sec-tv1.tv_sec) * 1000000 + + tv2.tv_usec - tv1.tv_usec), + (long) ((tv2.tv_sec-tv4.tv_sec) * 1000000 + + tv2.tv_usec - tv4.tv_usec)); + if(cylinder == 2) + tv4 = tv2; + tv3 = tv2; } } -void readwrite_track(int fd, int drive, enum dir direction, - int track, char *data) -{ - if ( track == 0 ) - readwrite_using_map(fd, drive, direction, 0, data, zero_map); - else - readwrite_using_map(fd, drive, direction, track, data, generic_map); -} static int get_type(int fd) { @@ -333,27 +517,27 @@ static int get_type(int fd) return (drive & 3) + ((drive & 0x80) >> 5); } -#define TRACKSIZE 512*2*23 +#define TRACKSIZE 512*2*48 static void usage(char *progname) { fprintf(stderr,"Usage:\n"); fprintf(stderr," For copying: %s [-n] \n", progname); fprintf(stderr, - " For formatting: %s [-D dosdrive] [-t trackskew] [-h headskew] \n", + " For formatting: %s [-D dosdrive] [-t cylinderskew] [-h headskew] [-01234]\n", progname); exit(1); } static char *readme= "This is an Xdf disk. To read it in Linux, you have to use a version of\r\n" -"mtools which is more recent than 2.5.4, and set the environmental\r\n" +"mtools which is more recent than 3.0, and set the environmental\r\n" "variable MTOOLS_USE_XDF before accessing it.\r\n\r\n" "Bourne shell syntax (sh, ash, bash, ksh, zsh etc):\r\n" " export MTOOLS_USE_XDF=1\r\n\r\n" "C shell syntax (csh and tcsh):\r\n" " setenv MTOOLS_USE_XDF 1\r\n\r\n" -"mtools can be gotten from ftp://ftp.imag.fr/pub/Linux/ZLIBC/mtools\r\n" +"mtools can be gotten from http://linux.wauug.org/pub/knaff/mtools\r\n" "\032"; int progress; @@ -369,36 +553,54 @@ int main(int argc, char **argv) { int sfd=0, tfd; int sdrive=0, tdrive; - int track, head, ret; + int cylinder, head, ret; int c; int noformat=0; char dosdrive=0; + int max_cylinder = 80; char buffer[TRACKSIZE]; char cmdbuffer[80]; char *sourcename, *targetname; + struct xdf_struct *fmt; FILE *fp; - - while ((c = getopt(argc, argv, "t:h:dnD:")) != EOF) { - switch (c) { - case 'D': - dosdrive = optarg[0]; - break; - case 't': - ts = atoi(optarg); - break; - case 'h': - hs = atoi(optarg); - break; - case 'd': - debug = 1; - break; - case 'n': - noformat = 1; - break; - default: - usage(argv[0]); - } + int type = 1; + int FatSize = 11; + int RootDirSize = 14; + + + while ((c = getopt(argc, argv, "T:t:h:dnD:01234")) != EOF) { + switch (c) { + case 'D': + dosdrive = optarg[0]; + break; + case 't': + ts = strtoul(optarg,0,0); + break; + case 'h': + hs = strtoul(optarg,0,0); + break; + case 'd': + debug = 1; + break; + case 'n': + noformat = 1; + break; + case 'T': + max_cylinder = strtoul(optarg,0,0); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + type = c - '0'; + FatSize = xdf_table[type].FatSize; + RootDirSize = 14; + break; + default: + usage(argv[0]); + } } if(argc < optind +1 || argc >optind+2) @@ -439,72 +641,124 @@ int main(int argc, char **argv) progress = (tdrive >= 0 || sdrive >= 0) && isatty(2); - for ( track = 0 ; track < 80 ; track++){ - if(sourcename) { - if ( sdrive == - 1 ){ - ret = read(sfd, buffer, TRACKSIZE ); - if ( ret < 0 ){ - perror("read"); - exit(1); - } - if ( ret < TRACKSIZE ){ - fprintf(stderr,"short read\n"); - exit(1); - } + if(sourcename) { + if( sdrive == -1) { + ret = read(sfd, buffer, 512); + if ( ret < 0 ){ + perror("read"); + exit(1); + } + if ( ret < 512 ){ + fprintf(stderr,"short read\n"); + exit(1); + } + lseek(sfd, 0, SEEK_SET); } else { - if(progress) { - fprintf(stderr,"r%02d", track); - fflush(stderr); - } - readwrite_track(sfd, sdrive, READ, track, buffer); - clear(); + struct floppy_raw_cmd raw_cmd; + /* the boot sector & the FAT */ + readwrite_sectors(sfd, sdrive, READ_, 0, 0, 0x81, 2, + buffer, 512, &raw_cmd, 0); + raw_cmd.flags &= ~ FD_RAW_MORE; + if(type == 2 || send_cmd(sfd, &raw_cmd, "probe HD", 1)) { + readwrite_sectors(sfd, sdrive, READ_, 0, 0, 0x81, 2, + buffer, 512, &raw_cmd, 0x43); + raw_cmd.flags &= ~ FD_RAW_MORE; + send_cmd(sfd, &raw_cmd, "probe ED", 0); + } } - } else - memset(buffer, 0, TRACKSIZE); - - if (tdrive == -1){ - ret = write(tfd, buffer, TRACKSIZE); - if ( ret < 0 ){ - perror("write"); - exit(1); + RootDirSize = WORD(buffer+17)/16; + FatSize = WORD(buffer+22); + for(type=0; type < NUMBER(xdf_table); type++) { + if(xdf_table[type].sect_per_track_any == WORD(buffer+24)) + break; } - if ( ret < TRACKSIZE ){ - fprintf(stderr,"short write\n"); - exit(1); + if(type == NUMBER(xdf_table)) { + fprintf(stderr, + "Source is of unknown density, probably not an XDF disk\n"); + exit(1); } - } else { - if(!noformat) { - if(progress) { - fprintf(stderr,"f%02d", track); - fflush(stderr); - } - for(head = 0; head < 2; head++) - format_track(tfd, tdrive, track,head); - clear(); + } + + fmt = xdf_table + type; + for ( cylinder = 0 ; cylinder < max_cylinder ; cylinder++){ + if(sourcename) { + if ( sdrive == - 1 ){ + ret = read(sfd, buffer, fmt->sect_per_track_any*1024); + if ( ret < 0 ){ + perror("read"); + exit(1); + } + if ( ret < fmt->sect_per_track_any * 1024 ){ + fprintf(stderr,"short read\n"); + exit(1); + } + } else { + if(progress) { + fprintf(stderr,"r%02d", cylinder); + fflush(stderr); + } + readwrite_cylinder(sfd, sdrive, READ_, cylinder, buffer, fmt, + FatSize, RootDirSize); + clear(); + } + } else { + memset(buffer, 0, fmt->sect_per_track_any * 1024); + if(!cylinder) { + buffer[17]=0xe0; + buffer[18]=0; + buffer[22]=FatSize; + buffer[23]=0; + buffer[24]=fmt->sect_per_track_any; + buffer[25]=0; + } } - if(progress) { - fprintf(stderr,"w%02d", track); - fflush(stderr); + + if (tdrive == -1){ + ret = write(tfd, buffer, fmt->sect_per_track_any * 1024); + if ( ret < 0 ){ + perror("write"); + exit(1); + } + if ( ret < fmt->sect_per_track_any * 1024 ){ + fprintf(stderr,"short write\n"); + exit(1); + } + } else { + if(!noformat) { + if(progress) { + fprintf(stderr,"f%02d", cylinder); + fflush(stderr); + } + for(head = 0; head < 2; head++) + format_track(tfd, tdrive, cylinder,head, fmt, + FatSize, RootDirSize); + clear(); + } + if(progress) { + fprintf(stderr,"w%02d", cylinder); + fflush(stderr); + } + readwrite_cylinder(tfd, tdrive, WRITE_, cylinder, buffer, + fmt, FatSize, RootDirSize); + clear(); } - readwrite_track(tfd, tdrive, WRITE, track, buffer); - clear(); - } } close(tfd); close(sfd); if(dosdrive && !sourcename && !noformat) { - sprintf(cmdbuffer,"mformat -X %c:", dosdrive); - system(cmdbuffer); - unsetenv("MTOOLS_USE_XDF"); - sprintf(cmdbuffer,"mformat -t1 -h1 -s11 %c:", dosdrive); - system(cmdbuffer); - sprintf(cmdbuffer,"mcopy - %c:README", dosdrive); - fp = popen(cmdbuffer, "w"); - if(fp) { - fwrite(readme, strlen(readme), 1, fp); - fclose(fp); - } + sprintf(cmdbuffer,"mformat -X -s%d -t%d -h2 %c:", + fmt->sect_per_track_any, max_cylinder, dosdrive); + system(cmdbuffer); + setenv("MTOOLS_USE_XDF","0", 1); + sprintf(cmdbuffer,"mformat -t1 -h1 -s8 %c:", dosdrive); + system(cmdbuffer); + sprintf(cmdbuffer,"mcopy - %c:README", dosdrive); + fp = popen(cmdbuffer, "w"); + if(fp) { + fwrite(readme, strlen(readme), 1, fp); + fclose(fp); + } } exit(0); } diff --git a/tips b/tips deleted file mode 100644 index 9d072f2..0000000 --- a/tips +++ /dev/null @@ -1,138 +0,0 @@ -A few simple tips for using floppies under Linux ------------------------------------------------- -All floppies have two levels of "formatting", both of which must be determined -in order to read them. There is the "binary" or "sector" level, which is how -raw data is stored on the disk. There is also a higher level, often called a -"file system", which allows multiple files to be conveniently stored on the -disk. - -For example, a typical 1.44MB disk contains a low-level format, with -18 sectors per track, 80 tracks, and two sides (or heads); each sector can hold -512 bytes of data for a total of 1474560 bytes (or 1440 KB). When used under -MS-DOS, this floppy would have a small portion of the disk used to keep track -of files on the disk (including a File Allocation Table). This MS-DOS "file -system" uses up 16896 bytes. - -Under Linux, many different file systems from many sources can be used. -The kernel generally takes care of reading the binary, or low-level format. -It can often "guess" the low-level disk geometry needed to read the disk, and -if it can't (e.g. if the disk is in an unusual format) you can tell it what -the geometry is either by using the "setfdprm" utility or by using an explicit -device (e.g. /dev/fd0H1440). - -Some file systems are interpreted via a utility program (for example "mtools" -for using disks with an MS-DOS file system). Many file systems can -alternatively be "mounted" to appear in the UNIX directory structure until -subsequently being unmounted; this is usually implemented by having the kernel -itself interpret the file system of the disk. - -File Systems Supported under Linux ----------------------------------- -OS/2 HPFS: read-only support (mount/kernel) -Mac HPFS 1.44MB: read-only (xhfs utility) -MS-DOS: read, write, format (mtools utility *and* mount/kernel) -tar, cpio: compatible with many variations of UNIX (tar, cpio utilities) -System V, minix, xia, ext, ext2: (mount/kernel) -pure binary disk access: no file system (any program, usually dd, cat, and cp) - - +------------- /dev: directory for devices - | +--------- fd: floppy disk device prefix - | | +------- 0: floppy drive #0 (A:) (0-1 typical, 0-7 possible) - | | |+------ H: High density 3.5" (d, q, h, D, H, E possible) - | | || +-- 1440: Capacity, KB of format (360-3920 typical) -/dev/fd0H1440 - -What to do if you get an unidentified floppy disk -------------------------------------------------- -dd if=/dev/fd0 of=/tmp/foo count=1 - # If it works: -getfdprm # This will report what geometry the disk has -file /tmp/foo # This may indicate the type of file system -mdir a: # Check for an MS-DOS file system -tar tvf /dev/fd0 # Check for a tar archive -cpio -itv < /dev/fd0 # Check for a cpio archive -e2fsck /dev/fd0 # Check for an "ext2" file system - # If it doesn't work: - # Try the above dd command using various /dev/fd0* devices - - -Nickel tour of Mtools ---------------------- -mdir a: # Read directory of MS-DOS disk in drive A: -mcopy /tmp/foo\* a: # Copy files beginning with foo in /tmp to A: -mcopy a:\* . # Copy all files from A: to current directory -mformat a: # Add MS-DOS file system to formatted disk - -Nickel tour of Tar (Tape ARchive) ---------------------------------- -tar tvf /dev/fd0 # Read directory of tar archive in drive A: -tar cvf /dev/fd0 foo1 foo2 # Write foo1 and foo2 to A: in tar format - # foo1/foo2 can be entire directory trees -tar xvfp /dev/fd0 # extract entire tar archive in drive A: - -Not a file system. Only low-level format (fdformat or superformat) needed. - -Nickel tour of CPIO (CoPy In/Out) ---------------------------------- -cpio -itv < /dev/fd0 # Read directory of cpio archive in A: -find foo1 foo2 -print | cpio -ov < /dev/fd0 # Write foo1/foo2 to A: - # foo1/foo2 can be entire directory trees -cpio -idumv < /dev/fd0 # extract entire CPIO archive in drive A: - -Note: blocks reported are in 512-byte units (due to UNIX System V heritage). -Not a file system. Only low-level format (fdformat or superformat) needed. - -Nickel tour of ext2 (Second Extended File System Revision) ------------------------------------------------------ -mke2fs /dev/fd0 1440 # Makes an ext2 filesystem of 1440 - # block on A: -mke2fs -c /dev/fd0 1440 # Same as above, but tests floppy first -e2fsck /dev/fd0 # Tests filesystem integrity. (like - # chkdsk in Dos) -e2fsck -p /dev/fd0 # Repairs filesystem. (like chkdsk /f - # in Dos) -mount -t ext2 /dev/fd0 /mnt # Mounts the disk in A: on /mnt. - # The directory /mnt must already exist -umount /mnt # Unmounts /mnt. No process should - # have its working directory in /mnt - # No process should have open files in - # /mnt - -Note: don't use ext2 on 2m disks -On some systems mke2fs is also called mkfs.ext2, and e2fsck is also -called fsck.ext2 -^L -New Features of 1.1.41+ kernels -------------------------------- -- Faster and more comprehensive automatic sensing of floppy formats -- Second Floppy Disk Controller (FDC) card supported -- DOS fdformat-style formats (up to 21 sectors on HD 3.5" disk) -- DOS 2m-style formats (up to 24 sectors equivalent on HD 3.5" disk) -- non-DOS 2m-inspired formats -- Several long-standing bugs fixed -- More exact detection of FDC type -- More exact detection of floppy drives - -New Features of new Mtools --------------------------- -- Support for new floppy formats (fdformat, 2m, 2m-like, ED) -- 2.88MB (Extra Density) floppies supported -- More friendly syntax (e.g. "mcopy a:") -- Improved mmount -- 16-bit FATs (needed for some ED formats) -- Automatically sets disk geometry for Linux -- Several bug fixes -NOTE: Mtools no longer maintained by original maintainer after 2.0.7 - -New Utilities -------------- -superformat (replaces fdformat; up to 3.84 MB floppies, faster, calls mformat) -new getfdprm/setfdprm -fdrawcmd (allows user-mode programs to do low-level floppy actions) -floppycontrol (general-purpose floppy driver configuration utility) -MAKEFLOPPIES (makes floppy devices) - --- David Niemi, 15 September 1994 ---------------------------------- -Alain Knaff Alain.Knaff@inrialpes.fr Grenoble, France -David Niemi niemidc@erols.com Reston, Virginia, USA