Remove long-unmaintained ftape driver subsystem.
authorJeff Garzik <jeff@garzik.org>
Mon, 4 Dec 2006 03:22:41 +0000 (22:22 -0500)
committerJeff Garzik <jeff@garzik.org>
Mon, 4 Dec 2006 03:22:41 +0000 (22:22 -0500)
It's bitrotten, long unmaintained, long hidden under BROKEN_ON_SMP,
etc.  As scheduled in feature-removal-schedule.txt, and ack'd several
times on lkml.

Signed-off-by: Jeff Garzik <jeff@garzik.org>
74 files changed:
Documentation/00-INDEX
Documentation/feature-removal-schedule.txt
Documentation/ftape.txt [deleted file]
Documentation/kernel-parameters.txt
MAINTAINERS
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/ftape/Kconfig [deleted file]
drivers/char/ftape/Makefile [deleted file]
drivers/char/ftape/README.PCI [deleted file]
drivers/char/ftape/RELEASE-NOTES [deleted file]
drivers/char/ftape/compressor/Makefile [deleted file]
drivers/char/ftape/compressor/lzrw3.c [deleted file]
drivers/char/ftape/compressor/lzrw3.h [deleted file]
drivers/char/ftape/compressor/zftape-compress.c [deleted file]
drivers/char/ftape/compressor/zftape-compress.h [deleted file]
drivers/char/ftape/lowlevel/Makefile [deleted file]
drivers/char/ftape/lowlevel/fc-10.c [deleted file]
drivers/char/ftape/lowlevel/fc-10.h [deleted file]
drivers/char/ftape/lowlevel/fdc-io.c [deleted file]
drivers/char/ftape/lowlevel/fdc-io.h [deleted file]
drivers/char/ftape/lowlevel/fdc-isr.c [deleted file]
drivers/char/ftape/lowlevel/fdc-isr.h [deleted file]
drivers/char/ftape/lowlevel/ftape-bsm.c [deleted file]
drivers/char/ftape/lowlevel/ftape-bsm.h [deleted file]
drivers/char/ftape/lowlevel/ftape-buffer.c [deleted file]
drivers/char/ftape/lowlevel/ftape-buffer.h [deleted file]
drivers/char/ftape/lowlevel/ftape-calibr.c [deleted file]
drivers/char/ftape/lowlevel/ftape-calibr.h [deleted file]
drivers/char/ftape/lowlevel/ftape-ctl.c [deleted file]
drivers/char/ftape/lowlevel/ftape-ctl.h [deleted file]
drivers/char/ftape/lowlevel/ftape-ecc.c [deleted file]
drivers/char/ftape/lowlevel/ftape-ecc.h [deleted file]
drivers/char/ftape/lowlevel/ftape-format.c [deleted file]
drivers/char/ftape/lowlevel/ftape-format.h [deleted file]
drivers/char/ftape/lowlevel/ftape-init.c [deleted file]
drivers/char/ftape/lowlevel/ftape-init.h [deleted file]
drivers/char/ftape/lowlevel/ftape-io.c [deleted file]
drivers/char/ftape/lowlevel/ftape-io.h [deleted file]
drivers/char/ftape/lowlevel/ftape-proc.c [deleted file]
drivers/char/ftape/lowlevel/ftape-proc.h [deleted file]
drivers/char/ftape/lowlevel/ftape-read.c [deleted file]
drivers/char/ftape/lowlevel/ftape-read.h [deleted file]
drivers/char/ftape/lowlevel/ftape-rw.c [deleted file]
drivers/char/ftape/lowlevel/ftape-rw.h [deleted file]
drivers/char/ftape/lowlevel/ftape-setup.c [deleted file]
drivers/char/ftape/lowlevel/ftape-tracing.c [deleted file]
drivers/char/ftape/lowlevel/ftape-tracing.h [deleted file]
drivers/char/ftape/lowlevel/ftape-write.c [deleted file]
drivers/char/ftape/lowlevel/ftape-write.h [deleted file]
drivers/char/ftape/lowlevel/ftape_syms.c [deleted file]
drivers/char/ftape/zftape/Makefile [deleted file]
drivers/char/ftape/zftape/zftape-buffers.c [deleted file]
drivers/char/ftape/zftape/zftape-buffers.h [deleted file]
drivers/char/ftape/zftape/zftape-ctl.c [deleted file]
drivers/char/ftape/zftape/zftape-ctl.h [deleted file]
drivers/char/ftape/zftape/zftape-eof.c [deleted file]
drivers/char/ftape/zftape/zftape-eof.h [deleted file]
drivers/char/ftape/zftape/zftape-init.c [deleted file]
drivers/char/ftape/zftape/zftape-init.h [deleted file]
drivers/char/ftape/zftape/zftape-read.c [deleted file]
drivers/char/ftape/zftape/zftape-read.h [deleted file]
drivers/char/ftape/zftape/zftape-rw.c [deleted file]
drivers/char/ftape/zftape/zftape-rw.h [deleted file]
drivers/char/ftape/zftape/zftape-vtbl.c [deleted file]
drivers/char/ftape/zftape/zftape-vtbl.h [deleted file]
drivers/char/ftape/zftape/zftape-write.c [deleted file]
drivers/char/ftape/zftape/zftape-write.h [deleted file]
drivers/char/ftape/zftape/zftape_syms.c [deleted file]
include/linux/Kbuild
include/linux/ftape-header-segment.h [deleted file]
include/linux/ftape-vendors.h [deleted file]
include/linux/ftape.h [deleted file]
include/linux/zftape.h [deleted file]

index 02457ec9c94fe27ec74dc943186283137774e232..f08ca953573392ec710a27db0f7f87f14ad54527 100644 (file)
@@ -104,8 +104,6 @@ firmware_class/
        - request_firmware() hotplug interface info.
 floppy.txt
        - notes and driver options for the floppy disk driver.
-ftape.txt
-       - notes about the floppy tape device driver.
 hayes-esp.txt
        - info on using the Hayes ESP serial driver.
 highuid.txt
index f81819364b7ab9ebade50ccc24ed494219160ed6..226ecf2ffd568158a2927b24e27e21bde00b6d30 100644 (file)
@@ -234,14 +234,6 @@ Who:       Jean Delvare <khali@linux-fr.org>
 
 ---------------------------
 
-What:  ftape
-When:  2.6.20
-Why:   Orphaned for ages.  SMP bugs long unfixed.  Few users left
-       in the world.
-Who:   Jeff Garzik <jeff@garzik.org>
-
----------------------------
-
 What:  IPv4 only connection tracking/NAT/helpers
 When:  2.6.22
 Why:   The new layer 3 independant connection tracking replaces the old
diff --git a/Documentation/ftape.txt b/Documentation/ftape.txt
deleted file mode 100644 (file)
index 7d8bb33..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-Intro
-=====
-
-This file describes some issues involved when using the "ftape"
-floppy tape device driver that comes with the Linux kernel.
-
-ftape has a home page at
-
-http://ftape.dot-heine.de/
-
-which contains further information about ftape. Please cross check
-this WWW address against the address given (if any) in the MAINTAINERS
-file located in the top level directory of the Linux kernel source
-tree.
-
-NOTE: This is an unmaintained set of drivers, and it is not guaranteed to work.
-If you are interested in taking over maintenance, contact Claus-Justus Heine
-<ch@dot-heine.de>, the former maintainer.
-
-Contents
-========
-
-A minus 1: Ftape documentation
-
-A. Changes
-   1. Goal
-   2. I/O Block Size
-   3. Write Access when not at EOD (End Of Data) or BOT (Begin Of Tape)
-   4. Formatting
-   5. Interchanging cartridges with other operating systems
-
-B. Debugging Output
-   1. Introduction
-   2. Tuning the debugging output
-
-C. Boot and load time configuration
-   1. Setting boot time parameters
-   2. Module load time parameters
-   3. Ftape boot- and load time options
-   4. Example kernel parameter setting
-   5. Example module parameter setting
-
-D. Support and contacts
-
-*******************************************************************************
-
-A minus 1. Ftape documentation
-==============================
-
-Unluckily, the ftape-HOWTO is out of date. This really needs to be
-changed. Up to date documentation as well as recent development
-versions of ftape and useful links to related topics can be found at
-the ftape home page at
-
-http://ftape.dot-heine.de/
-
-*******************************************************************************
-
-A. Changes
-==========
-
-1. Goal
-   ~~~~
-   The goal of all that incompatibilities was to give ftape an interface
-   that resembles the interface provided by SCSI tape drives as close
-   as possible. Thus any Unix backup program that is known to work
-   with SCSI tape drives should also work.
-
-   The concept of a fixed block size for read/write transfers is
-   rather unrelated to this SCSI tape compatibility at the file system
-   interface level. It developed out of a feature of zftape, a
-   block wise user transparent on-the-fly compression. That compression
-   support will not be dropped in future releases for compatibility
-   reasons with previous releases of zftape.
-
-2. I/O Block Size
-   ~~~~~~~~~~~~~~
-   The block size defaults to 10k which is the default block size of
-   GNU tar.
-
-   The block size can be tuned either during kernel configuration or
-   at runtime with the MTIOCTOP ioctl using the MTSETBLK operation
-   (i.e. do "mt -f /dev/qft0" setblk #BLKSZ). A block size of 0
-   switches to variable block size mode i.e. "mt setblk 0" switches
-   off the block size restriction. However, this disables zftape's
-   built in on-the-fly compression which doesn't work with variable
-   block size mode.
-
-   The BLKSZ parameter must be given as a byte count and must be a
-   multiple of 32k or 0, i.e. use "mt setblk 32768" to switch to a
-   block size of 32k.
-
-   The typical symptom of a block size mismatch is an "invalid
-   argument" error message.
-
-3. Write Access when not at EOD (End Of Data) or BOT (Begin Of Tape)
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-   zftape (the file system interface of ftape-3.x) denies write access
-   to the tape cartridge when it isn't positioned either at BOT or
-   EOD.
-
-4. Formatting
-   ~~~~~~~~~~
-   ftape DOES support formatting of floppy tape cartridges. You need the
-   `ftformat' program that is shipped with the modules version of ftape.
-   Please get the latest version of ftape from
-
-   ftp://sunsite.unc.edu/pub/Linux/kernel/tapes
-
-   or from the ftape home page at
-
-   http://ftape.dot-heine.de/
-
-   `ftformat' is contained in the `./contrib/' subdirectory of that
-   separate ftape package.
-
-5. Interchanging cartridges with other operating systems
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-   The internal emulation of Unix tape device file marks has changed
-   completely. ftape now uses the volume table segment as specified
-   by the QIC-40/80/3010/3020/113 standards to emulate file marks. As
-   a consequence there is limited support to interchange cartridges
-   with other operating systems.
-
-   To be more precise: ftape will detect volumes written by other OS's
-   programs and other OS's programs will detect volumes written by
-   ftape.
-
-   However, it isn't possible to extract the data dumped to the tape
-   by some MSDOS program with ftape. This exceeds the scope of a
-   kernel device driver. If you need such functionality, then go ahead
-   and write a user space utility that is able to do that. ftape already
-   provides all kernel level support necessary to do that.
-
-*******************************************************************************
-
-B. Debugging Output
-   ================
-
-1. Introduction
-   ~~~~~~~~~~~~
-   The ftape driver can be very noisy in that is can print lots of
-   debugging messages to the kernel log files and the system console.
-   While this is useful for debugging it might be annoying during
-   normal use and enlarges the size of the driver by several kilobytes.
-
-   To reduce the size of the driver you can trim the maximal amount of
-   debugging information available during kernel configuration. Please
-   refer to the kernel configuration script and its on-line help
-   functionality.
-
-   The amount of debugging output maps to the "tracing" boot time
-   option and the "ft_tracing" modules option as follows:
-
-   0              bugs
-   1              + errors (with call-stack dump)
-   2              + warnings
-   3              + information
-   4              + more information
-   5              + program flow
-   6              + fdc/dma info
-   7              + data flow
-   8              + everything else
-
-2. Tuning the debugging output
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-   To reduce the amount of debugging output printed to the system
-   console you can
-
-   i)  trim the debugging output at run-time with
-
-       mt -f /dev/nqft0 setdensity #DBGLVL
-
-       where "#DBGLVL" is a number between 0 and 9
-
-   ii) trim the debugging output at module load time with
-
-       modprobe ftape ft_tracing=#DBGLVL
-
-       Of course, this applies only if you have configured ftape to be
-       compiled as a module.
-
-   iii) trim the debugging output during system boot time. Add the
-       following to the kernel command line:
-
-       ftape=#DBGLVL,tracing
-
-       Please refer also to the next section if you don't know how to
-       set boot time parameters.
-
-*******************************************************************************
-
-C. Boot and load time configuration
-   ================================
-
-1. Setting boot time parameters
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
-   Assuming that you use lilo, the LI)nux LO)ader, boot time kernel
-   parameters can be set by adding a line
-
-   append some_kernel_boot_time_parameter
-
-   to `/etc/lilo.conf' or at real boot time by typing in the options
-   at the prompt provided by LILO. I can't give you advice on how to
-   specify those parameters with other loaders as I don't use them.
-
-   For ftape, each "some_kernel_boot_time_parameter" looks like
-   "ftape=value,option". As an example, the debugging output can be
-   increased with
-
-   ftape=4,tracing
-
-   NOTE: the value precedes the option name.
-
-2. Module load time parameters
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-   Module parameters can be specified either directly when invoking
-   the program 'modprobe' at the shell prompt:
-
-   modprobe ftape ft_tracing=4
-
-   or by editing the file `/etc/modprobe.conf' in which case they take
-   effect each time when the module is loaded with `modprobe' (please
-   refer to the respective manual pages). Thus, you should add a line
-
-   options ftape ft_tracing=4
-
-   to `/etc/modprobe.conf` if you intend to increase the debugging
-   output of the driver.
-
-
-3. Ftape boot- and load time options
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-   i.   Controlling the amount of debugging output
-        DBGLVL has to be replaced by a number between 0 and 8.
-
-        module                 |  kernel command line
-        -----------------------|----------------------
-        ft_tracing=DBGLVL      |  ftape=DBGLVL,tracing
-
-   ii.  Hardware setup
-       BASE is the base address of your floppy disk controller,
-        IRQ and DMA give its interrupt and DMA channel, respectively.
-        BOOL is an integer, "0" means "no"; any other value means
-       "yes". You don't need to specify anything if connecting your tape
-        drive to the standard floppy disk controller. All of these
-       values have reasonable defaults. The defaults can be modified
-       during kernel configuration, i.e. while running "make config",
-       "make menuconfig" or "make xconfig" in the top level directory
-       of the Linux kernel source tree. Please refer also to the on
-       line documentation provided during that kernel configuration
-       process.
-
-       ft_probe_fc10 is set to a non-zero value if you wish for ftape to
-       probe for a Colorado FC-10 or FC-20 controller.
-
-       ft_mach2 is set to a non-zero value if you wish for ftape to probe
-       for a Mountain MACH-2 controller.
-
-        module                 |  kernel command line
-        -----------------------|----------------------
-        ft_fdc_base=BASE       |  ftape=BASE,ioport
-        ft_fdc_irq=IRQ         |  ftape=IRQ,irq
-        ft_fdc_dma=DMA         |  ftape=DMA,dma
-        ft_probe_fc10=BOOL     |  ftape=BOOL,fc10
-        ft_mach2=BOOL          |  ftape=BOOL,mach2
-        ft_fdc_threshold=THR   |  ftape=THR,threshold
-        ft_fdc_rate_limit=RATE |  ftape=RATE,datarate
-
-4. Example kernel parameter setting
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
-   To configure ftape to probe for a Colorado FC-10/FC-20 controller
-   and to increase the amount of debugging output a little bit, add
-   the following line to `/etc/lilo.conf':
-
-   append ftape=1,fc10 ftape=4,tracing
-
-5. Example module parameter setting
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-   To do the same, but with ftape compiled as a loadable kernel
-   module, add the following line to `/etc/modprobe.conf':
-
-   options ftape ft_probe_fc10=1 ft_tracing=4
-
-*******************************************************************************
-
-D. Support and contacts
-   ====================
-
-   Ftape is distributed under the GNU General Public License. There is
-   absolutely no warranty for this software. However, you can reach
-   the current maintainer of the ftape package under the email address
-   given in the MAINTAINERS file which is located in the top level
-   directory of the Linux kernel source tree. There you'll find also
-   the relevant mailing list to use as a discussion forum and the web
-   page to query for the most recent documentation, related work and
-   development versions of ftape.
-
-   Changelog:
-   ==========
-
-~1996:         Original Document
-
-10-24-2004:    General cleanup and updating, noting additional module options.
-               James Nelson <james4765@gmail.com>
index 67473849f20e0e42cc4d2ef6ae015634b4c830ba..15e4fed127f69bd3200d2a8ae1e59832570def7e 100644 (file)
@@ -557,9 +557,6 @@ and is between 256 and 4096 characters. It is defined in the file
        floppy=         [HW]
                        See Documentation/floppy.txt.
 
-       ftape=          [HW] Floppy Tape subsystem debugging options.
-                       See Documentation/ftape.txt.
-
        gamecon.map[2|3]=
                        [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
                        support via parallel port (up to 5 devices per port)
index 45df5d4e2ab34a4009823d1b565d56494c3977df..8385a69138a802cb42658f60e1363f03ba684e80 100644 (file)
@@ -1166,11 +1166,6 @@ P:       David Howells
 M:     dhowells@redhat.com
 S:     Maintained
 
-FTAPE/QIC-117
-L:     linux-tape@vger.kernel.org
-W:     http://sourceforge.net/projects/ftape
-S:     Orphan
-
 FUSE: FILESYSTEM IN USERSPACE
 P:     Miklos Szeredi
 M:     miklos@szeredi.hu
index ad8b537ad47bc79203dc3d9421f83a5ddd23a33a..24f922f127830ea75880c8e65a5dfe3418599942 100644 (file)
@@ -855,39 +855,6 @@ config TANBAC_TB0219
        depends TANBAC_TB022X
        select GPIO_VR41XX
 
-menu "Ftape, the floppy tape device driver"
-
-config FTAPE
-       tristate "Ftape (QIC-80/Travan) support"
-       depends on BROKEN_ON_SMP && (ALPHA || X86)
-       ---help---
-         If you have a tape drive that is connected to your floppy
-         controller, say Y here.
-
-         Some tape drives (like the Seagate "Tape Store 3200" or the Iomega
-         "Ditto 3200" or the Exabyte "Eagle TR-3") come with a "high speed"
-         controller of their own. These drives (and their companion
-         controllers) are also supported if you say Y here.
-
-         If you have a special controller (such as the CMS FC-10, FC-20,
-         Mountain Mach-II, or any controller that is based on the Intel 82078
-         FDC like the high speed controllers by Seagate and Exabyte and
-         Iomega's "Ditto Dash") you must configure it by selecting the
-         appropriate entries from the "Floppy tape controllers" sub-menu
-         below and possibly modify the default values for the IRQ and DMA
-         channel and the IO base in ftape's configuration menu.
-
-         If you want to use your floppy tape drive on a PCI-bus based system,
-         please read the file <file:drivers/char/ftape/README.PCI>.
-
-         The ftape kernel driver is also available as a runtime loadable
-         module. To compile this driver as a module, choose M here: the
-         module will be called ftape.
-
-source "drivers/char/ftape/Kconfig"
-
-endmenu
-
 source "drivers/char/agp/Kconfig"
 
 source "drivers/char/drm/Kconfig"
index 777cad045094672c0d1fe86f0fa2df3d15cb42c4..b1fcdab909471e49b6489eeb048bca1b371ac070 100644 (file)
@@ -78,7 +78,6 @@ obj-$(CONFIG_TOSHIBA)         += toshiba.o
 obj-$(CONFIG_I8K)              += i8k.o
 obj-$(CONFIG_DS1620)           += ds1620.o
 obj-$(CONFIG_HW_RANDOM)                += hw_random/
-obj-$(CONFIG_FTAPE)            += ftape/
 obj-$(CONFIG_COBALT_LCD)       += lcd.o
 obj-$(CONFIG_PPDEV)            += ppdev.o
 obj-$(CONFIG_NWBUTTON)         += nwbutton.o
diff --git a/drivers/char/ftape/Kconfig b/drivers/char/ftape/Kconfig
deleted file mode 100644 (file)
index 0d65189..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-#
-# Ftape configuration
-#
-config ZFTAPE
-       tristate "Zftape, the VFS interface"
-       depends on FTAPE
-       ---help---
-         Normally, you want to say Y or M. DON'T say N here or you
-         WON'T BE ABLE TO USE YOUR FLOPPY TAPE DRIVE.
-
-         The ftape module itself no longer contains the routines necessary
-         to interface with the kernel VFS layer (i.e. to actually write data
-         to and read data from the tape drive).  Instead the file system
-         interface (i.e. the hardware independent part of the driver) has
-         been moved to a separate module.
-
-         To compile this driver as a module, choose M here: the
-         module will be called zftape.
-
-         Regardless of whether you say Y or M here, an additional runtime
-         loadable module called `zft-compressor' which contains code to
-         support user transparent on-the-fly compression based on Ross
-         William's lzrw3 algorithm will be produced.  If you have enabled the
-         kernel module loader (i.e. have said Y to "Kernel module loader
-         support", above) then `zft-compressor' will be loaded
-         automatically by zftape when needed.
-
-         Despite its name, zftape does NOT use compression by default.
-
-config ZFT_DFLT_BLK_SZ
-       int "Default block size"
-       depends on ZFTAPE
-       default "10240"
-       ---help---
-         If unsure leave this at its default value, i.e. 10240. Note that
-         you specify only the default block size here. The block size can be
-         changed at run time using the MTSETBLK tape operation with the
-         MTIOCTOP ioctl (i.e. with "mt -f /dev/qft0 setblk #BLKSZ" from the
-         shell command line).
-
-         The probably most striking difference between zftape and previous
-         versions of ftape is the fact that all data must be written or read
-         in multiples of a fixed block size. The block size defaults to
-         10240 which is what GNU tar uses. The values for the block size
-         should be either 1 or multiples of 1024 up to a maximum value of
-         63488 (i.e. 62 K). If you specify `1' then zftape's builtin
-         compression will be disabled.
-
-         Reasonable values are `10240' (GNU tar's default block size),
-         `5120' (afio's default block size), `32768' (default block size some
-         backup programs assume for SCSI tape drives) or `1' (no restriction
-         on block size, but disables builtin compression).
-
-comment "The compressor will be built as a module only!"
-       depends on FTAPE && ZFTAPE
-
-config ZFT_COMPRESSOR
-       tristate
-       depends on FTAPE!=n && ZFTAPE!=n
-       default m
-
-config FT_NR_BUFFERS
-       int "Number of ftape buffers (EXPERIMENTAL)"
-       depends on FTAPE && EXPERIMENTAL
-       default "3"
-       help
-         Please leave this at `3' unless you REALLY know what you are doing.
-         It is not necessary to change this value. Values below 3 make the
-         proper use of ftape impossible, values greater than 3 are a waste of
-         memory. You can change the amount of DMA memory used by ftape at
-         runtime with "mt -f /dev/qft0 setdrvbuffer #NUMBUFFERS". Each buffer
-         wastes 32 KB of memory. Please note that this memory cannot be
-         swapped out.
-
-config FT_PROC_FS
-       bool "Enable procfs status report (+2kb)"
-       depends on FTAPE && PROC_FS
-       ---help---
-         Optional. Saying Y will result in creation of a directory
-         `/proc/ftape' under the /proc file system. The files can be viewed
-         with your favorite pager (i.e. use "more /proc/ftape/history" or
-         "less /proc/ftape/history" or simply "cat /proc/ftape/history"). The
-         file will contain some status information about the inserted
-         cartridge, the kernel driver, your tape drive, the floppy disk
-         controller and the error history for the most recent use of the
-         kernel driver. Saying Y will enlarge the size of the ftape driver
-         by approximately 2 KB.
-
-         WARNING: When compiling ftape as a module (i.e. saying M to "Floppy
-         tape drive") it is dangerous to use ftape's /proc file system
-         interface. Accessing `/proc/ftape' while the module is unloaded will
-         result in a kernel Oops. This cannot be fixed from inside ftape.
-
-choice
-       prompt "Debugging output"
-       depends on FTAPE
-       default FT_NORMAL_DEBUG
-
-config FT_NORMAL_DEBUG
-       bool "Normal"
-       ---help---
-         This option controls the amount of debugging output the ftape driver
-         is ABLE to produce; it does not increase or diminish the debugging
-         level itself. If unsure, leave this at its default setting,
-         i.e. choose "Normal".
-
-         Ftape can print lots of debugging messages to the system console
-         resp. kernel log files. Reducing the amount of possible debugging
-         output reduces the size of the kernel module by some KB, so it might
-         be a good idea to use "None" for emergency boot floppies.
-
-         If you want to save memory then the following strategy is
-         recommended: leave this option at its default setting "Normal" until
-         you know that the driver works as expected, afterwards reconfigure
-         the kernel, this time specifying "Reduced" or "None" and recompile
-         and install the kernel as usual. Note that choosing "Excessive"
-         debugging output does not increase the amount of debugging output
-         printed to the console but only makes it possible to produce
-         "Excessive" debugging output.
-
-         Please read <file:Documentation/ftape.txt> for a short description
-         how to control the amount of debugging output.
-
-config FT_FULL_DEBUG
-       bool "Excessive"
-       help
-         Extremely verbose output for driver debugging purposes.
-
-config FT_NO_TRACE
-       bool "Reduced"
-       help
-         Reduced tape driver debugging output.
-
-config FT_NO_TRACE_AT_ALL
-       bool "None"
-       help
-         Suppress all debugging output from the tape drive.
-
-endchoice
-
-comment "Hardware configuration"
-       depends on FTAPE
-
-choice
-       prompt "Floppy tape controllers"
-       depends on FTAPE
-       default FT_STD_FDC
-
-config FT_STD_FDC
-       bool "Standard"
-       ---help---
-         Only change this setting if you have a special controller. If you
-         didn't plug any add-on card into your computer system but just
-         plugged the floppy tape cable into the already existing floppy drive
-         controller then you don't want to change the default setting,
-         i.e. choose "Standard".
-
-         Choose "MACH-2" if you have a Mountain Mach-2 controller.
-         Choose "FC-10/FC-20" if you have a Colorado FC-10 or FC-20
-         controller.
-         Choose "Alt/82078" if you have another controller that is located at
-         an IO base address different from the standard floppy drive
-         controller's base address of `0x3f0', or uses an IRQ (interrupt)
-         channel different from `6', or a DMA channel different from
-         `2'. This is necessary for any controller card that is based on
-         Intel's 82078 FDC such as Seagate's, Exabyte's and Iomega's "high
-         speed" controllers.
-
-         If you choose something other than "Standard" then please make
-         sure that the settings for the IO base address and the IRQ and DMA
-         channel in the configuration menus below are correct. Use the manual
-         of your tape drive to determine the correct settings!
-
-         If you are already successfully using your tape drive with another
-         operating system then you definitely should use the same settings
-         for the IO base, the IRQ and DMA channel that have proven to work
-         with that other OS.
-
-         Note that this menu lets you specify only the default setting for
-         the hardware setup. The hardware configuration can be changed at
-         boot time (when ftape is compiled into the kernel, i.e. if you
-         have said Y to "Floppy tape drive") or module load time (i.e. if you
-         have said M to "Floppy tape drive").
-
-         Please read also the file <file:Documentation/ftape.txt> which
-         contains a short description of the parameters that can be set at
-         boot or load time. If you want to use your floppy tape drive on a
-         PCI-bus based system, please read the file
-         <file:drivers/char/ftape/README.PCI>.
-
-config FT_MACH2
-       bool "MACH-2"
-
-config FT_PROBE_FC10
-       bool "FC-10/FC-20"
-
-config FT_ALT_FDC
-       bool "Alt/82078"
-
-endchoice
-
-comment "Consult the manuals of your tape drive for the correct settings!"
-       depends on FTAPE && !FT_STD_FDC
-
-config FT_FDC_BASE
-       hex "IO base of the floppy disk controller"
-       depends on FTAPE && !FT_STD_FDC
-       default "0"
-       ---help---
-         You don't need to specify a value if the following default
-         settings for the base IO address are correct:
-         <<< MACH-2     : 0x1E0 >>>
-         <<< FC-10/FC-20: 0x180 >>>
-         <<< Secondary  : 0x370 >>>
-         Secondary refers to a secondary FDC controller like the "high speed"
-         controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash.
-         Please make sure that the setting for the IO base address
-         specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR
-         CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already
-         successfully using the tape drive with another operating system then
-         you definitely should use the same settings for the IO base that has
-         proven to work with that other OS.
-
-         Note that this menu lets you specify only the default setting for
-         the IO base. The hardware configuration can be changed at boot time
-         (when ftape is compiled into the kernel, i.e. if you specified Y to
-         "Floppy tape drive") or module load time (i.e. if you have said M to
-         "Floppy tape drive").
-
-         Please read also the file <file:Documentation/ftape.txt> which
-         contains a short description of the parameters that can be set at
-         boot or load time.
-
-config FT_FDC_IRQ
-       int "IRQ channel of the floppy disk controller"
-       depends on FTAPE && !FT_STD_FDC
-       default "0"
-       ---help---
-         You don't need to specify a value if the following default
-         settings for the interrupt channel are correct:
-         <<< MACH-2     : 6 >>>
-         <<< FC-10/FC-20: 9 >>>
-         <<< Secondary  : 6 >>>
-         Secondary refers to secondary a FDC controller like the "high speed"
-         controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash.
-         Please make sure that the setting for the IO base address
-         specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR
-         CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already
-         successfully using the tape drive with another operating system then
-         you definitely should use the same settings for the IO base that has
-         proven to work with that other OS.
-
-         Note that this menu lets you specify only the default setting for
-         the IRQ channel. The hardware configuration can be changed at boot
-         time (when ftape is compiled into the kernel, i.e. if you said Y to
-         "Floppy tape drive") or module load time (i.e. if you said M to
-         "Floppy tape drive").
-
-         Please read also the file <file:Documentation/ftape.txt> which
-         contains a short description of the parameters that can be set at
-         boot or load time.
-
-config FT_FDC_DMA
-       int "DMA channel of the floppy disk controller"
-       depends on FTAPE && !FT_STD_FDC
-       default "0"
-       ---help---
-         You don't need to specify a value if the following default
-         settings for the DMA channel are correct:
-         <<< MACH-2     : 2 >>>
-         <<< FC-10/FC-20: 3 >>>
-         <<< Secondary  : 2 >>>
-         Secondary refers to a secondary FDC controller like the "high speed"
-         controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash.
-         Please make sure that the setting for the IO base address
-         specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR
-         CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already
-         successfully using the tape drive with another operating system then
-         you definitely should use the same settings for the IO base that has
-         proven to work with that other OS.
-
-         Note that this menu lets you specify only the default setting for
-         the DMA channel. The hardware configuration can be changed at boot
-         time (when ftape is compiled into the kernel, i.e. if you said Y to
-         "Floppy tape drive") or module load time (i.e. if you said M to
-         "Floppy tape drive").
-
-         Please read also the file <file:Documentation/ftape.txt> which
-         contains a short description of the parameters that can be set at
-         boot or load time.
-
-config FT_FDC_THR
-       int "Default FIFO threshold (EXPERIMENTAL)"
-       depends on FTAPE && EXPERIMENTAL
-       default "8"
-       help
-         Set the FIFO threshold of the FDC. If this is higher the DMA
-         controller may serve the FDC after a higher latency time. If this is
-         lower, fewer DMA transfers occur leading to less bus contention.
-         You may try to tune this if ftape annoys you with "reduced data
-         rate because of excessive overrun errors" messages. However, this
-         doesn't seem to have too much effect.
-
-         If unsure, don't touch the initial value, i.e. leave it at "8".
-
-config FT_FDC_MAX_RATE
-       int "Maximal data rate to use (EXPERIMENTAL)"
-       depends on FTAPE && EXPERIMENTAL
-       default "2000"
-       ---help---
-         With some motherboard/FDC combinations ftape will not be able to
-         run your FDC/tape drive combination at the highest available
-         speed. If this is the case you'll encounter "reduced data rate
-         because of excessive overrun errors" messages and lots of retries
-         before ftape finally decides to reduce the data rate.
-
-         In this case it might be desirable to tell ftape beforehand that
-         it need not try to run the tape drive at the highest available
-         speed. If unsure, leave this disabled, i.e. leave it at 2000
-         bits/sec.
-
-config FT_ALPHA_CLOCK
-       int "CPU clock frequency of your DEC Alpha" if ALPHA
-       depends on FTAPE
-       default "0"
-       help
-         On some DEC Alpha machines the CPU clock frequency cannot be
-         determined automatically, so you need to specify it here ONLY if
-         running a DEC Alpha, otherwise this setting has no effect.
-
diff --git a/drivers/char/ftape/Makefile b/drivers/char/ftape/Makefile
deleted file mode 100644 (file)
index 0e67d2f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-#       Copyright (C) 1997 Claus Heine.
-#
-# This program 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, 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; see the file COPYING.  If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/Makefile,v $
-# $Revision: 1.4 $
-# $Date: 1997/10/05 19:17:56 $
-#
-#      Makefile for the QIC-40/80/3010/3020 floppy-tape driver for
-#      Linux.
-#
-
-obj-$(CONFIG_FTAPE)            += lowlevel/
-obj-$(CONFIG_ZFTAPE)           += zftape/
-obj-$(CONFIG_ZFT_COMPRESSOR)   += compressor/
diff --git a/drivers/char/ftape/README.PCI b/drivers/char/ftape/README.PCI
deleted file mode 100644 (file)
index 18de159..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-Some notes for ftape users with PCI motherboards:
-=================================================
-
-The problem:
-------------
-
-There have been some problem reports from people using PCI-bus based
-systems getting overrun errors.
-I wasn't able to reproduce these until I ran ftape on a Intel Plato
-(Premiere PCI II) motherboard with bios version 1.00.08AX1.
-It turned out that if GAT (Guaranteed Access Timing) is enabled (?)
-ftape gets a lot of overrun errors.
-The problem disappears when disabling GAT in the bios.
-Note that Intel removed this setting (permanently disabled) from the
-1.00.10AX1 bios !
-
-It looks like that if GAT is enabled there are often large periods
-(greater than 120 us !??) on the ISA bus that the DMA controller cannot
-service the floppy disk controller.
-I cannot imagine this being acceptable in a decent PCI implementation.
-Maybe this is a `feature' of the chipset. I can only speculate why
-Intel choose to remove the option from the latest Bios...
-
-The lesson of this all is that there may be other motherboard
-implementations having the same of similar problems.
-If you experience a lot of overrun errors during a backup to tape,
-see if there is some setting in the Bios that may influence the
-bus timing.
-
-I judge this a hardware problem and not a limitation of ftape ;-)
-My DOS backup software seems to be suffering from the same problems
-and even refuses to run at 1 Mbps !
-Ftape will reduce the data-rate from 1 Mbps to 500 Kbps if the number
-of overrun errors on a track exceeds a threshold.
-
-
-Possible solutions:
--------------------
-
-Some of the problems were solved by upgrading the (flash) bios.
-Other suggest that it has to do with the FDC being on the PCI
-bus, but that is not the case with the Intel Premiere II boards.
-[If upgrading the bios doesn't solve the problem you could try
-a floppy disk controller on the isa-bus].
-
-Here is a list of systems and recommended BIOS settings:
-
-
-        Intel Premiere PCI (Revenge):
-
-Bios version 1.00.09.AF2 is reported to work.
-
-
-
-        Intel Premiere PCI II (Plato):
-
-Bios version 1.00.10.AX1 and version 11 beta are ok.
-If using version 1.00.08.AX1, GAT must be disabled !
-
-
-
-        ASUS PCI/I-SP3G:
-
-Preferred settings:     ISA-GAT-mode : disabled
-                        DMA-linebuffer-mode : standard
-                        ISA-masterbuffer-mode : standard
-
-
-        DELL Dimension XPS P90
-
-Bios version A2 is reported to be broken, while bios version A5 works.
-You can get a flash bios upgrade from http://www.dell.com
-
-
-To see if you're having the GAT problem, try making a backup
-under DOS. If it's very slow and often repositions you're
-probably having this problem.
-
-                        --//--
- LocalWords:  ftape PCI bios GAT ISA DMA chipset Mbps Kbps FDC isa AF ok ASUS
- LocalWords:  SP linebuffer masterbuffer XPS http www com
diff --git a/drivers/char/ftape/RELEASE-NOTES b/drivers/char/ftape/RELEASE-NOTES
deleted file mode 100644 (file)
index 03799db..0000000
+++ /dev/null
@@ -1,966 +0,0 @@
-Hey, Emacs, we're -*-Text-*- mode!
-
-===== Release notes for ftape-3.04d 25/11/97 =====
-- The correct pre-processor statement for "else if" is "#elif" not
-  "elsif".
-- Need to call zft_reset_position() when overwriting cartridges
-  previously written with ftape-2.x, sftape, or ancient
-  (pre-ftape-3.x) versions of zftape.
-
-===== Release notes for ftape-3.04c 16/11/97 =====
-- fdc_probe() was calling DUMPREGS with a result length of "1" which
-  was just fine. Undo previous change.
-
-===== Release notes for ftape-3.04b 14/11/97 =====
-
-- patches/2.x.x/floppy.c.diff was somewhat broken, releasing i/o
-  regions it never had allocated.
-- fdc_probe() was calling DUMPREGS with a result length of "1" instead
-  of "10"
-- Writing deleted data marks if the first segents on track zero are
-  should work now.
-- ftformat should now be able to handle those cases where the tape
-  drive sets the read only status bit (QIC-40/80 cartridges with
-  QIC-3010/3020 tape drives) because the header segment is damaged.
-- the MTIOCFTCMD ioctl may now be issued by the superuser ONLY.
-
-===== Release notes for ftape-3.04a 12/11/97 =====
-- Fix an "infinite loop can't be killed by signal" bug in
-  ftape_get_drive_status(). Only relevant when trying to access
-  buggy/misconfigured hardware
-- Try to compensate a bug in the HP Colorado T3000's firmware: it
-  doesn't set the write protect bit for QIC80/QIC40 cartridges.
-
-===== Release notes for ftape-3.04 06/11/97 =====
-- If positioning with fast seeking fails fall back to a slow seek
-  before giving up.
-- (nearly) no retries on "no data errors" when verifying after
-  formatting. Improved tuning of the bad sector map after formatting.
-- the directory layout has changed again to allow for easier kernel
-  integration
-- Module parameter "ftape_tracing" now is called "ft_tracing" because
-  the "ftape_tracing" variable has the version checksum attached to it.
-- `/proc/ftape' interface for 2.0.* kernels. `/proc/ftape' no longer
-  is a directory but a file that contains all the information formerly
-  provided in separate files under the `/proc/ftape/' directory.
-- Most of the configuration options have been prefixed by "CONFIG_FT_"
-  in preparation of the kernel inclusion. The Makefiles under
-  "./ftape/" should be directly usable by the kernel.
-- The MODVERSIONS stuff is now auto-detected.
-- Broke backslashed multi line options in MCONFIG into separate lines
-  using GNU-make's "+=" feature.
-- The html and dvi version of the manual is now installed under
-  '/usr/doc/ftape` with 'make install`
-- New SMP define in MCONFIG. ftape works with SMP if this is defined.
-- attempt to cope with "excessive overrun errors" by gradually
-  increasing FDC FIFO threshold. But this doesn't seem to have too
-  much an effect.
-- New load time configuration parameter "ft_fdc_rate_limit". If you
-  encounter too many overrun errors with a 2Mb controller then you
-  might want to set this to 1000.
-- overrun errors on the last sector in a segment sometimes result in
-  a zero DMA residue. Dunno why, but compensate for it.
-- there were still fdc_read() timeout errors. I think I have fixed it
-  now, please FIXME.
-- Sometimes ftape_write() failed to re-start the tape drive when a
-  segment without a good sector was reached ("wait for empty segment
-  failed"). This is fixed. Especially important for > QIC-3010.
-- sftape (aka ftape-2.x) has vanished. I didn't work on it for
-  ages. It is probably still possible to use the old code with
-  ftape-3.04, if one really needs it (BUT RECOMPILE IT)
-- zftape no longer alters the contents of already existing volume
-  table entries, which makes it possible to fill in missing fields,
-  like time stamps using some user space program.
-- ./contrib/vtblc/ contains such a program.
-- new perl script ./contrib/scripts/listtape that list the contents of a
-  floppy tape cartridge parsing the output of "mt volinfo" + "mt fsf"
-- the MTWEOF implementation has changed a little bit (after I had a
-  look at amanda). Calling MTWEOF while the tape is still held open
-  after writing something to the tape now will terminate the current
-  volume, and start a new one at the current position.
-- the volume table maintained by zftape now is a doubly linked list
-  that grows dynamically as needed.
-
-  formatting floppy tape cartridges
-  ---------------------------------
-  * there is a new user space formatting program that does most of the
-    dirty work in user space (auto-detect, computing the sector
-    coordinates, adjusting time stamps and statistics). It has a
-    simple command line interface.
-  * ftape-format.o has vanished, it has been folded into the low level
-    ftape.o module, and the ioctl interface into zftape.o. Most of the
-    complicated stuff has been moved to user space, so there was no
-    need for a separate module anymore.
-  * there is a new ioctl MTIOCFTCMD that sends a bare QIC-117 command
-    to the tape drive.
-  * there is a new mmap() feature to map the dma buffers into user
-    space to be used by the user level formatting program.
-  * Formatting of yet unformatted or totally degaussed cartridges
-    should be possible now. FIXME.
-
-===== Release notes for ftape-3.03b, <forgot the exact date> ====
-
-ftape-3.03b was released as a beta release only. Its main new feature
-was support of the DITTO-2GB drive. This was made possible by reverse
-engineering done by <fill in his name> after Iomega failed to support
-ftape. Although they had promised to do so (this makes me feel a bit
-sad and uncomfortable about Iomega).
-
-===== Release notes for ftape-3.03a, 22/05/97 ====
-
-- Finally fixed auto-un-loading of modules for kernels > 2.1.18
-- Add an "uninstall" target to the Makefile
-- removed the kdtime hack
-- texi2www didn't properly set the back-reference from a footnote back
-  to the regular text.
-
-  zftape specific
-  ---------------
-  * hide the old compression map volume. Taper doesn't accept the
-    presence of non-Taper volumes and Taper-written volume on the same
-    tape.
-  * EOD (End Of Data) handling was still broken: the expected behavior
-    is to return a zero byte count at the first attempt to read past
-    EOD, return a zero byte count at the second attempt to read past
-    EOD and THEN return -EIO.
-  
-  ftape-format specific
-  ---------------------
-  * Detection of QIC-40 cartridges in select_tape_format() was broken
-    and made it impossible to format QIC-3010/3020 cartridges.
-  * There are strange "TR-1 Extra" cartridges out there which weren't
-    detected properly because the don't strictly conform to the
-    QIC-80, Rev. N, spec.
-
-===== Release notes for ftape-3.03, 30/04/97 =====
-
-- Removed kernel integration code from the package. I plan to provide
-  a package that can be integrated into the stock kernel separately
-  (hopefully soon).
-  As a result, a simple `make' command now will build everything.
-- ALL compile time configuration options have been moved to the file
-  `MCONFIG'.
-- Quite a few `low level' changes to allow formatting of cartridges.
-- formatting is implemented as a separate module `ftape-format.o'. The
-  modified `mt' program contains sample code that shows how to use it.
-- The VFS interface has been moved from the `ftape.o' module to the
-  high level modules `zftape.o' resp. `sftape.o'. `ftape.o' contains
-  the hardware support only.
-- A bit of /proc support for kernels > 2.1.28
-- Moved documentation to Doc subdir. INSTALL now contains some real
-  installation notes.
-- `install' target in Makefile.
-
-zftape specific:
-----------------
-
-- zftape works for large cartridges now ( > 2^31 bytes)
-- MTIOCVOLINFO and MTIOCGETSIZE now return the size in KILOBYTES,
-  NO LONGER in bytes.
-
-- permissions for write access to a cartridge have changed:
-  * zftape now also takes the file access mode into account
-  * zftape no longer allows writing in the middle of the recorded
-    media. The tape has to be positioned at BOT or EOD for write
-    access.
-
-- MTBSF has changed. It used to position at the beginning of the
-  previous file when called with count 1. This was different from the
-  expected behavior for other Un*x tape drivers (i.e. SCSI). MTBSF
-  with count 1 should merely position at the beginning of the current
-  volume. Fixed. As a result, `tar --verify' now produces the desired
-  result: it verifies the last written volume, not the pre-last
-  written volume.
-
-- The compression map has vanished --> no need for `mt erase' any
-  more. Fast seeking in a compressed volume is still be possible, but
-  takes slightly longer. As a side effect, you may experience an
-  additional volume showing up in front of all others for old
-  cartridges. This is the tape volume that holds the compression map.
-
-- The compression support for zftape has been moved to a separate
-  module `zft-compressor'. DON'T forget to load it before trying to
-  read back compressed volumes. The stock `zftape.o' module probes for
-  the module `zft-compressor' using the kerneld message channel; you
-  have to install `zft-compressor.o' in a place where modprobe can
-  find it if you want to use this.
-
-- New experimental feature that tries to get the broken down GMT time
-  from user space via a kernel daemon message channel. You need to
-  compile and start the `kdtime' daemon contained in the contrib
-  directory to use it. Needed (?) for time stamps in the header
-  segments and the volume table.
-
-- variable block size mode via MTSETBLK 0
-
-- keep modules locked in memory after the block size has been changed
-
-sftape specific:
-----------------
-
-- end of tape handling should be fixed, i.e. multi volume archives
-  written with `afio' can be read back now.
-
-
-===== Release notes for ftape-3.02a, 09/01/97 =====
-
-No big news:
-- call zft_init() resp. sft_init() when compiling the entire stuff
-  into the kernel image.
-- fix bug in ftape-setup.c when NO_TRACE_AT_ALL was defined.
-- fix bug in sftape-eof.c/zftape-eof.c for old kernels (1.2.*)
-- add support for new module interface for recent kernels
-
-===== Release notes for ftape-3.02, 16/12/96 =====
-- Fixed the `FDC unlock command failed' bug in fdc-io.c. When the FIFO
-  was already locked when ftape was loaded, ftape failed to unlock it.
-- Fixed compilation of `contrib/gnumt'. It now finds `mtio.h' even if
-  ftape is NOT included into the kernel source tree.
-- fc-10.c: include <asm/io.h> for inb() and outb().
-- ftape/sftape/zftape: all global variable now have either a `ftape_',
-  a `ft_', `sft_', `zft_' or `qic_' prefix to prevent name clashes
-  with other parts of the kernel when including ftape into the kernel
-  source tree.
-- Kerneld support has changed. `ftape' now searches for a module
-  `ftape-frontend' when none of the frontend (`sftape' or `zftape') is
-  loaded. Please refer to the `Installation/Loading ftape' section of
-  the TeXinfo manual.
-- Add load resp. boot-time configuration of ftape. There are now
-  variables ft_fdc_base, ft_fdc_dma and ft_fdc_irq corresponding to
-  the former FDC_BASE etc. compile time definitions. One can also use
-  the kernel command line parameters to configure the driver if it is
-  compiled into the kernel. Also, the FC-10/FC-20 support is load-time
-  configurable now as well as the MACH-II hack (ft_probe_fc10,
-  resp. ft_mach2). Please refer to the section `Installation/Configure
-  ftape' of the TeXinfo manual.
-- I removed the MODVERSIONS option from `Makefile.module'. Let me alone
-  with ftape and MODVERSIONS unless you include the ftape sources into
-  the kernel source tree.
-- new vendors in `vendors.h':
-  * HP Colorado T3000 
-  * ComByte DoublePlay (including a bug fix for their broken
-    formatting software, thanks to whraven@njackn.com)
-  * Iomega DITTO 2GIG. NOTE: this drive cannot work with ftape because
-    the logical data layout of the cartridges used by this drive does
-    NOT conform to the QIC standards, it is a special Iomega specific
-    format. I've sent mail to Iomega but didn't receive an answer
-    yet. If you want this drive to be supported by ftape, ask Iomega
-    to give me information about it.
-- zftape:
-  * re-introduced the MTIOC_ZFTAPE_GETBLKSZ ioctl for compatibility
-    with zftape 1.06a and earlier. Please don't use it when writing
-    new software, use the MTIOCVOLINFO ioctl instead.
-  * Major overhaul of the code that updates the header segments. Never
-    change the tape label unless erasing the tape. Thus we almost
-    never need to write the header segments, unless we would modify
-    the bad sector map which isn't done yet. Updating of volume table
-    and compression map more secure now although it takes a bit
-    longer.
-  * Fixed bug when aborting a write operation with a signal: zftape
-    now finishes the current volume (i.e. writes an eof marker) at the
-    current position. It didn't before which led to somehow *strange*
-    behavior in this cases.
-  * Keep module locked in memory when using it with  the non-rewinding
-    devices and the tape is not logical at BOT. Needed for kerneld
-    support.
-- sftape:
-  * Keep module locked in memory when using it with  the non-rewinding
-    devices and the tape is not logical at BOT. Needed for kerneld
-    support.
-
-===== Release notes for ftape-3.01, 14/11/96 =====
-
-- Fixed silly bugs in ftape-3.00:
-  * MAKEDEV.ftape: major device number must be 27, not 23 
-  * sftape/sftape-read.c: sftape_read_header_segments() called 
-    itself recursively instead of calling ftape_read_header_segment()
-  * zftape/qic-vtbl.h: conversion of ftape's file marks to zftape's
-    internal volume table was broken.
-  * patches/2.x.x/linux-2.0.21.dif: my RCS (resp. CVS) system replaced
-    the `$Revison:' etc. macros in the `ftape.h' concerning part of the
-    patch :-( Fixed.
-  * info/ftape.info: Fixed misspellings (`cp' <-> `cp -r' etc.)
-  * when ftape/sftape or ftape/zftape was compiled into the kernel the
-    variable ftape_status was declared twice. Fixed.
-  * removed reference to undeclared variable kernel_version when not
-    compiling as module
-  * fixed a bug introduced by the use of bit-fields for some flags
-    (i.e. write_protected, no_cartridge, formatted)
-  * flag `header_read' is now reset correctly to zero when tape is
-    removed.
-- fixed a bug in sftape/sftape-eof.c that was already in the original
-  ftape code. MTFSF/BSF was not handled correctly when positioned
-  right before the file mark (think of tar)
-- Changed TRACE macros (following a suggestion of Marcin Dalecki) to use
-  the predefined __FUNCTION__ macro of GCC. Spares about 4k of code.
-- added new vendor id for Iomega DITTO 2GIG
-- fixed a bug already present in zftape-1.06 when aborting a write
-  with a signal: we now finish the current volume at that
-  position. Header segments remain NOT up to date until an explicit call
-  to MTREW or MTOFFL is done.  
-
-===== Release notes for ftape-3.00, 14/10/96 =====
-
-- Merged ftape with zftape. There are three modules now:
-  ftape for the hardware support, sftape for the implementation of the
-  original ftape eof mark stuff and zftape that implements zftape's way
-  of handling things (compression, volume table, tape blocks of
-  constant length)
-- Documentation in TeXinfo format in the `info' subdirectory.
-- New ioctls for zftape. See zftape/zftape.h
-- Dummy formatting ioctl for ftape. See ftape.h
-- Kernel patch files for the 2.*.* series to include ftape-3.00 in the
-  kernel source tree. These includes a kernel compatible Config.in
-  script and fairly large online information for the kernel configure
-  script.
-- Support for compiling with Linux-1.2.13. 
-- Modified GNU mt from their cpio package that can handle the new
-  ioctls.
-- ftape/sftape/zftape is kerneld save now!
-
-Notes on sftape:
-- sftape implements the eof handling code of the original ftape. If
-  you like to stick with the original ftape stuff, you have to use
-  this module, not zftape.
-- sftape is kerneld save, unlike the original ftape.
-- we keep the entire header segment now in memory, so no need to read
-  it before updating the header segments. Additional memory
-  consumption: 256 bytes. 
-
-Notes for zftape:
-- zftape has support for tapes with format code 6 now, which use a
-  slightly different volume table format compared with other floppy
-  tapes.
-- new ioctls for zftape. Have a look at zftape/zftape.h
-- The internal volume table representation has changed for zftape. Old
-  cartridges are converted automatically.
-- zftape no longer uses compression map segments, which have vanished
-  from the QIC specs, but creates volume table entry that reserves
-  enough space for the compression map. 
-- zftape is kerneld save now.
-- we keep the entire header segment now in memory, so no need to read
-  it before updating the header segments. Additional memory
-  consumption: 256 bytes. 
-
-Notes for contrib/gnumt:
-- modified mt from the GNU cpio package that supports all the new
-  ioctls of zftape.
-Notes for contrib/swapout:
-- This contains the swapout.c program that was written by Kai
-  Harrekilde-Pederson. I simply added a Makefile.
-
-===== Release notes for ftape-2.10, 14/10/96 =====
-
-The ftape maintainer has changed. 
-Kai Harrekilde-Petersen <khp@dolphinics.no>
-has resigned from maintaining ftape, and I,
-Claus-Justus Heine <claus@momo.math.rwth-aachen.de>,
-have taken over.
-
-- Added support for tapes with `format code 6', i.e. QIC-3020 tapes
-  with more than 2^16 segments.
-- merged changes made by Bas Laarhoven with ftape-2.09. Refer
-  to his release notes below. I've included them into this
-  file unchanged for your reference.
-- disabled call stack back trace for now. This new feature
-  introduced by the interim release 2.0.x still seems to
-  be buggy.
-- Tried to minimize differences between the ftape version
-  to be included into the kernel source tree and the standalone
-  module version.
-- Reintroduced support for Linux-1.2.13. Please refer to the
-  Install-guide. 
-
-===== Release notes for ftape-2.09, 16/06/96 =====
-
-There aren't any really big news in this release, mostly just that I
-(the maintainer) have changed my email address (due to a new job).  My
-new address is <khp@dolphinics.no>
-
-- The CLK_48MHZ and FDC_82078SL options has gone (all 2Mbps cards seem
-  to use a 48MHz oscillator anyway and I haven't heard of an 'SL
-  chip out there).
-- The S82078B has been `downgraded' to i82077AA compability.
-- TESTING option revived.  Right now, it'll enable the (seriously broken)
-  2Mbps code.  If you enable it, you'll experience a tape drive that's
-  *really* out to lunch!
-- Some (bold) changes in the init code.  Please notify me if they
-  break things for you.
-
-===== Release notes for ftape-2.08, 14/03/96 =====
-
-If you correct a problem with ftape, please send your patch to
-khp@dolphinics.no too.
-
-- Updated to reflect that NR_MEM_LISTS is gone in 1.3.74
-- Teac 700 added to list of known drives.
-- The registered device name is now "ft" rather than "ftape".
-
-===== Release notes for ftape-2.07a, 14/03/96 =====
-
-Bugfixes by Marcin Dalecki <dalecki@namu03.gwdg.de>:
-- In the last release it just compiled against 1.3.70;
-  now the params to request_irq() and free_irq are() are fixed, so it also 
-  works in 1.3.73 :-)
-- Support for modules is now correct for newer kernels.
-
-===== Release notes for ftape-2.07, 04/03/96 =====
-
-
-- ftape updated to compile against 1.3.70.
-- Iomega 700 and Wangtek 3200 recognised.
-
-
-===== Release notes for ftape-2.06b, 13/02/96 =====
-
-Another simple bugfix version.
-
-- Jumbo 700 recognised.
-- Typo in vendors.h fixed.
-
-
-===== Release notes for ftape-2.06a, 10/02/96 =====
-
-This release is a simple bugfix version.
-
-- Linux/SMP: ftape *should* work.
-- FC-10/20: Only accepts IRQs 3-7, or 9.  If IRQ 9, properly tell the card
-  to use IRQ 2.  Thanks to Greg Crider (gcrider@iclnet.org) for finding and
-  locating this bug and testing the patch.
-- Insight drive recognised correctly again.
-- Motor-on wakeup version of the Iomega 250 drive added
-
-
-===== Release notes for ftape-2.06, 28/01/96 =====
-
-Special thanks go to Neal Friedman and Steven Sorbom for their
-help in producing and testing this release.
-
-I have continued to clean up the code, with an eye towards inclusion
-of ftape in Linus' official kernel (In fact, as I type this, I am
-running on a kernel with ftape support statically linked).  I have
-test-compiled ftape against my 1.2.13 tree without problems.
-Hopefully, everything should be OK for the v1.2.x people.
-
-WARNING! Alan Cox has mailed me that ftape does *NOT* work with
-Linux/SMP.  If you try to run ftape under Linux/SMP, it will cause a
-kernel deadlock (which is worse than a panic).
-
-- QIC-3020/TR-3: 1Mbps support works.  Neal is capable of reading and
-  writing data to a tape.  ftape will automatically detect the type of
-  tape (e.g. TR-3 vs QIC-80) and move the fdc in and out of
-  "perpendicular mode" as necessary.
-- 2Mbps support is disabled by default, since it is not fully
-  debugged.  If you are adventurous, remove -DFDC_82078SL in the
-  Makefile and see what happens :-)
-- fdc detection: silly bugs removed (Only 2Mbps fdcs were affected)
-  and added detection of the National Semiconductors PC8744 fdc chip
-  (used in the PC873xx "super-IO" chips).
-- Removed warning about incompatible types when compiling with Linux
-  1.2.x.
-- README.PCI updated with info about the DELL Dimension XPS P90.
-- Connor TST3200R added to detected drives.
-- `swapout' utility added to distribution.  It will dirty 5Meg of
-  memory, trying to swap out other programs.  Just say `make swapout'
-  to build it.  ftape will do this automatically Real Soon Now (ie:
-  when I have found out which kernel memory alloc function to call).
-
-
-===== Release notes for ftape-2.05, 08/01/96 =====
-
-- For v1.2.x Kernels, you must apply the patch linux-1.2/ksyms.patch to
-  the kernel and rebuild it (it adds the __get_dma_pages symbol to
-  ksyms.c).
-- Included new asm-i386/io.h file from v1.3.x kernel series, to enable
-  gcc v.2.7.[12] to compile v1.2.x kernels (linux-1.2/io.h).
-- Module versions: If you wish to compile ftape as a versioned module,
-  you must first compile your kernel with CONFIG_MODVERSIONS=y.
-  Otherwise, you will get complaints that <linux/modversions.h> does not
-  exist (if that happens, a `touch modversions.h' will help you out).
-- CLK_48MHZ: new define in the Makefile (default: non-zero).  If you have
-  a tape controller card that uses the i82078(-1) chip, but cannot get
-  it to work with ftape, try set it to 0 (and please report this).
-- QIC-3010/3020: Complete support is still missing, but will hopefully
-  come soon.  Steven Sorbom has kindly provided me with hints about
-  this.  Writing of QIC-3020 tapes definitely does NOT work (do not try
-  it! - the drive will not be in "perpendicular mode" and this will ruin
-  the formatting info on the tape).
-- ftape_num_buffers is out of fashion: use NR_BUFFERS instead (and
-  recompile if you want to change it :-).
-
-
-===== Release notes for ftape-2.04, 01/01/96 =====
-
-This version by Kai Harrekilde-Petersen <khp@dolphinics.no>
-
-- ALERT! Support for Kernels earlier then v1.1.85 is about to go away.
-  I intend to clean up some of the code (getting rid of an annoyingly
-  large numbers of #ifdef mostly), which means that support for
-  pre-1.1.85 kernels must go as well.
-- NR_FTAPE_BUFFERS is gone; You can instead select the number of dma
-  buffers by saying `insmod ftape.o ftape_num_buffer=<n>' instead.
-- Configure script gone.  ftape will now automagically determine your
-  kernel version by /usr/include/linux/version.h instead.
-- CONFIG_MODVERSIONS now work.  All combinations of versioned /
-  unversioned kernel and ftape module works (at least with my 1.3.52
-  kernel).
-- If you have problems with inserting ftape into an old (1.2.x)
-  kernel (e.g. insmod says "1.2.8 does not match 1.2.8), recompile
-  your modules utilities with your new compiler.
-- Reveal TB1400 drive added to vendors.h
-- Support for the i82078-1 (2Mbps) chip is coming along.  The
-  biggest problem is that I don't have such a card, which makes
-  testing / debugging somewhat problematic.  The second biggest
-  problem is that I do not have the QIC-3010/3020 standards either.
-  Status right now is that the chip is detected, and it should be
-  possible to put it into 2Mbps mode.  However, I do not know what
-  "extras" are needed to complete the support.  Although putting the
-  i82078 into 1Mbps mode ought to work out of the box, it doesn't
-  (right now, ftape complains about id am errors).
-
-
-===== Release notes for ftape-2.04beta5, 29/12/95 =====
-
-Bas offline linux-tape
-----------------------
-For reasons only known to the majordomo mail list processor, Bas was
-kicked off the linux-tape list sometime during the summer.  Being
-overworked at his for-pay job, he didn't notice it much.  Instead I
-(Kai, khp@dolphinics.no) has worked on ftape to produce the 2.04(beta)
-version.
-
-zftape
-------
-Note that there exists a much improved version of ftape, written by
-Claus-Justus Heine <claus@willi.math.rwth-aachen.de> which is named
-zftape, which conforms to the QIC-80 specs on how to mark backups, and
-is capable of doing automatic compression.  However, zftape makes
-substantial changes to ftape, and I (Kai) have therefore declined to
-integrate zftape into ftape.  Hopefully, this will happen soon.
-
-CONFIG_QIC117 removed from the kernel
--------------------------------------
-The biggest change of all is that ftape now will allocate its dma
-buffers when it is inserted.  The means that the CONFIG_QIC117 option
-has disappeared from the Linux kernel as of v1.3.34.  If you have an
-earlier kernel, simply answer 'no' to the question will do the trick
-(if you get complains about __get_free_pages() missing, contact the
-linux-tape mailing list).
-
-Note that ftape-2.04beta will work equally well on kernels with and
-without `ftape support'.  The only catch is, that you will waste
-around 96-128Kb of precious DMA'able memory on a box that has ftape
-support compiled in.
-
-Now for the real changes:
-
-- FC-20 can now use DMA channels 1, 2, and 3. Thanks to Daniel
-  Cohen, catman@wpi.edu.
-- ftape no longer requires a (gigantic) 96Kb buffer to be statically
-  allocated by the kernel.
-- Added new Iomega drive (8882) to vendors.h
-- -fno-strength-reduce added to Makefile, since GCC is broken.
-- i82078-1 (2Mbps) FDC support started.
-
-
-===== Release notes for ftape-2.03b, 27/05/95 =====
-
-- Prevented verify_area to return error if called with zero length.
-- Fixed a bug in flush_buffers that caused too much padding to be
-  written when a final segment had bad sectors.
-- Increased maximum fast-seek overshoot value from 5 to 10 segments.
-- Breaking loop after 5 retries when positioning fails.
-- Fixed wrong calculation of tape length for QIC-3010 and QIC-3020
-  tapes (densities were swapped).
-- Fixed wrong calculation of overshoot on seek_forward: Wrong sign
-  of error.
-- Suppress (false) error message due to new tape loaded.
-- Added two new CMS drives (11c3 and 11c5) to vendors.h.
-
-
-===== Release notes for ftape-2.03a, 09/05/95 =====
-
-- Fixed display of old error (even if already cleared) in ftape_open.
-- Improved tape length detection, ioctls would fail for 425 ft tapes.
-  Until the tape length is calculated with data from the header
-  segment, we'll use worst-case values.
-- Clear eof_mark after rewinding ioctls.
-- Fixed wrong version message (2.03 had 2.02g id).
-- Fixed bug that caused the fdc to be reset very frequently.
-  This shouldn't affect normal operation but the timing of the
-  report routines has changed again and that may cause problems.
-  We'll just have to find out....
-- Implemented correct write precompensation setting for QIC-3010/3020.
-- Cleaned up fdc_interrupt_wait routine. Hope it still works :-)
-- Finally removed (already disabled) special eof mark handling for
-  gnu tar.
-- Changed order of get_dma_residue and disable_dma in fdc-isr.c
-  because the current order would fail on at least one system.
-  We're back to the original order again, hope (and expect) this
-  doesn't break any other system.
-
-
-===== Release notes for ftape-2.03, 07/05/95 =====
-
-(Changes refer to the first ftape-2.02 release)
-
-Support for wide and extended length tapes
-------------------------------------------
-The Conner TSM 420 and 850 drives are reported to be working.
-I haven't received any reports about other brands; the TSM 420
-and 850 seem to be the most widely used wide drives.
-Extended length tapes (425 ft) with normal QIC-80 drives
-are operating too (At least I've had no reports stating otherwise).
-_Not_ yet completely supported (although they may work) are
-QIC-3020 drives and 2 Mbps floppy disk controllers won't work at
-the highest speed.
-If someone is kind enough to send me one of these, I'll include
-support for it too ;-)
-
-Easier configuration
---------------------
-Problems due to wrong settings in the Makefile are prevented
-by using a configuration script that sets the necessary (kernel
-version dependent) compile time options.
-This kernel version is now determined from the sources found
-at /usr/src/linux, or if not found, the old way using
-/proc/version.
-Versioned modules will be used automatically when supported
-by- and configured in- the kernel.
-Note that the current modules code (1.1.87) is still broken
-and _needs_ the fix included in the insmod directory.
-Please don't send me any more Oops reports caused by insmod :-(
-
-Reduced module size
--------------------
-The standard module size is much reduced and some compile time
-options can even reduce it further. (I don't recommend this
-for normal use but it can be handy for rescue diskettes)
-
-Option:           Approx. module size:
-
-<standard>             150 Kb
-NO_TRACE               125 Kb
-NO_TRACE_AT_ALL         67 Kb
-
-
-Much improved driver interruption
----------------------------------
-Most possible loops have been broken and signal detection
-has been improved.
-In most cases the driver can be aborted by ^C (SIGINT) and
-SIGKILL (kill -9) will generate be a sure kill.
-(Note that aborting a tape operation may damage the last
-data written to tape)
-
-Improved error recovery
------------------------
-Ftape now returns an error (ENODATA) to the application if
-a segment proves to be unrecoverable and then skips the
-bad segment.
-This causes most applications to continue to work (tar
-and afio) loosing only a small amount (up to 29 Kb) of data.
-Retried read operations will now be done slightly off-track
-to improve the chance of success. Serious head off-track
-errors will be detected.
-
-FC-10 and FC-20 controllers
----------------------------
-Ftape now supports both the old CMS FC-10 and the newer FC-20
-controllers.
-Because the operation of these cards is still undocumented,
-thus far they will only work with the default settings (See
-Makefile). Any feed-back on how to use them with other settings
-will be welcome !
-Compilation will fail if one changes the settings to illegal
-values.
-
-Kernels and compilers
----------------------
-Ftape is currently being developed using the 2.5.8 compiler.
-The older 2.4.5 probably works too (Set option in Makefile!).
-I have no experience with any later compilers nor Elf support.
-Any information on this is welcome.
-The latest kernel I have tested ftape with is 1.2.6.
-
-Compression
------------
-An impressive collection of changes for ftape including
-on-the-fly compression is still lying on my desk.
-If 2.03 proves to be reliable I might start integrating these
-but as usual, I'm short in time :-(
-
-Formatting
-----------
-There is still no way to format tapes under Linux. As far as
-I know all attempts to write such a program have died now.
-Since formatted tapes are rather common now, I think all we
-need is a utility that writes a worst case pattern and verifies
-that with the drive put in verify mode, reducing margins.
-Any takers ?
-
-Furthermore
------------
-Cleaned up messages.
-Prepared to support multiple tape drives on one fdc.
-Thanks to all the people who sent bug reports and helped me
-improve the driver. Without trying to be complete I'll mention
-Gary Anderson (without his accurate reports and unreliable
-hardware there wouldn't be a 2.03), Stefan Kneifel (FC-20),
-Robert Broughton (FC-20, you were almost there ;-), Bjorn
-Ekwall (for the versioned modules and buggy insmod ;-), Peter
-Fox, Christopher Oliver, Ralph Whittaker and not the least
-Linus Torvalds (for Linux and keeping me busy because of
-changes to the kernel ;-)
-Thanks to anyone I forgot, for the bug reports, the ftape
-bashing and the mental support...
-
-
-That's it for now. Have Fun,
-
-Bas.
-
-
-===== Release notes for ftape-2.02g, 06/05/95 =====
-
-- Added extra test to break read-id loop with signal.
-- Changed rewind code to handle negative overshoot for drives
-  that take very long to start or stop.
-- Let use of get/set i/o-regions depend on kernel version.
-- Changed code to use a more general test for conditional
-  compilations depending on kernel version.
-- Improved micro-step functionality to go off-track only
-  while reading (id & data).
-- Added failure on tape-not-referenced bit in ftape_command.
-- Added FOREVER option to read-wait routine.
-- Changed read-id to use shorter timeout causing smaller
-  rewinds on timeout.
-- Made kernel-interface functions static.
-
-
-===== Release notes for ftape-2.02f, 03/05/95 =====
-
-- Added support for dual tape drives on my system, extended Configure
-  script to detect host 'dodo'.
-- Log media defect in history if ecc failed and no data was returned.
-- Fixed Configure script that was failing for kernel versions with
-  double digit version or revision numbers.
-
-
-===== Release notes for ftape-2.02e, 01/05/95 =====
-
-- Fixed reposition loop at logical eot (failing read_id).
-- Fixed 34 segment offset when rewinding.
-- Added fast seek capability for more than 255 segments.
-- Fixed wrong busy result from ftape_command causing reverse
-  seek to fail.
-- Added breakout from infinite rewind loop (if something fails).
-
-
-===== Release notes for ftape-2.02d, 30/04/95 =====
-
-- Improved abortion on signals: Interrupt will make a graceful
-  exit, Kill will be less nice and should be used if everything
-  else fails.
-- Included check for tape-head off track.
-- Implemented exit from tape-start loop.
-- Added kernel io-port registration.
-- Implemented skip of failing segment (ENODATA) on ecc failure.
-  This allows afio and tar to continue when the tape is damaged.
-- Made distinction between drive names with different codes.
-
-
-===== Release notes for ftape-2.02c, 22/04/95 =====
-
-- Fixed too tight command queueing after tape stop/pause command
-  issued from within interrupt service routine (Showed as timeout
-  on Acknowledge errors during retries on some systems)
-- Tried to fix timeouts when using 425 ft tape because the extended
-  length doesn't seem to be detected by the hardware.
-  We now use the format code from the header segment so adjust the
-  timing after reading the header segment.
-- Fixed some messages stating 'unexpected something...' being not
-  unexpected anymore.
-- Started preparations for merge of dynamic buffer allocation and
-  compression code.
-- Changed some debug messages to include relevant segment information
-  at level 4.
-- Included early bail-out when drive offline, preventing a lot of
-  false messages.
-- Moved ftape_parameter_xxx() offsets into function instead of in calls.
-- Removed 'weird, drive busy but no data' error when caused by
-  an error during a read-id.
-- Improved 'timeout on acknowledge' diagnostics.
-- Moved MODULE option into Configure.
-- Reduced code size when no tracing at all was set (Claus Heine).
-- No longer log error code 0 (no error) as an error.
-
-
-===== Release notes for ftape-2.02b, 09/04/95 =====
-
-- Relaxed timing for status operation and displaying
-  abnormal results. Hopefully this shows what's going
-  wrong with the Conner TSM850R drives.
-- Created script for configuration, using version number
-  of kernel source if available, otherwise /proc/version.
-- Fixed conditionals in kernel-interface.c.
-- Removed unavoidable TRACE output.
-
-
-===== Release notes for ftape-2.02a, 01/04/95 =====
-
-- Implemented `new-style' (versioned) modules support for new
-  kernels.
-- Reduced size of module by moving static data to bss.
-- Now using version number of kernel source instead of running
-  kernel for kernel versions >= 1.1.82
-- Added feedback on drive speeds to vendor information.
-- Included fixed insmod sources to distribution (Let's hope
-  the modules distribution get fixed soon :-/).
-
-Note that I haven't yet implemented any of the code extension I
-received. I hope to find some time to do this soon.
-
-
-===== Release notes for ftape-2.02, 15/01/95 =====
-
-
-- Fixed failing repositioning when overshoot was incremented.
-- Fixed rate selection: Because of a deficiency in the QIC-117
-  specification one cannot distinguish between a not implemented
-  and a failing command. Therefor we now try to find out if the
-  drive does support this command before usage.
-- Fixed error retry using wrong offset in fdc-isr.
-- Improved retry code to retry only once on a single no-data
-  error in a segment.
-- Validate sector number extracted from eof mark because an
-  invalid file mark (due to ???) could cause kernel panic.
-- Split ftape-io.c into ftape-io.c and ftape-ctl.c files.
-- Corrected too high media error count after writing to
-  a bad tape.
-- Added #include <asm/segment.h> again because old kernel versions
-  need it.
-- Fixed fdc not being disabled when open failed because no tape
-  drive was found.
-- Fixed problem with soft error in sector 32 (shift operator with
-  shiftcount 32 is not defined).
-
-
-===== Release notes for ftape-2.01, 08/01/95 =====
-
-
-- Removed TESTING setting from distributed Makefile.
-- Fixed `mt asf' failure: Rewind was deferred to close which
-  overruled the fsf ioctl.
-- Prevented non-interruptible commands being interrupted.
-- Added missing timeout.pause setting.
-- Maximum tape speed read from drive type information table.
-  If the information is not in the table (0) the drive will
-  determine the speed itself and put a message in the logfile.
-  This information should then be added to the table in the
-  vendors.h file (and reported to me).
-- Added call to ftape_init_drive after soft reset for those
-  (antique) drives that don't do an implicit seek_load_point
-  after a reset or power up.
-- Don't try to set data rate if reset failed.
-- Prevent update of seek variables when starting from the
-  beginning or the end of the tape.
-- Fixed wrong adjustment of overshoot in seek_forward().
-- Added sync to Makefile (again).
-- Added code to diagnose timer problems (calibr.c).
-- Replaced time differences by timediff calls.
-- Removed reference to do_floppy from object for recent kernels.
-- Fixed wrong display of 'failing dma controller' message.
-- Removed various no longer used #include statements.
-- Added max. tape speed value to vendor-struct.
-- Changed ftape-command to check pre-conditions and wait
-  if needed.
-- Further updated qic117.h to rev G.
-- Combined command name table and restrictions table to one.
-  Extended this table with some new fields.
-- Increased timeout on Ack timer value and included code to
-  report out of spec behaviour.
-- Increased rewind timeout margin to calculated + 20%.
-- Improved data rate selection so it won't fail on some
-  older (pre standard) drives.
-- Changed initialisation code so drive will be rewound if the
-  driver is reloaded and the tape is not at bot.
-- Moved some of the flush operations from close to the ioctls.
-- Added exit code value to failing verify area message.
-- Loop until tape halted in smart-stop.
-- Fast seek handled specially if located at bot or eot.
-- Being more conservative on overshoot value.
-
-
-===== Release notes for ftape-2.00, 31/12/94 =====
-
-  The Install-guide is completely rewritten and now also includes
-some information on how to use the driver. If you're either new
-to ftape or new to Unix tape devices make sure to read it !
-
-  If you own a pci system and experience problems with the
-ftape driver make sure to read the README.PCI file. It contains
-some hints on how to fix your hardware.
-
-  For anybody who hasn't noticed: The version number of the
-driver has been incremented (The latest released version has
-been version 1.14d).
-  This has been done for two major reasons:
-
-  o  A new (better) error recovery scheme is implemented.
-  o  Support for new drive types has been added.
-
-  All these improvements/changes will probably include a couple
-of new (and old?) bugs. If you encounter any problems that you think
-I'm not yet aware of, feel free to send a report to <bas@vimec.nl>.
-  I recommend keeping a version of ftape-1.14d available, just
-in case ;-)
-
-  This version should work with all kernel versions from 1.0.9 up
-to 1.1.72 (and probably earlier and later versions too).
-
-
-Major new features:
-
-- Better handling of tapes with defects: When a sector repeatedly
-  (SOFT_RETRIES in ftape.h) cannot be written to or read from it is
-  marked as an hard error and gets skipped.
-  The error correction code can handle up to three of these hard
-  errors provided there are no other errors in that segment (32 Kb).
-  
-- Allows writing to tapes with defects (although the risk of loosing
-  data increases !)
-  Look for the media-defects entry printed with the statistics when
-  the tape is closed. A non-zero value here shows a bad tape.
-  [the actual count is wrong (too high), this is a known bug].
-
-- Use of backup header segment if first one is failing.
-
-- Support for extended length tapes with QIC-80: both 425 and 1100 ft.
-  0.25 inch tapes are now recognized and handled.
-
-- Support for new QIC-80 drives with 8 mm `wide' tapes (e.g. Conner
-  TSM 420).
-
-- Support for new QIC-3010 and QIC-3020 drives (experimental) with
-  both 0.25 inch and 8 mm tapes.
-
-Some minor features were added, a couple of small bugs were fixed and
-probably some new ones introduced ;-).
-
-[lseek() didn't make it into this version]
-
-Have fun,
-
-Bas.
-----
- LocalWords:  ftape MCONFIG mt VFS zftape resp sftape proc subdir MTIOCVOLINFO
- LocalWords:  MTIOCGETSIZE BOT EOD MTBSF zft kerneld modprobe kdtime contrib TR
- LocalWords:  MTSETBLK afio uninstall texi www EIO QIC init sft eof aka dma GB
- LocalWords:  SIGKILL MTIOCFTCMD mmap Iomega FDC fdc io gnumt mtio fc asm inb
- LocalWords:  outb ft qic frontend TeXinfo irq mach MODVERSIONS CONFIG html dvi
- LocalWords:  usr doc SMP Mb Dunno FIXME vtblc perl listtape volinfo fsf MTWEOF
- LocalWords:  amanda degaussed ComByte DoublePlay whraven njackn com MTIOC vtbl
- LocalWords:  GETBLKSZ MAKEDEV zftape's linux dif CVS Revison cp MTREW MTOFFL
- LocalWords:  MTFSF BSF Marcin Dalecki GCC Config cpio swapout Kai Harrekilde
- LocalWords:  Pederson khp dolphinics Justus claus momo rwth aachen Laarhoven
diff --git a/drivers/char/ftape/compressor/Makefile b/drivers/char/ftape/compressor/Makefile
deleted file mode 100644 (file)
index 1fbd6c4..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-#       Copyright (C) 1997 Claus-Justus Heine.
-#
-# This program 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, 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; see the file COPYING.  If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/compressor/Makefile,v $
-# $Revision: 1.1 $
-# $Date: 1997/10/05 19:12:28 $
-#
-#      Makefile for the optional compressor for th zftape VFS
-#      interface to the QIC-40/80/3010/3020 floppy-tape driver for
-#      Linux.
-#
-
-obj-$(CONFIG_ZFT_COMPRESSOR) += zft-compressor.o
-
-zft-compressor-objs := zftape-compress.o lzrw3.o
-
-CFLAGS_lzrw3.o := -O6 -funroll-all-loops
diff --git a/drivers/char/ftape/compressor/lzrw3.c b/drivers/char/ftape/compressor/lzrw3.c
deleted file mode 100644 (file)
index a032a0e..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * $Source: /homes/cvs/ftape-stacked/ftape/compressor/lzrw3.c,v $
- * $Revision: 1.1 $
- * $Date: 1997/10/05 19:12:29 $
- *
- * Implementation of Ross Williams lzrw3 algorithm. Adaption for zftape.
- *
- */
-
-#include "../compressor/lzrw3.h"       /* Defines single exported function "compress".   */
-
-/******************************************************************************/
-/*                                                                            */
-/*                                    LZRW3.C                                 */
-/*                                                                            */
-/******************************************************************************/
-/*                                                                            */
-/* Author  : Ross Williams.                                                   */
-/* Date    : 30-Jun-1991.                                                     */
-/* Release : 1.                                                               */
-/*                                                                            */
-/******************************************************************************/
-/*                                                                            */
-/* This file contains an implementation of the LZRW3 data compression         */
-/* algorithm in C.                                                            */
-/*                                                                            */
-/* The algorithm is a general purpose compression algorithm that runs fast    */
-/* and gives reasonable compression. The algorithm is a member of the Lempel  */
-/* Ziv family of algorithms and bases its compression on the presence in the  */
-/* data of repeated substrings.                                               */
-/*                                                                            */
-/* This algorithm is unpatented and the code is public domain. As the         */
-/* algorithm is based on the LZ77 class of algorithms, it is unlikely to be   */
-/* the subject of a patent challenge.                                         */
-/*                                                                            */
-/* Unlike the LZRW1 and LZRW1-A algorithms, the LZRW3 algorithm is            */
-/* deterministic and is guaranteed to yield the same compressed               */
-/* representation for a given file each time it is run.                       */
-/*                                                                            */
-/* The LZRW3 algorithm was originally designed and implemented                */
-/* by Ross Williams on 31-Dec-1990.                                           */
-/*                                                                            */
-/* Here are the results of applying this code, compiled under THINK C 4.0     */
-/* and running on a Mac-SE (8MHz 68000), to the standard calgary corpus.      */
-/*                                                                            */
-/*    +----------------------------------------------------------------+      */
-/*    | DATA COMPRESSION TEST                                          |      */
-/*    | =====================                                          |      */
-/*    | Time of run     : Sun 30-Jun-1991 09:31PM                      |      */
-/*    | Timing accuracy : One part in 100                              |      */
-/*    | Context length  : 262144 bytes (= 256.0000K)                   |      */
-/*    | Test suite      : Calgary Corpus Suite                         |      */
-/*    | Files in suite  : 14                                           |      */
-/*    | Algorithm       : LZRW3                                        |      */
-/*    | Note: All averages are calculated from the un-rounded values.  |      */
-/*    +----------------------------------------------------------------+      */
-/*    | File Name   Length  CxB  ComLen  %Remn  Bits  Com K/s  Dec K/s |      */
-/*    | ----------  ------  ---  ------  -----  ----  -------  ------- |      */
-/*    | rpus:Bib.D  111261    1   55033   49.5  3.96    19.46    32.27 |      */
-/*    | us:Book1.D  768771    3  467962   60.9  4.87    17.03    31.07 |      */
-/*    | us:Book2.D  610856    3  317102   51.9  4.15    19.39    34.15 |      */
-/*    | rpus:Geo.D  102400    1   82424   80.5  6.44    11.65    18.18 |      */
-/*    | pus:News.D  377109    2  205670   54.5  4.36    17.14    27.47 |      */
-/*    | pus:Obj1.D   21504    1   13027   60.6  4.85    13.40    18.95 |      */
-/*    | pus:Obj2.D  246814    1  116286   47.1  3.77    19.31    30.10 |      */
-/*    | s:Paper1.D   53161    1   27522   51.8  4.14    18.60    31.15 |      */
-/*    | s:Paper2.D   82199    1   45160   54.9  4.40    18.45    32.84 |      */
-/*    | rpus:Pic.D  513216    2  122388   23.8  1.91    35.29    51.05 |      */
-/*    | us:Progc.D   39611    1   19669   49.7  3.97    18.87    30.64 |      */
-/*    | us:Progl.D   71646    1   28247   39.4  3.15    24.34    40.66 |      */
-/*    | us:Progp.D   49379    1   19377   39.2  3.14    23.91    39.23 |      */
-/*    | us:Trans.D   93695    1   33481   35.7  2.86    25.48    40.37 |      */
-/*    +----------------------------------------------------------------+      */
-/*    | Average     224401    1  110953   50.0  4.00    20.17    32.72 |      */
-/*    +----------------------------------------------------------------+      */
-/*                                                                            */
-/******************************************************************************/
-
-/******************************************************************************/
-
-/* The following structure is returned by the "compress" function below when  */
-/* the user asks the function to return identifying information.              */
-/* The most important field in the record is the working memory field which   */
-/* tells the calling program how much working memory should be passed to      */
-/* "compress" when it is called to perform a compression or decompression.    */
-/* LZRW3 uses the same amount of memory during compression and decompression. */
-/* For more information on this structure see "compress.h".                   */
-  
-#define U(X)            ((ULONG) X)
-#define SIZE_P_BYTE     (U(sizeof(UBYTE *)))
-#define SIZE_WORD       (U(sizeof(UWORD  )))
-#define ALIGNMENT_FUDGE (U(16))
-#define MEM_REQ ( U(4096)*(SIZE_P_BYTE) + ALIGNMENT_FUDGE )
-
-static struct compress_identity identity =
-{
- U(0x032DDEA8),                           /* Algorithm identification number. */
- MEM_REQ,                                 /* Working memory (bytes) required. */
- "LZRW3",                                 /* Name of algorithm.               */
- "1.0",                                   /* Version number of algorithm.     */
- "31-Dec-1990",                           /* Date of algorithm.               */
- "Public Domain",                         /* Copyright notice.                */
- "Ross N. Williams",                      /* Author of algorithm.             */
- "Renaissance Software",                  /* Affiliation of author.           */
- "Public Domain"                          /* Vendor of algorithm.             */
-};
-LOCAL void compress_compress  (UBYTE *,UBYTE *,ULONG,UBYTE *, LONG *);
-LOCAL void compress_decompress(UBYTE *,UBYTE *,LONG, UBYTE *, ULONG *);
-
-/******************************************************************************/
-
-/* This function is the only function exported by this module.                */
-/* Depending on its first parameter, the function can be requested to         */
-/* compress a block of memory, decompress a block of memory, or to identify   */
-/* itself. For more information, see the specification file "compress.h".     */
-
-EXPORT void lzrw3_compress(
-       UWORD     action,      /* Action to be performed.               */
-       UBYTE   *wrk_mem,       /* Address of working memory we can use.*/
-       UBYTE   *src_adr,       /* Address of input data.               */
-       LONG     src_len,       /* Length  of input data.               */
-       UBYTE   *dst_adr,       /* Address to put output data.          */
-       void  *p_dst_len        /* Address of longword for length of output data.*/
-)
-{
- switch (action)
-   {
-    case COMPRESS_ACTION_IDENTITY:
-       *((struct compress_identity **)p_dst_len)= &identity;
-       break;
-    case COMPRESS_ACTION_COMPRESS:
-       compress_compress(wrk_mem,src_adr,src_len,dst_adr,(LONG *)p_dst_len);
-       break;
-    case COMPRESS_ACTION_DECOMPRESS:
-       compress_decompress(wrk_mem,src_adr,src_len,dst_adr,(LONG *)p_dst_len);
-       break;
-   }
-}
-
-/******************************************************************************/
-/*                                                                            */
-/* BRIEF DESCRIPTION OF THE LZRW3 ALGORITHM                                   */
-/* ========================================                                   */
-/* The LZRW3 algorithm is identical to the LZRW1-A algorithm except that      */
-/* instead of transmitting history offsets, it transmits hash table indexes.  */
-/* In order to decode the indexes, the decompressor must maintain an          */
-/* identical hash table. Copy items are straightforward:when the decompressor */
-/* receives a copy item, it simply looks up the hash table to translate the   */
-/* index into a pointer into the data already decompressed. To update the     */
-/* hash table, it replaces the same table entry with a pointer to the start   */
-/* of the newly decoded phrase. The tricky part is with literal items, for at */
-/* the time that the decompressor receives a literal item the decompressor    */
-/* does not have the three bytes in the Ziv (that the compressor has) to      */
-/* perform the three-byte hash. To solve this problem, in LZRW3, both the     */
-/* compressor and decompressor are wired up so that they "buffer" these       */
-/* literals and update their hash tables only when three bytes are available. */
-/* This makes the maximum buffering 2 bytes.                                  */
-/*                                                                            */
-/* Replacement of offsets by hash table indexes yields a few percent extra    */
-/* compression at the cost of some speed. LZRW3 is slower than LZRW1, LZRW1-A */
-/* and LZRW2, but yields better compression.                                  */
-/*                                                                            */
-/* Extra compression could be obtained by using a hash table of depth two.    */
-/* However, increasing the depth above one incurs a significant decrease in   */
-/* compression speed which was not considered worthwhile. Another reason for  */
-/* keeping the depth down to one was to allow easy comparison with the        */
-/* LZRW1-A and LZRW2 algorithms so as to demonstrate the exact effect of the  */
-/* use of direct hash indexes.                                                */
-/*                                                                            */
-/*                                  +---+                                     */
-/*                                  |___|4095                                 */
-/*                                  |___|                                     */
-/*              +---------------------*_|<---+   /----+---\                   */
-/*              |                   |___|    +---|Hash    |                   */
-/*              |                   |___|        |Function|                   */
-/*              |                   |___|        \--------/                   */
-/*              |                   |___|0            ^                       */
-/*              |                   +---+             |                       */
-/*              |                   Hash        +-----+                       */
-/*              |                   Table       |                             */
-/*              |                              ---                            */
-/*              v                              ^^^                            */
-/*      +-------------------------------------|----------------+              */
-/*      ||||||||||||||||||||||||||||||||||||||||||||||||||||||||              */
-/*      +-------------------------------------|----------------+              */
-/*      |                                     |1......18|      |              */
-/*      |<------- Lempel=History ------------>|<--Ziv-->|      |              */
-/*      |     (=bytes already processed)      |<-Still to go-->|              */
-/*      |<-------------------- INPUT BLOCK ------------------->|              */
-/*                                                                            */
-/* The diagram above for LZRW3 looks almost identical to the diagram for      */
-/* LZRW1. The difference is that in LZRW3, the compressor transmits hash      */
-/* table indices instead of Lempel offsets. For this to work, the             */
-/* decompressor must maintain a hash table as well as the compressor and both */
-/* compressor and decompressor must "buffer" literals, as the decompressor    */
-/* cannot hash phrases commencing with a literal until another two bytes have */
-/* arrived.                                                                   */
-/*                                                                            */
-/*  LZRW3 Algorithm Execution Summary                                         */
-/*  ---------------------------------                                         */
-/*  1. Hash the first three bytes of the Ziv to yield a hash table index h.   */
-/*  2. Look up the hash table yielding history pointer p.                     */
-/*  3. Match where p points with the Ziv. If there is a match of three or     */
-/*     more bytes, code those bytes (in the Ziv) as a copy item, otherwise    */
-/*     code the next byte in the Ziv as a literal item.                       */
-/*  4. Update the hash table as possible subject to the constraint that only  */
-/*     phrases commencing three bytes back from the Ziv can be hashed and     */
-/*     entered into the hash table. (This enables the decompressor to keep    */
-/*     pace). See the description and code for more details.                  */
-/*                                                                            */
-/******************************************************************************/
-/*                                                                            */
-/*                     DEFINITION OF COMPRESSED FILE FORMAT                   */
-/*                     ====================================                   */
-/*  * A compressed file consists of a COPY FLAG followed by a REMAINDER.      */
-/*  * The copy flag CF uses up four bytes with the first byte being the       */
-/*    least significant.                                                      */
-/*  * If CF=1, then the compressed file represents the remainder of the file  */
-/*    exactly. Otherwise CF=0 and the remainder of the file consists of zero  */
-/*    or more GROUPS, each of which represents one or more bytes.             */
-/*  * Each group consists of two bytes of CONTROL information followed by     */
-/*    sixteen ITEMs except for the last group which can contain from one      */
-/*    to sixteen items.                                                       */
-/*  * An item can be either a LITERAL item or a COPY item.                    */
-/*  * Each item corresponds to a bit in the control bytes.                    */
-/*  * The first control byte corresponds to the first 8 items in the group    */
-/*    with bit 0 corresponding to the first item in the group and bit 7 to    */
-/*    the eighth item in the group.                                           */
-/*  * The second control byte corresponds to the second 8 items in the group  */
-/*    with bit 0 corresponding to the ninth item in the group and bit 7 to    */
-/*    the sixteenth item in the group.                                        */
-/*  * A zero bit in a control word means that the corresponding item is a     */
-/*    literal item. A one bit corresponds to a copy item.                     */
-/*  * A literal item consists of a single byte which represents itself.       */
-/*  * A copy item consists of two bytes that represent from 3 to 18 bytes.    */
-/*  * The first  byte in a copy item will be denoted C1.                      */
-/*  * The second byte in a copy item will be denoted C2.                      */
-/*  * Bits will be selected using square brackets.                            */
-/*    For example: C1[0..3] is the low nibble of the first control byte.      */
-/*    of copy item C1.                                                        */
-/*  * The LENGTH of a copy item is defined to be C1[0..3]+3 which is a number */
-/*    in the range [3,18].                                                    */
-/*  * The INDEX of a copy item is defined to be C1[4..7]*256+C2[0..8] which   */
-/*    is a number in the range [0,4095].                                      */
-/*  * A copy item represents the sequence of bytes                            */
-/*       text[POS-OFFSET..POS-OFFSET+LENGTH-1] where                          */
-/*          text   is the entire text of the uncompressed string.             */
-/*          POS    is the index in the text of the character following the    */
-/*                   string represented by all the items preceeding the item  */
-/*                   being defined.                                           */
-/*          OFFSET is obtained from INDEX by looking up the hash table.       */
-/*                                                                            */
-/******************************************************************************/
-
-/* The following #define defines the length of the copy flag that appears at  */
-/* the start of the compressed file. The value of four bytes was chosen       */
-/* because the fast_copy routine on my Macintosh runs faster if the source    */
-/* and destination blocks are relatively longword aligned.                    */
-/* The actual flag data appears in the first byte. The rest are zeroed so as  */
-/* to normalize the compressed representation (i.e. not non-deterministic).   */
-#define FLAG_BYTES 4
-
-/* The following #defines define the meaning of the values of the copy        */
-/* flag at the start of the compressed file.                                  */
-#define FLAG_COMPRESS 0     /* Signals that output was result of compression. */
-#define FLAG_COPY     1     /* Signals that output was simply copied over.    */
-
-/* The 68000 microprocessor (on which this algorithm was originally developed */
-/* is fussy about non-aligned arrays of words. To avoid these problems the    */
-/* following macro can be used to "waste" from 0 to 3 bytes so as to align    */
-/* the argument pointer.                                                      */
-#define ULONG_ALIGN_UP(X) ((((ULONG)X)+sizeof(ULONG)-1)&~(sizeof(ULONG)-1))
-
-
-/* The following constant defines the maximum length of an uncompressed item. */
-/* This definition must not be changed; its value is hardwired into the code. */
-/* The longest number of bytes that can be spanned by a single item is 18     */
-/* for the longest copy item.                                                 */
-#define MAX_RAW_ITEM (18)
-
-/* The following constant defines the maximum length of an uncompressed group.*/
-/* This definition must not be changed; its value is hardwired into the code. */
-/* A group contains at most 16 items which explains this definition.          */
-#define MAX_RAW_GROUP (16*MAX_RAW_ITEM)
-
-/* The following constant defines the maximum length of a compressed group.   */
-/* This definition must not be changed; its value is hardwired into the code. */
-/* A compressed group consists of two control bytes followed by up to 16      */
-/* compressed items each of which can have a maximum length of two bytes.     */
-#define MAX_CMP_GROUP (2+16*2)
-
-/* The following constant defines the number of entries in the hash table.    */
-/* This definition must not be changed; its value is hardwired into the code. */
-#define HASH_TABLE_LENGTH (4096)
-
-/* LZRW3, unlike LZRW1(-A), must initialize its hash table so as to enable    */
-/* the compressor and decompressor to stay in step maintaining identical hash */
-/* tables. In an early version of the algorithm, the tables were simply       */
-/* initialized to zero and a check for zero was included just before the      */
-/* matching code. However, this test costs time. A better solution is to      */
-/* initialize all the entries in the hash table to point to a constant        */
-/* string. The decompressor does the same. This solution requires no extra    */
-/* test. The contents of the string do not matter so long as the string is    */
-/* the same for the compressor and decompressor and contains at least         */
-/* MAX_RAW_ITEM bytes. I chose consecutive decimal digits because they do not */
-/* have white space problems (e.g. there is no chance that the compiler will  */
-/* replace more than one space by a TAB) and because they make the length of  */
-/* the string obvious by inspection.                                          */
-#define START_STRING_18 ((UBYTE *) "123456789012345678")
-
-/* In this algorithm, hash values have to be calculated at more than one      */
-/* point. The following macro neatens the code up for this.                   */
-#define HASH(PTR) \
-   (((40543*(((*(PTR))<<8)^((*((PTR)+1))<<4)^(*((PTR)+2))))>>4) & 0xFFF)
-
-/******************************************************************************/
-
-/* Input  : Hand over the required amount of working memory in p_wrk_mem.     */
-/* Input  : Specify input block using p_src_first and src_len.                */
-/* Input  : Point p_dst_first to the start of the output zone (OZ).           */
-/* Input  : Point p_dst_len to a ULONG to receive the output length.          */
-/* Input  : Input block and output zone must not overlap.                     */
-/* Output : Length of output block written to *p_dst_len.                     */
-/* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. May   */
-/* Output : write in OZ=Mem[p_dst_first..p_dst_first+src_len+MAX_CMP_GROUP-1].*/
-/* Output : Upon completion guaranteed *p_dst_len<=src_len+FLAG_BYTES.        */
-LOCAL void compress_compress(UBYTE *p_wrk_mem,
-                            UBYTE *p_src_first, ULONG  src_len,
-                            UBYTE *p_dst_first, LONG  *p_dst_len)
-{
- /* p_src and p_dst step through the source and destination blocks.           */
- register UBYTE *p_src = p_src_first;
- register UBYTE *p_dst = p_dst_first;
- /* The following variables are never modified and are used in the            */
- /* calculations that determine when the main loop terminates.                */
- UBYTE *p_src_post  = p_src_first+src_len;
- UBYTE *p_dst_post  = p_dst_first+src_len;
- UBYTE *p_src_max1  = p_src_first+src_len-MAX_RAW_ITEM;
- UBYTE *p_src_max16 = p_src_first+src_len-MAX_RAW_ITEM*16;
- /* The variables 'p_control' and 'control' are used to buffer control bits.  */
- /* Before each group is processed, the next two bytes of the output block    */
- /* are set aside for the control word for the group about to be processed.   */
- /* 'p_control' is set to point to the first byte of that word. Meanwhile,    */
- /* 'control' buffers the control bits being generated during the processing  */
- /* of the group. Instead of having a counter to keep track of how many items */
- /* have been processed (=the number of bits in the control word), at the     */
- /* start of each group, the top word of 'control' is filled with 1 bits.     */
- /* As 'control' is shifted for each item, the 1 bits in the top word are     */
- /* absorbed or destroyed. When they all run out (i.e. when the top word is   */
- /* all zero bits, we know that we are at the end of a group.                 */
-# define TOPWORD 0xFFFF0000
- UBYTE *p_control;
- register ULONG control=TOPWORD;
- /* THe variable 'hash' always points to the first element of the hash table. */
- UBYTE **hash= (UBYTE **)  ULONG_ALIGN_UP(p_wrk_mem);
- /* The following two variables represent the literal buffer. p_h1 points to  */
- /* the hash table entry corresponding to the youngest literal. p_h2 points   */
- /* to the hash table entry corresponding to the second youngest literal.     */
- /* Note: p_h1=0=>p_h2=0 because zero values denote absence of a pending      */
- /* literal. The variables are initialized to zero meaning an empty "buffer". */
- UBYTE **p_h1=NULL;
- UBYTE **p_h2=NULL;
-  
- /* To start, we write the flag bytes. Being optimistic, we set the flag to   */
- /* FLAG_COMPRESS. The remaining flag bytes are zeroed so as to keep the      */
- /* algorithm deterministic.                                                  */
- *p_dst++=FLAG_COMPRESS;
- {UWORD i; for (i=2;i<=FLAG_BYTES;i++) *p_dst++=0;}
-
- /* Reserve the first word of output as the control word for the first group. */
- /* Note: This is undone at the end if the input block is empty.              */
- p_control=p_dst; p_dst+=2;
- /* Initialize all elements of the hash table to point to a constant string.  */
- /* Use of an unrolled loop speeds this up considerably.                      */
- {UWORD i; UBYTE **p_h=hash;
-#  define ZH *p_h++=START_STRING_18
-  for (i=0;i<256;i++)     /* 256=HASH_TABLE_LENGTH/16. */
-    {ZH;ZH;ZH;ZH;
-     ZH;ZH;ZH;ZH;
-     ZH;ZH;ZH;ZH;
-     ZH;ZH;ZH;ZH;}
- }
-
- /* The main loop processes either 1 or 16 items per iteration. As its        */
- /* termination logic is complicated, I have opted for an infinite loop       */
- /* structure containing 'break' and 'goto' statements.                       */
- while (TRUE)
-   {/* Begin main processing loop. */
-   
-    /* Note: All the variables here except unroll should be defined within    */
-    /*       the inner loop. Unfortunately the loop hasn't got a block.       */
-     register UBYTE *p;         /* Scans through targ phrase during matching. */
-     register UBYTE *p_ziv= NULL ;     /* Points to first byte of current Ziv.       */
-     register UWORD unroll;     /* Loop counter for unrolled inner loop.      */
-     register UWORD index;      /* Index of current hash table entry.         */
-     register UBYTE **p_h0 = NULL ;     /* Pointer to current hash table entry.       */
-     
-    /* Test for overrun and jump to overrun code if necessary.                */
-    if (p_dst>p_dst_post)
-       goto overrun;
-       
-    /* The following cascade of if statements efficiently catches and deals   */
-    /* with varying degrees of closeness to the end of the input block.       */
-    /* When we get very close to the end, we stop updating the table and      */
-    /* code the remaining bytes as literals. This makes the code simpler.     */
-    unroll=16;
-    if (p_src>p_src_max16)
-      {
-       unroll=1;
-       if (p_src>p_src_max1)
-         {
-          if (p_src==p_src_post)
-             break;
-          else
-             goto literal;
-         }
-      }
-         
-    /* This inner unrolled loop processes 'unroll' (whose value is either 1   */
-    /* or 16) items. I have chosen to implement this loop with labels and     */
-    /* gotos to heighten the ease with which the loop may be implemented with */
-    /* a single decrement and branch instruction in assembly language and     */
-    /* also because the labels act as highly readable place markers.          */
-    /* (Also because we jump into the loop for endgame literals (see above)). */
-    
-    begin_unrolled_loop:
-    
-       /* To process the next phrase, we hash the next three bytes and use    */
-       /* the resultant hash table index to look up the hash table. A pointer */
-       /* to the entry is stored in p_h0 so as to avoid an array lookup. The  */
-       /* hash table entry *p_h0 is looked up yielding a pointer p to a       */
-       /* potential match of the Ziv in the history.                          */
-       index=HASH(p_src);
-       p_h0=&hash[index];
-       p=*p_h0;
-       
-       /* Having looked up the candidate position, we are in a position to    */
-       /* attempt a match. The match loop has been unrolled using the PS      */
-       /* macro so that failure within the first three bytes automatically    */
-       /* results in the literal branch being taken. The coding is simple.    */
-       /* p_ziv saves p_src so we can let p_src wander.                       */
-#       define PS *p++!=*p_src++
-       p_ziv=p_src;
-       if (PS || PS || PS)
-         {
-          /* Literal. */
-          
-          /* Code the literal byte as itself and a zero control bit.          */
-          p_src=p_ziv; literal: *p_dst++=*p_src++; control&=0xFFFEFFFF;
-          
-          /* We have just coded a literal. If we had two pending ones, that   */
-          /* makes three and we can update the hash table.                    */
-          if (p_h2!=0)
-             {*p_h2=p_ziv-2;}
-             
-          /* In any case, rotate the hash table pointers for next time. */
-          p_h2=p_h1; p_h1=p_h0;
-          
-         }
-       else
-         {
-          /* Copy */
-          
-          /* Match up to 15 remaining bytes using an unrolled loop and code. */
-#if 0
-          PS || PS || PS || PS || PS || PS || PS || PS ||
-          PS || PS || PS || PS || PS || PS || PS || p_src++;
-#else     
-          if (
-               !( PS || PS || PS || PS || PS || PS || PS || PS ||
-                  PS || PS || PS || PS || PS || PS || PS ) 
-             ) p_src++;
-#endif
-          *p_dst++=((index&0xF00)>>4)|(--p_src-p_ziv-3);
-          *p_dst++=index&0xFF;
-          
-          /* As we have just coded three bytes, we are now in a position to   */
-          /* update the hash table with the literal bytes that were pending   */
-          /* upon the arrival of extra context bytes.                         */
-          if (p_h1!=0)
-            {
-             if (p_h2)
-               {*p_h2=p_ziv-2; p_h2=NULL;}
-             *p_h1=p_ziv-1; p_h1=NULL;
-            }
-            
-          /* In any case, we can update the hash table based on the current   */
-          /* position as we just coded at least three bytes in a copy items.  */
-          *p_h0=p_ziv;
-          
-         }
-       control>>=1;
-                
-       /* This loop is all set up for a decrement and jump instruction! */
-#ifndef linux
-`    end_unrolled_loop: if (--unroll) goto begin_unrolled_loop;
-#else
-    /* end_unrolled_loop: */ if (--unroll) goto begin_unrolled_loop;
-#endif
-
-    /* At this point it will nearly always be the end of a group in which     */
-    /* case, we have to do some control-word processing. However, near the    */
-    /* end of the input block, the inner unrolled loop is only executed once. */
-    /* This necessitates the 'if' test.                                       */
-    if ((control&TOPWORD)==0)
-      {
-       /* Write the control word to the place we saved for it in the output. */
-       *p_control++=  control     &0xFF;
-       *p_control  = (control>>8) &0xFF;
-
-       /* Reserve the next word in the output block for the control word */
-       /* for the group about to be processed.                           */
-       p_control=p_dst; p_dst+=2;
-       
-       /* Reset the control bits buffer. */
-       control=TOPWORD;
-      }
-          
-   } /* End main processing loop. */
-   
- /* After the main processing loop has executed, all the input bytes have     */
- /* been processed. However, the control word has still to be written to the  */
- /* word reserved for it in the output at the start of the most recent group. */
- /* Before writing, the control word has to be shifted so that all the bits   */
- /* are in the right place. The "empty" bit positions are filled with 1s      */
- /* which partially fill the top word.                                        */
- while(control&TOPWORD) control>>=1;
- *p_control++= control     &0xFF;
- *p_control++=(control>>8) &0xFF;
- /* If the last group contained no items, delete the control word too.        */
- if (p_control==p_dst) p_dst-=2;
- /* Write the length of the output block to the dst_len parameter and return. */
- *p_dst_len=p_dst-p_dst_first;                           
- return;
- /* Jump here as soon as an overrun is detected. An overrun is defined to     */
- /* have occurred if p_dst>p_dst_first+src_len. That is, the moment the       */
- /* length of the output written so far exceeds the length of the input block.*/
- /* The algorithm checks for overruns at least at the end of each group       */
- /* which means that the maximum overrun is MAX_CMP_GROUP bytes.              */
- /* Once an overrun occurs, the only thing to do is to set the copy flag and  */
- /* copy the input over.                                                      */
- overrun:
-#if 0
- *p_dst_first=FLAG_COPY;
- fast_copy(p_src_first,p_dst_first+FLAG_BYTES,src_len);
- *p_dst_len=src_len+FLAG_BYTES;
-#else
- fast_copy(p_src_first,p_dst_first,src_len);
- *p_dst_len= -src_len; /* return a negative number to indicate uncompressed data */
-#endif
-}
-
-/******************************************************************************/
-
-/* Input  : Hand over the required amount of working memory in p_wrk_mem.     */
-/* Input  : Specify input block using p_src_first and src_len.                */
-/* Input  : Point p_dst_first to the start of the output zone.                */
-/* Input  : Point p_dst_len to a ULONG to receive the output length.          */
-/* Input  : Input block and output zone must not overlap. User knows          */
-/* Input  : upperbound on output block length from earlier compression.       */
-/* Input  : In any case, maximum expansion possible is nine times.            */
-/* Output : Length of output block written to *p_dst_len.                     */
-/* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1].       */
-/* Output : Writes only  in Mem[p_dst_first..p_dst_first+*p_dst_len-1].       */
-LOCAL void compress_decompress( UBYTE *p_wrk_mem,
-                               UBYTE *p_src_first, LONG   src_len,
-                               UBYTE *p_dst_first, ULONG *p_dst_len)
-{
- /* Byte pointers p_src and p_dst scan through the input and output blocks.   */
- register UBYTE *p_src = p_src_first+FLAG_BYTES;
- register UBYTE *p_dst = p_dst_first;
- /* we need to avoid a SEGV when trying to uncompress corrupt data */
- register UBYTE *p_dst_post = p_dst_first + *p_dst_len;
-
- /* The following two variables are never modified and are used to control    */
- /* the main loop.                                                            */
- UBYTE *p_src_post  = p_src_first+src_len;
- UBYTE *p_src_max16 = p_src_first+src_len-(MAX_CMP_GROUP-2);
- /* The hash table is the only resident of the working memory. The hash table */
- /* contains HASH_TABLE_LENGTH=4096 pointers to positions in the history. To  */
- /* keep Macintoshes happy, it is longword aligned.                           */
- UBYTE **hash = (UBYTE **) ULONG_ALIGN_UP(p_wrk_mem);
-
- /* The variable 'control' is used to buffer the control bits which appear in */
- /* groups of 16 bits (control words) at the start of each compressed group.  */
- /* When each group is read, bit 16 of the register is set to one. Whenever   */
- /* a new bit is needed, the register is shifted right. When the value of the */
- /* register becomes 1, we know that we have reached the end of a group.      */
- /* Initializing the register to 1 thus instructs the code to follow that it  */
- /* should read a new control word immediately.                               */
- register ULONG control=1;
- /* The value of 'literals' is always in the range 0..3. It is the number of  */
- /* consecutive literal items just seen. We have to record this number so as  */
- /* to know when to update the hash table. When literals gets to 3, there     */
- /* have been three consecutive literals and we can update at the position of */
- /* the oldest of the three.                                                  */
- register UWORD literals=0;
- /* Check the leading copy flag to see if the compressor chose to use a copy  */
- /* operation instead of a compression operation. If a copy operation was     */
- /* used, then all we need to do is copy the data over, set the output length */
- /* and return.                                                               */
-#if 0
- if (*p_src_first==FLAG_COPY)
-   {
-    fast_copy(p_src_first+FLAG_BYTES,p_dst_first,src_len-FLAG_BYTES);
-    *p_dst_len=src_len-FLAG_BYTES;
-    return;
-   }
-#else
-  if ( src_len < 0 )
-  {                                            
-   fast_copy(p_src_first,p_dst_first,-src_len );
-   *p_dst_len = (ULONG)-src_len;
-   return;
-  }
-#endif
-   
- /* Initialize all elements of the hash table to point to a constant string.  */
- /* Use of an unrolled loop speeds this up considerably.                      */
- {UWORD i; UBYTE **p_h=hash;
-#  define ZJ *p_h++=START_STRING_18
-  for (i=0;i<256;i++)     /* 256=HASH_TABLE_LENGTH/16. */
-    {ZJ;ZJ;ZJ;ZJ;
-     ZJ;ZJ;ZJ;ZJ;
-     ZJ;ZJ;ZJ;ZJ;
-     ZJ;ZJ;ZJ;ZJ;}
- }
-
- /* The outer loop processes either 1 or 16 items per iteration depending on  */
- /* how close p_src is to the end of the input block.                         */
- while (p_src!=p_src_post)
-   {/* Start of outer loop */
-   
-    register UWORD unroll;   /* Counts unrolled loop executions.              */
-    
-    /* When 'control' has the value 1, it means that the 16 buffered control  */
-    /* bits that were read in at the start of the current group have all been */
-    /* shifted out and that all that is left is the 1 bit that was injected   */
-    /* into bit 16 at the start of the current group. When we reach the end   */
-    /* of a group, we have to load a new control word and inject a new 1 bit. */
-    if (control==1)
-      {
-       control=0x10000|*p_src++;
-       control|=(*p_src++)<<8;
-      }
-
-    /* If it is possible that we are within 16 groups from the end of the     */
-    /* input, execute the unrolled loop only once, else process a whole group */
-    /* of 16 items by looping 16 times.                                       */
-    unroll= p_src<=p_src_max16 ? 16 : 1;
-
-    /* This inner loop processes one phrase (item) per iteration. */
-    while (unroll--)
-      { /* Begin unrolled inner loop. */
-      
-       /* Process a literal or copy item depending on the next control bit. */
-       if (control&1)
-         {
-          /* Copy item. */
-          
-          register UBYTE *p;           /* Points to place from which to copy. */
-          register UWORD lenmt;        /* Length of copy item minus three.    */
-          register UBYTE **p_hte;      /* Pointer to current hash table entry.*/
-          register UBYTE *p_ziv=p_dst; /* Pointer to start of current Ziv.    */
-          
-          /* Read and dismantle the copy word. Work out from where to copy.   */
-          lenmt=*p_src++;
-          p_hte=&hash[((lenmt&0xF0)<<4)|*p_src++];
-          p=*p_hte;
-          lenmt&=0xF;
-          
-          /* Now perform the copy using a half unrolled loop. */
-          *p_dst++=*p++;
-          *p_dst++=*p++;
-          *p_dst++=*p++;
-          while (lenmt--)
-             *p_dst++=*p++;
-                 
-          /* Because we have just received 3 or more bytes in a copy item     */
-          /* (whose bytes we have just installed in the output), we are now   */
-          /* in a position to flush all the pending literal hashings that had */
-          /* been postponed for lack of bytes.                                */
-          if (literals>0)
-            {
-             register UBYTE *r=p_ziv-literals;
-             hash[HASH(r)]=r;
-             if (literals==2)
-                {r++; hash[HASH(r)]=r;}
-             literals=0;
-            }
-            
-          /* In any case, we can immediately update the hash table with the   */
-          /* current position. We don't need to do a HASH(...) to work out    */
-          /* where to put the pointer, as the compressor just told us!!!      */
-          *p_hte=p_ziv;
-          
-         }
-       else
-         {
-          /* Literal item. */
-          
-          /* Copy over the literal byte. */
-          *p_dst++=*p_src++;
-          
-          /* If we now have three literals waiting to be hashed into the hash */
-          /* table, we can do one of them now (because there are three).      */
-          if (++literals == 3)
-             {register UBYTE *p=p_dst-3; hash[HASH(p)]=p; literals=2;}
-         }
-          
-       /* Shift the control buffer so the next control bit is in bit 0. */
-       control>>=1;
-#if 1
-       if (p_dst > p_dst_post) 
-       {
-              /* Shit: we tried to decompress corrupt data */
-              *p_dst_len = 0;
-              return;
-       }
-#endif
-      } /* End unrolled inner loop. */
-               
-   } /* End of outer loop */
-   
- /* Write the length of the decompressed data before returning. */
-  *p_dst_len=p_dst-p_dst_first;
-}
-
-/******************************************************************************/
-/*                               End of LZRW3.C                               */
-/******************************************************************************/
diff --git a/drivers/char/ftape/compressor/lzrw3.h b/drivers/char/ftape/compressor/lzrw3.h
deleted file mode 100644 (file)
index 533feba..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-#ifndef _LZRW3_H
-#define _LZRW3_H
-/*
- * $Source: /homes/cvs/ftape-stacked/ftape/compressor/lzrw3.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/10/05 19:12:30 $
- *
- *  include files for lzrw3. Only slighty modified from the original
- *  version. Assembles the three include files compress.h, port.h and
- *  fastcopy.h from the original lzrw3 package.
- *
- */
-
-#include <linux/types.h>
-#include <linux/string.h>
-
-/******************************************************************************/
-/*                                                                            */
-/*                                 COMPRESS.H                                 */
-/*                                                                            */
-/******************************************************************************/
-/*                                                                            */
-/* Author : Ross Williams.                                                    */
-/* Date   : December 1989.                                                    */
-/*                                                                            */
-/* This header file defines the interface to a set of functions called        */
-/* 'compress', each member of which implements a particular data compression  */
-/* algorithm.                                                                 */
-/*                                                                            */
-/* Normally in C programming, for each .H file, there is a corresponding .C   */
-/* file that implements the functions promised in the .H file.                */
-/* Here, there are many .C files corresponding to this header file.           */
-/* Each comforming implementation file contains a single function             */
-/* called 'compress' that implements a single data compression                */
-/* algorithm that conforms with the interface specified in this header file.  */
-/* Only one algorithm can be linked in at a time in this organization.        */
-/*                                                                            */
-/******************************************************************************/
-/*                                                                            */
-/*                    DEFINITION OF FUNCTION COMPRESS                         */
-/*                    ===============================                         */
-/*                                                                            */
-/* Summary of Function Compress                                               */
-/* ----------------------------                                               */
-/* The action that 'compress' takes depends on its first argument called      */
-/* 'action'.  The function provides three actions:                            */
-/*                                                                            */
-/*    - Return information about the algorithm.                               */
-/*    - Compress   a block of memory.                                         */
-/*    - Decompress a block of memory.                                         */
-/*                                                                            */
-/* Parameters                                                                 */
-/* ----------                                                                 */
-/* See the formal C definition later for a description of the parameters.     */
-/*                                                                            */
-/* Constants                                                                  */
-/* ---------                                                                  */
-/* COMPRESS_OVERRUN: The constant COMPRESS_OVERRUN defines by how many bytes  */
-/* an algorithm is allowed to expand a block during a compression operation.  */
-/*                                                                            */
-/* Although compression algorithms usually compress data, there will always   */
-/* be data that a given compressor will expand (this can be proven).          */
-/* Fortunately, the degree of expansion can be limited to a single bit, by    */
-/* copying over the input data if the data gets bigger during compression.    */
-/* To allow for this possibility, the first bit of a compressed               */
-/* representation can be used as a flag indicating whether the                */
-/* input data was copied over, or truly compressed. In practice, the first    */
-/* byte would be used to store this bit so as to maintain byte alignment.     */
-/*                                                                            */
-/* Unfortunately, in general, the only way to tell if an algorithm will       */
-/* expand a particular block of data is to run the algorithm on the data.     */
-/* If the algorithm does not continuously monitor how many output bytes it    */
-/* has written, it might write an output block far larger than the input      */
-/* block before realizing that it has done so.                                */
-/* On the other hand, continuous checks on output length are inefficient.     */
-/*                                                                            */
-/* To cater for all these problems, this interface definition:                */
-/* > Allows a compression algorithm to return an output block that is up to   */
-/*   COMPRESS_OVERRUN bytes longer than the input block.                      */
-/* > Allows a compression algorithm to write up to COMPRESS_OVERRUN bytes     */
-/*   more than the length of the input block to the memory of the output      */
-/*   block regardless of the length of the output block eventually returned.  */
-/*   This allows an algorithm to overrun the length of the input block in the */
-/*   output block by up to COMPRESS_OVERRUN bytes between expansion checks.   */
-/*                                                                            */
-/* The problem does not arise for decompression.                              */
-/*                                                                            */
-/* Identity Action                                                            */
-/* ---------------                                                            */
-/* > action must be COMPRESS_ACTION_IDENTITY.                                 */
-/* > p_dst_len must point to a longword to receive a longword address.        */
-/* > The value of the other parameters does not matter.                       */
-/* > After execution, the longword that p_dst_len points to will be a pointer */
-/*   to a structure of type compress_identity.                                */
-/*   Thus, for example, after the call, (*p_dst_len)->memory will return the  */
-/*   number of bytes of working memory that the algorithm requires to run.    */
-/* > The values of the identity structure returned are fixed constant         */
-/*   attributes of the algorithm and must not vary from call to call.         */
-/*                                                                            */
-/* Common Requirements for Compression and Decompression Actions              */
-/* -------------------------------------------------------------              */
-/* > wrk_mem must point to an unused block of memory of a length specified in */
-/*   the algorithm's identity block. The identity block can be obtained by    */
-/*   making a separate call to compress, specifying the identity action.      */
-/* > The INPUT BLOCK is defined to be Memory[src_addr,src_addr+src_len-1].    */
-/* > dst_len will be used to denote *p_dst_len.                               */
-/* > dst_len is not read by compress, only written.                           */
-/* > The value of dst_len is defined only upon termination.                   */
-/* > The OUTPUT BLOCK is defined to be Memory[dst_addr,dst_addr+dst_len-1].   */
-/*                                                                            */
-/* Compression Action                                                         */
-/* ------------------                                                         */
-/* > action must be COMPRESS_ACTION_COMPRESS.                                 */
-/* > src_len must be in the range [0,COMPRESS_MAX_ORG].                       */
-/* > The OUTPUT ZONE is defined to be                                         */
-/*      Memory[dst_addr,dst_addr+src_len-1+COMPRESS_OVERRUN].                 */
-/* > The function can modify any part of the output zone regardless of the    */
-/*   final length of the output block.                                        */
-/* > The input block and the output zone must not overlap.                    */
-/* > dst_len will be in the range [0,src_len+COMPRESS_OVERRUN].               */
-/* > dst_len will be in the range [0,COMPRESS_MAX_COM] (from prev fact).      */
-/* > The output block will consist of a representation of the input block.    */
-/*                                                                            */
-/* Decompression Action                                                       */
-/* --------------------                                                       */
-/* > action must be COMPRESS_ACTION_DECOMPRESS.                               */
-/* > The input block must be the result of an earlier compression operation.  */
-/* > If the previous fact is true, the following facts must also be true:     */
-/*   > src_len will be in the range [0,COMPRESS_MAX_COM].                     */
-/*   > dst_len will be in the range [0,COMPRESS_MAX_ORG].                     */
-/* > The input and output blocks must not overlap.                            */
-/* > Only the output block is modified.                                       */
-/* > Upon termination, the output block will consist of the bytes contained   */
-/*   in the input block passed to the earlier compression operation.          */
-/*                                                                            */
-/******************************************************************************/
-
-/******************************************************************************/
-/*                                                                            */
-/*                                    PORT.H                                  */
-/*                                                                            */
-/******************************************************************************/
-/*                                                                            */
-/* This module contains macro definitions and types that are likely to        */
-/* change between computers.                                                  */
-/*                                                                            */
-/******************************************************************************/
-
-#ifndef DONE_PORT       /* Only do this if not previously done.               */
-
-   #ifdef THINK_C
-      #define UBYTE unsigned char      /* Unsigned byte                       */
-      #define UWORD unsigned int       /* Unsigned word (2 bytes)             */
-      #define ULONG unsigned long      /* Unsigned word (4 bytes)             */
-      #define BOOL  unsigned char      /* Boolean                             */
-      #define FOPEN_BINARY_READ  "rb"  /* Mode string for binary reading.     */
-      #define FOPEN_BINARY_WRITE "wb"  /* Mode string for binary writing.     */
-      #define FOPEN_TEXT_APPEND  "a"   /* Mode string for text appending.     */
-      #define REAL double              /* USed for floating point stuff.      */
-   #endif
-   #if defined(LINUX) || defined(linux)
-      #define UBYTE __u8               /* Unsigned byte                       */
-      #define UWORD __u16              /* Unsigned word (2 bytes)             */
-      #define ULONG __u32              /* Unsigned word (4 bytes)             */
-      #define LONG  __s32              /* Signed   word (4 bytes)             */
-      #define BOOL  is not used here   /* Boolean                             */
-      #define FOPEN_BINARY_READ  not used  /* Mode string for binary reading. */
-      #define FOPEN_BINARY_WRITE not used  /* Mode string for binary writing. */
-      #define FOPEN_TEXT_APPEND  not used  /* Mode string for text appending. */
-      #define REAL not used                /* USed for floating point stuff.  */
-      #ifndef TRUE
-      #define TRUE 1
-      #endif
-   #endif
-
-   #define DONE_PORT                   /* Don't do all this again.            */
-   #define MALLOC_FAIL NULL            /* Failure status from malloc()        */
-   #define LOCAL static                /* For non-exported routines.          */
-   #define EXPORT                      /* Signals exported function.          */
-   #define then                        /* Useful for aligning ifs.            */
-
-#endif
-
-/******************************************************************************/
-/*                              End of PORT.H                                 */
-/******************************************************************************/
-
-#define COMPRESS_ACTION_IDENTITY   0
-#define COMPRESS_ACTION_COMPRESS   1
-#define COMPRESS_ACTION_DECOMPRESS 2
-
-#define COMPRESS_OVERRUN 1024
-#define COMPRESS_MAX_COM 0x70000000
-#define COMPRESS_MAX_ORG (COMPRESS_MAX_COM-COMPRESS_OVERRUN)
-
-#define COMPRESS_MAX_STRLEN 255
-
-/* The following structure provides information about the algorithm.         */
-/* > The top bit of id must be zero. The remaining bits must be chosen by    */
-/*   the author of the algorithm by tossing a coin 31 times.                 */
-/* > The amount of memory requested by the algorithm is specified in bytes   */
-/*   and must be in the range [0,0x70000000].                                */
-/* > All strings s must be such that strlen(s)<=COMPRESS_MAX_STRLEN.         */
-struct compress_identity
-  {
-   ULONG id;           /* Identifying number of algorithm.            */
-   ULONG memory;       /* Number of bytes of working memory required. */
-
-   char  *name;        /* Name of algorithm.                          */
-   char  *version;     /* Version number.                             */
-   char  *date;        /* Date of release of this version.            */
-   char  *copyright;   /* Copyright message.                          */
-
-   char  *author;      /* Author of algorithm.                        */
-   char  *affiliation; /* Affiliation of author.                      */
-   char  *vendor;      /* Where the algorithm can be obtained.        */
-  };
-
-void  lzrw3_compress(        /* Single function interface to compression algorithm. */
-UWORD     action,      /* Action to be performed.                             */
-UBYTE   *wrk_mem,      /* Working memory temporarily given to routine to use. */
-UBYTE   *src_adr,      /* Address of input  data.                             */
-LONG     src_len,      /* Length  of input  data.                             */
-UBYTE   *dst_adr,      /* Address of output data.                             */
-void  *p_dst_len       /* Pointer to a longword where routine will write:     */
-                       /*    If action=..IDENTITY   => Adr of id structure.   */
-                       /*    If action=..COMPRESS   => Length of output data. */
-                       /*    If action=..DECOMPRESS => Length of output data. */
-);
-
-/******************************************************************************/
-/*                             End of COMPRESS.H                              */
-/******************************************************************************/
-
-
-/******************************************************************************/
-/*                                  fast_copy.h                               */
-/******************************************************************************/
-
-/* This function copies a block of memory very quickly.                       */
-/* The exact speed depends on the relative alignment of the blocks of memory. */
-/* PRE  : 0<=src_len<=(2^32)-1 .                                              */
-/* PRE  : Source and destination blocks must not overlap.                     */
-/* POST : MEM[dst_adr,dst_adr+src_len-1]=MEM[src_adr,src_adr+src_len-1].      */
-/* POST : MEM[dst_adr,dst_adr+src_len-1] is the only memory changed.          */
-
-#define fast_copy(src,dst,len) memcpy(dst,src,len)
-
-/******************************************************************************/
-/*                               End of fast_copy.h                           */
-/******************************************************************************/
-
-#endif
diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
deleted file mode 100644 (file)
index 65ffc0b..0000000
+++ /dev/null
@@ -1,1203 +0,0 @@
-/*
- *      Copyright (C) 1994-1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
- *
- *     This file implements a "generic" interface between the *
- *     zftape-driver and a compression-algorithm. The *
- *     compression-algorithm currently used is a LZ77. I use the *
- *     implementation lzrw3 by Ross N. Williams (Renaissance *
- *     Software). The compression program itself is in the file
- *     lzrw3.c * and lzrw3.h.  To adopt another compression algorithm
- *     the functions * zft_compress() and zft_uncompress() must be
- *     changed * appropriately. See below.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../compressor/zftape-compress.h"
-#include "../zftape/zftape-vtbl.h"
-#include "../compressor/lzrw3.h"
-
-/*
- *   global variables
- */
-
-/* I handle the allocation of this buffer as a special case, because
- * it's size varies depending on the tape length inserted.
- */
-
-/* local variables 
- */
-static void *zftc_wrk_mem = NULL;
-static __u8 *zftc_buf     = NULL;
-static void *zftc_scratch_buf  = NULL;
-
-/* compression statistics 
- */
-static unsigned int zftc_wr_uncompressed = 0;
-static unsigned int zftc_wr_compressed   = 0;
-static unsigned int zftc_rd_uncompressed = 0;
-static unsigned int zftc_rd_compressed   = 0;
-
-/* forward */
-static int  zftc_write(int *write_cnt,
-                      __u8 *dst_buf, const int seg_sz,
-                      const __u8 __user *src_buf, const int req_len,
-                      const zft_position *pos, const zft_volinfo *volume);
-static int  zftc_read(int *read_cnt,
-                     __u8  __user *dst_buf, const int to_do,
-                     const __u8 *src_buf, const int seg_sz,
-                     const zft_position *pos, const zft_volinfo *volume);
-static int  zftc_seek(unsigned int new_block_pos, 
-                     zft_position *pos, const zft_volinfo *volume,
-                     __u8 *buffer);
-static void zftc_lock   (void);
-static void zftc_reset  (void);
-static void zftc_cleanup(void);
-static void zftc_stats      (void);
-
-/* compressed segment. This conforms to QIC-80-MC, Revision K.
- * 
- * Rev. K applies to tapes with `fixed length format' which is
- * indicated by format code 2,3 and 5. See below for format code 4 and 6
- *
- * 2 bytes: offset of compression segment structure
- *          29k > offset >= 29k-18: data from previous segment ens in this
- *                                  segment and no compressed block starts
- *                                  in this segment
- *                     offset == 0: data from previous segment occupies entire
- *                                  segment and continues in next segment
- * n bytes: remainder from previous segment
- * 
- * Rev. K:  
- * 4 bytes: 4 bytes: files set byte offset
- * Post Rev. K and QIC-3020/3020:
- * 8 bytes: 8 bytes: files set byte offset
- * 2 bytes: byte count N (amount of data following)
- *          bit 15 is set if data is compressed, bit 15 is not
- *          set if data is uncompressed
- * N bytes: data (as much as specified in the byte count)
- * 2 bytes: byte count N_1 of next cluster
- * N_1 bytes: data of next cluset
- * 2 bytes: byte count N_2 of next cluster
- * N_2 bytes: ...  
- *
- * Note that the `N' byte count accounts only for the bytes that in the
- * current segment if the cluster spans to the next segment.
- */
-
-typedef struct
-{
-       int cmpr_pos;             /* actual position in compression buffer */
-       int cmpr_sz;              /* what is left in the compression buffer
-                                  * when copying the compressed data to the
-                                  * deblock buffer
-                                  */
-       unsigned int first_block; /* location of header information in
-                                  * this segment
-                                  */
-       unsigned int count;       /* amount of data of current block
-                                  * contained in current segment 
-                                  */
-       unsigned int offset;      /* offset in current segment */
-       unsigned int spans:1;     /* might continue in next segment */
-       unsigned int uncmpr;      /* 0x8000 if this block contains
-                                  * uncompressed data 
-                                  */
-       __s64 foffs;              /* file set byte offset, same as in 
-                                  * compression map segment
-                                  */
-} cmpr_info;
-
-static cmpr_info cseg; /* static data. Must be kept uptodate and shared by 
-                       * read, write and seek functions
-                       */
-
-#define DUMP_CMPR_INFO(level, msg, info)                               \
-       TRACE(level, msg "\n"                                           \
-             KERN_INFO "cmpr_pos   : %d\n"                             \
-             KERN_INFO "cmpr_sz    : %d\n"                             \
-             KERN_INFO "first_block: %d\n"                             \
-             KERN_INFO "count      : %d\n"                             \
-             KERN_INFO "offset     : %d\n"                             \
-             KERN_INFO "spans      : %d\n"                             \
-             KERN_INFO "uncmpr     : 0x%04x\n"                         \
-             KERN_INFO "foffs      : " LL_X,                           \
-             (info)->cmpr_pos, (info)->cmpr_sz, (info)->first_block,   \
-             (info)->count, (info)->offset, (info)->spans == 1,        \
-             (info)->uncmpr, LL((info)->foffs))
-
-/*   dispatch compression segment info, return error code
- *  
- *   afterwards, cseg->offset points to start of data of the NEXT
- *   compressed block, and cseg->count contains the amount of data
- *   left in the actual compressed block. cseg->spans is set to 1 if
- *   the block is continued in the following segment. Otherwise it is
- *   set to 0. 
- */
-static int get_cseg (cmpr_info *cinfo, const __u8 *buff, 
-                    const unsigned int seg_sz,
-                    const zft_volinfo *volume)
-{
-       TRACE_FUN(ft_t_flow);
-
-       cinfo->first_block = GET2(buff, 0);
-       if (cinfo->first_block == 0) { /* data spans to next segment */
-               cinfo->count  = seg_sz - sizeof(__u16);
-               cinfo->offset = seg_sz;
-               cinfo->spans = 1;
-       } else { /* cluster definetely ends in this segment */
-               if (cinfo->first_block > seg_sz) {
-                       /* data corrupted */
-                       TRACE_ABORT(-EIO, ft_t_err, "corrupted data:\n"
-                                   KERN_INFO "segment size: %d\n"
-                                   KERN_INFO "first block : %d",
-                                   seg_sz, cinfo->first_block);
-               }
-               cinfo->count  = cinfo->first_block - sizeof(__u16);
-               cinfo->offset = cinfo->first_block;
-               cinfo->spans = 0;
-       }
-       /* now get the offset the first block should have in the
-        * uncompressed data stream.
-        *
-        * For this magic `18' refer to CRF-3 standard or QIC-80MC,
-        * Rev. K.  
-        */
-       if ((seg_sz - cinfo->offset) > 18) {
-               if (volume->qic113) { /* > revision K */
-                       TRACE(ft_t_data_flow, "New QIC-113 compliance");
-                       cinfo->foffs = GET8(buff, cinfo->offset);
-                       cinfo->offset += sizeof(__s64); 
-               } else {
-                       TRACE(/* ft_t_data_flow */ ft_t_noise, "pre QIC-113 version");
-                       cinfo->foffs   = (__s64)GET4(buff, cinfo->offset);
-                       cinfo->offset += sizeof(__u32); 
-               }
-       }
-       if (cinfo->foffs > volume->size) {
-               TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n"
-                           KERN_INFO "offset in current volume: %d\n"
-                           KERN_INFO "size of current volume  : %d",
-                           (int)(cinfo->foffs>>10), (int)(volume->size>>10));
-       }
-       if (cinfo->cmpr_pos + cinfo->count > volume->blk_sz) {
-               TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n"
-                           KERN_INFO "block size : %d\n"
-                           KERN_INFO "data record: %d",
-                           volume->blk_sz, cinfo->cmpr_pos + cinfo->count);
-       }
-       DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", cinfo);
-       TRACE_EXIT 0;
-}
-
-/*  This one is called, when a new cluster starts in same segment.
- *  
- *  Note: if this is the first cluster in the current segment, we must
- *  not check whether there are more than 18 bytes available because
- *  this have already been done in get_cseg() and there may be less
- *  than 18 bytes available due to header information.
- * 
- */
-static void get_next_cluster(cmpr_info *cluster, const __u8 *buff, 
-                            const int seg_sz, const int finish)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (seg_sz - cluster->offset > 18 || cluster->foffs != 0) {
-               cluster->count   = GET2(buff, cluster->offset);
-               cluster->uncmpr  = cluster->count & 0x8000;
-               cluster->count  -= cluster->uncmpr;
-               cluster->offset += sizeof(__u16);
-               cluster->foffs   = 0;
-               if ((cluster->offset + cluster->count) < seg_sz) {
-                       cluster->spans = 0;
-               } else if (cluster->offset + cluster->count == seg_sz) {
-                       cluster->spans = !finish;
-               } else {
-                       /* either an error or a volume written by an 
-                        * old version. If this is a data error, then we'll
-                        * catch it later.
-                        */
-                       TRACE(ft_t_data_flow, "Either error or old volume");
-                       cluster->spans = 1;
-                       cluster->count = seg_sz - cluster->offset;
-               }
-       } else {
-               cluster->count = 0;
-               cluster->spans = 0;
-               cluster->foffs = 0;
-       }
-       DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */ , "", cluster);
-       TRACE_EXIT;
-}
-
-static void zftc_lock(void)
-{
-}
-
-/*  this function is needed for zftape_reset_position in zftape-io.c 
- */
-static void zftc_reset(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       memset((void *)&cseg, '\0', sizeof(cseg));
-       zftc_stats();
-       TRACE_EXIT;
-}
-
-static int cmpr_mem_initialized = 0;
-static unsigned int alloc_blksz = 0;
-
-static int zft_allocate_cmpr_mem(unsigned int blksz)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (cmpr_mem_initialized && blksz == alloc_blksz) {
-               TRACE_EXIT 0;
-       }
-       TRACE_CATCH(zft_vmalloc_once(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE),
-                   zftc_cleanup());
-       TRACE_CATCH(zft_vmalloc_always(&zftc_buf, blksz + CMPR_OVERRUN),
-                   zftc_cleanup());
-       alloc_blksz = blksz;
-       TRACE_CATCH(zft_vmalloc_always(&zftc_scratch_buf, blksz+CMPR_OVERRUN),
-                   zftc_cleanup());
-       cmpr_mem_initialized = 1;
-       TRACE_EXIT 0;
-}
-
-static void zftc_cleanup(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       zft_vfree(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE);
-       zft_vfree(&zftc_buf, alloc_blksz + CMPR_OVERRUN);
-       zft_vfree(&zftc_scratch_buf, alloc_blksz + CMPR_OVERRUN);
-       cmpr_mem_initialized = alloc_blksz = 0;
-       TRACE_EXIT;
-}
-
-/*****************************************************************************
- *                                                                           *
- *  The following two functions "ftape_compress()" and                       *
- *  "ftape_uncompress()" are the interface to the actual compression         *
- *  algorithm (i.e. they are calling the "compress()" function from          *
- *  the lzrw3 package for now). These routines could quite easily be         *
- *  changed to adopt another compression algorithm instead of lzrw3,         *
- *  which currently is used.                                                 *
- *                                                                           *
- *****************************************************************************/
-
-/* called by zft_compress_write() to perform the compression. Must
- * return the size of the compressed data.
- *
- * NOTE: The size of the compressed data should not exceed the size of
- *       the uncompressed data. Most compression algorithms have means
- *       to store data unchanged if the "compressed" data amount would
- *       exceed the original one. Mostly this is done by storing some
- *       flag-bytes in front of the compressed data to indicate if it
- *       is compressed or not. Thus the worst compression result
- *       length is the original length plus those flag-bytes.
- *
- *       We don't want that, as the QIC-80 standard provides a means
- *       of marking uncompressed blocks by simply setting bit 15 of
- *       the compressed block's length. Thus a compessed block can
- *       have at most a length of 2^15-1 bytes. The QIC-80 standard
- *       restricts the block-length even further, allowing only 29k -
- *       6 bytes.
- *
- *       Currently, the maximum blocksize used by zftape is 28k.
- *
- *       In short: don't exceed the length of the input-package, set
- *       bit 15 of the compressed size to 1 if you have copied data
- *       instead of compressing it.
- */
-static int zft_compress(__u8 *in_buffer, unsigned int in_sz, __u8 *out_buffer)
-{ 
-       __s32 compressed_sz;
-       TRACE_FUN(ft_t_flow);
-       
-
-       lzrw3_compress(COMPRESS_ACTION_COMPRESS, zftc_wrk_mem,
-                      in_buffer, in_sz, out_buffer, &compressed_sz);
-       if (TRACE_LEVEL >= ft_t_info) {
-               /*  the compiler will optimize this away when
-                *  compiled with NO_TRACE_AT_ALL option
-                */
-               TRACE(ft_t_data_flow, "\n"
-                     KERN_INFO "before compression: %d bytes\n"
-                     KERN_INFO "after compresison : %d bytes", 
-                     in_sz, 
-                     (int)(compressed_sz < 0 
-                     ? -compressed_sz : compressed_sz));
-               /*  for statistical purposes
-                */
-               zftc_wr_compressed   += (compressed_sz < 0 
-                                          ? -compressed_sz : compressed_sz);
-               zftc_wr_uncompressed += in_sz;
-       }
-       TRACE_EXIT (int)compressed_sz;
-}
-
-/* called by zft_compress_read() to decompress the data. Must
- * return the size of the decompressed data for sanity checks
- * (compared with zft_blk_sz)
- *
- * NOTE: Read the note for zft_compress() above!  If bit 15 of the
- *       parameter in_sz is set, then the data in in_buffer isn't
- *       compressed, which must be handled by the un-compression
- *       algorithm. (I changed lzrw3 to handle this.)
- *
- *  The parameter max_out_sz is needed to prevent buffer overruns when 
- *  uncompressing corrupt data.
- */
-static unsigned int zft_uncompress(__u8 *in_buffer, 
-                                  int in_sz, 
-                                  __u8 *out_buffer,
-                                  unsigned int max_out_sz)
-{ 
-       TRACE_FUN(ft_t_flow);
-       
-       lzrw3_compress(COMPRESS_ACTION_DECOMPRESS, zftc_wrk_mem,
-                      in_buffer, (__s32)in_sz,
-                      out_buffer, (__u32 *)&max_out_sz);
-       
-       if (TRACE_LEVEL >= ft_t_info) {
-               TRACE(ft_t_data_flow, "\n"
-                     KERN_INFO "before decompression: %d bytes\n"
-                     KERN_INFO "after decompression : %d bytes", 
-                     in_sz < 0 ? -in_sz : in_sz,(int)max_out_sz);
-               /*  for statistical purposes
-                */
-               zftc_rd_compressed   += in_sz < 0 ? -in_sz : in_sz;
-               zftc_rd_uncompressed += max_out_sz;
-       }
-       TRACE_EXIT (unsigned int)max_out_sz;
-}
-
-/* print some statistics about the efficiency of the compression to
- * the kernel log 
- */
-static void zftc_stats(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (TRACE_LEVEL < ft_t_info) {
-               TRACE_EXIT;
-       }
-       if (zftc_wr_uncompressed != 0) {
-               if (zftc_wr_compressed > (1<<14)) {
-                       TRACE(ft_t_info, "compression statistics (writing):\n"
-                             KERN_INFO " compr./uncmpr.   : %3d %%",
-                             (((zftc_wr_compressed>>10) * 100)
-                              / (zftc_wr_uncompressed>>10)));
-               } else {
-                       TRACE(ft_t_info, "compression statistics (writing):\n"
-                             KERN_INFO " compr./uncmpr.   : %3d %%",
-                             ((zftc_wr_compressed * 100)
-                              / zftc_wr_uncompressed));
-               }
-       }
-       if (zftc_rd_uncompressed != 0) {
-               if (zftc_rd_compressed > (1<<14)) {
-                       TRACE(ft_t_info, "compression statistics (reading):\n"
-                             KERN_INFO " compr./uncmpr.   : %3d %%",
-                             (((zftc_rd_compressed>>10) * 100)
-                              / (zftc_rd_uncompressed>>10)));
-               } else {
-                       TRACE(ft_t_info, "compression statistics (reading):\n"
-                             KERN_INFO " compr./uncmpr.   : %3d %%",
-                             ((zftc_rd_compressed * 100)
-                              / zftc_rd_uncompressed));
-               }
-       }
-       /* only print it once: */
-       zftc_wr_uncompressed = 
-               zftc_wr_compressed  =
-               zftc_rd_uncompressed =
-               zftc_rd_compressed   = 0;
-       TRACE_EXIT;
-}
-
-/* start new compressed block 
- */
-static int start_new_cseg(cmpr_info *cluster, 
-                         char *dst_buf, 
-                         const zft_position *pos,
-                         const unsigned int blk_sz,
-                         const char *src_buf,
-                         const int this_segs_sz,
-                         const int qic113)
-{
-       int size_left;
-       int cp_cnt;
-       int buf_pos;
-       TRACE_FUN(ft_t_flow);
-
-       size_left = this_segs_sz - sizeof(__u16) - cluster->cmpr_sz;
-       TRACE(ft_t_data_flow,"\n" 
-             KERN_INFO "segment size   : %d\n"
-             KERN_INFO "compressed_sz: %d\n"
-             KERN_INFO "size_left      : %d",
-             this_segs_sz, cluster->cmpr_sz, size_left);
-       if (size_left > 18) { /* start a new cluseter */
-               cp_cnt = cluster->cmpr_sz;
-               cluster->cmpr_sz = 0;
-               buf_pos = cp_cnt + sizeof(__u16);
-               PUT2(dst_buf, 0, buf_pos);
-
-               if (qic113) {
-                       __s64 foffs = pos->volume_pos;
-                       if (cp_cnt) foffs += (__s64)blk_sz;
-
-                       TRACE(ft_t_data_flow, "new style QIC-113 header");
-                       PUT8(dst_buf, buf_pos, foffs);
-                       buf_pos += sizeof(__s64);
-               } else {
-                       __u32 foffs = (__u32)pos->volume_pos;
-                       if (cp_cnt) foffs += (__u32)blk_sz;
-                       
-                       TRACE(ft_t_data_flow, "old style QIC-80MC header");
-                       PUT4(dst_buf, buf_pos, foffs);
-                       buf_pos += sizeof(__u32);
-               }
-       } else if (size_left >= 0) {
-               cp_cnt = cluster->cmpr_sz;
-               cluster->cmpr_sz = 0;
-               buf_pos = cp_cnt + sizeof(__u16);
-               PUT2(dst_buf, 0, buf_pos);  
-               /* zero unused part of segment. */
-               memset(dst_buf + buf_pos, '\0', size_left);
-               buf_pos = this_segs_sz;
-       } else { /* need entire segment and more space */
-               PUT2(dst_buf, 0, 0); 
-               cp_cnt = this_segs_sz - sizeof(__u16);
-               cluster->cmpr_sz  -= cp_cnt;
-               buf_pos = this_segs_sz;
-       }
-       memcpy(dst_buf + sizeof(__u16), src_buf + cluster->cmpr_pos, cp_cnt);
-       cluster->cmpr_pos += cp_cnt;
-       TRACE_EXIT buf_pos;
-}
-
-/* return-value: the number of bytes removed from the user-buffer
- *               `src_buf' or error code
- *
- *  int *write_cnt           : how much actually has been moved to the
- *                             dst_buf. Need not be initialized when
- *                             function returns with an error code
- *                             (negativ return value) 
- *  __u8 *dst_buf            : kernel space buffer where the has to be
- *                             copied to. The contents of this buffers
- *                             goes to a specific segment.
- *  const int seg_sz         : the size of the segment dst_buf will be
- *                             copied to.
- *  const zft_position *pos  : struct containing the coordinates in
- *                             the current volume (byte position,
- *                             segment id of current segment etc)
- *  const zft_volinfo *volume: information about the current volume,
- *                             size etc.
- *  const __u8 *src_buf      : user space buffer that contains the
- *                             data the user wants to be written to
- *                             tape.
- *  const int req_len        : the amount of data the user wants to be
- *                             written to tape.
- */
-static int zftc_write(int *write_cnt,
-                     __u8 *dst_buf, const int seg_sz,
-                     const __u8 __user *src_buf, const int req_len,
-                     const zft_position *pos, const zft_volinfo *volume)
-{
-       int req_len_left = req_len;
-       int result;
-       int len_left;
-       int buf_pos_write = pos->seg_byte_pos;
-       TRACE_FUN(ft_t_flow);
-       
-       /* Note: we do not unlock the module because
-        * there are some values cached in that `cseg' variable.  We
-        * don't don't want to use this information when being
-        * unloaded by kerneld even when the tape is full or when we
-        * cannot allocate enough memory.
-        */
-       if (pos->tape_pos > (volume->size-volume->blk_sz-ZFT_CMPR_OVERHEAD)) {
-               TRACE_EXIT -ENOSPC;
-       }    
-       if (zft_allocate_cmpr_mem(volume->blk_sz) < 0) {
-               /* should we unlock the module? But it shouldn't 
-                * be locked anyway ...
-                */
-               TRACE_EXIT -ENOMEM;
-       }
-       if (buf_pos_write == 0) { /* fill a new segment */
-               *write_cnt = buf_pos_write = start_new_cseg(&cseg,
-                                                           dst_buf,
-                                                           pos,
-                                                           volume->blk_sz,
-                                                           zftc_buf, 
-                                                           seg_sz,
-                                                           volume->qic113);
-               if (cseg.cmpr_sz == 0 && cseg.cmpr_pos != 0) {
-                       req_len_left -= result = volume->blk_sz;
-                       cseg.cmpr_pos  = 0;
-               } else {
-                       result = 0;
-               }
-       } else {
-               *write_cnt = result = 0;
-       }
-       
-       len_left = seg_sz - buf_pos_write;
-       while ((req_len_left > 0) && (len_left > 18)) {
-               /* now we have some size left for a new compressed
-                * block.  We know, that the compression buffer is
-                * empty (else there wouldn't be any space left).  
-                */
-               if (copy_from_user(zftc_scratch_buf, src_buf + result, 
-                                  volume->blk_sz) != 0) {
-                       TRACE_EXIT -EFAULT;
-               }
-               req_len_left -= volume->blk_sz;
-               cseg.cmpr_sz = zft_compress(zftc_scratch_buf, volume->blk_sz, 
-                                           zftc_buf);
-               if (cseg.cmpr_sz < 0) {
-                       cseg.uncmpr = 0x8000;
-                       cseg.cmpr_sz = -cseg.cmpr_sz;
-               } else {
-                       cseg.uncmpr = 0;
-               }
-               /* increment "result" iff we copied the entire
-                * compressed block to the zft_deblock_buf 
-                */
-               len_left -= sizeof(__u16);
-               if (len_left >= cseg.cmpr_sz) {
-                       len_left -= cseg.count = cseg.cmpr_sz;
-                       cseg.cmpr_pos = cseg.cmpr_sz = 0;
-                       result += volume->blk_sz;
-               } else {
-                       cseg.cmpr_sz       -= 
-                               cseg.cmpr_pos =
-                               cseg.count    = len_left;
-                       len_left = 0;
-               }
-               PUT2(dst_buf, buf_pos_write, cseg.uncmpr | cseg.count);
-               buf_pos_write += sizeof(__u16);
-               memcpy(dst_buf + buf_pos_write, zftc_buf, cseg.count);
-               buf_pos_write += cseg.count;
-               *write_cnt    += cseg.count + sizeof(__u16);
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-       }
-       /* erase the remainder of the segment if less than 18 bytes
-        * left (18 bytes is due to the QIC-80 standard) 
-        */
-       if (len_left <= 18) {
-               memset(dst_buf + buf_pos_write, '\0', len_left);
-               (*write_cnt) += len_left;
-       }
-       TRACE(ft_t_data_flow, "returning %d", result);
-       TRACE_EXIT result;
-}   
-
-/* out:
- *
- * int *read_cnt: the number of bytes we removed from the zft_deblock_buf
- *                (result)
- * int *to_do   : the remaining size of the read-request.
- *
- * in:
- *
- * char *buff          : buff is the address of the upper part of the user
- *                       buffer, that hasn't been filled with data yet.
-
- * int buf_pos_read    : copy of from _ftape_read()
- * int buf_len_read    : copy of buf_len_rd from _ftape_read()
- * char *zft_deblock_buf: zft_deblock_buf
- * unsigned short blk_sz: the block size valid for this volume, may differ
- *                            from zft_blk_sz.
- * int finish: if != 0 means that this is the last segment belonging
- *  to this volume
- * returns the amount of data actually copied to the user-buffer
- *
- * to_do MUST NOT SHRINK except to indicate an EOF. In this case *to_do has to
- * be set to 0 
- */
-static int zftc_read (int *read_cnt, 
-                     __u8  __user *dst_buf, const int to_do, 
-                     const __u8 *src_buf, const int seg_sz, 
-                     const zft_position *pos, const zft_volinfo *volume)
-{          
-       int uncompressed_sz;         
-       int result = 0;
-       int remaining = to_do;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE_CATCH(zft_allocate_cmpr_mem(volume->blk_sz),);
-       if (pos->seg_byte_pos == 0) {
-               /* new segment just read
-                */
-               TRACE_CATCH(get_cseg(&cseg, src_buf, seg_sz, volume),
-                           *read_cnt = 0);
-               memcpy(zftc_buf + cseg.cmpr_pos, src_buf + sizeof(__u16), 
-                      cseg.count);
-               cseg.cmpr_pos += cseg.count;
-               *read_cnt      = cseg.offset;
-               DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", &cseg);
-       } else {
-               *read_cnt = 0;
-       }
-       /* loop and uncompress until user buffer full or
-        * deblock-buffer empty 
-        */
-       TRACE(ft_t_data_flow, "compressed_sz: %d, compos : %d, *read_cnt: %d",
-             cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt);
-       while ((cseg.spans == 0) && (remaining > 0)) {
-               if (cseg.cmpr_pos  != 0) { /* cmpr buf is not empty */
-                       uncompressed_sz = 
-                               zft_uncompress(zftc_buf,
-                                              cseg.uncmpr == 0x8000 ?
-                                              -cseg.cmpr_pos : cseg.cmpr_pos,
-                                              zftc_scratch_buf,
-                                              volume->blk_sz);
-                       if (uncompressed_sz != volume->blk_sz) {
-                               *read_cnt = 0;
-                               TRACE_ABORT(-EIO, ft_t_warn,
-                                     "Uncompressed blk (%d) != blk size (%d)",
-                                     uncompressed_sz, volume->blk_sz);
-                       }       
-                       if (copy_to_user(dst_buf + result, 
-                                        zftc_scratch_buf, 
-                                        uncompressed_sz) != 0 ) {
-                               TRACE_EXIT -EFAULT;
-                       }
-                       remaining      -= uncompressed_sz;
-                       result     += uncompressed_sz;
-                       cseg.cmpr_pos  = 0;
-               }                                              
-               if (remaining > 0) {
-                       get_next_cluster(&cseg, src_buf, seg_sz, 
-                                        volume->end_seg == pos->seg_pos);
-                       if (cseg.count != 0) {
-                               memcpy(zftc_buf, src_buf + cseg.offset,
-                                      cseg.count);
-                               cseg.cmpr_pos = cseg.count;
-                               cseg.offset  += cseg.count;
-                               *read_cnt += cseg.count + sizeof(__u16);
-                       } else {
-                               remaining = 0;
-                       }
-               }
-               TRACE(ft_t_data_flow, "\n" 
-                     KERN_INFO "compressed_sz: %d\n"
-                     KERN_INFO "compos       : %d\n"
-                     KERN_INFO "*read_cnt    : %d",
-                     cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt);
-       }
-       if (seg_sz - cseg.offset <= 18) {
-               *read_cnt += seg_sz - cseg.offset;
-               TRACE(ft_t_data_flow, "expanding read cnt to: %d", *read_cnt);
-       }
-       TRACE(ft_t_data_flow, "\n"
-             KERN_INFO "segment size   : %d\n"
-             KERN_INFO "read count     : %d\n"
-             KERN_INFO "buf_pos_read   : %d\n"
-             KERN_INFO "remaining      : %d",
-               seg_sz, *read_cnt, pos->seg_byte_pos, 
-               seg_sz - *read_cnt - pos->seg_byte_pos);
-       TRACE(ft_t_data_flow, "returning: %d", result);
-       TRACE_EXIT result;
-}                
-
-/* seeks to the new data-position. Reads sometimes a segment.
- *  
- * start_seg and end_seg give the boundaries of the current volume
- * blk_sz is the blk_sz of the current volume as stored in the
- * volume label
- *
- * We don't allow blocksizes less than 1024 bytes, therefore we don't need
- * a 64 bit argument for new_block_pos.
- */
-
-static int seek_in_segment(const unsigned int to_do, cmpr_info  *c_info,
-                          const char *src_buf, const int seg_sz, 
-                          const int seg_pos, const zft_volinfo *volume);
-static int slow_seek_forward_until_error(const unsigned int distance,
-                                        cmpr_info *c_info, zft_position *pos, 
-                                        const zft_volinfo *volume, __u8 *buf);
-static int search_valid_segment(unsigned int segment,
-                               const unsigned int end_seg,
-                               const unsigned int max_foffs,
-                               zft_position *pos, cmpr_info *c_info,
-                               const zft_volinfo *volume, __u8 *buf);
-static int slow_seek_forward(unsigned int dest, cmpr_info *c_info,
-                            zft_position *pos, const zft_volinfo *volume,
-                            __u8 *buf);
-static int compute_seg_pos(unsigned int dest, zft_position *pos,
-                          const zft_volinfo *volume);
-
-#define ZFT_SLOW_SEEK_THRESHOLD  10 /* segments */
-#define ZFT_FAST_SEEK_MAX_TRIALS 10 /* times */
-#define ZFT_FAST_SEEK_BACKUP     10 /* segments */
-
-static int zftc_seek(unsigned int new_block_pos,
-                    zft_position *pos, const zft_volinfo *volume, __u8 *buf)
-{
-       unsigned int dest;
-       int limit;
-       int distance;
-       int result = 0;
-       int seg_dist;
-       int new_seg;
-       int old_seg = 0;
-       int fast_seek_trials = 0;
-       TRACE_FUN(ft_t_flow);
-
-       if (new_block_pos == 0) {
-               pos->seg_pos      = volume->start_seg;
-               pos->seg_byte_pos = 0;
-               pos->volume_pos   = 0;
-               zftc_reset();
-               TRACE_EXIT 0;
-       }
-       dest = new_block_pos * (volume->blk_sz >> 10);
-       distance = dest - (pos->volume_pos >> 10);
-       while (distance != 0) {
-               seg_dist = compute_seg_pos(dest, pos, volume);
-               TRACE(ft_t_noise, "\n"
-                     KERN_INFO "seg_dist: %d\n"
-                     KERN_INFO "distance: %d\n"
-                     KERN_INFO "dest    : %d\n"
-                     KERN_INFO "vpos    : %d\n"
-                     KERN_INFO "seg_pos : %d\n"
-                     KERN_INFO "trials  : %d",
-                     seg_dist, distance, dest,
-                     (unsigned int)(pos->volume_pos>>10), pos->seg_pos,
-                     fast_seek_trials);
-               if (distance > 0) {
-                       if (seg_dist < 0) {
-                               TRACE(ft_t_bug, "BUG: distance %d > 0, "
-                                     "segment difference %d < 0",
-                                     distance, seg_dist);
-                               result = -EIO;
-                               break;
-                       }
-                       new_seg = pos->seg_pos + seg_dist;
-                       if (new_seg > volume->end_seg) {
-                               new_seg = volume->end_seg;
-                       }
-                       if (old_seg == new_seg || /* loop */
-                           seg_dist <= ZFT_SLOW_SEEK_THRESHOLD ||
-                           fast_seek_trials >= ZFT_FAST_SEEK_MAX_TRIALS) {
-                               TRACE(ft_t_noise, "starting slow seek:\n"
-                                  KERN_INFO "fast seek failed too often: %s\n"
-                                  KERN_INFO "near target position      : %s\n"
-                                  KERN_INFO "looping between two segs  : %s",
-                                     (fast_seek_trials >= 
-                                      ZFT_FAST_SEEK_MAX_TRIALS)
-                                     ? "yes" : "no",
-                                     (seg_dist <= ZFT_SLOW_SEEK_THRESHOLD) 
-                                     ? "yes" : "no",
-                                     (old_seg == new_seg)
-                                     ? "yes" : "no");
-                               result = slow_seek_forward(dest, &cseg, 
-                                                          pos, volume, buf);
-                               break;
-                       }
-                       old_seg = new_seg;
-                       limit = volume->end_seg;
-                       fast_seek_trials ++;
-                       for (;;) {
-                               result = search_valid_segment(new_seg, limit,
-                                                             volume->size,
-                                                             pos, &cseg,
-                                                             volume, buf);
-                               if (result == 0 || result == -EINTR) {
-                                       break;
-                               }
-                               if (new_seg == volume->start_seg) {
-                                       result = -EIO; /* set errror 
-                                                       * condition
-                                                       */
-                                       break;
-                               }
-                               limit    = new_seg;
-                               new_seg -= ZFT_FAST_SEEK_BACKUP;
-                               if (new_seg < volume->start_seg) {
-                                       new_seg = volume->start_seg;
-                               }
-                       }
-                       if (result < 0) {
-                               TRACE(ft_t_warn,
-                                     "Couldn't find a readable segment");
-                               break;
-                       }
-               } else /* if (distance < 0) */ {
-                       if (seg_dist > 0) {
-                               TRACE(ft_t_bug, "BUG: distance %d < 0, "
-                                     "segment difference %d >0",
-                                     distance, seg_dist);
-                               result = -EIO;
-                               break;
-                       }
-                       new_seg = pos->seg_pos + seg_dist;
-                       if (fast_seek_trials > 0 && seg_dist == 0) {
-                               /* this avoids sticking to the same
-                                * segment all the time. On the other hand:
-                                * if we got here for the first time, and the
-                                * deblock_buffer still contains a valid
-                                * segment, then there is no need to skip to 
-                                * the previous segment if the desired position
-                                * is inside this segment.
-                                */
-                               new_seg --;
-                       }
-                       if (new_seg < volume->start_seg) {
-                               new_seg = volume->start_seg;
-                       }
-                       limit   = pos->seg_pos;
-                       fast_seek_trials ++;
-                       for (;;) {
-                               result = search_valid_segment(new_seg, limit,
-                                                             pos->volume_pos,
-                                                             pos, &cseg,
-                                                             volume, buf);
-                               if (result == 0 || result == -EINTR) {
-                                       break;
-                               }
-                               if (new_seg == volume->start_seg) {
-                                       result = -EIO; /* set errror 
-                                                       * condition
-                                                       */
-                                       break;
-                               }
-                               limit    = new_seg;
-                               new_seg -= ZFT_FAST_SEEK_BACKUP;
-                               if (new_seg < volume->start_seg) {
-                                       new_seg = volume->start_seg;
-                               }
-                       }
-                       if (result < 0) {
-                               TRACE(ft_t_warn,
-                                     "Couldn't find a readable segment");
-                               break;
-                       }
-               }
-               distance = dest - (pos->volume_pos >> 10);
-       }
-       TRACE_EXIT result;
-}
-
-
-/*  advance inside the given segment at most to_do bytes.
- *  of kilobytes moved
- */
-
-static int seek_in_segment(const unsigned int to_do,
-                          cmpr_info  *c_info,
-                          const char *src_buf, 
-                          const int seg_sz, 
-                          const int seg_pos,
-                          const zft_volinfo *volume)
-{
-       int result = 0;
-       int blk_sz = volume->blk_sz >> 10;
-       int remaining = to_do;
-       TRACE_FUN(ft_t_flow);
-
-       if (c_info->offset == 0) {
-               /* new segment just read
-                */
-               TRACE_CATCH(get_cseg(c_info, src_buf, seg_sz, volume),);
-               c_info->cmpr_pos += c_info->count;
-               DUMP_CMPR_INFO(ft_t_noise, "", c_info);
-       }
-       /* loop and uncompress until user buffer full or
-        * deblock-buffer empty 
-        */
-       TRACE(ft_t_noise, "compressed_sz: %d, compos : %d",
-             c_info->cmpr_sz, c_info->cmpr_pos);
-       while (c_info->spans == 0 && remaining > 0) {
-               if (c_info->cmpr_pos  != 0) { /* cmpr buf is not empty */
-                       result       += blk_sz;
-                       remaining    -= blk_sz;
-                       c_info->cmpr_pos = 0;
-               }
-               if (remaining > 0) {
-                       get_next_cluster(c_info, src_buf, seg_sz, 
-                                        volume->end_seg == seg_pos);
-                       if (c_info->count != 0) {
-                               c_info->cmpr_pos = c_info->count;
-                               c_info->offset  += c_info->count;
-                       } else {
-                               break;
-                       }
-               }
-               /*  Allow escape from this loop on signal!
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               DUMP_CMPR_INFO(ft_t_noise, "", c_info);
-               TRACE(ft_t_noise, "to_do: %d", remaining);
-       }
-       if (seg_sz - c_info->offset <= 18) {
-               c_info->offset = seg_sz;
-       }
-       TRACE(ft_t_noise, "\n"
-             KERN_INFO "segment size   : %d\n"
-             KERN_INFO "buf_pos_read   : %d\n"
-             KERN_INFO "remaining      : %d",
-             seg_sz, c_info->offset,
-             seg_sz - c_info->offset);
-       TRACE_EXIT result;
-}                
-
-static int slow_seek_forward_until_error(const unsigned int distance,
-                                        cmpr_info *c_info,
-                                        zft_position *pos, 
-                                        const zft_volinfo *volume,
-                                        __u8 *buf)
-{
-       unsigned int remaining = distance;
-       int seg_sz;
-       int seg_pos;
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       seg_pos = pos->seg_pos;
-       do {
-               TRACE_CATCH(seg_sz = zft_fetch_segment(seg_pos, buf, 
-                                                      FT_RD_AHEAD),);
-               /* now we have the contents of the actual segment in
-                * the deblock buffer
-                */
-               TRACE_CATCH(result = seek_in_segment(remaining, c_info, buf,
-                                                    seg_sz, seg_pos,volume),);
-               remaining        -= result;
-               pos->volume_pos  += result<<10;
-               pos->seg_pos      = seg_pos;
-               pos->seg_byte_pos = c_info->offset;
-               seg_pos ++;
-               if (seg_pos <= volume->end_seg && c_info->offset == seg_sz) {
-                       pos->seg_pos ++;
-                       pos->seg_byte_pos = 0;
-                       c_info->offset = 0;
-               }
-               /*  Allow escape from this loop on signal!
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               TRACE(ft_t_noise, "\n"
-                     KERN_INFO "remaining:  %d\n"
-                     KERN_INFO "seg_pos:    %d\n"
-                     KERN_INFO "end_seg:    %d\n"
-                     KERN_INFO "result:     %d",
-                     remaining, seg_pos, volume->end_seg, result);  
-       } while (remaining > 0 && seg_pos <= volume->end_seg);
-       TRACE_EXIT 0;
-}
-
-/* return segment id of next segment containing valid data, -EIO otherwise
- */
-static int search_valid_segment(unsigned int segment,
-                               const unsigned int end_seg,
-                               const unsigned int max_foffs,
-                               zft_position *pos,
-                               cmpr_info *c_info,
-                               const zft_volinfo *volume,
-                               __u8 *buf)
-{
-       cmpr_info tmp_info;
-       int seg_sz;
-       TRACE_FUN(ft_t_flow);
-       
-       memset(&tmp_info, 0, sizeof(cmpr_info));
-       while (segment <= end_seg) {
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               TRACE(ft_t_noise,
-                     "Searching readable segment between %d and %d",
-                     segment, end_seg);
-               seg_sz = zft_fetch_segment(segment, buf, FT_RD_AHEAD);
-               if ((seg_sz > 0) &&
-                   (get_cseg (&tmp_info, buf, seg_sz, volume) >= 0) &&
-                   (tmp_info.foffs != 0 || segment == volume->start_seg)) {
-                       if ((tmp_info.foffs>>10) > max_foffs) {
-                               TRACE_ABORT(-EIO, ft_t_noise, "\n"
-                                           KERN_INFO "cseg.foff: %d\n"
-                                           KERN_INFO "dest     : %d",
-                                           (int)(tmp_info.foffs >> 10),
-                                           max_foffs);
-                       }
-                       DUMP_CMPR_INFO(ft_t_noise, "", &tmp_info);
-                       *c_info           = tmp_info;
-                       pos->seg_pos      = segment;
-                       pos->volume_pos   = c_info->foffs;
-                       pos->seg_byte_pos = c_info->offset;
-                       TRACE(ft_t_noise, "found segment at %d", segment);
-                       TRACE_EXIT 0;
-               }
-               segment++;
-       }
-       TRACE_EXIT -EIO;
-}
-
-static int slow_seek_forward(unsigned int dest,
-                            cmpr_info *c_info,
-                            zft_position *pos,
-                            const zft_volinfo *volume,
-                            __u8 *buf)
-{
-       unsigned int distance;
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-               
-       distance = dest - (pos->volume_pos >> 10);
-       while ((distance > 0) &&
-              (result = slow_seek_forward_until_error(distance,
-                                                      c_info,
-                                                      pos,
-                                                      volume,
-                                                      buf)) < 0) {
-               if (result == -EINTR) {
-                       break;
-               }
-               TRACE(ft_t_noise, "seg_pos: %d", pos->seg_pos);
-               /* the failing segment is either pos->seg_pos or
-                * pos->seg_pos + 1. There is no need to further try
-                * that segment, because ftape_read_segment() already
-                * has tried very much to read it. So we start with
-                * following segment, which is pos->seg_pos + 1
-                */
-               if(search_valid_segment(pos->seg_pos+1, volume->end_seg, dest,
-                                       pos, c_info,
-                                       volume, buf) < 0) {
-                       TRACE(ft_t_noise, "search_valid_segment() failed");
-                       result = -EIO;
-                       break;
-               }
-               distance = dest - (pos->volume_pos >> 10);
-               result = 0;
-               TRACE(ft_t_noise, "segment: %d", pos->seg_pos);
-               /* found valid segment, retry the seek */
-       }
-       TRACE_EXIT result;
-}
-
-static int compute_seg_pos(const unsigned int dest,
-                          zft_position *pos,
-                          const zft_volinfo *volume)
-{
-       int segment;
-       int distance = dest - (pos->volume_pos >> 10);
-       unsigned int raw_size;
-       unsigned int virt_size;
-       unsigned int factor;
-       TRACE_FUN(ft_t_flow);
-
-       if (distance >= 0) {
-               raw_size  = volume->end_seg - pos->seg_pos + 1;
-               virt_size = ((unsigned int)(volume->size>>10) 
-                            - (unsigned int)(pos->volume_pos>>10)
-                            + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);
-               virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;
-               if (virt_size == 0 || raw_size == 0) {
-                       TRACE_EXIT 0;
-               }
-               if (raw_size >= (1<<25)) {
-                       factor = raw_size/(virt_size>>7);
-               } else {
-                       factor = (raw_size<<7)/virt_size;
-               }
-               segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);
-               segment = (segment * factor)>>7;
-       } else {
-               raw_size  = pos->seg_pos - volume->start_seg + 1;
-               virt_size = ((unsigned int)(pos->volume_pos>>10)
-                            + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);
-               virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;
-               if (virt_size == 0 || raw_size == 0) {
-                       TRACE_EXIT 0;
-               }
-               if (raw_size >= (1<<25)) {
-                       factor = raw_size/(virt_size>>7);
-               } else {
-                       factor = (raw_size<<7)/virt_size;
-               }
-               segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);
-       }
-       TRACE(ft_t_noise, "factor: %d/%d", factor, 1<<7);
-       TRACE_EXIT segment;
-}
-
-static struct zft_cmpr_ops cmpr_ops = {
-       zftc_write,
-       zftc_read,
-       zftc_seek,
-       zftc_lock,
-       zftc_reset,
-       zftc_cleanup
-};
-
-int zft_compressor_init(void)
-{
-       TRACE_FUN(ft_t_flow);
-       
-#ifdef MODULE
-       printk(KERN_INFO "zftape compressor v1.00a 970514 for " FTAPE_VERSION "\n");
-        if (TRACE_LEVEL >= ft_t_info) {
-               printk(
-KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
-        }
-#else /* !MODULE */
-       /* print a short no-nonsense boot message */
-       printk(KERN_INFO "zftape compressor v1.00a 970514\n");
-       printk(KERN_INFO "For use with " FTAPE_VERSION "\n");
-#endif /* MODULE */
-       TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
-       TRACE(ft_t_info, "installing compressor for zftape ...");
-       TRACE_CATCH(zft_cmpr_register(&cmpr_ops),);
-       TRACE_EXIT 0;
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR(
-       "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de");
-MODULE_DESCRIPTION(
-"Compression routines for zftape. Uses the lzrw3 algorithm by Ross Williams");
-MODULE_LICENSE("GPL");
-
-/* Called by modules package when installing the driver
- */
-int init_module(void)
-{
-       return zft_compressor_init();
-}
-
-#endif /* MODULE */
diff --git a/drivers/char/ftape/compressor/zftape-compress.h b/drivers/char/ftape/compressor/zftape-compress.h
deleted file mode 100644 (file)
index f200741..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef _ZFTAPE_COMPRESS_H
-#define _ZFTAPE_COMPRESS_H
-/*
- *      Copyright (c) 1994-1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/compressor/zftape-compress.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/10/05 19:12:32 $
- *
- * This file contains macros and definitions for zftape's
- * builtin compression code.
- *
- */
-
-#include "../zftape/zftape-buffers.h"
-#include "../zftape/zftape-vtbl.h"
-#include "../compressor/lzrw3.h"
-
-/* CMPR_WRK_MEM_SIZE gives the size of the compression wrk_mem */
-/* I got these out of lzrw3.c */
-#define U(X)            ((__u32) X)
-#define SIZE_P_BYTE     (U(sizeof(__u8 *)))
-#define ALIGNMENT_FUDGE (U(16))
-
-#define CMPR_WRK_MEM_SIZE (U(4096)*(SIZE_P_BYTE) + ALIGNMENT_FUDGE)
-
-/* the maximum number of bytes the size of the "compressed" data can
- * exceed the uncompressed data. As it is quite useless to compress
- * data twice it is sometimes the case that it is more efficient to
- * copy a block of data but to feed it to the "compression"
- * algorithm. In this case there are some flag bytes or the like
- * proceding the "compressed" data.  THAT MUST NOT BE THE CASE for the
- * algorithm we use for this driver. Instead, the high bit 15 of
- * compressed_size:
- *
- * compressed_size = ftape_compress()
- *
- * must be set in such a case.
- *
- * Nevertheless, it might also be as for lzrw3 that there is an
- * "intermediate" overrun that exceeds the amount of the compressed
- * data that is actually produced. During the algorithm we need in the
- * worst case MAX_CMP_GROUP bytes more than the input-size.
- */
-#define MAX_CMP_GROUP (2+16*2) /* from lzrw3.c */
-
-#define CMPR_OVERRUN      MAX_CMP_GROUP /* during compression */
-
-/****************************************************/
-
-#define     CMPR_BUFFER_SIZE (MAX_BLOCK_SIZE + CMPR_OVERRUN)
-
-/* the compression map stores the byte offset compressed blocks within
- * the current volume for catridges with format code 2,3 and 5
- * (and old versions of zftape) and the offset measured in kilobytes for
- * format code 4 and 6. This gives us a possible max. size of a 
- * compressed volume of 1024*4GIG which should be enough.
- */
-typedef __u32 CmprMap;
-
-/* globals 
- */
-
-/* exported functions
- */
-
-#endif /* _ZFTAPE_COMPRESS_H */
diff --git a/drivers/char/ftape/lowlevel/Makefile b/drivers/char/ftape/lowlevel/Makefile
deleted file mode 100644 (file)
index febab07..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-#       Copyright (C) 1996, 1997 Clau-Justus Heine.
-#
-# This program 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, 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; see the file COPYING.  If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/Makefile,v $
-# $Revision: 1.4 $
-# $Date: 1997/10/07 09:26:02 $
-#
-#      Makefile for the lowlevel part QIC-40/80/3010/3020 floppy-tape
-#      driver for Linux.
-#
-
-obj-$(CONFIG_FTAPE) += ftape.o
-
-ftape-objs := ftape-init.o fdc-io.o fdc-isr.o \
-             ftape-bsm.o ftape-ctl.o ftape-read.o ftape-rw.o \
-             ftape-write.o ftape-io.o ftape-calibr.o ftape-ecc.o fc-10.o \
-             ftape-buffer.o ftape-format.o ftape_syms.o
-
-ifeq ($(CONFIG_FTAPE),y)
-ftape-objs += ftape-setup.o
-endif
-
-ifndef CONFIG_FT_NO_TRACE_AT_ALL
-ftape-objs += ftape-tracing.o
-endif
-
-ifeq ($(CONFIG_FT_PROC_FS),y)
-ftape-objs += ftape-proc.o
-endif
diff --git a/drivers/char/ftape/lowlevel/fc-10.c b/drivers/char/ftape/lowlevel/fc-10.c
deleted file mode 100644 (file)
index 9bc1cdd..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- *
-
-   Copyright (C) 1993,1994 Jon Tombs.
-
-   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.
-
-   The entire guts of this program was written by dosemu, modified to
-   record reads and writes to the ports in the 0x180-0x188 address space,
-   while running the CMS program TAPE.EXE V2.0.5 supplied with the drive.
-
-   Modified to use an array of addresses and generally cleaned up (made
-   much shorter) 4 June 94, dosemu isn't that good at writing short code it
-   would seem :-). Made independent of 0x180, but I doubt it will work
-   at any other address.
-
-   Modified for distribution with ftape source. 21 June 94, SJL.
-
-   Modifications on 20 October 95, by Daniel Cohen (catman@wpi.edu):
-   Modified to support different DMA, IRQ, and IO Ports.  Borland's
-   Turbo Debugger in virtual 8086 mode (TD386.EXE with hardware breakpoints
-   provided by the TDH386.SYS Device Driver) was used on the CMS program
-   TAPE V4.0.5.  I set breakpoints on I/O to ports 0x180-0x187.  Note that
-   CMS's program will not successfully configure the tape drive if you set
-   breakpoints on IO Reads, but you can set them on IO Writes without problems.
-   Known problems:
-   - You can not use DMA Channels 5 or 7.
-
-   Modification on 29 January 96, by Daniel Cohen (catman@wpi.edu):
-   Modified to only accept IRQs 3 - 7, or 9.  Since we can only send a 3 bit
-   number representing the IRQ to the card, special handling is required when
-   IRQ 9 is selected.  IRQ 2 and 9 are the same, and we should request IRQ 9
-   from the kernel while telling the card to use IRQ 2.  Thanks to Greg
-   Crider (gcrider@iclnet.org) for finding and locating this bug, as well as
-   testing the patch.
-
-   Modification on 11 December 96, by Claus Heine (claus@momo.math.rwth-aachen.de):
-   Modified a little to use variahle ft_fdc_base, ft_fdc_irq, ft_fdc_dma 
-   instead of preprocessor symbols. Thus we can compile this into the module
-   or kernel and let the user specify the options as command line arguments.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fc-10.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:04 $
- *
- *      This file contains code for the CMS FC-10/FC-20 card.
- */
-
-#include <asm/io.h>
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/fc-10.h"
-
-static __u16 inbs_magic[] = {
-       0x3, 0x3, 0x0, 0x4, 0x7, 0x2, 0x5, 0x3, 0x1, 0x4,
-       0x3, 0x5, 0x2, 0x0, 0x3, 0x7, 0x4, 0x2,
-       0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
-};
-
-static __u16 fc10_ports[] = {
-       0x180, 0x210, 0x2A0, 0x300, 0x330, 0x340, 0x370
-};
-
-int fc10_enable(void)
-{
-       int i;
-       __u8 cardConfig = 0x00;
-       __u8 x;
-       TRACE_FUN(ft_t_flow);
-
-/*  This code will only work if the FC-10 (or FC-20) is set to
- *  use DMA channels 1, 2, or 3.  DMA channels 5 and 7 seem to be 
- *  initialized by the same command as channels 1 and 3, respectively.
- */
-       if (ft_fdc_dma > 3) {
-               TRACE_ABORT(0, ft_t_err,
-"Error: The FC-10/20 must be set to use DMA channels 1, 2, or 3!");
-       }
-/*  Only allow the FC-10/20 to use IRQ 3-7, or 9.  Note that CMS's program
- *  only accepts IRQ's 2-7, but in linux, IRQ 2 is the same as IRQ 9.
- */
-       if (ft_fdc_irq < 3 || ft_fdc_irq == 8 || ft_fdc_irq > 9) {
-               TRACE_ABORT(0, ft_t_err, 
-"Error: The FC-10/20 must be set to use IRQ levels 3 - 7, or 9!\n"
-KERN_INFO "Note: IRQ 9 is the same as IRQ 2");
-       }
-       /*  Clear state machine ???
-        */
-       for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
-               inb(ft_fdc_base + inbs_magic[i]);
-       }
-       outb(0x0, ft_fdc_base);
-
-       x = inb(ft_fdc_base);
-       if (x == 0x13 || x == 0x93) {
-               for (i = 1; i < 8; i++) {
-                       if (inb(ft_fdc_base + i) != x) {
-                               TRACE_EXIT 0;
-                       }
-               }
-       } else {
-               TRACE_EXIT 0;
-       }
-
-       outb(0x8, ft_fdc_base);
-
-       for (i = 0; i < 8; i++) {
-               if (inb(ft_fdc_base + i) != 0x0) {
-                       TRACE_EXIT 0;
-               }
-       }
-       outb(0x10, ft_fdc_base);
-
-       for (i = 0; i < 8; i++) {
-               if (inb(ft_fdc_base + i) != 0xff) {
-                       TRACE_EXIT 0;
-               }
-       }
-
-       /*  Okay, we found a FC-10 card ! ???
-        */
-       outb(0x0, fdc.ccr);
-
-       /*  Clear state machine again ???
-        */
-       for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
-               inb(ft_fdc_base + inbs_magic[i]);
-       }
-       /* Send io port */
-       for (i = 0; i < NR_ITEMS(fc10_ports); i++)
-               if (ft_fdc_base == fc10_ports[i])
-                       cardConfig = i + 1;
-       if (cardConfig == 0) {
-               TRACE_EXIT 0;   /* Invalid I/O Port */
-       }
-       /* and IRQ - If using IRQ 9, tell the FC card it is actually IRQ 2 */
-       if (ft_fdc_irq != 9)
-               cardConfig |= ft_fdc_irq << 3;
-       else
-               cardConfig |= 2 << 3;
-
-       /* and finally DMA Channel */
-       cardConfig |= ft_fdc_dma << 6;
-       outb(cardConfig, ft_fdc_base);  /* DMA [2 bits]/IRQ [3 bits]/BASE [3 bits] */
-
-       /*  Enable FC-10 ???
-        */
-       outb(0, fdc.ccr);
-       outb(0, fdc.dor2);
-       outb(FDC_DMA_MODE /* 8 */, fdc.dor);
-       outb(FDC_DMA_MODE /* 8 */, fdc.dor);
-       outb(1, fdc.dor2);
-
-       /*************************************
-        *
-        * cH: why the hell should this be necessary? This is done 
-        *     by fdc_reset()!!!
-        *
-        *************************************/
-       /*  Initialize fdc, select drive B:
-        */
-       outb(FDC_DMA_MODE, fdc.dor);    /* assert reset, dma & irq enabled */
-       /*       0x08    */
-       outb(FDC_DMA_MODE|FDC_RESET_NOT, fdc.dor);      /* release reset */
-       /*       0x08    |   0x04   = 0x0c */
-       outb(FDC_DMA_MODE|FDC_RESET_NOT|FDC_MOTOR_1|FTAPE_SEL_B, fdc.dor);
-       /*       0x08    |   0x04      |  0x20     |  0x01  = 0x2d */    
-       /* select drive 1 */ /* why not drive 0 ???? */
-       TRACE_EXIT (x == 0x93) ? 2 : 1;
-}
diff --git a/drivers/char/ftape/lowlevel/fc-10.h b/drivers/char/ftape/lowlevel/fc-10.h
deleted file mode 100644 (file)
index da7b88b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _FC_10_H
-#define _FC_10_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fc-10.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/09/19 09:05:22 $
- *
- *      This file contains definitions for the FC-10 code
- *      of the QIC-40/80 floppy-tape driver for Linux.
- */
-
-/*
- *      fc-10.c defined global vars.
- */
-
-/*
- *      fc-10.c defined global functions.
- */
-extern int fc10_enable(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c
deleted file mode 100644 (file)
index bbcf918..0000000
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.c,v $
- * $Revision: 1.7.4.2 $
- * $Date: 1997/11/16 14:48:17 $
- *
- *      This file contains the low-level floppy disk interface code
- *      for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
- *      Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/fdc-isr.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-calibr.h"
-#include "../lowlevel/fc-10.h"
-
-/*      Global vars.
- */
-static int ftape_motor;
-volatile int ftape_current_cylinder = -1;
-volatile fdc_mode_enum fdc_mode = fdc_idle;
-fdc_config_info fdc;
-DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr);
-
-unsigned int ft_fdc_base       = CONFIG_FT_FDC_BASE;
-unsigned int ft_fdc_irq        = CONFIG_FT_FDC_IRQ;
-unsigned int ft_fdc_dma        = CONFIG_FT_FDC_DMA;
-unsigned int ft_fdc_threshold  = CONFIG_FT_FDC_THR;  /* bytes */
-unsigned int ft_fdc_rate_limit = CONFIG_FT_FDC_MAX_RATE; /* bits/sec */
-int ft_probe_fc10        = CONFIG_FT_PROBE_FC10;
-int ft_mach2             = CONFIG_FT_MACH2;
-
-/*      Local vars.
- */
-static spinlock_t fdc_io_lock; 
-static unsigned int fdc_calibr_count;
-static unsigned int fdc_calibr_time;
-static int fdc_status;
-volatile __u8 fdc_head;                /* FDC head from sector id */
-volatile __u8 fdc_cyl;         /* FDC track from sector id */
-volatile __u8 fdc_sect;                /* FDC sector from sector id */
-static int fdc_data_rate = 500;        /* data rate (Kbps) */
-static int fdc_rate_code;      /* data rate code (0 == 500 Kbps) */
-static int fdc_seek_rate = 2;  /* step rate (msec) */
-static void (*do_ftape) (void);
-static int fdc_fifo_state;     /* original fifo setting - fifo enabled */
-static int fdc_fifo_thr;       /* original fifo setting - threshold */
-static int fdc_lock_state;     /* original lock setting - locked */
-static int fdc_fifo_locked;    /* has fifo && lock set ? */
-static __u8 fdc_precomp;       /* default precomp. value (nsec) */
-static __u8 fdc_prec_code;     /* fdc precomp. select code */
-
-static char ftape_id[] = "ftape";  /* used by request irq and free irq */
-
-static int fdc_set_seek_rate(int seek_rate);
-
-void fdc_catch_stray_interrupts(int count)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&fdc_io_lock, flags);
-       if (count == 0) {
-               ft_expected_stray_interrupts = 0;
-       } else {
-               ft_expected_stray_interrupts += count;
-       }
-       spin_unlock_irqrestore(&fdc_io_lock, flags);
-}
-
-/*  Wait during a timeout period for a given FDC status.
- *  If usecs == 0 then just test status, else wait at least for usecs.
- *  Returns -ETIME on timeout. Function must be calibrated first !
- */
-static int fdc_wait(unsigned int usecs, __u8 mask, __u8 state)
-{
-       int count_1 = (fdc_calibr_count * usecs +
-                       fdc_calibr_count - 1) / fdc_calibr_time;
-
-       do {
-               fdc_status = inb_p(fdc.msr);
-               if ((fdc_status & mask) == state) {
-                       return 0;
-               }
-       } while (count_1-- >= 0);
-       return -ETIME;
-}
-
-int fdc_ready_wait(unsigned int usecs)
-{
-       return fdc_wait(usecs, FDC_DATA_READY | FDC_BUSY, FDC_DATA_READY);
-}
-
-/* Why can't we just use udelay()?
- */
-static void fdc_usec_wait(unsigned int usecs)
-{
-       fdc_wait(usecs, 0, 1);  /* will always timeout ! */
-}
-
-static int fdc_ready_out_wait(unsigned int usecs)
-{
-       fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
-       return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_OUT_READY);
-}
-
-void fdc_wait_calibrate(void)
-{
-       ftape_calibrate("fdc_wait",
-                       fdc_usec_wait, &fdc_calibr_count, &fdc_calibr_time); 
-}
-
-/*  Wait for a (short) while for the FDC to become ready
- *  and transfer the next command byte.
- *  Return -ETIME on timeout on getting ready (depends on hardware!).
- */
-static int fdc_write(const __u8 data)
-{
-       fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
-       if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_IN_READY) < 0) {
-               return -ETIME;
-       } else {
-               outb(data, fdc.fifo);
-               return 0;
-       }
-}
-
-/*  Wait for a (short) while for the FDC to become ready
- *  and transfer the next result byte.
- *  Return -ETIME if timeout on getting ready (depends on hardware!).
- */
-static int fdc_read(__u8 * data)
-{
-       fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
-       if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_OUT_READY) < 0) {
-               return -ETIME;
-       } else {
-               *data = inb(fdc.fifo);
-               return 0;
-       }
-}
-
-/*  Output a cmd_len long command string to the FDC.
- *  The FDC should be ready to receive a new command or
- *  an error (EBUSY or ETIME) will occur.
- */
-int fdc_command(const __u8 * cmd_data, int cmd_len)
-{
-       int result = 0;
-       unsigned long flags;
-       int count = cmd_len;
-       int retry = 0;
-#ifdef TESTING
-       static unsigned int last_time;
-       unsigned int time;
-#endif
-       TRACE_FUN(ft_t_any);
-
-       fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
-       spin_lock_irqsave(&fdc_io_lock, flags);
-       if (!in_interrupt())
-               /* Yes, I know, too much comments inside this function
-                * ...
-                * 
-                * Yet another bug in the original driver. All that
-                * havoc is caused by the fact that the isr() sends
-                * itself a command to the floppy tape driver (pause,
-                * micro step pause).  Now, the problem is that
-                * commands are transmitted via the fdc_seek
-                * command. But: the fdc performs seeks in the
-                * background i.e. it doesn't signal busy while
-                * sending the step pulses to the drive. Therefore the
-                * non-interrupt level driver has no chance to tell
-                * whether the isr() just has issued a seek. Therefore
-                * we HAVE TO have a look at the ft_hide_interrupt
-                * flag: it signals the non-interrupt level part of
-                * the driver that it has to wait for the fdc until it
-                * has completet seeking.
-                *
-                * THIS WAS PRESUMABLY THE REASON FOR ALL THAT
-                * "fdc_read timeout" errors, I HOPE :-)
-                */
-               if (ft_hide_interrupt) {
-                       restore_flags(flags);
-                       TRACE(ft_t_info,
-                             "Waiting for the isr() completing fdc_seek()");
-                       if (fdc_interrupt_wait(2 * FT_SECOND) < 0) {
-                               TRACE(ft_t_warn,
-                     "Warning: timeout waiting for isr() seek to complete");
-                       }
-                       if (ft_hide_interrupt || !ft_seek_completed) {
-                               /* There cannot be another
-                                * interrupt. The isr() only stops
-                                * the tape and the next interrupt
-                                * won't come until we have send our
-                                * command to the drive.
-                                */
-                               TRACE_ABORT(-EIO, ft_t_bug,
-                                           "BUG? isr() is still seeking?\n"
-                                           KERN_INFO "hide: %d\n"
-                                           KERN_INFO "seek: %d",
-                                           ft_hide_interrupt,
-                                           ft_seek_completed);
-
-                       }
-                       fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
-                       spin_lock_irqsave(&fdc_io_lock, flags);
-               }
-       fdc_status = inb(fdc.msr);
-       if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) {
-               spin_unlock_irqrestore(&fdc_io_lock, flags);
-               TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready");
-       } 
-       fdc_mode = *cmd_data;   /* used by isr */
-#ifdef TESTING
-       if (fdc_mode == FDC_SEEK) {
-               time = ftape_timediff(last_time, ftape_timestamp());
-               if (time < 6000) {
-       TRACE(ft_t_bug,"Warning: short timeout between seek commands: %d",
-             time);
-               }
-       }
-#endif
-       if (!in_interrupt()) {
-               /* shouldn't be cleared if called from isr
-                */
-               ft_interrupt_seen = 0;
-       }
-       while (count) {
-               result = fdc_write(*cmd_data);
-               if (result < 0) {
-                       TRACE(ft_t_fdc_dma,
-                             "fdc_mode = %02x, status = %02x at index %d",
-                             (int) fdc_mode, (int) fdc_status,
-                             cmd_len - count);
-                       if (++retry <= 3) {
-                               TRACE(ft_t_warn, "fdc_write timeout, retry");
-                       } else {
-                               TRACE(ft_t_err, "fdc_write timeout, fatal");
-                               /* recover ??? */
-                               break;
-                       }
-               } else {
-                       --count;
-                       ++cmd_data;
-               }
-        }
-#ifdef TESTING
-       if (fdc_mode == FDC_SEEK) {
-               last_time = ftape_timestamp();
-       }
-#endif
-       spin_unlock_irqrestore(&fdc_io_lock, flags);
-       TRACE_EXIT result;
-}
-
-/*  Input a res_len long result string from the FDC.
- *  The FDC should be ready to send the result or an error
- *  (EBUSY or ETIME) will occur.
- */
-int fdc_result(__u8 * res_data, int res_len)
-{
-       int result = 0;
-       unsigned long flags;
-       int count = res_len;
-       int retry = 0;
-       TRACE_FUN(ft_t_any);
-
-       spin_lock_irqsave(&fdc_io_lock, flags);
-       fdc_status = inb(fdc.msr);
-       if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) {
-               TRACE(ft_t_err, "fdc not ready");
-               result = -EBUSY;
-       } else while (count) {
-               if (!(fdc_status & FDC_BUSY)) {
-                       spin_unlock_irqrestore(&fdc_io_lock, flags);
-                       TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase");
-               }
-               result = fdc_read(res_data);
-               if (result < 0) {
-                       TRACE(ft_t_fdc_dma,
-                             "fdc_mode = %02x, status = %02x at index %d",
-                             (int) fdc_mode,
-                             (int) fdc_status,
-                             res_len - count);
-                       if (++retry <= 3) {
-                               TRACE(ft_t_warn, "fdc_read timeout, retry");
-                       } else {
-                               TRACE(ft_t_err, "fdc_read timeout, fatal");
-                               /* recover ??? */
-                               break;
-                               ++retry;
-                       }
-               } else {
-                       --count;
-                       ++res_data;
-               }
-       }
-       spin_unlock_irqrestore(&fdc_io_lock, flags);
-       fdc_usec_wait(FT_RQM_DELAY);    /* allow FDC to negate BSY */
-       TRACE_EXIT result;
-}
-
-/*      Handle command and result phases for
- *      commands without data phase.
- */
-static int fdc_issue_command(const __u8 * out_data, int out_count,
-                     __u8 * in_data, int in_count)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (out_count > 0) {
-               TRACE_CATCH(fdc_command(out_data, out_count),);
-       }
-       /* will take 24 - 30 usec for fdc_sense_drive_status and
-        * fdc_sense_interrupt_status commands.
-        *    35 fails sometimes (5/9/93 SJL)
-        * On a loaded system it incidentally takes longer than
-        * this for the fdc to get ready ! ?????? WHY ??????
-        * So until we know what's going on use a very long timeout.
-        */
-       TRACE_CATCH(fdc_ready_out_wait(500 /* usec */),);
-       if (in_count > 0) {
-               TRACE_CATCH(fdc_result(in_data, in_count),
-                           TRACE(ft_t_err, "result phase aborted"));
-       }
-       TRACE_EXIT 0;
-}
-
-/*      Wait for FDC interrupt with timeout (in milliseconds).
- *      Signals are blocked so the wait will not be aborted.
- *      Note: interrupts must be enabled ! (23/05/93 SJL)
- */
-int fdc_interrupt_wait(unsigned int time)
-{
-       DECLARE_WAITQUEUE(wait,current);
-       sigset_t old_sigmask;   
-       static int resetting;
-       long timeout;
-
-       TRACE_FUN(ft_t_fdc_dma);
-
-       if (waitqueue_active(&ftape_wait_intr)) {
-               TRACE_ABORT(-EIO, ft_t_err, "error: nested call");
-       }
-       /* timeout time will be up to USPT microseconds too long ! */
-       timeout = (1000 * time + FT_USPT - 1) / FT_USPT;
-
-       spin_lock_irq(&current->sighand->siglock);
-       old_sigmask = current->blocked;
-       sigfillset(&current->blocked);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-
-       set_current_state(TASK_INTERRUPTIBLE);
-       add_wait_queue(&ftape_wait_intr, &wait);
-       while (!ft_interrupt_seen && timeout)
-               timeout = schedule_timeout_interruptible(timeout);
-
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = old_sigmask;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-       
-       remove_wait_queue(&ftape_wait_intr, &wait);
-       /*  the following IS necessary. True: as well
-        *  wake_up_interruptible() as the schedule() set TASK_RUNNING
-        *  when they wakeup a task, BUT: it may very well be that
-        *  ft_interrupt_seen is already set to 1 when we enter here
-        *  in which case schedule() gets never called, and
-        *  TASK_RUNNING never set. This has the funny effect that we
-        *  execute all the code until we leave kernel space, but then
-        *  the task is stopped (a task CANNOT be preempted while in
-        *  kernel mode. Sending a pair of SIGSTOP/SIGCONT to the
-        *  tasks wakes it up again. Funny! :-)
-        */
-       current->state = TASK_RUNNING; 
-       if (ft_interrupt_seen) { /* woken up by interrupt */
-               ft_interrupt_seen = 0;
-               TRACE_EXIT 0;
-       }
-       /*  Original comment:
-        *  In first instance, next statement seems unnecessary since
-        *  it will be cleared in fdc_command. However, a small part of
-        *  the software seems to rely on this being cleared here
-        *  (ftape_close might fail) so stick to it until things get fixed !
-        */
-       /*  My deeply sought of knowledge:
-        *  Behold NO! It is obvious. fdc_reset() doesn't call fdc_command()
-        *  but nevertheless uses fdc_interrupt_wait(). OF COURSE this needs to
-        *  be reset here.
-        */
-       ft_interrupt_seen = 0;  /* clear for next call */
-       if (!resetting) {
-               resetting = 1;  /* break infinite recursion if reset fails */
-               TRACE(ft_t_any, "cleanup reset");
-               fdc_reset();
-               resetting = 0;
-       }
-       TRACE_EXIT (signal_pending(current)) ? -EINTR : -ETIME;
-}
-
-/*      Start/stop drive motor. Enable DMA mode.
- */
-void fdc_motor(int motor)
-{
-       int unit = ft_drive_sel;
-       int data = unit | FDC_RESET_NOT | FDC_DMA_MODE;
-       TRACE_FUN(ft_t_any);
-
-       ftape_motor = motor;
-       if (ftape_motor) {
-               data |= FDC_MOTOR_0 << unit;
-               TRACE(ft_t_noise, "turning motor %d on", unit);
-       } else {
-               TRACE(ft_t_noise, "turning motor %d off", unit);
-       }
-       if (ft_mach2) {
-               outb_p(data, fdc.dor2);
-       } else {
-               outb_p(data, fdc.dor);
-       }
-       ftape_sleep(10 * FT_MILLISECOND);
-       TRACE_EXIT;
-}
-
-static void fdc_update_dsr(void)
-{
-       TRACE_FUN(ft_t_any);
-
-       TRACE(ft_t_flow, "rate = %d Kbps, precomp = %d ns",
-             fdc_data_rate, fdc_precomp);
-       if (fdc.type >= i82077) {
-               outb_p((fdc_rate_code & 0x03) | fdc_prec_code, fdc.dsr);
-       } else {
-               outb_p(fdc_rate_code & 0x03, fdc.ccr);
-       }
-       TRACE_EXIT;
-}
-
-void fdc_set_write_precomp(int precomp)
-{
-       TRACE_FUN(ft_t_any);
-
-       TRACE(ft_t_noise, "New precomp: %d nsec", precomp);
-       fdc_precomp = precomp;
-       /*  write precompensation can be set in multiples of 41.67 nsec.
-        *  round the parameter to the nearest multiple and convert it
-        *  into a fdc setting. Note that 0 means default to the fdc,
-        *  7 is used instead of that.
-        */
-       fdc_prec_code = ((fdc_precomp + 21) / 42) << 2;
-       if (fdc_prec_code == 0 || fdc_prec_code > (6 << 2)) {
-               fdc_prec_code = 7 << 2;
-       }
-       fdc_update_dsr();
-       TRACE_EXIT;
-}
-
-/*  Reprogram the 82078 registers to use Data Rate Table 1 on all drives.
- */
-static void fdc_set_drive_specs(void)
-{
-       __u8 cmd[] = { FDC_DRIVE_SPEC, 0x00, 0x00, 0x00, 0x00, 0xc0};
-       int result;
-       TRACE_FUN(ft_t_any);
-
-       TRACE(ft_t_flow, "Setting of drive specs called");
-       if (fdc.type >= i82078_1) {
-               cmd[1] = (0 << 5) | (2 << 2);
-               cmd[2] = (1 << 5) | (2 << 2);
-               cmd[3] = (2 << 5) | (2 << 2);
-               cmd[4] = (3 << 5) | (2 << 2);
-               result = fdc_command(cmd, NR_ITEMS(cmd));
-               if (result < 0) {
-                       TRACE(ft_t_err, "Setting of drive specs failed");
-               }
-       }
-       TRACE_EXIT;
-}
-
-/* Select clock for fdc, must correspond with tape drive setting !
- * This also influences the fdc timing so we must adjust some values.
- */
-int fdc_set_data_rate(int rate)
-{
-       int bad_rate = 0;
-       TRACE_FUN(ft_t_any);
-
-       /* Select clock for fdc, must correspond with tape drive setting !
-        * This also influences the fdc timing so we must adjust some values.
-        */
-       TRACE(ft_t_fdc_dma, "new rate = %d", rate);
-       switch (rate) {
-       case 250:
-               fdc_rate_code = fdc_data_rate_250;
-               break;
-       case 500:
-               fdc_rate_code = fdc_data_rate_500;
-               break;
-       case 1000:
-               if (fdc.type < i82077) {
-                       bad_rate = 1;
-                } else {
-                       fdc_rate_code = fdc_data_rate_1000;
-               }
-               break;
-       case 2000:
-               if (fdc.type < i82078_1) {
-                       bad_rate = 1;
-                } else {
-                       fdc_rate_code = fdc_data_rate_2000;
-               }
-               break;
-       default:
-               bad_rate = 1;
-        }
-       if (bad_rate) {
-               TRACE_ABORT(-EIO,
-                           ft_t_fdc_dma, "%d is not a valid data rate", rate);
-       }
-       fdc_data_rate = rate;
-       fdc_update_dsr();
-       fdc_set_seek_rate(fdc_seek_rate);  /* clock changed! */
-       ftape_udelay(1000);
-       TRACE_EXIT 0;
-}
-
-/*  keep the unit select if keep_select is != 0,
- */
-static void fdc_dor_reset(int keep_select)
-{
-       __u8 fdc_ctl = ft_drive_sel;
-
-       if (keep_select != 0) {
-               fdc_ctl |= FDC_DMA_MODE;
-               if (ftape_motor) {
-                       fdc_ctl |= FDC_MOTOR_0 << ft_drive_sel;
-               }
-       }
-       ftape_udelay(10); /* ??? but seems to be necessary */
-       if (ft_mach2) {
-               outb_p(fdc_ctl & 0x0f, fdc.dor);
-               outb_p(fdc_ctl, fdc.dor2);
-       } else {
-               outb_p(fdc_ctl, fdc.dor);
-       }
-       fdc_usec_wait(10); /* delay >= 14 fdc clocks */
-       if (keep_select == 0) {
-               fdc_ctl = 0;
-       }
-       fdc_ctl |= FDC_RESET_NOT;
-       if (ft_mach2) {
-               outb_p(fdc_ctl & 0x0f, fdc.dor);
-               outb_p(fdc_ctl, fdc.dor2);
-       } else {
-               outb_p(fdc_ctl, fdc.dor);
-       }
-}
-
-/*      Reset the floppy disk controller. Leave the ftape_unit selected.
- */
-void fdc_reset(void)
-{
-       int st0;
-       int i;
-       int dummy;
-       unsigned long flags;
-       TRACE_FUN(ft_t_any);
-
-       spin_lock_irqsave(&fdc_io_lock, flags);
-
-       fdc_dor_reset(1); /* keep unit selected */
-
-       fdc_mode = fdc_idle;
-
-       /*  maybe the spin_lock_irq* pair is not necessary, BUT:
-        *  the following line MUST be here. Otherwise fdc_interrupt_wait()
-        *  won't wait. Note that fdc_reset() is called from 
-        *  ftape_dumb_stop() when the fdc is busy transferring data. In this
-        *  case fdc_isr() MOST PROBABLY sets ft_interrupt_seen, and tries
-        *  to get the result bytes from the fdc etc. CLASH.
-        */
-       ft_interrupt_seen = 0;
-       
-       /*  Program data rate
-        */
-       fdc_update_dsr();               /* restore data rate and precomp */
-
-       spin_unlock_irqrestore(&fdc_io_lock, flags);
-
-        /*
-         *     Wait for first polling cycle to complete
-        */
-       if (fdc_interrupt_wait(1 * FT_SECOND) < 0) {
-               TRACE(ft_t_err, "no drive polling interrupt!");
-       } else {        /* clear all disk-changed statuses */
-               for (i = 0; i < 4; ++i) {
-                       if(fdc_sense_interrupt_status(&st0, &dummy) != 0) {
-                               TRACE(ft_t_err, "sense failed for %d", i);
-                       }
-                       if (i == ft_drive_sel) {
-                               ftape_current_cylinder = dummy;
-                       }
-               }
-               TRACE(ft_t_noise, "drive polling completed");
-       }
-       /*
-         *     SPECIFY COMMAND
-        */
-       fdc_set_seek_rate(fdc_seek_rate);
-       /*
-        *      DRIVE SPECIFICATION COMMAND (if fdc type known)
-        */
-       if (fdc.type >= i82078_1) {
-               fdc_set_drive_specs();
-       }
-       TRACE_EXIT;
-}
-
-#if !defined(CLK_48MHZ)
-# define CLK_48MHZ 1
-#endif
-
-/*  When we're done, put the fdc into reset mode so that the regular
- *  floppy disk driver will figure out that something is wrong and
- *  initialize the controller the way it wants.
- */
-void fdc_disable(void)
-{
-       __u8 cmd1[] = {FDC_CONFIGURE, 0x00, 0x00, 0x00};
-       __u8 cmd2[] = {FDC_LOCK};
-       __u8 cmd3[] = {FDC_UNLOCK};
-       __u8 stat[1];
-       TRACE_FUN(ft_t_flow);
-
-       if (!fdc_fifo_locked) {
-               fdc_reset();
-               TRACE_EXIT;
-       }
-       if (fdc_issue_command(cmd3, 1, stat, 1) < 0 || stat[0] != 0x00) {
-               fdc_dor_reset(0);
-               TRACE_ABORT(/**/, ft_t_bug, 
-               "couldn't unlock fifo, configuration remains changed");
-       }
-       fdc_fifo_locked = 0;
-       if (CLK_48MHZ && fdc.type >= i82078) {
-               cmd1[0] |= FDC_CLK48_BIT;
-       }
-       cmd1[2] = ((fdc_fifo_state) ? 0 : 0x20) + (fdc_fifo_thr - 1);
-       if (fdc_command(cmd1, NR_ITEMS(cmd1)) < 0) {
-               fdc_dor_reset(0);
-               TRACE_ABORT(/**/, ft_t_bug,
-               "couldn't reconfigure fifo to old state");
-       }
-       if (fdc_lock_state &&
-           fdc_issue_command(cmd2, 1, stat, 1) < 0) {
-               fdc_dor_reset(0);
-               TRACE_ABORT(/**/, ft_t_bug, "couldn't lock old state again");
-       }
-       TRACE(ft_t_noise, "fifo restored: %sabled, thr. %d, %slocked",
-             fdc_fifo_state ? "en" : "dis",
-             fdc_fifo_thr, (fdc_lock_state) ? "" : "not ");
-       fdc_dor_reset(0);
-       TRACE_EXIT;
-}
-
-/*      Specify FDC seek-rate (milliseconds)
- */
-static int fdc_set_seek_rate(int seek_rate)
-{
-       /* set step rate, dma mode, and minimal head load and unload times
-        */
-       __u8 in[3] = { FDC_SPECIFY, 1, (1 << 1)};
-       fdc_seek_rate = seek_rate;
-       in[1] |= (16 - (fdc_data_rate * fdc_seek_rate) / 500) << 4;
-
-       return fdc_command(in, 3);
-}
-
-/*      Sense drive status: get unit's drive status (ST3)
- */
-int fdc_sense_drive_status(int *st3)
-{
-       __u8 out[2];
-       __u8 in[1];
-       TRACE_FUN(ft_t_any);
-
-       out[0] = FDC_SENSED;
-       out[1] = ft_drive_sel;
-       TRACE_CATCH(fdc_issue_command(out, 2, in, 1),);
-       *st3 = in[0];
-       TRACE_EXIT 0;
-}
-
-/*      Sense Interrupt Status command:
- *      should be issued at the end of each seek.
- *      get ST0 and current cylinder.
- */
-int fdc_sense_interrupt_status(int *st0, int *current_cylinder)
-{
-       __u8 out[1];
-       __u8 in[2];
-       TRACE_FUN(ft_t_any);
-
-       out[0] = FDC_SENSEI;
-       TRACE_CATCH(fdc_issue_command(out, 1, in, 2),);
-       *st0 = in[0];
-       *current_cylinder = in[1];
-       TRACE_EXIT 0;
-}
-
-/*      step to track
- */
-int fdc_seek(int track)
-{
-       __u8 out[3];
-       int st0, pcn;
-#ifdef TESTING
-       unsigned int time;
-#endif
-       TRACE_FUN(ft_t_any);
-
-       out[0] = FDC_SEEK;
-       out[1] = ft_drive_sel;
-       out[2] = track;
-#ifdef TESTING
-       time = ftape_timestamp();
-#endif
-       /*  We really need this command to work !
-        */
-       ft_seek_completed = 0;
-       TRACE_CATCH(fdc_command(out, 3),
-                   fdc_reset();
-                   TRACE(ft_t_noise, "destination was: %d, resetting FDC...",
-                         track));
-       /*    Handle interrupts until ft_seek_completed or timeout.
-        */
-       for (;;) {
-               TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
-               if (ft_seek_completed) {
-                       TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
-                       if ((st0 & ST0_SEEK_END) == 0) {
-                               TRACE_ABORT(-EIO, ft_t_err,
-                                     "no seek-end after seek completion !??");
-                       }
-                       break;
-               }
-       }
-#ifdef TESTING
-       time = ftape_timediff(time, ftape_timestamp()) / abs(track - ftape_current_cylinder);
-       if ((time < 900 || time > 3100) && abs(track - ftape_current_cylinder) > 5) {
-               TRACE(ft_t_warn, "Wrong FDC STEP interval: %d usecs (%d)",
-                         time, track - ftape_current_cylinder);
-       }
-#endif
-       /*    Verify whether we issued the right tape command.
-        */
-       /* Verify that we seek to the proper track. */
-       if (pcn != track) {
-               TRACE_ABORT(-EIO, ft_t_err, "bad seek..");
-       }
-       ftape_current_cylinder = track;
-       TRACE_EXIT 0;
-}
-
-static int perpend_mode; /* set if fdc is in perpendicular mode */
-
-static int perpend_off(void)
-{
-       __u8 perpend[] = {FDC_PERPEND, 0x00};
-       TRACE_FUN(ft_t_any);
-       
-       if (perpend_mode) {
-               /* Turn off perpendicular mode */
-               perpend[1] = 0x80;
-               TRACE_CATCH(fdc_command(perpend, 2),
-                           TRACE(ft_t_err,"Perpendicular mode exit failed!"));
-               perpend_mode = 0;
-       }
-       TRACE_EXIT 0;
-}
-
-static int handle_perpend(int segment_id)
-{
-       __u8 perpend[] = {FDC_PERPEND, 0x00};
-       TRACE_FUN(ft_t_any);
-
-       /* When writing QIC-3020 tapes, turn on perpendicular mode
-        * if tape is moving in forward direction (even tracks).
-        */
-       if (ft_qic_std == QIC_TAPE_QIC3020 &&
-           ((segment_id / ft_segments_per_track) & 1) == 0) {
-/*  FIXME: some i82077 seem to support perpendicular mode as
- *  well. 
- */
-#if 0
-               if (fdc.type < i82077AA) {}
-#else
-               if (fdc.type < i82077 && ft_data_rate < 1000) {
-#endif
-                       /*  fdc does not support perpendicular mode: complain 
-                        */
-                       TRACE_ABORT(-EIO, ft_t_err,
-                                   "Your FDC does not support QIC-3020.");
-               }
-               perpend[1] = 0x03 /* 0x83 + (0x4 << ft_drive_sel) */ ;
-               TRACE_CATCH(fdc_command(perpend, 2),
-                          TRACE(ft_t_err,"Perpendicular mode entry failed!"));
-               TRACE(ft_t_flow, "Perpendicular mode set");
-               perpend_mode = 1;
-               TRACE_EXIT 0;
-       }
-       TRACE_EXIT perpend_off();
-}
-
-static inline void fdc_setup_dma(char mode,
-                                volatile void *addr, unsigned int count)
-{
-       /* Program the DMA controller.
-        */
-       disable_dma(fdc.dma);
-       clear_dma_ff(fdc.dma);
-       set_dma_mode(fdc.dma, mode);
-       set_dma_addr(fdc.dma, virt_to_bus((void*)addr));
-       set_dma_count(fdc.dma, count);
-       enable_dma(fdc.dma);
-}
-
-/*  Setup fdc and dma for formatting the next segment
- */
-int fdc_setup_formatting(buffer_struct * buff)
-{
-       unsigned long flags;
-       __u8 out[6] = {
-               FDC_FORMAT, 0x00, 3, 4 * FT_SECTORS_PER_SEGMENT, 0x00, 0x6b
-       };
-       TRACE_FUN(ft_t_any);
-       
-       TRACE_CATCH(handle_perpend(buff->segment_id),);
-       /* Program the DMA controller.
-        */
-        TRACE(ft_t_fdc_dma,
-             "phys. addr. = %lx", virt_to_bus((void*) buff->ptr));
-       spin_lock_irqsave(&fdc_io_lock, flags);
-       fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4);
-       /* Issue FDC command to start reading/writing.
-        */
-       out[1] = ft_drive_sel;
-       out[4] = buff->gap3;
-       TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)),
-                   restore_flags(flags); fdc_mode = fdc_idle);
-       spin_unlock_irqrestore(&fdc_io_lock, flags);
-       TRACE_EXIT 0;
-}
-
-
-/*      Setup Floppy Disk Controller and DMA to read or write the next cluster
- *      of good sectors from or to the current segment.
- */
-int fdc_setup_read_write(buffer_struct * buff, __u8 operation)
-{
-       unsigned long flags;
-       __u8 out[9];
-       int dma_mode;
-       TRACE_FUN(ft_t_any);
-
-       switch(operation) {
-       case FDC_VERIFY:
-               if (fdc.type < i82077) {
-                       operation = FDC_READ;
-               }
-       case FDC_READ:
-       case FDC_READ_DELETED:
-               dma_mode = DMA_MODE_READ;
-               TRACE(ft_t_fdc_dma, "xfer %d sectors to 0x%p",
-                     buff->sector_count, buff->ptr);
-               TRACE_CATCH(perpend_off(),);
-               break;
-       case FDC_WRITE_DELETED:
-               TRACE(ft_t_noise, "deleting segment %d", buff->segment_id);
-       case FDC_WRITE:
-               dma_mode = DMA_MODE_WRITE;
-               /* When writing QIC-3020 tapes, turn on perpendicular mode
-                * if tape is moving in forward direction (even tracks).
-                */
-               TRACE_CATCH(handle_perpend(buff->segment_id),);
-               TRACE(ft_t_fdc_dma, "xfer %d sectors from 0x%p",
-                     buff->sector_count, buff->ptr);
-               break;
-       default:
-               TRACE_ABORT(-EIO,
-                           ft_t_bug, "bug: invalid operation parameter");
-       }
-       TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr));
-       spin_lock_irqsave(&fdc_io_lock, flags);
-       if (operation != FDC_VERIFY) {
-               fdc_setup_dma(dma_mode, buff->ptr,
-                             FT_SECTOR_SIZE * buff->sector_count);
-       }
-       /* Issue FDC command to start reading/writing.
-        */
-       out[0] = operation;
-       out[1] = ft_drive_sel;
-       out[2] = buff->cyl;
-       out[3] = buff->head;
-       out[4] = buff->sect + buff->sector_offset;
-       out[5] = 3;             /* Sector size of 1K. */
-       out[6] = out[4] + buff->sector_count - 1;       /* last sector */
-       out[7] = 109;           /* Gap length. */
-       out[8] = 0xff;          /* No limit to transfer size. */
-       TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x",
-               out[2], out[3], out[4], out[6] - out[4] + 1);
-       spin_unlock_irqrestore(&fdc_io_lock, flags);
-       TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle);
-       TRACE_EXIT 0;
-}
-
-int fdc_fifo_threshold(__u8 threshold,
-                      int *fifo_state, int *lock_state, int *fifo_thr)
-{
-       const __u8 cmd0[] = {FDC_DUMPREGS};
-       __u8 cmd1[] = {FDC_CONFIGURE, 0, (0x0f & (threshold - 1)), 0};
-       const __u8 cmd2[] = {FDC_LOCK};
-       const __u8 cmd3[] = {FDC_UNLOCK};
-       __u8 reg[10];
-       __u8 stat;
-       int i;
-       int result;
-       TRACE_FUN(ft_t_any);
-
-       if (CLK_48MHZ && fdc.type >= i82078) {
-               cmd1[0] |= FDC_CLK48_BIT;
-       }
-       /*  Dump fdc internal registers for examination
-        */
-       TRACE_CATCH(fdc_command(cmd0, NR_ITEMS(cmd0)),
-                   TRACE(ft_t_warn, "dumpreg cmd failed, fifo unchanged"));
-       /*  Now read fdc internal registers from fifo
-        */
-       for (i = 0; i < (int)NR_ITEMS(reg); ++i) {
-               fdc_read(&reg[i]);
-               TRACE(ft_t_fdc_dma, "Register %d = 0x%02x", i, reg[i]);
-       }
-       if (fifo_state && lock_state && fifo_thr) {
-               *fifo_state = (reg[8] & 0x20) == 0;
-               *lock_state = reg[7] & 0x80;
-               *fifo_thr = 1 + (reg[8] & 0x0f);
-       }
-       TRACE(ft_t_noise,
-             "original fifo state: %sabled, threshold %d, %slocked",
-             ((reg[8] & 0x20) == 0) ? "en" : "dis",
-             1 + (reg[8] & 0x0f), (reg[7] & 0x80) ? "" : "not ");
-       /*  If fdc is already locked, unlock it first ! */
-       if (reg[7] & 0x80) {
-               fdc_ready_wait(100);
-               TRACE_CATCH(fdc_issue_command(cmd3, NR_ITEMS(cmd3), &stat, 1),
-                           TRACE(ft_t_bug, "FDC unlock command failed, "
-                                 "configuration unchanged"));
-       }
-       fdc_fifo_locked = 0;
-       /*  Enable fifo and set threshold at xx bytes to allow a
-        *  reasonably large latency and reduce number of dma bursts.
-        */
-       fdc_ready_wait(100);
-       if ((result = fdc_command(cmd1, NR_ITEMS(cmd1))) < 0) {
-               TRACE(ft_t_bug, "configure cmd failed, fifo unchanged");
-       }
-       /*  Now lock configuration so reset will not change it
-        */
-        if(fdc_issue_command(cmd2, NR_ITEMS(cmd2), &stat, 1) < 0 ||
-          stat != 0x10) {
-               TRACE_ABORT(-EIO, ft_t_bug,
-                           "FDC lock command failed, stat = 0x%02x", stat);
-       }
-       fdc_fifo_locked = 1;
-       TRACE_EXIT result;
-}
-
-static int fdc_fifo_enable(void)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (fdc_fifo_locked) {
-               TRACE_ABORT(0, ft_t_warn, "Fifo not enabled because locked");
-       }
-       TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
-                                      &fdc_fifo_state,
-                                      &fdc_lock_state,
-                                      &fdc_fifo_thr),);
-       TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
-                                      NULL, NULL, NULL),);
-       TRACE_EXIT 0;
-}
-
-/*   Determine fd controller type 
- */
-static __u8 fdc_save_state[2];
-
-static int fdc_probe(void)
-{
-       __u8 cmd[1];
-       __u8 stat[16]; /* must be able to hold dumpregs & save results */
-       int i;
-       TRACE_FUN(ft_t_any);
-
-       /*  Try to find out what kind of fd controller we have to deal with
-        *  Scheme borrowed from floppy driver:
-        *  first try if FDC_DUMPREGS command works
-        *  (this indicates that we have a 82072 or better)
-        *  then try the FDC_VERSION command (82072 doesn't support this)
-        *  then try the FDC_UNLOCK command (some older 82077's don't support this)
-        *  then try the FDC_PARTID command (82078's support this)
-        */
-       cmd[0] = FDC_DUMPREGS;
-       if (fdc_issue_command(cmd, 1, stat, 1) != 0) {
-               TRACE_ABORT(no_fdc, ft_t_bug, "No FDC found");
-       }
-       if (stat[0] == 0x80) {
-               /* invalid command: must be pre 82072 */
-               TRACE_ABORT(i8272,
-                           ft_t_warn, "Type 8272A/765A compatible FDC found");
-       }
-       fdc_result(&stat[1], 9);
-       fdc_save_state[0] = stat[7];
-       fdc_save_state[1] = stat[8];
-       cmd[0] = FDC_VERSION;
-       if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
-               TRACE_ABORT(i8272, ft_t_warn, "Type 82072 FDC found");
-       }
-       if (*stat != 0x90) {
-               TRACE_ABORT(i8272, ft_t_warn, "Unknown FDC found");
-       }
-       cmd[0] = FDC_UNLOCK;
-       if(fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] != 0x00) {
-               TRACE_ABORT(i8272, ft_t_warn,
-                           "Type pre-1991 82077 FDC found, "
-                           "treating it like a 82072");
-       }
-       if (fdc_save_state[0] & 0x80) { /* was locked */
-               cmd[0] = FDC_LOCK; /* restore lock */
-               (void)fdc_issue_command(cmd, 1, stat, 1);
-               TRACE(ft_t_warn, "FDC is already locked");
-       }
-       /* Test for a i82078 FDC */
-       cmd[0] = FDC_PARTID;
-       if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
-               /* invalid command: not a i82078xx type FDC */
-               for (i = 0; i < 4; ++i) {
-                       outb_p(i, fdc.tdr);
-                       if ((inb_p(fdc.tdr) & 0x03) != i) {
-                               TRACE_ABORT(i82077,
-                                           ft_t_warn, "Type 82077 FDC found");
-                       }
-               }
-               TRACE_ABORT(i82077AA, ft_t_warn, "Type 82077AA FDC found");
-       }
-       /* FDC_PARTID cmd succeeded */
-       switch (stat[0] >> 5) {
-       case 0x0:
-               /* i82078SL or i82078-1.  The SL part cannot run at
-                * 2Mbps (the SL and -1 dies are identical; they are
-                * speed graded after production, according to Intel).
-                * Some SL's can be detected by doing a SAVE cmd and
-                * look at bit 7 of the first byte (the SEL3V# bit).
-                * If it is 0, the part runs off 3Volts, and hence it
-                * is a SL.
-                */
-               cmd[0] = FDC_SAVE;
-               if(fdc_issue_command(cmd, 1, stat, 16) < 0) {
-                       TRACE(ft_t_err, "FDC_SAVE failed. Dunno why");
-                       /* guess we better claim the fdc to be a i82078 */
-                       TRACE_ABORT(i82078,
-                                   ft_t_warn,
-                                   "Type i82078 FDC (i suppose) found");
-               }
-               if ((stat[0] & FDC_SEL3V_BIT)) {
-                       /* fdc running off 5Volts; Pray that it's a i82078-1
-                        */
-                       TRACE_ABORT(i82078_1, ft_t_warn,
-                                 "Type i82078-1 or 5Volt i82078SL FDC found");
-               }
-               TRACE_ABORT(i82078, ft_t_warn,
-                           "Type 3Volt i82078SL FDC (1Mbps) found");
-       case 0x1:
-       case 0x2: /* S82078B  */
-               /* The '78B  isn't '78 compatible.  Detect it as a '77AA */
-               TRACE_ABORT(i82077AA, ft_t_warn, "Type i82077AA FDC found");
-       case 0x3: /* NSC PC8744 core; used in several super-IO chips */
-               TRACE_ABORT(i82077AA,
-                           ft_t_warn, "Type 82077AA compatible FDC found");
-       default:
-               TRACE(ft_t_warn, "A previously undetected FDC found");
-               TRACE_ABORT(i82077AA, ft_t_warn,
-                         "Treating it as a 82077AA. Please report partid= %d",
-                           stat[0]);
-       } /* switch(stat[ 0] >> 5) */
-       TRACE_EXIT no_fdc;
-}
-
-static int fdc_request_regions(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (ft_mach2 || ft_probe_fc10) {
-               if (!request_region(fdc.sra, 8, "fdc (ft)")) {
-#ifndef BROKEN_FLOPPY_DRIVER
-                       TRACE_EXIT -EBUSY;
-#else
-                       TRACE(ft_t_warn,
-"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
-#endif
-               }
-       } else {
-               if (!request_region(fdc.sra, 6, "fdc (ft)")) {
-#ifndef BROKEN_FLOPPY_DRIVER
-                       TRACE_EXIT -EBUSY;
-#else
-                       TRACE(ft_t_warn,
-"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
-#endif
-               }
-               if (!request_region(fdc.sra + 7, 1, "fdc (ft)")) {
-#ifndef BROKEN_FLOPPY_DRIVER
-                       release_region(fdc.sra, 6);
-                       TRACE_EXIT -EBUSY;
-#else
-                       TRACE(ft_t_warn,
-"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra + 7);
-#endif
-               }
-       }
-       TRACE_EXIT 0;
-}
-
-void fdc_release_regions(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (fdc.sra != 0) {
-               if (fdc.dor2 != 0) {
-                       release_region(fdc.sra, 8);
-               } else {
-                       release_region(fdc.sra, 6);
-                       release_region(fdc.dir, 1);
-               }
-       }
-       TRACE_EXIT;
-}
-
-static int fdc_config_regs(unsigned int fdc_base, 
-                          unsigned int fdc_irq, 
-                          unsigned int fdc_dma)
-{
-       TRACE_FUN(ft_t_flow);
-
-       fdc.irq = fdc_irq;
-       fdc.dma = fdc_dma;
-       fdc.sra = fdc_base;
-       fdc.srb = fdc_base + 1;
-       fdc.dor = fdc_base + 2;
-       fdc.tdr = fdc_base + 3;
-       fdc.msr = fdc.dsr = fdc_base + 4;
-       fdc.fifo = fdc_base + 5;
-       fdc.dir = fdc.ccr = fdc_base + 7;
-       fdc.dor2 = (ft_mach2 || ft_probe_fc10) ? fdc_base + 6 : 0;
-       TRACE_CATCH(fdc_request_regions(), fdc.sra = 0);
-       TRACE_EXIT 0;
-}
-
-static int fdc_config(void)
-{
-       static int already_done;
-       TRACE_FUN(ft_t_any);
-
-       if (already_done) {
-               TRACE_CATCH(fdc_request_regions(),);
-               *(fdc.hook) = fdc_isr;  /* hook our handler in */
-               TRACE_EXIT 0;
-       }
-       if (ft_probe_fc10) {
-               int fc_type;
-               
-               TRACE_CATCH(fdc_config_regs(ft_fdc_base,
-                                           ft_fdc_irq, ft_fdc_dma),);
-               fc_type = fc10_enable();
-               if (fc_type != 0) {
-                       TRACE(ft_t_warn, "FC-%c0 controller found", '0' + fc_type);
-                       fdc.type = fc10;
-                       fdc.hook = &do_ftape;
-                       *(fdc.hook) = fdc_isr;  /* hook our handler in */
-                       already_done = 1;
-                       TRACE_EXIT 0;
-               } else {
-                       TRACE(ft_t_warn, "FC-10/20 controller not found");
-                       fdc_release_regions();
-                       fdc.type = no_fdc;
-                       ft_probe_fc10 = 0;
-                       ft_fdc_base   = 0x3f0;
-                       ft_fdc_irq    = 6;
-                       ft_fdc_dma    = 2;
-               }
-       }
-       TRACE(ft_t_warn, "fdc base: 0x%x, irq: %d, dma: %d", 
-             ft_fdc_base, ft_fdc_irq, ft_fdc_dma);
-       TRACE_CATCH(fdc_config_regs(ft_fdc_base, ft_fdc_irq, ft_fdc_dma),);
-       fdc.hook = &do_ftape;
-       *(fdc.hook) = fdc_isr;  /* hook our handler in */
-       already_done = 1;
-       TRACE_EXIT 0;
-}
-
-static irqreturn_t ftape_interrupt(int irq, void *dev_id)
-{
-       void (*handler) (void) = *fdc.hook;
-       int handled = 0;
-       TRACE_FUN(ft_t_any);
-
-       *fdc.hook = NULL;
-       if (handler) {
-               handled = 1;
-               handler();
-       } else {
-               TRACE(ft_t_bug, "Unexpected ftape interrupt");
-       }
-       TRACE_EXIT IRQ_RETVAL(handled);
-}
-
-static int fdc_grab_irq_and_dma(void)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (fdc.hook == &do_ftape) {
-               /*  Get fast interrupt handler.
-                */
-               if (request_irq(fdc.irq, ftape_interrupt,
-                               IRQF_DISABLED, "ft", ftape_id)) {
-                       TRACE_ABORT(-EIO, ft_t_bug,
-                                   "Unable to grab IRQ%d for ftape driver",
-                                   fdc.irq);
-               }
-               if (request_dma(fdc.dma, ftape_id)) {
-                       free_irq(fdc.irq, ftape_id);
-                       TRACE_ABORT(-EIO, ft_t_bug,
-                             "Unable to grab DMA%d for ftape driver",
-                             fdc.dma);
-               }
-       }
-       if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
-               /* Using same dma channel or irq as standard fdc, need
-                * to disable the dma-gate on the std fdc. This
-                * couldn't be done in the floppy driver as some
-                * laptops are using the dma-gate to enter a low power
-                * or even suspended state :-(
-                */
-               outb_p(FDC_RESET_NOT, 0x3f2);
-               TRACE(ft_t_noise, "DMA-gate on standard fdc disabled");
-       }
-       TRACE_EXIT 0;
-}
-
-int fdc_release_irq_and_dma(void)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (fdc.hook == &do_ftape) {
-               disable_dma(fdc.dma);   /* just in case... */
-               free_dma(fdc.dma);
-               free_irq(fdc.irq, ftape_id);
-       }
-       if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
-               /* Using same dma channel as standard fdc, need to
-                * disable the dma-gate on the std fdc. This couldn't
-                * be done in the floppy driver as some laptops are
-                * using the dma-gate to enter a low power or even
-                * suspended state :-(
-                */
-               outb_p(FDC_RESET_NOT | FDC_DMA_MODE, 0x3f2);
-               TRACE(ft_t_noise, "DMA-gate on standard fdc enabled again");
-       }
-       TRACE_EXIT 0;
-}
-
-int fdc_init(void)
-{
-       TRACE_FUN(ft_t_any);
-
-       /* find a FDC to use */
-       TRACE_CATCH(fdc_config(),);
-       TRACE_CATCH(fdc_grab_irq_and_dma(), fdc_release_regions());
-       ftape_motor = 0;
-       fdc_catch_stray_interrupts(0);  /* clear number of awainted
-                                        * stray interrupte 
-                                        */
-       fdc_catch_stray_interrupts(1);  /* one always comes (?) */
-       TRACE(ft_t_flow, "resetting fdc");
-       fdc_set_seek_rate(2);           /* use nominal QIC step rate */
-       fdc_reset();                    /* init fdc & clear track counters */
-       if (fdc.type == no_fdc) {       /* no FC-10 or FC-20 found */
-               fdc.type = fdc_probe();
-               fdc_reset();            /* update with new knowledge */
-       }
-       if (fdc.type == no_fdc) {
-               fdc_release_irq_and_dma();
-               fdc_release_regions();
-               TRACE_EXIT -ENXIO;
-       }
-       if (fdc.type >= i82077) {
-               if (fdc_fifo_enable() < 0) {
-                       TRACE(ft_t_warn, "couldn't enable fdc fifo !");
-               } else {
-                       TRACE(ft_t_flow, "fdc fifo enabled and locked");
-               }
-       }
-       TRACE_EXIT 0;
-}
diff --git a/drivers/char/ftape/lowlevel/fdc-io.h b/drivers/char/ftape/lowlevel/fdc-io.h
deleted file mode 100644 (file)
index 7ec3c72..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-#ifndef _FDC_IO_H
-#define _FDC_IO_H
-
-/*
- *    Copyright (C) 1993-1996 Bas Laarhoven,
- *              (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.h,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:18:06 $
- *
- *      This file contains the declarations for the low level
- *      functions that communicate with the floppy disk controller,
- *      for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
- *      Linux.
- */
-
-#include <linux/fdreg.h>
-
-#include "../lowlevel/ftape-bsm.h"
-
-#define FDC_SK_BIT      (0x20)
-#define FDC_MT_BIT      (0x80)
-
-#define FDC_READ        (FD_READ & ~(FDC_SK_BIT | FDC_MT_BIT))
-#define FDC_WRITE       (FD_WRITE & ~FDC_MT_BIT)
-#define FDC_READ_DELETED  (0x4c)
-#define FDC_WRITE_DELETED (0x49)
-#define FDC_VERIFY        (0x56)
-#define FDC_READID      (0x4a)
-#define FDC_SENSED      (0x04)
-#define FDC_SENSEI      (FD_SENSEI)
-#define FDC_FORMAT      (FD_FORMAT)
-#define FDC_RECAL       (FD_RECALIBRATE)
-#define FDC_SEEK        (FD_SEEK)
-#define FDC_SPECIFY     (FD_SPECIFY)
-#define FDC_RECALIBR    (FD_RECALIBRATE)
-#define FDC_VERSION     (FD_VERSION)
-#define FDC_PERPEND     (FD_PERPENDICULAR)
-#define FDC_DUMPREGS    (FD_DUMPREGS)
-#define FDC_LOCK        (FD_LOCK)
-#define FDC_UNLOCK      (FD_UNLOCK)
-#define FDC_CONFIGURE   (FD_CONFIGURE)
-#define FDC_DRIVE_SPEC  (0x8e) /* i82078 has this (any others?) */
-#define FDC_PARTID      (0x18) /* i82078 has this */
-#define FDC_SAVE        (0x2e) /* i82078 has this (any others?) */
-#define FDC_RESTORE     (0x4e) /* i82078 has this (any others?) */
-
-#define FDC_STATUS_MASK (STATUS_BUSY | STATUS_DMA | STATUS_DIR | STATUS_READY)
-#define FDC_DATA_READY  (STATUS_READY)
-#define FDC_DATA_OUTPUT (STATUS_DIR)
-#define FDC_DATA_READY_MASK (STATUS_READY | STATUS_DIR)
-#define FDC_DATA_OUT_READY  (STATUS_READY | STATUS_DIR)
-#define FDC_DATA_IN_READY   (STATUS_READY)
-#define FDC_BUSY        (STATUS_BUSY)
-#define FDC_CLK48_BIT   (0x80)
-#define FDC_SEL3V_BIT   (0x40)
-
-#define ST0_INT_MASK    (ST0_INTR)
-#define FDC_INT_NORMAL  (ST0_INTR & 0x00)
-#define FDC_INT_ABNORMAL (ST0_INTR & 0x40)
-#define FDC_INT_INVALID (ST0_INTR & 0x80)
-#define FDC_INT_READYCH (ST0_INTR & 0xC0)
-#define ST0_SEEK_END    (ST0_SE)
-#define ST3_TRACK_0     (ST3_TZ)
-
-#define FDC_RESET_NOT   (0x04)
-#define FDC_DMA_MODE    (0x08)
-#define FDC_MOTOR_0     (0x10)
-#define FDC_MOTOR_1     (0x20)
-
-typedef struct {
-       void (**hook) (void);   /* our wedge into the isr */
-       enum {
-               no_fdc, i8272, i82077, i82077AA, fc10,
-               i82078, i82078_1
-       } type;                 /* FDC type */
-       unsigned int irq; /* FDC irq nr */
-       unsigned int dma; /* FDC dma channel nr */
-       __u16 sra;        /* Status register A (PS/2 only) */
-       __u16 srb;        /* Status register B (PS/2 only) */
-       __u16 dor;        /* Digital output register */
-       __u16 tdr;        /* Tape Drive Register (82077SL-1 &
-                            82078 only) */
-       __u16 msr;        /* Main Status Register */
-       __u16 dsr;        /* Datarate Select Register (8207x only) */
-       __u16 fifo;       /* Data register / Fifo on 8207x */
-       __u16 dir;        /* Digital Input Register */
-       __u16 ccr;        /* Configuration Control Register */
-       __u16 dor2;       /* Alternate dor on MACH-2 controller,
-                            also used with FC-10, meaning unknown */
-} fdc_config_info;
-
-typedef enum {
-       fdc_data_rate_250  = 2,
-       fdc_data_rate_300  = 1, /* any fdc in default configuration */
-       fdc_data_rate_500  = 0,
-       fdc_data_rate_1000 = 3,
-       fdc_data_rate_2000 = 1, /* i82078-1: when using Data Rate Table #2 */
-} fdc_data_rate_type;
-
-typedef enum {
-       fdc_idle          = 0,
-       fdc_reading_data  = FDC_READ,
-       fdc_seeking       = FDC_SEEK,
-       fdc_writing_data  = FDC_WRITE,
-       fdc_deleting      = FDC_WRITE_DELETED,
-       fdc_reading_id    = FDC_READID,
-       fdc_recalibrating = FDC_RECAL,
-       fdc_formatting    = FDC_FORMAT,
-       fdc_verifying     = FDC_VERIFY
-} fdc_mode_enum;
-
-typedef enum {
-       waiting = 0,
-       reading,
-       writing,
-       formatting,
-       verifying,
-       deleting,
-       done,
-       error,
-       mmapped,
-} buffer_state_enum;
-
-typedef struct {
-       __u8 *address;
-       volatile buffer_state_enum status;
-       volatile __u8 *ptr;
-       volatile unsigned int bytes;
-       volatile unsigned int segment_id;
-
-       /* bitmap for remainder of segment not yet handled.
-        * one bit set for each bad sector that must be skipped.
-        */
-       volatile SectorMap bad_sector_map;
-
-       /* bitmap with bad data blocks in data buffer.
-        * the errors in this map may be retried.
-        */
-       volatile SectorMap soft_error_map;
-
-       /* bitmap with bad data blocks in data buffer
-        * the errors in this map may not be retried.
-        */
-       volatile SectorMap hard_error_map;
-
-       /* retry counter for soft errors.
-        */
-       volatile int retry;
-
-       /* sectors to skip on retry ???
-        */
-       volatile unsigned int skip;
-
-       /* nr of data blocks in data buffer
-        */
-       volatile unsigned int data_offset;
-
-       /* offset in segment for first sector to be handled.
-        */
-       volatile unsigned int sector_offset;
-
-       /* size of cluster of good sectors to be handled.
-        */
-       volatile unsigned int sector_count;
-
-       /* size of remaining part of segment to be handled.
-        */
-       volatile unsigned int remaining;
-
-       /* points to next segment (contiguous) to be handled,
-        * or is zero if no read-ahead is allowed.
-        */
-       volatile unsigned int next_segment;
-
-       /* flag being set if deleted data was read.
-        */
-       volatile int deleted;
-
-       /* floppy coordinates of first sector in segment */
-       volatile __u8 head;
-       volatile __u8 cyl;
-       volatile __u8 sect;
-
-       /* gap to use when formatting */
-       __u8 gap3;
-       /* flag set when buffer is mmaped */
-       int mmapped;
-} buffer_struct;
-
-/*
- *      fdc-io.c defined public variables
- */
-extern volatile fdc_mode_enum fdc_mode;
-extern int fdc_setup_error;    /* outdated ??? */
-extern wait_queue_head_t ftape_wait_intr;
-extern volatile int ftape_current_cylinder; /* track nr FDC thinks we're on */
-extern volatile __u8 fdc_head; /* FDC head */
-extern volatile __u8 fdc_cyl;  /* FDC track */
-extern volatile __u8 fdc_sect; /* FDC sector */
-extern fdc_config_info fdc;    /* FDC hardware configuration */
-
-extern unsigned int ft_fdc_base;
-extern unsigned int ft_fdc_irq;
-extern unsigned int ft_fdc_dma;
-extern unsigned int ft_fdc_threshold;
-extern unsigned int ft_fdc_rate_limit;
-extern int ft_probe_fc10;
-extern int ft_mach2;
-/*
- *      fdc-io.c defined public functions
- */
-extern void fdc_catch_stray_interrupts(int count);
-extern int fdc_ready_wait(unsigned int timeout);
-extern int fdc_command(const __u8 * cmd_data, int cmd_len);
-extern int fdc_result(__u8 * res_data, int res_len);
-extern int fdc_interrupt_wait(unsigned int time);
-extern int fdc_seek(int track);
-extern int fdc_sense_drive_status(int *st3);
-extern void fdc_motor(int motor);
-extern void fdc_reset(void);
-extern void fdc_disable(void);
-extern int fdc_fifo_threshold(__u8 threshold,
-                             int *fifo_state, int *lock_state, int *fifo_thr);
-extern void fdc_wait_calibrate(void);
-extern int fdc_sense_interrupt_status(int *st0, int *current_cylinder);
-extern void fdc_save_drive_specs(void);
-extern void fdc_restore_drive_specs(void);
-extern int fdc_set_data_rate(int rate);
-extern void fdc_set_write_precomp(int precomp);
-extern int fdc_release_irq_and_dma(void);
-extern void fdc_release_regions(void);
-extern int fdc_init(void);
-extern int fdc_setup_read_write(buffer_struct * buff, __u8 operation);
-extern int fdc_setup_formatting(buffer_struct * buff);
-#endif
diff --git a/drivers/char/ftape/lowlevel/fdc-isr.c b/drivers/char/ftape/lowlevel/fdc-isr.c
deleted file mode 100644 (file)
index ad2bc73..0000000
+++ /dev/null
@@ -1,1170 +0,0 @@
-/*
- *      Copyright (C) 1994-1996 Bas Laarhoven,
- *                (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-isr.c,v $
- * $Revision: 1.9 $
- * $Date: 1997/10/17 23:01:53 $
- *
- *      This file contains the interrupt service routine and
- *      associated code for the QIC-40/80/3010/3020 floppy-tape driver
- *      "ftape" for Linux.
- */
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define volatile               /* */
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-isr.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-calibr.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/*      Global vars.
- */
-volatile int ft_expected_stray_interrupts;
-volatile int ft_interrupt_seen;
-volatile int ft_seek_completed;
-volatile int ft_hide_interrupt;
-/*      Local vars.
- */
-typedef enum {
-       no_error = 0, id_am_error = 0x01, id_crc_error = 0x02,
-       data_am_error = 0x04, data_crc_error = 0x08,
-       no_data_error = 0x10, overrun_error = 0x20,
-} error_cause;
-static int stop_read_ahead;
-
-
-static void print_error_cause(int cause)
-{
-       TRACE_FUN(ft_t_any);
-
-       switch (cause) {
-       case no_data_error:
-               TRACE(ft_t_noise, "no data error");
-               break;
-       case id_am_error:
-               TRACE(ft_t_noise, "id am error");
-               break;
-       case id_crc_error:
-               TRACE(ft_t_noise, "id crc error");
-               break;
-       case data_am_error:
-               TRACE(ft_t_noise, "data am error");
-               break;
-       case data_crc_error:
-               TRACE(ft_t_noise, "data crc error");
-               break;
-       case overrun_error:
-               TRACE(ft_t_noise, "overrun error");
-               break;
-       default:;
-       }
-       TRACE_EXIT;
-}
-
-static char *fdc_mode_txt(fdc_mode_enum mode)
-{
-       switch (mode) {
-       case fdc_idle:
-               return "fdc_idle";
-       case fdc_reading_data:
-               return "fdc_reading_data";
-       case fdc_seeking:
-               return "fdc_seeking";
-       case fdc_writing_data:
-               return "fdc_writing_data";
-       case fdc_reading_id:
-               return "fdc_reading_id";
-       case fdc_recalibrating:
-               return "fdc_recalibrating";
-       case fdc_formatting:
-               return "fdc_formatting";
-       case fdc_verifying:
-               return "fdc_verifying";
-       default:
-               return "unknown";
-       }
-}
-
-static inline error_cause decode_irq_cause(fdc_mode_enum mode, __u8 st[])
-{
-       error_cause cause = no_error;
-       TRACE_FUN(ft_t_any);
-
-       /*  Valid st[], decode cause of interrupt.
-        */
-       switch (st[0] & ST0_INT_MASK) {
-       case FDC_INT_NORMAL:
-               TRACE(ft_t_fdc_dma,"normal completion: %s",fdc_mode_txt(mode));
-               break;
-       case FDC_INT_ABNORMAL:
-               TRACE(ft_t_flow, "abnormal completion %s", fdc_mode_txt(mode));
-               TRACE(ft_t_fdc_dma, "ST0: 0x%02x, ST1: 0x%02x, ST2: 0x%02x",
-                     st[0], st[1], st[2]);
-               TRACE(ft_t_fdc_dma,
-                     "C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x",
-                     st[3], st[4], st[5], st[6]);
-               if (st[1] & 0x01) {
-                       if (st[2] & 0x01) {
-                               cause = data_am_error;
-                       } else {
-                               cause = id_am_error;
-                       }
-               } else if (st[1] & 0x20) {
-                       if (st[2] & 0x20) {
-                               cause = data_crc_error;
-                       } else {
-                               cause = id_crc_error;
-                       }
-               } else if (st[1] & 0x04) {
-                       cause = no_data_error;
-               } else if (st[1] & 0x10) {
-                       cause = overrun_error;
-               }
-               print_error_cause(cause);
-               break;
-       case FDC_INT_INVALID:
-               TRACE(ft_t_flow, "invalid completion %s", fdc_mode_txt(mode));
-               break;
-       case FDC_INT_READYCH:
-               if (st[0] & ST0_SEEK_END) {
-                       TRACE(ft_t_flow, "drive poll completed");
-               } else {
-                       TRACE(ft_t_flow, "ready change %s",fdc_mode_txt(mode));
-               }
-               break;
-       default:
-               break;
-       }
-       TRACE_EXIT cause;
-}
-
-static void update_history(error_cause cause)
-{
-       switch (cause) {
-       case id_am_error:
-               ft_history.id_am_errors++;
-               break;
-       case id_crc_error:
-               ft_history.id_crc_errors++;
-               break;
-       case data_am_error:
-               ft_history.data_am_errors++;
-               break;
-       case data_crc_error:
-               ft_history.data_crc_errors++;
-               break;
-       case overrun_error:
-               ft_history.overrun_errors++;
-               break;
-       case no_data_error:
-               ft_history.no_data_errors++;
-               break;
-       default:;
-       }
-}
-
-static void skip_bad_sector(buffer_struct * buff)
-{
-       TRACE_FUN(ft_t_any);
-
-       /*  Mark sector as soft error and skip it
-        */
-       if (buff->remaining > 0) {
-               ++buff->sector_offset;
-               ++buff->data_offset;
-               --buff->remaining;
-               buff->ptr += FT_SECTOR_SIZE;
-               buff->bad_sector_map >>= 1;
-       } else {
-               /*  Hey, what is this????????????? C code: if we shift 
-                *  more than 31 bits, we get no shift. That's bad!!!!!!
-                */
-               ++buff->sector_offset;  /* hack for error maps */
-               TRACE(ft_t_warn, "skipping last sector in segment");
-       }
-       TRACE_EXIT;
-}
-
-static void update_error_maps(buffer_struct * buff, unsigned int error_offset)
-{
-       int hard = 0;
-       TRACE_FUN(ft_t_any);
-
-       if (buff->retry < FT_SOFT_RETRIES) {
-               buff->soft_error_map |= (1 << error_offset);
-       } else {
-               buff->hard_error_map |= (1 << error_offset);
-               buff->soft_error_map &= ~buff->hard_error_map;
-               buff->retry = -1;  /* will be set to 0 in setup_segment */
-               hard = 1;
-       }
-       TRACE(ft_t_noise, "sector %d : %s error\n"
-             KERN_INFO "hard map: 0x%08lx\n"
-             KERN_INFO "soft map: 0x%08lx",
-             FT_SECTOR(error_offset), hard ? "hard" : "soft",
-             (long) buff->hard_error_map, (long) buff->soft_error_map);
-       TRACE_EXIT;
-}
-
-static void print_progress(buffer_struct *buff, error_cause cause)
-{
-       TRACE_FUN(ft_t_any);
-
-       switch (cause) {
-       case no_error: 
-               TRACE(ft_t_flow,"%d Sector(s) transferred", buff->sector_count);
-               break;
-       case no_data_error:
-               TRACE(ft_t_flow, "Sector %d not found",
-                     FT_SECTOR(buff->sector_offset));
-               break;
-       case overrun_error:
-               /*  got an overrun error on the first byte, must be a
-                *  hardware problem
-                */
-               TRACE(ft_t_bug,
-                     "Unexpected error: failing DMA or FDC controller ?");
-               break;
-       case data_crc_error:
-               TRACE(ft_t_flow, "Error in sector %d",
-                     FT_SECTOR(buff->sector_offset - 1));
-               break;
-       case id_crc_error:
-       case id_am_error:
-       case data_am_error:
-               TRACE(ft_t_flow, "Error in sector %d",
-                     FT_SECTOR(buff->sector_offset));
-               break;
-       default:
-               TRACE(ft_t_flow, "Unexpected error at sector %d",
-                     FT_SECTOR(buff->sector_offset));
-               break;
-       }
-       TRACE_EXIT;
-}
-
-/*
- *  Error cause:   Amount xferred:  Action:
- *
- *  id_am_error         0           mark bad and skip
- *  id_crc_error        0           mark bad and skip
- *  data_am_error       0           mark bad and skip
- *  data_crc_error    % 1024        mark bad and skip
- *  no_data_error       0           retry on write
- *                                  mark bad and skip on read
- *  overrun_error  [ 0..all-1 ]     mark bad and skip
- *  no_error           all          continue
- */
-
-/*  the arg `sector' is returned by the fdc and tells us at which sector we
- *  are positioned at (relative to starting sector of segment)
- */
-static void determine_verify_progress(buffer_struct *buff,
-                                     error_cause cause,
-                                     __u8 sector)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (cause == no_error && sector == 1) {
-               buff->sector_offset = FT_SECTORS_PER_SEGMENT;
-               buff->remaining     = 0;
-               if (TRACE_LEVEL >= ft_t_flow) {
-                       print_progress(buff, cause);
-               }
-       } else {
-               buff->sector_offset = sector - buff->sect;
-               buff->remaining = FT_SECTORS_PER_SEGMENT - buff->sector_offset;
-               TRACE(ft_t_noise, "%ssector offset: 0x%04x", 
-                     (cause == no_error) ? "unexpected " : "",
-                     buff->sector_offset);
-               switch (cause) {
-               case overrun_error:
-                       break;
-#if 0
-               case no_data_error:
-                       buff->retry = FT_SOFT_RETRIES;
-                       if (buff->hard_error_map    &&
-                           buff->sector_offset > 1 &&
-                           (buff->hard_error_map & 
-                            (1 << (buff->sector_offset-2)))) {
-                               buff->retry --;
-                       }
-                       break;
-#endif
-               default:
-                       buff->retry = FT_SOFT_RETRIES;
-                       break;
-               }
-               if (TRACE_LEVEL >= ft_t_flow) {
-                       print_progress(buff, cause);
-               }
-               /*  Sector_offset points to the problem area Now adjust
-                *  sector_offset so it always points one past he failing
-                *  sector. I.e. skip the bad sector.
-                */
-               ++buff->sector_offset;
-               --buff->remaining;
-               update_error_maps(buff, buff->sector_offset - 1);
-       }
-       TRACE_EXIT;
-}
-
-static void determine_progress(buffer_struct *buff,
-                              error_cause cause,
-                              __u8 sector)
-{
-       unsigned int dma_residue;
-       TRACE_FUN(ft_t_any);
-
-       /*  Using less preferred order of disable_dma and
-        *  get_dma_residue because this seems to fail on at least one
-        *  system if reversed!
-        */
-       dma_residue = get_dma_residue(fdc.dma);
-       disable_dma(fdc.dma);
-       if (cause != no_error || dma_residue != 0) {
-               TRACE(ft_t_noise, "%sDMA residue: 0x%04x", 
-                     (cause == no_error) ? "unexpected " : "",
-                     dma_residue);
-               /* adjust to actual value: */
-               if (dma_residue == 0) {
-                       /* this happens sometimes with overrun errors.
-                        * I don't know whether we could ignore the
-                        * overrun error. Play save.
-                        */
-                       buff->sector_count --;
-               } else {
-                       buff->sector_count -= ((dma_residue + 
-                                               (FT_SECTOR_SIZE - 1)) /
-                                              FT_SECTOR_SIZE);
-               }
-       }
-       /*  Update var's influenced by the DMA operation.
-        */
-       if (buff->sector_count > 0) {
-               buff->sector_offset   += buff->sector_count;
-               buff->data_offset     += buff->sector_count;
-               buff->ptr             += (buff->sector_count *
-                                         FT_SECTOR_SIZE);
-               buff->remaining       -= buff->sector_count;
-               buff->bad_sector_map >>= buff->sector_count;
-       }
-       if (TRACE_LEVEL >= ft_t_flow) {
-               print_progress(buff, cause);
-       }
-       if (cause != no_error) {
-               if (buff->remaining == 0) {
-                       TRACE(ft_t_warn, "foo?\n"
-                             KERN_INFO "count : %d\n"
-                             KERN_INFO "offset: %d\n"
-                             KERN_INFO "soft  : %08x\n"
-                             KERN_INFO "hard  : %08x",
-                             buff->sector_count,
-                             buff->sector_offset,
-                             buff->soft_error_map,
-                             buff->hard_error_map);
-               }
-               /*  Sector_offset points to the problem area, except if we got
-                *  a data_crc_error. In that case it points one past the
-                *  failing sector.
-                *
-                *  Now adjust sector_offset so it always points one past he
-                *  failing sector. I.e. skip the bad sector.  
-                */
-               if (cause != data_crc_error) {
-                       skip_bad_sector(buff);
-               }
-               update_error_maps(buff, buff->sector_offset - 1);
-       }
-       TRACE_EXIT;
-}
-
-static int calc_steps(int cmd)
-{
-       if (ftape_current_cylinder > cmd) {
-               return ftape_current_cylinder - cmd;
-       } else {
-               return ftape_current_cylinder + cmd;
-       }
-}
-
-static void pause_tape(int retry, int mode)
-{
-       int result;
-       __u8 out[3] = {FDC_SEEK, ft_drive_sel, 0};
-       TRACE_FUN(ft_t_any);
-
-       /*  We'll use a raw seek command to get the tape to rewind and
-        *  stop for a retry.
-        */
-       ++ft_history.rewinds;
-       if (qic117_cmds[ftape_current_command].non_intr) {
-               TRACE(ft_t_warn, "motion command may be issued too soon");
-       }
-       if (retry && (mode == fdc_reading_data ||
-                     mode == fdc_reading_id   ||
-                     mode == fdc_verifying)) {
-               ftape_current_command = QIC_MICRO_STEP_PAUSE;
-               ftape_might_be_off_track = 1;
-       } else {
-               ftape_current_command = QIC_PAUSE;
-       }
-       out[2] = calc_steps(ftape_current_command);
-       result = fdc_command(out, 3); /* issue QIC_117 command */
-       ftape_current_cylinder = out[ 2];
-       if (result < 0) {
-               TRACE(ft_t_noise, "qic-pause failed, status = %d", result);
-       } else {
-               ft_location.known  = 0;
-               ft_runner_status   = idle;
-               ft_hide_interrupt     = 1;
-               ftape_tape_running = 0;
-       }
-       TRACE_EXIT;
-}
-
-static void continue_xfer(buffer_struct *buff,
-                         fdc_mode_enum mode, 
-                         unsigned int skip)
-{
-       int write = 0;
-       TRACE_FUN(ft_t_any);
-
-       if (mode == fdc_writing_data || mode == fdc_deleting) {
-               write = 1;
-       }
-       /*  This part can be removed if it never happens
-        */
-       if (skip > 0 &&
-           (ft_runner_status != running ||
-            (write && (buff->status != writing)) ||
-            (!write && (buff->status != reading && 
-                        buff->status != verifying)))) {
-               TRACE(ft_t_err, "unexpected runner/buffer state %d/%d",
-                     ft_runner_status, buff->status);
-               buff->status = error;
-               /* finish this buffer: */
-               (void)ftape_next_buffer(ft_queue_head);
-               ft_runner_status = aborting;
-               fdc_mode         = fdc_idle;
-       } else if (buff->remaining > 0 && ftape_calc_next_cluster(buff) > 0) {
-               /*  still sectors left in current segment, continue
-                *  with this segment
-                */
-               if (fdc_setup_read_write(buff, mode) < 0) {
-                       /* failed, abort operation
-                        */
-                       buff->bytes = buff->ptr - buff->address;
-                       buff->status = error;
-                       /* finish this buffer: */
-                       (void)ftape_next_buffer(ft_queue_head);
-                       ft_runner_status = aborting;
-                       fdc_mode         = fdc_idle;
-               }
-       } else {
-               /* current segment completed
-                */
-               unsigned int last_segment = buff->segment_id;
-               int eot = ((last_segment + 1) % ft_segments_per_track) == 0;
-               unsigned int next = buff->next_segment; /* 0 means stop ! */
-
-               buff->bytes = buff->ptr - buff->address;
-               buff->status = done;
-               buff = ftape_next_buffer(ft_queue_head);
-               if (eot) {
-                       /*  finished last segment on current track,
-                        *  can't continue
-                        */
-                       ft_runner_status = logical_eot;
-                       fdc_mode         = fdc_idle;
-                       TRACE_EXIT;
-               }
-               if (next <= 0) {
-                       /*  don't continue with next segment
-                        */
-                       TRACE(ft_t_noise, "no %s allowed, stopping tape",
-                             (write) ? "write next" : "read ahead");
-                       pause_tape(0, mode);
-                       ft_runner_status = idle;  /*  not quite true until
-                                                  *  next irq 
-                                                  */
-                       TRACE_EXIT;
-               }
-               /*  continue with next segment
-                */
-               if (buff->status != waiting) {
-                       TRACE(ft_t_noise, "all input buffers %s, pausing tape",
-                             (write) ? "empty" : "full");
-                       pause_tape(0, mode);
-                       ft_runner_status = idle;  /*  not quite true until
-                                                  *  next irq 
-                                                  */
-                       TRACE_EXIT;
-               }
-               if (write && next != buff->segment_id) {
-                       TRACE(ft_t_noise, 
-                             "segments out of order, aborting write");
-                       ft_runner_status = do_abort;
-                       fdc_mode         = fdc_idle;
-                       TRACE_EXIT;
-               }
-               ftape_setup_new_segment(buff, next, 0);
-               if (stop_read_ahead) {
-                       buff->next_segment = 0;
-                       stop_read_ahead = 0;
-               }
-               if (ftape_calc_next_cluster(buff) == 0 ||
-                   fdc_setup_read_write(buff, mode) != 0) {
-                       TRACE(ft_t_err, "couldn't start %s-ahead",
-                             write ? "write" : "read");
-                       ft_runner_status = do_abort;
-                       fdc_mode         = fdc_idle;
-               } else {
-                       /* keep on going */
-                       switch (ft_driver_state) {
-                       case   reading: buff->status = reading;   break;
-                       case verifying: buff->status = verifying; break;
-                       case   writing: buff->status = writing;   break;
-                       case  deleting: buff->status = deleting;  break;
-                       default:
-                               TRACE(ft_t_err, 
-                     "BUG: ft_driver_state %d should be one out of "
-                     "{reading, writing, verifying, deleting}",
-                                     ft_driver_state);
-                               buff->status = write ? writing : reading;
-                               break;
-                       }
-               }
-       }
-       TRACE_EXIT;
-}
-
-static void retry_sector(buffer_struct *buff, 
-                        int mode,
-                        unsigned int skip)
-{
-       TRACE_FUN(ft_t_any);
-
-       TRACE(ft_t_noise, "%s error, will retry",
-             (mode == fdc_writing_data || mode == fdc_deleting) ? "write" : "read");
-       pause_tape(1, mode);
-       ft_runner_status = aborting;
-       buff->status     = error;
-       buff->skip       = skip;
-       TRACE_EXIT;
-}
-
-static unsigned int find_resume_point(buffer_struct *buff)
-{
-       int i = 0;
-       SectorMap mask;
-       SectorMap map;
-       TRACE_FUN(ft_t_any);
-
-       /*  This function is to be called after all variables have been
-        *  updated to point past the failing sector.
-        *  If there are any soft errors before the failing sector,
-        *  find the first soft error and return the sector offset.
-        *  Otherwise find the last hard error.
-        *  Note: there should always be at least one hard or soft error !
-        */
-       if (buff->sector_offset < 1 || buff->sector_offset > 32) {
-               TRACE(ft_t_bug, "BUG: sector_offset = %d",
-                     buff->sector_offset);
-               TRACE_EXIT 0;
-       }
-       if (buff->sector_offset >= 32) { /* C-limitation on shift ! */
-               mask = 0xffffffff;
-       } else {
-               mask = (1 << buff->sector_offset) - 1;
-       }
-       map = buff->soft_error_map & mask;
-       if (map) {
-               while ((map & (1 << i)) == 0) {
-                       ++i;
-               }
-               TRACE(ft_t_noise, "at sector %d", FT_SECTOR(i));
-       } else {
-               map = buff->hard_error_map & mask;
-               i = buff->sector_offset - 1;
-               if (map) {
-                       while ((map & (1 << i)) == 0) {
-                               --i;
-                       }
-                       TRACE(ft_t_noise, "after sector %d", FT_SECTOR(i));
-                       ++i; /* first sector after last hard error */
-               } else {
-                       TRACE(ft_t_bug, "BUG: no soft or hard errors");
-               }
-       }
-       TRACE_EXIT i;
-}
-
-/*  check possible dma residue when formatting, update position record in
- *  buffer struct. This is, of course, modelled after determine_progress(), but
- *  we don't need to set up for retries because the format process cannot be
- *  interrupted (except at the end of the tape track).
- */
-static int determine_fmt_progress(buffer_struct *buff, error_cause cause)
-{
-       unsigned int dma_residue;
-       TRACE_FUN(ft_t_any);
-
-       /*  Using less preferred order of disable_dma and
-        *  get_dma_residue because this seems to fail on at least one
-        *  system if reversed!
-        */
-       dma_residue = get_dma_residue(fdc.dma);
-       disable_dma(fdc.dma);
-       if (cause != no_error || dma_residue != 0) {
-               TRACE(ft_t_info, "DMA residue = 0x%04x", dma_residue);
-               fdc_mode = fdc_idle;
-               switch(cause) {
-               case no_error:
-                       ft_runner_status = aborting;
-                       buff->status = idle;
-                       break;
-               case overrun_error:
-                       /*  got an overrun error on the first byte, must be a
-                        *  hardware problem 
-                        */
-                       TRACE(ft_t_bug, 
-                             "Unexpected error: failing DMA controller ?");
-                       ft_runner_status = do_abort;
-                       buff->status = error;
-                       break;
-               default:
-                       TRACE(ft_t_noise, "Unexpected error at segment %d",
-                             buff->segment_id);
-                       ft_runner_status = do_abort;
-                       buff->status = error;
-                       break;
-               }
-               TRACE_EXIT -EIO; /* can only retry entire track in format mode
-                                 */
-       }
-       /*  Update var's influenced by the DMA operation.
-        */
-       buff->ptr             += FT_SECTORS_PER_SEGMENT * 4;
-       buff->bytes           -= FT_SECTORS_PER_SEGMENT * 4;
-       buff->remaining       -= FT_SECTORS_PER_SEGMENT;
-       buff->segment_id ++; /* done with segment */
-       TRACE_EXIT 0;
-}
-
-/*
- *  Continue formatting, switch buffers if there is no data left in
- *  current buffer. This is, of course, modelled after
- *  continue_xfer(), but we don't need to set up for retries because
- *  the format process cannot be interrupted (except at the end of the
- *  tape track).
- */
-static void continue_formatting(buffer_struct *buff)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (buff->remaining <= 0) { /*  no space left in dma buffer */
-               unsigned int next = buff->next_segment; 
-
-               if (next == 0) { /* end of tape track */
-                       buff->status     = done;
-                       ft_runner_status = logical_eot;
-                       fdc_mode         = fdc_idle;
-                       TRACE(ft_t_noise, "Done formatting track %d",
-                             ft_location.track);
-                       TRACE_EXIT;
-               }
-               /*
-                *  switch to next buffer!
-                */
-               buff->status   = done;
-               buff = ftape_next_buffer(ft_queue_head);
-
-               if (buff->status != waiting  || next != buff->segment_id) {
-                       goto format_setup_error;
-               }
-       }
-       if (fdc_setup_formatting(buff) < 0) {
-               goto format_setup_error;
-       }
-       buff->status = formatting;
-       TRACE(ft_t_fdc_dma, "Formatting segment %d on track %d",
-             buff->segment_id, ft_location.track);
-       TRACE_EXIT;
- format_setup_error:
-       ft_runner_status = do_abort;
-       fdc_mode         = fdc_idle;
-       buff->status     = error;
-       TRACE(ft_t_err, "Error setting up for segment %d on track %d",
-             buff->segment_id, ft_location.track);
-       TRACE_EXIT;
-
-}
-
-/*  this handles writing, read id, reading and formatting
- */
-static void handle_fdc_busy(buffer_struct *buff)
-{
-       static int no_data_error_count;
-       int retry = 0;
-       error_cause cause;
-       __u8 in[7];
-       int skip;
-       fdc_mode_enum fmode = fdc_mode;
-       TRACE_FUN(ft_t_any);
-
-       if (fdc_result(in, 7) < 0) { /* better get it fast ! */
-               TRACE(ft_t_err, 
-                     "Probably fatal error during FDC Result Phase\n"
-                     KERN_INFO
-                     "drive may hang until (power on) reset :-(");
-               /*  what to do next ????
-                */
-               TRACE_EXIT;
-       }
-       cause = decode_irq_cause(fdc_mode, in);
-#ifdef TESTING
-       { int i;
-       for (i = 0; i < (int)ft_nr_buffers; ++i)
-               TRACE(ft_t_any, "buffer[%d] status: %d, segment_id: %d",
-                     i, ft_buffer[i]->status, ft_buffer[i]->segment_id);
-       }
-#endif
-       if (fmode == fdc_reading_data && ft_driver_state == verifying) {
-               fmode = fdc_verifying;
-       }
-       switch (fmode) {
-       case fdc_verifying:
-               if (ft_runner_status == aborting ||
-                   ft_runner_status == do_abort) {
-                       TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
-                       break;
-               }
-               if (buff->retry > 0) {
-                       TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
-               }
-               switch (cause) {
-               case no_error:
-                       no_data_error_count = 0;
-                       determine_verify_progress(buff, cause, in[5]);
-                       if (in[2] & 0x40) {
-                               /*  This should not happen when verifying
-                                */
-                               TRACE(ft_t_warn,
-                                     "deleted data in segment %d/%d",
-                                     buff->segment_id,
-                                     FT_SECTOR(buff->sector_offset - 1));
-                               buff->remaining = 0; /* abort transfer */
-                               buff->hard_error_map = EMPTY_SEGMENT;
-                               skip = 1;
-                       } else {
-                               skip = 0;
-                       }
-                       continue_xfer(buff, fdc_mode, skip);
-                       break;
-               case no_data_error:
-                       no_data_error_count ++;
-               case overrun_error:
-                       retry ++;
-               case id_am_error:
-               case id_crc_error:
-               case data_am_error:
-               case data_crc_error:
-                       determine_verify_progress(buff, cause, in[5]); 
-                       if (cause == no_data_error) {
-                               if (no_data_error_count >= 2) {
-                                       TRACE(ft_t_warn,
-                                             "retrying because of successive "
-                                             "no data errors");
-                                       no_data_error_count = 0;
-                               } else {
-                                       retry --;
-                               }
-                       } else {
-                               no_data_error_count = 0;
-                       }
-                       if (retry) {
-                               skip = find_resume_point(buff);
-                       } else {
-                               skip = buff->sector_offset;
-                       }
-                       if (retry && skip < 32) {
-                               retry_sector(buff, fdc_mode, skip);
-                       } else {
-                               continue_xfer(buff, fdc_mode, skip);
-                       }
-                       update_history(cause);
-                       break;
-               default:
-                       /*  Don't know why this could happen 
-                        *  but find out.
-                        */
-                       determine_verify_progress(buff, cause, in[5]);
-                       retry_sector(buff, fdc_mode, 0);
-                       TRACE(ft_t_err, "Error: unexpected error");
-                       break;
-               }
-               break;
-       case fdc_reading_data:
-#ifdef TESTING
-               /* I'm sorry, but: NOBODY ever used this trace
-                * messages for ages. I guess that Bas was the last person
-                * that ever really used this (thank you, between the lines)
-                */
-               if (cause == no_error) {
-                       TRACE(ft_t_flow,"reading segment %d",buff->segment_id);
-               } else {
-                       TRACE(ft_t_noise, "error reading segment %d",
-                             buff->segment_id);
-                       TRACE(ft_t_noise, "\n"
-                             KERN_INFO
-                            "IRQ:C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x\n"
-                             KERN_INFO
-                             "BUF:C: 0x%02x, H: 0x%02x, R: 0x%02x",
-                             in[3], in[4], in[5], in[6],
-                             buff->cyl, buff->head, buff->sect);
-               }
-#endif
-               if (ft_runner_status == aborting ||
-                   ft_runner_status == do_abort) {
-                       TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
-                       break;
-               }
-               if (buff->bad_sector_map == FAKE_SEGMENT) {
-                       /* This condition occurs when reading a `fake'
-                        * sector that's not accessible. Doesn't
-                        * really matter as we would have ignored it
-                        * anyway !
-                        *
-                        * Chance is that we're past the next segment
-                        * now, so the next operation may fail and
-                        * result in a retry.  
-                        */
-                       buff->remaining = 0;    /* skip failing sector */
-                       /* buff->ptr       = buff->address; */
-                       /* fake success: */
-                       continue_xfer(buff, fdc_mode, 1);
-                       /*  trace calls are expensive: place them AFTER
-                        *  the real stuff has been done.
-                        *  
-                        */
-                       TRACE(ft_t_noise, "skipping empty segment %d (read), size? %d",
-                             buff->segment_id, buff->ptr - buff->address);
-                       TRACE_EXIT;
-               }
-               if (buff->retry > 0) {
-                       TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
-               }
-               switch (cause) {
-               case no_error:
-                       determine_progress(buff, cause, in[5]);
-                       if (in[2] & 0x40) {
-                               /*  Handle deleted data in header segments.
-                                *  Skip segment and force read-ahead.
-                                */
-                               TRACE(ft_t_warn,
-                                     "deleted data in segment %d/%d",
-                                     buff->segment_id,
-                                     FT_SECTOR(buff->sector_offset - 1));
-                               buff->deleted = 1;
-                               buff->remaining = 0;/*abort transfer */
-                               buff->soft_error_map |=
-                                               (-1L << buff->sector_offset);
-                               if (buff->segment_id == 0) {
-                                       /* stop on next segment */
-                                       stop_read_ahead = 1;
-                               }
-                               /* force read-ahead: */
-                               buff->next_segment = 
-                                       buff->segment_id + 1;
-                               skip = (FT_SECTORS_PER_SEGMENT - 
-                                       buff->sector_offset);
-                       } else {
-                               skip = 0;
-                       }
-                       continue_xfer(buff, fdc_mode, skip);
-                       break;
-               case no_data_error:
-                       /* Tape started too far ahead of or behind the
-                        * right sector.  This may also happen in the
-                        * middle of a segment !
-                        *
-                        * Handle no-data as soft error. If next
-                        * sector fails too, a retry (with needed
-                        * reposition) will follow.
-                        */
-                       retry ++;
-               case id_am_error:
-               case id_crc_error:
-               case data_am_error:
-               case data_crc_error:
-               case overrun_error:
-                       retry += (buff->soft_error_map != 0 ||
-                                 buff->hard_error_map != 0);
-                       determine_progress(buff, cause, in[5]); 
-#if 1 || defined(TESTING)
-                       if (cause == overrun_error) retry ++;
-#endif
-                       if (retry) {
-                               skip = find_resume_point(buff);
-                       } else {
-                               skip = buff->sector_offset;
-                       }
-                       /*  Try to resume with next sector on single
-                        *  errors (let ecc correct it), but retry on
-                        *  no_data (we'll be past the target when we
-                        *  get here so we cannot retry) or on
-                        *  multiple errors (reduce chance on ecc
-                        *  failure).
-                        */
-                       /*  cH: 23/02/97: if the last sector in the 
-                        *  segment was a hard error, then there is 
-                        *  no sense in a retry. This occasion seldom
-                        *  occurs but ... @:³²¸`@%&§$
-                        */
-                       if (retry && skip < 32) {
-                               retry_sector(buff, fdc_mode, skip);
-                       } else {
-                               continue_xfer(buff, fdc_mode, skip);
-                       }
-                       update_history(cause);
-                       break;
-               default:
-                       /*  Don't know why this could happen 
-                        *  but find out.
-                        */
-                       determine_progress(buff, cause, in[5]);
-                       retry_sector(buff, fdc_mode, 0);
-                       TRACE(ft_t_err, "Error: unexpected error");
-                       break;
-               }
-               break;
-       case fdc_reading_id:
-               if (cause == no_error) {
-                       fdc_cyl = in[3];
-                       fdc_head = in[4];
-                       fdc_sect = in[5];
-                       TRACE(ft_t_fdc_dma,
-                             "id read: C: 0x%02x, H: 0x%02x, R: 0x%02x",
-                             fdc_cyl, fdc_head, fdc_sect);
-               } else {        /* no valid information, use invalid sector */
-                       fdc_cyl = fdc_head = fdc_sect = 0;
-                       TRACE(ft_t_flow, "Didn't find valid sector Id");
-               }
-               fdc_mode = fdc_idle;
-               break;
-       case fdc_deleting:
-       case fdc_writing_data:
-#ifdef TESTING
-               if (cause == no_error) {
-                       TRACE(ft_t_flow, "writing segment %d", buff->segment_id);
-               } else {
-                       TRACE(ft_t_noise, "error writing segment %d",
-                             buff->segment_id);
-               }
-#endif
-               if (ft_runner_status == aborting ||
-                   ft_runner_status == do_abort) {
-                       TRACE(ft_t_flow, "aborting %s",fdc_mode_txt(fdc_mode));
-                       break;
-               }
-               if (buff->retry > 0) {
-                       TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
-               }
-               if (buff->bad_sector_map == FAKE_SEGMENT) {
-                       /* This condition occurs when trying to write to a
-                        * `fake' sector that's not accessible. Doesn't really
-                        * matter as it isn't used anyway ! Might be located
-                        * at wrong segment, then we'll fail on the next
-                        * segment.
-                        */
-                       TRACE(ft_t_noise, "skipping empty segment (write)");
-                       buff->remaining = 0;    /* skip failing sector */
-                       /* fake success: */
-                       continue_xfer(buff, fdc_mode, 1);
-                       break;
-               }
-               switch (cause) {
-               case no_error:
-                       determine_progress(buff, cause, in[5]);
-                       continue_xfer(buff, fdc_mode, 0);
-                       break;
-               case no_data_error:
-               case id_am_error:
-               case id_crc_error:
-               case data_am_error:
-               case overrun_error:
-                       update_history(cause);
-                       determine_progress(buff, cause, in[5]);
-                       skip = find_resume_point(buff);
-                       retry_sector(buff, fdc_mode, skip);
-                       break;
-               default:
-                       if (in[1] & 0x02) {
-                               TRACE(ft_t_err, "media not writable");
-                       } else {
-                               TRACE(ft_t_bug, "unforeseen write error");
-                       }
-                       fdc_mode = fdc_idle;
-                       break;
-               }
-               break; /* fdc_deleting || fdc_writing_data */
-       case fdc_formatting:
-               /*  The interrupt comes after formatting a segment. We then
-                *  have to set up QUICKLY for the next segment. But
-                *  afterwards, there is plenty of time.
-                */
-               switch (cause) {
-               case no_error:
-                       /*  would like to keep most of the formatting stuff
-                        *  outside the isr code, but timing is too critical
-                        */
-                       if (determine_fmt_progress(buff, cause) >= 0) {
-                               continue_formatting(buff);
-                       }
-                       break;
-               case no_data_error:
-               case id_am_error:
-               case id_crc_error:
-               case data_am_error:
-               case overrun_error:
-               default:
-                       determine_fmt_progress(buff, cause);
-                       update_history(cause);
-                       if (in[1] & 0x02) {
-                               TRACE(ft_t_err, "media not writable");
-                       } else {
-                               TRACE(ft_t_bug, "unforeseen write error");
-                       }
-                       break;
-               } /* cause */
-               break;
-       default:
-               TRACE(ft_t_warn, "Warning: unexpected irq during: %s",
-                     fdc_mode_txt(fdc_mode));
-               fdc_mode = fdc_idle;
-               break;
-       }
-       TRACE_EXIT;
-}
-
-/*      FDC interrupt service routine.
- */
-void fdc_isr(void)
-{
-       static int isr_active;
-#ifdef TESTING
-       unsigned int t0 = ftape_timestamp();
-#endif
-       TRACE_FUN(ft_t_any);
-
-       if (isr_active++) {
-               --isr_active;
-               TRACE(ft_t_bug, "BUG: nested interrupt, not good !");
-               *fdc.hook = fdc_isr; /*  hook our handler into the fdc
-                                     *  code again 
-                                     */
-               TRACE_EXIT;
-       }
-       sti();
-       if (inb_p(fdc.msr) & FDC_BUSY) {        /*  Entering Result Phase */
-               ft_hide_interrupt = 0;
-               handle_fdc_busy(ftape_get_buffer(ft_queue_head));
-               if (ft_runner_status == do_abort) {
-                       /*      cease operation, remember tape position
-                        */
-                       TRACE(ft_t_flow, "runner aborting");
-                       ft_runner_status = aborting;
-                       ++ft_expected_stray_interrupts;
-               }
-       } else { /* !FDC_BUSY */
-               /*  clear interrupt, cause should be gotten by issuing
-                *  a Sense Interrupt Status command.
-                */
-               if (fdc_mode == fdc_recalibrating || fdc_mode == fdc_seeking) {
-                       if (ft_hide_interrupt) {
-                               int st0;
-                               int pcn;
-
-                               if (fdc_sense_interrupt_status(&st0, &pcn) < 0)
-                                       TRACE(ft_t_err,
-                                             "sense interrupt status failed");
-                               ftape_current_cylinder = pcn;
-                               TRACE(ft_t_flow, "handled hidden interrupt");
-                       }
-                       ft_seek_completed = 1;
-                       fdc_mode = fdc_idle;
-               } else if (!waitqueue_active(&ftape_wait_intr)) {
-                       if (ft_expected_stray_interrupts == 0) {
-                               TRACE(ft_t_warn, "unexpected stray interrupt");
-                       } else {
-                               TRACE(ft_t_flow, "expected stray interrupt");
-                               --ft_expected_stray_interrupts;
-                       }
-               } else {
-                       if (fdc_mode == fdc_reading_data ||
-                           fdc_mode == fdc_verifying    ||
-                           fdc_mode == fdc_writing_data ||
-                           fdc_mode == fdc_deleting     ||
-                           fdc_mode == fdc_formatting   ||
-                           fdc_mode == fdc_reading_id) {
-                               if (inb_p(fdc.msr) & FDC_BUSY) {
-                                       TRACE(ft_t_bug,
-                                       "***** FDC failure, busy too late");
-                               } else {
-                                       TRACE(ft_t_bug,
-                                             "***** FDC failure, no busy");
-                               }
-                       } else {
-                               TRACE(ft_t_fdc_dma, "awaited stray interrupt");
-                       }
-               }
-               ft_hide_interrupt = 0;
-       }
-       /*    Handle sleep code.
-        */
-       if (!ft_hide_interrupt) {
-               ft_interrupt_seen ++;
-               if (waitqueue_active(&ftape_wait_intr)) {
-                       wake_up_interruptible(&ftape_wait_intr);
-               }
-       } else {
-               TRACE(ft_t_flow, "hiding interrupt while %s", 
-                     waitqueue_active(&ftape_wait_intr) ? "waiting":"active");
-       }
-#ifdef TESTING
-       t0 = ftape_timediff(t0, ftape_timestamp());
-       if (t0 >= 1000) {
-               /* only tell us about long calls */
-               TRACE(ft_t_noise, "isr() duration: %5d usec", t0);
-       }
-#endif
-       *fdc.hook = fdc_isr;    /* hook our handler into the fdc code again */
-       --isr_active;
-       TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/lowlevel/fdc-isr.h b/drivers/char/ftape/lowlevel/fdc-isr.h
deleted file mode 100644 (file)
index 065aa97..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _FDC_ISR_H
-#define _FDC_ISR_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-isr.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:07 $
- *
- *      This file declares the global variables necessary to
- *      synchronize the interrupt service routine (isr) with the
- *      remainder of the QIC-40/80/3010/3020 floppy-tape driver
- *      "ftape" for Linux.
- */
-
-/*
- *      fdc-isr.c defined public variables
- */
-extern volatile int ft_expected_stray_interrupts; /* masks stray interrupts */
-extern volatile int ft_seek_completed;           /* flag set by isr */
-extern volatile int ft_interrupt_seen;           /* flag set by isr */
-extern volatile int ft_hide_interrupt;            /* flag set by isr */
-
-/*
- *      fdc-io.c defined public functions
- */
-extern void fdc_isr(void);
-
-/*
- *      A kernel hook that steals one interrupt from the floppy
- *      driver (Should be fixed when the new fdc driver gets ready)
- *      See the linux kernel source files:
- *          drivers/block/floppy.c & drivers/block/blk.h
- *      for the details.
- */
-extern void (*do_floppy) (void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-bsm.c b/drivers/char/ftape/lowlevel/ftape-bsm.c
deleted file mode 100644 (file)
index d1a301c..0000000
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- *      Copyright (C) 1994-1996 Bas Laarhoven,
- *                (C) 1996-1997 Claus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-bsm.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:15:15 $
- *
- *      This file contains the bad-sector map handling code for
- *      the QIC-117 floppy tape driver for Linux.
- *      QIC-40, QIC-80, QIC-3010 and QIC-3020 maps are implemented.
- */
-
-#include <linux/string.h>
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-
-/*      Global vars.
- */
-
-/*      Local vars.
- */
-static __u8 *bad_sector_map;
-static SectorCount *bsm_hash_ptr; 
-
-typedef enum {
-       forward, backward
-} mode_type;
-
-#if 0
-static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map);
-#endif
-
-#if 0
-/*  fix_tape converts a normal QIC-80 tape into a 'wide' tape.
- *  For testing purposes only !
- */
-void fix_tape(__u8 * buffer, ft_format_type new_code)
-{
-       static __u8 list[BAD_SECTOR_MAP_SIZE];
-       SectorMap *src_ptr = (SectorMap *) list;
-       __u8 *dst_ptr = bad_sector_map;
-       SectorMap map;
-       unsigned int sector = 1;
-       int i;
-
-       if (format_code != fmt_var && format_code != fmt_big) {
-               memcpy(list, bad_sector_map, sizeof(list));
-               memset(bad_sector_map, 0, sizeof(bad_sector_map));
-               while ((__u8 *) src_ptr - list < sizeof(list)) {
-                       map = *src_ptr++;
-                       if (map == EMPTY_SEGMENT) {
-                               *(SectorMap *) dst_ptr = 0x800000 + sector;
-                               dst_ptr += 3;
-                               sector += SECTORS_PER_SEGMENT;
-                       } else {
-                               for (i = 0; i < SECTORS_PER_SEGMENT; ++i) {
-                                       if (map & 1) {
-                                               *(SewctorMap *) dst_ptr = sector;
-                                               dst_ptr += 3;
-                                       }
-                                       map >>= 1;
-                                       ++sector;
-                               }
-                       }
-               }
-       }
-       bad_sector_map_changed = 1;
-       *(buffer + 4) = new_code;       /* put new format code */
-       if (format_code != fmt_var && new_code == fmt_big) {
-               PUT4(buffer, FT_6_HSEG_1,   (__u32)GET2(buffer, 6));
-               PUT4(buffer, FT_6_HSEG_2,   (__u32)GET2(buffer, 8));
-               PUT4(buffer, FT_6_FRST_SEG, (__u32)GET2(buffer, 10));
-               PUT4(buffer, FT_6_LAST_SEG, (__u32)GET2(buffer, 12));
-               memset(buffer+6, '\0', 8);
-       }
-       format_code = new_code;
-}
-
-#endif
-
-/*   given buffer that contains a header segment, find the end of
- *   of the bsm list
- */
-__u8 * ftape_find_end_of_bsm_list(__u8 * address)
-{
-       __u8 *ptr   = address + FT_HEADER_END; /* start of bsm list */
-       __u8 *limit = address + FT_SEGMENT_SIZE;
-       while (ptr + 2 < limit) {
-               if (ptr[0] || ptr[1] || ptr[2]) {
-                       ptr += 3;
-               } else {
-                       return ptr;
-               }
-       }
-       return NULL;
-}
-
-static inline void put_sector(SectorCount *ptr, unsigned int sector)
-{
-       ptr->bytes[0] = sector & 0xff;
-       sector >>= 8;
-       ptr->bytes[1] = sector & 0xff;
-       sector >>= 8;
-       ptr->bytes[2] = sector & 0xff;
-}
-
-static inline unsigned int get_sector(SectorCount *ptr)
-{
-#if 1
-       unsigned int sector;
-
-       sector  = ptr->bytes[0];
-       sector += ptr->bytes[1] <<  8;
-       sector += ptr->bytes[2] << 16;
-
-       return sector;
-#else
-       /*  GET4 gets the next four bytes in Intel little endian order
-        *  and converts them to host byte order and handles unaligned
-        *  access.
-        */
-       return (GET4(ptr, 0) & 0x00ffffff); /* back to host byte order */
-#endif
-}
-
-static void bsm_debug_fake(void)
-{
-       /* for testing of bad sector handling at end of tape
-        */
-#if 0
-       ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 3,
-                                  0x000003e0;
-       ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 2,
-                                  0xff3fffff;
-       ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 1,
-                                  0xffffe000;
-#endif
-       /*  Enable to test bad sector handling
-        */
-#if 0
-       ftape_put_bad_sector_entry(30, 0xfffffffe)
-       ftape_put_bad_sector_entry(32, 0x7fffffff);
-       ftape_put_bad_sector_entry(34, 0xfffeffff);
-       ftape_put_bad_sector_entry(36, 0x55555555);
-       ftape_put_bad_sector_entry(38, 0xffffffff);
-       ftape_put_bad_sector_entry(50, 0xffff0000);
-       ftape_put_bad_sector_entry(51, 0xffffffff);
-       ftape_put_bad_sector_entry(52, 0xffffffff);
-       ftape_put_bad_sector_entry(53, 0x0000ffff);
-#endif
-       /*  Enable when testing multiple volume tar dumps.
-        */
-#if 0
-       {
-               int i;
-
-               for (i = ft_first_data_segment;
-                    i <= ft_last_data_segment - 7; ++i) {
-                       ftape_put_bad_sector_entry(i, EMPTY_SEGMENT);
-               }
-       }
-#endif
-       /*  Enable when testing bit positions in *_error_map
-        */
-#if 0
-       {
-               int i;
-               
-               for (i = first_data_segment; i <= last_data_segment; ++i) {
-                       ftape_put_bad_sector_entry(i,
-                                          ftape_get_bad_sector_entry(i) 
-                                          | 0x00ff00ff);
-               }
-       }
-#endif
-}
-
-static void print_bad_sector_map(void)
-{
-       unsigned int good_sectors;
-       unsigned int total_bad = 0;
-       int i;
-       TRACE_FUN(ft_t_flow);
-
-       if (ft_format_code == fmt_big || 
-           ft_format_code == fmt_var || 
-           ft_format_code == fmt_1100ft) {
-               SectorCount *ptr = (SectorCount *)bad_sector_map;
-               unsigned int sector;
-               __u16 *ptr16;
-
-               while((sector = get_sector(ptr++)) != 0) {
-                       if ((ft_format_code == fmt_big || 
-                            ft_format_code == fmt_var) &&
-                           sector & 0x800000) {
-                               total_bad += FT_SECTORS_PER_SEGMENT - 3;
-                               TRACE(ft_t_noise, "bad segment at sector: %6d",
-                                     sector & 0x7fffff);
-                       } else {
-                               ++total_bad;
-                               TRACE(ft_t_noise, "bad sector: %6d", sector);
-                       }
-               }
-               /*  Display old ftape's end-of-file marks
-                */
-               ptr16 = (__u16*)ptr;
-               while ((sector = get_unaligned(ptr16++)) != 0) {
-                       TRACE(ft_t_noise, "Old ftape eof mark: %4d/%2d",
-                             sector, get_unaligned(ptr16++));
-               }
-       } else { /* fixed size format */
-               for (i = ft_first_data_segment;
-                    i < (int)(ft_segments_per_track * ft_tracks_per_tape); ++i) {
-                       SectorMap map = ((SectorMap *) bad_sector_map)[i];
-
-                       if (map) {
-                               TRACE(ft_t_noise,
-                                     "bsm for segment %4d: 0x%08x", i, (unsigned int)map);
-                               total_bad += ((map == EMPTY_SEGMENT)
-                                              ? FT_SECTORS_PER_SEGMENT - 3
-                                              : count_ones(map));
-                       }
-               }
-       }
-       good_sectors =
-               ((ft_segments_per_track * ft_tracks_per_tape - ft_first_data_segment)
-                * (FT_SECTORS_PER_SEGMENT - 3)) - total_bad;
-       TRACE(ft_t_info, "%d Kb usable on this tape", good_sectors);
-       if (total_bad == 0) {
-               TRACE(ft_t_info,
-                     "WARNING: this tape has no bad blocks registered !");
-       } else {
-               TRACE(ft_t_info, "%d bad sectors", total_bad);
-       }
-       TRACE_EXIT;
-}
-
-
-void ftape_extract_bad_sector_map(__u8 * buffer)
-{
-       TRACE_FUN(ft_t_any);
-
-       /*  Fill the bad sector map with the contents of buffer.
-        */
-       if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
-               /* QIC-3010/3020 and wide QIC-80 tapes no longer have a failed
-                * sector log but use this area to extend the bad sector map.
-                */
-               bad_sector_map = &buffer[FT_HEADER_END];
-       } else {
-               /* non-wide QIC-80 tapes have a failed sector log area that
-                * mustn't be included in the bad sector map.
-                */
-               bad_sector_map = &buffer[FT_FSL + FT_FSL_SIZE];
-       }
-       if (ft_format_code == fmt_1100ft || 
-           ft_format_code == fmt_var    ||
-           ft_format_code == fmt_big) {
-               bsm_hash_ptr = (SectorCount *)bad_sector_map;
-       } else {
-               bsm_hash_ptr = NULL;
-       }
-       bsm_debug_fake();
-       if (TRACE_LEVEL >= ft_t_info) {
-               print_bad_sector_map();
-       }
-       TRACE_EXIT;
-}
-
-static inline SectorMap cvt2map(unsigned int sector)
-{
-       return 1 << (((sector & 0x7fffff) - 1) % FT_SECTORS_PER_SEGMENT);
-}
-
-static inline int cvt2segment(unsigned int sector)
-{
-       return ((sector & 0x7fffff) - 1) / FT_SECTORS_PER_SEGMENT;
-}
-
-static int forward_seek_entry(int segment_id, 
-                             SectorCount **ptr, 
-                             SectorMap *map)
-{
-       unsigned int sector;
-       int segment;
-
-       do {
-               sector = get_sector((*ptr)++);
-               segment = cvt2segment(sector);
-       } while (sector != 0 && segment < segment_id);
-       (*ptr) --; /* point to first sector >= segment_id */
-       /*  Get all sectors in segment_id
-        */
-       if (sector == 0 || segment != segment_id) {
-               *map = 0;
-               return 0;
-       } else if ((sector & 0x800000) &&
-                  (ft_format_code == fmt_var || ft_format_code == fmt_big)) {
-               *map = EMPTY_SEGMENT;
-               return FT_SECTORS_PER_SEGMENT;
-       } else {
-               int count = 1;
-               SectorCount *tmp_ptr = (*ptr) + 1;
-               
-               *map = cvt2map(sector);
-               while ((sector = get_sector(tmp_ptr++)) != 0 &&
-                      (segment = cvt2segment(sector)) == segment_id) {
-                       *map |= cvt2map(sector);
-                       ++count;
-               }
-               return count;
-       }
-}
-
-static int backwards_seek_entry(int segment_id,
-                               SectorCount **ptr,
-                               SectorMap *map)
-{
-       unsigned int sector;
-       int segment; /* max unsigned int */
-
-       if (*ptr <= (SectorCount *)bad_sector_map) {
-               *map = 0;
-               return 0;
-       }
-       do {
-               sector  = get_sector(--(*ptr));
-               segment = cvt2segment(sector);
-       } while (*ptr > (SectorCount *)bad_sector_map && segment > segment_id);
-       if (segment > segment_id) { /*  at start of list, no entry found */
-               *map = 0;
-               return 0;
-       } else if (segment < segment_id) {
-               /*  before smaller entry, adjust for overshoot */
-               (*ptr) ++;
-               *map = 0;
-               return 0;
-       } else if ((sector & 0x800000) &&
-                  (ft_format_code == fmt_big || ft_format_code == fmt_var)) {
-               *map = EMPTY_SEGMENT;
-               return FT_SECTORS_PER_SEGMENT;
-       } else { /*  get all sectors in segment_id */
-               int count = 1;
-
-               *map = cvt2map(sector);
-               while(*ptr > (SectorCount *)bad_sector_map) {
-                       sector = get_sector(--(*ptr));
-                       segment = cvt2segment(sector);
-                       if (segment != segment_id) {
-                               break;
-                       }
-                       *map |= cvt2map(sector);
-                       ++count;
-               }
-               if (segment < segment_id) {
-                       (*ptr) ++;
-               }
-               return count;
-       }
-}
-
-#if 0
-static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map)
-{
-       SectorCount *ptr = (SectorCount *)bad_sector_map;
-       int count;
-       int new_count;
-       SectorMap map;
-       TRACE_FUN(ft_t_any);
-
-       if (ft_format_code == fmt_1100ft || 
-           ft_format_code == fmt_var || 
-           ft_format_code == fmt_big) {
-               count = forward_seek_entry(segment_id, &ptr, &map);
-               new_count = count_ones(new_map);
-               /* If format code == 4 put empty segment instead of 32
-                * bad sectors.
-                */
-               if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
-                       if (new_count == FT_SECTORS_PER_SEGMENT) {
-                               new_count = 1;
-                       }
-                       if (count == FT_SECTORS_PER_SEGMENT) {
-                               count = 1;
-                       }
-               }
-               if (count != new_count) {
-                       /* insert (or delete if < 0) new_count - count
-                        * entries.  Move trailing part of list
-                        * including terminating 0.
-                        */
-                       SectorCount *hi_ptr = ptr;
-
-                       do {
-                       } while (get_sector(hi_ptr++) != 0);
-                       /*  Note: ptr is of type byte *, and each bad sector
-                        *  consumes 3 bytes.
-                        */
-                       memmove(ptr + new_count, ptr + count,
-                               (size_t)(hi_ptr - (ptr + count))*sizeof(SectorCount));
-               }
-               TRACE(ft_t_noise, "putting map 0x%08x at %p, segment %d",
-                     (unsigned int)new_map, ptr, segment_id);
-               if (new_count == 1 && new_map == EMPTY_SEGMENT) {
-                       put_sector(ptr++, (0x800001 + 
-                                         segment_id * 
-                                         FT_SECTORS_PER_SEGMENT));
-               } else {
-                       int i = 0;
-
-                       while (new_map) {
-                               if (new_map & 1) {
-                                       put_sector(ptr++, 
-                                                  1 + segment_id * 
-                                                  FT_SECTORS_PER_SEGMENT + i);
-                               }
-                               ++i;
-                               new_map >>= 1;
-                       }
-               }
-       } else {
-               ((SectorMap *) bad_sector_map)[segment_id] = new_map;
-       }
-       TRACE_EXIT;
-}
-#endif  /*  0  */
-
-SectorMap ftape_get_bad_sector_entry(int segment_id)
-{
-       if (ft_used_header_segment == -1) {
-               /*  When reading header segment we'll need a blank map.
-                */
-               return 0;
-       } else if (bsm_hash_ptr != NULL) {
-               /*  Invariants:
-                *    map - mask value returned on last call.
-                *    bsm_hash_ptr - points to first sector greater or equal to
-                *          first sector in last_referenced segment.
-                *    last_referenced - segment id used in the last call,
-                *                      sector and map belong to this id.
-                *  This code is designed for sequential access and retries.
-                *  For true random access it may have to be redesigned.
-                */
-               static int last_reference = -1;
-               static SectorMap map;
-
-               if (segment_id > last_reference) {
-                       /*  Skip all sectors before segment_id
-                        */
-                       forward_seek_entry(segment_id, &bsm_hash_ptr, &map);
-               } else if (segment_id < last_reference) {
-                       /* Skip backwards until begin of buffer or
-                        * first sector in segment_id 
-                        */
-                       backwards_seek_entry(segment_id, &bsm_hash_ptr, &map);
-               }               /* segment_id == last_reference : keep map */
-               last_reference = segment_id;
-               return map;
-       } else {
-               return ((SectorMap *) bad_sector_map)[segment_id];
-       }
-}
-
-/*  This is simply here to prevent us from overwriting other kernel
- *  data. Writes will result in NULL Pointer dereference.
- */
-void ftape_init_bsm(void)
-{
-       bad_sector_map = NULL;
-       bsm_hash_ptr   = NULL;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-bsm.h b/drivers/char/ftape/lowlevel/ftape-bsm.h
deleted file mode 100644 (file)
index ed45465..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _FTAPE_BSM_H
-#define _FTAPE_BSM_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-bsm.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:07 $
- *
- *      This file contains definitions for the bad sector map handling
- *      routines for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape.h>
-#include <linux/ftape-header-segment.h>
-
-#define EMPTY_SEGMENT           (0xffffffff)
-#define FAKE_SEGMENT            (0xfffffffe)
-
-/*  maximum (format code 4) bad sector map size (bytes).
- */
-#define BAD_SECTOR_MAP_SIZE     (29 * SECTOR_SIZE - 256)
-
-/*  format code 4 bad sector entry, ftape uses this
- *  internally for all format codes
- */
-typedef __u32 SectorMap;
-/*  variable and 1100 ft bad sector map entry. These three bytes represent
- *  a single sector address measured from BOT. 
- */
-typedef struct NewSectorMap {          
-       __u8 bytes[3];
-} SectorCount;
-
-
-/*
- *      ftape-bsm.c defined global vars.
- */
-
-/*
- *      ftape-bsm.c defined global functions.
- */
-extern void update_bad_sector_map(__u8 * buffer);
-extern void ftape_extract_bad_sector_map(__u8 * buffer);
-extern SectorMap ftape_get_bad_sector_entry(int segment_id);
-extern __u8 *ftape_find_end_of_bsm_list(__u8 * address);
-extern void ftape_init_bsm(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-buffer.c b/drivers/char/ftape/lowlevel/ftape-buffer.c
deleted file mode 100644 (file)
index c706ff1..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *      Copyright (C) 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-buffer.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/16 23:33:11 $
- *
- *  This file contains the allocator/dealloctor for ftape's dynamic dma
- *  buffer.
- */
-
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <asm/dma.h>
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-buffer.h"
-
-/*  DMA'able memory allocation stuff.
- */
-
-static inline void *dmaalloc(size_t size)
-{
-       unsigned long addr;
-
-       if (size == 0) {
-               return NULL;
-       }
-       addr = __get_dma_pages(GFP_KERNEL, get_order(size));
-       if (addr) {
-               struct page *page;
-
-               for (page = virt_to_page(addr); page < virt_to_page(addr+size); page++)
-                       SetPageReserved(page);
-       }
-       return (void *)addr;
-}
-
-static inline void dmafree(void *addr, size_t size)
-{
-       if (size > 0) {
-               struct page *page;
-
-               for (page = virt_to_page((unsigned long)addr);
-                    page < virt_to_page((unsigned long)addr+size); page++)
-                       ClearPageReserved(page);
-               free_pages((unsigned long) addr, get_order(size));
-       }
-}
-
-static int add_one_buffer(void)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       if (ft_nr_buffers >= FT_MAX_NR_BUFFERS) {
-               TRACE_EXIT -ENOMEM;
-       }
-       ft_buffer[ft_nr_buffers] = kmalloc(sizeof(buffer_struct), GFP_KERNEL);
-       if (ft_buffer[ft_nr_buffers] == NULL) {
-               TRACE_EXIT -ENOMEM;
-       }
-       memset(ft_buffer[ft_nr_buffers], 0, sizeof(buffer_struct));
-       ft_buffer[ft_nr_buffers]->address = dmaalloc(FT_BUFF_SIZE);
-       if (ft_buffer[ft_nr_buffers]->address == NULL) {
-               kfree(ft_buffer[ft_nr_buffers]);
-               ft_buffer[ft_nr_buffers] = NULL;
-               TRACE_EXIT -ENOMEM;
-       }
-       ft_nr_buffers ++;
-       TRACE(ft_t_info, "buffer nr #%d @ %p, dma area @ %p",
-             ft_nr_buffers,
-             ft_buffer[ft_nr_buffers-1],
-             ft_buffer[ft_nr_buffers-1]->address);
-       TRACE_EXIT 0;
-}
-
-static void del_one_buffer(void)
-{
-       TRACE_FUN(ft_t_flow);
-       if (ft_nr_buffers > 0) {
-               TRACE(ft_t_info, "releasing buffer nr #%d @ %p, dma area @ %p",
-                     ft_nr_buffers,
-                     ft_buffer[ft_nr_buffers-1],
-                     ft_buffer[ft_nr_buffers-1]->address);
-               ft_nr_buffers --;
-               dmafree(ft_buffer[ft_nr_buffers]->address, FT_BUFF_SIZE);
-               kfree(ft_buffer[ft_nr_buffers]);
-               ft_buffer[ft_nr_buffers] = NULL;
-       }
-       TRACE_EXIT;
-}
-
-int ftape_set_nr_buffers(int cnt)
-{
-       int delta = cnt - ft_nr_buffers;
-       TRACE_FUN(ft_t_flow);
-
-       if (delta > 0) {
-               while (delta--) {
-                       if (add_one_buffer() < 0) {
-                               TRACE_EXIT -ENOMEM;
-                       }
-               }
-       } else if (delta < 0) {
-               while (delta++) {
-                       del_one_buffer();
-               }
-       }
-       ftape_zap_read_buffers();
-       TRACE_EXIT 0;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-buffer.h b/drivers/char/ftape/lowlevel/ftape-buffer.h
deleted file mode 100644 (file)
index eec99ce..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _FTAPE_BUFFER_H
-#define _FTAPE_BUFFER_H
-
-/*
- *      Copyright (C) 1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-buffer.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:08 $
- *
- *  This file contains the allocator/dealloctor for ftape's dynamic dma
- *  buffer.
- */
-
-extern int  ftape_set_nr_buffers(int cnt);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-calibr.c b/drivers/char/ftape/lowlevel/ftape-calibr.c
deleted file mode 100644 (file)
index 8e50bfd..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-calibr.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:08 $
- *
- *      GP calibration routine for processor speed dependent
- *      functions.
- */
-
-#include <linux/errno.h>
-#include <linux/jiffies.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#if defined(__alpha__)
-# include <asm/hwrpb.h>
-#elif defined(__x86_64__)
-# include <asm/msr.h>
-# include <asm/timex.h>
-#elif defined(__i386__)
-# include <linux/timex.h>
-#endif
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-calibr.h"
-#include "../lowlevel/fdc-io.h"
-
-#undef DEBUG
-
-#if !defined(__alpha__) && !defined(__i386__) && !defined(__x86_64__)
-# error Ftape is not implemented for this architecture!
-#endif
-
-#if defined(__alpha__) || defined(__x86_64__)
-static unsigned long ps_per_cycle = 0;
-#endif
-
-static spinlock_t calibr_lock;
-
-/*
- * Note: On Intel PCs, the clock ticks at 100 Hz (HZ==100) which is
- * too slow for certain timeouts (and that clock doesn't even tick
- * when interrupts are disabled).  For that reason, the 8254 timer is
- * used directly to implement fine-grained timeouts.  However, on
- * Alpha PCs, the 8254 is *not* used to implement the clock tick
- * (which is 1024 Hz, normally) and the 8254 timer runs at some
- * "random" frequency (it seems to run at 18Hz, but it's not safe to
- * rely on this value).  Instead, we use the Alpha's "rpcc"
- * instruction to read cycle counts.  As this is a 32 bit counter,
- * it will overflow only once per 30 seconds (on a 200MHz machine),
- * which is plenty.
- */
-
-unsigned int ftape_timestamp(void)
-{
-#if defined(__alpha__)
-       unsigned long r;
-
-       asm volatile ("rpcc %0" : "=r" (r));
-       return r;
-#elif defined(__x86_64__)
-       unsigned long r;
-       rdtscl(r);
-       return r;
-#elif defined(__i386__)
-
-/*
- * Note that there is some time between counter underflowing and jiffies
- * increasing, so the code below won't always give correct output.
- * -Vojtech
- */
-
-       unsigned long flags;
-       __u16 lo;
-       __u16 hi;
-
-       spin_lock_irqsave(&calibr_lock, flags);
-       outb_p(0x00, 0x43);     /* latch the count ASAP */
-       lo = inb_p(0x40);       /* read the latched count */
-       lo |= inb(0x40) << 8;
-       hi = jiffies;
-       spin_unlock_irqrestore(&calibr_lock, flags);
-       return ((hi + 1) * (unsigned int) LATCH) - lo;  /* downcounter ! */
-#endif
-}
-
-static unsigned int short_ftape_timestamp(void)
-{
-#if defined(__alpha__) || defined(__x86_64__)
-       return ftape_timestamp();
-#elif defined(__i386__)
-       unsigned int count;
-       unsigned long flags;
-       spin_lock_irqsave(&calibr_lock, flags);
-       outb_p(0x00, 0x43);     /* latch the count ASAP */
-       count = inb_p(0x40);    /* read the latched count */
-       count |= inb(0x40) << 8;
-       spin_unlock_irqrestore(&calibr_lock, flags);
-       return (LATCH - count); /* normal: downcounter */
-#endif
-}
-
-static unsigned int diff(unsigned int t0, unsigned int t1)
-{
-#if defined(__alpha__) || defined(__x86_64__)
-       return (t1 - t0);
-#elif defined(__i386__)
-       /*
-        * This is tricky: to work for both short and full ftape_timestamps
-        * we'll have to discriminate between these.
-        * If it _looks_ like short stamps with wrapping around we'll
-        * asume it are. This will generate a small error if it really
-        * was a (very large) delta from full ftape_timestamps.
-        */
-       return (t1 <= t0 && t0 <= LATCH) ? t1 + LATCH - t0 : t1 - t0;
-#endif
-}
-
-static unsigned int usecs(unsigned int count)
-{
-#if defined(__alpha__) || defined(__x86_64__)
-       return (ps_per_cycle * count) / 1000000UL;
-#elif defined(__i386__)
-       return (10000 * count) / ((CLOCK_TICK_RATE + 50) / 100);
-#endif
-}
-
-unsigned int ftape_timediff(unsigned int t0, unsigned int t1)
-{
-       /*
-        *  Calculate difference in usec for ftape_timestamp results t0 & t1.
-        *  Note that on the i386 platform with short time-stamps, the
-        *  maximum allowed timespan is 1/HZ or we'll lose ticks!
-        */
-       return usecs(diff(t0, t1));
-}
-
-/*      To get an indication of the I/O performance,
- *      measure the duration of the inb() function.
- */
-static void time_inb(void)
-{
-       int i;
-       int t0, t1;
-       unsigned long flags;
-       int status;
-       TRACE_FUN(ft_t_any);
-
-       spin_lock_irqsave(&calibr_lock, flags);
-       t0 = short_ftape_timestamp();
-       for (i = 0; i < 1000; ++i) {
-               status = inb(fdc.msr);
-       }
-       t1 = short_ftape_timestamp();
-       spin_unlock_irqrestore(&calibr_lock, flags);
-       TRACE(ft_t_info, "inb() duration: %d nsec", ftape_timediff(t0, t1));
-       TRACE_EXIT;
-}
-
-static void init_clock(void)
-{
-       TRACE_FUN(ft_t_any);
-
-#if defined(__x86_64__)
-       ps_per_cycle = 1000000000UL / cpu_khz;
-#elif defined(__alpha__)
-       extern struct hwrpb_struct *hwrpb;
-       ps_per_cycle = (1000*1000*1000*1000UL) / hwrpb->cycle_freq;
-#endif
-       TRACE_EXIT;
-}
-
-/*
- *      Input:  function taking int count as parameter.
- *              pointers to calculated calibration variables.
- */
-void ftape_calibrate(char *name,
-                   void (*fun) (unsigned int), 
-                   unsigned int *calibr_count, 
-                   unsigned int *calibr_time)
-{
-       static int first_time = 1;
-       int i;
-       unsigned int tc = 0;
-       unsigned int count;
-       unsigned int time;
-#if defined(__i386__)
-       unsigned int old_tc = 0;
-       unsigned int old_count = 1;
-       unsigned int old_time = 1;
-#endif
-       TRACE_FUN(ft_t_flow);
-
-       if (first_time) {             /* get idea of I/O performance */
-               init_clock();
-               time_inb();
-               first_time = 0;
-       }
-       /*    value of timeout must be set so that on very slow systems
-        *    it will give a time less than one jiffy, and on
-        *    very fast systems it'll give reasonable precision.
-        */
-
-       count = 40;
-       for (i = 0; i < 15; ++i) {
-               unsigned int t0;
-               unsigned int t1;
-               unsigned int once;
-               unsigned int multiple;
-               unsigned long flags;
-
-               *calibr_count =
-               *calibr_time = count;   /* set TC to 1 */
-               spin_lock_irqsave(&calibr_lock, flags);
-               fun(0);         /* dummy, get code into cache */
-               t0 = short_ftape_timestamp();
-               fun(0);         /* overhead + one test */
-               t1 = short_ftape_timestamp();
-               once = diff(t0, t1);
-               t0 = short_ftape_timestamp();
-               fun(count);             /* overhead + count tests */
-               t1 = short_ftape_timestamp();
-               multiple = diff(t0, t1);
-               spin_unlock_irqrestore(&calibr_lock, flags);
-               time = ftape_timediff(0, multiple - once);
-               tc = (1000 * time) / (count - 1);
-               TRACE(ft_t_any, "once:%3d us,%6d times:%6d us, TC:%5d ns",
-                       usecs(once), count - 1, usecs(multiple), tc);
-#if defined(__alpha__) || defined(__x86_64__)
-               /*
-                * Increase the calibration count exponentially until the
-                * calibration time exceeds 100 ms.
-                */
-               if (time >= 100*1000) {
-                       break;
-               }
-#elif defined(__i386__)
-               /*
-                * increase the count until the resulting time nears 2/HZ,
-                * then the tc will drop sharply because we lose LATCH counts.
-                */
-               if (tc <= old_tc / 2) {
-                       time = old_time;
-                       count = old_count;
-                       break;
-               }
-               old_tc = tc;
-               old_count = count;
-               old_time = time;
-#endif
-               count *= 2;
-       }
-       *calibr_count = count - 1;
-       *calibr_time  = time;
-       TRACE(ft_t_info, "TC for `%s()' = %d nsec (at %d counts)",
-            name, (1000 * *calibr_time) / *calibr_count, *calibr_count);
-       TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-calibr.h b/drivers/char/ftape/lowlevel/ftape-calibr.h
deleted file mode 100644 (file)
index 0c7e752..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _FTAPE_CALIBR_H
-#define _FTAPE_CALIBR_H
-
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-calibr.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/09/19 09:05:26 $
- *
- *      This file contains a gp calibration routine for
- *      hardware dependent timeout functions.
- */
-
-extern void ftape_calibrate(char *name,
-                           void (*fun) (unsigned int),
-                           unsigned int *calibr_count,
-                           unsigned int *calibr_time);
-extern unsigned int ftape_timestamp(void);
-extern unsigned int ftape_timediff(unsigned int t0, unsigned int t1);
-
-#endif /* _FTAPE_CALIBR_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-ctl.c b/drivers/char/ftape/lowlevel/ftape-ctl.c
deleted file mode 100644 (file)
index 5d7c1ce..0000000
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven,
- *                    1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.c,v $
- * $Revision: 1.4 $
- * $Date: 1997/11/11 14:37:44 $
- *
- *      This file contains the non-read/write ftape functions for the
- *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-/* ease porting between pre-2.4.x and later kernels */
-#define vma_get_pgoff(v)      ((v)->vm_pgoff)
-
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/*      Global vars.
- */
-ftape_info ftape_status = {
-/*  vendor information */
-       { 0, },     /* drive type */
-/*  data rates */
-       500,        /* used data rate */
-       500,        /* drive max rate */
-       500,        /* fdc max rate   */
-/*  drive selection, either FTAPE_SEL_A/B/C/D */
-       -1,     /* drive selection */
-/*  flags set after decode the drive and tape status   */
-       0,          /* formatted */
-       1,          /* no tape */
-       1,          /* write protected */
-       1,          /* new tape */
-/*  values of last queried drive/tape status and error */
-       {{0,}},     /* last error code */
-       {{0,}},     /* drive status, configuration, tape status */
-/*  cartridge geometry */
-        20,         /* tracks_per_tape */
-        102,        /* segments_per_track */
-/*  location of header segments, etc. */
-       -1,     /* used_header_segment */
-       -1,     /* header_segment_1 */
-       -1,     /* header_segment_2 */
-       -1,     /* first_data_segment */
-        -1,     /* last_data_segment */
-/*  the format code as stored in the header segment  */
-       fmt_normal, /* format code */
-/*  the default for the qic std: unknown */
-       -1,
-/*  is tape running? */
-       idle,       /* runner_state */
-/*  is tape reading/writing/verifying/formatting/deleting */
-       idle,       /* driver state */
-/*  flags fatal hardware error */
-       1,          /* failure */
-/*  history record */
-       { 0, }      /* history record */
-};
-       
-int ftape_segments_per_head     = 1020;
-int ftape_segments_per_cylinder = 4;
-int ftape_init_drive_needed = 1; /* need to be global for ftape_reset_drive()
-                                 * in ftape-io.c
-                                 */
-
-/*      Local vars.
- */
-static const vendor_struct vendors[] = QIC117_VENDORS;
-static const wakeup_method methods[] = WAKEUP_METHODS;
-
-const ftape_info *ftape_get_status(void)
-{
-#if defined(STATUS_PARANOYA)
-       static ftape_info get_status;
-
-       get_status = ftape_status;
-       return &get_status;
-#else
-       return &ftape_status; /*  maybe return only a copy of it to assure 
-                              *  read only access
-                              */
-#endif
-}
-
-static int ftape_not_operational(int status)
-{
-       /* return true if status indicates tape can not be used.
-        */
-       return ((status ^ QIC_STATUS_CARTRIDGE_PRESENT) &
-               (QIC_STATUS_ERROR |
-                QIC_STATUS_CARTRIDGE_PRESENT |
-                QIC_STATUS_NEW_CARTRIDGE));
-}
-
-int ftape_seek_to_eot(void)
-{
-       int status;
-       TRACE_FUN(ft_t_any);
-
-       TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
-       while ((status & QIC_STATUS_AT_EOT) == 0) {
-               if (ftape_not_operational(status)) {
-                       TRACE_EXIT -EIO;
-               }
-               TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD,
-                                              ftape_timeout.rewind,&status),);
-       }
-       TRACE_EXIT 0;
-}
-
-int ftape_seek_to_bot(void)
-{
-       int status;
-       TRACE_FUN(ft_t_any);
-
-       TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
-       while ((status & QIC_STATUS_AT_BOT) == 0) {
-               if (ftape_not_operational(status)) {
-                       TRACE_EXIT -EIO;
-               }
-               TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE,
-                                              ftape_timeout.rewind,&status),);
-       }
-       TRACE_EXIT 0;
-}
-
-static int ftape_new_cartridge(void)
-{
-       ft_location.track = -1; /* force seek on first access */
-       ftape_zap_read_buffers();
-       ftape_zap_write_buffers();
-       return 0;
-}
-
-int ftape_abort_operation(void)
-{
-       int result = 0;
-       int status;
-       TRACE_FUN(ft_t_flow);
-
-       if (ft_runner_status == running) {
-               TRACE(ft_t_noise, "aborting runner, waiting");
-               
-               ft_runner_status = do_abort;
-               /* set timeout so that the tape will run to logical EOT
-                * if we missed the last sector and there are no queue pulses.
-                */
-               result = ftape_dumb_stop();
-       }
-       if (ft_runner_status != idle) {
-               if (ft_runner_status == do_abort) {
-                       TRACE(ft_t_noise, "forcing runner abort");
-               }
-               TRACE(ft_t_noise, "stopping tape");
-               result = ftape_stop_tape(&status);
-               ft_location.known = 0;
-               ft_runner_status  = idle;
-       }
-       ftape_reset_buffer();
-       ftape_zap_read_buffers();
-       ftape_set_state(idle);
-       TRACE_EXIT result;
-}
-
-static int lookup_vendor_id(unsigned int vendor_id)
-{
-       int i = 0;
-
-       while (vendors[i].vendor_id != vendor_id) {
-               if (++i >= NR_ITEMS(vendors)) {
-                       return -1;
-               }
-       }
-       return i;
-}
-
-static void ftape_detach_drive(void)
-{
-       TRACE_FUN(ft_t_any);
-
-       TRACE(ft_t_flow, "disabling tape drive and fdc");
-       ftape_put_drive_to_sleep(ft_drive_type.wake_up);
-       fdc_catch_stray_interrupts(1);  /* one always comes */
-       fdc_disable();
-       fdc_release_irq_and_dma();
-       fdc_release_regions();
-       TRACE_EXIT;
-}
-
-static void clear_history(void)
-{
-       ft_history.used = 0;
-       ft_history.id_am_errors =
-               ft_history.id_crc_errors =
-               ft_history.data_am_errors =
-               ft_history.data_crc_errors =
-               ft_history.overrun_errors =
-               ft_history.no_data_errors =
-               ft_history.retries =
-               ft_history.crc_errors =
-               ft_history.crc_failures =
-               ft_history.ecc_failures =
-               ft_history.corrected =
-               ft_history.defects =
-               ft_history.rewinds = 0;
-}
-
-static int ftape_activate_drive(vendor_struct * drive_type)
-{
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-
-       /* If we already know the drive type, wake it up.
-        * Else try to find out what kind of drive is attached.
-        */
-       if (drive_type->wake_up != unknown_wake_up) {
-               TRACE(ft_t_flow, "enabling tape drive and fdc");
-               result = ftape_wakeup_drive(drive_type->wake_up);
-               if (result < 0) {
-                       TRACE(ft_t_err, "known wakeup method failed");
-               }
-       } else {
-               wake_up_types method;
-               const ft_trace_t old_tracing = TRACE_LEVEL;
-               if (TRACE_LEVEL < ft_t_flow) {
-                       SET_TRACE_LEVEL(ft_t_bug);
-               }
-
-               /*  Try to awaken the drive using all known methods.
-                *  Lower tracing for a while.
-                */
-               for (method=no_wake_up; method < NR_ITEMS(methods); ++method) {
-                       drive_type->wake_up = method;
-#ifdef CONFIG_FT_TWO_DRIVES
-                       /*  Test setup for dual drive configuration.
-                        *  /dev/rft2 uses mountain wakeup
-                        *  /dev/rft3 uses colorado wakeup
-                        *  Other systems will use the normal scheme.
-                        */
-                       if ((ft_drive_sel < 2)                            ||
-                           (ft_drive_sel == 2 && method == FT_WAKE_UP_1) ||
-                           (ft_drive_sel == 3 && method == FT_WAKE_UP_2)) {
-                               result=ftape_wakeup_drive(drive_type->wake_up);
-                       } else {
-                               result = -EIO;
-                       }
-#else
-                       result = ftape_wakeup_drive(drive_type->wake_up);
-#endif
-                       if (result >= 0) {
-                               TRACE(ft_t_warn, "drive wakeup method: %s",
-                                     methods[drive_type->wake_up].name);
-                               break;
-                       }
-               }
-               SET_TRACE_LEVEL(old_tracing);
-
-               if (method >= NR_ITEMS(methods)) {
-                       /* no response at all, cannot open this drive */
-                       drive_type->wake_up = unknown_wake_up;
-                       TRACE(ft_t_err, "no tape drive found !");
-                       result = -ENODEV;
-               }
-       }
-       TRACE_EXIT result;
-}
-
-static int ftape_get_drive_status(void)
-{
-       int result;
-       int status;
-       TRACE_FUN(ft_t_flow);
-
-       ft_no_tape = ft_write_protected = 0;
-       /*    Tape drive is activated now.
-        *    First clear error status if present.
-        */
-       do {
-               result = ftape_ready_wait(ftape_timeout.reset, &status);
-               if (result < 0) {
-                       if (result == -ETIME) {
-                               TRACE(ft_t_err, "ftape_ready_wait timeout");
-                       } else if (result == -EINTR) {
-                               TRACE(ft_t_err, "ftape_ready_wait aborted");
-                       } else {
-                               TRACE(ft_t_err, "ftape_ready_wait failed");
-                       }
-                       TRACE_EXIT -EIO;
-               }
-               /*  Clear error condition (drive is ready !)
-                */
-               if (status & QIC_STATUS_ERROR) {
-                       unsigned int error;
-                       qic117_cmd_t command;
-
-                       TRACE(ft_t_err, "error status set");
-                       result = ftape_report_error(&error, &command, 1);
-                       if (result < 0) {
-                               TRACE(ft_t_err,
-                                     "report_error_code failed: %d", result);
-                               /* hope it's working next time */
-                               ftape_reset_drive();
-                               TRACE_EXIT -EIO;
-                       } else if (error != 0) {
-                               TRACE(ft_t_noise, "error code   : %d", error);
-                               TRACE(ft_t_noise, "error command: %d", command);
-                       }
-               }
-               if (status & QIC_STATUS_NEW_CARTRIDGE) {
-                       unsigned int error;
-                       qic117_cmd_t command;
-                       const ft_trace_t old_tracing = TRACE_LEVEL;
-                       SET_TRACE_LEVEL(ft_t_bug);
-
-                       /*  Undocumented feature: Must clear (not present!)
-                        *  error here or we'll fail later.
-                        */
-                       ftape_report_error(&error, &command, 1);
-
-                       SET_TRACE_LEVEL(old_tracing);
-                       TRACE(ft_t_info, "status: new cartridge");
-                       ft_new_tape = 1;
-               } else {
-                       ft_new_tape = 0;
-               }
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-       } while (status & QIC_STATUS_ERROR);
-       
-       ft_no_tape = !(status & QIC_STATUS_CARTRIDGE_PRESENT);
-       ft_write_protected = (status & QIC_STATUS_WRITE_PROTECT) != 0;
-       if (ft_no_tape) {
-               TRACE(ft_t_warn, "no cartridge present");
-       } else {
-               if (ft_write_protected) {
-                       TRACE(ft_t_noise, "Write protected cartridge");
-               }
-       }
-       TRACE_EXIT 0;
-}
-
-static void ftape_log_vendor_id(void)
-{
-       int vendor_index;
-       TRACE_FUN(ft_t_flow);
-
-       ftape_report_vendor_id(&ft_drive_type.vendor_id);
-       vendor_index = lookup_vendor_id(ft_drive_type.vendor_id);
-       if (ft_drive_type.vendor_id == UNKNOWN_VENDOR &&
-           ft_drive_type.wake_up == wake_up_colorado) {
-               vendor_index = 0;
-               /* hack to get rid of all this mail */
-               ft_drive_type.vendor_id = 0;
-       }
-       if (vendor_index < 0) {
-               /* Unknown vendor id, first time opening device.  The
-                * drive_type remains set to type found at wakeup
-                * time, this will probably keep the driver operating
-                * for this new vendor.  
-                */
-               TRACE(ft_t_warn, "\n"
-                     KERN_INFO "============ unknown vendor id ===========\n"
-                     KERN_INFO "A new, yet unsupported tape drive is found\n"
-                     KERN_INFO "Please report the following values:\n"
-                     KERN_INFO "   Vendor id     : 0x%04x\n"
-                     KERN_INFO "   Wakeup method : %s\n"
-                     KERN_INFO "And a description of your tape drive\n"
-                     KERN_INFO "to "THE_FTAPE_MAINTAINER"\n"
-                     KERN_INFO "==========================================",
-                     ft_drive_type.vendor_id,
-                     methods[ft_drive_type.wake_up].name);
-               ft_drive_type.speed = 0;                /* unknown */
-       } else {
-               ft_drive_type.name  = vendors[vendor_index].name;
-               ft_drive_type.speed = vendors[vendor_index].speed;
-               TRACE(ft_t_info, "tape drive type: %s", ft_drive_type.name);
-               /* scan all methods for this vendor_id in table */
-               while(ft_drive_type.wake_up != vendors[vendor_index].wake_up) {
-                       if (vendor_index < NR_ITEMS(vendors) - 1 &&
-                           vendors[vendor_index + 1].vendor_id 
-                           == 
-                           ft_drive_type.vendor_id) {
-                               ++vendor_index;
-                       } else {
-                               break;
-                       }
-               }
-               if (ft_drive_type.wake_up != vendors[vendor_index].wake_up) {
-                       TRACE(ft_t_warn, "\n"
-                    KERN_INFO "==========================================\n"
-                    KERN_INFO "wakeup type mismatch:\n"
-                    KERN_INFO "found: %s, expected: %s\n"
-                    KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n"
-                    KERN_INFO "==========================================",
-                             methods[ft_drive_type.wake_up].name,
-                             methods[vendors[vendor_index].wake_up].name);
-               }
-       }
-       TRACE_EXIT;
-}
-
-void ftape_calc_timeouts(unsigned int qic_std,
-                        unsigned int data_rate,
-                        unsigned int tape_len)
-{
-       int speed;              /* deci-ips ! */
-       int ff_speed;
-       int length;
-       TRACE_FUN(ft_t_any);
-
-       /*                           tape transport speed
-        *  data rate:        QIC-40   QIC-80   QIC-3010 QIC-3020
-        *
-        *    250 Kbps        25 ips     n/a      n/a      n/a
-        *    500 Kbps        50 ips   34 ips   22.6 ips   n/a
-        *      1 Mbps          n/a    68 ips   45.2 ips 22.6 ips
-        *      2 Mbps          n/a      n/a      n/a    45.2 ips
-        *
-        *  fast tape transport speed is at least 68 ips.
-        */
-       switch (qic_std) {
-       case QIC_TAPE_QIC40:
-               speed = (data_rate == 250) ? 250 : 500;
-               break;
-       case QIC_TAPE_QIC80:
-               speed = (data_rate == 500) ? 340 : 680;
-               break;
-       case QIC_TAPE_QIC3010:
-               speed = (data_rate == 500) ? 226 : 452;
-               break;
-       case QIC_TAPE_QIC3020:
-               speed = (data_rate == 1000) ? 226 : 452;
-               break;
-       default:
-               TRACE(ft_t_bug, "Unknown qic_std (bug) ?");
-               speed = 500;
-               break;
-       }
-       if (ft_drive_type.speed == 0) {
-               unsigned long t0;
-               static int dt = 0;     /* keep gcc from complaining */
-               static int first_time = 1;
-
-               /*  Measure the time it takes to wind to EOT and back to BOT.
-                *  If the tape length is known, calculate the rewind speed.
-                *  Else keep the time value for calculation of the rewind
-                *  speed later on, when the length _is_ known.
-                *  Ask for a report only when length and speed are both known.
-                */
-               if (first_time) {
-                       ftape_seek_to_bot();
-                       t0 = jiffies;
-                       ftape_seek_to_eot();
-                       ftape_seek_to_bot();
-                       dt = (int) (((jiffies - t0) * FT_USPT) / 1000);
-                       if (dt < 1) {
-                               dt = 1; /* prevent div by zero on failures */
-                       }
-                       first_time = 0;
-                       TRACE(ft_t_info,
-                             "trying to determine seek timeout, got %d msec",
-                             dt);
-               }
-               if (tape_len != 0) {
-                       ft_drive_type.speed = 
-                               (2 * 12 * tape_len * 1000) / dt;
-                       TRACE(ft_t_warn, "\n"
-                    KERN_INFO "==========================================\n"
-                    KERN_INFO "drive type: %s\n"
-                    KERN_INFO "delta time = %d ms, length = %d ft\n"
-                    KERN_INFO "has a maximum tape speed of %d ips\n"
-                    KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n"
-                    KERN_INFO "==========================================",
-                             ft_drive_type.name, dt, tape_len, 
-                             ft_drive_type.speed);
-               }
-       }
-       /*  Handle unknown length tapes as very long ones. We'll
-        *  determine the actual length from a header segment later.
-        *  This is normal for all modern (Wide,TR1/2/3) formats.
-        */
-       if (tape_len <= 0) {
-               TRACE(ft_t_noise,
-                     "Unknown tape length, using maximal timeouts");
-               length = QIC_TOP_TAPE_LEN;      /* use worst case values */
-       } else {
-               length = tape_len;              /* use actual values */
-       }
-       if (ft_drive_type.speed == 0) {
-               ff_speed = speed; 
-       } else {
-               ff_speed = ft_drive_type.speed;
-       }
-       /*  time to go from bot to eot at normal speed (data rate):
-        *  time = (1+delta) * length (ft) * 12 (inch/ft) / speed (ips)
-        *  delta = 10 % for seek speed, 20 % for rewind speed.
-        */
-       ftape_timeout.seek = (length * 132 * FT_SECOND) / speed;
-       ftape_timeout.rewind = (length * 144 * FT_SECOND) / (10 * ff_speed);
-       ftape_timeout.reset = 20 * FT_SECOND + ftape_timeout.rewind;
-       TRACE(ft_t_noise, "timeouts for speed = %d, length = %d\n"
-             KERN_INFO "seek timeout  : %d sec\n"
-             KERN_INFO "rewind timeout: %d sec\n"
-             KERN_INFO "reset timeout : %d sec",
-             speed, length,
-             (ftape_timeout.seek + 500) / 1000,
-             (ftape_timeout.rewind + 500) / 1000,
-             (ftape_timeout.reset + 500) / 1000);
-       TRACE_EXIT;
-}
-
-/* This function calibrates the datarate (i.e. determines the maximal
- * usable data rate) and sets the global variable ft_qic_std to qic_std
- *
- */
-int ftape_calibrate_data_rate(unsigned int qic_std)
-{
-       int rate = ft_fdc_rate_limit;
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       ft_qic_std = qic_std;
-
-       if (ft_qic_std == -1) {
-               TRACE_ABORT(-EIO, ft_t_err,
-               "Unable to determine data rate if QIC standard is unknown");
-       }
-
-       /*  Select highest rate supported by both fdc and drive.
-        *  Start with highest rate supported by the fdc.
-        */
-       while (fdc_set_data_rate(rate) < 0 && rate > 250) {
-               rate /= 2;
-       }
-       TRACE(ft_t_info,
-             "Highest FDC supported data rate: %d Kbps", rate);
-       ft_fdc_max_rate = rate;
-       do {
-               result = ftape_set_data_rate(rate, ft_qic_std);
-       } while (result == -EINVAL && (rate /= 2) > 250);
-       if (result < 0) {
-               TRACE_ABORT(-EIO, ft_t_err, "set datarate failed");
-       }
-       ft_data_rate = rate;
-       TRACE_EXIT 0;
-}
-
-static int ftape_init_drive(void)
-{
-       int status;
-       qic_model model;
-       unsigned int qic_std;
-       unsigned int data_rate;
-       TRACE_FUN(ft_t_flow);
-
-       ftape_init_drive_needed = 0; /* don't retry if this fails ? */
-       TRACE_CATCH(ftape_report_raw_drive_status(&status),);
-       if (status & QIC_STATUS_CARTRIDGE_PRESENT) {
-               if (!(status & QIC_STATUS_AT_BOT)) {
-                       /*  Antique drives will get here after a soft reset,
-                        *  modern ones only if the driver is loaded when the
-                        *  tape wasn't rewound properly.
-                        */
-                       /* Tape should be at bot if new cartridge ! */
-                       ftape_seek_to_bot();
-               }
-               if (!(status & QIC_STATUS_REFERENCED)) {
-                       TRACE(ft_t_flow, "starting seek_load_point");
-                       TRACE_CATCH(ftape_command_wait(QIC_SEEK_LOAD_POINT,
-                                                      ftape_timeout.reset,
-                                                      &status),);
-               }
-       }
-       ft_formatted = (status & QIC_STATUS_REFERENCED) != 0;
-       if (!ft_formatted) {
-               TRACE(ft_t_warn, "Warning: tape is not formatted !");
-       }
-
-       /*  report configuration aborts when ftape_tape_len == -1
-        *  unknown qic_std is okay if not formatted.
-        */
-       TRACE_CATCH(ftape_report_configuration(&model,
-                                              &data_rate,
-                                              &qic_std,
-                                              &ftape_tape_len),);
-
-       /*  Maybe add the following to the /proc entry
-        */
-       TRACE(ft_t_info, "%s drive @ %d Kbps",
-             (model == prehistoric) ? "prehistoric" :
-             ((model == pre_qic117c) ? "pre QIC-117C" :
-              ((model == post_qic117b) ? "post QIC-117B" :
-               "post QIC-117D")), data_rate);
-
-       if (ft_formatted) {
-               /*  initialize ft_used_data_rate to maximum value 
-                *  and set ft_qic_std
-                */
-               TRACE_CATCH(ftape_calibrate_data_rate(qic_std),);
-               if (ftape_tape_len == 0) {
-                       TRACE(ft_t_info, "unknown length QIC-%s tape",
-                             (ft_qic_std == QIC_TAPE_QIC40) ? "40" :
-                             ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
-                              ((ft_qic_std == QIC_TAPE_QIC3010) 
-                               ? "3010" : "3020")));
-               } else {
-                       TRACE(ft_t_info, "%d ft. QIC-%s tape", ftape_tape_len,
-                             (ft_qic_std == QIC_TAPE_QIC40) ? "40" :
-                             ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
-                              ((ft_qic_std == QIC_TAPE_QIC3010)
-                               ? "3010" : "3020")));
-               }
-               ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
-               /* soft write-protect QIC-40/QIC-80 cartridges used with a
-                * Colorado T3000 drive. Buggy hardware!
-                */
-               if ((ft_drive_type.vendor_id == 0x011c6) &&
-                   ((ft_qic_std == QIC_TAPE_QIC40 ||
-                     ft_qic_std == QIC_TAPE_QIC80) &&
-                    !ft_write_protected)) {
-                       TRACE(ft_t_warn, "\n"
-       KERN_INFO "The famous Colorado T3000 bug:\n"
-       KERN_INFO "%s drives can't write QIC40 and QIC80\n"
-       KERN_INFO "cartridges but don't set the write-protect flag!",
-                             ft_drive_type.name);
-                       ft_write_protected = 1;
-               }
-       } else {
-               /*  Doesn't make too much sense to set the data rate
-                *  because we don't know what to use for the write
-                *  precompensation.
-                *  Need to do this again when formatting the cartridge.
-                */
-               ft_data_rate = data_rate;
-               ftape_calc_timeouts(QIC_TAPE_QIC40,
-                                   data_rate,
-                                   ftape_tape_len);
-       }
-       ftape_new_cartridge();
-       TRACE_EXIT 0;
-}
-
-static void ftape_munmap(void)
-{
-       int i;
-       TRACE_FUN(ft_t_flow);
-       
-       for (i = 0; i < ft_nr_buffers; i++) {
-               ft_buffer[i]->mmapped = 0;
-       }
-       TRACE_EXIT;
-}
-
-/*   Map the dma buffers into the virtual address range given by vma.
- *   We only check the caller doesn't map non-existent buffers. We
- *   don't check for multiple mappings.
- */
-int ftape_mmap(struct vm_area_struct *vma)
-{
-       int num_buffers;
-       int i;
-       TRACE_FUN(ft_t_flow);
-       
-       if (ft_failure) {
-               TRACE_EXIT -ENODEV;
-       }
-       if (!(vma->vm_flags & (VM_READ|VM_WRITE))) {
-               TRACE_ABORT(-EINVAL, ft_t_err, "Undefined mmap() access");
-       }
-       if (vma_get_pgoff(vma) != 0) {
-               TRACE_ABORT(-EINVAL, ft_t_err, "page offset must be 0");
-       }
-       if ((vma->vm_end - vma->vm_start) % FT_BUFF_SIZE != 0) {
-               TRACE_ABORT(-EINVAL, ft_t_err,
-                           "size = %ld, should be a multiple of %d",
-                           vma->vm_end - vma->vm_start,
-                           FT_BUFF_SIZE);
-       }
-       num_buffers = (vma->vm_end - vma->vm_start) / FT_BUFF_SIZE;
-       if (num_buffers > ft_nr_buffers) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_err, "size = %ld, should be less than %d",
-                           vma->vm_end - vma->vm_start,
-                           ft_nr_buffers * FT_BUFF_SIZE);
-       }
-       if (ft_driver_state != idle) {
-               /* this also clears the buffer states 
-                */
-               ftape_abort_operation();
-       } else {
-               ftape_reset_buffer();
-       }
-       for (i = 0; i < num_buffers; i++) {
-               unsigned long pfn;
-
-               pfn = virt_to_phys(ft_buffer[i]->address) >> PAGE_SHIFT;
-               TRACE_CATCH(remap_pfn_range(vma, vma->vm_start +
-                                            i * FT_BUFF_SIZE,
-                                            pfn,
-                                            FT_BUFF_SIZE,
-                                            vma->vm_page_prot),
-                           _res = -EAGAIN);
-               TRACE(ft_t_noise, "remapped dma buffer @ %p to location @ %p",
-                     ft_buffer[i]->address,
-                     (void *)(vma->vm_start + i * FT_BUFF_SIZE));
-       }
-       for (i = 0; i < num_buffers; i++) {
-               memset(ft_buffer[i]->address, 0xAA, FT_BUFF_SIZE);
-               ft_buffer[i]->mmapped++;
-       }       
-       TRACE_EXIT 0;
-}
-
-static void ftape_init_driver(void); /* forward declaration */
-
-/*      OPEN routine called by kernel-interface code
- */
-int ftape_enable(int drive_selection)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (ft_drive_sel == -1 || ft_drive_sel != drive_selection) {
-               /* Other selection than last time
-                */
-               ftape_init_driver();
-       }
-       ft_drive_sel = FTAPE_SEL(drive_selection);
-       ft_failure = 0;
-       TRACE_CATCH(fdc_init(),); /* init & detect fdc */
-       TRACE_CATCH(ftape_activate_drive(&ft_drive_type),
-                   fdc_disable();
-                   fdc_release_irq_and_dma();
-                   fdc_release_regions());
-       TRACE_CATCH(ftape_get_drive_status(), ftape_detach_drive());
-       if (ft_drive_type.vendor_id == UNKNOWN_VENDOR) {
-               ftape_log_vendor_id();
-       }
-       if (ft_new_tape) {
-               ftape_init_drive_needed = 1;
-       }
-       if (!ft_no_tape && ftape_init_drive_needed) {
-               TRACE_CATCH(ftape_init_drive(), ftape_detach_drive());
-       }
-       ftape_munmap(); /* clear the mmap flag */
-       clear_history();
-       TRACE_EXIT 0;
-}
-
-/*   release routine called by the high level interface modules
- *   zftape or sftape.
- */
-void ftape_disable(void)
-{
-       int i;
-       TRACE_FUN(ft_t_any);
-
-       for (i = 0; i < ft_nr_buffers; i++) {
-               if (ft_buffer[i]->mmapped) {
-                       TRACE(ft_t_noise, "first byte of buffer %d: 0x%02x",
-                             i, *ft_buffer[i]->address);
-               }
-       }
-       if (sigtestsetmask(&current->pending.signal, _DONT_BLOCK) && 
-           !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)) &&
-           ftape_tape_running) {
-               TRACE(ft_t_warn,
-                     "Interrupted by fatal signal and tape still running");
-               ftape_dumb_stop();
-               ftape_abort_operation(); /* it's annoying */
-       } else {
-               ftape_set_state(idle);
-       }
-       ftape_detach_drive();
-       if (ft_history.used) {
-               TRACE(ft_t_info, "== Non-fatal errors this run: ==");
-               TRACE(ft_t_info, "fdc isr statistics:\n"
-                     KERN_INFO " id_am_errors     : %3d\n"
-                     KERN_INFO " id_crc_errors    : %3d\n"
-                     KERN_INFO " data_am_errors   : %3d\n"
-                     KERN_INFO " data_crc_errors  : %3d\n"
-                     KERN_INFO " overrun_errors   : %3d\n"
-                     KERN_INFO " no_data_errors   : %3d\n"
-                     KERN_INFO " retries          : %3d",
-                     ft_history.id_am_errors,   ft_history.id_crc_errors,
-                     ft_history.data_am_errors, ft_history.data_crc_errors,
-                     ft_history.overrun_errors, ft_history.no_data_errors,
-                     ft_history.retries);
-               if (ft_history.used & 1) {
-                       TRACE(ft_t_info, "ecc statistics:\n"
-                             KERN_INFO " crc_errors       : %3d\n"
-                             KERN_INFO " crc_failures     : %3d\n"
-                             KERN_INFO " ecc_failures     : %3d\n"
-                             KERN_INFO " sectors corrected: %3d",
-                             ft_history.crc_errors,   ft_history.crc_failures,
-                             ft_history.ecc_failures, ft_history.corrected);
-               }
-               if (ft_history.defects > 0) {
-                       TRACE(ft_t_warn, "Warning: %d media defects!",
-                             ft_history.defects);
-               }
-               if (ft_history.rewinds > 0) {
-                       TRACE(ft_t_info, "tape motion statistics:\n"
-                             KERN_INFO "repositions       : %3d",
-                             ft_history.rewinds);
-               }
-       }
-       ft_failure = 1;
-       TRACE_EXIT;
-}
-
-static void ftape_init_driver(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       ft_drive_type.vendor_id = UNKNOWN_VENDOR;
-       ft_drive_type.speed     = 0;
-       ft_drive_type.wake_up   = unknown_wake_up;
-       ft_drive_type.name      = "Unknown";
-
-       ftape_timeout.seek      = 650 * FT_SECOND;
-       ftape_timeout.reset     = 670 * FT_SECOND;
-       ftape_timeout.rewind    = 650 * FT_SECOND;
-       ftape_timeout.head_seek =  15 * FT_SECOND;
-       ftape_timeout.stop      =   5 * FT_SECOND;
-       ftape_timeout.pause     =  16 * FT_SECOND;
-
-       ft_qic_std             = -1;
-       ftape_tape_len         = 0;  /* unknown */
-       ftape_current_command  = 0;
-       ftape_current_cylinder = -1;
-
-       ft_segments_per_track       = 102;
-       ftape_segments_per_head     = 1020;
-       ftape_segments_per_cylinder = 4;
-       ft_tracks_per_tape          = 20;
-
-       ft_failure = 1;
-
-       ft_formatted       = 0;
-       ft_no_tape         = 1;
-       ft_write_protected = 1;
-       ft_new_tape        = 1;
-
-       ft_driver_state = idle;
-
-       ft_data_rate = 
-               ft_fdc_max_rate   = 500;
-       ft_drive_max_rate = 0; /* triggers set_rate_test() */
-
-       ftape_init_drive_needed = 1;
-
-       ft_header_segment_1    = -1;
-       ft_header_segment_2    = -1;
-       ft_used_header_segment = -1;
-       ft_first_data_segment  = -1;
-       ft_last_data_segment   = -1;
-
-       ft_location.track = -1;
-       ft_location.known = 0;
-
-       ftape_tape_running = 0;
-       ftape_might_be_off_track = 1;
-
-       ftape_new_cartridge();  /* init some tape related variables */
-       ftape_init_bsm();
-       TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-ctl.h b/drivers/char/ftape/lowlevel/ftape-ctl.h
deleted file mode 100644 (file)
index 5f5e30b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef _FTAPE_CTL_H
-#define _FTAPE_CTL_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:09 $
- *
- *      This file contains the non-standard IOCTL related definitions
- *      for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
- *      Linux.
- */
-
-#include <linux/ioctl.h>
-#include <linux/mtio.h>
-#include <linux/ftape-vendors.h>
-
-#include "../lowlevel/ftape-rw.h"
-#include <linux/ftape-header-segment.h>
-
-typedef struct {
-       int used;               /* any reading or writing done */
-       /* isr statistics */
-       unsigned int id_am_errors;      /* id address mark not found */
-       unsigned int id_crc_errors;     /* crc error in id address mark */
-       unsigned int data_am_errors;    /* data address mark not found */
-       unsigned int data_crc_errors;   /* crc error in data field */
-       unsigned int overrun_errors;    /* fdc access timing problem */
-       unsigned int no_data_errors;    /* sector not found */
-       unsigned int retries;   /* number of tape retries */
-       /* ecc statistics */
-       unsigned int crc_errors;        /* crc error in data */
-       unsigned int crc_failures;      /* bad data without crc error */
-       unsigned int ecc_failures;      /* failed to correct */
-       unsigned int corrected; /* total sectors corrected */
-       /* general statistics */
-       unsigned int rewinds;   /* number of tape rewinds */
-       unsigned int defects;   /* bad sectors due to media defects */
-} history_record;
-
-/* this structure contains * ALL * information that we want
- * our child modules to know about, but don't want them to
- * modify. 
- */
-typedef struct {
-       /*  vendor information */
-       vendor_struct fti_drive_type;
-       /*  data rates */
-       unsigned int fti_used_data_rate;
-       unsigned int fti_drive_max_rate;
-       unsigned int fti_fdc_max_rate;
-       /*  drive selection, either FTAPE_SEL_A/B/C/D */
-       int fti_drive_sel;      
-       /*  flags set after decode the drive and tape status   */
-       unsigned int fti_formatted      :1;
-       unsigned int fti_no_tape        :1;
-       unsigned int fti_write_protected:1;
-       unsigned int fti_new_tape       :1;
-       /*  values of last queried drive/tape status and error */
-       ft_drive_error  fti_last_error;
-       ft_drive_status fti_last_status;
-       /*  cartridge geometry */
-       unsigned int fti_tracks_per_tape;
-       unsigned int fti_segments_per_track;
-       /*  location of header segments, etc. */
-       int fti_used_header_segment;
-       int fti_header_segment_1;
-       int fti_header_segment_2;
-       int fti_first_data_segment;
-       int fti_last_data_segment;
-       /*  the format code as stored in the header segment  */
-       ft_format_type  fti_format_code;
-       /*  the following is the sole reason for the ftape_set_status() call */
-       unsigned int fti_qic_std;
-       /*  is tape running? */
-       volatile enum runner_status_enum fti_runner_status;
-       /*  is tape reading/writing/verifying/formatting/deleting */
-       buffer_state_enum fti_state;
-       /*  flags fatal hardware error */
-       unsigned int fti_failure:1;
-       /*  history record */
-       history_record fti_history;
-} ftape_info;
-
-/* vendor information */
-#define ft_drive_type          ftape_status.fti_drive_type
-/*  data rates */
-#define ft_data_rate           ftape_status.fti_used_data_rate
-#define ft_drive_max_rate      ftape_status.fti_drive_max_rate
-#define ft_fdc_max_rate        ftape_status.fti_fdc_max_rate
-/*  drive selection, either FTAPE_SEL_A/B/C/D */
-#define ft_drive_sel           ftape_status.fti_drive_sel
-/*  flags set after decode the drive and tape status   */
-#define ft_formatted           ftape_status.fti_formatted
-#define ft_no_tape             ftape_status.fti_no_tape
-#define ft_write_protected     ftape_status.fti_write_protected
-#define ft_new_tape            ftape_status.fti_new_tape
-/*  values of last queried drive/tape status and error */
-#define ft_last_error          ftape_status.fti_last_error
-#define ft_last_status         ftape_status.fti_last_status
-/*  cartridge geometry */
-#define ft_tracks_per_tape     ftape_status.fti_tracks_per_tape
-#define ft_segments_per_track  ftape_status.fti_segments_per_track
-/*  the format code as stored in the header segment  */
-#define ft_format_code         ftape_status.fti_format_code
-/*  the qic status as returned by report drive configuration */
-#define ft_qic_std             ftape_status.fti_qic_std
-#define ft_used_header_segment ftape_status.fti_used_header_segment
-#define ft_header_segment_1    ftape_status.fti_header_segment_1
-#define ft_header_segment_2    ftape_status.fti_header_segment_2
-#define ft_first_data_segment  ftape_status.fti_first_data_segment
-#define ft_last_data_segment   ftape_status.fti_last_data_segment
-/*  is tape running? */
-#define ft_runner_status       ftape_status.fti_runner_status
-/*  is tape reading/writing/verifying/formatting/deleting */
-#define ft_driver_state        ftape_status.fti_state
-/*  flags fatal hardware error */
-#define ft_failure             ftape_status.fti_failure
-/*  history record */
-#define ft_history             ftape_status.fti_history
-
-/*
- *      ftape-ctl.c defined global vars.
- */
-extern ftape_info ftape_status;
-extern int ftape_segments_per_head;
-extern int ftape_segments_per_cylinder;
-extern int ftape_init_drive_needed;
-
-/*
- *      ftape-ctl.c defined global functions.
- */
-extern int  ftape_mmap(struct vm_area_struct *vma);
-extern int  ftape_enable(int drive_selection);
-extern void ftape_disable(void);
-extern int  ftape_seek_to_bot(void);
-extern int  ftape_seek_to_eot(void);
-extern int  ftape_abort_operation(void);
-extern void ftape_calc_timeouts(unsigned int qic_std,
-                                unsigned int data_rate,
-                                unsigned int tape_len);
-extern int  ftape_calibrate_data_rate(unsigned int qic_std);
-extern const ftape_info *ftape_get_status(void);
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-ecc.c b/drivers/char/ftape/lowlevel/ftape-ecc.c
deleted file mode 100644 (file)
index e5632f6..0000000
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- *
- *      Copyright (c) 1993 Ning and David Mosberger.
- This is based on code originally written by Bas Laarhoven (bas@vimec.nl)
- and David L. Brown, Jr., and incorporates improvements suggested by
- Kai Harrekilde-Petersen.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ecc.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:18:10 $
- *
- *      This file contains the Reed-Solomon error correction code 
- *      for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape.h>
-
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-ecc.h"
-
-/* Machines that are big-endian should define macro BIG_ENDIAN.
- * Unfortunately, there doesn't appear to be a standard include file
- * that works for all OSs.
- */
-
-#if defined(__sparc__) || defined(__hppa)
-#define BIG_ENDIAN
-#endif                         /* __sparc__ || __hppa */
-
-#if defined(__mips__)
-#error Find a smart way to determine the Endianness of the MIPS CPU
-#endif
-
-/* Notice: to minimize the potential for confusion, we use r to
- *         denote the independent variable of the polynomials in the
- *         Galois Field GF(2^8).  We reserve x for polynomials that
- *         that have coefficients in GF(2^8).
- *         
- * The Galois Field in which coefficient arithmetic is performed are
- * the polynomials over Z_2 (i.e., 0 and 1) modulo the irreducible
- * polynomial f(r), where f(r)=r^8 + r^7 + r^2 + r + 1.  A polynomial
- * is represented as a byte with the MSB as the coefficient of r^7 and
- * the LSB as the coefficient of r^0.  For example, the binary
- * representation of f(x) is 0x187 (of course, this doesn't fit into 8
- * bits).  In this field, the polynomial r is a primitive element.
- * That is, r^i with i in 0,...,255 enumerates all elements in the
- * field.
- *
- * The generator polynomial for the QIC-80 ECC is
- *
- *      g(x) = x^3 + r^105*x^2 + r^105*x + 1
- *
- * which can be factored into:
- *
- *      g(x) = (x-r^-1)(x-r^0)(x-r^1)
- *
- * the byte representation of the coefficients are:
- *
- *      r^105 = 0xc0
- *      r^-1  = 0xc3
- *      r^0   = 0x01
- *      r^1   = 0x02
- *
- * Notice that r^-1 = r^254 as exponent arithmetic is performed
- * modulo 2^8-1 = 255.
- *
- * For more information on Galois Fields and Reed-Solomon codes, refer
- * to any good book.  I found _An Introduction to Error Correcting
- * Codes with Applications_ by S. A. Vanstone and P. C. van Oorschot
- * to be a good introduction into the former.  _CODING THEORY: The
- * Essentials_ I found very useful for its concise description of
- * Reed-Solomon encoding/decoding.
- *
- */
-
-typedef __u8 Matrix[3][3];
-
-/*
- * gfpow[] is defined such that gfpow[i] returns r^i if
- * i is in the range [0..255].
- */
-static const __u8 gfpow[] =
-{
-       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-       0x87, 0x89, 0x95, 0xad, 0xdd, 0x3d, 0x7a, 0xf4,
-       0x6f, 0xde, 0x3b, 0x76, 0xec, 0x5f, 0xbe, 0xfb,
-       0x71, 0xe2, 0x43, 0x86, 0x8b, 0x91, 0xa5, 0xcd,
-       0x1d, 0x3a, 0x74, 0xe8, 0x57, 0xae, 0xdb, 0x31,
-       0x62, 0xc4, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0x67,
-       0xce, 0x1b, 0x36, 0x6c, 0xd8, 0x37, 0x6e, 0xdc,
-       0x3f, 0x7e, 0xfc, 0x7f, 0xfe, 0x7b, 0xf6, 0x6b,
-       0xd6, 0x2b, 0x56, 0xac, 0xdf, 0x39, 0x72, 0xe4,
-       0x4f, 0x9e, 0xbb, 0xf1, 0x65, 0xca, 0x13, 0x26,
-       0x4c, 0x98, 0xb7, 0xe9, 0x55, 0xaa, 0xd3, 0x21,
-       0x42, 0x84, 0x8f, 0x99, 0xb5, 0xed, 0x5d, 0xba,
-       0xf3, 0x61, 0xc2, 0x03, 0x06, 0x0c, 0x18, 0x30,
-       0x60, 0xc0, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0,
-       0x47, 0x8e, 0x9b, 0xb1, 0xe5, 0x4d, 0x9a, 0xb3,
-       0xe1, 0x45, 0x8a, 0x93, 0xa1, 0xc5, 0x0d, 0x1a,
-       0x34, 0x68, 0xd0, 0x27, 0x4e, 0x9c, 0xbf, 0xf9,
-       0x75, 0xea, 0x53, 0xa6, 0xcb, 0x11, 0x22, 0x44,
-       0x88, 0x97, 0xa9, 0xd5, 0x2d, 0x5a, 0xb4, 0xef,
-       0x59, 0xb2, 0xe3, 0x41, 0x82, 0x83, 0x81, 0x85,
-       0x8d, 0x9d, 0xbd, 0xfd, 0x7d, 0xfa, 0x73, 0xe6,
-       0x4b, 0x96, 0xab, 0xd1, 0x25, 0x4a, 0x94, 0xaf,
-       0xd9, 0x35, 0x6a, 0xd4, 0x2f, 0x5e, 0xbc, 0xff,
-       0x79, 0xf2, 0x63, 0xc6, 0x0b, 0x16, 0x2c, 0x58,
-       0xb0, 0xe7, 0x49, 0x92, 0xa3, 0xc1, 0x05, 0x0a,
-       0x14, 0x28, 0x50, 0xa0, 0xc7, 0x09, 0x12, 0x24,
-       0x48, 0x90, 0xa7, 0xc9, 0x15, 0x2a, 0x54, 0xa8,
-       0xd7, 0x29, 0x52, 0xa4, 0xcf, 0x19, 0x32, 0x64,
-       0xc8, 0x17, 0x2e, 0x5c, 0xb8, 0xf7, 0x69, 0xd2,
-       0x23, 0x46, 0x8c, 0x9f, 0xb9, 0xf5, 0x6d, 0xda,
-       0x33, 0x66, 0xcc, 0x1f, 0x3e, 0x7c, 0xf8, 0x77,
-       0xee, 0x5b, 0xb6, 0xeb, 0x51, 0xa2, 0xc3, 0x01
-};
-
-/*
- * This is a log table.  That is, gflog[r^i] returns i (modulo f(r)).
- * gflog[0] is undefined and the first element is therefore not valid.
- */
-static const __u8 gflog[256] =
-{
-       0xff, 0x00, 0x01, 0x63, 0x02, 0xc6, 0x64, 0x6a,
-       0x03, 0xcd, 0xc7, 0xbc, 0x65, 0x7e, 0x6b, 0x2a,
-       0x04, 0x8d, 0xce, 0x4e, 0xc8, 0xd4, 0xbd, 0xe1,
-       0x66, 0xdd, 0x7f, 0x31, 0x6c, 0x20, 0x2b, 0xf3,
-       0x05, 0x57, 0x8e, 0xe8, 0xcf, 0xac, 0x4f, 0x83,
-       0xc9, 0xd9, 0xd5, 0x41, 0xbe, 0x94, 0xe2, 0xb4,
-       0x67, 0x27, 0xde, 0xf0, 0x80, 0xb1, 0x32, 0x35,
-       0x6d, 0x45, 0x21, 0x12, 0x2c, 0x0d, 0xf4, 0x38,
-       0x06, 0x9b, 0x58, 0x1a, 0x8f, 0x79, 0xe9, 0x70,
-       0xd0, 0xc2, 0xad, 0xa8, 0x50, 0x75, 0x84, 0x48,
-       0xca, 0xfc, 0xda, 0x8a, 0xd6, 0x54, 0x42, 0x24,
-       0xbf, 0x98, 0x95, 0xf9, 0xe3, 0x5e, 0xb5, 0x15,
-       0x68, 0x61, 0x28, 0xba, 0xdf, 0x4c, 0xf1, 0x2f,
-       0x81, 0xe6, 0xb2, 0x3f, 0x33, 0xee, 0x36, 0x10,
-       0x6e, 0x18, 0x46, 0xa6, 0x22, 0x88, 0x13, 0xf7,
-       0x2d, 0xb8, 0x0e, 0x3d, 0xf5, 0xa4, 0x39, 0x3b,
-       0x07, 0x9e, 0x9c, 0x9d, 0x59, 0x9f, 0x1b, 0x08,
-       0x90, 0x09, 0x7a, 0x1c, 0xea, 0xa0, 0x71, 0x5a,
-       0xd1, 0x1d, 0xc3, 0x7b, 0xae, 0x0a, 0xa9, 0x91,
-       0x51, 0x5b, 0x76, 0x72, 0x85, 0xa1, 0x49, 0xeb,
-       0xcb, 0x7c, 0xfd, 0xc4, 0xdb, 0x1e, 0x8b, 0xd2,
-       0xd7, 0x92, 0x55, 0xaa, 0x43, 0x0b, 0x25, 0xaf,
-       0xc0, 0x73, 0x99, 0x77, 0x96, 0x5c, 0xfa, 0x52,
-       0xe4, 0xec, 0x5f, 0x4a, 0xb6, 0xa2, 0x16, 0x86,
-       0x69, 0xc5, 0x62, 0xfe, 0x29, 0x7d, 0xbb, 0xcc,
-       0xe0, 0xd3, 0x4d, 0x8c, 0xf2, 0x1f, 0x30, 0xdc,
-       0x82, 0xab, 0xe7, 0x56, 0xb3, 0x93, 0x40, 0xd8,
-       0x34, 0xb0, 0xef, 0x26, 0x37, 0x0c, 0x11, 0x44,
-       0x6f, 0x78, 0x19, 0x9a, 0x47, 0x74, 0xa7, 0xc1,
-       0x23, 0x53, 0x89, 0xfb, 0x14, 0x5d, 0xf8, 0x97,
-       0x2e, 0x4b, 0xb9, 0x60, 0x0f, 0xed, 0x3e, 0xe5,
-       0xf6, 0x87, 0xa5, 0x17, 0x3a, 0xa3, 0x3c, 0xb7
-};
-
-/* This is a multiplication table for the factor 0xc0 (i.e., r^105 (mod f(r)).
- * gfmul_c0[f] returns r^105 * f(r) (modulo f(r)).
- */
-static const __u8 gfmul_c0[256] =
-{
-       0x00, 0xc0, 0x07, 0xc7, 0x0e, 0xce, 0x09, 0xc9,
-       0x1c, 0xdc, 0x1b, 0xdb, 0x12, 0xd2, 0x15, 0xd5,
-       0x38, 0xf8, 0x3f, 0xff, 0x36, 0xf6, 0x31, 0xf1,
-       0x24, 0xe4, 0x23, 0xe3, 0x2a, 0xea, 0x2d, 0xed,
-       0x70, 0xb0, 0x77, 0xb7, 0x7e, 0xbe, 0x79, 0xb9,
-       0x6c, 0xac, 0x6b, 0xab, 0x62, 0xa2, 0x65, 0xa5,
-       0x48, 0x88, 0x4f, 0x8f, 0x46, 0x86, 0x41, 0x81,
-       0x54, 0x94, 0x53, 0x93, 0x5a, 0x9a, 0x5d, 0x9d,
-       0xe0, 0x20, 0xe7, 0x27, 0xee, 0x2e, 0xe9, 0x29,
-       0xfc, 0x3c, 0xfb, 0x3b, 0xf2, 0x32, 0xf5, 0x35,
-       0xd8, 0x18, 0xdf, 0x1f, 0xd6, 0x16, 0xd1, 0x11,
-       0xc4, 0x04, 0xc3, 0x03, 0xca, 0x0a, 0xcd, 0x0d,
-       0x90, 0x50, 0x97, 0x57, 0x9e, 0x5e, 0x99, 0x59,
-       0x8c, 0x4c, 0x8b, 0x4b, 0x82, 0x42, 0x85, 0x45,
-       0xa8, 0x68, 0xaf, 0x6f, 0xa6, 0x66, 0xa1, 0x61,
-       0xb4, 0x74, 0xb3, 0x73, 0xba, 0x7a, 0xbd, 0x7d,
-       0x47, 0x87, 0x40, 0x80, 0x49, 0x89, 0x4e, 0x8e,
-       0x5b, 0x9b, 0x5c, 0x9c, 0x55, 0x95, 0x52, 0x92,
-       0x7f, 0xbf, 0x78, 0xb8, 0x71, 0xb1, 0x76, 0xb6,
-       0x63, 0xa3, 0x64, 0xa4, 0x6d, 0xad, 0x6a, 0xaa,
-       0x37, 0xf7, 0x30, 0xf0, 0x39, 0xf9, 0x3e, 0xfe,
-       0x2b, 0xeb, 0x2c, 0xec, 0x25, 0xe5, 0x22, 0xe2,
-       0x0f, 0xcf, 0x08, 0xc8, 0x01, 0xc1, 0x06, 0xc6,
-       0x13, 0xd3, 0x14, 0xd4, 0x1d, 0xdd, 0x1a, 0xda,
-       0xa7, 0x67, 0xa0, 0x60, 0xa9, 0x69, 0xae, 0x6e,
-       0xbb, 0x7b, 0xbc, 0x7c, 0xb5, 0x75, 0xb2, 0x72,
-       0x9f, 0x5f, 0x98, 0x58, 0x91, 0x51, 0x96, 0x56,
-       0x83, 0x43, 0x84, 0x44, 0x8d, 0x4d, 0x8a, 0x4a,
-       0xd7, 0x17, 0xd0, 0x10, 0xd9, 0x19, 0xde, 0x1e,
-       0xcb, 0x0b, 0xcc, 0x0c, 0xc5, 0x05, 0xc2, 0x02,
-       0xef, 0x2f, 0xe8, 0x28, 0xe1, 0x21, 0xe6, 0x26,
-       0xf3, 0x33, 0xf4, 0x34, 0xfd, 0x3d, 0xfa, 0x3a
-};
-
-
-/* Returns V modulo 255 provided V is in the range -255,-254,...,509.
- */
-static inline __u8 mod255(int v)
-{
-       if (v > 0) {
-               if (v < 255) {
-                       return v;
-               } else {
-                       return v - 255;
-               }
-       } else {
-               return v + 255;
-       }
-}
-
-
-/* Add two numbers in the field.  Addition in this field is equivalent
- * to a bit-wise exclusive OR operation---subtraction is therefore
- * identical to addition.
- */
-static inline __u8 gfadd(__u8 a, __u8 b)
-{
-       return a ^ b;
-}
-
-
-/* Add two vectors of numbers in the field.  Each byte in A and B gets
- * added individually.
- */
-static inline unsigned long gfadd_long(unsigned long a, unsigned long b)
-{
-       return a ^ b;
-}
-
-
-/* Multiply two numbers in the field:
- */
-static inline __u8 gfmul(__u8 a, __u8 b)
-{
-       if (a && b) {
-               return gfpow[mod255(gflog[a] + gflog[b])];
-       } else {
-               return 0;
-       }
-}
-
-
-/* Just like gfmul, except we have already looked up the log of the
- * second number.
- */
-static inline __u8 gfmul_exp(__u8 a, int b)
-{
-       if (a) {
-               return gfpow[mod255(gflog[a] + b)];
-       } else {
-               return 0;
-       }
-}
-
-
-/* Just like gfmul_exp, except that A is a vector of numbers.  That
- * is, each byte in A gets multiplied by gfpow[mod255(B)].
- */
-static inline unsigned long gfmul_exp_long(unsigned long a, int b)
-{
-       __u8 t;
-
-       if (sizeof(long) == 4) {
-               return (
-               ((t = (__u32)a >> 24 & 0xff) ?
-                (((__u32) gfpow[mod255(gflog[t] + b)]) << 24) : 0) |
-               ((t = (__u32)a >> 16 & 0xff) ?
-                (((__u32) gfpow[mod255(gflog[t] + b)]) << 16) : 0) |
-               ((t = (__u32)a >> 8 & 0xff) ?
-                (((__u32) gfpow[mod255(gflog[t] + b)]) << 8) : 0) |
-               ((t = (__u32)a >> 0 & 0xff) ?
-                (((__u32) gfpow[mod255(gflog[t] + b)]) << 0) : 0));
-       } else if (sizeof(long) == 8) {
-               return (
-               ((t = (__u64)a >> 56 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 56) : 0) |
-               ((t = (__u64)a >> 48 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 48) : 0) |
-               ((t = (__u64)a >> 40 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 40) : 0) |
-               ((t = (__u64)a >> 32 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 32) : 0) |
-               ((t = (__u64)a >> 24 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 24) : 0) |
-               ((t = (__u64)a >> 16 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 16) : 0) |
-               ((t = (__u64)a >> 8 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 8) : 0) |
-               ((t = (__u64)a >> 0 & 0xff) ?
-                (((__u64) gfpow[mod255(gflog[t] + b)]) << 0) : 0));
-       } else {
-               TRACE_FUN(ft_t_any);
-               TRACE_ABORT(-1, ft_t_err, "Error: size of long is %d bytes",
-                           (int)sizeof(long));
-       }
-}
-
-
-/* Divide two numbers in the field.  Returns a/b (modulo f(x)).
- */
-static inline __u8 gfdiv(__u8 a, __u8 b)
-{
-       if (!b) {
-               TRACE_FUN(ft_t_any);
-               TRACE_ABORT(0xff, ft_t_bug, "Error: division by zero");
-       } else if (a == 0) {
-               return 0;
-       } else {
-               return gfpow[mod255(gflog[a] - gflog[b])];
-       }
-}
-
-
-/* The following functions return the inverse of the matrix of the
- * linear system that needs to be solved to determine the error
- * magnitudes.  The first deals with matrices of rank 3, while the
- * second deals with matrices of rank 2.  The error indices are passed
- * in arguments L0,..,L2 (0=first sector, 31=last sector).  The error
- * indices must be sorted in ascending order, i.e., L0<L1<L2.
- *
- * The linear system that needs to be solved for the error magnitudes
- * is A * b = s, where s is the known vector of syndromes, b is the
- * vector of error magnitudes and A in the ORDER=3 case:
- *
- *    A_3 = {{1/r^L[0], 1/r^L[1], 1/r^L[2]},
- *          {        1,        1,        1},
- *          { r^L[0], r^L[1], r^L[2]}} 
- */
-static inline int gfinv3(__u8 l0,
-                        __u8 l1, 
-                        __u8 l2, 
-                        Matrix Ainv)
-{
-       __u8 det;
-       __u8 t20, t10, t21, t12, t01, t02;
-       int log_det;
-
-       /* compute some intermediate results: */
-       t20 = gfpow[l2 - l0];           /* t20 = r^l2/r^l0 */
-       t10 = gfpow[l1 - l0];           /* t10 = r^l1/r^l0 */
-       t21 = gfpow[l2 - l1];           /* t21 = r^l2/r^l1 */
-       t12 = gfpow[l1 - l2 + 255];     /* t12 = r^l1/r^l2 */
-       t01 = gfpow[l0 - l1 + 255];     /* t01 = r^l0/r^l1 */
-       t02 = gfpow[l0 - l2 + 255];     /* t02 = r^l0/r^l2 */
-       /* Calculate the determinant of matrix A_3^-1 (sometimes
-        * called the Vandermonde determinant):
-        */
-       det = gfadd(t20, gfadd(t10, gfadd(t21, gfadd(t12, gfadd(t01, t02)))));
-       if (!det) {
-               TRACE_FUN(ft_t_any);
-               TRACE_ABORT(0, ft_t_err,
-                          "Inversion failed (3 CRC errors, >0 CRC failures)");
-       }
-       log_det = 255 - gflog[det];
-
-       /* Now, calculate all of the coefficients:
-        */
-       Ainv[0][0]= gfmul_exp(gfadd(gfpow[l1], gfpow[l2]), log_det);
-       Ainv[0][1]= gfmul_exp(gfadd(t21, t12), log_det);
-       Ainv[0][2]= gfmul_exp(gfadd(gfpow[255 - l1], gfpow[255 - l2]),log_det);
-
-       Ainv[1][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l2]), log_det);
-       Ainv[1][1]= gfmul_exp(gfadd(t20, t02), log_det);
-       Ainv[1][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l2]),log_det);
-
-       Ainv[2][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l1]), log_det);
-       Ainv[2][1]= gfmul_exp(gfadd(t10, t01), log_det);
-       Ainv[2][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l1]),log_det);
-
-       return 1;
-}
-
-
-static inline int gfinv2(__u8 l0, __u8 l1, Matrix Ainv)
-{
-       __u8 det;
-       __u8 t1, t2;
-       int log_det;
-
-       t1 = gfpow[255 - l0];
-       t2 = gfpow[255 - l1];
-       det = gfadd(t1, t2);
-       if (!det) {
-               TRACE_FUN(ft_t_any);
-               TRACE_ABORT(0, ft_t_err,
-                          "Inversion failed (2 CRC errors, >0 CRC failures)");
-       }
-       log_det = 255 - gflog[det];
-
-       /* Now, calculate all of the coefficients:
-        */
-       Ainv[0][0] = Ainv[1][0] = gfpow[log_det];
-
-       Ainv[0][1] = gfmul_exp(t2, log_det);
-       Ainv[1][1] = gfmul_exp(t1, log_det);
-
-       return 1;
-}
-
-
-/* Multiply matrix A by vector S and return result in vector B.  M is
- * assumed to be of order NxN, S and B of order Nx1.
- */
-static inline void gfmat_mul(int n, Matrix A, 
-                            __u8 *s, __u8 *b)
-{
-       int i, j;
-       __u8 dot_prod;
-
-       for (i = 0; i < n; ++i) {
-               dot_prod = 0;
-               for (j = 0; j < n; ++j) {
-                       dot_prod = gfadd(dot_prod, gfmul(A[i][j], s[j]));
-               }
-               b[i] = dot_prod;
-       }
-}
-\f
-
-
-/* The Reed Solomon ECC codes are computed over the N-th byte of each
- * block, where N=SECTOR_SIZE.  There are up to 29 blocks of data, and
- * 3 blocks of ECC.  The blocks are stored contiguously in memory.  A
- * segment, consequently, is assumed to have at least 4 blocks: one or
- * more data blocks plus three ECC blocks.
- *
- * Notice: In QIC-80 speak, a CRC error is a sector with an incorrect
- *         CRC.  A CRC failure is a sector with incorrect data, but
- *         a valid CRC.  In the error control literature, the former
- *         is usually called "erasure", the latter "error."
- */
-/* Compute the parity bytes for C columns of data, where C is the
- * number of bytes that fit into a long integer.  We use a linear
- * feed-back register to do this.  The parity bytes P[0], P[STRIDE],
- * P[2*STRIDE] are computed such that:
- *
- *              x^k * p(x) + m(x) = 0 (modulo g(x))
- *
- * where k = NBLOCKS,
- *       p(x) = P[0] + P[STRIDE]*x + P[2*STRIDE]*x^2, and
- *       m(x) = sum_{i=0}^k m_i*x^i.
- *       m_i = DATA[i*SECTOR_SIZE]
- */
-static inline void set_parity(unsigned long *data,
-                             int nblocks, 
-                             unsigned long *p, 
-                             int stride)
-{
-       unsigned long p0, p1, p2, t1, t2, *end;
-
-       end = data + nblocks * (FT_SECTOR_SIZE / sizeof(long));
-       p0 = p1 = p2 = 0;
-       while (data < end) {
-               /* The new parity bytes p0_i, p1_i, p2_i are computed
-                * from the old values p0_{i-1}, p1_{i-1}, p2_{i-1}
-                * recursively as:
-                *
-                *        p0_i = p1_{i-1} + r^105 * (m_{i-1} - p0_{i-1})
-                *        p1_i = p2_{i-1} + r^105 * (m_{i-1} - p0_{i-1})
-                *        p2_i =                    (m_{i-1} - p0_{i-1})
-                *
-                * With the initial condition: p0_0 = p1_0 = p2_0 = 0.
-                */
-               t1 = gfadd_long(*data, p0);
-               /*
-                * Multiply each byte in t1 by 0xc0:
-                */
-               if (sizeof(long) == 4) {
-                       t2= (((__u32) gfmul_c0[(__u32)t1 >> 24 & 0xff]) << 24 |
-                            ((__u32) gfmul_c0[(__u32)t1 >> 16 & 0xff]) << 16 |
-                            ((__u32) gfmul_c0[(__u32)t1 >>  8 & 0xff]) <<  8 |
-                            ((__u32) gfmul_c0[(__u32)t1 >>  0 & 0xff]) <<  0);
-               } else if (sizeof(long) == 8) {
-                       t2= (((__u64) gfmul_c0[(__u64)t1 >> 56 & 0xff]) << 56 |
-                            ((__u64) gfmul_c0[(__u64)t1 >> 48 & 0xff]) << 48 |
-                            ((__u64) gfmul_c0[(__u64)t1 >> 40 & 0xff]) << 40 |
-                            ((__u64) gfmul_c0[(__u64)t1 >> 32 & 0xff]) << 32 |
-                            ((__u64) gfmul_c0[(__u64)t1 >> 24 & 0xff]) << 24 |
-                            ((__u64) gfmul_c0[(__u64)t1 >> 16 & 0xff]) << 16 |
-                            ((__u64) gfmul_c0[(__u64)t1 >>  8 & 0xff]) <<  8 |
-                            ((__u64) gfmul_c0[(__u64)t1 >>  0 & 0xff]) <<  0);
-               } else {
-                       TRACE_FUN(ft_t_any);
-                       TRACE(ft_t_err, "Error: long is of size %d",
-                             (int) sizeof(long));
-                       TRACE_EXIT;
-               }
-               p0 = gfadd_long(t2, p1);
-               p1 = gfadd_long(t2, p2);
-               p2 = t1;
-               data += FT_SECTOR_SIZE / sizeof(long);
-       }
-       *p = p0;
-       p += stride;
-       *p = p1;
-       p += stride;
-       *p = p2;
-       return;
-}
-
-
-/* Compute the 3 syndrome values.  DATA should point to the first byte
- * of the column for which the syndromes are desired.  The syndromes
- * are computed over the first NBLOCKS of rows.  The three bytes will
- * be placed in S[0], S[1], and S[2].
- *
- * S[i] is the value of the "message" polynomial m(x) evaluated at the
- * i-th root of the generator polynomial g(x).
- *
- * As g(x)=(x-r^-1)(x-1)(x-r^1) we evaluate the message polynomial at
- * x=r^-1 to get S[0], at x=r^0=1 to get S[1], and at x=r to get S[2].
- * This could be done directly and efficiently via the Horner scheme.
- * However, it would require multiplication tables for the factors
- * r^-1 (0xc3) and r (0x02).  The following scheme does not require
- * any multiplication tables beyond what's needed for set_parity()
- * anyway and is slightly faster if there are no errors and slightly
- * slower if there are errors.  The latter is hopefully the infrequent
- * case.
- *
- * To understand the alternative algorithm, notice that set_parity(m,
- * k, p) computes parity bytes such that:
- *
- *      x^k * p(x) = m(x) (modulo g(x)).
- *
- * That is, to evaluate m(r^m), where r^m is a root of g(x), we can
- * simply evaluate (r^m)^k*p(r^m).  Also, notice that p is 0 if and
- * only if s is zero.  That is, if all parity bytes are 0, we know
- * there is no error in the data and consequently there is no need to
- * compute s(x) at all!  In all other cases, we compute s(x) from p(x)
- * by evaluating (r^m)^k*p(r^m) for m=-1, m=0, and m=1.  The p(x)
- * polynomial is evaluated via the Horner scheme.
- */
-static int compute_syndromes(unsigned long *data, int nblocks, unsigned long *s)
-{
-       unsigned long p[3];
-
-       set_parity(data, nblocks, p, 1);
-       if (p[0] | p[1] | p[2]) {
-               /* Some of the checked columns do not have a zero
-                * syndrome.  For simplicity, we compute the syndromes
-                * for all columns that we have computed the
-                * remainders for.
-                */
-               s[0] = gfmul_exp_long(
-                       gfadd_long(p[0], 
-                                  gfmul_exp_long(
-                                          gfadd_long(p[1], 
-                                                     gfmul_exp_long(p[2], -1)),
-                                          -1)), 
-                       -nblocks);
-               s[1] = gfadd_long(gfadd_long(p[2], p[1]), p[0]);
-               s[2] = gfmul_exp_long(
-                       gfadd_long(p[0], 
-                                  gfmul_exp_long(
-                                          gfadd_long(p[1],
-                                                     gfmul_exp_long(p[2], 1)),
-                                          1)),
-                       nblocks);
-               return 0;
-       } else {
-               return 1;
-       }
-}
-
-
-/* Correct the block in the column pointed to by DATA.  There are NBAD
- * CRC errors and their indices are in BAD_LOC[0], up to
- * BAD_LOC[NBAD-1].  If NBAD>1, Ainv holds the inverse of the matrix
- * of the linear system that needs to be solved to determine the error
- * magnitudes.  S[0], S[1], and S[2] are the syndrome values.  If row
- * j gets corrected, then bit j will be set in CORRECTION_MAP.
- */
-static inline int correct_block(__u8 *data, int nblocks,
-                               int nbad, int *bad_loc, Matrix Ainv,
-                               __u8 *s,
-                               SectorMap * correction_map)
-{
-       int ncorrected = 0;
-       int i;
-       __u8 t1, t2;
-       __u8 c0, c1, c2;        /* check bytes */
-       __u8 error_mag[3], log_error_mag;
-       __u8 *dp, l, e;
-       TRACE_FUN(ft_t_any);
-
-       switch (nbad) {
-       case 0:
-               /* might have a CRC failure: */
-               if (s[0] == 0) {
-                       /* more than one error */
-                       TRACE_ABORT(-1, ft_t_err,
-                                "ECC failed (0 CRC errors, >1 CRC failures)");
-               }
-               t1 = gfdiv(s[1], s[0]);
-               if ((bad_loc[nbad++] = gflog[t1]) >= nblocks) {
-                       TRACE(ft_t_err,
-                             "ECC failed (0 CRC errors, >1 CRC failures)");
-                       TRACE_ABORT(-1, ft_t_err,
-                                 "attempt to correct data at %d", bad_loc[0]);
-               }
-               error_mag[0] = s[1];
-               break;
-       case 1:
-               t1 = gfadd(gfmul_exp(s[1], bad_loc[0]), s[2]);
-               t2 = gfadd(gfmul_exp(s[0], bad_loc[0]), s[1]);
-               if (t1 == 0 && t2 == 0) {
-                       /* one erasure, no error: */
-                       Ainv[0][0] = gfpow[bad_loc[0]];
-               } else if (t1 == 0 || t2 == 0) {
-                       /* one erasure and more than one error: */
-                       TRACE_ABORT(-1, ft_t_err,
-                                   "ECC failed (1 erasure, >1 error)");
-               } else {
-                       /* one erasure, one error: */
-                       if ((bad_loc[nbad++] = gflog[gfdiv(t1, t2)]) 
-                           >= nblocks) {
-                               TRACE(ft_t_err, "ECC failed "
-                                     "(1 CRC errors, >1 CRC failures)");
-                               TRACE_ABORT(-1, ft_t_err,
-                                           "attempt to correct data at %d",
-                                           bad_loc[1]);
-                       }
-                       if (!gfinv2(bad_loc[0], bad_loc[1], Ainv)) {
-                               /* inversion failed---must have more
-                                 *  than one error 
-                                */
-                               TRACE_EXIT -1;
-                       }
-               }
-               /* FALL THROUGH TO ERROR MAGNITUDE COMPUTATION:
-                */
-       case 2:
-       case 3:
-               /* compute error magnitudes: */
-               gfmat_mul(nbad, Ainv, s, error_mag);
-               break;
-
-       default:
-               TRACE_ABORT(-1, ft_t_err,
-                           "Internal Error: number of CRC errors > 3");
-       }
-
-       /* Perform correction by adding ERROR_MAG[i] to the byte at
-        * offset BAD_LOC[i].  Also add the value of the computed
-        * error polynomial to the syndrome values.  If the correction
-        * was successful, the resulting check bytes should be zero
-        * (i.e., the corrected data is a valid code word).
-        */
-       c0 = s[0];
-       c1 = s[1];
-       c2 = s[2];
-       for (i = 0; i < nbad; ++i) {
-               e = error_mag[i];
-               if (e) {
-                       /* correct the byte at offset L by magnitude E: */
-                       l = bad_loc[i];
-                       dp = &data[l * FT_SECTOR_SIZE];
-                       *dp = gfadd(*dp, e);
-                       *correction_map |= 1 << l;
-                       ++ncorrected;
-
-                       log_error_mag = gflog[e];
-                       c0 = gfadd(c0, gfpow[mod255(log_error_mag - l)]);
-                       c1 = gfadd(c1, e);
-                       c2 = gfadd(c2, gfpow[mod255(log_error_mag + l)]);
-               }
-       }
-       if (c0 || c1 || c2) {
-               TRACE_ABORT(-1, ft_t_err,
-                           "ECC self-check failed, too many errors");
-       }
-       TRACE_EXIT ncorrected;
-}
-
-
-#if defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID)
-
-/* Perform a sanity check on the computed parity bytes:
- */
-static int sanity_check(unsigned long *data, int nblocks)
-{
-       TRACE_FUN(ft_t_any);
-       unsigned long s[3];
-
-       if (!compute_syndromes(data, nblocks, s)) {
-               TRACE_ABORT(0, ft_bug,
-                           "Internal Error: syndrome self-check failed");
-       }
-       TRACE_EXIT 1;
-}
-
-#endif /* defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID) */
-
-/* Compute the parity for an entire segment of data.
- */
-int ftape_ecc_set_segment_parity(struct memory_segment *mseg)
-{
-       int i;
-       __u8 *parity_bytes;
-
-       parity_bytes = &mseg->data[(mseg->blocks - 3) * FT_SECTOR_SIZE];
-       for (i = 0; i < FT_SECTOR_SIZE; i += sizeof(long)) {
-               set_parity((unsigned long *) &mseg->data[i], mseg->blocks - 3,
-                          (unsigned long *) &parity_bytes[i],
-                          FT_SECTOR_SIZE / sizeof(long));
-#ifdef ECC_PARANOID
-               if (!sanity_check((unsigned long *) &mseg->data[i],
-                                  mseg->blocks)) {
-                       return -1;
-               }
-#endif                         /* ECC_PARANOID */
-       }
-       return 0;
-}
-
-
-/* Checks and corrects (if possible) the segment MSEG.  Returns one of
- * ECC_OK, ECC_CORRECTED, and ECC_FAILED.
- */
-int ftape_ecc_correct_data(struct memory_segment *mseg)
-{
-       int col, i, result;
-       int ncorrected = 0;
-       int nerasures = 0;      /* # of erasures (CRC errors) */
-       int erasure_loc[3];     /* erasure locations */
-       unsigned long ss[3];
-       __u8 s[3];
-       Matrix Ainv;
-       TRACE_FUN(ft_t_flow);
-
-       mseg->corrected = 0;
-
-       /* find first column that has non-zero syndromes: */
-       for (col = 0; col < FT_SECTOR_SIZE; col += sizeof(long)) {
-               if (!compute_syndromes((unsigned long *) &mseg->data[col],
-                                      mseg->blocks, ss)) {
-                       /* something is wrong---have to fix things */
-                       break;
-               }
-       }
-       if (col >= FT_SECTOR_SIZE) {
-               /* all syndromes are ok, therefore nothing to correct */
-               TRACE_EXIT ECC_OK;
-       }
-       /* count the number of CRC errors if there were any: */
-       if (mseg->read_bad) {
-               for (i = 0; i < mseg->blocks; i++) {
-                       if (BAD_CHECK(mseg->read_bad, i)) {
-                               if (nerasures >= 3) {
-                                       /* this is too much for ECC */
-                                       TRACE_ABORT(ECC_FAILED, ft_t_err,
-                                               "ECC failed (>3 CRC errors)");
-                               }       /* if */
-                               erasure_loc[nerasures++] = i;
-                       }
-               }
-       }
-       /*
-        * If there are at least 2 CRC errors, determine inverse of matrix
-        * of linear system to be solved:
-        */
-       switch (nerasures) {
-       case 2:
-               if (!gfinv2(erasure_loc[0], erasure_loc[1], Ainv)) {
-                       TRACE_EXIT ECC_FAILED;
-               }
-               break;
-       case 3:
-               if (!gfinv3(erasure_loc[0], erasure_loc[1],
-                           erasure_loc[2], Ainv)) {
-                       TRACE_EXIT ECC_FAILED;
-               }
-               break;
-       default:
-               /* this is not an error condition... */
-               break;
-       }
-
-       do {
-               for (i = 0; i < sizeof(long); ++i) {
-                       s[0] = ss[0];
-                       s[1] = ss[1];
-                       s[2] = ss[2];
-                       if (s[0] | s[1] | s[2]) {
-#ifdef BIG_ENDIAN
-                               result = correct_block(
-                                       &mseg->data[col + sizeof(long) - 1 - i],
-                                       mseg->blocks,
-                                       nerasures,
-                                       erasure_loc,
-                                       Ainv,
-                                       s,
-                                       &mseg->corrected);
-#else
-                               result = correct_block(&mseg->data[col + i],
-                                                      mseg->blocks,
-                                                      nerasures,
-                                                      erasure_loc,
-                                                      Ainv,
-                                                      s,
-                                                      &mseg->corrected);
-#endif
-                               if (result < 0) {
-                                       TRACE_EXIT ECC_FAILED;
-                               }
-                               ncorrected += result;
-                       }
-                       ss[0] >>= 8;
-                       ss[1] >>= 8;
-                       ss[2] >>= 8;
-               }
-
-#ifdef ECC_SANITY_CHECK
-               if (!sanity_check((unsigned long *) &mseg->data[col],
-                                 mseg->blocks)) {
-                       TRACE_EXIT ECC_FAILED;
-               }
-#endif                         /* ECC_SANITY_CHECK */
-
-               /* find next column with non-zero syndromes: */
-               while ((col += sizeof(long)) < FT_SECTOR_SIZE) {
-                       if (!compute_syndromes((unsigned long *)
-                                   &mseg->data[col], mseg->blocks, ss)) {
-                               /* something is wrong---have to fix things */
-                               break;
-                       }
-               }
-       } while (col < FT_SECTOR_SIZE);
-       if (ncorrected && nerasures == 0) {
-               TRACE(ft_t_warn, "block contained error not caught by CRC");
-       }
-       TRACE((ncorrected > 0) ? ft_t_noise : ft_t_any, "number of corrections: %d", ncorrected);
-       TRACE_EXIT ncorrected ? ECC_CORRECTED : ECC_OK;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-ecc.h b/drivers/char/ftape/lowlevel/ftape-ecc.h
deleted file mode 100644 (file)
index 4829146..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef _FTAPE_ECC_H_
-#define _FTAPE_ECC_H_
-
-/*
- *      Copyright (C) 1993 Ning and David Mosberger.
- *      Original:
- *      Copyright (C) 1993 Bas Laarhoven.
- *      Copyright (C) 1992 David L. Brown, Jr.
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ecc.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:11 $
- *
- *      This file contains the definitions for the
- *      Reed-Solomon error correction code 
- *      for the QIC-40/80 tape streamer device driver.
- */
-
-#include "../lowlevel/ftape-bsm.h"
-
-#define BAD_CLEAR(entry) ((entry)=0)
-#define BAD_SET(entry,sector) ((entry)|=(1<<(sector)))
-#define BAD_CHECK(entry,sector) ((entry)&(1<<(sector)))
-
-/*
- * Return values for ecc_correct_data:
- */
-enum {
-       ECC_OK,                 /* Data was correct. */
-       ECC_CORRECTED,          /* Correctable error in data. */
-       ECC_FAILED,             /* Could not correct data. */
-};
-
-/*
- * Representation of an in memory segment.  MARKED_BAD lists the
- * sectors that were marked bad during formatting.  If the N-th sector
- * in a segment is marked bad, bit 1<<N will be set in MARKED_BAD.
- * The sectors should be read in from the disk and packed, as if the
- * bad sectors were not there, and the segment just contained fewer
- * sectors.  READ_SECTORS is a bitmap of errors encountered while
- * reading the data.  These offsets are relative to the packed data.
- * BLOCKS is a count of the sectors not marked bad.  This is just to
- * prevent having to count the zero bits in MARKED_BAD each time this
- * is needed.  DATA is the actual sector packed data from (or to) the
- * tape.
- */
- struct memory_segment {
-       SectorMap marked_bad;
-       SectorMap read_bad;
-       int blocks;
-       __u8 *data;
-       SectorMap corrected;
- };
-
-/*
- * ecc.c defined global variables:
- */
-#ifdef TEST
-extern int ftape_ecc_tracing;
-#endif
-
-/*
- * ecc.c defined global functions:
- */
-extern int ftape_ecc_correct_data(struct memory_segment *data);
-extern int ftape_ecc_set_segment_parity(struct memory_segment *data);
-
-#endif /* _FTAPE_ECC_H_ */
diff --git a/drivers/char/ftape/lowlevel/ftape-format.c b/drivers/char/ftape/lowlevel/ftape-format.c
deleted file mode 100644 (file)
index 5dd4c59..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-format.c,v $
- * $Revision: 1.2.4.1 $
- * $Date: 1997/11/14 16:05:39 $
- *
- *      This file contains the code to support formatting of floppy
- *      tape cartridges with the QIC-40/80/3010/3020 floppy-tape
- *      driver "ftape" for Linux.
- */
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-format.h"
-
-#if defined(TESTING)
-#define FT_FMT_SEGS_PER_BUF 50
-#else
-#define FT_FMT_SEGS_PER_BUF (FT_BUFF_SIZE/(4*FT_SECTORS_PER_SEGMENT))
-#endif
-
-static spinlock_t ftape_format_lock;
-
-/*
- *  first segment of the new buffer
- */
-static int switch_segment;
-
-/*
- *  at most 256 segments fit into one 32 kb buffer.  Even TR-1 cartridges have
- *  more than this many segments per track, so better be careful.
- *
- *  buffer_struct *buff: buffer to store the formatting coordinates in
- *  int  start: starting segment for this buffer.
- *  int    spt: segments per track
- *
- *  Note: segment ids are relative to the start of the track here.
- */
-static void setup_format_buffer(buffer_struct *buff, int start, int spt,
-                               __u8 gap3)
-{
-       int to_do = spt - start;
-       TRACE_FUN(ft_t_flow);
-
-       if (to_do > FT_FMT_SEGS_PER_BUF) {
-               to_do = FT_FMT_SEGS_PER_BUF;
-       }
-       buff->ptr          = buff->address;
-       buff->remaining    = to_do * FT_SECTORS_PER_SEGMENT; /* # sectors */
-       buff->bytes        = buff->remaining * 4; /* need 4 bytes per sector */
-       buff->gap3         = gap3;
-       buff->segment_id   = start;
-       buff->next_segment = start + to_do;
-       if (buff->next_segment >= spt) {
-               buff->next_segment = 0; /* 0 means: stop runner */
-       }
-       buff->status       = waiting; /* tells the isr that it can use
-                                      * this buffer
-                                      */
-       TRACE_EXIT;
-}
-
-
-/*
- *  start formatting a new track.
- */
-int ftape_format_track(const unsigned int track, const __u8 gap3)
-{
-       unsigned long flags;
-       buffer_struct *tail, *head;
-       int status;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
-       if (track & 1) {
-               if (!(status & QIC_STATUS_AT_EOT)) {
-                       TRACE_CATCH(ftape_seek_to_eot(),);
-               }
-       } else {
-               if (!(status & QIC_STATUS_AT_BOT)) {
-                       TRACE_CATCH(ftape_seek_to_bot(),);
-               }
-       }
-       ftape_abort_operation(); /* this sets ft_head = ft_tail = 0 */
-       ftape_set_state(formatting);
-
-       TRACE(ft_t_noise,
-             "Formatting track %d, logical: from segment %d to %d",
-             track, track * ft_segments_per_track, 
-             (track + 1) * ft_segments_per_track - 1);
-       
-       /*
-        *  initialize the buffer switching protocol for this track
-        */
-       head = ftape_get_buffer(ft_queue_head); /* tape isn't running yet */
-       tail = ftape_get_buffer(ft_queue_tail); /* tape isn't running yet */
-       switch_segment = 0;
-       do {
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               setup_format_buffer(tail, switch_segment,
-                                   ft_segments_per_track, gap3);
-               switch_segment = tail->next_segment;
-       } while ((switch_segment != 0) &&
-                ((tail = ftape_next_buffer(ft_queue_tail)) != head));
-       /* go */
-       head->status = formatting;
-       TRACE_CATCH(ftape_seek_head_to_track(track),);
-       TRACE_CATCH(ftape_command(QIC_LOGICAL_FORWARD),);
-       spin_lock_irqsave(&ftape_format_lock, flags);
-       TRACE_CATCH(fdc_setup_formatting(head), restore_flags(flags));
-       spin_unlock_irqrestore(&ftape_format_lock, flags);
-       TRACE_EXIT 0;
-}
-
-/*   return segment id of segment currently being formatted and do the
- *   buffer switching stuff.
- */
-int ftape_format_status(unsigned int *segment_id)
-{
-       buffer_struct *tail = ftape_get_buffer(ft_queue_tail);
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       while (switch_segment != 0 &&
-              ftape_get_buffer(ft_queue_head) != tail) {
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               /*  need more buffers, first wait for empty buffer
-                */
-               TRACE_CATCH(ftape_wait_segment(formatting),);
-               /*  don't worry for gap3. If we ever hit this piece of code,
-                *  then all buffer already have the correct gap3 set!
-                */
-               setup_format_buffer(tail, switch_segment,
-                                   ft_segments_per_track, tail->gap3);
-               switch_segment = tail->next_segment;
-               if (switch_segment != 0) {
-                       tail = ftape_next_buffer(ft_queue_tail);
-               }
-       }
-       /*    should runner stop ?
-        */
-       if (ft_runner_status == aborting || ft_runner_status == do_abort) {
-               buffer_struct *head = ftape_get_buffer(ft_queue_head);
-               TRACE(ft_t_warn, "Error formatting segment %d",
-                     ftape_get_buffer(ft_queue_head)->segment_id);
-               (void)ftape_abort_operation();
-               TRACE_EXIT (head->status != error) ? -EAGAIN : -EIO;
-       }
-       /*
-        *  don't care if the timer expires, this is just kind of a
-        *  "select" operation that lets the calling process sleep
-        *  until something has happened
-        */
-       if (fdc_interrupt_wait(5 * FT_SECOND) < 0) {
-               TRACE(ft_t_noise, "End of track %d at segment %d",
-                     ft_location.track,
-                     ftape_get_buffer(ft_queue_head)->segment_id);
-               result = 1;  /* end of track, unlock module */
-       } else {
-               result = 0;
-       }
-       /*
-        *  the calling process should use the seg id to determine
-        *  which parts of the dma buffers can be safely overwritten
-        *  with new data.
-        */
-       *segment_id = ftape_get_buffer(ft_queue_head)->segment_id;
-       /*
-        *  Internally we start counting segment ids from the start of
-        *  each track when formatting, but externally we keep them
-        *  relative to the start of the tape:
-        */
-       *segment_id += ft_location.track * ft_segments_per_track;
-       TRACE_EXIT result;
-}
-
-/*
- *  The segment id is relative to the start of the tape
- */
-int ftape_verify_segment(const unsigned int segment_id, SectorMap *bsm)
-{
-       int result;
-       int verify_done = 0;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "Verifying segment %d", segment_id);
-
-       if (ft_driver_state != verifying) {
-               TRACE(ft_t_noise, "calling ftape_abort_operation");
-               if (ftape_abort_operation() < 0) {
-                       TRACE(ft_t_err, "ftape_abort_operation failed");
-                       TRACE_EXIT -EIO;
-               }
-       }
-       *bsm = 0x00000000;
-       ftape_set_state(verifying);
-       for (;;) {
-               buffer_struct *tail;
-               /*
-                *  Allow escape from this loop on signal
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               /*
-                *  Search all full buffers for the first matching the
-                *  wanted segment.  Clear other buffers on the fly.
-                */
-               tail = ftape_get_buffer(ft_queue_tail);
-               while (!verify_done && tail->status == done) {
-                       /*
-                        *  Allow escape from this loop on signal !
-                        */
-                       FT_SIGNAL_EXIT(_DONT_BLOCK);
-                       if (tail->segment_id == segment_id) {
-                               /*  If out buffer is already full,
-                                *  return its contents.  
-                                */
-                               TRACE(ft_t_flow, "found segment in cache: %d",
-                                     segment_id);
-                               if ((tail->soft_error_map |
-                                    tail->hard_error_map) != 0) {
-                                       TRACE(ft_t_info,"bsm[%d] = 0x%08lx",
-                                             segment_id,
-                                             (unsigned long)
-                                             (tail->soft_error_map |
-                                             tail->hard_error_map));
-                                       *bsm = (tail->soft_error_map |
-                                               tail->hard_error_map);
-                               }
-                               verify_done = 1;
-                       } else {
-                               TRACE(ft_t_flow,"zapping segment in cache: %d",
-                                     tail->segment_id);
-                       }
-                       tail->status = waiting;
-                       tail = ftape_next_buffer(ft_queue_tail);
-               }
-               if (!verify_done && tail->status == verifying) {
-                       if (tail->segment_id == segment_id) {
-                               switch(ftape_wait_segment(verifying)) {
-                               case 0:
-                                       break;
-                               case -EINTR:
-                                       TRACE_ABORT(-EINTR, ft_t_warn,
-                                                   "interrupted by "
-                                                   "non-blockable signal");
-                                       break;
-                               default:
-                                       ftape_abort_operation();
-                                       ftape_set_state(verifying);
-                                       /* be picky */
-                                       TRACE_ABORT(-EIO, ft_t_warn,
-                                                   "wait_segment failed");
-                               }
-                       } else {
-                               /*  We're reading the wrong segment,
-                                *  stop runner.
-                                */
-                               TRACE(ft_t_noise, "verifying wrong segment");
-                               ftape_abort_operation();
-                               ftape_set_state(verifying);
-                       }
-               }
-               /*    should runner stop ?
-                */
-               if (ft_runner_status == aborting) {
-                       buffer_struct *head = ftape_get_buffer(ft_queue_head);
-                       if (head->status == error ||
-                           head->status == verifying) {
-                               /* no data or overrun error */
-                               head->status = waiting;
-                       }
-                       TRACE_CATCH(ftape_dumb_stop(),);
-               } else {
-                       /*  If just passed last segment on tape: wait
-                        *  for BOT or EOT mark. Sets ft_runner_status to
-                        *  idle if at lEOT and successful 
-                        */
-                       TRACE_CATCH(ftape_handle_logical_eot(),);
-               }
-               if (verify_done) {
-                       TRACE_EXIT 0;
-               }
-               /*    Now at least one buffer is idle!
-                *    Restart runner & tape if needed.
-                */
-               /*  We could optimize the following a little bit. We know that 
-                *  the bad sector map is empty.
-                */
-               tail = ftape_get_buffer(ft_queue_tail);
-               if (tail->status == waiting) {
-                       buffer_struct *head = ftape_get_buffer(ft_queue_head);
-
-                       ftape_setup_new_segment(head, segment_id, -1);
-                       ftape_calc_next_cluster(head);
-                       if (ft_runner_status == idle) {
-                               result = ftape_start_tape(segment_id,
-                                                         head->sector_offset);
-                               switch(result) {
-                               case 0:
-                                       break;
-                               case -ETIME:
-                               case -EINTR:
-                                       TRACE_ABORT(result, ft_t_err, "Error: "
-                                                   "segment %d unreachable",
-                                                   segment_id);
-                                       break;
-                               default:
-                                       *bsm = EMPTY_SEGMENT;
-                                       TRACE_EXIT 0;
-                                       break;
-                               }
-                       }
-                       head->status = verifying;
-                       fdc_setup_read_write(head, FDC_VERIFY);
-               }
-       }
-       /* not reached */
-       TRACE_EXIT -EIO;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-format.h b/drivers/char/ftape/lowlevel/ftape-format.h
deleted file mode 100644 (file)
index f151615..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _FTAPE_FORMAT_H
-#define _FTAPE_FORMAT_H
-
-/*
- * Copyright (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-format.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:13 $
- *
- *      This file contains the low level definitions for the
- *      formatting support for the QIC-40/80/3010/3020 floppy-tape
- *      driver "ftape" for Linux.
- */
-
-#ifdef __KERNEL__
-extern int ftape_format_track(const unsigned int track, const __u8 gap3);
-extern int ftape_format_status(unsigned int *segment_id);
-extern int ftape_verify_segment(const unsigned int segment_id, SectorMap *bsm);
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c
deleted file mode 100644 (file)
index 4998132..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven,
- *                (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- *      This file contains the code that interfaces the kernel
- *      for the QIC-40/80/3010/3020 floppy-tape driver for Linux.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/major.h>
-
-#include <linux/ftape.h>
-#include <linux/init.h>
-#include <linux/qic117.h>
-#ifdef CONFIG_ZFTAPE
-#include <linux/zftape.h>
-#endif
-
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-buffer.h"
-#include "../lowlevel/ftape-proc.h"
-#include "../lowlevel/ftape-tracing.h"
-
-
-#if defined(MODULE) && !defined(CONFIG_FT_NO_TRACE_AT_ALL)
-static int ft_tracing = -1;
-#endif
-
-
-/*  Called by modules package when installing the driver
- *  or by kernel during the initialization phase
- */
-static int __init ftape_init(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-#ifdef MODULE
-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
-       if (ft_tracing != -1) {
-               ftape_tracing = ft_tracing;
-       }
-#endif
-       printk(KERN_INFO FTAPE_VERSION "\n");
-        if (TRACE_LEVEL >= ft_t_info) {
-               printk(
-KERN_INFO "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl)\n"
-KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n"
-KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n");
-        }
-#else /* !MODULE */
-       /* print a short no-nonsense boot message */
-       printk(KERN_INFO FTAPE_VERSION "\n");
-#endif /* MODULE */
-       TRACE(ft_t_info, "installing QIC-117 floppy tape hardware drive ... ");
-       TRACE(ft_t_info, "ftape_init @ 0x%p", ftape_init);
-       /*  Allocate the DMA buffers. They are deallocated at cleanup() time.
-        */
-#ifdef TESTING
-#ifdef MODULE
-       while (ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS) < 0) {
-               ftape_sleep(FT_SECOND/20);
-               if (signal_pending(current)) {
-                       (void)ftape_set_nr_buffers(0);
-                       TRACE(ft_t_bug,
-                             "Killed by signal while allocating buffers.");
-                       TRACE_ABORT(-EINTR, 
-                                   ft_t_bug, "Free up memory and retry");
-               }
-       }
-#else
-       TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS),
-                   (void)ftape_set_nr_buffers(0));
-#endif
-#else
-       TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS),
-                   (void)ftape_set_nr_buffers(0));
-#endif
-       ft_drive_sel = -1;
-       ft_failure   = 1;         /* inhibit any operation but open */
-       ftape_udelay_calibrate(); /* must be before fdc_wait_calibrate ! */
-       fdc_wait_calibrate();
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
-       (void)ftape_proc_init();
-#endif
-#ifdef CONFIG_ZFTAPE
-       (void)zft_init();
-#endif
-       TRACE_EXIT 0;
-}
-
-module_param(ft_fdc_base,       uint, 0);
-MODULE_PARM_DESC(ft_fdc_base,  "Base address of FDC controller.");
-module_param(ft_fdc_irq,        uint, 0);
-MODULE_PARM_DESC(ft_fdc_irq,   "IRQ (interrupt channel) to use.");
-module_param(ft_fdc_dma,        uint, 0);
-MODULE_PARM_DESC(ft_fdc_dma,   "DMA channel to use.");
-module_param(ft_fdc_threshold,  uint, 0);
-MODULE_PARM_DESC(ft_fdc_threshold,  "Threshold of the FDC Fifo.");
-module_param(ft_fdc_rate_limit, uint, 0);
-MODULE_PARM_DESC(ft_fdc_rate_limit, "Maximal data rate for FDC.");
-module_param(ft_probe_fc10,     bool, 0);
-MODULE_PARM_DESC(ft_probe_fc10,
-           "If non-zero, probe for a Colorado FC-10/FC-20 controller.");
-module_param(ft_mach2,          bool, 0);
-MODULE_PARM_DESC(ft_mach2,
-           "If non-zero, probe for a Mountain MACH-2 controller.");
-#if defined(MODULE) && !defined(CONFIG_FT_NO_TRACE_AT_ALL)
-module_param(ft_tracing,        int, 0644);
-MODULE_PARM_DESC(ft_tracing,
-           "Amount of debugging output, 0 <= tracing <= 8, default 3.");
-#endif
-
-MODULE_AUTHOR(
-       "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl), "
-       "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no), "
-       "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)");
-MODULE_DESCRIPTION(
-       "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives.");
-MODULE_LICENSE("GPL");
-
-static void __exit ftape_exit(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
-       ftape_proc_destroy();
-#endif
-       (void)ftape_set_nr_buffers(0);
-        printk(KERN_INFO "ftape: unloaded.\n");
-       TRACE_EXIT;
-}
-
-module_init(ftape_init);
-module_exit(ftape_exit);
diff --git a/drivers/char/ftape/lowlevel/ftape-init.h b/drivers/char/ftape/lowlevel/ftape-init.h
deleted file mode 100644 (file)
index 99a7b8a..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _FTAPE_INIT_H
-#define _FTAPE_INIT_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-init.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:16 $
- *
- * This file contains the definitions for the interface to 
- * the Linux kernel for floppy tape driver ftape.
- *
- */
-
-#include <linux/linkage.h>
-#include <linux/signal.h>
-
-#define _NEVER_BLOCK    (sigmask(SIGKILL) | sigmask(SIGSTOP))
-#define _DONT_BLOCK     (_NEVER_BLOCK | sigmask(SIGINT))
-#define _DO_BLOCK       (sigmask(SIGPIPE))
-
-#ifndef QIC117_TAPE_MAJOR
-#define QIC117_TAPE_MAJOR 27
-#endif
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-io.c b/drivers/char/ftape/lowlevel/ftape-io.c
deleted file mode 100644 (file)
index 259015a..0000000
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven,
- *                (C) 1996      Kai Harrekilde-Petersen,
- *                (C) 1997      Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.c,v $
- * $Revision: 1.4 $
- * $Date: 1997/11/11 14:02:36 $
- *
- *      This file contains the general control functions for the
- *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/system.h>
-#include <linux/ioctl.h>
-#include <linux/mtio.h>
-#include <linux/delay.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-calibr.h"
-
-/*      Global vars.
- */
-/* NOTE: sectors start numbering at 1, all others at 0 ! */
-ft_timeout_table ftape_timeout;
-unsigned int ftape_tape_len;
-volatile qic117_cmd_t ftape_current_command;
-const struct qic117_command_table qic117_cmds[] = QIC117_COMMANDS;
-int ftape_might_be_off_track;
-
-/*      Local vars.
- */
-static int diagnostic_mode;
-static unsigned int ftape_udelay_count;
-static unsigned int ftape_udelay_time;
-
-void ftape_udelay(unsigned int usecs)
-{
-       volatile int count = (ftape_udelay_count * usecs +
-                              ftape_udelay_count - 1) / ftape_udelay_time;
-       volatile int i;
-
-       while (count-- > 0) {
-               for (i = 0; i < 20; ++i);
-       }
-}
-
-void ftape_udelay_calibrate(void)
-{
-       ftape_calibrate("ftape_udelay",
-                       ftape_udelay, &ftape_udelay_count, &ftape_udelay_time);
-}
-
-/*      Delay (msec) routine.
- */
-void ftape_sleep(unsigned int time)
-{
-       TRACE_FUN(ft_t_any);
-
-       time *= 1000;   /* msecs -> usecs */
-       if (time < FT_USPT) {
-               /*  Time too small for scheduler, do a busy wait ! */
-               ftape_udelay(time);
-       } else {
-               long timeout;
-               unsigned long flags;
-               unsigned int ticks = (time + FT_USPT - 1) / FT_USPT;
-
-               TRACE(ft_t_any, "%d msec, %d ticks", time/1000, ticks);
-               timeout = ticks;
-               save_flags(flags);
-               sti();
-               msleep_interruptible(jiffies_to_msecs(timeout));
-               /*  Mmm. Isn't current->blocked == 0xffffffff ?
-                */
-               if (signal_pending(current)) {
-                       TRACE(ft_t_err, "awoken by non-blocked signal :-(");
-               }
-               restore_flags(flags);
-       }
-       TRACE_EXIT;
-}
-
-/*  send a command or parameter to the drive
- *  Generates # of step pulses.
- */
-static inline int ft_send_to_drive(int arg)
-{
-       /*  Always wait for a command_timeout period to separate
-        *  individuals commands and/or parameters.
-        */
-       ftape_sleep(3 * FT_MILLISECOND);
-       /*  Keep cylinder nr within range, step towards home if possible.
-        */
-       if (ftape_current_cylinder >= arg) {
-               return fdc_seek(ftape_current_cylinder - arg);
-       } else {
-               return fdc_seek(ftape_current_cylinder + arg);
-       }
-}
-
-/* forward */ int ftape_report_raw_drive_status(int *status);
-
-static int ft_check_cmd_restrictions(qic117_cmd_t command)
-{
-       int status = -1;
-       TRACE_FUN(ft_t_any);
-       
-       TRACE(ft_t_flow, "%s", qic117_cmds[command].name);
-       /* A new motion command during an uninterruptible (motion)
-        *  command requires a ready status before the new command can
-        *  be issued. Otherwise a new motion command needs to be
-        *  checked against required status.
-        */
-       if (qic117_cmds[command].cmd_type == motion &&
-           qic117_cmds[ftape_current_command].non_intr) {
-               ftape_report_raw_drive_status(&status);
-               if ((status & QIC_STATUS_READY) == 0) {
-                       TRACE(ft_t_noise,
-                             "motion cmd (%d) during non-intr cmd (%d)",
-                             command, ftape_current_command);
-                       TRACE(ft_t_noise, "waiting until drive gets ready");
-                       ftape_ready_wait(ftape_timeout.seek,
-                                        &status);
-               }
-       }
-       if (qic117_cmds[command].mask != 0) {
-               __u8 difference;
-               /*  Some commands do require a certain status:
-                */
-               if (status == -1) {     /* not yet set */
-                       ftape_report_raw_drive_status(&status);
-               }
-               difference = ((status ^ qic117_cmds[command].state) &
-                             qic117_cmds[command].mask);
-               /*  Wait until the drive gets
-                *  ready. This may last forever if
-                *  the drive never gets ready... 
-                */
-               while ((difference & QIC_STATUS_READY) != 0) {
-                       TRACE(ft_t_noise, "command %d issued while not ready",
-                             command);
-                       TRACE(ft_t_noise, "waiting until drive gets ready");
-                       if (ftape_ready_wait(ftape_timeout.seek,
-                                            &status) == -EINTR) {
-                               /*  Bail out on signal !
-                                */
-                               TRACE_ABORT(-EINTR, ft_t_warn,
-                                     "interrupted by non-blockable signal");
-                       }
-                       difference = ((status ^ qic117_cmds[command].state) &
-                                     qic117_cmds[command].mask);
-               }
-               while ((difference & QIC_STATUS_ERROR) != 0) {
-                       int err;
-                       qic117_cmd_t cmd;
-
-                       TRACE(ft_t_noise,
-                             "command %d issued while error pending",
-                             command);
-                       TRACE(ft_t_noise, "clearing error status");
-                       ftape_report_error(&err, &cmd, 1);
-                       ftape_report_raw_drive_status(&status);
-                       difference = ((status ^ qic117_cmds[command].state) &
-                                     qic117_cmds[command].mask);
-                       if ((difference & QIC_STATUS_ERROR) != 0) {
-                               /*  Bail out on fatal signal !
-                                */
-                               FT_SIGNAL_EXIT(_NEVER_BLOCK);
-                       }
-               }
-               if (difference) {
-                       /*  Any remaining difference can't be solved
-                        *  here.  
-                        */
-                       if (difference & (QIC_STATUS_CARTRIDGE_PRESENT |
-                                         QIC_STATUS_NEW_CARTRIDGE |
-                                         QIC_STATUS_REFERENCED)) {
-                               TRACE(ft_t_warn,
-                                     "Fatal: tape removed or reinserted !");
-                               ft_failure = 1;
-                       } else {
-                               TRACE(ft_t_err, "wrong state: 0x%02x should be: 0x%02x",
-                                     status & qic117_cmds[command].mask,
-                                     qic117_cmds[command].state);
-                       }
-                       TRACE_EXIT -EIO;
-               }
-               if (~status & QIC_STATUS_READY & qic117_cmds[command].mask) {
-                       TRACE_ABORT(-EBUSY, ft_t_err, "Bad: still busy!");
-               }
-       }
-       TRACE_EXIT 0;
-}
-
-/*      Issue a tape command:
- */
-int ftape_command(qic117_cmd_t command)
-{
-       int result = 0;
-       static int level;
-       TRACE_FUN(ft_t_any);
-
-       if ((unsigned int)command > NR_ITEMS(qic117_cmds)) {
-               /*  This is a bug we'll want to know about too.
-                */
-               TRACE_ABORT(-EIO, ft_t_bug, "bug - bad command: %d", command);
-       }
-       if (++level > 5) { /*  This is a bug we'll want to know about. */
-               --level;
-               TRACE_ABORT(-EIO, ft_t_bug, "bug - recursion for command: %d",
-                           command);
-       }
-       /*  disable logging and restriction check for some commands,
-        *  check all other commands that have a prescribed starting
-        *  status.
-        */
-       if (diagnostic_mode) {
-               TRACE(ft_t_flow, "diagnostic command %d", command);
-       } else if (command == QIC_REPORT_DRIVE_STATUS ||
-                  command == QIC_REPORT_NEXT_BIT) {
-               TRACE(ft_t_any, "%s", qic117_cmds[command].name);
-       } else {
-               TRACE_CATCH(ft_check_cmd_restrictions(command), --level);
-       }
-       /*  Now all conditions are met or result was < 0.
-        */
-       result = ft_send_to_drive((unsigned int)command);
-       if (qic117_cmds[command].cmd_type == motion &&
-           command != QIC_LOGICAL_FORWARD && command != QIC_STOP_TAPE) {
-               ft_location.known = 0;
-       }
-       ftape_current_command = command;
-       --level;
-       TRACE_EXIT result;
-}
-
-/*      Send a tape command parameter:
- *      Generates command # of step pulses.
- *      Skips tape-status call !
- */
-int ftape_parameter(unsigned int parameter)
-{
-       TRACE_FUN(ft_t_any);
-
-       TRACE(ft_t_flow, "called with parameter = %d", parameter);
-       TRACE_EXIT ft_send_to_drive(parameter + 2);
-}
-
-/*      Wait for the drive to get ready.
- *      timeout time in milli-seconds
- *      Returned status is valid if result != -EIO
- *
- *      Should we allow to be killed by SIGINT?  (^C)
- *      Would be nice at least for large timeouts.
- */
-int ftape_ready_wait(unsigned int timeout, int *status)
-{
-       unsigned long t0;
-       unsigned int poll_delay;
-       int signal_retries;
-       TRACE_FUN(ft_t_any);
-
-       /*  the following ** REALLY ** reduces the system load when
-        *  e.g. one simply rewinds or retensions. The tape is slow 
-        *  anyway. It is really not necessary to detect error 
-        *  conditions with 1/10 seconds granularity
-        *
-        *  On my AMD 133MHZ 486: 100 ms: 23% system load
-        *                        1  sec:  5%
-        *                        5  sec:  0.6%, yeah
-        */
-       if (timeout <= FT_SECOND) {
-               poll_delay = 100 * FT_MILLISECOND;
-               signal_retries = 20; /* two seconds */
-       } else if (timeout < 20 * FT_SECOND) {
-               TRACE(ft_t_flow, "setting poll delay to 1 second");
-               poll_delay = FT_SECOND;
-               signal_retries = 2; /* two seconds */
-       } else {
-               TRACE(ft_t_flow, "setting poll delay to 5 seconds");
-               poll_delay = 5 * FT_SECOND;
-               signal_retries = 1; /* five seconds */
-       }
-       for (;;) {
-               t0 = jiffies;
-               TRACE_CATCH(ftape_report_raw_drive_status(status),);
-               if (*status & QIC_STATUS_READY) {
-                       TRACE_EXIT 0;
-               }
-               if (!signal_retries--) {
-                       FT_SIGNAL_EXIT(_NEVER_BLOCK);
-               }
-               if ((int)timeout >= 0) {
-                       /* this will fail when jiffies wraps around about
-                        * once every year :-)
-                        */
-                       timeout -= ((jiffies - t0) * FT_SECOND) / HZ;
-                       if (timeout <= 0) {
-                               TRACE_ABORT(-ETIME, ft_t_err, "timeout");
-                       }
-                       ftape_sleep(poll_delay);
-                       timeout -= poll_delay;
-               } else {
-                       ftape_sleep(poll_delay);
-               }
-       }
-       TRACE_EXIT -ETIME;
-}
-
-/*      Issue command and wait up to timeout milli seconds for drive ready
- */
-int ftape_command_wait(qic117_cmd_t command, unsigned int timeout, int *status)
-{
-       int result;
-
-       /* Drive should be ready, issue command
-        */
-       result = ftape_command(command);
-       if (result >= 0) {
-               result = ftape_ready_wait(timeout, status);
-       }
-       return result;
-}
-
-static int ftape_parameter_wait(unsigned int parm, unsigned int timeout, int *status)
-{
-       int result;
-
-       /* Drive should be ready, issue command
-        */
-       result = ftape_parameter(parm);
-       if (result >= 0) {
-               result = ftape_ready_wait(timeout, status);
-       }
-       return result;
-}
-
-/*--------------------------------------------------------------------------
- *      Report operations
- */
-
-/* Query the drive about its status.  The command is sent and
-   result_length bits of status are returned (2 extra bits are read
-   for start and stop). */
-
-int ftape_report_operation(int *status,
-                          qic117_cmd_t command,
-                          int result_length)
-{
-       int i, st3;
-       unsigned int t0;
-       unsigned int dt;
-       TRACE_FUN(ft_t_any);
-
-       TRACE_CATCH(ftape_command(command),);
-       t0 = ftape_timestamp();
-       i = 0;
-       do {
-               ++i;
-               ftape_sleep(3 * FT_MILLISECOND);        /* see remark below */
-               TRACE_CATCH(fdc_sense_drive_status(&st3),);
-               dt = ftape_timediff(t0, ftape_timestamp());
-               /*  Ack should be asserted within Ttimout + Tack = 6 msec.
-                *  Looks like some drives fail to do this so extend this
-                *  period to 300 msec.
-                */
-       } while (!(st3 & ST3_TRACK_0) && dt < 300000);
-       if (!(st3 & ST3_TRACK_0)) {
-               TRACE(ft_t_err,
-                     "No acknowledge after %u msec. (%i iter)", dt / 1000, i);
-               TRACE_ABORT(-EIO, ft_t_err, "timeout on Acknowledge");
-       }
-       /*  dt may be larger than expected because of other tasks
-        *  scheduled while we were sleeping.
-        */
-       if (i > 1 && dt > 6000) {
-               TRACE(ft_t_err, "Acknowledge after %u msec. (%i iter)",
-                     dt / 1000, i);
-       }
-       *status = 0;
-       for (i = 0; i < result_length + 1; i++) {
-               TRACE_CATCH(ftape_command(QIC_REPORT_NEXT_BIT),);
-               TRACE_CATCH(fdc_sense_drive_status(&st3),);
-               if (i < result_length) {
-                       *status |= ((st3 & ST3_TRACK_0) ? 1 : 0) << i;
-               } else if ((st3 & ST3_TRACK_0) == 0) {
-                       TRACE_ABORT(-EIO, ft_t_err, "missing status stop bit");
-               }
-       }
-       /* this command will put track zero and index back into normal state */
-       (void)ftape_command(QIC_REPORT_NEXT_BIT);
-       TRACE_EXIT 0;
-}
-
-/* Report the current drive status. */
-
-int ftape_report_raw_drive_status(int *status)
-{
-       int result;
-       int count = 0;
-       TRACE_FUN(ft_t_any);
-
-       do {
-               result = ftape_report_operation(status,
-                                               QIC_REPORT_DRIVE_STATUS, 8);
-       } while (result < 0 && ++count <= 3);
-       if (result < 0) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "report_operation failed after %d trials", count);
-       }
-       if ((*status & 0xff) == 0xff) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "impossible drive status 0xff");
-       }
-       if (*status & QIC_STATUS_READY) {
-               ftape_current_command = QIC_NO_COMMAND; /* completed */
-       }
-       ft_last_status.status.drive_status = (__u8)(*status & 0xff);
-       TRACE_EXIT 0;
-}
-
-int ftape_report_drive_status(int *status)
-{
-       TRACE_FUN(ft_t_any);
-
-       TRACE_CATCH(ftape_report_raw_drive_status(status),);
-       if (*status & QIC_STATUS_NEW_CARTRIDGE ||
-           !(*status & QIC_STATUS_CARTRIDGE_PRESENT)) {
-               ft_failure = 1; /* will inhibit further operations */
-               TRACE_EXIT -EIO;
-       }
-       if (*status & QIC_STATUS_READY && *status & QIC_STATUS_ERROR) {
-               /*  Let caller handle all errors */
-               TRACE_ABORT(1, ft_t_warn, "warning: error status set!");
-       }
-       TRACE_EXIT 0;
-}
-
-int ftape_report_error(unsigned int *error,
-                      qic117_cmd_t *command, int report)
-{
-       static const ftape_error ftape_errors[] = QIC117_ERRORS;
-       int code;
-       TRACE_FUN(ft_t_any);
-
-       TRACE_CATCH(ftape_report_operation(&code, QIC_REPORT_ERROR_CODE, 16),);
-       *error   = (unsigned int)(code & 0xff);
-       *command = (qic117_cmd_t)((code>>8)&0xff);
-       /*  remember hardware status, maybe useful for status ioctls
-        */
-       ft_last_error.error.command = (__u8)*command;
-       ft_last_error.error.error   = (__u8)*error;
-       if (!report) {
-               TRACE_EXIT 0;
-       }
-       if (*error == 0) {
-               TRACE_ABORT(0, ft_t_info, "No error");
-       }
-       TRACE(ft_t_info, "errorcode: %d", *error);
-       if (*error < NR_ITEMS(ftape_errors)) {
-               TRACE(ft_t_noise, "%sFatal ERROR:",
-                     (ftape_errors[*error].fatal ? "" : "Non-"));
-               TRACE(ft_t_noise, "%s ...", ftape_errors[*error].message);
-       } else {
-               TRACE(ft_t_noise, "Unknown ERROR !");
-       }
-       if ((unsigned int)*command < NR_ITEMS(qic117_cmds) &&
-           qic117_cmds[*command].name != NULL) {
-               TRACE(ft_t_noise, "... caused by command \'%s\'",
-                     qic117_cmds[*command].name);
-       } else {
-               TRACE(ft_t_noise, "... caused by unknown command %d",
-                     *command);
-       }
-       TRACE_EXIT 0;
-}
-
-int ftape_report_configuration(qic_model *model,
-                              unsigned int *rate,
-                              int *qic_std,
-                              int *tape_len)
-{
-       int result;
-       int config;
-       int status;
-       static const unsigned int qic_rates[ 4] = { 250, 2000, 500, 1000 };
-       TRACE_FUN(ft_t_any);
-
-       result = ftape_report_operation(&config,
-                                       QIC_REPORT_DRIVE_CONFIGURATION, 8);
-       if (result < 0) {
-               ft_last_status.status.drive_config = (__u8)0x00;
-               *model = prehistoric;
-               *rate = 500;
-               *qic_std = QIC_TAPE_QIC40;
-               *tape_len = 205;
-               TRACE_EXIT 0;
-       } else {
-               ft_last_status.status.drive_config = (__u8)(config & 0xff);
-       }
-       *rate = qic_rates[(config & QIC_CONFIG_RATE_MASK) >> QIC_CONFIG_RATE_SHIFT];
-       result = ftape_report_operation(&status, QIC_REPORT_TAPE_STATUS, 8);
-       if (result < 0) {
-               ft_last_status.status.tape_status = (__u8)0x00;
-               /* pre- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is valid.
-                */
-               *qic_std = (config & QIC_CONFIG_80) ?
-                       QIC_TAPE_QIC80 : QIC_TAPE_QIC40;
-               /* ?? how's about 425ft tapes? */
-               *tape_len = (config & QIC_CONFIG_LONG) ? 307 : 0;
-               *model = pre_qic117c;
-               result = 0;
-       } else {
-               ft_last_status.status.tape_status = (__u8)(status & 0xff);
-               *model = post_qic117b;
-               TRACE(ft_t_any, "report tape status result = %02x", status);
-               /* post- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is
-                * invalid. 
-                */
-               switch (status & QIC_TAPE_STD_MASK) {
-               case QIC_TAPE_QIC40:
-               case QIC_TAPE_QIC80:
-               case QIC_TAPE_QIC3020:
-               case QIC_TAPE_QIC3010:
-                       *qic_std = status & QIC_TAPE_STD_MASK;
-                       break;
-               default:
-                       *qic_std = -1;
-                       break;
-               }
-               switch (status & QIC_TAPE_LEN_MASK) {
-               case QIC_TAPE_205FT:
-                       /* 205 or 425+ ft 550 Oe tape */
-                       *tape_len = 0;
-                       break;
-               case QIC_TAPE_307FT:
-                       /* 307.5 ft 550 Oe Extended Length (XL) tape */
-                       *tape_len = 307;
-                       break;
-               case QIC_TAPE_VARIABLE:
-                       /* Variable length 550 Oe tape */
-                       *tape_len = 0;
-                       break;
-               case QIC_TAPE_1100FT:
-                       /* 1100 ft 550 Oe tape */
-                       *tape_len = 1100;
-                       break;
-               case QIC_TAPE_FLEX:
-                       /* Variable length 900 Oe tape */
-                       *tape_len = 0;
-                       break;
-               default:
-                       *tape_len = -1;
-                       break;
-               }
-               if (*qic_std == -1 || *tape_len == -1) {
-                       TRACE(ft_t_any,
-                             "post qic-117b spec drive with unknown tape");
-               }
-               result = *tape_len == -1 ? -EIO : 0;
-               if (status & QIC_TAPE_WIDE) {
-                       switch (*qic_std) {
-                       case QIC_TAPE_QIC80:
-                               TRACE(ft_t_info, "TR-1 tape detected");
-                               break;
-                       case QIC_TAPE_QIC3010:
-                               TRACE(ft_t_info, "TR-2 tape detected");
-                               break;
-                       case QIC_TAPE_QIC3020:
-                               TRACE(ft_t_info, "TR-3 tape detected");
-                               break;
-                       default:
-                               TRACE(ft_t_warn,
-                                     "Unknown Travan tape type detected");
-                               break;
-                       }
-               }
-       }
-       TRACE_EXIT (result < 0) ? -EIO : 0;
-}
-
-static int ftape_report_rom_version(int *version)
-{
-
-       if (ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8) < 0) {
-               return -EIO;
-       } else {
-               return 0;
-       }
-}
-
-void ftape_report_vendor_id(unsigned int *id)
-{
-       int result;
-       TRACE_FUN(ft_t_any);
-
-       /* We'll try to get a vendor id from the drive.  First
-        * according to the QIC-117 spec, a 16-bit id is requested.
-        * If that fails we'll try an 8-bit version, otherwise we'll
-        * try an undocumented query.
-        */
-       result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 16);
-       if (result < 0) {
-               result = ftape_report_operation((int *) id,
-                                               QIC_REPORT_VENDOR_ID, 8);
-               if (result < 0) {
-                       /* The following is an undocumented call found
-                        * in the CMS code.
-                        */
-                       result = ftape_report_operation((int *) id, 24, 8);
-                       if (result < 0) {
-                               *id = UNKNOWN_VENDOR;
-                       } else {
-                               TRACE(ft_t_noise, "got old 8 bit id: %04x",
-                                     *id);
-                               *id |= 0x20000;
-                       }
-               } else {
-                       TRACE(ft_t_noise, "got 8 bit id: %04x", *id);
-                       *id |= 0x10000;
-               }
-       } else {
-               TRACE(ft_t_noise, "got 16 bit id: %04x", *id);
-       }
-       if (*id == 0x0047) {
-               int version;
-               int sign;
-
-               if (ftape_report_rom_version(&version) < 0) {
-                       TRACE(ft_t_bug, "report rom version failed");
-                       TRACE_EXIT;
-               }
-               TRACE(ft_t_noise, "CMS rom version: %d", version);
-               ftape_command(QIC_ENTER_DIAGNOSTIC_1);
-               ftape_command(QIC_ENTER_DIAGNOSTIC_1);
-               diagnostic_mode = 1;
-               if (ftape_report_operation(&sign, 9, 8) < 0) {
-                       unsigned int error;
-                       qic117_cmd_t command;
-
-                       ftape_report_error(&error, &command, 1);
-                       ftape_command(QIC_ENTER_PRIMARY_MODE);
-                       diagnostic_mode = 0;
-                       TRACE_EXIT;     /* failure ! */
-               } else {
-                       TRACE(ft_t_noise, "CMS signature: %02x", sign);
-               }
-               if (sign == 0xa5) {
-                       result = ftape_report_operation(&sign, 37, 8);
-                       if (result < 0) {
-                               if (version >= 63) {
-                                       *id = 0x8880;
-                                       TRACE(ft_t_noise,
-                                             "This is an Iomega drive !");
-                               } else {
-                                       *id = 0x0047;
-                                       TRACE(ft_t_noise,
-                                             "This is a real CMS drive !");
-                               }
-                       } else {
-                               *id = 0x0047;
-                               TRACE(ft_t_noise, "CMS status: %d", sign);
-                       }
-               } else {
-                       *id = UNKNOWN_VENDOR;
-               }
-               ftape_command(QIC_ENTER_PRIMARY_MODE);
-               diagnostic_mode = 0;
-       }
-       TRACE_EXIT;
-}
-
-static int qic_rate_code(unsigned int rate)
-{
-       switch (rate) {
-       case 250:
-               return QIC_CONFIG_RATE_250;
-       case 500:
-               return QIC_CONFIG_RATE_500;
-       case 1000:
-               return QIC_CONFIG_RATE_1000;
-       case 2000:
-               return QIC_CONFIG_RATE_2000;
-       default:
-               return QIC_CONFIG_RATE_500;
-       }
-}
-
-static int ftape_set_rate_test(unsigned int *max_rate)
-{
-       unsigned int error;
-       qic117_cmd_t command;
-       int status;
-       int supported = 0;
-       TRACE_FUN(ft_t_any);
-
-       /*  Check if the drive does support the select rate command
-        *  by testing all different settings. If any one is accepted
-        *  we assume the command is supported, else not.
-        */
-       for (*max_rate = 2000; *max_rate >= 250; *max_rate /= 2) {
-               if (ftape_command(QIC_SELECT_RATE) < 0) {
-                       continue;
-               }               
-               if (ftape_parameter_wait(qic_rate_code(*max_rate),
-                                        1 * FT_SECOND, &status) < 0) {
-                       continue;
-               }
-               if (status & QIC_STATUS_ERROR) {
-                       ftape_report_error(&error, &command, 0);
-                       continue;
-               }
-               supported = 1; /* did accept a request */
-               break;
-       }
-       TRACE(ft_t_noise, "Select Rate command is%s supported", 
-             supported ? "" : " not");
-       TRACE_EXIT supported;
-}
-
-int ftape_set_data_rate(unsigned int new_rate /* Kbps */, unsigned int qic_std)
-{
-       int status;
-       int result = 0;
-       unsigned int data_rate = new_rate;
-       static int supported;
-       int rate_changed = 0;
-       qic_model dummy_model;
-       unsigned int dummy_qic_std, dummy_tape_len;
-       TRACE_FUN(ft_t_any);
-
-       if (ft_drive_max_rate == 0) { /* first time */
-               supported = ftape_set_rate_test(&ft_drive_max_rate);
-       }
-       if (supported) {
-               ftape_command(QIC_SELECT_RATE);
-               result = ftape_parameter_wait(qic_rate_code(new_rate),
-                                             1 * FT_SECOND, &status);
-               if (result >= 0 && !(status & QIC_STATUS_ERROR)) {
-                       rate_changed = 1;
-               }
-       }
-       TRACE_CATCH(result = ftape_report_configuration(&dummy_model,
-                                                       &data_rate, 
-                                                       &dummy_qic_std,
-                                                       &dummy_tape_len),);
-       if (data_rate != new_rate) {
-               if (!supported) {
-                       TRACE(ft_t_warn, "Rate change not supported!");
-               } else if (rate_changed) {
-                       TRACE(ft_t_warn, "Requested: %d, got %d",
-                             new_rate, data_rate);
-               } else {
-                       TRACE(ft_t_warn, "Rate change failed!");
-               }
-               result = -EINVAL;
-       }
-       /*
-        *  Set data rate and write precompensation as specified:
-        *
-        *            |  QIC-40/80  | QIC-3010/3020
-        *   rate     |   precomp   |    precomp
-        *  ----------+-------------+--------------
-        *  250 Kbps. |   250 ns.   |     0 ns.
-        *  500 Kbps. |   125 ns.   |     0 ns.
-        *    1 Mbps. |    42 ns.   |     0 ns.
-        *    2 Mbps  |      N/A    |     0 ns.
-        */
-       if ((qic_std == QIC_TAPE_QIC40 && data_rate > 500) || 
-           (qic_std == QIC_TAPE_QIC80 && data_rate > 1000)) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_warn, "Datarate too high for QIC-mode");
-       }
-       TRACE_CATCH(fdc_set_data_rate(data_rate),_res = -EINVAL);
-       ft_data_rate = data_rate;
-       if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) {
-               switch (data_rate) {
-               case 250:
-                       fdc_set_write_precomp(250);
-                       break;
-               default:
-               case 500:
-                       fdc_set_write_precomp(125);
-                       break;
-               case 1000:
-                       fdc_set_write_precomp(42);
-                       break;
-               }
-       } else {
-               fdc_set_write_precomp(0);
-       }
-       TRACE_EXIT result;
-}
-
-/*  The next two functions are used to cope with excessive overrun errors
- */
-int ftape_increase_threshold(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (fdc.type < i82077 || ft_fdc_threshold >= 12) {
-               TRACE_ABORT(-EIO, ft_t_err, "cannot increase fifo threshold");
-       }
-       if (fdc_fifo_threshold(++ft_fdc_threshold, NULL, NULL, NULL) < 0) {
-               TRACE(ft_t_err, "cannot increase fifo threshold");
-               ft_fdc_threshold --;
-               fdc_reset();
-       }
-       TRACE(ft_t_info, "New FIFO threshold: %d", ft_fdc_threshold);
-       TRACE_EXIT 0;
-}
-
-int ftape_half_data_rate(void)
-{
-       if (ft_data_rate < 500) {
-               return -1;
-       }
-       if (ftape_set_data_rate(ft_data_rate / 2, ft_qic_std) < 0) {
-               return -EIO;
-       }
-       ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
-       return 0;
-}
-
-/*      Seek the head to the specified track.
- */
-int ftape_seek_head_to_track(unsigned int track)
-{
-       int status;
-       TRACE_FUN(ft_t_any);
-
-       ft_location.track = -1; /* remains set in case of error */
-       if (track >= ft_tracks_per_tape) {
-               TRACE_ABORT(-EINVAL, ft_t_bug, "track out of bounds");
-       }
-       TRACE(ft_t_flow, "seeking track %d", track);
-       TRACE_CATCH(ftape_command(QIC_SEEK_HEAD_TO_TRACK),);
-       TRACE_CATCH(ftape_parameter_wait(track, ftape_timeout.head_seek,
-                                        &status),);
-       ft_location.track = track;
-       ftape_might_be_off_track = 0;
-       TRACE_EXIT 0;
-}
-
-int ftape_wakeup_drive(wake_up_types method)
-{
-       int status;
-       int motor_on = 0;
-       TRACE_FUN(ft_t_any);
-
-       switch (method) {
-       case wake_up_colorado:
-               TRACE_CATCH(ftape_command(QIC_PHANTOM_SELECT),);
-               TRACE_CATCH(ftape_parameter(0 /* ft_drive_sel ?? */),);
-               break;
-       case wake_up_mountain:
-               TRACE_CATCH(ftape_command(QIC_SOFT_SELECT),);
-               ftape_sleep(FT_MILLISECOND);    /* NEEDED */
-               TRACE_CATCH(ftape_parameter(18),);
-               break;
-       case wake_up_insight:
-               ftape_sleep(100 * FT_MILLISECOND);
-               motor_on = 1;
-               fdc_motor(motor_on);    /* enable is done by motor-on */
-       case no_wake_up:
-               break;
-       default:
-               TRACE_EXIT -ENODEV;     /* unknown wakeup method */
-               break;
-       }
-       /*  If wakeup succeeded we shouldn't get an error here..
-        */
-       TRACE_CATCH(ftape_report_raw_drive_status(&status),
-                   if (motor_on) {
-                           fdc_motor(0);
-                   });
-       TRACE_EXIT 0;
-}
-
-int ftape_put_drive_to_sleep(wake_up_types method)
-{
-       TRACE_FUN(ft_t_any);
-
-       switch (method) {
-       case wake_up_colorado:
-               TRACE_CATCH(ftape_command(QIC_PHANTOM_DESELECT),);
-               break;
-       case wake_up_mountain:
-               TRACE_CATCH(ftape_command(QIC_SOFT_DESELECT),);
-               break;
-       case wake_up_insight:
-               fdc_motor(0);   /* enable is done by motor-on */
-       case no_wake_up:        /* no wakeup / no sleep ! */
-               break;
-       default:
-               TRACE_EXIT -ENODEV;     /* unknown wakeup method */
-       }
-       TRACE_EXIT 0;
-}
-
-int ftape_reset_drive(void)
-{
-       int result = 0;
-       int status;
-       unsigned int err_code;
-       qic117_cmd_t err_command;
-       int i;
-       TRACE_FUN(ft_t_any);
-
-       /*  We want to re-establish contact with our drive.  Fire a
-        *  number of reset commands (single step pulses) and pray for
-        *  success.
-        */
-       for (i = 0; i < 2; ++i) {
-               TRACE(ft_t_flow, "Resetting fdc");
-               fdc_reset();
-               ftape_sleep(10 * FT_MILLISECOND);
-               TRACE(ft_t_flow, "Reset command to drive");
-               result = ftape_command(QIC_RESET);
-               if (result == 0) {
-                       ftape_sleep(1 * FT_SECOND); /*  drive not
-                                                    *  accessible
-                                                    *  during 1 second
-                                                    */
-                       TRACE(ft_t_flow, "Re-selecting drive");
-
-                       /* Strange, the QIC-117 specs don't mention
-                        * this but the drive gets deselected after a
-                        * soft reset !  So we need to enable it
-                        * again.
-                        */
-                       if (ftape_wakeup_drive(ft_drive_type.wake_up) < 0) {
-                               TRACE(ft_t_err, "Wakeup failed !");
-                       }
-                       TRACE(ft_t_flow, "Waiting until drive gets ready");
-                       result= ftape_ready_wait(ftape_timeout.reset, &status);
-                       if (result == 0 && (status & QIC_STATUS_ERROR)) {
-                               result = ftape_report_error(&err_code,
-                                                           &err_command, 1);
-                               if (result == 0 && err_code == 27) {
-                                       /*  Okay, drive saw reset
-                                        *  command and responded as it
-                                        *  should
-                                        */
-                                       break;
-                               } else {
-                                       result = -EIO;
-                               }
-                       } else {
-                               result = -EIO;
-                       }
-               }
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-       }
-       if (result != 0) {
-               TRACE(ft_t_err, "General failure to reset tape drive");
-       } else {
-               /*  Restore correct settings: keep original rate 
-                */
-               ftape_set_data_rate(ft_data_rate, ft_qic_std);
-       }
-       ftape_init_drive_needed = 1;
-       TRACE_EXIT result;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-io.h b/drivers/char/ftape/lowlevel/ftape-io.h
deleted file mode 100644 (file)
index 26a7baa..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _FTAPE_IO_H
-#define _FTAPE_IO_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- *           (C) 1997      Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:18 $
- *
- *      This file contains definitions for the glue part of the
- *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/qic117.h>
-#include <linux/ftape-vendors.h>
-
-typedef struct {
-       unsigned int seek;
-       unsigned int reset;
-       unsigned int rewind;
-       unsigned int head_seek;
-       unsigned int stop;
-       unsigned int pause;
-} ft_timeout_table;
-
-typedef enum {
-       prehistoric, pre_qic117c, post_qic117b, post_qic117d 
-} qic_model;
-
-/*
- *      ftape-io.c defined global vars.
- */
-extern ft_timeout_table ftape_timeout;
-extern unsigned int ftape_tape_len;
-extern volatile qic117_cmd_t ftape_current_command;
-extern const struct qic117_command_table qic117_cmds[];
-extern int ftape_might_be_off_track;
-
-/*
- *      ftape-io.c defined global functions.
- */
-extern void ftape_udelay(unsigned int usecs);
-extern void  ftape_udelay_calibrate(void);
-extern void ftape_sleep(unsigned int time);
-extern void ftape_report_vendor_id(unsigned int *id);
-extern int  ftape_command(qic117_cmd_t command);
-extern int  ftape_command_wait(qic117_cmd_t command,
-                              unsigned int timeout,
-                              int *status);
-extern int  ftape_parameter(unsigned int parameter);
-extern int ftape_report_operation(int *status,
-                                 qic117_cmd_t  command,
-                                 int result_length);
-extern int ftape_report_configuration(qic_model *model,
-                                     unsigned int *rate,
-                                     int *qic_std,
-                                     int *tape_len);
-extern int ftape_report_drive_status(int *status);
-extern int ftape_report_raw_drive_status(int *status);
-extern int ftape_report_status(int *status);
-extern int ftape_ready_wait(unsigned int timeout, int *status);
-extern int ftape_seek_head_to_track(unsigned int track);
-extern int ftape_set_data_rate(unsigned int new_rate, unsigned int qic_std);
-extern int ftape_report_error(unsigned int *error,
-                             qic117_cmd_t *command,
-                             int report);
-extern int ftape_reset_drive(void);
-extern int ftape_put_drive_to_sleep(wake_up_types method);
-extern int ftape_wakeup_drive(wake_up_types method);
-extern int ftape_increase_threshold(void);
-extern int ftape_half_data_rate(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-proc.c b/drivers/char/ftape/lowlevel/ftape-proc.c
deleted file mode 100644 (file)
index e805b15..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *      Copyright (C) 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-proc.c,v $
- * $Revision: 1.11 $
- * $Date: 1997/10/24 14:47:37 $
- *
- *      This file contains the procfs interface for the
- *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
-
- *     Old code removed, switched to dynamic proc entry.
- */
-
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
-
-#include <linux/proc_fs.h>
-
-#include <linux/ftape.h>
-#include <linux/init.h>
-#include <linux/qic117.h>
-
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-proc.h"
-#include "../lowlevel/ftape-tracing.h"
-
-static size_t get_driver_info(char *buf)
-{
-       const char *debug_level[] = { "bugs"  ,
-                                     "errors",
-                                     "warnings",
-                                     "informational",
-                                     "noisy",
-                                     "program flow",
-                                     "fdc and dma",
-                                     "data flow",
-                                     "anything" };
-
-       return sprintf(buf,
-                      "version       : %s\n"
-                      "used data rate: %d kbit/sec\n"
-                      "dma memory    : %d kb\n"
-                      "debug messages: %s\n",
-                      FTAPE_VERSION,
-                      ft_data_rate,
-                      FT_BUFF_SIZE * ft_nr_buffers >> 10,
-                      debug_level[TRACE_LEVEL]);
-}
-
-static size_t get_tapedrive_info(char *buf)
-{ 
-       return sprintf(buf,
-                      "vendor id : 0x%04x\n"
-                      "drive name: %s\n"
-                      "wind speed: %d ips\n"
-                      "wakeup    : %s\n"
-                      "max. rate : %d kbit/sec\n",
-                      ft_drive_type.vendor_id,
-                      ft_drive_type.name,
-                      ft_drive_type.speed,
-                      ((ft_drive_type.wake_up == no_wake_up)
-                       ? "No wakeup needed" :
-                       ((ft_drive_type.wake_up == wake_up_colorado)
-                        ? "Colorado" :
-                        ((ft_drive_type.wake_up == wake_up_mountain)
-                         ? "Mountain" :
-                         ((ft_drive_type.wake_up == wake_up_insight)
-                          ? "Motor on" :
-                          "Unknown")))),
-                      ft_drive_max_rate);
-}
-
-static size_t get_cartridge_info(char *buf)
-{
-       if (ftape_init_drive_needed) {
-               return sprintf(buf, "uninitialized\n");
-       }
-       if (ft_no_tape) {
-               return sprintf(buf, "no cartridge inserted\n");
-       }
-       return sprintf(buf,
-                      "segments  : %5d\n"
-                      "tracks    : %5d\n"
-                      "length    : %5dft\n"
-                      "formatted : %3s\n"
-                      "writable  : %3s\n"
-                      "QIC spec. : QIC-%s\n"
-                      "fmt-code  : %1d\n",
-                      ft_segments_per_track,
-                      ft_tracks_per_tape,
-                      ftape_tape_len,
-                      (ft_formatted == 1) ? "yes" : "no",
-                      (ft_write_protected == 1) ? "no" : "yes",
-                      ((ft_qic_std == QIC_TAPE_QIC40) ? "40" :
-                       ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
-                        ((ft_qic_std == QIC_TAPE_QIC3010) ? "3010" :
-                         ((ft_qic_std == QIC_TAPE_QIC3020) ? "3020" :
-                          "???")))),
-                      ft_format_code);
-}
-
-static size_t get_controller_info(char *buf)
-{
-       const char  *fdc_name[] = { "no fdc",
-                                   "i8272",
-                                   "i82077",
-                                   "i82077AA",
-                                   "Colorado FC-10 or FC-20",
-                                   "i82078",
-                                   "i82078_1" };
-
-       return sprintf(buf,
-                      "FDC type  : %s\n"
-                      "FDC base  : 0x%03x\n"
-                      "FDC irq   : %d\n"
-                      "FDC dma   : %d\n"
-                      "FDC thr.  : %d\n"
-                      "max. rate : %d kbit/sec\n",
-                      ft_mach2 ? "Mountain MACH-2" : fdc_name[fdc.type],
-                      fdc.sra, fdc.irq, fdc.dma,
-                      ft_fdc_threshold, ft_fdc_max_rate);
-}
-
-static size_t get_history_info(char *buf)
-{
-        size_t len;
-
-       len  = sprintf(buf,
-                      "\nFDC isr statistics\n"
-                      " id_am_errors     : %3d\n"
-                      " id_crc_errors    : %3d\n"
-                      " data_am_errors   : %3d\n"
-                      " data_crc_errors  : %3d\n"
-                      " overrun_errors   : %3d\n"
-                      " no_data_errors   : %3d\n"
-                      " retries          : %3d\n",
-                      ft_history.id_am_errors,   ft_history.id_crc_errors,
-                      ft_history.data_am_errors, ft_history.data_crc_errors,
-                      ft_history.overrun_errors, ft_history.no_data_errors,
-                      ft_history.retries);
-       len += sprintf(buf + len,
-                      "\nECC statistics\n"
-                      " crc_errors       : %3d\n"
-                      " crc_failures     : %3d\n"
-                      " ecc_failures     : %3d\n"
-                      " sectors corrected: %3d\n",
-                      ft_history.crc_errors,   ft_history.crc_failures,
-                      ft_history.ecc_failures, ft_history.corrected);
-       len += sprintf(buf + len,
-                      "\ntape quality statistics\n"
-                      " media defects    : %3d\n",
-                      ft_history.defects);
-       len += sprintf(buf + len,
-                      "\ntape motion statistics\n"
-                      " repositions      : %3d\n",
-                      ft_history.rewinds);
-       return len;
-}
-
-static int ftape_read_proc(char *page, char **start, off_t off,
-                          int count, int *eof, void *data)
-{
-       char *ptr = page;
-       size_t len;
-       
-       ptr += sprintf(ptr, "Kernel Driver\n\n");
-       ptr += get_driver_info(ptr);
-       ptr += sprintf(ptr, "\nTape Drive\n\n");
-       ptr += get_tapedrive_info(ptr);
-       ptr += sprintf(ptr, "\nFDC Controller\n\n");
-       ptr += get_controller_info(ptr);
-       ptr += sprintf(ptr, "\nTape Cartridge\n\n");
-       ptr += get_cartridge_info(ptr);
-       ptr += sprintf(ptr, "\nHistory Record\n\n");
-       ptr += get_history_info(ptr);
-
-       len = strlen(page);
-       *start = NULL;
-       if (off+count >= len) {
-               *eof = 1;
-       } else {
-               *eof = 0;
-       }
-       return len;
-}
-
-int __init ftape_proc_init(void)
-{
-       return create_proc_read_entry("ftape", 0, &proc_root,
-               ftape_read_proc, NULL) != NULL;
-}
-
-void ftape_proc_destroy(void)
-{
-       remove_proc_entry("ftape", &proc_root);
-}
-
-#endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) */
diff --git a/drivers/char/ftape/lowlevel/ftape-proc.h b/drivers/char/ftape/lowlevel/ftape-proc.h
deleted file mode 100644 (file)
index 264dfcc..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _FTAPE_PROC_H
-#define _FTAPE_PROC_H
-
-/*
- *      Copyright (C) 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-proc.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:20 $
- *
- *      This file contains definitions for the procfs interface of the
- *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/proc_fs.h>
-
-extern int  ftape_proc_init(void);
-extern void ftape_proc_destroy(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-read.c b/drivers/char/ftape/lowlevel/ftape-read.c
deleted file mode 100644 (file)
index d967d8c..0000000
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven,
- *                (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.c,v $
- * $Revision: 1.6 $
- * $Date: 1997/10/21 14:39:22 $
- *
- *      This file contains the reading code
- *      for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/*      Global vars.
- */
-
-/*      Local vars.
- */
-
-void ftape_zap_read_buffers(void)
-{
-       int i;
-
-       for (i = 0; i < ft_nr_buffers; ++i) {
-/*  changed to "fit" with dynamic allocation of tape_buffer. --khp  */
-               ft_buffer[i]->status = waiting;
-               ft_buffer[i]->bytes = 0;
-               ft_buffer[i]->skip = 0;
-               ft_buffer[i]->retry = 0;
-       }
-/*     ftape_reset_buffer(); */
-}
-
-static SectorMap convert_sector_map(buffer_struct * buff)
-{
-       int i = 0;
-       SectorMap bad_map = ftape_get_bad_sector_entry(buff->segment_id);
-       SectorMap src_map = buff->soft_error_map | buff->hard_error_map;
-       SectorMap dst_map = 0;
-       TRACE_FUN(ft_t_any);
-
-       if (bad_map || src_map) {
-               TRACE(ft_t_flow, "bad_map = 0x%08lx", (long) bad_map);
-               TRACE(ft_t_flow, "src_map = 0x%08lx", (long) src_map);
-       }
-       while (bad_map) {
-               while ((bad_map & 1) == 0) {
-                       if (src_map & 1) {
-                               dst_map |= (1 << i);
-                       }
-                       src_map >>= 1;
-                       bad_map >>= 1;
-                       ++i;
-               }
-               /* (bad_map & 1) == 1 */
-               src_map >>= 1;
-               bad_map >>= 1;
-       }
-       if (src_map) {
-               dst_map |= (src_map << i);
-       }
-       if (dst_map) {
-               TRACE(ft_t_flow, "dst_map = 0x%08lx", (long) dst_map);
-       }
-       TRACE_EXIT dst_map;
-}
-
-static int correct_and_copy_fraction(buffer_struct *buff, __u8 * destination,
-                                    int start, int size)
-{
-       struct memory_segment mseg;
-       int result;
-       SectorMap read_bad;
-       TRACE_FUN(ft_t_any);
-
-       mseg.read_bad = convert_sector_map(buff);
-       mseg.marked_bad = 0;    /* not used... */
-       mseg.blocks = buff->bytes / FT_SECTOR_SIZE;
-       mseg.data = buff->address;
-       /*    If there are no data sectors we can skip this segment.
-        */
-       if (mseg.blocks <= 3) {
-               TRACE_ABORT(0, ft_t_noise, "empty segment");
-       }
-       read_bad = mseg.read_bad;
-       ft_history.crc_errors += count_ones(read_bad);
-       result = ftape_ecc_correct_data(&mseg);
-       if (read_bad != 0 || mseg.corrected != 0) {
-               TRACE(ft_t_noise, "crc error map: 0x%08lx", (unsigned long)read_bad);
-               TRACE(ft_t_noise, "corrected map: 0x%08lx", (unsigned long)mseg.corrected);
-               ft_history.corrected += count_ones(mseg.corrected);
-       }
-       if (result == ECC_CORRECTED || result == ECC_OK) {
-               if (result == ECC_CORRECTED) {
-                       TRACE(ft_t_info, "ecc corrected segment: %d", buff->segment_id);
-               }
-               if(start < 0) {
-                       start= 0;
-               }
-               if((start+size) > ((mseg.blocks - 3) * FT_SECTOR_SIZE)) {
-                       size = (mseg.blocks - 3) * FT_SECTOR_SIZE  - start;
-               } 
-               if (size < 0) {
-                       size= 0;
-               }
-               if(size > 0) {
-                       memcpy(destination + start, mseg.data + start, size);
-               }
-               if ((read_bad ^ mseg.corrected) & mseg.corrected) {
-                       /* sectors corrected without crc errors set */
-                       ft_history.crc_failures++;
-               }
-               TRACE_EXIT size; /* (mseg.blocks - 3) * FT_SECTOR_SIZE; */
-       } else {
-               ft_history.ecc_failures++;
-               TRACE_ABORT(-EAGAIN,
-                           ft_t_err, "ecc failure on segment %d",
-                           buff->segment_id);
-       }
-       TRACE_EXIT 0;
-}
-
-/*      Read given segment into buffer at address.
- */
-int ftape_read_segment_fraction(const int segment_id,
-                               void  *address, 
-                               const ft_read_mode_t read_mode,
-                               const int start,
-                               const int size)
-{
-       int result = 0;
-       int retry  = 0;
-       int bytes_read = 0;
-       int read_done  = 0;
-       TRACE_FUN(ft_t_flow);
-
-       ft_history.used |= 1;
-       TRACE(ft_t_data_flow, "segment_id = %d", segment_id);
-       if (ft_driver_state != reading) {
-               TRACE(ft_t_noise, "calling ftape_abort_operation");
-               TRACE_CATCH(ftape_abort_operation(),);
-               ftape_set_state(reading);
-       }
-       for(;;) {
-               buffer_struct *tail;
-               /*  Allow escape from this loop on signal !
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               /*  Search all full buffers for the first matching the
-                *  wanted segment.  Clear other buffers on the fly.
-                */
-               tail = ftape_get_buffer(ft_queue_tail);
-               while (!read_done && tail->status == done) {
-                       /*  Allow escape from this loop on signal !
-                        */
-                       FT_SIGNAL_EXIT(_DONT_BLOCK);
-                       if (tail->segment_id == segment_id) {
-                               /*  If out buffer is already full,
-                                *  return its contents.  
-                                */
-                               TRACE(ft_t_flow, "found segment in cache: %d",
-                                     segment_id);
-                               if (tail->deleted) {
-                                       /*  Return a value that
-                                        *  read_header_segment
-                                        *  understands.  As this
-                                        *  should only occur when
-                                        *  searching for the header
-                                        *  segments it shouldn't be
-                                        *  misinterpreted elsewhere.
-                                        */
-                                       TRACE_EXIT 0;
-                               }
-                               result = correct_and_copy_fraction(
-                                       tail,
-                                       address,
-                                       start,
-                                       size);
-                               TRACE(ft_t_flow, "segment contains (bytes): %d",
-                                     result);
-                               if (result < 0) {
-                                       if (result != -EAGAIN) {
-                                               TRACE_EXIT result;
-                                       }
-                                       /* keep read_done == 0, will
-                                        * trigger
-                                        * ftape_abort_operation
-                                        * because reading wrong
-                                        * segment.
-                                        */
-                                       TRACE(ft_t_err, "ecc failed, retry");
-                                       ++retry;
-                               } else {
-                                       read_done = 1;
-                                       bytes_read = result;
-                               }
-                       } else {
-                               TRACE(ft_t_flow,"zapping segment in cache: %d",
-                                     tail->segment_id);
-                       }
-                       tail->status = waiting;
-                       tail = ftape_next_buffer(ft_queue_tail);
-               }
-               if (!read_done && tail->status == reading) {
-                       if (tail->segment_id == segment_id) {
-                               switch(ftape_wait_segment(reading)) {
-                               case 0:
-                                       break;
-                               case -EINTR:
-                                       TRACE_ABORT(-EINTR, ft_t_warn,
-                                                   "interrupted by "
-                                                   "non-blockable signal");
-                                       break;
-                               default:
-                                       TRACE(ft_t_noise,
-                                             "wait_segment failed");
-                                       ftape_abort_operation();
-                                       ftape_set_state(reading);
-                                       break;
-                               }
-                       } else {
-                               /*  We're reading the wrong segment,
-                                *  stop runner.
-                                */
-                               TRACE(ft_t_noise, "reading wrong segment");
-                               ftape_abort_operation();
-                               ftape_set_state(reading);
-                       }
-               }
-               /*    should runner stop ?
-                */
-               if (ft_runner_status == aborting) {
-                       buffer_struct *head = ftape_get_buffer(ft_queue_head);
-                       switch(head->status) {
-                       case error:
-                               ft_history.defects += 
-                                       count_ones(head->hard_error_map);
-                       case reading:
-                               head->status = waiting;
-                               break;
-                       default:
-                               break;
-                       }
-                       TRACE_CATCH(ftape_dumb_stop(),);
-               } else {
-                       /*  If just passed last segment on tape: wait
-                        *  for BOT or EOT mark. Sets ft_runner_status to
-                        *  idle if at lEOT and successful 
-                        */
-                       TRACE_CATCH(ftape_handle_logical_eot(),);
-               }
-               /*    If we got a segment: quit, or else retry up to limit.
-                *
-                *    If segment to read is empty, do not start runner for it,
-                *    but wait for next read call.
-                */
-               if (read_done ||
-                   ftape_get_bad_sector_entry(segment_id) == EMPTY_SEGMENT ) {
-                       /* bytes_read = 0;  should still be zero */
-                       TRACE_EXIT bytes_read;
-
-               }
-               if (retry > FT_RETRIES_ON_ECC_ERROR) {
-                       ft_history.defects++;
-                       TRACE_ABORT(-ENODATA, ft_t_err,
-                                   "too many retries on ecc failure");
-               }
-               /*    Now at least one buffer is empty !
-                *    Restart runner & tape if needed.
-                */
-               TRACE(ft_t_any, "head: %d, tail: %d, ft_runner_status: %d",
-                     ftape_buffer_id(ft_queue_head),
-                     ftape_buffer_id(ft_queue_tail),
-                     ft_runner_status);
-               TRACE(ft_t_any, "buffer[].status, [head]: %d, [tail]: %d",
-                     ftape_get_buffer(ft_queue_head)->status,
-                     ftape_get_buffer(ft_queue_tail)->status);
-               tail = ftape_get_buffer(ft_queue_tail);
-               if (tail->status == waiting) {
-                       buffer_struct *head = ftape_get_buffer(ft_queue_head);
-
-                       ftape_setup_new_segment(head, segment_id, -1);
-                       if (read_mode == FT_RD_SINGLE) {
-                               /* disable read-ahead */
-                               head->next_segment = 0;
-                       }
-                       ftape_calc_next_cluster(head);
-                       if (ft_runner_status == idle) {
-                               result = ftape_start_tape(segment_id,
-                                                         head->sector_offset);
-                               if (result < 0) {
-                                       TRACE_ABORT(result, ft_t_err, "Error: "
-                                                   "segment %d unreachable",
-                                                   segment_id);
-                               }
-                       }
-                       head->status = reading;
-                       fdc_setup_read_write(head, FDC_READ);
-               }
-       }
-       /* not reached */
-       TRACE_EXIT -EIO;
-}
-
-int ftape_read_header_segment(__u8 *address)
-{
-       int result;
-       int header_segment;
-       int first_failed = 0;
-       int status;
-       TRACE_FUN(ft_t_flow);
-
-       ft_used_header_segment = -1;
-       TRACE_CATCH(ftape_report_drive_status(&status),);
-       TRACE(ft_t_flow, "reading...");
-       /*  We're looking for the first header segment.
-        *  A header segment cannot contain bad sectors, therefor at the
-        *  tape start, segments with bad sectors are (according to QIC-40/80)
-        *  written with deleted data marks and must be skipped.
-        */
-       memset(address, '\0', (FT_SECTORS_PER_SEGMENT - 3) * FT_SECTOR_SIZE); 
-       result = 0;
-#define HEADER_SEGMENT_BOUNDARY 68  /* why not 42? */
-       for (header_segment = 0;
-            header_segment < HEADER_SEGMENT_BOUNDARY && result == 0;
-            ++header_segment) {
-               /*  Set no read-ahead, the isr will force read-ahead whenever
-                *  it encounters deleted data !
-                */
-               result = ftape_read_segment(header_segment,
-                                           address,
-                                           FT_RD_SINGLE);
-               if (result < 0 && !first_failed) {
-                       TRACE(ft_t_err, "header segment damaged, trying backup");
-                       first_failed = 1;
-                       result = 0;     /* force read of next (backup) segment */
-               }
-       }
-       if (result < 0 || header_segment >= HEADER_SEGMENT_BOUNDARY) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "no readable header segment found");
-       }
-       TRACE_CATCH(ftape_abort_operation(),);
-       ft_used_header_segment = header_segment;
-       result = ftape_decode_header_segment(address);
-       TRACE_EXIT result;
-}
-
-int ftape_decode_header_segment(__u8 *address)
-{
-       unsigned int max_floppy_side;
-       unsigned int max_floppy_track;
-       unsigned int max_floppy_sector;
-       unsigned int new_tape_len;
-       TRACE_FUN(ft_t_flow);
-
-       if (GET4(address, FT_SIGNATURE) == FT_D2G_MAGIC) {
-               /* Ditto 2GB header segment. They encrypt the bad sector map.
-                * We decrypt it and store them in normal format.
-                * I hope this is correct.
-                */
-               int i;
-               TRACE(ft_t_warn,
-                     "Found Ditto 2GB tape, "
-                     "trying to decrypt bad sector map");
-               for (i=256; i < 29 * FT_SECTOR_SIZE; i++) {
-                       address[i] = ~(address[i] - (i&0xff));
-               }
-               PUT4(address, 0,FT_HSEG_MAGIC);
-       } else if (GET4(address, FT_SIGNATURE) != FT_HSEG_MAGIC) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "wrong signature in header segment");
-       }
-       ft_format_code = (ft_format_type) address[FT_FMT_CODE];
-       if (ft_format_code != fmt_big) {
-               ft_header_segment_1   = GET2(address, FT_HSEG_1);
-               ft_header_segment_2   = GET2(address, FT_HSEG_2);
-               ft_first_data_segment = GET2(address, FT_FRST_SEG);
-               ft_last_data_segment  = GET2(address, FT_LAST_SEG);
-       } else {
-               ft_header_segment_1   = GET4(address, FT_6_HSEG_1);
-               ft_header_segment_2   = GET4(address, FT_6_HSEG_2);
-               ft_first_data_segment = GET4(address, FT_6_FRST_SEG);
-               ft_last_data_segment  = GET4(address, FT_6_LAST_SEG);
-       }
-       TRACE(ft_t_noise, "first data segment: %d", ft_first_data_segment);
-       TRACE(ft_t_noise, "last  data segment: %d", ft_last_data_segment);
-       TRACE(ft_t_noise, "header segments are %d and %d",
-             ft_header_segment_1, ft_header_segment_2);
-
-       /*    Verify tape parameters...
-        *    QIC-40/80 spec:                 tape_parameters:
-        *
-        *    segments-per-track              segments_per_track
-        *    tracks-per-cartridge            tracks_per_tape
-        *    max-floppy-side                 (segments_per_track *
-        *                                    tracks_per_tape - 1) /
-        *                                    ftape_segments_per_head
-        *    max-floppy-track                ftape_segments_per_head /
-        *                                    ftape_segments_per_cylinder - 1
-        *    max-floppy-sector               ftape_segments_per_cylinder *
-        *                                    FT_SECTORS_PER_SEGMENT
-        */
-       ft_segments_per_track = GET2(address, FT_SPT);
-       ft_tracks_per_tape    = address[FT_TPC];
-       max_floppy_side       = address[FT_FHM];
-       max_floppy_track      = address[FT_FTM];
-       max_floppy_sector     = address[FT_FSM];
-       TRACE(ft_t_noise, "(fmt/spt/tpc/fhm/ftm/fsm) = %d/%d/%d/%d/%d/%d",
-             ft_format_code, ft_segments_per_track, ft_tracks_per_tape,
-             max_floppy_side, max_floppy_track, max_floppy_sector);
-       new_tape_len = ftape_tape_len;
-       switch (ft_format_code) {
-       case fmt_425ft:
-               new_tape_len = 425;
-               break;
-       case fmt_normal:
-               if (ftape_tape_len == 0) {      /* otherwise 307 ft */
-                       new_tape_len = 205;
-               }
-               break;
-       case fmt_1100ft:
-               new_tape_len = 1100;
-               break;
-       case fmt_var:{
-                       int segments_per_1000_inch = 1;         /* non-zero default for switch */
-                       switch (ft_qic_std) {
-                       case QIC_TAPE_QIC40:
-                               segments_per_1000_inch = 332;
-                               break;
-                       case QIC_TAPE_QIC80:
-                               segments_per_1000_inch = 488;
-                               break;
-                       case QIC_TAPE_QIC3010:
-                               segments_per_1000_inch = 730;
-                               break;
-                       case QIC_TAPE_QIC3020:
-                               segments_per_1000_inch = 1430;
-                               break;
-                       }
-                       new_tape_len = (1000 * ft_segments_per_track +
-                                       (segments_per_1000_inch - 1)) / segments_per_1000_inch;
-                       break;
-               }
-       case fmt_big:{
-                       int segments_per_1000_inch = 1;         /* non-zero default for switch */
-                       switch (ft_qic_std) {
-                       case QIC_TAPE_QIC40:
-                               segments_per_1000_inch = 332;
-                               break;
-                       case QIC_TAPE_QIC80:
-                               segments_per_1000_inch = 488;
-                               break;
-                       case QIC_TAPE_QIC3010:
-                               segments_per_1000_inch = 730;
-                               break;
-                       case QIC_TAPE_QIC3020:
-                               segments_per_1000_inch = 1430;
-                               break;
-                       default:
-                               TRACE_ABORT(-EIO, ft_t_bug,
-                       "%x QIC-standard with fmt-code %d, please report",
-                                           ft_qic_std, ft_format_code);
-                       }
-                       new_tape_len = ((1000 * ft_segments_per_track +
-                                        (segments_per_1000_inch - 1)) / 
-                                       segments_per_1000_inch);
-                       break;
-               }
-       default:
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "unknown tape format, please report !");
-       }
-       if (new_tape_len != ftape_tape_len) {
-               ftape_tape_len = new_tape_len;
-               TRACE(ft_t_info, "calculated tape length is %d ft",
-                     ftape_tape_len);
-               ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
-       }
-       if (ft_segments_per_track == 0 && ft_tracks_per_tape == 0 &&
-           max_floppy_side == 0 && max_floppy_track == 0 &&
-           max_floppy_sector == 0) {
-               /*  QIC-40 Rev E and earlier has no values in the header.
-                */
-               ft_segments_per_track = 68;
-               ft_tracks_per_tape = 20;
-               max_floppy_side = 1;
-               max_floppy_track = 169;
-               max_floppy_sector = 128;
-       }
-       /*  This test will compensate for the wrong parameter on tapes
-        *  formatted by Conner software.
-        */
-       if (ft_segments_per_track == 150 &&
-           ft_tracks_per_tape == 28 &&
-           max_floppy_side == 7 &&
-           max_floppy_track == 149 &&
-           max_floppy_sector == 128) {
-TRACE(ft_t_info, "the famous CONNER bug: max_floppy_side off by one !");
-               max_floppy_side = 6;
-       }
-       /*  These tests will compensate for the wrong parameter on tapes
-        *  formatted by ComByte Windows software.
-        *
-        *  First, for 205 foot tapes
-        */
-       if (ft_segments_per_track == 100 &&
-           ft_tracks_per_tape == 28 &&
-           max_floppy_side == 9 &&
-           max_floppy_track == 149 &&
-           max_floppy_sector == 128) {
-TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");
-               max_floppy_side = 4;
-       }
-       /* Next, for 307 foot tapes. */
-       if (ft_segments_per_track == 150 &&
-           ft_tracks_per_tape == 28 &&
-           max_floppy_side == 9 &&
-           max_floppy_track == 149 &&
-           max_floppy_sector == 128) {
-TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");
-               max_floppy_side = 6;
-       }
-       /*  This test will compensate for the wrong parameter on tapes
-        *  formatted by Colorado Windows software.
-        */
-       if (ft_segments_per_track == 150 &&
-           ft_tracks_per_tape == 28 &&
-           max_floppy_side == 6 &&
-           max_floppy_track == 150 &&
-           max_floppy_sector == 128) {
-TRACE(ft_t_info, "the famous Colorado bug: max_floppy_track off by one !");
-               max_floppy_track = 149;
-       }
-       ftape_segments_per_head = ((max_floppy_sector/FT_SECTORS_PER_SEGMENT) *
-                                  (max_floppy_track + 1));
-       /*  This test will compensate for some bug reported by Dima
-        *  Brodsky.  Seems to be a Colorado bug, either. (freebee
-        *  Imation tape shipped together with Colorado T3000
-        */
-       if ((ft_format_code == fmt_var || ft_format_code == fmt_big) &&
-           ft_tracks_per_tape == 50 &&
-           max_floppy_side == 54 &&
-           max_floppy_track == 255 &&
-           max_floppy_sector == 128) {
-TRACE(ft_t_info, "the famous ??? bug: max_floppy_track off by one !");
-               max_floppy_track = 254;
-       }
-       /*
-        *    Verify drive_configuration with tape parameters
-        */
-       if (ftape_segments_per_head == 0 || ftape_segments_per_cylinder == 0 ||
-         ((ft_segments_per_track * ft_tracks_per_tape - 1) / ftape_segments_per_head
-          != max_floppy_side) ||
-           (ftape_segments_per_head / ftape_segments_per_cylinder - 1 != max_floppy_track) ||
-       (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT != max_floppy_sector)
-#ifdef TESTING
-           || ((ft_format_code == fmt_var || ft_format_code == fmt_big) && 
-               (max_floppy_track != 254 || max_floppy_sector != 128))
-#endif
-          ) {
-               char segperheadz = ftape_segments_per_head ? ' ' : '?';
-               char segpercylz  = ftape_segments_per_cylinder ? ' ' : '?';
-               TRACE(ft_t_err,"Tape parameters inconsistency, please report");
-               TRACE(ft_t_err, "reported = %d/%d/%d/%d/%d/%d",
-                     ft_format_code,
-                     ft_segments_per_track,
-                     ft_tracks_per_tape,
-                     max_floppy_side,
-                     max_floppy_track,
-                     max_floppy_sector);
-               TRACE(ft_t_err, "required = %d/%d/%d/%d%c/%d%c/%d",
-                     ft_format_code,
-                     ft_segments_per_track,
-                     ft_tracks_per_tape,
-                     ftape_segments_per_head ?
-                     ((ft_segments_per_track * ft_tracks_per_tape -1) / 
-                      ftape_segments_per_head ) :
-                       (ft_segments_per_track * ft_tracks_per_tape -1),
-                       segperheadz,
-                     ftape_segments_per_cylinder ?
-                     (ftape_segments_per_head / 
-                      ftape_segments_per_cylinder - 1 ) :
-                       ftape_segments_per_head - 1,
-                       segpercylz,
-                     (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT));
-               TRACE_EXIT -EIO;
-       }
-       ftape_extract_bad_sector_map(address);
-       TRACE_EXIT 0;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-read.h b/drivers/char/ftape/lowlevel/ftape-read.h
deleted file mode 100644 (file)
index 069f99f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _FTAPE_READ_H
-#define _FTAPE_READ_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:22 $
- *
- *      This file contains the definitions for the read functions
- *      for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-/*      ftape-read.c defined global functions.
- */
-typedef enum {
-       FT_RD_SINGLE = 0,
-       FT_RD_AHEAD  = 1,
-} ft_read_mode_t;
-
-extern int ftape_read_header_segment(__u8 *address);
-extern int ftape_decode_header_segment(__u8 *address);
-extern int ftape_read_segment_fraction(const int segment,
-                                      void  *address, 
-                                      const ft_read_mode_t read_mode,
-                                      const int start,
-                                      const int size);
-#define ftape_read_segment(segment, address, read_mode)                        \
-       ftape_read_segment_fraction(segment, address, read_mode,        \
-                                   0, FT_SEGMENT_SIZE)
-extern void ftape_zap_read_buffers(void);
-
-#endif                         /* _FTAPE_READ_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-rw.c b/drivers/char/ftape/lowlevel/ftape-rw.c
deleted file mode 100644 (file)
index c0d6dc2..0000000
+++ /dev/null
@@ -1,1092 +0,0 @@
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven,
- *                (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-rw.c,v $
- * $Revision: 1.7 $
- * $Date: 1997/10/28 14:26:49 $
- *
- *      This file contains some common code for the segment read and
- *      segment write routines for the QIC-117 floppy-tape driver for
- *      Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/*      Global vars.
- */
-int ft_nr_buffers;
-buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS];
-static volatile int ft_head;
-static volatile int ft_tail;   /* not volatile but need same type as head */
-int fdc_setup_error;
-location_record ft_location = {-1, 0};
-volatile int ftape_tape_running;
-
-/*      Local vars.
- */
-static int overrun_count_offset;
-static int inhibit_correction;
-
-/*  maxmimal allowed overshoot when fast seeking
- */
-#define OVERSHOOT_LIMIT 10
-
-/*      Increment cyclic buffer nr.
- */
-buffer_struct *ftape_next_buffer(ft_buffer_queue_t pos)
-{
-       switch (pos) {
-       case ft_queue_head:
-               if (++ft_head >= ft_nr_buffers) {
-                       ft_head = 0;
-               }
-               return ft_buffer[ft_head];
-       case ft_queue_tail:
-               if (++ft_tail >= ft_nr_buffers) {
-                       ft_tail = 0;
-               }
-               return ft_buffer[ft_tail];
-       default:
-               return NULL;
-       }
-}
-int ftape_buffer_id(ft_buffer_queue_t pos)
-{
-       switch(pos) {
-       case ft_queue_head: return ft_head;
-       case ft_queue_tail: return ft_tail;
-       default: return -1;
-       }
-}
-buffer_struct *ftape_get_buffer(ft_buffer_queue_t pos)
-{
-       switch(pos) {
-       case ft_queue_head: return ft_buffer[ft_head];
-       case ft_queue_tail: return ft_buffer[ft_tail];
-       default: return NULL;
-       }
-}
-void ftape_reset_buffer(void)
-{
-       ft_head = ft_tail = 0;
-}
-
-buffer_state_enum ftape_set_state(buffer_state_enum new_state)
-{
-       buffer_state_enum old_state = ft_driver_state;
-
-       ft_driver_state = new_state;
-       return old_state;
-}
-/*      Calculate Floppy Disk Controller and DMA parameters for a segment.
- *      head:   selects buffer struct in array.
- *      offset: number of physical sectors to skip (including bad ones).
- *      count:  number of physical sectors to handle (including bad ones).
- */
-static int setup_segment(buffer_struct * buff, 
-                        int segment_id,
-                        unsigned int sector_offset, 
-                        unsigned int sector_count, 
-                        int retry)
-{
-       SectorMap offset_mask;
-       SectorMap mask;
-       TRACE_FUN(ft_t_any);
-
-       buff->segment_id = segment_id;
-       buff->sector_offset = sector_offset;
-       buff->remaining = sector_count;
-       buff->head = segment_id / ftape_segments_per_head;
-       buff->cyl = (segment_id % ftape_segments_per_head) / ftape_segments_per_cylinder;
-       buff->sect = (segment_id % ftape_segments_per_cylinder) * FT_SECTORS_PER_SEGMENT + 1;
-       buff->deleted = 0;
-       offset_mask = (1 << buff->sector_offset) - 1;
-       mask = ftape_get_bad_sector_entry(segment_id) & offset_mask;
-       while (mask) {
-               if (mask & 1) {
-                       offset_mask >>= 1;      /* don't count bad sector */
-               }
-               mask >>= 1;
-       }
-       buff->data_offset = count_ones(offset_mask);    /* good sectors to skip */
-       buff->ptr = buff->address + buff->data_offset * FT_SECTOR_SIZE;
-       TRACE(ft_t_flow, "data offset = %d sectors", buff->data_offset);
-       if (retry) {
-               buff->soft_error_map &= offset_mask;    /* keep skipped part */
-       } else {
-               buff->hard_error_map = buff->soft_error_map = 0;
-       }
-       buff->bad_sector_map = ftape_get_bad_sector_entry(buff->segment_id);
-       if (buff->bad_sector_map != 0) {
-               TRACE(ft_t_noise, "segment: %d, bad sector map: %08lx",
-                       buff->segment_id, (long)buff->bad_sector_map);
-       } else {
-               TRACE(ft_t_flow, "segment: %d", buff->segment_id);
-       }
-       if (buff->sector_offset > 0) {
-               buff->bad_sector_map >>= buff->sector_offset;
-       }
-       if (buff->sector_offset != 0 || buff->remaining != FT_SECTORS_PER_SEGMENT) {
-               TRACE(ft_t_flow, "sector offset = %d, count = %d",
-                       buff->sector_offset, buff->remaining);
-       }
-       /*    Segments with 3 or less sectors are not written with valid
-        *    data because there is no space left for the ecc.  The
-        *    data written is whatever happens to be in the buffer.
-        *    Reading such a segment will return a zero byte-count.
-        *    To allow us to read/write segments with all bad sectors
-        *    we fake one readable sector in the segment. This
-        *    prevents having to handle these segments in a very
-        *    special way.  It is not important if the reading of this
-        *    bad sector fails or not (the data is ignored). It is
-        *    only read to keep the driver running.
-        *
-        *    The QIC-40/80 spec. has no information on how to handle
-        *    this case, so this is my interpretation.  
-        */
-       if (buff->bad_sector_map == EMPTY_SEGMENT) {
-               TRACE(ft_t_flow, "empty segment %d, fake first sector good",
-                     buff->segment_id);
-               if (buff->ptr != buff->address) {
-                       TRACE(ft_t_bug, "This is a bug: %p/%p",
-                             buff->ptr, buff->address);
-               }
-               buff->bad_sector_map = FAKE_SEGMENT;
-       }
-       fdc_setup_error = 0;
-       buff->next_segment = segment_id + 1;
-       TRACE_EXIT 0;
-}
-
-/*      Calculate Floppy Disk Controller and DMA parameters for a new segment.
- */
-int ftape_setup_new_segment(buffer_struct * buff, int segment_id, int skip)
-{
-       int result = 0;
-       static int old_segment_id = -1;
-       static buffer_state_enum old_ft_driver_state = idle;
-       int retry = 0;
-       unsigned offset = 0;
-       int count = FT_SECTORS_PER_SEGMENT;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_flow, "%s segment %d (old = %d)",
-             (ft_driver_state == reading || ft_driver_state == verifying) 
-             ? "reading" : "writing",
-             segment_id, old_segment_id);
-       if (ft_driver_state != old_ft_driver_state) {   /* when verifying */
-               old_segment_id = -1;
-               old_ft_driver_state = ft_driver_state;
-       }
-       if (segment_id == old_segment_id) {
-               ++buff->retry;
-               ++ft_history.retries;
-               TRACE(ft_t_flow, "setting up for retry nr %d", buff->retry);
-               retry = 1;
-               if (skip && buff->skip > 0) {   /* allow skip on retry */
-                       offset = buff->skip;
-                       count -= offset;
-                       TRACE(ft_t_flow, "skipping %d sectors", offset);
-               }
-       } else {
-               buff->retry = 0;
-               buff->skip = 0;
-               old_segment_id = segment_id;
-       }
-       result = setup_segment(buff, segment_id, offset, count, retry);
-       TRACE_EXIT result;
-}
-
-/*      Determine size of next cluster of good sectors.
- */
-int ftape_calc_next_cluster(buffer_struct * buff)
-{
-       /* Skip bad sectors.
-        */
-       while (buff->remaining > 0 && (buff->bad_sector_map & 1) != 0) {
-               buff->bad_sector_map >>= 1;
-               ++buff->sector_offset;
-               --buff->remaining;
-       }
-       /* Find next cluster of good sectors
-        */
-       if (buff->bad_sector_map == 0) {        /* speed up */
-               buff->sector_count = buff->remaining;
-       } else {
-               SectorMap map = buff->bad_sector_map;
-
-               buff->sector_count = 0;
-               while (buff->sector_count < buff->remaining && (map & 1) == 0) {
-                       ++buff->sector_count;
-                       map >>= 1;
-               }
-       }
-       return buff->sector_count;
-}
-
-/*  if just passed the last segment on a track, wait for BOT
- *  or EOT mark.
- */
-int ftape_handle_logical_eot(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (ft_runner_status == logical_eot) {
-               int status;
-
-               TRACE(ft_t_noise, "tape at logical EOT");
-               TRACE_CATCH(ftape_ready_wait(ftape_timeout.seek, &status),);
-               if ((status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) == 0) {
-                       TRACE_ABORT(-EIO, ft_t_err, "eot/bot not reached");
-               }
-               ft_runner_status = end_of_tape;
-       }
-       if (ft_runner_status == end_of_tape) {
-               TRACE(ft_t_noise, "runner stopped because of logical EOT");
-               ft_runner_status = idle;
-       }
-       TRACE_EXIT 0;
-}
-
-static int check_bot_eot(int status)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) {
-               ft_location.bot = ((ft_location.track & 1) == 0 ?
-                               (status & QIC_STATUS_AT_BOT) != 0:
-                               (status & QIC_STATUS_AT_EOT) != 0);
-               ft_location.eot = !ft_location.bot;
-               ft_location.segment = (ft_location.track +
-                       (ft_location.bot ? 0 : 1)) * ft_segments_per_track - 1;
-               ft_location.sector = -1;
-               ft_location.known  = 1;
-               TRACE(ft_t_flow, "tape at logical %s",
-                     ft_location.bot ? "bot" : "eot");
-               TRACE(ft_t_flow, "segment = %d", ft_location.segment);
-       } else {
-               ft_location.known = 0;
-       }
-       TRACE_EXIT ft_location.known;
-}
-
-/*      Read Id of first sector passing tape head.
- */
-static int ftape_read_id(void)
-{
-       int status;
-       __u8 out[2];
-       TRACE_FUN(ft_t_any);
-
-       /* Assume tape is running on entry, be able to handle
-        * situation where it stopped or is stopping.
-        */
-       ft_location.known = 0;  /* default is location not known */
-       out[0] = FDC_READID;
-       out[1] = ft_drive_sel;
-       TRACE_CATCH(fdc_command(out, 2),);
-       switch (fdc_interrupt_wait(20 * FT_SECOND)) {
-       case 0:
-               if (fdc_sect == 0) {
-                       if (ftape_report_drive_status(&status) >= 0 &&
-                           (status & QIC_STATUS_READY)) {
-                               ftape_tape_running = 0;
-                               TRACE(ft_t_flow, "tape has stopped");
-                               check_bot_eot(status);
-                       }
-               } else {
-                       ft_location.known = 1;
-                       ft_location.segment = (ftape_segments_per_head
-                                              * fdc_head
-                                              + ftape_segments_per_cylinder
-                                              * fdc_cyl
-                                              + (fdc_sect - 1)
-                                              / FT_SECTORS_PER_SEGMENT);
-                       ft_location.sector = ((fdc_sect - 1)
-                                             % FT_SECTORS_PER_SEGMENT);
-                       ft_location.eot = ft_location.bot = 0;
-               }
-               break;
-       case -ETIME:
-               /*  Didn't find id on tape, must be near end: Wait
-                *  until stopped.
-                */
-               if (ftape_ready_wait(FT_FOREVER, &status) >= 0) {
-                       ftape_tape_running = 0;
-                       TRACE(ft_t_flow, "tape has stopped");
-                       check_bot_eot(status);
-               }
-               break;
-       default:
-               /*  Interrupted or otherwise failing
-                *  fdc_interrupt_wait() 
-                */
-               TRACE(ft_t_err, "fdc_interrupt_wait failed");
-               break;
-       }
-       if (!ft_location.known) {
-               TRACE_ABORT(-EIO, ft_t_flow, "no id found");
-       }
-       if (ft_location.sector == 0) {
-               TRACE(ft_t_flow, "passing segment %d/%d",
-                     ft_location.segment, ft_location.sector);
-       } else {
-               TRACE(ft_t_fdc_dma, "passing segment %d/%d",
-                     ft_location.segment, ft_location.sector);
-       }
-       TRACE_EXIT 0;
-}
-
-static int logical_forward(void)
-{
-       ftape_tape_running = 1;
-       return ftape_command(QIC_LOGICAL_FORWARD);
-}
-
-int ftape_stop_tape(int *pstatus)
-{
-       int retry = 0;
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       do {
-               result = ftape_command_wait(QIC_STOP_TAPE,
-                                           ftape_timeout.stop, pstatus);
-               if (result == 0) {
-                       if ((*pstatus & QIC_STATUS_READY) == 0) {
-                               result = -EIO;
-                       } else {
-                               ftape_tape_running = 0;
-                       }
-               }
-       } while (result < 0 && ++retry <= 3);
-       if (result < 0) {
-               TRACE(ft_t_err, "failed ! (fatal)");
-       }
-       TRACE_EXIT result;
-}
-
-int ftape_dumb_stop(void)
-{
-       int result;
-       int status;
-       TRACE_FUN(ft_t_flow);
-
-       /*  Abort current fdc operation if it's busy (probably read
-        *  or write operation pending) with a reset.
-        */
-       if (fdc_ready_wait(100 /* usec */) < 0) {
-               TRACE(ft_t_noise, "aborting fdc operation");
-               fdc_reset();
-       }
-       /*  Reading id's after the last segment on a track may fail
-        *  but eventually the drive will become ready (logical eot).
-        */
-       result = ftape_report_drive_status(&status);
-       ft_location.known = 0;
-       do {
-               if (result == 0 && status & QIC_STATUS_READY) {
-                       /* Tape is not running any more.
-                        */
-                       TRACE(ft_t_noise, "tape already halted");
-                       check_bot_eot(status);
-                       ftape_tape_running = 0;
-               } else if (ftape_tape_running) {
-                       /*  Tape is (was) still moving.
-                        */
-#ifdef TESTING
-                       ftape_read_id();
-#endif
-                       result = ftape_stop_tape(&status);
-               } else {
-                       /*  Tape not yet ready but stopped.
-                        */
-                       result = ftape_ready_wait(ftape_timeout.pause,&status);
-               }
-       } while (ftape_tape_running
-                && !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)));
-#ifndef TESTING
-       ft_location.known = 0;
-#endif
-       if (ft_runner_status == aborting || ft_runner_status == do_abort) {
-               ft_runner_status = idle;
-       }
-       TRACE_EXIT result;
-}
-
-/*      Wait until runner has finished tail buffer.
- *
- */
-int ftape_wait_segment(buffer_state_enum state)
-{
-       int status;
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-
-       while (ft_buffer[ft_tail]->status == state) {
-               TRACE(ft_t_flow, "state: %d", ft_buffer[ft_tail]->status);
-               /*  First buffer still being worked on, wait up to timeout.
-                *
-                *  Note: we check two times for being killed. 50
-                *  seconds are quite long. Note that
-                *  fdc_interrupt_wait() is not killable by any
-                *  means. ftape_read_segment() wants us to return
-                *  -EINTR in case of a signal.  
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               result = fdc_interrupt_wait(50 * FT_SECOND);
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               if (result < 0) {
-                       TRACE_ABORT(result,
-                                   ft_t_err, "fdc_interrupt_wait failed");
-               }
-               if (fdc_setup_error) {
-                       /* recover... FIXME */
-                       TRACE_ABORT(-EIO, ft_t_err, "setup error");
-               }
-       }
-       if (ft_buffer[ft_tail]->status != error) {
-               TRACE_EXIT 0;
-       }
-       TRACE_CATCH(ftape_report_drive_status(&status),);
-       TRACE(ft_t_noise, "ftape_report_drive_status: 0x%02x", status);
-       if ((status & QIC_STATUS_READY) && 
-           (status & QIC_STATUS_ERROR)) {
-               unsigned int error;
-               qic117_cmd_t command;
-               
-               /*  Report and clear error state.
-                *  In case the drive can't operate at the selected
-                *  rate, select the next lower data rate.
-                */
-               ftape_report_error(&error, &command, 1);
-               if (error == 31 && command == QIC_LOGICAL_FORWARD) {
-                       /* drive does not accept this data rate */
-                       if (ft_data_rate > 250) {
-                               TRACE(ft_t_info,
-                                     "Probable data rate conflict");
-                               TRACE(ft_t_info,
-                                     "Lowering data rate to %d Kbps",
-                                     ft_data_rate / 2);
-                               ftape_half_data_rate();
-                               if (ft_buffer[ft_tail]->retry > 0) {
-                                       /* give it a chance */
-                                       --ft_buffer[ft_tail]->retry;
-                               }
-                       } else {
-                               /* no rate is accepted... */
-                               TRACE(ft_t_err, "We're dead :(");
-                       }
-               } else {
-                       TRACE(ft_t_err, "Unknown error");
-               }
-               TRACE_EXIT -EIO;   /* g.p. error */
-       }
-       TRACE_EXIT 0;
-}
-
-/* forward */ static int seek_forward(int segment_id, int fast);
-
-static int fast_seek(int count, int reverse)
-{
-       int result = 0;
-       int status;
-       TRACE_FUN(ft_t_flow);
-
-       if (count > 0) {
-               /*  If positioned at begin or end of tape, fast seeking needs
-                *  special treatment.
-                *  Starting from logical bot needs a (slow) seek to the first
-                *  segment before the high speed seek. Most drives do this
-                *  automatically but some older don't, so we treat them
-                *  all the same.
-                *  Starting from logical eot is even more difficult because
-                *  we cannot (slow) reverse seek to the last segment.
-                *  TO BE IMPLEMENTED.
-                */
-               inhibit_correction = 0;
-               if (ft_location.known &&
-                   ((ft_location.bot && !reverse) ||
-                    (ft_location.eot && reverse))) {
-                       if (!reverse) {
-                               /*  (slow) skip to first segment on a track
-                                */
-                               seek_forward(ft_location.track * ft_segments_per_track, 0);
-                               --count;
-                       } else {
-                               /*  When seeking backwards from
-                                *  end-of-tape the number of erased
-                                *  gaps found seems to be higher than
-                                *  expected.  Therefor the drive must
-                                *  skip some more segments than
-                                *  calculated, but we don't know how
-                                *  many.  Thus we will prevent the
-                                *  re-calculation of offset and
-                                *  overshoot when seeking backwards.
-                                */
-                               inhibit_correction = 1;
-                               count += 3;     /* best guess */
-                       }
-               }
-       } else {
-               TRACE(ft_t_flow, "warning: zero or negative count: %d", count);
-       }
-       if (count > 0) {
-               int i;
-               int nibbles = count > 255 ? 3 : 2;
-
-               if (count > 4095) {
-                       TRACE(ft_t_noise, "skipping clipped at 4095 segment");
-                       count = 4095;
-               }
-               /* Issue this tape command first. */
-               if (!reverse) {
-                       TRACE(ft_t_noise, "skipping %d segment(s)", count);
-                       result = ftape_command(nibbles == 3 ?
-                          QIC_SKIP_EXTENDED_FORWARD : QIC_SKIP_FORWARD);
-               } else {
-                       TRACE(ft_t_noise, "backing up %d segment(s)", count);
-                       result = ftape_command(nibbles == 3 ?
-                          QIC_SKIP_EXTENDED_REVERSE : QIC_SKIP_REVERSE);
-               }
-               if (result < 0) {
-                       TRACE(ft_t_noise, "Skip command failed");
-               } else {
-                       --count;        /* 0 means one gap etc. */
-                       for (i = 0; i < nibbles; ++i) {
-                               if (result >= 0) {
-                                       result = ftape_parameter(count & 15);
-                                       count /= 16;
-                               }
-                       }
-                       result = ftape_ready_wait(ftape_timeout.rewind, &status);
-                       if (result >= 0) {
-                               ftape_tape_running = 0;
-                       }
-               }
-       }
-       TRACE_EXIT result;
-}
-
-static int validate(int id)
-{
-       /* Check to see if position found is off-track as reported
-        *  once.  Because all tracks in one direction lie next to
-        *  each other, if off-track the error will be approximately
-        *  2 * ft_segments_per_track.
-        */
-       if (ft_location.track == -1) {
-               return 1; /* unforseen situation, don't generate error */
-       } else {
-               /* Use margin of ft_segments_per_track on both sides
-                * because ftape needs some margin and the error we're
-                * looking for is much larger !
-                */
-               int lo = (ft_location.track - 1) * ft_segments_per_track;
-               int hi = (ft_location.track + 2) * ft_segments_per_track;
-
-               return (id >= lo && id < hi);
-       }
-}
-
-static int seek_forward(int segment_id, int fast)
-{
-       int failures = 0;
-       int count;
-       static int margin = 1;  /* fixed: stop this before target */
-       static int overshoot = 1;
-       static int min_count = 8;
-       int expected = -1;
-       int target = segment_id - margin;
-       int fast_seeking;
-       int prev_segment = ft_location.segment;
-       TRACE_FUN(ft_t_flow);
-
-       if (!ft_location.known) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "fatal: cannot seek from unknown location");
-       }
-       if (!validate(segment_id)) {
-               ftape_sleep(1 * FT_SECOND);
-               ft_failure = 1;
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "fatal: head off track (bad hardware?)");
-       }
-       TRACE(ft_t_noise, "from %d/%d to %d/0 - %d",
-             ft_location.segment, ft_location.sector,segment_id,margin);
-       count = target - ft_location.segment - overshoot;
-       fast_seeking = (fast &&
-                       count > (min_count + (ft_location.bot ? 1 : 0)));
-       if (fast_seeking) {
-               TRACE(ft_t_noise, "fast skipping %d segments", count);
-               expected = segment_id - margin;
-               fast_seek(count, 0);
-       }
-       if (!ftape_tape_running) {
-               logical_forward();
-       }
-       while (ft_location.segment < segment_id) {
-               /*  This requires at least one sector in a (bad) segment to
-                *  have a valid and readable sector id !
-                *  It looks like this is not guaranteed, so we must try
-                *  to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!!
-                */
-               if (ftape_read_id() < 0 || !ft_location.known ||
-                   sigtestsetmask(&current->pending.signal, _DONT_BLOCK)) {
-                       ft_location.known = 0;
-                       if (!ftape_tape_running ||
-                           ++failures > FT_SECTORS_PER_SEGMENT) {
-                               TRACE_ABORT(-EIO, ft_t_err,
-                                           "read_id failed completely");
-                       }
-                       FT_SIGNAL_EXIT(_DONT_BLOCK);
-                       TRACE(ft_t_flow, "read_id failed, retry (%d)",
-                             failures);
-                       continue;
-               }
-               if (fast_seeking) {
-                       TRACE(ft_t_noise, "ended at %d/%d (%d,%d)",
-                             ft_location.segment, ft_location.sector,
-                             overshoot, inhibit_correction);
-                       if (!inhibit_correction &&
-                           (ft_location.segment < expected ||
-                            ft_location.segment > expected + margin)) {
-                               int error = ft_location.segment - expected;
-                               TRACE(ft_t_noise,
-                                     "adjusting overshoot from %d to %d",
-                                     overshoot, overshoot + error);
-                               overshoot += error;
-                               /*  All overshoots have the same
-                                *  direction, so it should never
-                                *  become negative, but who knows.
-                                */
-                               if (overshoot < -5 ||
-                                   overshoot > OVERSHOOT_LIMIT) {
-                                       if (overshoot < 0) {
-                                               /* keep sane value */
-                                               overshoot = -5;
-                                       } else {
-                                               /* keep sane value */
-                                               overshoot = OVERSHOOT_LIMIT;
-                                       }
-                                       TRACE(ft_t_noise,
-                                             "clipped overshoot to %d",
-                                             overshoot);
-                               }
-                       }
-                       fast_seeking = 0;
-               }
-               if (ft_location.known) {
-                       if (ft_location.segment > prev_segment + 1) {
-                               TRACE(ft_t_noise,
-                                     "missed segment %d while skipping",
-                                     prev_segment + 1);
-                       }
-                       prev_segment = ft_location.segment;
-               }
-       }
-       if (ft_location.segment > segment_id) {
-               TRACE_ABORT(-EIO,
-                           ft_t_noise, "failed: skip ended at segment %d/%d",
-                           ft_location.segment, ft_location.sector);
-       }
-       TRACE_EXIT 0;
-}
-
-static int skip_reverse(int segment_id, int *pstatus)
-{
-       int failures = 0;
-       static int overshoot = 1;
-       static int min_rewind = 2;      /* 1 + overshoot */
-       static const int margin = 1;    /* stop this before target */
-       int expected = 0;
-       int count = 1;
-       int short_seek;
-       int target = segment_id - margin;
-       TRACE_FUN(ft_t_flow);
-
-       if (ft_location.known && !validate(segment_id)) {
-               ftape_sleep(1 * FT_SECOND);
-               ft_failure = 1;
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "fatal: head off track (bad hardware?)");
-       }
-       do {
-               if (!ft_location.known) {
-                       TRACE(ft_t_warn, "warning: location not known");
-               }
-               TRACE(ft_t_noise, "from %d/%d to %d/0 - %d",
-                     ft_location.segment, ft_location.sector,
-                     segment_id, margin);
-               /*  min_rewind == 1 + overshoot_when_doing_minimum_rewind
-                *  overshoot  == overshoot_when_doing_larger_rewind
-                *  Initially min_rewind == 1 + overshoot, optimization
-                *  of both values will be done separately.
-                *  overshoot and min_rewind can be negative as both are
-                *  sums of three components:
-                *  any_overshoot == rewind_overshoot - 
-                *                   stop_overshoot   -
-                *                   start_overshoot
-                */
-               if (ft_location.segment - target - (min_rewind - 1) < 1) {
-                       short_seek = 1;
-               } else {
-                       count = ft_location.segment - target - overshoot;
-                       short_seek = (count < 1);
-               }
-               if (short_seek) {
-                       count = 1;      /* do shortest rewind */
-                       expected = ft_location.segment - min_rewind;
-                       if (expected/ft_segments_per_track != ft_location.track) {
-                               expected = (ft_location.track * 
-                                           ft_segments_per_track);
-                       }
-               } else {
-                       expected = target;
-               }
-               fast_seek(count, 1);
-               logical_forward();
-               if (ftape_read_id() < 0 || !ft_location.known ||
-                   (sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) {
-                       if ((!ftape_tape_running && !ft_location.known) ||
-                           ++failures > FT_SECTORS_PER_SEGMENT) {
-                               TRACE_ABORT(-EIO, ft_t_err,
-                                           "read_id failed completely");
-                       }
-                       FT_SIGNAL_EXIT(_DONT_BLOCK);
-                       TRACE_CATCH(ftape_report_drive_status(pstatus),);
-                       TRACE(ft_t_noise, "ftape_read_id failed, retry (%d)",
-                             failures);
-                       continue;
-               }
-               TRACE(ft_t_noise, "ended at %d/%d (%d,%d,%d)", 
-                     ft_location.segment, ft_location.sector,
-                     min_rewind, overshoot, inhibit_correction);
-               if (!inhibit_correction &&
-                   (ft_location.segment < expected ||
-                    ft_location.segment > expected + margin)) {
-                       int error = expected - ft_location.segment;
-                       if (short_seek) {
-                               TRACE(ft_t_noise,
-                                     "adjusting min_rewind from %d to %d",
-                                     min_rewind, min_rewind + error);
-                               min_rewind += error;
-                               if (min_rewind < -5) {
-                                       /* is this right ? FIXME ! */
-                                       /* keep sane value */
-                                       min_rewind = -5;
-                                       TRACE(ft_t_noise, 
-                                             "clipped min_rewind to %d",
-                                             min_rewind);
-                               }
-                       } else {
-                               TRACE(ft_t_noise,
-                                     "adjusting overshoot from %d to %d",
-                                     overshoot, overshoot + error);
-                               overshoot += error;
-                               if (overshoot < -5 ||
-                                   overshoot > OVERSHOOT_LIMIT) {
-                                       if (overshoot < 0) {
-                                               /* keep sane value */
-                                               overshoot = -5;
-                                       } else {
-                                               /* keep sane value */
-                                               overshoot = OVERSHOOT_LIMIT;
-                                       }
-                                       TRACE(ft_t_noise,
-                                             "clipped overshoot to %d",
-                                             overshoot);
-                               }
-                       }
-               }
-       } while (ft_location.segment > segment_id);
-       if (ft_location.known) {
-               TRACE(ft_t_noise, "current location: %d/%d",
-                     ft_location.segment, ft_location.sector);
-       }
-       TRACE_EXIT 0;
-}
-
-static int determine_position(void)
-{
-       int retry = 0;
-       int status;
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       if (!ftape_tape_running) {
-               /*  This should only happen if tape is stopped by isr.
-                */
-               TRACE(ft_t_flow, "waiting for tape stop");
-               if (ftape_ready_wait(ftape_timeout.pause, &status) < 0) {
-                       TRACE(ft_t_flow, "drive still running (fatal)");
-                       ftape_tape_running = 1; /* ? */
-               }
-       } else {
-               ftape_report_drive_status(&status);
-       }
-       if (status & QIC_STATUS_READY) {
-               /*  Drive must be ready to check error state !
-                */
-               TRACE(ft_t_flow, "drive is ready");
-               if (status & QIC_STATUS_ERROR) {
-                       unsigned int error;
-                       qic117_cmd_t command;
-
-                       /*  Report and clear error state, try to continue.
-                        */
-                       TRACE(ft_t_flow, "error status set");
-                       ftape_report_error(&error, &command, 1);
-                       ftape_ready_wait(ftape_timeout.reset, &status);
-                       ftape_tape_running = 0; /* ? */
-               }
-               if (check_bot_eot(status)) {
-                       if (ft_location.bot) {
-                               if ((status & QIC_STATUS_READY) == 0) {
-                                       /* tape moving away from
-                                        * bot/eot, let's see if we
-                                        * can catch up with the first
-                                        * segment on this track.
-                                        */
-                               } else {
-                                       TRACE(ft_t_flow,
-                                             "start tape from logical bot");
-                                       logical_forward();      /* start moving */
-                               }
-                       } else {
-                               if ((status & QIC_STATUS_READY) == 0) {
-                                       TRACE(ft_t_noise, "waiting for logical end of track");
-                                       result = ftape_ready_wait(ftape_timeout.reset, &status);
-                                       /* error handling needed ? */
-                               } else {
-                                       TRACE(ft_t_noise,
-                                             "tape at logical end of track");
-                               }
-                       }
-               } else {
-                       TRACE(ft_t_flow, "start tape");
-                       logical_forward();      /* start moving */
-                       ft_location.known = 0;  /* not cleared by logical forward ! */
-               }
-       }
-       /* tape should be moving now, start reading id's
-        */
-       while (!ft_location.known &&
-              retry++ < FT_SECTORS_PER_SEGMENT &&
-              (result = ftape_read_id()) < 0) {
-
-               TRACE(ft_t_flow, "location unknown");
-
-               /* exit on signal
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-
-               /*  read-id somehow failed, tape may
-                *  have reached end or some other
-                *  error happened.
-                */
-               TRACE(ft_t_flow, "read-id failed");
-               TRACE_CATCH(ftape_report_drive_status(&status),);
-               TRACE(ft_t_err, "ftape_report_drive_status: 0x%02x", status);
-               if (status & QIC_STATUS_READY) {
-                       ftape_tape_running = 0;
-                       TRACE(ft_t_noise, "tape stopped for unknown reason! "
-                             "status = 0x%02x", status);
-                       if (status & QIC_STATUS_ERROR ||
-                           !check_bot_eot(status)) {
-                               /* oops, tape stopped but not at end!
-                                */
-                               TRACE_EXIT -EIO;
-                       }
-               }
-       }
-       TRACE(ft_t_flow,
-             "tape is positioned at segment %d", ft_location.segment);
-       TRACE_EXIT ft_location.known ? 0 : -EIO;
-}
-
-/*      Get the tape running and position it just before the
- *      requested segment.
- *      Seek tape-track and reposition as needed.
- */
-int ftape_start_tape(int segment_id, int sector_offset)
-{
-       int track = segment_id / ft_segments_per_track;
-       int result = -EIO;
-       int status;
-       static int last_segment = -1;
-       static int bad_bus_timing = 0;
-       /* number of segments passing the head between starting the tape
-        * and being able to access the first sector.
-        */
-       static int start_offset = 1;
-       int retry;
-       TRACE_FUN(ft_t_flow);
-
-       /* If sector_offset > 0, seek into wanted segment instead of
-        * into previous.
-        * This allows error recovery if a part of the segment is bad
-        * (erased) causing the tape drive to generate an index pulse
-        * thus causing a no-data error before the requested sector
-        * is reached.
-        */
-       ftape_tape_running = 0;
-       TRACE(ft_t_noise, "target segment: %d/%d%s", segment_id, sector_offset,
-               ft_buffer[ft_head]->retry > 0 ? " retry" : "");
-       if (ft_buffer[ft_head]->retry > 0) {    /* this is a retry */
-               int dist = segment_id - last_segment;
-
-               if ((int)ft_history.overrun_errors < overrun_count_offset) {
-                       overrun_count_offset = ft_history.overrun_errors;
-               } else if (dist < 0 || dist > 50) {
-                       overrun_count_offset = ft_history.overrun_errors;
-               } else if ((ft_history.overrun_errors -
-                           overrun_count_offset) >= 8) {
-                       if (ftape_increase_threshold() >= 0) {
-                               --ft_buffer[ft_head]->retry;
-                               overrun_count_offset =
-                                       ft_history.overrun_errors;
-                               TRACE(ft_t_warn, "increased threshold because "
-                                     "of excessive overrun errors");
-                       } else if (!bad_bus_timing && ft_data_rate >= 1000) {
-                               ftape_half_data_rate();
-                               --ft_buffer[ft_head]->retry;
-                               bad_bus_timing = 1;
-                               overrun_count_offset =
-                                       ft_history.overrun_errors;
-                               TRACE(ft_t_warn, "reduced datarate because "
-                                     "of excessive overrun errors");
-                       }
-               }
-       }
-       last_segment = segment_id;
-       if (ft_location.track != track ||
-           (ftape_might_be_off_track && ft_buffer[ft_head]->retry== 0)) {
-               /* current track unknown or not equal to destination
-                */
-               ftape_ready_wait(ftape_timeout.seek, &status);
-               ftape_seek_head_to_track(track);
-               /* overrun_count_offset = ft_history.overrun_errors; */
-       }
-       result = -EIO;
-       retry = 0;
-       while (result < 0     &&
-              retry++ <= 5   &&
-              !ft_failure &&
-              !(sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) {
-               
-               if (retry && start_offset < 5) {
-                       start_offset ++;
-               }
-               /*  Check if we are able to catch the requested
-                *  segment in time.
-                */
-               if ((ft_location.known || (determine_position() == 0)) &&
-                   ft_location.segment >=
-                   (segment_id -
-                    ((ftape_tape_running || ft_location.bot)
-                     ? 0 : start_offset))) {
-                       /*  Too far ahead (in or past target segment).
-                        */
-                       if (ftape_tape_running) {
-                               if ((result = ftape_stop_tape(&status)) < 0) {
-                                       TRACE(ft_t_err,
-                                             "stop tape failed with code %d",
-                                             result);
-                                       break;
-                               }
-                               TRACE(ft_t_noise, "tape stopped");
-                               ftape_tape_running = 0;
-                       }
-                       TRACE(ft_t_noise, "repositioning");
-                       ++ft_history.rewinds;
-                       if (segment_id % ft_segments_per_track < start_offset){
-                               TRACE(ft_t_noise, "end of track condition\n"
-                                     KERN_INFO "segment_id        : %d\n"
-                                     KERN_INFO "ft_segments_per_track: %d\n"
-                                     KERN_INFO "start_offset      : %d",
-                                     segment_id, ft_segments_per_track, 
-                                     start_offset);
-                                     
-                               /*  If seeking to first segments on
-                                *  track better do a complete rewind
-                                *  to logical begin of track to get a
-                                *  more steady tape motion.  
-                                */
-                               result = ftape_command_wait(
-                                       (ft_location.track & 1)
-                                       ? QIC_PHYSICAL_FORWARD
-                                       : QIC_PHYSICAL_REVERSE,
-                                       ftape_timeout.rewind, &status);
-                               check_bot_eot(status);  /* update location */
-                       } else {
-                               result= skip_reverse(segment_id - start_offset,
-                                                    &status);
-                       }
-               }
-               if (!ft_location.known) {
-                       TRACE(ft_t_bug, "panic: location not known");
-                       result = -EIO;
-                       continue; /* while() will check for failure */
-               }
-               TRACE(ft_t_noise, "current segment: %d/%d",
-                     ft_location.segment, ft_location.sector);
-               /*  We're on the right track somewhere before the
-                *  wanted segment.  Start tape movement if needed and
-                *  skip to just before or inside the requested
-                *  segment. Keep tape running.  
-                */
-               result = 0;
-               if (ft_location.segment < 
-                   (segment_id - ((ftape_tape_running || ft_location.bot)
-                                  ? 0 : start_offset))) {
-                       if (sector_offset > 0) {
-                               result = seek_forward(segment_id,
-                                                     retry <= 3);
-                       } else {
-                               result = seek_forward(segment_id - 1,
-                                                     retry <= 3);
-                       }
-               }
-               if (result == 0 &&
-                   ft_location.segment !=
-                   (segment_id - (sector_offset > 0 ? 0 : 1))) {
-                       result = -EIO;
-               }
-       }
-       if (result < 0) {
-               TRACE(ft_t_err, "failed to reposition");
-       } else {
-               ft_runner_status = running;
-       }
-       TRACE_EXIT result;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-rw.h b/drivers/char/ftape/lowlevel/ftape-rw.h
deleted file mode 100644 (file)
index 32f4fee..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _FTAPE_RW_H
-#define _FTAPE_RW_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-rw.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:25 $
- *
- *      This file contains the definitions for the read and write
- *      functions for the QIC-117 floppy-tape driver for Linux.
- *
- * Claus-Justus Heine (1996/09/20): Add definition of format code 6
- * Claus-Justus Heine (1996/10/04): Changed GET/PUT macros to cast to (__u8 *)
- *
- */
-
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-bsm.h"
-
-#include <asm/unaligned.h>
-
-#define GET2(address, offset) get_unaligned((__u16*)((__u8 *)address + offset))
-#define GET4(address, offset) get_unaligned((__u32*)((__u8 *)address + offset))
-#define GET8(address, offset) get_unaligned((__u64*)((__u8 *)address + offset))
-#define PUT2(address, offset , value) put_unaligned((value), (__u16*)((__u8 *)address + offset))
-#define PUT4(address, offset , value) put_unaligned((value), (__u32*)((__u8 *)address + offset))
-#define PUT8(address, offset , value) put_unaligned((value), (__u64*)((__u8 *)address + offset))
-
-enum runner_status_enum {
-       idle = 0,
-       running,
-       do_abort,
-       aborting,
-       logical_eot,
-       end_of_tape,
-};
-
-typedef enum ft_buffer_queue {
-       ft_queue_head = 0,
-       ft_queue_tail = 1
-} ft_buffer_queue_t;
-
-
-typedef struct {
-       int track;              /* tape head position */
-       volatile int segment;   /* current segment */
-       volatile int sector;    /* sector offset within current segment */
-       volatile unsigned int bot;      /* logical begin of track */
-       volatile unsigned int eot;      /* logical end of track */
-       volatile unsigned int known;    /* validates bot, segment, sector */
-} location_record;
-
-/*      Count nr of 1's in pattern.
- */
-static inline int count_ones(unsigned long mask)
-{
-       int bits;
-
-       for (bits = 0; mask != 0; mask >>= 1) {
-               if (mask & 1) {
-                       ++bits;
-               }
-       }
-       return bits;
-}
-
-#define FT_MAX_NR_BUFFERS 16 /* arbitrary value */
-/*      ftape-rw.c defined global vars.
- */
-extern buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS];
-extern int ft_nr_buffers;
-extern location_record ft_location;
-extern volatile int ftape_tape_running;
-
-/*      ftape-rw.c defined global functions.
- */
-extern int  ftape_setup_new_segment(buffer_struct * buff,
-                                   int segment_id,
-                                   int offset);
-extern int  ftape_calc_next_cluster(buffer_struct * buff);
-extern buffer_struct *ftape_next_buffer (ft_buffer_queue_t pos);
-extern buffer_struct *ftape_get_buffer  (ft_buffer_queue_t pos);
-extern int            ftape_buffer_id   (ft_buffer_queue_t pos);
-extern void           ftape_reset_buffer(void);
-extern void ftape_tape_parameters(__u8 drive_configuration);
-extern int  ftape_wait_segment(buffer_state_enum state);
-extern int  ftape_dumb_stop(void);
-extern int  ftape_start_tape(int segment_id, int offset);
-extern int  ftape_stop_tape(int *pstatus);
-extern int  ftape_handle_logical_eot(void);
-extern buffer_state_enum ftape_set_state(buffer_state_enum new_state);
-#endif                         /* _FTAPE_RW_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-setup.c b/drivers/char/ftape/lowlevel/ftape-setup.c
deleted file mode 100644 (file)
index 678340a..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* 
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-setup.c,v $
- * $Revision: 1.7 $
- * $Date: 1997/10/10 09:57:06 $
- *
- *      This file contains the code for processing the kernel command
- *      line options for the QIC-40/80/3010/3020 floppy-tape driver
- *      "ftape" for Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/ftape.h>
-#include <linux/init.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-
-static struct param_table {
-       const char *name;
-       int *var;
-       int def_param;
-       int min;
-       int max;
-} config_params[] __initdata = {
-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
-       { "tracing",   &ftape_tracing,     3,              ft_t_bug, ft_t_any},
-#endif
-       { "ioport",    &ft_fdc_base,       CONFIG_FT_FDC_BASE,     0x0, 0xfff},
-       { "irq",       &ft_fdc_irq,        CONFIG_FT_FDC_IRQ,        2,    15},
-       { "dma",       &ft_fdc_dma,        CONFIG_FT_FDC_DMA,        0,     3},
-       { "threshold", &ft_fdc_threshold,  CONFIG_FT_FDC_THR,         1,    16},
-       { "datarate",  &ft_fdc_rate_limit, CONFIG_FT_FDC_MAX_RATE, 500,  2000},
-       { "fc10",      &ft_probe_fc10,     CONFIG_FT_PROBE_FC10,     0,     1},
-       { "mach2",     &ft_mach2,          CONFIG_FT_MACH2,          0,     1}
-};
-
-static int __init ftape_setup(char *str)
-{
-       int i;
-       int param;
-       int ints[2];
-
-       TRACE_FUN(ft_t_flow);
-
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       if (str) {
-               for (i=0; i < NR_ITEMS(config_params); i++) {
-                       if (strcmp(str,config_params[i].name) == 0){
-                               if (ints[0]) {
-                                       param = ints[1];
-                               } else {
-                                       param = config_params[i].def_param;
-                               }
-                               if (param < config_params[i].min ||
-                                   param > config_params[i].max) {
-                                       TRACE(ft_t_err,
-                                       "parameter %s out of range %d ... %d",
-                                             config_params[i].name,
-                                             config_params[i].min,
-                                             config_params[i].max);
-                                       goto out;
-                               }
-                               if(config_params[i].var) {
-                                       TRACE(ft_t_info, "%s=%d", str, param);
-                                       *config_params[i].var = param;
-                               }
-                               goto out;
-                       }
-               }
-       }
-       if (str) {
-               TRACE(ft_t_err, "unknown ftape option [%s]", str);
-               
-               TRACE(ft_t_err, "allowed options are:");
-               for (i=0; i < NR_ITEMS(config_params); i++) {
-                       TRACE(ft_t_err, " %s",config_params[i].name);
-               }
-       } else {
-               TRACE(ft_t_err, "botched ftape option");
-       }
- out:
-       TRACE_EXIT 1;
-}
-
-__setup("ftape=", ftape_setup);
diff --git a/drivers/char/ftape/lowlevel/ftape-tracing.c b/drivers/char/ftape/lowlevel/ftape-tracing.c
deleted file mode 100644 (file)
index 7fdc656..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven,
- *                (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-tracing.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:27 $
- *
- *      This file contains the reading code
- *      for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-
-/*      Global vars.
- */
-/*      tracing
- *      set it to:     to log :
- *       0              bugs
- *       1              + errors
- *       2              + warnings
- *       3              + information
- *       4              + more information
- *       5              + program flow
- *       6              + fdc/dma info
- *       7              + data flow
- *       8              + everything else
- */
-ft_trace_t ftape_tracing = ft_t_info; /* Default level: information and up */
-int  ftape_function_nest_level;
-
-/*      Local vars.
- */
-static __u8 trace_id;
-static char spacing[] = "*                              ";
-
-void ftape_trace_call(const char *file, const char *name)
-{
-       char *indent;
-
-       /*    Since printk seems not to work with "%*s" format
-        *    we'll use this work-around.
-        */
-       if (ftape_function_nest_level < 0) {
-               printk(KERN_INFO "function nest level (%d) < 0\n",
-                      ftape_function_nest_level);
-               ftape_function_nest_level = 0;
-       }
-       if (ftape_function_nest_level < sizeof(spacing)) {
-               indent = (spacing +
-                         sizeof(spacing) - 1 -
-                         ftape_function_nest_level);
-       } else {
-               indent = spacing;
-       }
-       printk(KERN_INFO "[%03d]%s+%s (%s)\n",
-              (int) trace_id++, indent, file, name);
-}
-
-void ftape_trace_exit(const char *file, const char *name)
-{
-       char *indent;
-
-       /*    Since printk seems not to work with "%*s" format
-        *    we'll use this work-around.
-        */
-       if (ftape_function_nest_level < 0) {
-               printk(KERN_INFO "function nest level (%d) < 0\n", ftape_function_nest_level);
-               ftape_function_nest_level = 0;
-       }
-       if (ftape_function_nest_level < sizeof(spacing)) {
-               indent = (spacing +
-                         sizeof(spacing) - 1 -
-                         ftape_function_nest_level);
-       } else {
-               indent = spacing;
-       }
-       printk(KERN_INFO "[%03d]%s-%s (%s)\n",
-              (int) trace_id++, indent, file, name);
-}
-
-void ftape_trace_log(const char *file, const char *function)
-{
-       char *indent;
-
-       /*    Since printk seems not to work with "%*s" format
-        *    we'll use this work-around.
-        */
-       if (ftape_function_nest_level < 0) {
-               printk(KERN_INFO "function nest level (%d) < 0\n", ftape_function_nest_level);
-               ftape_function_nest_level = 0;
-       }
-       if (ftape_function_nest_level < sizeof(spacing)) {
-               indent = (spacing + 
-                         sizeof(spacing) - 1 - 
-                         ftape_function_nest_level);
-       } else {
-               indent = spacing;
-       }
-       printk(KERN_INFO "[%03d]%s%s (%s) - ", 
-              (int) trace_id++, indent, file, function);
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-tracing.h b/drivers/char/ftape/lowlevel/ftape-tracing.h
deleted file mode 100644 (file)
index 2950810..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-#ifndef _FTAPE_TRACING_H
-#define _FTAPE_TRACING_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-tracing.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:28 $
- *
- *      This file contains definitions that eases the debugging of the
- *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/kernel.h>
-
-/*
- *  Be very careful with TRACE_EXIT and TRACE_ABORT.
- *
- *  if (something) TRACE_EXIT error;
- *
- *  will NOT work. Use
- *
- *  if (something) {
- *    TRACE_EXIT error;
- *  }
- *
- *  instead. Maybe a bit dangerous, but save lots of lines of code.
- */
-
-#define LL_X "%d/%d KB"
-#define LL(x) (unsigned int)((__u64)(x)>>10), (unsigned int)((x)&1023)
-
-typedef enum {
-       ft_t_nil = -1,
-       ft_t_bug,
-       ft_t_err,
-       ft_t_warn,
-       ft_t_info,
-       ft_t_noise,
-       ft_t_flow,
-       ft_t_fdc_dma,
-       ft_t_data_flow,
-       ft_t_any
-} ft_trace_t;
-
-#ifdef  CONFIG_FT_NO_TRACE_AT_ALL
-/*  the compiler will optimize away most TRACE() macros
- */
-#define FT_TRACE_TOP_LEVEL     ft_t_bug
-#define TRACE_FUN(level)       do {} while(0)
-#define TRACE_EXIT             return
-#define TRACE(l, m, i...)                                              \
-{                                                                      \
-       if ((ft_trace_t)(l) == FT_TRACE_TOP_LEVEL) {                    \
-               printk(KERN_INFO"ftape%s(%s):\n"                        \
-                      KERN_INFO m".\n" ,__FILE__, __FUNCTION__ , ##i); \
-       }                                                               \
-}
-#define SET_TRACE_LEVEL(l)      if ((l) == (l)) do {} while(0)
-#define TRACE_LEVEL            FT_TRACE_TOP_LEVEL
-
-#else
-
-#ifdef CONFIG_FT_NO_TRACE
-/*  the compiler will optimize away many TRACE() macros
- *  the ftape_simple_trace_call() function simply increments 
- *  the function nest level.
- */ 
-#define FT_TRACE_TOP_LEVEL     ft_t_warn
-#define TRACE_FUN(level)       ftape_function_nest_level++
-#define TRACE_EXIT             ftape_function_nest_level--; return
-
-#else
-#ifdef CONFIG_FT_FULL_DEBUG
-#define FT_TRACE_TOP_LEVEL ft_t_any
-#else
-#define FT_TRACE_TOP_LEVEL ft_t_flow
-#endif
-#define TRACE_FUN(level)                                       \
-       const ft_trace_t _tracing = level;                      \
-       if (ftape_tracing >= (ft_trace_t)(level) &&             \
-           (ft_trace_t)(level) <= FT_TRACE_TOP_LEVEL)          \
-               ftape_trace_call(__FILE__, __FUNCTION__);       \
-       ftape_function_nest_level ++;
-
-#define TRACE_EXIT                                             \
-       --ftape_function_nest_level;                            \
-       if (ftape_tracing >= (ft_trace_t)(_tracing) &&          \
-           (ft_trace_t)(_tracing) <= FT_TRACE_TOP_LEVEL)       \
-               ftape_trace_exit(__FILE__, __FUNCTION__);       \
-       return
-
-#endif
-
-#define TRACE(l, m, i...)                                      \
-{                                                              \
-       if (ftape_tracing >= (ft_trace_t)(l) &&                 \
-           (ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) {            \
-               ftape_trace_log(__FILE__, __FUNCTION__);        \
-               printk(m".\n" ,##i);                            \
-       }                                                       \
-}
-
-#define SET_TRACE_LEVEL(l)                             \
-{                                                      \
-       if ((ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) {    \
-               ftape_tracing = (ft_trace_t)(l);        \
-       } else {                                        \
-               ftape_tracing = FT_TRACE_TOP_LEVEL;     \
-       }                                               \
-}
-#define TRACE_LEVEL                                                                 \
-((ftape_tracing <= FT_TRACE_TOP_LEVEL) ? ftape_tracing : FT_TRACE_TOP_LEVEL)
-
-
-/*      Global variables declared in tracing.c
- */
-extern ft_trace_t ftape_tracing;  /* sets default level */
-extern int ftape_function_nest_level;
-
-/*      Global functions declared in tracing.c
- */
-extern void ftape_trace_call(const char *file, const char *name);
-extern void ftape_trace_exit(const char *file, const char *name);
-extern void ftape_trace_log (const char *file, const char *name);
-
-#endif /* !defined(CONFIG_FT_NO_TRACE_AT_ALL) */
-
-/*
- *   Abort with a message.
- */
-#define TRACE_ABORT(res, i...)                 \
-{                                              \
-       TRACE(i);                               \
-       TRACE_EXIT res;                         \
-}
-
-/*   The following transforms the common "if(result < 0) ... " into a
- *   one-liner.
- */
-#define _TRACE_CATCH(level, fun, action)                               \
-{                                                                      \
-       int _res = (fun);                                               \
-       if (_res < 0) {                                                 \
-               do { action /* */ ; } while(0);                         \
-               TRACE_ABORT(_res, level, "%s failed: %d", #fun, _res);  \
-       }                                                               \
-}
-
-#define TRACE_CATCH(fun, fail) _TRACE_CATCH(ft_t_err, fun, fail)
-
-/*  Abort the current function when signalled. This doesn't belong here,
- *  but rather into ftape-rw.h (maybe)
- */
-#define FT_SIGNAL_EXIT(sig_mask)                                       \
-       if (sigtestsetmask(&current->pending.signal, sig_mask)) {       \
-               TRACE_ABORT(-EINTR,                                     \
-                           ft_t_warn,                                  \
-                           "interrupted by non-blockable signal");     \
-       }
-
-#endif /* _FTAPE_TRACING_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-write.c b/drivers/char/ftape/lowlevel/ftape-write.c
deleted file mode 100644 (file)
index 45601ec..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- *      Copyright (C) 1993-1995 Bas Laarhoven,
- *                (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-write.c,v $
- * $Revision: 1.3.4.1 $
- * $Date: 1997/11/14 18:07:04 $
- *
- *      This file contains the writing code
- *      for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/fdc-isr.h"
-
-/*      Global vars.
- */
-
-/*      Local vars.
- */
-static int last_write_failed;
-
-void ftape_zap_write_buffers(void)
-{
-       int i;
-
-       for (i = 0; i < ft_nr_buffers; ++i) {
-               ft_buffer[i]->status = done;
-       }
-       ftape_reset_buffer();
-}
-
-static int copy_and_gen_ecc(void *destination, 
-                           const void *source,
-                           const SectorMap bad_sector_map)
-{
-       int result;
-       struct memory_segment mseg;
-       int bads = count_ones(bad_sector_map);
-       TRACE_FUN(ft_t_any);
-
-       if (bads > 0) {
-               TRACE(ft_t_noise, "bad sectors in map: %d", bads);
-       }
-       if (bads + 3 >= FT_SECTORS_PER_SEGMENT) {
-               TRACE(ft_t_noise, "empty segment");
-               mseg.blocks = 0; /* skip entire segment */
-               result = 0;      /* nothing written */
-       } else {
-               mseg.blocks = FT_SECTORS_PER_SEGMENT - bads;
-               mseg.data = destination;
-               memcpy(mseg.data, source, (mseg.blocks - 3) * FT_SECTOR_SIZE);
-               result = ftape_ecc_set_segment_parity(&mseg);
-               if (result < 0) {
-                       TRACE(ft_t_err, "ecc_set_segment_parity failed");
-               } else {
-                       result = (mseg.blocks - 3) * FT_SECTOR_SIZE;
-               }
-       }
-       TRACE_EXIT result;
-}
-
-
-int ftape_start_writing(const ft_write_mode_t mode)
-{
-       buffer_struct *head = ftape_get_buffer(ft_queue_head);
-       int segment_id = head->segment_id;
-       int result;
-       buffer_state_enum wanted_state = (mode == FT_WR_DELETE
-                                         ? deleting
-                                         : writing);
-       TRACE_FUN(ft_t_flow);
-
-       if ((ft_driver_state != wanted_state) || head->status != waiting) {
-               TRACE_EXIT 0;
-       }
-       ftape_setup_new_segment(head, segment_id, 1);
-       if (mode == FT_WR_SINGLE) {
-               /* stop tape instead of pause */
-               head->next_segment = 0;
-       }
-       ftape_calc_next_cluster(head); /* prepare */
-       head->status = ft_driver_state; /* either writing or deleting */
-       if (ft_runner_status == idle) {
-               TRACE(ft_t_noise,
-                     "starting runner for segment %d", segment_id);
-               TRACE_CATCH(ftape_start_tape(segment_id,head->sector_offset),);
-       } else {
-               TRACE(ft_t_noise, "runner not idle, not starting tape");
-       }
-       /* go */
-       result = fdc_setup_read_write(head, (mode == FT_WR_DELETE
-                                            ? FDC_WRITE_DELETED : FDC_WRITE));
-       ftape_set_state(wanted_state); /* should not be necessary */
-       TRACE_EXIT result;
-}
-
-/*  Wait until all data is actually written to tape.
- *  
- *  There is a problem: when the tape runs into logical EOT, then this
- *  failes. We need to restart the runner in this case.
- */
-int ftape_loop_until_writes_done(void)
-{
-       buffer_struct *head;
-       TRACE_FUN(ft_t_flow);
-
-       while ((ft_driver_state == writing || ft_driver_state == deleting) && 
-              ftape_get_buffer(ft_queue_head)->status != done) {
-               /* set the runner status to idle if at lEOT */
-               TRACE_CATCH(ftape_handle_logical_eot(), last_write_failed = 1);
-               /* restart the tape if necessary */
-               if (ft_runner_status == idle) {
-                       TRACE(ft_t_noise, "runner is idle, restarting");
-                       if (ft_driver_state == deleting) {
-                               TRACE_CATCH(ftape_start_writing(FT_WR_DELETE),
-                                           last_write_failed = 1);
-                       } else {
-                               TRACE_CATCH(ftape_start_writing(FT_WR_MULTI),
-                                           last_write_failed = 1);
-                       }
-               }
-               TRACE(ft_t_noise, "tail: %d, head: %d", 
-                     ftape_buffer_id(ft_queue_tail),
-                     ftape_buffer_id(ft_queue_head));
-               TRACE_CATCH(fdc_interrupt_wait(5 * FT_SECOND),
-                           last_write_failed = 1);
-               head = ftape_get_buffer(ft_queue_head);
-               if (head->status == error) {
-                       /* Allow escape from loop when signaled !
-                        */
-                       FT_SIGNAL_EXIT(_DONT_BLOCK);
-                       if (head->hard_error_map != 0) {
-                               /*  Implement hard write error recovery here
-                                */
-                       }
-                       /* retry this one */
-                       head->status = waiting;
-                       if (ft_runner_status == aborting) {
-                               ftape_dumb_stop();
-                       }
-                       if (ft_runner_status != idle) {
-                               TRACE_ABORT(-EIO, ft_t_err,
-                                           "unexpected state: "
-                                           "ft_runner_status != idle");
-                       }
-                       ftape_start_writing(ft_driver_state == deleting
-                                           ? FT_WR_MULTI : FT_WR_DELETE);
-               }
-               TRACE(ft_t_noise, "looping until writes done");
-       }
-       ftape_set_state(idle);
-       TRACE_EXIT 0;
-}
-
-/*      Write given segment from buffer at address to tape.
- */
-static int write_segment(const int segment_id,
-                        const void *address, 
-                        const ft_write_mode_t write_mode)
-{
-       int bytes_written = 0;
-       buffer_struct *tail;
-       buffer_state_enum wanted_state = (write_mode == FT_WR_DELETE
-                                         ? deleting : writing);
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "segment_id = %d", segment_id);
-       if (ft_driver_state != wanted_state) {
-               if (ft_driver_state == deleting ||
-                   wanted_state == deleting) {
-                       TRACE_CATCH(ftape_loop_until_writes_done(),);
-               }
-               TRACE(ft_t_noise, "calling ftape_abort_operation");
-               TRACE_CATCH(ftape_abort_operation(),);
-               ftape_zap_write_buffers();
-               ftape_set_state(wanted_state);
-       }
-       /*    if all buffers full we'll have to wait...
-        */
-       ftape_wait_segment(wanted_state);
-       tail = ftape_get_buffer(ft_queue_tail);
-       switch(tail->status) {
-       case done:
-               ft_history.defects += count_ones(tail->hard_error_map);
-               break;
-       case waiting:
-               /* this could happen with multiple EMPTY_SEGMENTs, but
-                * shouldn't happen any more as we re-start the runner even
-                * with an empty segment.
-                */
-               bytes_written = -EAGAIN;
-               break;
-       case error:
-               /*  setup for a retry
-                */
-               tail->status = waiting;
-               bytes_written = -EAGAIN; /* force retry */
-               if (tail->hard_error_map != 0) {
-                       TRACE(ft_t_warn, 
-                             "warning: %d hard error(s) in written segment",
-                             count_ones(tail->hard_error_map));
-                       TRACE(ft_t_noise, "hard_error_map = 0x%08lx", 
-                             (long)tail->hard_error_map);
-                       /*  Implement hard write error recovery here
-                        */
-               }
-               break;
-       default:
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "wait for empty segment failed, tail status: %d",
-                           tail->status);
-       }
-       /*    should runner stop ?
-        */
-       if (ft_runner_status == aborting) {
-               buffer_struct *head = ftape_get_buffer(ft_queue_head);
-               if (head->status == wanted_state) {
-                       head->status = done; /* ???? */
-               }
-               /*  don't call abort_operation(), we don't want to zap
-                *  the dma buffers
-                */
-               TRACE_CATCH(ftape_dumb_stop(),);
-       } else {
-               /*  If just passed last segment on tape: wait for BOT
-                *  or EOT mark. Sets ft_runner_status to idle if at lEOT
-                *  and successful 
-                */
-               TRACE_CATCH(ftape_handle_logical_eot(),);
-       }
-       if (tail->status == done) {
-               /* now at least one buffer is empty, fill it with our
-                * data.  skip bad sectors and generate ecc.
-                * copy_and_gen_ecc return nr of bytes written, range
-                * 0..29 Kb inclusive!  
-                *
-                * Empty segments are handled inside coyp_and_gen_ecc()
-                */
-               if (write_mode != FT_WR_DELETE) {
-                       TRACE_CATCH(bytes_written = copy_and_gen_ecc(
-                               tail->address, address,
-                               ftape_get_bad_sector_entry(segment_id)),);
-               }
-               tail->segment_id = segment_id;
-               tail->status = waiting;
-               tail = ftape_next_buffer(ft_queue_tail);
-       }
-       /*  Start tape only if all buffers full or flush mode.
-        *  This will give higher probability of streaming.
-        */
-       if (ft_runner_status != running && 
-           ((tail->status == waiting &&
-             ftape_get_buffer(ft_queue_head) == tail) ||
-            write_mode != FT_WR_ASYNC)) {
-               TRACE_CATCH(ftape_start_writing(write_mode),);
-       }
-       TRACE_EXIT bytes_written;
-}
-
-/*  Write as much as fits from buffer to the given segment on tape
- *  and handle retries.
- *  Return the number of bytes written (>= 0), or:
- *      -EIO          write failed
- *      -EINTR        interrupted by signal
- *      -ENOSPC       device full
- */
-int ftape_write_segment(const int segment_id,
-                       const void *buffer, 
-                       const ft_write_mode_t flush)
-{
-       int retry = 0;
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       ft_history.used |= 2;
-       if (segment_id >= ft_tracks_per_tape*ft_segments_per_track) {
-               /* tape full */
-               TRACE_ABORT(-ENOSPC, ft_t_err,
-                           "invalid segment id: %d (max %d)", 
-                           segment_id, 
-                           ft_tracks_per_tape * ft_segments_per_track -1);
-       }
-       for (;;) {
-               if ((result = write_segment(segment_id, buffer, flush)) >= 0) {
-                       if (result == 0) { /* empty segment */
-                               TRACE(ft_t_noise,
-                                     "empty segment, nothing written");
-                       }
-                       TRACE_EXIT result;
-               }
-               if (result == -EAGAIN) {
-                       if (++retry > 100) { /* give up */
-                               TRACE_ABORT(-EIO, ft_t_err,
-                                     "write failed, >100 retries in segment");
-                       }
-                       TRACE(ft_t_warn, "write error, retry %d (%d)",
-                             retry,
-                             ftape_get_buffer(ft_queue_tail)->segment_id);
-               } else {
-                       TRACE_ABORT(result, ft_t_err,
-                                   "write_segment failed, error: %d", result);
-               }
-               /* Allow escape from loop when signaled !
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-       }
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-write.h b/drivers/char/ftape/lowlevel/ftape-write.h
deleted file mode 100644 (file)
index 0e7f898..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _FTAPE_WRITE_H
-#define _FTAPE_WRITE_H
-
-/*
- * Copyright (C) 1994-1995 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-write.h,v $
- $Author: claus $
- *
- $Revision: 1.2 $
- $Date: 1997/10/05 19:18:30 $
- $State: Exp $
- *
- *      This file contains the definitions for the write functions
- *      for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-
-/*      ftape-write.c defined global functions.
- */
-typedef enum {
-       FT_WR_ASYNC  = 0, /* start tape only when all buffers are full */
-       FT_WR_MULTI  = 1, /* start tape, but don't necessarily stop */
-       FT_WR_SINGLE = 2, /* write a single segment and stop afterwards */
-       FT_WR_DELETE = 3  /* write deleted data marks */
-} ft_write_mode_t;
-
-extern int  ftape_start_writing(const ft_write_mode_t mode);
-extern int  ftape_write_segment(const int segment,
-                               const void *address, 
-                               const ft_write_mode_t flushing);
-extern void ftape_zap_write_buffers(void);
-extern int  ftape_loop_until_writes_done(void);
-
-#endif                         /* _FTAPE_WRITE_H */
-
diff --git a/drivers/char/ftape/lowlevel/ftape_syms.c b/drivers/char/ftape/lowlevel/ftape_syms.c
deleted file mode 100644 (file)
index 8e0dc4a..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *      Copyright (C) 1996-1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape_syms.c,v $
- * $Revision: 1.4 $
- * $Date: 1997/10/17 00:03:51 $
- *
- *      This file contains the symbols that the ftape low level
- *      part of the QIC-40/80/3010/3020 floppy-tape driver "ftape"
- *      exports to its high level clients
- */
-
-#include <linux/module.h>
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-buffer.h"
-#include "../lowlevel/ftape-format.h"
-
-/* bad sector handling from ftape-bsm.c */
-EXPORT_SYMBOL(ftape_get_bad_sector_entry);
-EXPORT_SYMBOL(ftape_find_end_of_bsm_list);
-/* from ftape-rw.c */
-EXPORT_SYMBOL(ftape_set_state);
-/* from ftape-ctl.c */
-EXPORT_SYMBOL(ftape_seek_to_bot);
-EXPORT_SYMBOL(ftape_seek_to_eot);
-EXPORT_SYMBOL(ftape_abort_operation);
-EXPORT_SYMBOL(ftape_get_status);
-EXPORT_SYMBOL(ftape_enable);
-EXPORT_SYMBOL(ftape_disable);
-EXPORT_SYMBOL(ftape_mmap);
-EXPORT_SYMBOL(ftape_calibrate_data_rate);
-/* from ftape-io.c */
-EXPORT_SYMBOL(ftape_reset_drive);
-EXPORT_SYMBOL(ftape_command);
-EXPORT_SYMBOL(ftape_parameter);
-EXPORT_SYMBOL(ftape_ready_wait);
-EXPORT_SYMBOL(ftape_report_operation);
-EXPORT_SYMBOL(ftape_report_error);
-/* from ftape-read.c */
-EXPORT_SYMBOL(ftape_read_segment_fraction);
-EXPORT_SYMBOL(ftape_zap_read_buffers);
-EXPORT_SYMBOL(ftape_read_header_segment);
-EXPORT_SYMBOL(ftape_decode_header_segment);
-/* from ftape-write.c */
-EXPORT_SYMBOL(ftape_write_segment);
-EXPORT_SYMBOL(ftape_start_writing);
-EXPORT_SYMBOL(ftape_loop_until_writes_done);
-/* from ftape-buffer.h */
-EXPORT_SYMBOL(ftape_set_nr_buffers);
-/* from ftape-format.h */
-EXPORT_SYMBOL(ftape_format_track);
-EXPORT_SYMBOL(ftape_format_status);
-EXPORT_SYMBOL(ftape_verify_segment);
-/* from tracing.c */
-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
-EXPORT_SYMBOL(ftape_tracing);
-EXPORT_SYMBOL(ftape_function_nest_level);
-EXPORT_SYMBOL(ftape_trace_call);
-EXPORT_SYMBOL(ftape_trace_exit);
-EXPORT_SYMBOL(ftape_trace_log);
-#endif
-
diff --git a/drivers/char/ftape/zftape/Makefile b/drivers/char/ftape/zftape/Makefile
deleted file mode 100644 (file)
index 6d91c1f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-#       Copyright (C) 1996, 1997 Claus-Justus Heine.
-#
-# This program 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, 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; see the file COPYING.  If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/zftape/Makefile,v $
-# $Revision: 1.4 $
-# $Date: 1997/10/05 19:18:58 $
-#
-#      Makefile for the QIC-40/80/3010/3020 zftape interface VFS to
-#      ftape
-#
-
-
-# ZFT_OBSOLETE - enable the MTIOC_ZFTAPE_GETBLKSZ ioctl. You should
-#                leave this enabled for compatibility with taper.
-
-obj-$(CONFIG_ZFTAPE) += zftape.o
-
-zftape-objs := zftape-rw.o zftape-ctl.o zftape-read.o \
-              zftape-write.o zftape-vtbl.o zftape-eof.o \
-              zftape-init.o zftape-buffers.o zftape_syms.o
-
-EXTRA_CFLAGS := -DZFT_OBSOLETE
diff --git a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c
deleted file mode 100644 (file)
index 7ebce2e..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- *      Copyright (C) 1995-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-buffers.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:59 $
- *
- *      This file contains the dynamic buffer allocation routines 
- *      of zftape
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/zftape.h>
-
-#include <linux/vmalloc.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/*  global variables
- */
-
-/*  local varibales
- */
-static unsigned int used_memory;
-static unsigned int peak_memory;
-
-void zft_memory_stats(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "Memory usage (vmalloc allocations):\n"
-             KERN_INFO "total allocated: %d\n"
-             KERN_INFO "peak allocation: %d",
-             used_memory, peak_memory);
-       peak_memory = used_memory;
-       TRACE_EXIT;
-}
-
-int zft_vcalloc_once(void *new, size_t size)
-{
-       TRACE_FUN(ft_t_flow);
-       if (zft_vmalloc_once(new, size) < 0) {
-               TRACE_EXIT -ENOMEM;
-       }
-       memset(*(void **)new, '\0', size);
-       TRACE_EXIT 0;
-}
-int zft_vmalloc_once(void *new, size_t size)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (*(void **)new != NULL || size == 0) {
-               TRACE_EXIT 0;
-       }
-       if ((*(void **)new = vmalloc(size)) == NULL) {
-               TRACE_EXIT -ENOMEM;
-       }
-       used_memory += size;
-       if (peak_memory < used_memory) {
-               peak_memory = used_memory;
-       }
-       TRACE_ABORT(0, ft_t_noise,
-                   "allocated buffer @ %p, %zd bytes", *(void **)new, size);
-}
-int zft_vmalloc_always(void *new, size_t size)
-{
-       TRACE_FUN(ft_t_flow);
-
-       zft_vfree(new, size);
-       TRACE_EXIT zft_vmalloc_once(new, size);
-}
-void zft_vfree(void *old, size_t size)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (*(void **)old) {
-               vfree(*(void **)old);
-               used_memory -= size;
-               TRACE(ft_t_noise, "released buffer @ %p, %zd bytes",
-                     *(void **)old, size);
-               *(void **)old = NULL;
-       }
-       TRACE_EXIT;
-}
-
-void *zft_kmalloc(size_t size)
-{
-       void *new;
-
-       while ((new = kmalloc(size, GFP_KERNEL)) == NULL) {
-               msleep_interruptible(100);
-       }
-       memset(new, 0, size);
-       used_memory += size;
-       if (peak_memory < used_memory) {
-               peak_memory = used_memory;
-       }
-       return new;
-}
-
-void zft_kfree(void *old, size_t size)
-{
-       kfree(old);
-       used_memory -= size;
-}
-
-/* there are some more buffers that are allocated on demand.
- * cleanup_module() calles this function to be sure to have released
- * them 
- */
-void zft_uninit_mem(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       zft_vfree(&zft_hseg_buf, FT_SEGMENT_SIZE);
-       zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE); zft_deblock_segment = -1;
-       zft_free_vtbl();
-       if (zft_cmpr_lock(0 /* don't load */) == 0) {
-               (*zft_cmpr_ops->cleanup)();
-               (*zft_cmpr_ops->reset)(); /* unlock it again */
-       }
-       zft_memory_stats();
-       TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/zftape/zftape-buffers.h b/drivers/char/ftape/zftape/zftape-buffers.h
deleted file mode 100644 (file)
index 798e312..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _FTAPE_DYNMEM_H
-#define _FTAPE_DYNMEM_H
-
-/*
- *      Copyright (C) 1995-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-buffers.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:59 $
- *
- *   memory allocation routines.
- *
- */
-
-/* we do not allocate all of the really large buffer memory before
- * someone tries to open the drive. ftape_open() may fail with
- * -ENOMEM, but that's better having 200k of vmalloced memory which
- * cannot be swapped out.
- */
-
-extern void  zft_memory_stats(void);
-extern int   zft_vmalloc_once(void *new, size_t size);
-extern int   zft_vcalloc_once(void *new, size_t size);
-extern int   zft_vmalloc_always(void *new, size_t size);
-extern void  zft_vfree(void *old, size_t size);
-extern void *zft_kmalloc(size_t size);
-extern void  zft_kfree(void *old, size_t size);
-
-/* called by cleanup_module() 
- */
-extern void zft_uninit_mem(void);
-
-#endif
-
-
-
-
-
-
-
diff --git a/drivers/char/ftape/zftape/zftape-ctl.c b/drivers/char/ftape/zftape/zftape-ctl.c
deleted file mode 100644 (file)
index 22ba0f5..0000000
+++ /dev/null
@@ -1,1417 +0,0 @@
-/* 
- *      Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-ctl.c,v $
- * $Revision: 1.2.6.2 $
- * $Date: 1997/11/14 18:07:33 $
- *
- *      This file contains the non-read/write zftape functions
- *      for the QIC-40/80/3010/3020 floppy-tape driver for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/fcntl.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/*      Global vars.
- */
-int zft_write_protected; /* this is when cartridge rdonly or O_RDONLY */
-int zft_header_read;
-int zft_offline;
-unsigned int zft_unit;
-int zft_resid;
-int zft_mt_compression;
-
-/*      Local vars.
- */
-static int going_offline;
-
-typedef int (mt_fun)(int *argptr);
-typedef int (*mt_funp)(int *argptr);
-typedef struct
-{
-       mt_funp function;
-       unsigned offline         : 1; /* op permitted if offline or no_tape */
-       unsigned write_protected : 1; /* op permitted if write-protected    */
-       unsigned not_formatted   : 1; /* op permitted if tape not formatted */
-       unsigned raw_mode        : 1; /* op permitted if zft_mode == 0    */
-       unsigned need_idle_state : 1; /* need to call def_idle_state        */
-       char     *name;
-} fun_entry;
-
-static mt_fun mt_dummy, mt_reset, mt_fsr, mt_bsr, mt_rew, mt_offl, mt_nop,
-       mt_weof, mt_erase, mt_ras2, mt_setblk, mt_setdensity,
-       mt_seek, mt_tell, mt_reten, mt_eom, mt_fsf, mt_bsf,
-       mt_fsfm, mt_bsfm, mt_setdrvbuffer, mt_compression;
-
-static fun_entry mt_funs[]=
-{ 
-       {mt_reset       , 1, 1, 1, 1, 0, "MT_RESET" }, /*  0 */
-       {mt_fsf         , 0, 1, 0, 0, 1, "MT_FSF"   },
-       {mt_bsf         , 0, 1, 0, 0, 1, "MT_BSF"   },
-       {mt_fsr         , 0, 1, 0, 1, 1, "MT_FSR"   },
-       {mt_bsr         , 0, 1, 0, 1, 1, "MT_BSR"   },
-       {mt_weof        , 0, 0, 0, 0, 0, "MT_WEOF"  }, /*  5 */
-       {mt_rew         , 0, 1, 1, 1, 0, "MT_REW"   },
-       {mt_offl        , 0, 1, 1, 1, 0, "MT_OFFL"  },
-       {mt_nop         , 1, 1, 1, 1, 0, "MT_NOP"   },
-       {mt_reten       , 0, 1, 1, 1, 0, "MT_RETEN" },
-       {mt_bsfm        , 0, 1, 0, 0, 1, "MT_BSFM"  }, /* 10 */
-       {mt_fsfm        , 0, 1, 0, 0, 1, "MT_FSFM"  },
-       {mt_eom         , 0, 1, 0, 0, 1, "MT_EOM"   },
-       {mt_erase       , 0, 0, 0, 1, 0, "MT_ERASE" },
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_RAS1"  },
-       {mt_ras2        , 0, 0, 0, 1, 0, "MT_RAS2"  },
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_RAS3"  },
-       {mt_dummy       , 1, 1, 1, 1, 0, "UNKNOWN"  },
-       {mt_dummy       , 1, 1, 1, 1, 0, "UNKNOWN"  },
-       {mt_dummy       , 1, 1, 1, 1, 0, "UNKNOWN"  },
-       {mt_setblk      , 1, 1, 1, 1, 1, "MT_SETBLK"}, /* 20 */
-       {mt_setdensity  , 1, 1, 1, 1, 0, "MT_SETDENSITY"},
-       {mt_seek        , 0, 1, 0, 1, 1, "MT_SEEK"  },
-       {mt_dummy       , 0, 1, 0, 1, 1, "MT_TELL"  }, /* wr-only ?! */
-       {mt_setdrvbuffer, 1, 1, 1, 1, 0, "MT_SETDRVBUFFER" },
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_FSS"   }, /* 25 */
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_BSS"   },
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_WSM"   },
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_LOCK"  },
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_UNLOCK"},
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_LOAD"  }, /* 30 */
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_UNLOAD"},
-       {mt_compression , 1, 1, 1, 0, 1, "MT_COMPRESSION"},
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_SETPART"},
-       {mt_dummy       , 1, 1, 1, 1, 0, "MT_MKPART"}
-};  
-
-#define NR_MT_CMDS NR_ITEMS(mt_funs)
-
-void zft_reset_position(zft_position *pos)
-{
-       TRACE_FUN(ft_t_flow);
-
-       pos->seg_byte_pos =
-               pos->volume_pos = 0;
-       if (zft_header_read) {
-               /* need to keep track of the volume table and
-                * compression map. We therefor simply
-                * position at the beginning of the first
-                * volume. This covers old ftape archives as
-                * well has various flavours of the
-                * compression map segments. The worst case is
-                * that the compression map shows up as a
-                * additional volume in front of all others.
-                */
-               pos->seg_pos  = zft_find_volume(0)->start_seg;
-               pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
-       } else {
-               pos->tape_pos =  0;
-               pos->seg_pos  = -1;
-       }
-       zft_just_before_eof =  0;
-       zft_deblock_segment = -1;
-       zft_io_state        = zft_idle;
-       zft_zap_read_buffers();
-       zft_prevent_flush();
-       /*  unlock the compresison module if it is loaded.
-        *  The zero arg means not to try to load the module.
-        */
-       if (zft_cmpr_lock(0) == 0) {
-               (*zft_cmpr_ops->reset)(); /* unlock */
-       }
-       TRACE_EXIT;
-}
-
-static void zft_init_driver(void)
-{
-       TRACE_FUN(ft_t_flow);
-
-       zft_resid =
-               zft_header_read          =
-               zft_old_ftape            =
-               zft_offline              =
-               zft_write_protected      =
-               going_offline            =
-               zft_mt_compression       =
-               zft_header_changed       =
-               zft_volume_table_changed =
-               zft_written_segments     = 0;
-       zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ;
-       zft_reset_position(&zft_pos); /* does most of the stuff */
-       ftape_zap_read_buffers();
-       ftape_set_state(idle);
-       TRACE_EXIT;
-}
-
-int zft_def_idle_state(void)
-{ 
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-       
-       if (!zft_header_read) {
-               result = zft_read_header_segments();
-       } else if ((result = zft_flush_buffers()) >= 0 && zft_qic_mode) {
-               /*  don't move past eof
-                */
-               (void)zft_close_volume(&zft_pos);
-       }
-       if (ftape_abort_operation() < 0) {
-               TRACE(ft_t_warn, "ftape_abort_operation() failed");
-               result = -EIO;
-       }
-       /* clear remaining read buffers */
-       zft_zap_read_buffers();
-       zft_io_state = zft_idle;
-       TRACE_EXIT result;
-}
-
-/*****************************************************************************
- *                                                                           *
- *  functions for the MTIOCTOP commands                                      *
- *                                                                           *
- *****************************************************************************/
-
-static int mt_dummy(int *dummy)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE_EXIT -ENOSYS;
-}
-
-static int mt_reset(int *dummy)
-{        
-       TRACE_FUN(ft_t_flow);
-       
-       (void)ftape_seek_to_bot();
-       TRACE_CATCH(ftape_reset_drive(),
-                   zft_init_driver(); zft_uninit_mem(); zft_offline = 1);
-       /*  fake a re-open of the device. This will set all flage and 
-        *  allocate buffers as appropriate. The new tape condition will
-        *  force the open routine to do anything we need.
-        */
-       TRACE_CATCH(_zft_open(-1 /* fake reopen */, 0 /* dummy */),);
-       TRACE_EXIT 0;
-}
-
-static int mt_fsf(int *arg)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       result = zft_skip_volumes(*arg, &zft_pos);
-       zft_just_before_eof = 0;
-       TRACE_EXIT result;
-}
-
-static int mt_bsf(int *arg)
-{
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-       
-       if (*arg != 0) {
-               result = zft_skip_volumes(-*arg + 1, &zft_pos);
-       }
-       TRACE_EXIT result;
-}
-
-static int seek_block(__s64 data_offset,
-                     __s64 block_increment,
-                     zft_position *pos)
-{ 
-       int result      = 0;
-       __s64 new_block_pos;
-       __s64 vol_block_count;
-       const zft_volinfo *volume;
-       int exceed;
-       TRACE_FUN(ft_t_flow);
-       
-       volume = zft_find_volume(pos->seg_pos);
-       if (volume->start_seg == 0 || volume->end_seg == 0) {
-               TRACE_EXIT -EIO;
-       }
-       new_block_pos   = (zft_div_blksz(data_offset, volume->blk_sz)
-                          + block_increment);
-       vol_block_count = zft_div_blksz(volume->size, volume->blk_sz);
-       if (new_block_pos < 0) {
-               TRACE(ft_t_noise,
-                     "new_block_pos " LL_X " < 0", LL(new_block_pos));
-               zft_resid     = (int)new_block_pos;
-               new_block_pos = 0;
-               exceed = 1;
-       } else if (new_block_pos > vol_block_count) {
-               TRACE(ft_t_noise,
-                     "new_block_pos " LL_X " exceeds size of volume " LL_X,
-                     LL(new_block_pos), LL(vol_block_count));
-               zft_resid     = (int)(vol_block_count - new_block_pos);
-               new_block_pos = vol_block_count;
-               exceed = 1;
-       } else {
-               exceed = 0;
-       }
-       if (zft_use_compression && volume->use_compression) {
-               TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
-               result = (*zft_cmpr_ops->seek)(new_block_pos, pos, volume,
-                                              zft_deblock_buf);
-               pos->tape_pos  = zft_calc_tape_pos(pos->seg_pos);
-               pos->tape_pos += pos->seg_byte_pos;
-       } else {
-               pos->volume_pos = zft_mul_blksz(new_block_pos, volume->blk_sz);
-               pos->tape_pos   = zft_calc_tape_pos(volume->start_seg);
-               pos->tape_pos  += pos->volume_pos;
-               pos->seg_pos    = zft_calc_seg_byte_coord(&pos->seg_byte_pos,
-                                                         pos->tape_pos);
-       }
-       zft_just_before_eof = volume->size == pos->volume_pos;
-       if (zft_just_before_eof) {
-               /* why this? because zft_file_no checks agains start
-                * and end segment of a volume. We do not want to
-                * advance to the next volume with this function.
-                */
-               TRACE(ft_t_noise, "set zft_just_before_eof");
-               zft_position_before_eof(pos, volume);
-       }
-       TRACE(ft_t_noise, "\n"
-             KERN_INFO "new_seg_pos : %d\n"
-             KERN_INFO "new_tape_pos: " LL_X "\n"
-             KERN_INFO "vol_size    : " LL_X "\n"
-             KERN_INFO "seg_byte_pos: %d\n"
-             KERN_INFO "blk_sz  : %d", 
-             pos->seg_pos, LL(pos->tape_pos),
-             LL(volume->size), pos->seg_byte_pos,
-             volume->blk_sz);
-       if (!exceed) {
-               zft_resid = new_block_pos - zft_div_blksz(pos->volume_pos,
-                                                         volume->blk_sz);
-       }
-       if (zft_resid < 0) {
-               zft_resid = -zft_resid;
-       }
-       TRACE_EXIT ((exceed || zft_resid != 0) && result >= 0) ? -EINVAL : result;
-}     
-
-static int mt_fsr(int *arg)
-{ 
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       result = seek_block(zft_pos.volume_pos,  *arg, &zft_pos);
-       TRACE_EXIT result;
-}
-
-static int mt_bsr(int *arg)
-{   
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       result = seek_block(zft_pos.volume_pos, -*arg, &zft_pos);
-       TRACE_EXIT result;
-}
-
-static int mt_weof(int *arg)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE_CATCH(zft_flush_buffers(),);
-       result = zft_weof(*arg, &zft_pos);
-       TRACE_EXIT result;
-}
-
-static int mt_rew(int *dummy)
-{          
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       if(zft_header_read) {
-               (void)zft_def_idle_state();
-       }
-       result = ftape_seek_to_bot();
-       zft_reset_position(&zft_pos);
-       TRACE_EXIT result;
-}
-
-static int mt_offl(int *dummy)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       going_offline= 1;
-       result = mt_rew(NULL);
-       TRACE_EXIT result;
-}
-
-static int mt_nop(int *dummy)
-{
-       TRACE_FUN(ft_t_flow);
-       /*  should we set tape status?
-        */
-       if (!zft_offline) { /* offline includes no_tape */
-               (void)zft_def_idle_state();
-       }
-       TRACE_EXIT 0; 
-}
-
-static int mt_reten(int *dummy)
-{  
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       if(zft_header_read) {
-               (void)zft_def_idle_state();
-       }
-       result = ftape_seek_to_eot();
-       if (result >= 0) {
-               result = ftape_seek_to_bot();
-       }
-       TRACE_EXIT(result);
-}
-
-static int fsfbsfm(int arg, zft_position *pos)
-{ 
-       const zft_volinfo *vtbl;
-       __s64 block_pos;
-       TRACE_FUN(ft_t_flow);
-       
-       /* What to do? This should seek to the next file-mark and
-        * position BEFORE. That is, a next write would just extend
-        * the current file.  Well. Let's just seek to the end of the
-        * current file, if count == 1.  If count > 1, then do a
-        * "mt_fsf(count - 1)", and then seek to the end of that file.
-        * If count == 0, do nothing
-        */
-       if (arg == 0) {
-               TRACE_EXIT 0;
-       }
-       zft_just_before_eof = 0;
-       TRACE_CATCH(zft_skip_volumes(arg < 0 ? arg : arg-1, pos),
-                   if (arg > 0) {
-                           zft_resid ++; 
-                   });
-       vtbl      = zft_find_volume(pos->seg_pos);
-       block_pos = zft_div_blksz(vtbl->size, vtbl->blk_sz);
-       (void)seek_block(0, block_pos, pos);
-       if (pos->volume_pos != vtbl->size) {
-               zft_just_before_eof = 0;
-               zft_resid = 1;
-               /* we didn't managed to go there */
-               TRACE_ABORT(-EIO, ft_t_err, 
-                           "wanted file position " LL_X ", arrived at " LL_X, 
-                           LL(vtbl->size), LL(pos->volume_pos));
-       }
-       zft_just_before_eof = 1;
-       TRACE_EXIT 0; 
-}
-
-static int mt_bsfm(int *arg)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       result = fsfbsfm(-*arg, &zft_pos);
-       TRACE_EXIT result;
-}
-
-static int mt_fsfm(int *arg)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       result = fsfbsfm(*arg, &zft_pos);
-       TRACE_EXIT result;
-}
-
-static int mt_eom(int *dummy)
-{              
-       TRACE_FUN(ft_t_flow);
-       
-       zft_skip_to_eom(&zft_pos);
-       TRACE_EXIT 0;
-}
-
-static int mt_erase(int *dummy)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       result = zft_erase();
-       TRACE_EXIT result;
-}
-
-static int mt_ras2(int *dummy)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       result = -ENOSYS;
-       TRACE_EXIT result;
-} 
-
-/*  Sets the new blocksize in BYTES
- *
- */
-static int mt_setblk(int *new_size)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       if((unsigned int)(*new_size) > ZFT_MAX_BLK_SZ) {
-               TRACE_ABORT(-EINVAL, ft_t_info,
-                           "desired blk_sz (%d) should be <= %d bytes",
-                           *new_size, ZFT_MAX_BLK_SZ);
-       }
-       if ((*new_size & (FT_SECTOR_SIZE-1)) != 0) {
-               TRACE_ABORT(-EINVAL, ft_t_info,
-                       "desired blk_sz (%d) must be a multiple of %d bytes",
-                           *new_size, FT_SECTOR_SIZE);
-       }
-       if (*new_size == 0) {
-               if (zft_use_compression) {
-                       TRACE_ABORT(-EINVAL, ft_t_info,
-                                   "Variable block size not yet "
-                                   "supported with compression");
-               }
-               *new_size = 1;
-       }
-       zft_blk_sz = *new_size;
-       TRACE_EXIT 0;
-} 
-
-static int mt_setdensity(int *arg)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       SET_TRACE_LEVEL(*arg);
-       TRACE(TRACE_LEVEL, "tracing set to %d", TRACE_LEVEL);
-       if ((int)TRACE_LEVEL != *arg) {
-               TRACE_EXIT -EINVAL;
-       }
-       TRACE_EXIT 0;
-}          
-
-static int mt_seek(int *new_block_pos)
-{ 
-       int result= 0;        
-       TRACE_FUN(ft_t_any);
-       
-       result = seek_block(0, (__s64)*new_block_pos, &zft_pos);
-       TRACE_EXIT result;
-}
-
-/*  OK, this is totally different from SCSI, but the worst thing that can 
- *  happen is that there is not enough defragmentated memory that can be 
- *  allocated. Also, there is a hardwired limit of 16 dma buffers in the 
- *  stock ftape module. This shouldn't bring the system down.
- *
- * NOTE: the argument specifies the total number of dma buffers to use.
- *       The driver needs at least 3 buffers to function at all.
- * 
- */
-static int mt_setdrvbuffer(int *cnt)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (*cnt < 3) {
-               TRACE_EXIT -EINVAL;
-       }
-       TRACE_CATCH(ftape_set_nr_buffers(*cnt),);
-       TRACE_EXIT 0;
-}
-/* return the block position from start of volume 
- */
-static int mt_tell(int *arg)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       *arg   = zft_div_blksz(zft_pos.volume_pos,
-                              zft_find_volume(zft_pos.seg_pos)->blk_sz);
-       TRACE_EXIT 0;
-}
-
-static int mt_compression(int *arg)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       /*  Ok. We could also check whether compression is available at
-        *  all by trying to load the compression module.  We could
-        *  also check for a block size of 1 byte which is illegal
-        *  with compression.  Instead of doing it here we rely on
-        *  zftape_write() to do the proper checks.
-        */
-       if ((unsigned int)*arg > 1) {
-               TRACE_EXIT -EINVAL;
-       }
-       if (*arg != 0 && zft_blk_sz == 1) { /* variable block size */
-               TRACE_ABORT(-EINVAL, ft_t_info,
-                           "Compression not yet supported "
-                           "with variable block size");
-       }
-       zft_mt_compression  = *arg;
-       if ((zft_unit & ZFT_ZIP_MODE) == 0) {
-               zft_use_compression = zft_mt_compression;
-       }
-       TRACE_EXIT 0;
-}
-
-/*  check whether write access is allowed. Write access is denied when
- *  + zft_write_protected == 1 -- this accounts for either hard write 
- *                                protection of the cartridge or for 
- *                                O_RDONLY access mode of the tape device
- *  + zft_offline == 1         -- this meany that there is either no tape 
- *                                or that the MTOFFLINE ioctl has been 
- *                                previously issued (`soft eject')
- *  + ft_formatted == 0        -- this means that the cartridge is not
- *                                formatted
- *  Then we distinuguish two cases. When zft_qic_mode is TRUE, then we try
- *  to emulate a `traditional' (aka SCSI like) UN*X tape device. Therefore we
- *  deny writes when
- *  + zft_qic_mode ==1 && 
- *       (!zft_tape_at_lbot() &&   -- tape no at logical BOT
- *        !(zft_tape_at_eom() ||   -- tape not at logical EOM (or EOD)
- *          (zft_tape_at_eom() &&
- *           zft_old_ftape())))    -- we can't add new volume to tapes 
- *                                    written by old ftape because ftape
- *                                    don't use the volume table
- *
- *  when the drive is in true raw mode (aka /dev/rawft0) then we don't 
- *  care about LBOT and EOM conditions. This device is intended for a 
- *  user level program that wants to truly implement the QIC-80 compliance
- *  at the logical data layout level of the cartridge, i.e. implement all
- *  that volume table and volume directory stuff etc.<
- */
-int zft_check_write_access(zft_position *pos)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (zft_offline) { /* offline includes no_tape */
-               TRACE_ABORT(-ENXIO,
-                           ft_t_info, "tape is offline or no cartridge");
-       }
-       if (!ft_formatted) {
-               TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted");
-       } 
-       if (zft_write_protected) {
-               TRACE_ABORT(-EACCES, ft_t_info, "cartridge write protected");
-       } 
-       if (zft_qic_mode) {
-               /*  check BOT condition */
-               if (!zft_tape_at_lbot(pos)) {
-                       /*  protect cartridges written by old ftape if
-                        *  not at BOT because they use the vtbl
-                        *  segment for storing data
-                        */
-                       if (zft_old_ftape) {
-                               TRACE_ABORT(-EACCES, ft_t_warn, 
-      "Cannot write to cartridges written by old ftape when not at BOT");
-                       }
-                       /*  not at BOT, but allow writes at EOD, of course
-                        */
-                       if (!zft_tape_at_eod(pos)) {
-                               TRACE_ABORT(-EACCES, ft_t_info,
-                                           "tape not at BOT and not at EOD");
-                       }
-               }
-               /*  fine. Now the tape is either at BOT or at EOD. */
-       }
-       /* or in raw mode in which case we don't care about BOT and EOD */
-       TRACE_EXIT 0;
-}
-
-/*      OPEN routine called by kernel-interface code
- *
- *      NOTE: this is also called by mt_reset() with dev_minor == -1
- *            to fake a reopen after a reset.
- */
-int _zft_open(unsigned int dev_minor, unsigned int access_mode)
-{
-       static unsigned int tape_unit;
-       static unsigned int file_access_mode;
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       if ((int)dev_minor == -1) {
-               /* fake reopen */
-               zft_unit    = tape_unit;
-               access_mode = file_access_mode;
-               zft_init_driver(); /* reset all static data to defaults */
-       } else {
-               tape_unit        = dev_minor;
-               file_access_mode = access_mode;
-               if ((result = ftape_enable(FTAPE_SEL(dev_minor))) < 0) {
-                       TRACE_ABORT(-ENXIO, ft_t_err,
-                                   "ftape_enable failed: %d", result);
-               }
-               if (ft_new_tape || ft_no_tape || !ft_formatted ||
-                   (FTAPE_SEL(zft_unit) != FTAPE_SEL(dev_minor)) ||
-                   (zft_unit & ZFT_RAW_MODE) != (dev_minor & ZFT_RAW_MODE)) {
-                       /* reset all static data to defaults,
-                        */
-                       zft_init_driver(); 
-               }
-               zft_unit = dev_minor;
-       }
-       zft_set_flags(zft_unit); /* decode the minor bits */
-       if (zft_blk_sz == 1 && zft_use_compression) {
-               ftape_disable(); /* resets ft_no_tape */
-               TRACE_ABORT(-ENODEV, ft_t_warn, "Variable block size not yet "
-                           "supported with compression");
-       }
-       /*  no need for most of the buffers when no tape or not
-        *  formatted.  for the read/write operations, it is the
-        *  regardless whether there is no tape, a not-formatted tape
-        *  or the whether the driver is soft offline.  
-        *  Nevertheless we allow some ioctls with non-formatted tapes, 
-        *  like rewind and reset.
-        */
-       if (ft_no_tape || !ft_formatted) {
-               zft_uninit_mem();
-       }
-       if (ft_no_tape) {
-               zft_offline = 1; /* so we need not test two variables */
-       }
-       if ((access_mode == O_WRONLY || access_mode == O_RDWR) &&
-           (ft_write_protected || ft_no_tape)) {
-               ftape_disable(); /* resets ft_no_tape */
-               TRACE_ABORT(ft_no_tape ? -ENXIO : -EROFS,
-                           ft_t_warn, "wrong access mode %s cartridge",
-                           ft_no_tape ? "without a" : "with write protected");
-       }
-       zft_write_protected = (access_mode == O_RDONLY || 
-                              ft_write_protected != 0);
-       if (zft_write_protected) {
-               TRACE(ft_t_noise,
-                     "read only access mode: %d, "
-                     "drive write protected: %d", 
-                     access_mode == O_RDONLY,
-                     ft_write_protected != 0);
-       }
-       if (!zft_offline) {
-               TRACE_CATCH(zft_vmalloc_once(&zft_deblock_buf,FT_SEGMENT_SIZE),
-                           ftape_disable());
-       }
-       /* zft_seg_pos should be greater than the vtbl segpos but not
-        * if in compatibility mode and only after we read in the
-        * header segments
-        *
-        * might also be a problem if the user makes a backup with a
-        * *qft* device and rewinds it with a raw device.
-        */
-       if (zft_qic_mode         &&
-           !zft_old_ftape       &&
-           zft_pos.seg_pos >= 0 &&
-           zft_header_read      && 
-           zft_pos.seg_pos <= ft_first_data_segment) {
-               TRACE(ft_t_noise, "you probably mixed up the zftape devices!");
-               zft_reset_position(&zft_pos); 
-       }
-       TRACE_EXIT 0;
-}
-
-/*      RELEASE routine called by kernel-interface code
- */
-int _zft_close(void)
-{
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-       
-       if (zft_offline) {
-               /* call the hardware release routine. Puts the drive offline */
-               ftape_disable();
-               TRACE_EXIT 0;
-       }
-       if (!(ft_write_protected || zft_old_ftape)) {
-               result = zft_flush_buffers();
-               TRACE(ft_t_noise, "writing file mark at current position");
-               if (zft_qic_mode && zft_close_volume(&zft_pos) == 0) {
-                       zft_move_past_eof(&zft_pos);
-               }
-               if ((zft_tape_at_lbot(&zft_pos) ||
-                    !(zft_unit & FTAPE_NO_REWIND))) {
-                       if (result >= 0) {
-                               result = zft_update_header_segments();
-                       } else {
-                               TRACE(ft_t_err,
-                               "Error: unable to update header segments");
-                       }
-               }
-       }
-       ftape_abort_operation();
-       if (!(zft_unit & FTAPE_NO_REWIND)) {
-               TRACE(ft_t_noise, "rewinding tape");
-               if (ftape_seek_to_bot() < 0 && result >= 0) {
-                       result = -EIO; /* keep old value */
-               }
-               zft_reset_position(&zft_pos);
-       } 
-       zft_zap_read_buffers();
-       /*  now free up memory as much as possible. We don't destroy
-        *  the deblock buffer if it containes a valid segment.
-        */
-       if (zft_deblock_segment == -1) {
-               zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE); 
-       }
-       /* high level driver status, forces creation of a new volume
-        * when calling ftape_write again and not zft_just_before_eof
-        */
-       zft_io_state = zft_idle;  
-       if (going_offline) {
-               zft_init_driver();
-               zft_uninit_mem();
-               going_offline = 0;
-               zft_offline   = 1;
-       } else if (zft_cmpr_lock(0 /* don't load */) == 0) {
-               (*zft_cmpr_ops->reset)(); /* unlock it again */
-       }
-       zft_memory_stats();
-       /* call the hardware release routine. Puts the drive offline */
-       ftape_disable();
-       TRACE_EXIT result;
-}
-
-/*
- *  the wrapper function around the wrapper MTIOCTOP ioctl
- */
-static int mtioctop(struct mtop *mtop, int arg_size)
-{
-       int result = 0;
-       fun_entry *mt_fun_entry;
-       TRACE_FUN(ft_t_flow);
-       
-       if (arg_size != sizeof(struct mtop) || mtop->mt_op >= NR_MT_CMDS) {
-               TRACE_EXIT -EINVAL;
-       }
-       TRACE(ft_t_noise, "calling MTIOCTOP command: %s",
-             mt_funs[mtop->mt_op].name);
-       mt_fun_entry= &mt_funs[mtop->mt_op];
-       zft_resid = mtop->mt_count;
-       if (!mt_fun_entry->offline && zft_offline) {
-               if (ft_no_tape) {
-                       TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
-               } else {
-                       TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline");
-               }
-       }
-       if (!mt_fun_entry->not_formatted && !ft_formatted) {
-               TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted");
-       }
-       if (!mt_fun_entry->write_protected) {
-               TRACE_CATCH(zft_check_write_access(&zft_pos),);
-       }
-       if (mt_fun_entry->need_idle_state && !(zft_offline || !ft_formatted)) {
-               TRACE_CATCH(zft_def_idle_state(),);
-       }
-       if (!zft_qic_mode && !mt_fun_entry->raw_mode) {
-               TRACE_ABORT(-EACCES, ft_t_info, 
-"Drive needs to be in QIC-80 compatibility mode for this command");
-       }
-       result = (mt_fun_entry->function)(&mtop->mt_count);
-       if (zft_tape_at_lbot(&zft_pos)) {
-               TRACE_CATCH(zft_update_header_segments(),);
-       }
-       if (result >= 0) {
-               zft_resid = 0;
-       }
-       TRACE_EXIT result;
-}
-
-/*
- *  standard MTIOCGET ioctl
- */
-static int mtiocget(struct mtget *mtget, int arg_size)
-{
-       const zft_volinfo *volume;
-       __s64 max_tape_pos;
-       TRACE_FUN(ft_t_flow);
-       
-       if (arg_size != sizeof(struct mtget)) {
-               TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
-                           arg_size);
-       }
-       mtget->mt_type  = ft_drive_type.vendor_id + 0x800000;
-       mtget->mt_dsreg = ft_last_status.space;
-       mtget->mt_erreg = ft_last_error.space; /* error register */
-       mtget->mt_resid = zft_resid; /* residuum of writes, reads and
-                                     * MTIOCTOP commands 
-                                     */
-       if (!zft_offline) { /* neither no_tape nor soft offline */
-               mtget->mt_gstat = GMT_ONLINE(~0UL);
-               /* should rather return the status of the cartridge
-                * than the access mode of the file, therefor use
-                * ft_write_protected, not zft_write_protected 
-                */
-               if (ft_write_protected) {
-                       mtget->mt_gstat |= GMT_WR_PROT(~0UL);
-               }
-               if(zft_header_read) { /* this catches non-formatted */
-                       volume = zft_find_volume(zft_pos.seg_pos);
-                       mtget->mt_fileno = volume->count;
-                       max_tape_pos = zft_capacity - zft_blk_sz;
-                       if (zft_use_compression) {
-                               max_tape_pos -= ZFT_CMPR_OVERHEAD;
-                       }
-                       if (zft_tape_at_eod(&zft_pos)) {
-                               mtget->mt_gstat |= GMT_EOD(~0UL);
-                       }
-                       if (zft_pos.tape_pos > max_tape_pos) {
-                               mtget->mt_gstat |= GMT_EOT(~0UL);
-                       }
-                       mtget->mt_blkno = zft_div_blksz(zft_pos.volume_pos,
-                                                       volume->blk_sz);
-                       if (zft_just_before_eof) {
-                               mtget->mt_gstat |= GMT_EOF(~0UL);
-                       }
-                       if (zft_tape_at_lbot(&zft_pos)) {
-                               mtget->mt_gstat |= GMT_BOT(~0UL);
-                       }
-               } else {
-                       mtget->mt_fileno = mtget->mt_blkno = -1;
-                       if (mtget->mt_dsreg & QIC_STATUS_AT_BOT) {
-                               mtget->mt_gstat |= GMT_BOT(~0UL);
-                       }
-               }
-       } else {
-               if (ft_no_tape) {
-                       mtget->mt_gstat = GMT_DR_OPEN(~0UL);
-               } else {
-                       mtget->mt_gstat = 0UL;
-               }
-               mtget->mt_fileno = mtget->mt_blkno = -1;
-       }
-       TRACE_EXIT 0;
-}
-
-#ifdef MTIOCRDFTSEG
-/*
- *  Read a floppy tape segment. This is useful for manipulating the
- *  volume table, and read the old header segment before re-formatting
- *  the cartridge.
- */
-static int mtiocrdftseg(struct mtftseg * mtftseg, int arg_size)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCRDFTSEG");
-       if (zft_qic_mode) {
-               TRACE_ABORT(-EACCES, ft_t_info,
-                           "driver needs to be in raw mode for this ioctl");
-       } 
-       if (arg_size != sizeof(struct mtftseg)) {
-               TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
-                           arg_size);
-       }
-       if (zft_offline) {
-               TRACE_EXIT -ENXIO;
-       }
-       if (mtftseg->mt_mode != FT_RD_SINGLE &&
-           mtftseg->mt_mode != FT_RD_AHEAD) {
-               TRACE_ABORT(-EINVAL, ft_t_info, "invalid read mode");
-       }
-       if (!ft_formatted) {
-               TRACE_EXIT -EACCES; /* -ENXIO ? */
-
-       }
-       if (!zft_header_read) {
-               TRACE_CATCH(zft_def_idle_state(),);
-       }
-       if (mtftseg->mt_segno > ft_last_data_segment) {
-               TRACE_ABORT(-EINVAL, ft_t_info, "segment number is too large");
-       }
-       mtftseg->mt_result = ftape_read_segment(mtftseg->mt_segno,
-                                               zft_deblock_buf,
-                                               mtftseg->mt_mode);
-       if (mtftseg->mt_result < 0) {
-               /*  a negativ result is not an ioctl error. if
-                *  the user wants to read damaged tapes,
-                *  it's up to her/him
-                */
-               TRACE_EXIT 0;
-       }
-       if (copy_to_user(mtftseg->mt_data,
-                        zft_deblock_buf,
-                        mtftseg->mt_result) != 0) {
-               TRACE_EXIT -EFAULT;
-       }
-       TRACE_EXIT 0;
-}
-#endif
-
-#ifdef MTIOCWRFTSEG
-/*
- *  write a floppy tape segment. This version features writing of
- *  deleted address marks, and gracefully ignores the (software)
- *  ft_formatted flag to support writing of header segments after
- *  formatting.
- */
-static int mtiocwrftseg(struct mtftseg * mtftseg, int arg_size)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCWRFTSEG");
-       if (zft_write_protected || zft_qic_mode) {
-               TRACE_EXIT -EACCES;
-       } 
-       if (arg_size != sizeof(struct mtftseg)) {
-               TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
-                           arg_size);
-       }
-       if (zft_offline) {
-               TRACE_EXIT -ENXIO;
-       }
-       if (mtftseg->mt_mode != FT_WR_ASYNC   && 
-           mtftseg->mt_mode != FT_WR_MULTI   &&
-           mtftseg->mt_mode != FT_WR_SINGLE  &&
-           mtftseg->mt_mode != FT_WR_DELETE) {
-               TRACE_ABORT(-EINVAL, ft_t_info, "invalid write mode");
-       }
-       /*
-        *  We don't check for ft_formatted, because this gives
-        *  only the software status of the driver.
-        *
-        *  We assume that the user knows what it is
-        *  doing. And rely on the low level stuff to fail
-        *  when the tape isn't formatted. We only make sure
-        *  that The header segment buffer is allocated,
-        *  because it holds the bad sector map.
-        */
-       if (zft_hseg_buf == NULL) {
-               TRACE_EXIT -ENXIO;
-       }
-       if (mtftseg->mt_mode != FT_WR_DELETE) {
-               if (copy_from_user(zft_deblock_buf, 
-                                  mtftseg->mt_data,
-                                  FT_SEGMENT_SIZE) != 0) {
-                       TRACE_EXIT -EFAULT;
-               }
-       }
-       mtftseg->mt_result = ftape_write_segment(mtftseg->mt_segno, 
-                                                zft_deblock_buf,
-                                                mtftseg->mt_mode);
-       if (mtftseg->mt_result >= 0 && mtftseg->mt_mode == FT_WR_SINGLE) {
-               /*  
-                *  a negativ result is not an ioctl error. if
-                *  the user wants to write damaged tapes,
-                *  it's up to her/him
-                */
-               if ((result = ftape_loop_until_writes_done()) < 0) {
-                       mtftseg->mt_result = result;
-               }
-       }
-       TRACE_EXIT 0;
-}
-#endif
-  
-#ifdef MTIOCVOLINFO
-/*
- *  get information about volume positioned at.
- */
-static int mtiocvolinfo(struct mtvolinfo *volinfo, int arg_size)
-{
-       const zft_volinfo *volume;
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCVOLINFO");
-       if (arg_size != sizeof(struct mtvolinfo)) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_info, "bad argument size: %d", arg_size);
-       }
-       if (zft_offline) {
-               TRACE_EXIT -ENXIO;
-       }
-       if (!ft_formatted) {
-               TRACE_EXIT -EACCES;
-       }
-       TRACE_CATCH(zft_def_idle_state(),);
-       volume = zft_find_volume(zft_pos.seg_pos);
-       volinfo->mt_volno   = volume->count;
-       volinfo->mt_blksz   = volume->blk_sz == 1 ? 0 : volume->blk_sz;
-       volinfo->mt_size    = volume->size >> 10;
-       volinfo->mt_rawsize = ((zft_calc_tape_pos(volume->end_seg + 1) >> 10) -
-                              (zft_calc_tape_pos(volume->start_seg) >> 10));
-       volinfo->mt_cmpr    = volume->use_compression;
-       TRACE_EXIT 0;
-}
-#endif
-
-#ifdef ZFT_OBSOLETE  
-static int mtioc_zftape_getblksz(struct mtblksz *blksz, int arg_size)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "\n"
-             KERN_INFO "Mag tape ioctl command: MTIOC_ZTAPE_GETBLKSZ\n"
-             KERN_INFO "This ioctl is here merely for compatibility.\n"
-             KERN_INFO "Please use MTIOCVOLINFO instead");
-       if (arg_size != sizeof(struct mtblksz)) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_info, "bad argument size: %d", arg_size);
-       }
-       if (zft_offline) {
-               TRACE_EXIT -ENXIO;
-       }
-       if (!ft_formatted) {
-               TRACE_EXIT -EACCES;
-       }
-       TRACE_CATCH(zft_def_idle_state(),);
-       blksz->mt_blksz = zft_find_volume(zft_pos.seg_pos)->blk_sz;
-       TRACE_EXIT 0;
-}
-#endif
-
-#ifdef MTIOCGETSIZE
-/*
- *  get the capacity of the tape cartridge.
- */
-static int mtiocgetsize(struct mttapesize *size, int arg_size)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "Mag tape ioctl command: MTIOC_ZFTAPE_GETSIZE");
-       if (arg_size != sizeof(struct mttapesize)) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_info, "bad argument size: %d", arg_size);
-       }
-       if (zft_offline) {
-               TRACE_EXIT -ENXIO;
-       }
-       if (!ft_formatted) {
-               TRACE_EXIT -EACCES;
-       }
-       TRACE_CATCH(zft_def_idle_state(),);
-       size->mt_capacity = (unsigned int)(zft_capacity>>10);
-       size->mt_used     = (unsigned int)(zft_get_eom_pos()>>10);
-       TRACE_EXIT 0;
-}
-#endif
-
-static int mtiocpos(struct mtpos *mtpos, int arg_size)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCPOS");
-       if (arg_size != sizeof(struct mtpos)) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_info, "bad argument size: %d", arg_size);
-       }
-       result = mt_tell((int *)&mtpos->mt_blkno);
-       TRACE_EXIT result;
-}
-
-#ifdef MTIOCFTFORMAT
-/*
- * formatting of floppy tape cartridges. This is intended to be used
- * together with the MTIOCFTCMD ioctl and the new mmap feature 
- */
-
-/* 
- *  This function uses ftape_decode_header_segment() to inform the low
- *  level ftape module about the new parameters.
- *
- *  It erases the hseg_buf. The calling process must specify all
- *  parameters to assure proper operation.
- *
- *  return values: -EINVAL - wrong argument size
- *                 -EINVAL - if ftape_decode_header_segment() failed.
- */
-static int set_format_parms(struct ftfmtparms *p, __u8 *hseg_buf)
-{
-       ft_trace_t old_level = TRACE_LEVEL;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_SETPARMS");
-       memset(hseg_buf, 0, FT_SEGMENT_SIZE);
-       PUT4(hseg_buf, FT_SIGNATURE, FT_HSEG_MAGIC);
-
-       /*  fill in user specified parameters
-        */
-       hseg_buf[FT_FMT_CODE] = (__u8)p->ft_fmtcode;
-       PUT2(hseg_buf, FT_SPT, p->ft_spt);
-       hseg_buf[FT_TPC]      = (__u8)p->ft_tpc;
-       hseg_buf[FT_FHM]      = (__u8)p->ft_fhm;
-       hseg_buf[FT_FTM]      = (__u8)p->ft_ftm;
-
-       /*  fill in sane defaults to make ftape happy.
-        */ 
-       hseg_buf[FT_FSM] = (__u8)128; /* 128 is hard wired all over ftape */
-       if (p->ft_fmtcode == fmt_big) {
-               PUT4(hseg_buf, FT_6_HSEG_1,   0);
-               PUT4(hseg_buf, FT_6_HSEG_2,   1);
-               PUT4(hseg_buf, FT_6_FRST_SEG, 2);
-               PUT4(hseg_buf, FT_6_LAST_SEG, p->ft_spt * p->ft_tpc - 1);
-       } else {
-               PUT2(hseg_buf, FT_HSEG_1,    0);
-               PUT2(hseg_buf, FT_HSEG_2,    1);
-               PUT2(hseg_buf, FT_FRST_SEG,  2);
-               PUT2(hseg_buf, FT_LAST_SEG, p->ft_spt * p->ft_tpc - 1);
-       }
-
-       /*  Synchronize with the low level module. This is particularly
-        *  needed for unformatted cartridges as the QIC std was previously 
-        *  unknown BUT is needed to set data rate and to calculate timeouts.
-        */
-       TRACE_CATCH(ftape_calibrate_data_rate(p->ft_qicstd&QIC_TAPE_STD_MASK),
-                   _res = -EINVAL);
-
-       /*  The following will also recalcualte the timeouts for the tape
-        *  length and QIC std we want to format to.
-        *  abort with -EINVAL rather than -EIO
-        */
-       SET_TRACE_LEVEL(ft_t_warn);
-       TRACE_CATCH(ftape_decode_header_segment(hseg_buf),
-                   SET_TRACE_LEVEL(old_level); _res = -EINVAL);
-       SET_TRACE_LEVEL(old_level);
-       TRACE_EXIT 0;
-}
-
-/*
- *  Return the internal SOFTWARE status of the kernel driver. This does
- *  NOT query the tape drive about its status.
- */
-static int get_format_parms(struct ftfmtparms *p, __u8 *hseg_buffer)
-{
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_GETPARMS");
-       p->ft_qicstd  = ft_qic_std;
-       p->ft_fmtcode = ft_format_code;
-       p->ft_fhm     = hseg_buffer[FT_FHM];
-       p->ft_ftm     = hseg_buffer[FT_FTM];
-       p->ft_spt     = ft_segments_per_track;
-       p->ft_tpc     = ft_tracks_per_tape;
-       TRACE_EXIT 0;
-}
-
-static int mtiocftformat(struct mtftformat *mtftformat, int arg_size)
-{
-       int result;
-       union fmt_arg *arg = &mtftformat->fmt_arg;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTFORMAT");
-       if (zft_offline) {
-               if (ft_no_tape) {
-                       TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
-               } else {
-                       TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline");
-               }
-       }
-       if (zft_qic_mode) {
-               TRACE_ABORT(-EACCES, ft_t_info,
-                           "driver needs to be in raw mode for this ioctl");
-       } 
-       if (zft_hseg_buf == NULL) {
-               TRACE_CATCH(zft_vcalloc_once(&zft_hseg_buf, FT_SEGMENT_SIZE),);
-       }
-       zft_header_read = 0;
-       switch(mtftformat->fmt_op) {
-       case FTFMT_SET_PARMS:
-               TRACE_CATCH(set_format_parms(&arg->fmt_parms, zft_hseg_buf),);
-               TRACE_EXIT 0;
-       case FTFMT_GET_PARMS:
-               TRACE_CATCH(get_format_parms(&arg->fmt_parms, zft_hseg_buf),);
-               TRACE_EXIT 0;
-       case FTFMT_FORMAT_TRACK:
-               if ((ft_formatted && zft_check_write_access(&zft_pos) < 0) ||
-                   (!ft_formatted && zft_write_protected)) {
-                       TRACE_ABORT(-EACCES, ft_t_info, "Write access denied");
-               }
-               TRACE_CATCH(ftape_format_track(arg->fmt_track.ft_track,
-                                              arg->fmt_track.ft_gap3),);
-               TRACE_EXIT 0;
-       case FTFMT_STATUS:
-               TRACE_CATCH(ftape_format_status(&arg->fmt_status.ft_segment),);
-               TRACE_EXIT 0;
-       case FTFMT_VERIFY:
-               TRACE_CATCH(ftape_verify_segment(arg->fmt_verify.ft_segment,
-                               (SectorMap *)&arg->fmt_verify.ft_bsm),);
-               TRACE_EXIT 0;
-       default:
-               TRACE_ABORT(-EINVAL, ft_t_err, "Invalid format operation");
-       }
-       TRACE_EXIT result;
-}
-#endif
-
-#ifdef MTIOCFTCMD
-/*
- *  send a QIC-117 command to the drive, with optional timeouts,
- *  parameter and result bits. This is intended to be used together
- *  with the formatting ioctl.
- */
-static int mtiocftcmd(struct mtftcmd *ftcmd, int arg_size)
-{
-       int i;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTCMD");
-       if (!capable(CAP_SYS_ADMIN)) {
-               TRACE_ABORT(-EPERM, ft_t_info,
-                           "need CAP_SYS_ADMIN capability to send raw qic-117 commands");
-       }
-       if (zft_qic_mode) {
-               TRACE_ABORT(-EACCES, ft_t_info,
-                           "driver needs to be in raw mode for this ioctl");
-       } 
-       if (arg_size != sizeof(struct mtftcmd)) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_info, "bad argument size: %d", arg_size);
-       }
-       if (ftcmd->ft_wait_before) {
-               TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_before,
-                                            &ftcmd->ft_status),);
-       }
-       if (ftcmd->ft_status & QIC_STATUS_ERROR)
-               goto ftmtcmd_error;
-       if (ftcmd->ft_result_bits != 0) {
-               TRACE_CATCH(ftape_report_operation(&ftcmd->ft_result,
-                                                  ftcmd->ft_cmd,
-                                                  ftcmd->ft_result_bits),);
-       } else {
-               TRACE_CATCH(ftape_command(ftcmd->ft_cmd),);
-               if (ftcmd->ft_status & QIC_STATUS_ERROR)
-                       goto ftmtcmd_error;
-               for (i = 0; i < ftcmd->ft_parm_cnt; i++) {
-                       TRACE_CATCH(ftape_parameter(ftcmd->ft_parms[i]&0x0f),);
-                       if (ftcmd->ft_status & QIC_STATUS_ERROR)
-                               goto ftmtcmd_error;
-               }
-       }
-       if (ftcmd->ft_wait_after != 0) {
-               TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_after,
-                                            &ftcmd->ft_status),);
-       }
-ftmtcmd_error:        
-       if (ftcmd->ft_status & QIC_STATUS_ERROR) {
-               TRACE(ft_t_noise, "error status set");
-               TRACE_CATCH(ftape_report_error(&ftcmd->ft_error,
-                                              &ftcmd->ft_cmd, 1),);
-       }
-       TRACE_EXIT 0; /* this is not an i/o error */
-}
-#endif
-
-/*  IOCTL routine called by kernel-interface code
- */
-int _zft_ioctl(unsigned int command, void __user * arg)
-{
-       int result;
-       union { struct mtop       mtop;
-               struct mtget      mtget;
-               struct mtpos      mtpos;
-#ifdef MTIOCRDFTSEG
-               struct mtftseg    mtftseg;
-#endif
-#ifdef MTIOCVOLINFO
-               struct mtvolinfo  mtvolinfo;
-#endif
-#ifdef MTIOCGETSIZE
-               struct mttapesize mttapesize;
-#endif
-#ifdef MTIOCFTFORMAT
-               struct mtftformat mtftformat;
-#endif
-#ifdef ZFT_OBSOLETE
-               struct mtblksz mtblksz;
-#endif
-#ifdef MTIOCFTCMD
-               struct mtftcmd mtftcmd;
-#endif
-       } krnl_arg;
-       int arg_size = _IOC_SIZE(command);
-       int dir = _IOC_DIR(command);
-       TRACE_FUN(ft_t_flow);
-
-       /* This check will only catch arguments that are too large !
-        */
-       if (dir & (_IOC_READ | _IOC_WRITE) && arg_size > sizeof(krnl_arg)) {
-               TRACE_ABORT(-EINVAL,
-                           ft_t_info, "bad argument size: %d", arg_size);
-       }
-       if (dir & _IOC_WRITE) {
-               if (copy_from_user(&krnl_arg, arg, arg_size) != 0) {
-                       TRACE_EXIT -EFAULT;
-               }
-       }
-       TRACE(ft_t_flow, "called with ioctl command: 0x%08x", command);
-       switch (command) {
-       case MTIOCTOP:
-               result = mtioctop(&krnl_arg.mtop, arg_size);
-               break;
-       case MTIOCGET:
-               result = mtiocget(&krnl_arg.mtget, arg_size);
-               break;
-       case MTIOCPOS:
-               result = mtiocpos(&krnl_arg.mtpos, arg_size);
-               break;
-#ifdef MTIOCVOLINFO
-       case MTIOCVOLINFO:
-               result = mtiocvolinfo(&krnl_arg.mtvolinfo, arg_size);
-               break;
-#endif
-#ifdef ZFT_OBSOLETE
-       case MTIOC_ZFTAPE_GETBLKSZ:
-               result = mtioc_zftape_getblksz(&krnl_arg.mtblksz, arg_size);
-               break;
-#endif
-#ifdef MTIOCRDFTSEG
-       case MTIOCRDFTSEG: /* read a segment via ioctl */
-               result = mtiocrdftseg(&krnl_arg.mtftseg, arg_size);
-               break;
-#endif
-#ifdef MTIOCWRFTSEG
-       case MTIOCWRFTSEG: /* write a segment via ioctl */
-               result = mtiocwrftseg(&krnl_arg.mtftseg, arg_size);
-               break;
-#endif
-#ifdef MTIOCGETSIZE
-       case MTIOCGETSIZE:
-               result = mtiocgetsize(&krnl_arg.mttapesize, arg_size);
-               break;
-#endif
-#ifdef MTIOCFTFORMAT
-       case MTIOCFTFORMAT:
-               result = mtiocftformat(&krnl_arg.mtftformat, arg_size);
-               break;
-#endif
-#ifdef MTIOCFTCMD
-       case MTIOCFTCMD:
-               result = mtiocftcmd(&krnl_arg.mtftcmd, arg_size);
-               break;
-#endif
-       default:
-               result = -EINVAL;
-               break;
-       }
-       if ((result >= 0) && (dir & _IOC_READ)) {
-               if (copy_to_user(arg, &krnl_arg, arg_size) != 0) {
-                       TRACE_EXIT -EFAULT;
-               }
-       }
-       TRACE_EXIT result;
-}
diff --git a/drivers/char/ftape/zftape/zftape-ctl.h b/drivers/char/ftape/zftape/zftape-ctl.h
deleted file mode 100644 (file)
index 8e6f2d7..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef _ZFTAPE_CTL_H
-#define _ZFTAPE_CTL_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-ctl.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:02 $
- *
- *      This file contains the non-standard IOCTL related definitions
- *      for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/ioctl.h>
-#include <linux/mtio.h>
-
-#include "../zftape/zftape-rw.h"
-
-#ifdef CONFIG_ZFTAPE_MODULE
-#define ftape_status (*zft_status)
-#endif
-
-extern int zft_offline;
-extern int zft_mt_compression;
-extern int zft_write_protected;
-extern int zft_header_read;
-extern unsigned int zft_unit;
-extern int zft_resid;
-
-extern void zft_reset_position(zft_position *pos);
-extern int  zft_check_write_access(zft_position *pos);
-extern int  zft_def_idle_state(void);
-
-/*  hooks for the VFS interface 
- */
-extern int  _zft_open(unsigned int dev_minor, unsigned int access_mode);
-extern int  _zft_close(void);
-extern int  _zft_ioctl(unsigned int command, void __user *arg);
-#endif
-
-
-
diff --git a/drivers/char/ftape/zftape/zftape-eof.c b/drivers/char/ftape/zftape/zftape-eof.c
deleted file mode 100644 (file)
index dcadcae..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- *   I use these routines just to decide when I have to fake a 
- *   volume-table to preserve compatibility to original ftape.
- */
-/*
- *      Copyright (C) 1994-1995 Bas Laarhoven.
- *      
- *      Modified for zftape 1996, 1997 Claus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-eof.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:02 $
- *
- *      This file contains the eof mark handling code
- *      for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include <linux/zftape.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-eof.h"
-
-/*      Global vars.
- */
-
-/* a copy of the failed sector log from the header segment.
- */
-eof_mark_union *zft_eof_map;
-
-/* number of eof marks (entries in bad sector log) on tape.
- */
-int zft_nr_eof_marks = -1;
-
-
-/*      Local vars.
- */
-
-static char linux_tape_label[] = "Linux raw format V";
-enum { 
-       min_fmt_version = 1, max_fmt_version = 2 
-};
-static unsigned ftape_fmt_version = 0;
-
-
-/* Ftape (mis)uses the bad sector log to record end-of-file marks.
- * Initially (when the tape is erased) all entries in the bad sector
- * log are added to the tape's bad sector map. The bad sector log then
- * is cleared.
- *
- * The bad sector log normally contains entries of the form: 
- * even 16-bit word: segment number of bad sector 
- * odd 16-bit word: encoded date
- * There can be a total of 448 entries (1792 bytes).
- *
- * My guess is that no program is using this bad sector log (the *
- * format seems useless as there is no indication of the bad sector
- * itself, only the segment) However, if any program does use the bad
- * sector log, the format used by ftape will let the program think
- * there are some bad sectors and no harm is done.
- *  
- * The eof mark entries that ftape stores in the bad sector log: even
- * 16-bit word: segment number of eof mark odd 16-bit word: sector
- * number of eof mark [1..32]
- *  
- * The zft_eof_map as maintained is a sorted list of eof mark entries.
- *
- *
- * The tape name field in the header segments is used to store a linux
- * tape identification string and a version number.  This way the tape
- * can be recognized as a Linux raw format tape when using tools under
- * other OS's.
- *
- * 'Wide' QIC tapes (format code 4) don't have a failed sector list
- * anymore. That space is used for the (longer) bad sector map that
- * now is a variable length list too.  We now store our end-of-file
- * marker list after the bad-sector-map on tape. The list is delimited
- * by a (__u32) 0 entry.
- */
-
-int zft_ftape_validate_label(char *label)
-{
-       static char tmp_label[45];
-       int result = 0;
-       TRACE_FUN(ft_t_any);
-       
-       memcpy(tmp_label, label, FT_LABEL_SZ);
-       tmp_label[FT_LABEL_SZ] = '\0';
-       TRACE(ft_t_noise, "tape  label = `%s'", tmp_label);
-       ftape_fmt_version = 0;
-       if (memcmp(label, linux_tape_label, strlen(linux_tape_label)) == 0) {
-               int pos = strlen(linux_tape_label);
-               while (label[pos] >= '0' && label[pos] <= '9') {
-                       ftape_fmt_version *= 10;
-                       ftape_fmt_version = label[ pos++] - '0';
-               }
-               result = (ftape_fmt_version >= min_fmt_version &&
-                         ftape_fmt_version <= max_fmt_version);
-       }
-       TRACE(ft_t_noise, "format version = %d", ftape_fmt_version);
-       TRACE_EXIT result;
-}
-
-static __u8 * find_end_of_eof_list(__u8 * ptr, __u8 * limit)
-{
-       while (ptr + 3 < limit) {
-
-               if (get_unaligned((__u32*)ptr)) {
-                       ptr += sizeof(__u32);
-               } else {
-                       return ptr;
-               }
-       }
-       return NULL;
-}
-
-void zft_ftape_extract_file_marks(__u8* address)
-{
-       int i;
-       TRACE_FUN(ft_t_any);
-       
-       zft_eof_map = NULL;
-       if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
-               __u8* end;
-               __u8* start = ftape_find_end_of_bsm_list(address);
-
-               zft_nr_eof_marks = 0;
-               if (start) {
-                       start += 3; /* skip end of list mark */
-                       end = find_end_of_eof_list(start, 
-                                                  address + FT_SEGMENT_SIZE);
-                       if (end && end - start <= FT_FSL_SIZE) {
-                               zft_nr_eof_marks = ((end - start) / 
-                                                   sizeof(eof_mark_union));
-                               zft_eof_map = (eof_mark_union *)start;
-                       } else {
-                               TRACE(ft_t_err,
-                                     "EOF Mark List is too long or damaged!");
-                       }
-               } else {
-                       TRACE(ft_t_err, 
-                             "Bad Sector List is too long or damaged !");
-               }
-       } else {
-               zft_eof_map = (eof_mark_union *)&address[FT_FSL];
-               zft_nr_eof_marks = GET2(address, FT_FSL_CNT);
-       }
-       TRACE(ft_t_noise, "number of file marks: %d", zft_nr_eof_marks);
-       if (ftape_fmt_version == 1) {
-               TRACE(ft_t_info, "swapping version 1 fields");
-               /* version 1 format uses swapped sector and segment
-                * fields, correct that !  
-                */
-               for (i = 0; i < zft_nr_eof_marks; ++i) {
-                       __u16 tmp = GET2(&zft_eof_map[i].mark.segment,0);
-                       PUT2(&zft_eof_map[i].mark.segment, 0, 
-                            GET2(&zft_eof_map[i].mark.date,0));
-                       PUT2(&zft_eof_map[i].mark.date, 0, tmp);
-               }
-       }
-       for (i = 0; i < zft_nr_eof_marks; ++i) {
-               TRACE(ft_t_noise, "eof mark: %5d/%2d",
-                       GET2(&zft_eof_map[i].mark.segment, 0), 
-                       GET2(&zft_eof_map[i].mark.date,0));
-       }
-       TRACE_EXIT;
-}
-
-void zft_clear_ftape_file_marks(void)
-{
-       TRACE_FUN(ft_t_flow);
-       /*  Clear failed sector log: remove all tape marks. We
-        *  don't use old ftape-style EOF-marks.
-        */
-       TRACE(ft_t_info, "Clearing old ftape's eof map");
-       memset(zft_eof_map, 0, zft_nr_eof_marks * sizeof(__u32));
-       zft_nr_eof_marks = 0;
-       PUT2(zft_hseg_buf, FT_FSL_CNT, 0); /* nr of eof-marks */
-       zft_header_changed = 1;
-       zft_update_label(zft_hseg_buf);
-       TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/zftape/zftape-eof.h b/drivers/char/ftape/zftape/zftape-eof.h
deleted file mode 100644 (file)
index 26568c2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _ZFTAPE_EOF_H
-#define _ZFTAPE_EOF_H
-
-/*
- * Copyright (C) 1994-1995 Bas Laarhoven.
- * adaptaed for zftape 1996, 1997 by Claus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-eof.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:03 $
- *
- *      Definitions and declarations for the end of file markers
- *      for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape-header-segment.h>
-#include "../zftape/zftape-buffers.h"
-/*  failed sector log size (only used if format code != 4).
- */
-
-typedef union {
-       ft_fsl_entry mark;
-       __u32 entry;
-} eof_mark_union;
-/*      ftape-eof.c defined global vars.
- */
-extern int zft_nr_eof_marks;
-extern eof_mark_union *zft_eof_map;
-
-/*      ftape-eof.c defined global functions.
- */
-extern void zft_ftape_extract_file_marks(__u8* address);
-extern int  zft_ftape_validate_label(char* label);
-extern void zft_clear_ftape_file_marks(void);
-
-#endif
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
deleted file mode 100644 (file)
index 164a1aa..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- *      Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- *      This file contains the code that registers the zftape frontend 
- *      to the ftape floppy tape driver for Linux
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-
-#include <linux/zftape.h>
-#include <linux/init.h>
-#include <linux/device.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-buffers.h"
-
-MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine "
-             "(claus@momo.math.rwth-aachen.de)");
-MODULE_DESCRIPTION(ZFTAPE_VERSION " - "
-                  "VFS interface for the Linux floppy tape driver. "
-                  "Support for QIC-113 compatible volume table "
-                  "and builtin compression (lzrw3 algorithm)");
-MODULE_SUPPORTED_DEVICE("char-major-27");
-MODULE_LICENSE("GPL");
-
-/*      Global vars.
- */
-struct zft_cmpr_ops *zft_cmpr_ops = NULL;
-const ftape_info *zft_status;
-
-/*      Local vars.
- */
-static unsigned long busy_flag;
-
-static sigset_t orig_sigmask;
-
-/*  the interface to the kernel vfs layer
- */
-
-/* Note about llseek():
- *
- * st.c and tpqic.c update fp->f_pos but don't implment llseek() and
- * initialize the llseek component of the file_ops struct with NULL.
- * This means that the user will get the default seek, but the tape
- * device will not respect the new position, but happily read from the
- * old position. Think a zftape specific llseek() function would be
- * better, returning -ESPIPE. TODO.
- */
-
-static int  zft_open (struct inode *ino, struct file *filep);
-static int zft_close(struct inode *ino, struct file *filep);
-static int  zft_ioctl(struct inode *ino, struct file *filep,
-                     unsigned int command, unsigned long arg);
-static int  zft_mmap(struct file *filep, struct vm_area_struct *vma);
-static ssize_t zft_read (struct file *fp, char __user *buff,
-                        size_t req_len, loff_t *ppos);
-static ssize_t zft_write(struct file *fp, const char __user *buff,
-                        size_t req_len, loff_t *ppos);
-
-static const struct file_operations zft_cdev =
-{
-       .owner          = THIS_MODULE,
-       .read           = zft_read,
-       .write          = zft_write,
-       .ioctl          = zft_ioctl,
-       .mmap           = zft_mmap,
-       .open           = zft_open,
-       .release        = zft_close,
-};
-
-static struct class *zft_class;
-
-/*      Open floppy tape device
- */
-static int zft_open(struct inode *ino, struct file *filep)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       nonseekable_open(ino, filep);
-       TRACE(ft_t_flow, "called for minor %d", iminor(ino));
-       if ( test_and_set_bit(0,&busy_flag) ) {
-               TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy");
-       }
-       if ((iminor(ino) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND))
-            > 
-           FTAPE_SEL_D) {
-               clear_bit(0,&busy_flag);
-               TRACE_ABORT(-ENXIO, ft_t_err, "failed: invalid unit nr");
-       }
-       orig_sigmask = current->blocked;
-       sigfillset(&current->blocked);
-       result = _zft_open(iminor(ino), filep->f_flags & O_ACCMODE);
-       if (result < 0) {
-               current->blocked = orig_sigmask; /* restore mask */
-               clear_bit(0,&busy_flag);
-               TRACE_ABORT(result, ft_t_err, "_ftape_open failed");
-       } else {
-               /* Mask signals that will disturb proper operation of the
-                * program that is calling.
-                */
-               current->blocked = orig_sigmask;
-               sigaddsetmask (&current->blocked, _DO_BLOCK);
-               TRACE_EXIT 0;
-       }
-}
-
-/*      Close floppy tape device
- */
-static int zft_close(struct inode *ino, struct file *filep)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit) {
-               TRACE(ft_t_err, "failed: not busy or wrong unit");
-               TRACE_EXIT 0;
-       }
-       sigfillset(&current->blocked);
-       result = _zft_close();
-       if (result < 0) {
-               TRACE(ft_t_err, "_zft_close failed");
-       }
-       current->blocked = orig_sigmask; /* restore before open state */
-       clear_bit(0,&busy_flag);
-       TRACE_EXIT 0;
-}
-
-/*      Ioctl for floppy tape device
- */
-static int zft_ioctl(struct inode *ino, struct file *filep,
-                    unsigned int command, unsigned long arg)
-{
-       int result = -EIO;
-       sigset_t old_sigmask;
-       TRACE_FUN(ft_t_flow);
-
-       if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "failed: not busy, failure or wrong unit");
-       }
-       old_sigmask = current->blocked; /* save mask */
-       sigfillset(&current->blocked);
-       /* This will work as long as sizeof(void *) == sizeof(long) */
-       result = _zft_ioctl(command, (void __user *) arg);
-       current->blocked = old_sigmask; /* restore mask */
-       TRACE_EXIT result;
-}
-
-/*      Ioctl for floppy tape device
- */
-static int  zft_mmap(struct file *filep, struct vm_area_struct *vma)
-{
-       int result = -EIO;
-       sigset_t old_sigmask;
-       TRACE_FUN(ft_t_flow);
-
-       if ( !test_bit(0,&busy_flag) || 
-           iminor(filep->f_dentry->d_inode) != zft_unit || 
-           ft_failure)
-       {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "failed: not busy, failure or wrong unit");
-       }
-       old_sigmask = current->blocked; /* save mask */
-       sigfillset(&current->blocked);
-       if ((result = ftape_mmap(vma)) >= 0) {
-#ifndef MSYNC_BUG_WAS_FIXED
-               static struct vm_operations_struct dummy = { NULL, };
-               vma->vm_ops = &dummy;
-#endif
-       }
-       current->blocked = old_sigmask; /* restore mask */
-       TRACE_EXIT result;
-}
-
-/*      Read from floppy tape device
- */
-static ssize_t zft_read(struct file *fp, char __user *buff,
-                       size_t req_len, loff_t *ppos)
-{
-       int result = -EIO;
-       sigset_t old_sigmask;
-       struct inode *ino = fp->f_dentry->d_inode;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len);
-       if (!test_bit(0,&busy_flag)  || iminor(ino) != zft_unit || ft_failure) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "failed: not busy, failure or wrong unit");
-       }
-       old_sigmask = current->blocked; /* save mask */
-       sigfillset(&current->blocked);
-       result = _zft_read(buff, req_len);
-       current->blocked = old_sigmask; /* restore mask */
-       TRACE(ft_t_data_flow, "return with count: %d", result);
-       TRACE_EXIT result;
-}
-
-/*      Write to tape device
- */
-static ssize_t zft_write(struct file *fp, const char __user *buff,
-                        size_t req_len, loff_t *ppos)
-{
-       int result = -EIO;
-       sigset_t old_sigmask;
-       struct inode *ino = fp->f_dentry->d_inode;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len);
-       if (!test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "failed: not busy, failure or wrong unit");
-       }
-       old_sigmask = current->blocked; /* save mask */
-       sigfillset(&current->blocked);
-       result = _zft_write(buff, req_len);
-       current->blocked = old_sigmask; /* restore mask */
-       TRACE(ft_t_data_flow, "return with count: %d", result);
-       TRACE_EXIT result;
-}
-
-/*                    END OF VFS INTERFACE 
- *          
- *****************************************************************************/
-
-/*  driver/module initialization
- */
-
-/*  the compression module has to call this function to hook into the zftape 
- *  code
- */
-int zft_cmpr_register(struct zft_cmpr_ops *new_ops)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       if (zft_cmpr_ops != NULL) {
-               TRACE_EXIT -EBUSY;
-       } else {
-               zft_cmpr_ops = new_ops;
-               TRACE_EXIT 0;
-       }
-}
-
-/*  lock the zft-compressor() module.
- */
-int zft_cmpr_lock(int try_to_load)
-{
-       if (zft_cmpr_ops == NULL) {
-#ifdef CONFIG_KMOD
-               if (try_to_load) {
-                       request_module("zft-compressor");
-                       if (zft_cmpr_ops == NULL) {
-                               return -ENOSYS;
-                       }
-               } else {
-                       return -ENOSYS;
-               }
-#else
-               return -ENOSYS;
-#endif
-       }
-       (*zft_cmpr_ops->lock)();
-       return 0;
-}
-
-#ifdef CONFIG_ZFT_COMPRESSOR
-extern int zft_compressor_init(void);
-#endif
-
-/*  Called by modules package when installing the driver or by kernel
- *  during the initialization phase
- */
-int __init zft_init(void)
-{
-       int i;
-       TRACE_FUN(ft_t_flow);
-
-#ifdef MODULE
-       printk(KERN_INFO ZFTAPE_VERSION "\n");
-        if (TRACE_LEVEL >= ft_t_info) {
-               printk(
-KERN_INFO
-"(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO
-"vfs interface for ftape floppy tape driver.\n"
-KERN_INFO
-"Support for QIC-113 compatible volume table, dynamic memory allocation\n"
-KERN_INFO
-"and builtin compression (lzrw3 algorithm).\n");
-        }
-#else /* !MODULE */
-       /* print a short no-nonsense boot message */
-       printk(KERN_INFO ZFTAPE_VERSION "\n");
-#endif /* MODULE */
-       TRACE(ft_t_info, "zft_init @ 0x%p", zft_init);
-       TRACE(ft_t_info,
-             "installing zftape VFS interface for ftape driver ...");
-       TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),);
-
-       zft_class = class_create(THIS_MODULE, "zft");
-       for (i = 0; i < 4; i++) {
-               class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
-               class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
-               class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
-               class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
-               class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
-               class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
-       }
-
-#ifdef CONFIG_ZFT_COMPRESSOR
-       (void)zft_compressor_init();
-#endif
-       zft_status = ftape_get_status(); /*  fetch global data of ftape 
-                                         *  hardware driver 
-                                         */
-       TRACE_EXIT 0;
-}
-
-
-/* Called by modules package when removing the driver 
- */
-static void zft_exit(void)
-{
-       int i;
-       TRACE_FUN(ft_t_flow);
-
-       if (unregister_chrdev(QIC117_TAPE_MAJOR, "zft") != 0) {
-               TRACE(ft_t_warn, "failed");
-       } else {
-               TRACE(ft_t_info, "successful");
-       }
-        for (i = 0; i < 4; i++) {
-               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i));
-               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4));
-               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16));
-               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20));
-               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32));
-               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36));
-       }
-       class_destroy(zft_class);
-       zft_uninit_mem(); /* release remaining memory, if any */
-        printk(KERN_INFO "zftape successfully unloaded.\n");
-       TRACE_EXIT;
-}
-
-module_init(zft_init);
-module_exit(zft_exit);
diff --git a/drivers/char/ftape/zftape/zftape-init.h b/drivers/char/ftape/zftape/zftape-init.h
deleted file mode 100644 (file)
index 937e5d4..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef _ZFTAPE_INIT_H
-#define _ZFTAPE_INIT_H
-
-/*
- * Copyright (C) 1996, 1997 Claus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-init.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:05 $
- *
- * This file contains definitions and macro for the vfs 
- * interface defined by zftape
- *
- */
-
-#include <linux/ftape-header-segment.h>
-
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-buffer.h"
-#include "../lowlevel/ftape-format.h"
-
-#include "../zftape/zftape-rw.h"
-
-#ifdef MODULE
-#define ftape_status (*zft_status)
-#endif
-
-extern const  ftape_info *zft_status; /* needed for zftape-vtbl.h */
-
-#include "../zftape/zftape-vtbl.h"
-
-struct zft_cmpr_ops {
-       int (*write)(int *write_cnt,
-                    __u8 *dst_buf, const int seg_sz,
-                    const __u8 __user *src_buf, const int req_len, 
-                    const zft_position *pos, const zft_volinfo *volume);
-       int (*read)(int *read_cnt,
-                   __u8 __user *dst_buf, const int req_len,
-                   const __u8 *src_buf, const int seg_sz,
-                   const zft_position *pos, const zft_volinfo *volume);
-       int (*seek)(unsigned int new_block_pos,
-                   zft_position *pos, const zft_volinfo *volume,
-                   __u8 *buffer);
-       void (*lock)   (void);
-       void (*reset)  (void);
-       void (*cleanup)(void);
-};
-
-extern struct zft_cmpr_ops *zft_cmpr_ops;
-/* zftape-init.c defined global functions.
- */
-extern int                  zft_cmpr_register(struct zft_cmpr_ops *new_ops);
-extern int                  zft_cmpr_lock(int try_to_load);
-
-#endif
-
-
diff --git a/drivers/char/ftape/zftape/zftape-read.c b/drivers/char/ftape/zftape/zftape-read.c
deleted file mode 100644 (file)
index 214bf03..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- *      Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-read.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:06 $
- *
- *      This file contains the high level reading code
- *      for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/*      Global vars.
- */
-int zft_just_before_eof;
-
-/*      Local vars.
- */
-static int buf_len_rd;
-
-void zft_zap_read_buffers(void)
-{
-       buf_len_rd = 0;
-}
-
-int zft_read_header_segments(void)      
-{
-       TRACE_FUN(ft_t_flow);
-
-       zft_header_read = 0;
-       TRACE_CATCH(zft_vmalloc_once(&zft_hseg_buf, FT_SEGMENT_SIZE),);
-       TRACE_CATCH(ftape_read_header_segment(zft_hseg_buf),);
-       TRACE(ft_t_info, "Segments written since first format: %d",
-             (int)GET4(zft_hseg_buf, FT_SEG_CNT));
-       zft_qic113 = (ft_format_code != fmt_normal &&
-                     ft_format_code != fmt_1100ft &&
-                     ft_format_code != fmt_425ft);
-       TRACE(ft_t_info, "ft_first_data_segment: %d, ft_last_data_segment: %d", 
-             ft_first_data_segment, ft_last_data_segment);
-       zft_capacity = zft_get_capacity();
-       zft_old_ftape = zft_ftape_validate_label(&zft_hseg_buf[FT_LABEL]);
-       if (zft_old_ftape) {
-               TRACE(ft_t_info, 
-"Found old ftaped tape, emulating eof marks, entering read-only mode");
-               zft_ftape_extract_file_marks(zft_hseg_buf);
-               TRACE_CATCH(zft_fake_volume_headers(zft_eof_map, 
-                                                   zft_nr_eof_marks),);
-       } else {
-               /* the specs say that the volume table must be
-                * initialized with zeroes during formatting, so it
-                * MUST be readable, i.e. contain vaid ECC
-                * information.  
-                */
-               TRACE_CATCH(ftape_read_segment(ft_first_data_segment, 
-                                              zft_deblock_buf, 
-                                              FT_RD_SINGLE),);
-               TRACE_CATCH(zft_extract_volume_headers(zft_deblock_buf),);
-       }
-       zft_header_read = 1;
-       zft_set_flags(zft_unit);
-       zft_reset_position(&zft_pos);
-       TRACE_EXIT 0;
-}
-
-int zft_fetch_segment_fraction(const unsigned int segment, void *buffer,
-                              const ft_read_mode_t read_mode,
-                              const unsigned int start,
-                              const unsigned int size)
-{
-       int seg_sz;
-       TRACE_FUN(ft_t_flow);
-
-       if (segment == zft_deblock_segment) {
-               TRACE(ft_t_data_flow,
-                     "re-using segment %d already in deblock buffer",
-                     segment);
-               seg_sz = zft_get_seg_sz(segment);
-               if (start > seg_sz) {
-                       TRACE_ABORT(-EINVAL, ft_t_bug,
-                                   "trying to read beyond end of segment:\n"
-                                   KERN_INFO "seg_sz : %d\n"
-                                   KERN_INFO "start  : %d\n"
-                                   KERN_INFO "segment: %d",
-                                   seg_sz, start, segment);
-               }
-               if ((start + size) > seg_sz) {
-                       TRACE_EXIT seg_sz - start;
-               }
-               TRACE_EXIT size;
-       }
-       seg_sz = ftape_read_segment_fraction(segment, buffer, read_mode,
-                                            start, size);
-       TRACE(ft_t_data_flow, "segment %d, result %d", segment, seg_sz);
-       if ((int)seg_sz >= 0 && start == 0 && size == FT_SEGMENT_SIZE) {
-               /*  this implicitly assumes that we are always called with
-                *  buffer == zft_deblock_buf 
-                */
-               zft_deblock_segment = segment;
-       } else {
-               zft_deblock_segment = -1;
-       }
-       TRACE_EXIT seg_sz;
-}
-
-/*
- * out:
- *
- * int *read_cnt: the number of bytes we removed from the
- *                zft_deblock_buf (result)
- *
- * int *to_do   : the remaining size of the read-request. Is changed.
- *
- * in:
- *
- * char *buff      : buff is the address of the upper part of the user
- *                   buffer, that hasn't been filled with data yet.
- * int buf_pos_read: copy of buf_pos_rd
- * int buf_len_read: copy of buf_len_rd
- * char *zft_deblock_buf: ftape_zft_deblock_buf
- *
- * returns the amount of data actually copied to the user-buffer
- *
- * to_do MUST NOT SHRINK except to indicate an EOT. In this case to_do
- * has to be set to 0. We cannot return -ENOSPC, because we return the
- * amount of data actually * copied to the user-buffer
- */
-static int zft_simple_read (int *read_cnt, 
-                           __u8  __user *dst_buf, 
-                           const int to_do, 
-                           const __u8 *src_buf, 
-                           const int seg_sz, 
-                           const zft_position *pos,
-                           const zft_volinfo *volume)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (seg_sz - pos->seg_byte_pos < to_do) {
-               *read_cnt = seg_sz - pos->seg_byte_pos;
-       } else {
-               *read_cnt = to_do;
-       }
-       if (copy_to_user(dst_buf, 
-                        src_buf + pos->seg_byte_pos, *read_cnt) != 0) {
-               TRACE_EXIT -EFAULT;
-       }
-       TRACE(ft_t_noise, "nr bytes just read: %d", *read_cnt);
-       TRACE_EXIT *read_cnt;
-}
-
-/* req_len: gets clipped due to EOT of EOF.
- * req_clipped: is a flag indicating whether req_len was clipped or not
- * volume: contains information on current volume (blk_sz etc.)
- */
-static int check_read_access(int *req_len, 
-                            const zft_volinfo **volume,
-                            int *req_clipped, 
-                            const zft_position *pos)
-{
-       static __s64 remaining;
-       static int eod;
-       TRACE_FUN(ft_t_flow);
-       
-       if (zft_io_state != zft_reading) {
-               if (zft_offline) { /* offline includes no_tape */
-                       TRACE_ABORT(-ENXIO, ft_t_warn,
-                                   "tape is offline or no cartridge");
-               }
-               if (!ft_formatted) {
-                       TRACE_ABORT(-EACCES,
-                                   ft_t_warn, "tape is not formatted");
-               }
-               /*  now enter defined state, read header segment if not
-                *  already done and flush write buffers
-                */
-               TRACE_CATCH(zft_def_idle_state(),);
-               zft_io_state = zft_reading;
-               if (zft_tape_at_eod(pos)) {
-                       eod = 1;
-                       TRACE_EXIT 1;
-               }
-               eod = 0;
-               *volume = zft_find_volume(pos->seg_pos);
-               /* get the space left until EOF */
-               remaining = zft_check_for_eof(*volume, pos);
-               buf_len_rd = 0;
-               TRACE(ft_t_noise, "remaining: " LL_X ", vol_no: %d",
-                     LL(remaining), (*volume)->count);
-       } else if (zft_tape_at_eod(pos)) {
-               if (++eod > 2) {
-                       TRACE_EXIT -EIO; /* st.c also returns -EIO */
-               } else {
-                       TRACE_EXIT 1;
-               }
-       }
-       if ((*req_len % (*volume)->blk_sz) != 0) {
-               /*  this message is informational only. The user gets the
-                *  proper return value
-                */
-               TRACE_ABORT(-EINVAL, ft_t_info,
-                           "req_len %d not a multiple of block size %d",
-                           *req_len, (*volume)->blk_sz);
-       }
-       /* As GNU tar doesn't accept partial read counts when the
-        * multiple volume flag is set, we make sure to return the
-        * requested amount of data. Except, of course, at the end of
-        * the tape or file mark.  
-        */
-       remaining -= *req_len;
-       if (remaining <= 0) {
-               TRACE(ft_t_noise, 
-                     "clipped request from %d to %d.", 
-                     *req_len, (int)(*req_len + remaining));
-               *req_len += remaining;
-               *req_clipped = 1;
-       } else {
-               *req_clipped = 0;
-       }
-       TRACE_EXIT 0;
-}
-
-/* this_segs_size: the current segment's size.
- * buff: the USER-SPACE buffer provided by the calling function.
- * req_len: how much data should be read at most.
- * volume: contains information on current volume (blk_sz etc.)
- */  
-static int empty_deblock_buf(__u8 __user *usr_buf, const int req_len,
-                            const __u8 *src_buf, const int seg_sz,
-                            zft_position *pos,
-                            const zft_volinfo *volume)
-{
-       int cnt;
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_data_flow, "this_segs_size: %d", seg_sz);
-       if (zft_use_compression && volume->use_compression) {
-               TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
-               TRACE_CATCH(result= (*zft_cmpr_ops->read)(&cnt,
-                                                         usr_buf, req_len,
-                                                         src_buf, seg_sz,
-                                                         pos, volume),);
-       } else {                                  
-               TRACE_CATCH(result= zft_simple_read (&cnt,
-                                                    usr_buf, req_len,
-                                                    src_buf, seg_sz,
-                                                    pos, volume),);
-       }
-       pos->volume_pos   += result;
-        pos->tape_pos     += cnt;
-       pos->seg_byte_pos += cnt;
-       buf_len_rd        -= cnt; /* remaining bytes in buffer */
-       TRACE(ft_t_data_flow, "buf_len_rd: %d, cnt: %d", buf_len_rd, cnt);
-       if(pos->seg_byte_pos >= seg_sz) {
-               pos->seg_pos++;
-               pos->seg_byte_pos = 0;
-       }
-       TRACE(ft_t_data_flow, "bytes moved out of deblock-buffer: %d", cnt);
-       TRACE_EXIT result;
-}
-
-
-/* note: we store the segment id of the segment that is inside the
- * deblock buffer. This spares a lot of ftape_read_segment()s when we
- * use small block-sizes. The block-size may be 1kb (SECTOR_SIZE). In
- * this case a MTFSR 28 maybe still inside the same segment.
- */
-int _zft_read(char __user *buff, int req_len)
-{
-       int req_clipped;
-       int result     = 0;
-       int bytes_read = 0;
-       static unsigned int seg_sz = 0;
-       static const zft_volinfo *volume = NULL;
-       TRACE_FUN(ft_t_flow);
-       
-       zft_resid = req_len;
-       result = check_read_access(&req_len, &volume,
-                                  &req_clipped, &zft_pos);
-       switch(result) {
-       case 0: 
-               break; /* nothing special */
-       case 1: 
-               TRACE(ft_t_noise, "EOD reached");
-               TRACE_EXIT 0;   /* EOD */
-       default:
-               TRACE_ABORT(result, ft_t_noise,
-                           "check_read_access() failed with result %d",
-                           result);
-               TRACE_EXIT result;
-       }
-       while (req_len > 0) { 
-               /*  Allow escape from this loop on signal !
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               /* buf_len_rd == 0 means that we need to read a new
-                * segment.
-                */
-               if (buf_len_rd == 0) {
-                       while((result = zft_fetch_segment(zft_pos.seg_pos,
-                                                         zft_deblock_buf,
-                                                         FT_RD_AHEAD)) == 0) {
-                               zft_pos.seg_pos ++;
-                               zft_pos.seg_byte_pos = 0;
-                       }
-                       if (result < 0) {
-                               zft_resid -= bytes_read;
-                               TRACE_ABORT(result, ft_t_noise,
-                                           "zft_fetch_segment(): %d",
-                                           result);
-                       }
-                       seg_sz = result;
-                       buf_len_rd = seg_sz - zft_pos.seg_byte_pos;
-               }
-               TRACE_CATCH(result = empty_deblock_buf(buff, 
-                                                      req_len,
-                                                      zft_deblock_buf, 
-                                                      seg_sz, 
-                                                      &zft_pos,
-                                                      volume),
-                           zft_resid -= bytes_read);
-               TRACE(ft_t_data_flow, "bytes just read: %d", result);
-               bytes_read += result; /* what we got so far       */
-               buff       += result; /* index in user-buffer     */
-               req_len    -= result; /* what's left from req_len */
-       } /* while (req_len  > 0) */
-       if (req_clipped) {
-               TRACE(ft_t_data_flow,
-                     "maybe partial count because of eof mark");
-               if (zft_just_before_eof && bytes_read == 0) {
-                       /* req_len was > 0, but user didn't get
-                        * anything the user has read in the eof-mark 
-                        */
-                       zft_move_past_eof(&zft_pos);
-                       ftape_abort_operation();
-               } else {
-                       /* don't skip to the next file before the user
-                        * tried to read a second time past EOF Just
-                        * mark that we are at EOF and maybe decrement
-                        * zft_seg_pos to stay in the same volume;
-                        */
-                       zft_just_before_eof = 1;
-                       zft_position_before_eof(&zft_pos, volume);
-                       TRACE(ft_t_noise, "just before eof");
-               }
-       }
-       zft_resid -= result; /* for MTSTATUS       */
-       TRACE_EXIT bytes_read;
-}
diff --git a/drivers/char/ftape/zftape/zftape-read.h b/drivers/char/ftape/zftape/zftape-read.h
deleted file mode 100644 (file)
index 42941de..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _ZFTAPE_READ_H
-#define _ZFTAPE_READ_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-read.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:07 $
- *
- *      This file contains the definitions for the read functions
- *      for the zftape driver for Linux.
- *
- */
-
-#include "../lowlevel/ftape-read.h"
-
-/*      ftape-read.c defined global vars.
- */
-extern int zft_just_before_eof;
-       
-/*      ftape-read.c defined global functions.
- */
-extern void zft_zap_read_buffers(void);
-extern int  zft_read_header_segments(void);
-extern int  zft_fetch_segment_fraction(const unsigned int segment,
-                                      void *buffer,
-                                      const ft_read_mode_t read_mode,
-                                      const unsigned int start,
-                                      const unsigned int size);
-#define zft_fetch_segment(segment, address, read_mode)         \
-       zft_fetch_segment_fraction(segment, address, read_mode, \
-                                  0, FT_SEGMENT_SIZE)
-/*   hook for the VFS interface
- */
-extern int  _zft_read(char __user *buff, int req_len);
-
-#endif /* _ZFTAPE_READ_H */
diff --git a/drivers/char/ftape/zftape/zftape-rw.c b/drivers/char/ftape/zftape/zftape-rw.c
deleted file mode 100644 (file)
index dab6346..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- *      Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-rw.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:08 $
- *
- *      This file contains some common code for the r/w code for
- *      zftape.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/zftape.h>
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/*      Global vars.
- */
-
-__u8 *zft_deblock_buf;
-__u8 *zft_hseg_buf;
-int zft_deblock_segment = -1;
-zft_status_enum zft_io_state = zft_idle;
-int zft_header_changed;
-int zft_qic113; /* conform to old specs. and old zftape */
-int zft_use_compression;
-zft_position zft_pos = {
-       -1, /* seg_pos */
-       0,  /* seg_byte_pos */
-       0,  /* tape_pos */
-       0   /* volume_pos */
-};
-unsigned int zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ;
-__s64 zft_capacity;
-
-unsigned int zft_written_segments;
-int zft_label_changed;
-
-/*      Local vars.
- */
-
-unsigned int zft_get_seg_sz(unsigned int segment)
-{
-       int size;
-       TRACE_FUN(ft_t_any);
-       
-       size = FT_SEGMENT_SIZE - 
-               count_ones(ftape_get_bad_sector_entry(segment))*FT_SECTOR_SIZE;
-       if (size > 0) {
-               TRACE_EXIT (unsigned)size; 
-       } else {
-               TRACE_EXIT 0;
-       }
-}
-
-/* ftape_set_flags(). Claus-Justus Heine, 1994/1995
- */
-void zft_set_flags(unsigned minor_unit)
-{     
-       TRACE_FUN(ft_t_flow);
-       
-       zft_use_compression = zft_qic_mode = 0;
-       switch (minor_unit & ZFT_MINOR_OP_MASK) {
-       case (ZFT_Q80_MODE | ZFT_ZIP_MODE):
-       case ZFT_ZIP_MODE:
-               zft_use_compression = 1;
-       case 0:
-       case ZFT_Q80_MODE:
-               zft_qic_mode = 1;
-               if (zft_mt_compression) { /* override the default */
-                       zft_use_compression = 1;
-               }
-               break;
-       case ZFT_RAW_MODE:
-               TRACE(ft_t_noise, "switching to raw mode");
-               break;
-       default:
-               TRACE(ft_t_warn, "Warning:\n"
-                     KERN_INFO "Wrong combination of minor device bits.\n"
-                     KERN_INFO "Switching to raw read-only mode.");
-               zft_write_protected = 1;
-               break;
-       }
-       TRACE_EXIT;
-}
-
-/* computes the segment and byte offset inside the segment
- * corresponding to tape_pos.
- *
- * tape_pos gives the offset in bytes from the beginning of the
- * ft_first_data_segment *seg_byte_pos is the offset in the current
- * segment in bytes
- *
- * Of, if this routine was called often one should cache the last data
- * pos it was called with, but actually this is only needed in
- * ftape_seek_block(), that is, almost never.
- */
-int zft_calc_seg_byte_coord(int *seg_byte_pos, __s64 tape_pos)
-{
-       int segment;
-       int seg_sz;
-       TRACE_FUN(ft_t_flow);
-       
-       if (tape_pos == 0) {
-               *seg_byte_pos = 0;
-               segment = ft_first_data_segment;
-       } else {
-               seg_sz = 0;
-               
-               for (segment = ft_first_data_segment; 
-                    ((tape_pos > 0) && (segment <= ft_last_data_segment));
-                    segment++) {
-                       seg_sz = zft_get_seg_sz(segment); 
-                       tape_pos -= seg_sz;
-               }
-               if(tape_pos >= 0) {
-                       /* the case tape_pos > != 0 means that the
-                        * argument tape_pos lies beyond the EOT.
-                        */
-                       *seg_byte_pos= 0;
-               } else { /* tape_pos < 0 */
-                       segment--;
-                       *seg_byte_pos= tape_pos + seg_sz;
-               }
-       }
-       TRACE_EXIT(segment);
-}
-
-/* ftape_calc_tape_pos().
- *
- * computes the offset in bytes from the beginning of the
- * ft_first_data_segment inverse to ftape_calc_seg_byte_coord
- *
- * We should do some caching. But how:
- *
- * Each time the header segments are read in, this routine is called
- * with ft_tracks_per_tape*segments_per_track argumnet. So this should be
- * the time to reset the cache.
- *
- * Also, it might be in the future that the bad sector map gets
- * changed.  -> reset the cache
- */
-static int seg_pos;
-static __s64 tape_pos;
-
-__s64 zft_get_capacity(void)
-{
-       seg_pos  = ft_first_data_segment;
-       tape_pos = 0;
-
-       while (seg_pos <= ft_last_data_segment) {
-               tape_pos += zft_get_seg_sz(seg_pos ++);
-       }
-       return tape_pos;
-}
-
-__s64 zft_calc_tape_pos(int segment)
-{
-       int d1, d2, d3;
-       TRACE_FUN(ft_t_any);
-       
-       if (segment > ft_last_data_segment) {
-               TRACE_EXIT zft_capacity;
-       }
-       if (segment < ft_first_data_segment) {
-               TRACE_EXIT 0;
-       }
-       d2 = segment - seg_pos;
-       if (-d2 > 10) {
-               d1 = segment - ft_first_data_segment;
-               if (-d2 > d1) {
-                       tape_pos = 0;
-                       seg_pos = ft_first_data_segment;
-                       d2 = d1;
-               }
-       }
-       if (d2 > 10) {
-               d3 = ft_last_data_segment - segment;
-               if (d2 > d3) {
-                       tape_pos = zft_capacity;
-                       seg_pos  = ft_last_data_segment + 1;
-                       d2 = -d3;
-               }
-       }               
-       if (d2 > 0) {
-               while (seg_pos < segment) {
-                       tape_pos +=  zft_get_seg_sz(seg_pos++);
-               }
-       } else {
-               while (seg_pos > segment) {
-                       tape_pos -=  zft_get_seg_sz(--seg_pos);
-               }
-       }
-       TRACE(ft_t_noise, "new cached pos: %d", seg_pos);
-
-       TRACE_EXIT tape_pos;
-}
-
-/* copy Z-label string to buffer, keeps track of the correct offset in
- * `buffer' 
- */
-void zft_update_label(__u8 *buffer)
-{ 
-       TRACE_FUN(ft_t_flow);
-       
-       if (strncmp(&buffer[FT_LABEL], ZFTAPE_LABEL, 
-                   sizeof(ZFTAPE_LABEL)-1) != 0) {
-               TRACE(ft_t_info, "updating label from \"%s\" to \"%s\"",
-                     &buffer[FT_LABEL], ZFTAPE_LABEL);
-               strcpy(&buffer[FT_LABEL], ZFTAPE_LABEL);
-               memset(&buffer[FT_LABEL] + sizeof(ZFTAPE_LABEL) - 1, ' ', 
-                      FT_LABEL_SZ - sizeof(ZFTAPE_LABEL + 1));
-               PUT4(buffer, FT_LABEL_DATE, 0);
-               zft_label_changed = zft_header_changed = 1; /* changed */
-       }
-       TRACE_EXIT;
-}
-
-int zft_verify_write_segments(unsigned int segment, 
-                             __u8 *data, size_t size,
-                             __u8 *buffer)
-{
-       int result;
-       __u8 *write_buf;
-       __u8 *src_buf;
-       int single;
-       int seg_pos;
-       int seg_sz;
-       int remaining;
-       ft_write_mode_t write_mode;
-       TRACE_FUN(ft_t_flow);
-
-       seg_pos   = segment;
-       seg_sz    = zft_get_seg_sz(seg_pos);
-       src_buf   = data;
-       single    = size <= seg_sz;
-       remaining = size;
-       do {
-               TRACE(ft_t_noise, "\n"
-                     KERN_INFO "remaining: %d\n"
-                     KERN_INFO "seg_sz   : %d\n"
-                     KERN_INFO "segment  : %d",
-                     remaining, seg_sz, seg_pos);
-               if (remaining == seg_sz) {
-                       write_buf = src_buf;
-                       write_mode = single ? FT_WR_SINGLE : FT_WR_MULTI;
-                       remaining = 0;
-               } else if (remaining > seg_sz) {
-                       write_buf = src_buf;
-                       write_mode = FT_WR_ASYNC; /* don't start tape */
-                       remaining -= seg_sz;
-               } else { /* remaining < seg_sz */
-                       write_buf = buffer;
-                       memcpy(write_buf, src_buf, remaining);
-                       memset(&write_buf[remaining],'\0',seg_sz-remaining);
-                       write_mode = single ? FT_WR_SINGLE : FT_WR_MULTI;
-                       remaining = 0;
-               }
-               if ((result = ftape_write_segment(seg_pos, 
-                                                 write_buf, 
-                                                 write_mode)) != seg_sz) {
-                       TRACE(ft_t_err, "Error: "
-                             "Couldn't write segment %d", seg_pos);
-                       TRACE_EXIT result < 0 ? result : -EIO; /* bail out */
-               }
-               zft_written_segments ++;
-               seg_sz = zft_get_seg_sz(++seg_pos);
-               src_buf += result;
-       } while (remaining > 0);
-       if (ftape_get_status()->fti_state == writing) {
-               TRACE_CATCH(ftape_loop_until_writes_done(),);
-               TRACE_CATCH(ftape_abort_operation(),);
-               zft_prevent_flush();
-       }
-       seg_pos = segment;
-       src_buf = data;
-       remaining = size;
-       do {
-               TRACE_CATCH(result = ftape_read_segment(seg_pos, buffer, 
-                                                       single ? FT_RD_SINGLE
-                                                       : FT_RD_AHEAD),);
-               if (memcmp(src_buf, buffer, 
-                          remaining > result ? result : remaining) != 0) {
-                       TRACE_ABORT(-EIO, ft_t_err,
-                                   "Failed to verify written segment %d",
-                                   seg_pos);
-               }
-               remaining -= result;
-               TRACE(ft_t_noise, "verify successful:\n"
-                     KERN_INFO "segment  : %d\n"
-                     KERN_INFO "segsize  : %d\n"
-                     KERN_INFO "remaining: %d",
-                     seg_pos, result, remaining);
-               src_buf   += seg_sz;
-               seg_pos++;
-       } while (remaining > 0);
-       TRACE_EXIT size;
-}
-
-
-/* zft_erase().  implemented compression-handling
- *
- * calculate the first data-segment when using/not using compression.
- *
- * update header-segment and compression-map-segment.
- */
-int zft_erase(void)
-{
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-       
-       if (!zft_header_read) {
-               TRACE_CATCH(zft_vmalloc_once((void **)&zft_hseg_buf,
-                                            FT_SEGMENT_SIZE),);
-               /* no need to read the vtbl and compression map */
-               TRACE_CATCH(ftape_read_header_segment(zft_hseg_buf),);
-               if ((zft_old_ftape = 
-                    zft_ftape_validate_label(&zft_hseg_buf[FT_LABEL]))) {
-                       zft_ftape_extract_file_marks(zft_hseg_buf);
-               }
-               TRACE(ft_t_noise,
-                     "ft_first_data_segment: %d, ft_last_data_segment: %d", 
-                     ft_first_data_segment, ft_last_data_segment);
-               zft_qic113 = (ft_format_code != fmt_normal &&
-                             ft_format_code != fmt_1100ft &&
-                             ft_format_code != fmt_425ft);
-       }
-       if (zft_old_ftape) {
-               zft_clear_ftape_file_marks();
-               zft_old_ftape = 0; /* no longer old ftape */
-       }
-       PUT2(zft_hseg_buf, FT_CMAP_START, 0);
-       zft_volume_table_changed = 1;
-       zft_capacity = zft_get_capacity();
-       zft_init_vtbl();
-       /* the rest must be done in ftape_update_header_segments 
-        */
-       zft_header_read = 1;
-       zft_header_changed = 1; /* force update of timestamp */
-       result = zft_update_header_segments();
-
-       ftape_abort_operation();
-
-       zft_reset_position(&zft_pos);
-       zft_set_flags (zft_unit);
-       TRACE_EXIT result;
-}
-
-unsigned int zft_get_time(void) 
-{
-       unsigned int date = FT_TIME_STAMP(2097, 11, 30, 23, 59, 59); /* fun */
-       return date;
-}
diff --git a/drivers/char/ftape/zftape/zftape-rw.h b/drivers/char/ftape/zftape/zftape-rw.h
deleted file mode 100644 (file)
index 1ceec22..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef _ZFTAPE_RW_H
-#define _ZFTAPE_RW_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-rw.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:09 $
- *
- *      This file contains the definitions for the read and write
- *      functions for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-#include "../zftape/zftape-buffers.h"
-
-#define SEGMENTS_PER_TAPE  (ft_segments_per_track * ft_tracks_per_tape)
-
-/*  QIC-113 Rev. G says that `a maximum of 63488 raw bytes may be
- *  compressed into a single frame'.
- *  Maybe we should stick to 32kb to make it more `beautiful'
- */
-#define ZFT_MAX_BLK_SZ           (62*1024) /* bytes */
-#if !defined(CONFIG_ZFT_DFLT_BLK_SZ)
-# define CONFIG_ZFT_DFLT_BLK_SZ   (10*1024) /* bytes, default of gnu tar */
-#elif CONFIG_ZFT_DFLT_BLK_SZ == 0
-# undef  CONFIG_ZFT_DFLT_BLK_SZ
-# define CONFIG_ZFT_DFLT_BLK_SZ 1
-#elif (CONFIG_ZFT_DFLT_BLK_SZ % 1024) != 0
-# error CONFIG_ZFT_DFLT_BLK_SZ must be 1 or a multiple of 1024
-#endif
-/* The *optional* compression routines need some overhead per tape
- *  block for their purposes. Instead of asking the actual compression
- *  implementation how much it needs, we restrict this overhead to be
- *  maximal of ZFT_CMPT_OVERHEAD size. We need this for EOT
- *  conditions. The tape is assumed to be logical at EOT when the
- *  distance from the physical EOT is less than 
- *  one tape block + ZFT_CMPR_OVERHEAD 
- */
-#define ZFT_CMPR_OVERHEAD 16        /* bytes */
-
-typedef enum
-{ 
-       zft_idle = 0,
-       zft_reading,
-       zft_writing,
-} zft_status_enum;
-
-typedef struct               /*  all values measured in bytes */
-{
-       int   seg_pos;       /*  segment currently positioned at */
-       int   seg_byte_pos;  /*  offset in current segment */ 
-       __s64 tape_pos;      /*  real offset from BOT */
-       __s64 volume_pos;    /*  pos. in uncompressed data stream in
-                             *  current volume 
-                             */
-} zft_position; 
-
-extern zft_position zft_pos;
-extern __u8 *zft_deblock_buf;
-extern __u8 *zft_hseg_buf;
-extern int zft_deblock_segment;
-extern zft_status_enum zft_io_state;
-extern int zft_header_changed;
-extern int zft_qic113; /* conform to old specs. and old zftape */
-extern int zft_use_compression;
-extern unsigned int zft_blk_sz;
-extern __s64 zft_capacity;
-extern unsigned int zft_written_segments;
-extern int zft_label_changed;
-
-/*  zftape-rw.c exported functions
- */
-extern unsigned int zft_get_seg_sz(unsigned int segment);
-extern void  zft_set_flags(unsigned int minor_unit);
-extern int   zft_calc_seg_byte_coord(int *seg_byte_pos, __s64 tape_pos);
-extern __s64 zft_calc_tape_pos(int segment);
-extern __s64 zft_get_capacity(void);
-extern void  zft_update_label(__u8 *buffer);
-extern int   zft_erase(void);
-extern int   zft_verify_write_segments(unsigned int segment, 
-                                      __u8 *data, size_t size, __u8 *buffer);
-extern unsigned int zft_get_time(void);
-#endif /* _ZFTAPE_RW_H */
-
diff --git a/drivers/char/ftape/zftape/zftape-vtbl.c b/drivers/char/ftape/zftape/zftape-vtbl.c
deleted file mode 100644 (file)
index ad7f8be..0000000
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- *      Copyright (c) 1995-1997 Claus-Justus Heine 
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-vtbl.c,v $
- * $Revision: 1.7.6.1 $
- * $Date: 1997/11/24 13:48:31 $
- *
- *      This file defines a volume table as defined in various QIC
- *      standards.
- * 
- *      This is a minimal implementation, just allowing ordinary DOS
- *      :( prgrams to identify the cartridge as used.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-#include <linux/zftape.h>
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-#define ZFT_CMAP_HACK /* leave this defined to hide the compression map */
-
-/*
- *  global variables 
- */
-int zft_qic_mode   = 1; /* use the vtbl */
-int zft_old_ftape; /* prevents old ftaped tapes to be overwritten */
-int zft_volume_table_changed; /* for write_header_segments() */
-
-/*
- *  private variables (only exported for inline functions)
- */
-LIST_HEAD(zft_vtbl);
-
-/*  We could also allocate these dynamically when extracting the volume table
- *  sizeof(zft_volinfo) is about 32 or something close to that
- */
-static zft_volinfo  tape_vtbl;
-static zft_volinfo  eot_vtbl;
-static zft_volinfo *cur_vtbl;
-
-static inline void zft_new_vtbl_entry(void)
-{
-       struct list_head *tmp = &zft_last_vtbl->node;
-       zft_volinfo *new = zft_kmalloc(sizeof(zft_volinfo));
-
-       list_add(&new->node, tmp);
-       new->count = zft_eom_vtbl->count ++;
-}
-
-void zft_free_vtbl(void)
-{
-       for (;;) {
-               struct list_head *tmp = zft_vtbl.prev;
-               zft_volinfo *vtbl;
-
-               if (tmp == &zft_vtbl)
-                       break;
-               list_del(tmp);
-               vtbl = list_entry(tmp, zft_volinfo, node);
-               zft_kfree(vtbl, sizeof(zft_volinfo));
-       }
-       INIT_LIST_HEAD(&zft_vtbl);
-       cur_vtbl = NULL;
-}
-
-/*  initialize vtbl, called by ftape_new_cartridge()
- */
-void zft_init_vtbl(void)
-{ 
-       zft_volinfo *new;
-
-       zft_free_vtbl();
-       
-       /*  Create the two dummy vtbl entries
-        */
-       new = zft_kmalloc(sizeof(zft_volinfo));
-       list_add(&new->node, &zft_vtbl);
-       new = zft_kmalloc(sizeof(zft_volinfo));
-       list_add(&new->node, &zft_vtbl);
-       zft_head_vtbl->end_seg   = ft_first_data_segment;
-       zft_head_vtbl->blk_sz    = zft_blk_sz;
-       zft_head_vtbl->count     = -1;
-       zft_eom_vtbl->start_seg  = ft_first_data_segment + 1;
-       zft_eom_vtbl->end_seg    = ft_last_data_segment + 1;
-       zft_eom_vtbl->blk_sz     = zft_blk_sz;
-       zft_eom_vtbl->count      = 0;
-
-       /*  Reset the pointer for zft_find_volume()
-        */
-       cur_vtbl = zft_eom_vtbl;
-
-       /* initialize the dummy vtbl entries for zft_qic_mode == 0
-        */
-       eot_vtbl.start_seg       = ft_last_data_segment + 1;
-       eot_vtbl.end_seg         = ft_last_data_segment + 1;
-       eot_vtbl.blk_sz          = zft_blk_sz;
-       eot_vtbl.count           = -1;
-       tape_vtbl.start_seg = ft_first_data_segment;
-       tape_vtbl.end_seg   = ft_last_data_segment;
-       tape_vtbl.blk_sz    = zft_blk_sz;
-       tape_vtbl.size      = zft_capacity;
-       tape_vtbl.count     = 0;
-}
-
-/* check for a valid VTBL signature. 
- */
-static int vtbl_signature_valid(__u8 signature[4])
-{
-       const char *vtbl_ids[] = VTBL_IDS; /* valid signatures */
-       int j;
-       
-       for (j = 0; 
-            (j < NR_ITEMS(vtbl_ids)) && (memcmp(signature, vtbl_ids[j], 4) != 0);
-            j++);
-       return j < NR_ITEMS(vtbl_ids);
-}
-
-/* We used to store the block-size of the volume in the volume-label,
- * using the keyword "blocksize". The blocksize written to the
- * volume-label is in bytes.
- *
- * We use this now only for compatibility with old zftape version. We
- * store the blocksize directly as binary number in the vendor
- * extension part of the volume entry.
- */
-static int check_volume_label(const char *label, int *blk_sz)
-{ 
-       int valid_format;
-       char *blocksize;
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "called with \"%s\" / \"%s\"", label, ZFT_VOL_NAME);
-       if (strncmp(label, ZFT_VOL_NAME, strlen(ZFT_VOL_NAME)) != 0) {
-               *blk_sz = 1; /* smallest block size that we allow */
-               valid_format = 0;
-       } else {
-               TRACE(ft_t_noise, "got old style zftape vtbl entry");
-               /* get the default blocksize */
-               /* use the kernel strstr()   */
-               blocksize= strstr(label, " blocksize ");
-               if (blocksize) {
-                       blocksize += strlen(" blocksize ");
-                       for(*blk_sz= 0; 
-                           *blocksize >= '0' && *blocksize <= '9'; 
-                           blocksize++) {
-                               *blk_sz *= 10;
-                               *blk_sz += *blocksize - '0';
-                       }
-                       if (*blk_sz > ZFT_MAX_BLK_SZ) {
-                               *blk_sz= 1;
-                               valid_format= 0;
-                       } else {
-                               valid_format = 1;
-                       }
-               } else {
-                       *blk_sz= 1;
-                       valid_format= 0;
-               }
-       }
-       TRACE_EXIT valid_format;
-}
-
-/*   check for a zftape volume
- */
-static int check_volume(__u8 *entry, zft_volinfo *volume)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       if(strncmp(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG,
-                  strlen(ZFTAPE_SIG)) == 0) {
-               TRACE(ft_t_noise, "got new style zftape vtbl entry");
-               volume->blk_sz = GET2(entry, VTBL_EXT+EXT_ZFTAPE_BLKSZ);
-               volume->qic113 = entry[VTBL_EXT+EXT_ZFTAPE_QIC113];
-               TRACE_EXIT 1;
-       } else {
-               TRACE_EXIT check_volume_label(&entry[VTBL_DESC], &volume->blk_sz);
-       }
-}
-
-
-/* create zftape specific vtbl entry, the volume bounds are inserted
- * in the calling function, zft_create_volume_headers()
- */
-static void create_zft_volume(__u8 *entry, zft_volinfo *vtbl)
-{
-       TRACE_FUN(ft_t_flow);
-
-       memset(entry, 0, VTBL_SIZE);
-       memcpy(&entry[VTBL_SIG], VTBL_ID, 4);
-       sprintf(&entry[VTBL_DESC], ZFT_VOL_NAME" %03d", vtbl->count);
-       entry[VTBL_FLAGS] = (VTBL_FL_NOT_VERIFIED | VTBL_FL_SEG_SPANNING);
-       entry[VTBL_M_NO] = 1; /* multi_cartridge_count */
-       strcpy(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG);
-       PUT2(entry, VTBL_EXT+EXT_ZFTAPE_BLKSZ, vtbl->blk_sz);
-       if (zft_qic113) {
-               PUT8(entry, VTBL_DATA_SIZE, vtbl->size);
-               entry[VTBL_CMPR] = VTBL_CMPR_UNREG; 
-               if (vtbl->use_compression) { /* use compression: */
-                       entry[VTBL_CMPR] |= VTBL_CMPR_USED;
-               }
-               entry[VTBL_EXT+EXT_ZFTAPE_QIC113] = 1;
-       } else {
-               PUT4(entry, VTBL_DATA_SIZE, vtbl->size);
-               entry[VTBL_K_CMPR] = VTBL_CMPR_UNREG; 
-               if (vtbl->use_compression) { /* use compression: */
-                       entry[VTBL_K_CMPR] |= VTBL_CMPR_USED;
-               }
-       }
-       if (ft_format_code == fmt_big) {
-               /* SCSI like vtbl, store the number of used
-                * segments as 4 byte value 
-                */
-               PUT4(entry, VTBL_SCSI_SEGS, vtbl->end_seg-vtbl->start_seg + 1);
-       } else {
-               /* normal, QIC-80MC like vtbl 
-                */
-               PUT2(entry, VTBL_START, vtbl->start_seg);
-               PUT2(entry, VTBL_END, vtbl->end_seg);
-       }
-       TRACE_EXIT;
-}
-
-/* this one creates the volume headers for each volume. It is assumed
- * that buffer already contains the old volume-table, so that vtbl
- * entries without the zft_volume flag set can savely be ignored.
- */
-static void zft_create_volume_headers(__u8 *buffer)
-{   
-       __u8 *entry;
-       struct list_head *tmp;
-       zft_volinfo *vtbl;
-       TRACE_FUN(ft_t_flow);
-       
-#ifdef ZFT_CMAP_HACK
-       if((strncmp(&buffer[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG,
-                   strlen(ZFTAPE_SIG)) == 0) && 
-          buffer[VTBL_EXT+EXT_ZFTAPE_CMAP] != 0) {
-               TRACE(ft_t_noise, "deleting cmap volume");
-               memmove(buffer, buffer + VTBL_SIZE,
-                       FT_SEGMENT_SIZE - VTBL_SIZE);
-       }
-#endif
-       entry = buffer;
-       for (tmp = zft_head_vtbl->node.next;
-            tmp != &zft_eom_vtbl->node;
-            tmp = tmp->next) {
-               vtbl = list_entry(tmp, zft_volinfo, node);
-               /* we now fill in the values only for newly created volumes.
-                */
-               if (vtbl->new_volume) {
-                       create_zft_volume(entry, vtbl);
-                       vtbl->new_volume = 0; /* clear the flag */
-               }
-               
-               DUMP_VOLINFO(ft_t_noise, &entry[VTBL_DESC], vtbl);
-               entry += VTBL_SIZE;
-       }
-       memset(entry, 0, FT_SEGMENT_SIZE - zft_eom_vtbl->count * VTBL_SIZE);
-       TRACE_EXIT;
-}
-
-/*  write volume table to tape. Calls zft_create_volume_headers()
- */
-int zft_update_volume_table(unsigned int segment)
-{
-       int result = 0;
-       __u8 *verify_buf = NULL;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE_CATCH(result = ftape_read_segment(ft_first_data_segment, 
-                                               zft_deblock_buf,
-                                               FT_RD_SINGLE),);
-       zft_create_volume_headers(zft_deblock_buf);
-       TRACE(ft_t_noise, "writing volume table segment %d", segment);
-       if (zft_vmalloc_once(&verify_buf, FT_SEGMENT_SIZE) == 0) {
-               TRACE_CATCH(zft_verify_write_segments(segment, 
-                                                     zft_deblock_buf, result,
-                                                     verify_buf),
-                           zft_vfree(&verify_buf, FT_SEGMENT_SIZE));
-               zft_vfree(&verify_buf, FT_SEGMENT_SIZE);
-       } else {
-               TRACE_CATCH(ftape_write_segment(segment, zft_deblock_buf, 
-                                               FT_WR_SINGLE),);
-       }
-       TRACE_EXIT 0;
-}
-
-/* non zftape volumes are handled in raw mode. Thus we need to
- * calculate the raw amount of data contained in those segments.  
- */
-static void extract_alien_volume(__u8 *entry, zft_volinfo *vtbl)
-{
-       TRACE_FUN(ft_t_flow);
-
-       vtbl->size  = (zft_calc_tape_pos(zft_last_vtbl->end_seg+1) -
-                      zft_calc_tape_pos(zft_last_vtbl->start_seg));
-       vtbl->use_compression = 0;
-       vtbl->qic113 = zft_qic113;
-       if (vtbl->qic113) {
-               TRACE(ft_t_noise, 
-                     "Fake alien volume's size from " LL_X " to " LL_X, 
-                     LL(GET8(entry, VTBL_DATA_SIZE)), LL(vtbl->size));
-       } else {
-               TRACE(ft_t_noise,
-                     "Fake alien volume's size from %d to " LL_X, 
-                     (int)GET4(entry, VTBL_DATA_SIZE), LL(vtbl->size));
-       }
-       TRACE_EXIT;
-}
-
-
-/* extract an zftape specific volume
- */
-static void extract_zft_volume(__u8 *entry, zft_volinfo *vtbl)
-{
-       TRACE_FUN(ft_t_flow);
-
-       if (vtbl->qic113) {
-               vtbl->size = GET8(entry, VTBL_DATA_SIZE);
-               vtbl->use_compression = 
-                       (entry[VTBL_CMPR] & VTBL_CMPR_USED) != 0; 
-       } else {
-               vtbl->size = GET4(entry, VTBL_DATA_SIZE);
-               if (entry[VTBL_K_CMPR] & VTBL_CMPR_UNREG) {
-                       vtbl->use_compression = 
-                               (entry[VTBL_K_CMPR] & VTBL_CMPR_USED) != 0;
-               } else if (entry[VTBL_CMPR] & VTBL_CMPR_UNREG) {
-                       vtbl->use_compression = 
-                               (entry[VTBL_CMPR] & VTBL_CMPR_USED) != 0; 
-               } else {
-                       TRACE(ft_t_warn, "Geeh! There is something wrong:\n"
-                             KERN_INFO "QIC compression (Rev = K): %x\n"
-                             KERN_INFO "QIC compression (Rev > K): %x",
-                             entry[VTBL_K_CMPR], entry[VTBL_CMPR]);
-               }
-       }
-       TRACE_EXIT;
-}
-
-/* extract the volume table from buffer. "buffer" must already contain
- * the vtbl-segment 
- */
-int zft_extract_volume_headers(__u8 *buffer)
-{                            
-        __u8 *entry;
-       TRACE_FUN(ft_t_flow);
-       
-       zft_init_vtbl();
-       entry = buffer;
-#ifdef ZFT_CMAP_HACK
-       if ((strncmp(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG,
-                    strlen(ZFTAPE_SIG)) == 0) &&
-           entry[VTBL_EXT+EXT_ZFTAPE_CMAP] != 0) {
-               TRACE(ft_t_noise, "ignoring cmap volume");
-               entry += VTBL_SIZE;
-       } 
-#endif
-       /* the end of the vtbl is indicated by an invalid signature 
-        */
-       while (vtbl_signature_valid(&entry[VTBL_SIG]) &&
-              (entry - buffer) < FT_SEGMENT_SIZE) {
-               zft_new_vtbl_entry();
-               if (ft_format_code == fmt_big) {
-                       /* SCSI like vtbl, stores only the number of
-                        * segments used 
-                        */
-                       unsigned int num_segments= GET4(entry, VTBL_SCSI_SEGS);
-                       zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;
-                       zft_last_vtbl->end_seg = 
-                               zft_last_vtbl->start_seg + num_segments - 1;
-               } else {
-                       /* `normal', QIC-80 like vtbl 
-                        */
-                       zft_last_vtbl->start_seg = GET2(entry, VTBL_START);
-                       zft_last_vtbl->end_seg   = GET2(entry, VTBL_END);
-               }
-               zft_eom_vtbl->start_seg  = zft_last_vtbl->end_seg + 1;
-               /* check if we created this volume and get the
-                * blk_sz 
-                */
-               zft_last_vtbl->zft_volume = check_volume(entry, zft_last_vtbl);
-               if (zft_last_vtbl->zft_volume == 0) {
-                       extract_alien_volume(entry, zft_last_vtbl);
-               } else {
-                       extract_zft_volume(entry, zft_last_vtbl);
-               }
-               DUMP_VOLINFO(ft_t_noise, &entry[VTBL_DESC], zft_last_vtbl);
-               entry +=VTBL_SIZE;
-       }
-#if 0
-/*
- *  undefine to test end of tape handling
- */
-       zft_new_vtbl_entry();
-       zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;
-       zft_last_vtbl->end_seg   = ft_last_data_segment - 10;
-       zft_last_vtbl->blk_sz          = zft_blk_sz;
-       zft_last_vtbl->zft_volume      = 1;
-       zft_last_vtbl->qic113          = zft_qic113;
-       zft_last_vtbl->size = (zft_calc_tape_pos(zft_last_vtbl->end_seg+1)
-                              - zft_calc_tape_pos(zft_last_vtbl->start_seg));
-#endif
-       TRACE_EXIT 0;
-}
-
-/* this functions translates the failed_sector_log, misused as
- * EOF-marker list, into a virtual volume table. The table mustn't be
- * written to tape, because this would occupy the first data segment,
- * which should be the volume table, but is actually the first segment
- * that is filled with data (when using standard ftape).  We assume,
- * that we get a non-empty failed_sector_log.
- */
-int zft_fake_volume_headers (eof_mark_union *eof_map, int num_failed_sectors)
-{
-       unsigned int segment, sector;
-       int have_eom = 0;
-       int vol_no;
-       TRACE_FUN(ft_t_flow);
-
-       if ((num_failed_sectors >= 2) &&
-           (GET2(&eof_map[num_failed_sectors - 1].mark.segment, 0) 
-            == 
-            GET2(&eof_map[num_failed_sectors - 2].mark.segment, 0) + 1) &&
-           (GET2(&eof_map[num_failed_sectors - 1].mark.date, 0) == 1)) {
-               /* this should be eom. We keep the remainder of the
-                * tape as another volume.
-                */
-               have_eom = 1;
-       }
-       zft_init_vtbl();
-       zft_eom_vtbl->start_seg = ft_first_data_segment;
-       for(vol_no = 0; vol_no < num_failed_sectors - have_eom; vol_no ++) {
-               zft_new_vtbl_entry();
-
-               segment = GET2(&eof_map[vol_no].mark.segment, 0);
-               sector  = GET2(&eof_map[vol_no].mark.date, 0);
-
-               zft_last_vtbl->start_seg  = zft_eom_vtbl->start_seg;
-               zft_last_vtbl->end_seg    = segment;
-               zft_eom_vtbl->start_seg  = segment + 1;
-               zft_last_vtbl->blk_sz     = 1;
-               zft_last_vtbl->size       = 
-                       (zft_calc_tape_pos(zft_last_vtbl->end_seg)
-                        - zft_calc_tape_pos(zft_last_vtbl->start_seg)
-                        + (sector-1) * FT_SECTOR_SIZE);
-               TRACE(ft_t_noise, 
-                     "failed sector log: segment: %d, sector: %d", 
-                     segment, sector);
-               DUMP_VOLINFO(ft_t_noise, "Faked volume", zft_last_vtbl);
-       }
-       if (!have_eom) {
-               zft_new_vtbl_entry();
-               zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;
-               zft_last_vtbl->end_seg   = ft_last_data_segment;
-               zft_eom_vtbl->start_seg  = ft_last_data_segment + 1;
-               zft_last_vtbl->size      = zft_capacity;
-               zft_last_vtbl->size     -= zft_calc_tape_pos(zft_last_vtbl->start_seg);
-               zft_last_vtbl->blk_sz    = 1;
-               DUMP_VOLINFO(ft_t_noise, "Faked volume",zft_last_vtbl);
-       }
-       TRACE_EXIT 0;
-}
-
-/* update the internal volume table
- *
- * if before start of last volume: erase all following volumes if
- * inside a volume: set end of volume to infinity
- *
- * this function is intended to be called every time _ftape_write() is
- * called
- *
- * return: 0 if no new volume was created, 1 if a new volume was
- * created
- *
- * NOTE: we don't need to check for zft_mode as ftape_write() does
- * that already. This function gets never called without accessing
- * zftape via the *qft* devices 
- */
-
-int zft_open_volume(zft_position *pos, int blk_sz, int use_compression)
-{ 
-       TRACE_FUN(ft_t_flow);
-       
-       if (!zft_qic_mode) {
-               TRACE_EXIT 0;
-       }
-       if (zft_tape_at_lbot(pos)) {
-               zft_init_vtbl();
-               if(zft_old_ftape) {
-                       /* clear old ftape's eof marks */
-                       zft_clear_ftape_file_marks();
-                       zft_old_ftape = 0; /* no longer old ftape */
-               }
-               zft_reset_position(pos);
-       }
-       if (pos->seg_pos != zft_last_vtbl->end_seg + 1) {
-               TRACE_ABORT(-EIO, ft_t_bug, 
-                     "BUG: seg_pos: %d, zft_last_vtbl->end_seg: %d", 
-                     pos->seg_pos, zft_last_vtbl->end_seg);
-       }                            
-       TRACE(ft_t_noise, "create new volume");
-       if (zft_eom_vtbl->count >= ZFT_MAX_VOLUMES) {
-               TRACE_ABORT(-ENOSPC, ft_t_err,
-                           "Error: maxmimal number of volumes exhausted "
-                           "(maxmimum is %d)", ZFT_MAX_VOLUMES);
-       }
-       zft_new_vtbl_entry();
-       pos->volume_pos = pos->seg_byte_pos = 0;
-       zft_last_vtbl->start_seg       = pos->seg_pos;
-       zft_last_vtbl->end_seg         = ft_last_data_segment; /* infinity */
-       zft_last_vtbl->blk_sz          = blk_sz;
-       zft_last_vtbl->size            = zft_capacity;
-       zft_last_vtbl->zft_volume      = 1;
-       zft_last_vtbl->use_compression = use_compression;
-       zft_last_vtbl->qic113          = zft_qic113;
-       zft_last_vtbl->new_volume      = 1;
-       zft_last_vtbl->open            = 1;
-       zft_volume_table_changed = 1;
-       zft_eom_vtbl->start_seg  = ft_last_data_segment + 1;
-       TRACE_EXIT 0;
-}
-
-/*  perform mtfsf, mtbsf, not allowed without zft_qic_mode
- */
-int zft_skip_volumes(int count, zft_position *pos)
-{ 
-       const zft_volinfo *vtbl;
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_noise, "count: %d", count);
-       
-       vtbl= zft_find_volume(pos->seg_pos);
-       while (count > 0 && vtbl != zft_eom_vtbl) {
-               vtbl = list_entry(vtbl->node.next, zft_volinfo, node);
-               count --;
-       }
-       while (count < 0 && vtbl != zft_first_vtbl) {
-               vtbl = list_entry(vtbl->node.prev, zft_volinfo, node);
-               count ++;
-       }
-       pos->seg_pos        = vtbl->start_seg;
-       pos->seg_byte_pos   = 0;
-       pos->volume_pos     = 0;
-       pos->tape_pos       = zft_calc_tape_pos(pos->seg_pos);
-       zft_just_before_eof = vtbl->size == 0;
-       if (zft_cmpr_ops) {
-               (*zft_cmpr_ops->reset)();
-       }
-       zft_deblock_segment = -1; /* no need to keep cache */
-       TRACE(ft_t_noise, "repositioning to:\n"
-             KERN_INFO "zft_seg_pos        : %d\n"
-             KERN_INFO "zft_seg_byte_pos   : %d\n"
-             KERN_INFO "zft_tape_pos       : " LL_X "\n"
-             KERN_INFO "zft_volume_pos     : " LL_X "\n"
-             KERN_INFO "file number        : %d",
-             pos->seg_pos, pos->seg_byte_pos, 
-             LL(pos->tape_pos), LL(pos->volume_pos), vtbl->count);
-       zft_resid = count < 0 ? -count : count;
-       TRACE_EXIT zft_resid ? -EINVAL : 0;
-}
-
-/* the following simply returns the raw data position of the EOM
- * marker, MTIOCSIZE ioctl 
- */
-__s64 zft_get_eom_pos(void)
-{
-       if (zft_qic_mode) {
-               return zft_calc_tape_pos(zft_eom_vtbl->start_seg);
-       } else {
-               /* there is only one volume in raw mode */
-               return zft_capacity;
-       }
-}
-
-/* skip to eom, used for MTEOM
- */
-void zft_skip_to_eom(zft_position *pos)
-{
-       TRACE_FUN(ft_t_flow);
-       pos->seg_pos      = zft_eom_vtbl->start_seg;
-       pos->seg_byte_pos = 
-               pos->volume_pos     = 
-               zft_just_before_eof = 0;
-       pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
-       TRACE(ft_t_noise, "ftape positioned to segment %d, data pos " LL_X, 
-             pos->seg_pos, LL(pos->tape_pos));
-       TRACE_EXIT;
-}
-
-/*  write an EOF-marker by setting zft_last_vtbl->end_seg to seg_pos.
- *  NOTE: this function assumes that zft_last_vtbl points to a valid
- *  vtbl entry
- *
- *  NOTE: this routine always positions before the EOF marker
- */
-int zft_close_volume(zft_position *pos)
-{
-       TRACE_FUN(ft_t_any);
-
-       if (zft_vtbl_empty || !zft_last_vtbl->open) { /* should not happen */
-               TRACE(ft_t_noise, "There are no volumes to finish");
-               TRACE_EXIT -EIO;
-       }
-       if (pos->seg_byte_pos == 0 && 
-           pos->seg_pos != zft_last_vtbl->start_seg) {
-               pos->seg_pos --;
-               pos->seg_byte_pos      = zft_get_seg_sz(pos->seg_pos);
-       }
-       zft_last_vtbl->end_seg   = pos->seg_pos;
-       zft_last_vtbl->size      = pos->volume_pos;
-       zft_volume_table_changed = 1;
-       zft_just_before_eof      = 1;
-       zft_eom_vtbl->start_seg  = zft_last_vtbl->end_seg + 1;
-       zft_last_vtbl->open      = 0; /* closed */
-       TRACE_EXIT 0;
-}
-
-/* write count file-marks at current position. 
- *
- *  The tape is positioned after the eof-marker, that is at byte 0 of
- *  the segment following the eof-marker
- *
- *  this function is only allowed in zft_qic_mode
- *
- *  Only allowed when tape is at BOT or EOD.
- */
-int zft_weof(unsigned int count, zft_position *pos)
-{
-       
-       TRACE_FUN(ft_t_flow);
-
-       if (!count) { /* write zero EOF marks should be a real no-op */
-               TRACE_EXIT 0;
-       }
-       zft_volume_table_changed = 1;
-       if (zft_tape_at_lbot(pos)) {
-               zft_init_vtbl();
-               if(zft_old_ftape) {
-                       /* clear old ftape's eof marks */
-                       zft_clear_ftape_file_marks();
-                       zft_old_ftape = 0;    /* no longer old ftape */
-               }
-       }
-       if (zft_last_vtbl->open) {
-               zft_close_volume(pos);
-               zft_move_past_eof(pos);
-               count --;
-       }
-       /* now it's easy, just append eof-marks, that is empty
-        * volumes, to the end of the already recorded media.
-        */
-       while (count > 0 && 
-              pos->seg_pos <= ft_last_data_segment && 
-              zft_eom_vtbl->count < ZFT_MAX_VOLUMES) {
-               TRACE(ft_t_noise,
-                     "Writing zero sized file at segment %d", pos->seg_pos);
-               zft_new_vtbl_entry();
-               zft_last_vtbl->start_seg       = pos->seg_pos;
-               zft_last_vtbl->end_seg         = pos->seg_pos;
-               zft_last_vtbl->size            = 0;
-               zft_last_vtbl->blk_sz          = zft_blk_sz;
-               zft_last_vtbl->zft_volume      = 1;
-               zft_last_vtbl->use_compression = 0;
-               pos->tape_pos += zft_get_seg_sz(pos->seg_pos);
-               zft_eom_vtbl->start_seg = ++ pos->seg_pos;
-               count --;
-       } 
-       if (count > 0) {
-               /*  there are two possibilities: end of tape, or the
-                *  maximum number of files is exhausted.
-                */
-               zft_resid = count;
-               TRACE(ft_t_noise,"Number of marks NOT written: %d", zft_resid);
-               if (zft_eom_vtbl->count == ZFT_MAX_VOLUMES) {
-                       TRACE_ABORT(-EINVAL, ft_t_warn,
-                                   "maximum allowed number of files "
-                                   "exhausted: %d", ZFT_MAX_VOLUMES);
-               } else {
-                       TRACE_ABORT(-ENOSPC,
-                                   ft_t_noise, "reached end of tape");
-               }
-       }
-       TRACE_EXIT 0;
-}
-
-const zft_volinfo *zft_find_volume(unsigned int seg_pos)
-{
-       TRACE_FUN(ft_t_flow);
-       
-       TRACE(ft_t_any, "called with seg_pos %d",seg_pos);
-       if (!zft_qic_mode) {
-               if (seg_pos > ft_last_data_segment) {
-                       TRACE_EXIT &eot_vtbl;
-               }
-               tape_vtbl.blk_sz =  zft_blk_sz;
-               TRACE_EXIT &tape_vtbl;
-       }
-       if (seg_pos < zft_first_vtbl->start_seg) {
-               TRACE_EXIT (cur_vtbl = zft_first_vtbl);
-       }
-       while (seg_pos > cur_vtbl->end_seg) {
-               cur_vtbl = list_entry(cur_vtbl->node.next, zft_volinfo, node);
-               TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg);
-       }
-       while (seg_pos < cur_vtbl->start_seg) {
-               cur_vtbl = list_entry(cur_vtbl->node.prev, zft_volinfo, node);
-               TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg);
-       }
-       if (seg_pos > cur_vtbl->end_seg || seg_pos < cur_vtbl->start_seg) {
-               TRACE(ft_t_bug, "This cannot happen");
-       }
-       DUMP_VOLINFO(ft_t_noise, "", cur_vtbl);
-       TRACE_EXIT cur_vtbl;
-}
-
-/* this function really assumes that we are just before eof
- */
-void zft_move_past_eof(zft_position *pos)
-{ 
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_noise, "old seg. pos: %d", pos->seg_pos);
-       pos->tape_pos += zft_get_seg_sz(pos->seg_pos++) - pos->seg_byte_pos;
-       pos->seg_byte_pos = 0;
-       pos->volume_pos   = 0;
-       if (zft_cmpr_ops) {
-               (*zft_cmpr_ops->reset)();
-       }
-       zft_just_before_eof =  0;
-       zft_deblock_segment = -1; /* no need to cache it anymore */
-       TRACE(ft_t_noise, "new seg. pos: %d", pos->seg_pos);
-       TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/zftape/zftape-vtbl.h b/drivers/char/ftape/zftape/zftape-vtbl.h
deleted file mode 100644 (file)
index f31d196..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-#ifndef _ZFTAPE_VTBL_H
-#define _ZFTAPE_VTBL_H
-
-/*
- *      Copyright (c) 1995-1997  Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-vtbl.h,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/28 14:30:09 $
- *
- *      This file defines a volume table as defined in the QIC-80
- *      development standards.
- */
-
-#include <linux/list.h>
-
-#include "../lowlevel/ftape-tracing.h"
-
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-rw.h"
-
-#define VTBL_SIZE 128 /* bytes */
-
-/* The following are offsets in the vtbl.  */
-#define VTBL_SIG   0
-#define VTBL_START 4
-#define VTBL_END   6
-#define VTBL_DESC  8
-#define VTBL_DATE  52
-#define VTBL_FLAGS 56
-#define VTBL_FL_VENDOR_SPECIFIC (1<<0)
-#define VTBL_FL_MUTLI_CARTRIDGE (1<<1)
-#define VTBL_FL_NOT_VERIFIED    (1<<2)
-#define VTBL_FL_REDIR_INHIBIT   (1<<3)
-#define VTBL_FL_SEG_SPANNING    (1<<4)
-#define VTBL_FL_DIRECTORY_LAST  (1<<5)
-#define VTBL_FL_RESERVED_6      (1<<6)
-#define VTBL_FL_RESERVED_7      (1<<7)
-#define VTBL_M_NO  57
-#define VTBL_EXT   58
-#define EXT_ZFTAPE_SIG     0
-#define EXT_ZFTAPE_BLKSZ  10
-#define EXT_ZFTAPE_CMAP   12
-#define EXT_ZFTAPE_QIC113 13
-#define VTBL_PWD   84
-#define VTBL_DIR_SIZE 92
-#define VTBL_DATA_SIZE 96
-#define VTBL_OS_VERSION 104
-#define VTBL_SRC_DRIVE  106
-#define VTBL_DEV        122
-#define VTBL_RESERVED_1 123
-#define VTBL_CMPR       124
-#define VTBL_CMPR_UNREG 0x3f
-#define VTBL_CMPR_USED  0x80
-#define VTBL_FMT        125
-#define VTBL_RESERVED_2 126
-#define VTBL_RESERVED_3 127
-/* compatibility with pre revision K */
-#define VTBL_K_CMPR     120 
-
-/*  the next is used by QIC-3020 tapes with format code 6 (>2^16
- *  segments) It is specified in QIC-113, Rev. G, Section 5 (SCSI
- *  volume table). The difference is simply, that we only store the
- *  number of segments used, not the starting segment.
- */
-#define VTBL_SCSI_SEGS  4 /* is a 4 byte value */
-
-/*  one vtbl is 128 bytes, that results in a maximum number of
- *  29*1024/128 = 232 volumes.
- */
-#define ZFT_MAX_VOLUMES (FT_SEGMENT_SIZE/VTBL_SIZE)
-#define VTBL_ID  "VTBL"
-#define VTBL_IDS { VTBL_ID, "XTBL", "UTID", "EXVT" } /* other valid ids */
-#define ZFT_VOL_NAME "zftape volume" /* volume label used by me */
-#define ZFTAPE_SIG "LINUX ZFT"
-
-/*  global variables
- */
-typedef struct zft_internal_vtbl
-{
-       struct list_head node;
-       int          count;
-       unsigned int start_seg;         /* 32 bits are enough for now */
-       unsigned int end_seg;           /* 32 bits are enough for now */
-       __s64        size;              /* uncompressed size */
-        unsigned int blk_sz;            /* block size for this volume */
-       unsigned int zft_volume     :1; /* zftape created this volume */
-       unsigned int use_compression:1; /* compressed volume  */
-       unsigned int qic113         :1; /* layout of compressed block
-                                        * info and vtbl conforms to
-                                        * QIC-113, Rev. G 
-                                        */
-       unsigned int new_volume     :1; /* it was created by us, this
-                                        * run.  this allows the
-                                        * fields that aren't really
-                                        * used by zftape to be filled
-                                        * in by some user level
-                                        * program.
-                                        */
-       unsigned int open           :1; /* just in progress of being 
-                                        * written
-                                        */
-} zft_volinfo;
-
-extern struct list_head zft_vtbl;
-#define zft_head_vtbl  list_entry(zft_vtbl.next, zft_volinfo, node)
-#define zft_eom_vtbl   list_entry(zft_vtbl.prev, zft_volinfo, node)
-#define zft_last_vtbl  list_entry(zft_eom_vtbl->node.prev, zft_volinfo, node)
-#define zft_first_vtbl list_entry(zft_head_vtbl->node.next, zft_volinfo, node)
-#define zft_vtbl_empty (zft_eom_vtbl->node.prev == &zft_head_vtbl->node)
-
-#define DUMP_VOLINFO(level, desc, info)                                        \
-{                                                                      \
-       char tmp[21];                                                   \
-       strlcpy(tmp, desc, sizeof(tmp));                                \
-       TRACE(level, "Volume %d:\n"                                     \
-             KERN_INFO "description  : %s\n"                           \
-             KERN_INFO "first segment: %d\n"                           \
-             KERN_INFO "last  segment: %d\n"                           \
-             KERN_INFO "size         : " LL_X "\n"                     \
-             KERN_INFO "block size   : %d\n"                           \
-             KERN_INFO "compression  : %d\n"                           \
-             KERN_INFO "zftape volume: %d\n"                           \
-             KERN_INFO "QIC-113 conf.: %d",                            \
-             (info)->count, tmp, (info)->start_seg, (info)->end_seg,   \
-             LL((info)->size), (info)->blk_sz,                         \
-             (info)->use_compression != 0, (info)->zft_volume != 0,    \
-             (info)->qic113 != 0);                                     \
-}
-
-extern int zft_qic_mode;
-extern int zft_old_ftape;
-extern int zft_volume_table_changed;
-
-/* exported functions */
-extern void  zft_init_vtbl             (void);
-extern void  zft_free_vtbl             (void);
-extern int   zft_extract_volume_headers(__u8 *buffer);
-extern int   zft_update_volume_table   (unsigned int segment);
-extern int   zft_open_volume           (zft_position *pos,
-                                       int blk_sz, int use_compression);
-extern int   zft_close_volume          (zft_position *pos);
-extern const zft_volinfo *zft_find_volume(unsigned int seg_pos);
-extern int   zft_skip_volumes          (int count, zft_position *pos);
-extern __s64 zft_get_eom_pos           (void);
-extern void  zft_skip_to_eom           (zft_position *pos);
-extern int   zft_fake_volume_headers   (eof_mark_union *eof_map, 
-                                       int num_failed_sectors);
-extern int   zft_weof                  (unsigned int count, zft_position *pos);
-extern void  zft_move_past_eof         (zft_position *pos);
-
-static inline int   zft_tape_at_eod         (const zft_position *pos);
-static inline int   zft_tape_at_lbot        (const zft_position *pos);
-static inline void  zft_position_before_eof (zft_position *pos, 
-                                            const zft_volinfo *volume);
-static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
-                                     const zft_position *pos);
-
-/* this function decrements the zft_seg_pos counter if we are right
- * at the beginning of a segment. This is to handle fsfm/bsfm -- we
- * need to position before the eof mark.  NOTE: zft_tape_pos is not
- * changed 
- */
-static inline void zft_position_before_eof(zft_position *pos, 
-                                          const zft_volinfo *volume)
-{ 
-       TRACE_FUN(ft_t_flow);
-
-       if (pos->seg_pos == volume->end_seg + 1 &&  pos->seg_byte_pos == 0) {
-               pos->seg_pos --;
-               pos->seg_byte_pos = zft_get_seg_sz(pos->seg_pos);
-       }
-       TRACE_EXIT;
-}
-
-/*  Mmmh. Is the position at the end of the last volume, that is right
- *  before the last EOF mark also logical an EOD condition?
- */
-static inline int zft_tape_at_eod(const zft_position *pos)
-{ 
-       TRACE_FUN(ft_t_any);
-
-       if (zft_qic_mode) {
-               TRACE_EXIT (pos->seg_pos >= zft_eom_vtbl->start_seg ||
-                           zft_last_vtbl->open);
-       } else {
-               TRACE_EXIT pos->seg_pos > ft_last_data_segment;
-       }
-}
-
-static inline int zft_tape_at_lbot(const zft_position *pos)
-{
-       if (zft_qic_mode) {
-               return (pos->seg_pos <= zft_first_vtbl->start_seg &&
-                       pos->volume_pos == 0);
-       } else {
-               return (pos->seg_pos <= ft_first_data_segment && 
-                       pos->volume_pos == 0);
-       }
-}
-
-/* This one checks for EOF.  return remaing space (may be negative) 
- */
-static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
-                                     const zft_position *pos)
-{     
-       return (__s64)(vtbl->size - pos->volume_pos);
-}
-
-#endif /* _ZFTAPE_VTBL_H */
diff --git a/drivers/char/ftape/zftape/zftape-write.c b/drivers/char/ftape/zftape/zftape-write.c
deleted file mode 100644 (file)
index 94327b8..0000000
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- *      Copyright (C) 1996, 1997 Claus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-write.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/11/06 00:50:29 $
- *
- *      This file contains the writing code
- *      for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/*      Global vars.
- */
-
-/*      Local vars.
- */
-static int last_write_failed;
-static int need_flush;
-
-void zft_prevent_flush(void)
-{
-       need_flush = 0;
-}
-
-static int zft_write_header_segments(__u8* buffer)
-{
-       int header_1_ok = 0;
-       int header_2_ok = 0;
-       unsigned int time_stamp;
-       TRACE_FUN(ft_t_noise);
-       
-       TRACE_CATCH(ftape_abort_operation(),);
-       ftape_seek_to_bot();    /* prevents extra rewind */
-       if (GET4(buffer, 0) != FT_HSEG_MAGIC) {
-               TRACE_ABORT(-EIO, ft_t_err,
-                           "wrong header signature found, aborting");
-       } 
-       /*   Be optimistic: */
-       PUT4(buffer, FT_SEG_CNT,
-            zft_written_segments + GET4(buffer, FT_SEG_CNT) + 2);
-       if ((time_stamp = zft_get_time()) != 0) {
-               PUT4(buffer, FT_WR_DATE, time_stamp);
-               if (zft_label_changed) {
-                       PUT4(buffer, FT_LABEL_DATE, time_stamp);
-               }
-       }
-       TRACE(ft_t_noise,
-             "writing first header segment %d", ft_header_segment_1);
-       header_1_ok = zft_verify_write_segments(ft_header_segment_1, 
-                                               buffer, FT_SEGMENT_SIZE,
-                                               zft_deblock_buf) >= 0;
-       TRACE(ft_t_noise,
-             "writing second header segment %d", ft_header_segment_2);
-       header_2_ok = zft_verify_write_segments(ft_header_segment_2, 
-                                               buffer, FT_SEGMENT_SIZE,
-                                               zft_deblock_buf) >= 0;
-       if (!header_1_ok) {
-               TRACE(ft_t_warn, "Warning: "
-                     "update of first header segment failed");
-       }
-       if (!header_2_ok) {
-               TRACE(ft_t_warn, "Warning: "
-                     "update of second header segment failed");
-       }
-       if (!header_1_ok && !header_2_ok) {
-               TRACE_ABORT(-EIO, ft_t_err, "Error: "
-                     "update of both header segments failed.");
-       }
-       TRACE_EXIT 0;
-}
-
-int zft_update_header_segments(void)
-{
-       TRACE_FUN(ft_t_noise);
-       
-       /*  must NOT use zft_write_protected, as it also includes the
-        *  file access mode. But we also want to update when soft
-        *  write protection is enabled (O_RDONLY)
-        */
-       if (ft_write_protected || zft_old_ftape) {
-               TRACE_ABORT(0, ft_t_noise, "Tape set read-only: no update");
-       } 
-       if (!zft_header_read) {
-               TRACE_ABORT(0, ft_t_noise, "Nothing to update");
-       }
-       if (!zft_header_changed) {
-               zft_header_changed = zft_written_segments > 0;
-       }
-       if (!zft_header_changed && !zft_volume_table_changed) {
-               TRACE_ABORT(0, ft_t_noise, "Nothing to update");
-       }
-       TRACE(ft_t_noise, "Updating header segments");
-       if (ftape_get_status()->fti_state == writing) {
-               TRACE_CATCH(ftape_loop_until_writes_done(),);
-       }
-       TRACE_CATCH(ftape_abort_operation(),);
-       
-       zft_deblock_segment = -1; /* invalidate the cache */
-       if (zft_header_changed) {
-               TRACE_CATCH(zft_write_header_segments(zft_hseg_buf),);
-       }
-       if (zft_volume_table_changed) {
-               TRACE_CATCH(zft_update_volume_table(ft_first_data_segment),);
-       }
-       zft_header_changed =
-               zft_volume_table_changed = 
-               zft_label_changed        =
-               zft_written_segments     = 0;
-       TRACE_CATCH(ftape_abort_operation(),);
-       ftape_seek_to_bot();
-       TRACE_EXIT 0;
-}
-
-static int read_merge_buffer(int seg_pos, __u8 *buffer, int offset, int seg_sz)
-{
-       int result = 0;
-       const ft_trace_t old_tracing = TRACE_LEVEL;
-       TRACE_FUN(ft_t_flow);
-       
-       if (zft_qic_mode) {
-               /*  writing in the middle of a volume is NOT allowed
-                *
-                */
-               TRACE(ft_t_noise, "No need to read a segment");
-               memset(buffer + offset, 0, seg_sz - offset);
-               TRACE_EXIT 0;
-       }
-       TRACE(ft_t_any, "waiting");
-       ftape_start_writing(FT_WR_MULTI);
-       TRACE_CATCH(ftape_loop_until_writes_done(),);
-       
-       TRACE(ft_t_noise, "trying to read segment %d from offset %d",
-             seg_pos, offset);
-       SET_TRACE_LEVEL(ft_t_bug);
-       result = zft_fetch_segment_fraction(seg_pos, buffer, 
-                                           FT_RD_SINGLE,
-                                           offset, seg_sz - offset);
-       SET_TRACE_LEVEL(old_tracing);
-       if (result != (seg_sz - offset)) {
-               TRACE(ft_t_noise, "Ignore error: read_segment() result: %d",
-                     result);
-               memset(buffer + offset, 0, seg_sz - offset);
-       }
-       TRACE_EXIT 0;
-}
-
-/* flush the write buffer to tape and write an eof-marker at the
- * current position if not in raw mode.  This function always
- * positions the tape before the eof-marker.  _ftape_close() should
- * then advance to the next segment.
- *
- * the parameter "finish_volume" describes whether to position before
- * or after the possibly created file-mark. We always position after
- * the file-mark when called from ftape_close() and a flush was needed
- * (that is ftape_write() was the last tape operation before calling
- * ftape_flush) But we always position before the file-mark when this
- * function get's called from outside ftape_close() 
- */
-int zft_flush_buffers(void)
-{
-       int result;
-       int data_remaining;
-       int this_segs_size;
-       TRACE_FUN(ft_t_flow);
-
-       TRACE(ft_t_data_flow,
-             "entered, ftape_state = %d", ftape_get_status()->fti_state);
-       if (ftape_get_status()->fti_state != writing && !need_flush) {
-               TRACE_ABORT(0, ft_t_noise, "no need for flush");
-       }
-       zft_io_state = zft_idle; /*  triggers some initializations for the
-                                 *  read and write routines 
-                                 */
-       if (last_write_failed) {
-               ftape_abort_operation();
-               TRACE_EXIT -EIO;
-       }
-       TRACE(ft_t_noise, "flushing write buffers");
-       this_segs_size = zft_get_seg_sz(zft_pos.seg_pos);
-       if (this_segs_size == zft_pos.seg_byte_pos) {
-               zft_pos.seg_pos ++;
-               data_remaining = zft_pos.seg_byte_pos = 0;
-       } else {
-               data_remaining = zft_pos.seg_byte_pos;
-       }
-       /* If there is any data not written to tape yet, append zero's
-        * up to the end of the sector (if using compression) or merge
-        * it with the data existing on the tape Then write the
-        * segment(s) to tape.
-        */
-       TRACE(ft_t_noise, "Position:\n"
-             KERN_INFO "seg_pos  : %d\n"
-             KERN_INFO "byte pos : %d\n"
-             KERN_INFO "remaining: %d",
-             zft_pos.seg_pos, zft_pos.seg_byte_pos, data_remaining);
-       if (data_remaining > 0) {
-               do {
-                       this_segs_size = zft_get_seg_sz(zft_pos.seg_pos);
-                       if (this_segs_size > data_remaining) {
-                               TRACE_CATCH(read_merge_buffer(zft_pos.seg_pos,
-                                                             zft_deblock_buf,
-                                                             data_remaining,
-                                                             this_segs_size),
-                                           last_write_failed = 1);
-                       }
-                       result = ftape_write_segment(zft_pos.seg_pos, 
-                                                    zft_deblock_buf,
-                                                    FT_WR_MULTI);
-                       if (result != this_segs_size) {
-                               TRACE(ft_t_err, "flush buffers failed");
-                               zft_pos.tape_pos    -= zft_pos.seg_byte_pos;
-                               zft_pos.seg_byte_pos = 0;
-
-                               last_write_failed = 1;
-                               TRACE_EXIT result;
-                       }
-                       zft_written_segments ++;
-                       TRACE(ft_t_data_flow,
-                             "flush, moved out buffer: %d", result);
-                       /* need next segment for more data (empty segments?)
-                        */
-                       if (result < data_remaining) { 
-                               if (result > 0) {       
-                                       /* move remainder to buffer beginning 
-                                        */
-                                       memmove(zft_deblock_buf, 
-                                               zft_deblock_buf + result,
-                                               FT_SEGMENT_SIZE - result);
-                               }
-                       } 
-                       data_remaining -= result;
-                       zft_pos.seg_pos ++;
-               } while (data_remaining > 0);
-               TRACE(ft_t_any, "result: %d", result);
-               zft_deblock_segment = --zft_pos.seg_pos;
-               if (data_remaining == 0) {  /* first byte next segment */
-                       zft_pos.seg_byte_pos = this_segs_size;
-               } else { /* after data previous segment, data_remaining < 0 */
-                       zft_pos.seg_byte_pos = data_remaining + result;
-               }
-       } else {
-               TRACE(ft_t_noise, "zft_deblock_buf empty");
-               zft_pos.seg_pos --;
-               zft_pos.seg_byte_pos = zft_get_seg_sz (zft_pos.seg_pos);
-               ftape_start_writing(FT_WR_MULTI);
-       }
-       TRACE(ft_t_any, "waiting");
-       if ((result = ftape_loop_until_writes_done()) < 0) {
-               /* that's really bad. What to to with zft_tape_pos? 
-                */
-               TRACE(ft_t_err, "flush buffers failed");
-       }
-       TRACE(ft_t_any, "zft_seg_pos: %d, zft_seg_byte_pos: %d",
-             zft_pos.seg_pos, zft_pos.seg_byte_pos);
-       last_write_failed  =
-               need_flush = 0;
-       TRACE_EXIT result;
-}
-
-/* return-value: the number of bytes removed from the user-buffer
- *
- * out: 
- *      int *write_cnt: how much actually has been moved to the
- *                      zft_deblock_buf
- *      int req_len  : MUST NOT BE CHANGED, except at EOT, in 
- *                      which case it may be adjusted
- * in : 
- *      char *buff        : the user buffer
- *      int buf_pos_write : copy of buf_len_wr int
- *      this_segs_size    : the size in bytes of the actual segment
- *                          char
- *      *zft_deblock_buf   : zft_deblock_buf
- */
-static int zft_simple_write(int *cnt,
-                           __u8 *dst_buf, const int seg_sz,
-                           const __u8 __user *src_buf, const int req_len, 
-                           const zft_position *pos,const zft_volinfo *volume)
-{
-       int space_left;
-       TRACE_FUN(ft_t_flow);
-
-       /* volume->size holds the tape capacity while volume is open */
-       if (pos->tape_pos + volume->blk_sz > volume->size) {
-               TRACE_EXIT -ENOSPC;
-       }
-       /*  remaining space in this segment, NOT zft_deblock_buf
-        */
-       space_left = seg_sz - pos->seg_byte_pos;
-       *cnt = req_len < space_left ? req_len : space_left;
-       if (copy_from_user(dst_buf + pos->seg_byte_pos, src_buf, *cnt) != 0) {
-               TRACE_EXIT -EFAULT;
-       }
-       TRACE_EXIT *cnt;
-}
-
-static int check_write_access(int req_len,
-                             const zft_volinfo **volume,
-                             zft_position *pos,
-                             const unsigned int blk_sz)
-{
-       int result;
-       TRACE_FUN(ft_t_flow);
-
-       if ((req_len % zft_blk_sz) != 0) {
-               TRACE_ABORT(-EINVAL, ft_t_info,
-                           "write-count %d must be multiple of block-size %d",
-                           req_len, blk_sz);
-       }
-       if (zft_io_state == zft_writing) {
-               /*  all other error conditions have been checked earlier
-                */
-               TRACE_EXIT 0;
-       }
-       zft_io_state = zft_idle;
-       TRACE_CATCH(zft_check_write_access(pos),);
-       /*  If we haven't read the header segment yet, do it now.
-        *  This will verify the configuration, get the bad sector
-        *  table and read the volume table segment 
-        */
-       if (!zft_header_read) {
-               TRACE_CATCH(zft_read_header_segments(),);
-       }
-       /*  fine. Now the tape is either at BOT or at EOD,
-        *  Write start of volume now
-        */
-       TRACE_CATCH(zft_open_volume(pos, blk_sz, zft_use_compression),);
-       *volume = zft_find_volume(pos->seg_pos);
-       DUMP_VOLINFO(ft_t_noise, "", *volume);
-       zft_just_before_eof = 0;
-       /* now merge with old data if necessary */
-       if (!zft_qic_mode && pos->seg_byte_pos != 0){
-               result = zft_fetch_segment(pos->seg_pos,
-                                          zft_deblock_buf,
-                                          FT_RD_SINGLE);
-               if (result < 0) {
-                       if (result == -EINTR || result == -ENOSPC) {
-                               TRACE_EXIT result;
-                       }
-                       TRACE(ft_t_noise, 
-                             "ftape_read_segment() result: %d. "
-                             "This might be normal when using "
-                             "a newly\nformatted tape", result);
-                       memset(zft_deblock_buf, '\0', pos->seg_byte_pos);
-               }
-       }
-       zft_io_state = zft_writing;
-       TRACE_EXIT 0;
-}
-
-static int fill_deblock_buf(__u8 *dst_buf, const int seg_sz,
-                           zft_position *pos, const zft_volinfo *volume,
-                           const char __user *usr_buf, const int req_len)
-{
-       int cnt = 0;
-       int result = 0;
-       TRACE_FUN(ft_t_flow);
-
-       if (seg_sz == 0) {
-               TRACE_ABORT(0, ft_t_data_flow, "empty segment");
-       }
-       TRACE(ft_t_data_flow, "\n"
-             KERN_INFO "remaining req_len: %d\n"
-             KERN_INFO "          buf_pos: %d", 
-             req_len, pos->seg_byte_pos);
-       /* zft_deblock_buf will not contain a valid segment any longer */
-       zft_deblock_segment = -1;
-       if (zft_use_compression) {
-               TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
-               TRACE_CATCH(result= (*zft_cmpr_ops->write)(&cnt,
-                                                          dst_buf, seg_sz,
-                                                          usr_buf, req_len,
-                                                          pos, volume),);
-       } else {
-               TRACE_CATCH(result= zft_simple_write(&cnt,
-                                                    dst_buf, seg_sz,
-                                                    usr_buf, req_len,
-                                                    pos, volume),);
-       }
-       pos->volume_pos   += result;
-       pos->seg_byte_pos += cnt;
-       pos->tape_pos     += cnt;
-       TRACE(ft_t_data_flow, "\n"
-             KERN_INFO "removed from user-buffer : %d bytes.\n"
-             KERN_INFO "copied to zft_deblock_buf: %d bytes.\n"
-             KERN_INFO "zft_tape_pos             : " LL_X " bytes.",
-             result, cnt, LL(pos->tape_pos));
-       TRACE_EXIT result;
-}
-
-
-/*  called by the kernel-interface routine "zft_write()"
- */
-int _zft_write(const char __user *buff, int req_len)
-{
-       int result = 0;
-       int written = 0;
-       int write_cnt;
-       int seg_sz;
-       static const zft_volinfo *volume = NULL;
-       TRACE_FUN(ft_t_flow);
-       
-       zft_resid         = req_len;    
-       last_write_failed = 1; /* reset to 0 when successful */
-       /* check if write is allowed 
-        */
-       TRACE_CATCH(check_write_access(req_len, &volume,&zft_pos,zft_blk_sz),);
-       while (req_len > 0) {
-               /* Allow us to escape from this loop with a signal !
-                */
-               FT_SIGNAL_EXIT(_DONT_BLOCK);
-               seg_sz = zft_get_seg_sz(zft_pos.seg_pos);
-               if ((write_cnt = fill_deblock_buf(zft_deblock_buf,
-                                                 seg_sz,
-                                                 &zft_pos,
-                                                 volume,
-                                                 buff,
-                                                 req_len)) < 0) {
-                       zft_resid -= written;
-                       if (write_cnt == -ENOSPC) {
-                               /* leave the remainder to flush_buffers()
-                                */
-                               TRACE(ft_t_info, "No space left on device");
-                               last_write_failed = 0;
-                               if (!need_flush) {
-                                       need_flush = written > 0;
-                               }
-                               TRACE_EXIT written > 0 ? written : -ENOSPC;
-                       } else {
-                               TRACE_EXIT result;
-                       }
-               }
-               if (zft_pos.seg_byte_pos == seg_sz) {
-                       TRACE_CATCH(ftape_write_segment(zft_pos.seg_pos, 
-                                                       zft_deblock_buf,
-                                                       FT_WR_ASYNC),
-                                   zft_resid -= written);
-                       zft_written_segments ++;
-                       zft_pos.seg_byte_pos =  0;
-                       zft_deblock_segment  = zft_pos.seg_pos;
-                       ++zft_pos.seg_pos;
-               }
-               written += write_cnt;
-               buff    += write_cnt;
-               req_len -= write_cnt;
-       } /* while (req_len > 0) */
-       TRACE(ft_t_data_flow, "remaining in blocking buffer: %d",
-              zft_pos.seg_byte_pos);
-       TRACE(ft_t_data_flow, "just written bytes: %d", written);
-       last_write_failed = 0;
-       zft_resid -= written;
-       need_flush = need_flush || written > 0;
-       TRACE_EXIT written;               /* bytes written */
-}
diff --git a/drivers/char/ftape/zftape/zftape-write.h b/drivers/char/ftape/zftape/zftape-write.h
deleted file mode 100644 (file)
index ea88701..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _ZFTAPE_WRITE_H
-#define _ZFTAPE_WRITE_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-write.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:13 $
- *
- *      This file contains the definitions for the write functions
- *      for the zftape driver for Linux.
- *
- */
-
-extern int  zft_flush_buffers(void);
-extern int  zft_update_header_segments(void);
-extern void zft_prevent_flush(void);
-
-/*  hook for the VFS interface 
- */
-extern int _zft_write(const char __user *buff, int req_len);
-#endif /* _ZFTAPE_WRITE_H */
diff --git a/drivers/char/ftape/zftape/zftape_syms.c b/drivers/char/ftape/zftape/zftape_syms.c
deleted file mode 100644 (file)
index 2db1401..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *      Copyright (C) 1997 Claus-Justus Heine
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape_syms.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:19:14 $
- *
- *      This file contains the symbols that the zftape frontend to 
- *      the ftape floppy tape driver exports 
- */             
-
-#include <linux/module.h>
-
-#include <linux/zftape.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-buffers.h"
-#include "../zftape/zftape-ctl.h"
-
-/* zftape-init.c */
-EXPORT_SYMBOL(zft_cmpr_register);
-/* zftape-read.c */
-EXPORT_SYMBOL(zft_fetch_segment_fraction);
-/* zftape-buffers.c */
-EXPORT_SYMBOL(zft_vmalloc_once);
-EXPORT_SYMBOL(zft_vmalloc_always);
-EXPORT_SYMBOL(zft_vfree);
index d7e04689304c6f408552959f4a3bc04d5d1e6587..ff433126361fc51cd12e2063814dba2a96365262 100644 (file)
@@ -60,8 +60,6 @@ header-y += fadvise.h
 header-y += fd.h
 header-y += fdreg.h
 header-y += fib_rules.h
-header-y += ftape-header-segment.h
-header-y += ftape-vendors.h
 header-y += fuse.h
 header-y += futex.h
 header-y += genetlink.h
@@ -206,7 +204,6 @@ unifdef-y += fcntl.h
 unifdef-y += filter.h
 unifdef-y += flat.h
 unifdef-y += fs.h
-unifdef-y += ftape.h
 unifdef-y += gameport.h
 unifdef-y += generic_serial.h
 unifdef-y += genhd.h
@@ -341,6 +338,5 @@ unifdef-y += wait.h
 unifdef-y += wanrouter.h
 unifdef-y += watchdog.h
 unifdef-y += xfrm.h
-unifdef-y += zftape.h
 
 objhdr-y += version.h
diff --git a/include/linux/ftape-header-segment.h b/include/linux/ftape-header-segment.h
deleted file mode 100644 (file)
index 4732218..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef _FTAPE_HEADER_SEGMENT_H
-#define _FTAPE_HEADER_SEGMENT_H
-
-/*
- * Copyright (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/include/linux/ftape-header-segment.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:28 $
- *
- *      This file defines some offsets into the header segment of a
- *      floppy tape cartridge.  For use with the QIC-40/80/3010/3020
- *      floppy-tape driver "ftape" for Linux.
- */
-
-#define FT_SIGNATURE   0  /* must be 0xaa55aa55 */
-#define FT_FMT_CODE    4
-#define FT_REV_LEVEL   5  /* only for QIC-80 since. Rev. L (== 0x0c)         */
-#define FT_HSEG_1      6  /* first header segment, except for format code  6 */
-#define FT_HSEG_2      8  /* second header segment, except for format code 6 */
-#define FT_FRST_SEG   10  /* first data segment, except for format code 6    */
-#define FT_LAST_SEG   12  /* last data segment, except for format code 6     */
-#define FT_FMT_DATE   14  /* date and time of most recent format, see below  */
-#define FT_WR_DATE    18  /* date and time of most recent write or format    */
-#define FT_SPT        24  /* segments per track                              */
-#define FT_TPC        26  /* tracks per cartridge                            */
-#define FT_FHM        27  /* floppy drive head (maximum of it)               */
-#define FT_FTM        28  /* floppy track max.                               */
-#define FT_FSM        29  /* floppy sector max. (128)                        */
-#define FT_LABEL      30  /* floppy tape label                               */
-#define FT_LABEL_DATE 74  /* date and time the tape label was written        */
-#define FT_LABEL_SZ   (FT_LABEL_DATE - FT_LABEL)
-#define FT_CMAP_START 78  /* starting segment of compression map             */
-#define FT_FMT_ERROR 128  /* must be set to 0xff if remainder gets lost during
-                          * tape format
-                          */
-#define FT_SEG_CNT   130  /* number of seg. written, formatted or verified
-                          * through lifetime of tape (why not read?)
-                          */
-#define FT_INIT_DATE 138  /* date and time of initial tape format    */
-#define FT_FMT_CNT   142  /* number of times tape has been formatted */
-#define FT_FSL_CNT   144  /* number of segments in failed sector log */
-#define FT_MK_CODE   146  /* id string of tape manufacturer          */
-#define FT_LOT_CODE  190  /* tape manufacturer lot code              */
-#define FT_6_HSEG_1  234  /* first header segment for format code  6 */
-#define FT_6_HSEG_2  238  /* second header segment for format code 6 */
-#define FT_6_FRST_SEG 242 /* first data segment for format code 6    */
-#define FT_6_LAST_SEG 246 /* last data segment for format code 6     */
-
-#define FT_FSL        256
-#define FT_HEADER_END 256 /* space beyond this point:
-                          * format codes 2, 3 and 5: 
-                          * -  failed sector log until byte 2047
-                          * -  bad sector map in the reamining part of segment
-                          * format codes 4 and 6:
-                          * -  bad sector map  starts hear
-                          */
-
-
-/*  value to be stored at the FT_SIGNATURE offset 
- */
-#define FT_HSEG_MAGIC 0xaa55aa55
-#define FT_D2G_MAGIC  0x82288228 /* Ditto 2GB */
-
-/* data and time encoding: */
-#define FT_YEAR_SHIFT 25
-#define FT_YEAR_MASK  0xfe000000
-#define FT_YEAR_0     1970
-#define FT_YEAR_MAX   127
-#define FT_YEAR(year) ((((year)-FT_YEAR_0)<<FT_YEAR_SHIFT)&FT_YEAR_MASK)
-
-#define FT_TIME_SHIFT   0
-#define FT_TIME_MASK    0x01FFFFFF
-#define FT_TIME_MAX     0x01ea6dff /* last second of a year */
-#define FT_TIME(mo,d,h,m,s) \
-       ((((s)+60*((m)+60*((h)+24*((d)+31*(mo))))) & FT_TIME_MASK))
-
-#define FT_TIME_STAMP(y,mo,d,h,m,s) (FT_YEAR(y) | FT_TIME(mo,d,h,m,s))
-
-/* values for the format code field */
-typedef enum {
-       fmt_normal = 2, /*  QIC-80 post Rev. B 205Ft or 307Ft tape    */
-       fmt_1100ft = 3, /*  QIC-80 post Rev. B 1100Ft tape            */
-       fmt_var    = 4, /*  QIC-80 post Rev. B variabel length format */
-       fmt_425ft  = 5, /*  QIC-80 post Rev. B 425Ft tape             */
-       fmt_big    = 6  /*  QIC-3010/3020 variable length tape with more 
-                        *  than 2^16 segments per tape
-                        */
-} ft_format_type;
-
-/* definitions for the failed sector log */
-#define FT_FSL_SIZE        (2 * FT_SECTOR_SIZE - FT_HEADER_END)
-#define FT_FSL_MAX_ENTRIES (FT_FSL_SIZE/sizeof(__u32))
-
-typedef struct ft_fsl_entry {
-       __u16 segment;
-       __u16 date;
-} __attribute__ ((packed)) ft_fsl_entry;
-
-
-/*  date encoding for the failed sector log 
- *  month: 1..12, day: 1..31, year: 1970..2097
- */
-#define FT_FSL_TIME_STAMP(y,m,d) \
-       (((((y) - FT_YEAR_0)<<9)&0xfe00) | (((m)<<5)&0x01e0) | ((d)&0x001f))
-
-#endif /* _FTAPE_HEADER_SEGMENT_H */
diff --git a/include/linux/ftape-vendors.h b/include/linux/ftape-vendors.h
deleted file mode 100644 (file)
index ec1a81f..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-#ifndef _FTAPE_VENDORS_H
-#define _FTAPE_VENDORS_H
-
-/*
- *      Copyright (C) 1993-1996 Bas Laarhoven,
- *                (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/include/linux/ftape-vendors.h,v $
- * $Revision: 1.6 $
- * $Date: 1997/10/09 15:38:11 $
- *
- *      This file contains the supported drive types with their
- *      QIC-117 spec. vendor code and drive dependent configuration
- *      information.
- */
-
-typedef enum {
-       unknown_wake_up = 0,
-       no_wake_up,
-       wake_up_colorado,
-       wake_up_mountain,
-       wake_up_insight,
-} wake_up_types;
-
-typedef struct {
-       wake_up_types wake_up;  /* see wake_up_types */
-       char *name;             /* Text describing the drive */
-} wakeup_method;
-
-/*  Note: order of entries in WAKEUP_METHODS must be so that a variable
- *        of type wake_up_types can be used as an index in the array.
- */
-#define WAKEUP_METHODS { \
-  { unknown_wake_up,    "Unknown" }, \
-  { no_wake_up,         "None" }, \
-  { wake_up_colorado,   "Colorado" }, \
-  { wake_up_mountain,   "Mountain" }, \
-  { wake_up_insight,    "Motor-on" }, \
-}
-
-typedef struct {
-       unsigned int vendor_id; /* vendor id from drive */
-       int speed;              /* maximum tape transport speed (ips) */
-       wake_up_types wake_up;  /* see wake_up_types */
-       char *name;             /* Text describing the drive */
-} vendor_struct;
-
-#define UNKNOWN_VENDOR (-1)
-
-#define QIC117_VENDORS {                                                   \
-/* see _vendor_struct */                                                   \
-  { 0x00000,  82, wake_up_colorado,  "Colorado DJ-10 (old)" },             \
-  { 0x00047,  90, wake_up_colorado,  "Colorado DJ-10/DJ-20" },             \
-  { 0x011c2,  84, wake_up_colorado,  "Colorado 700" },                     \
-  { 0x011c3,  90, wake_up_colorado,  "Colorado 1400" },                            \
-  { 0x011c4,  84, wake_up_colorado,  "Colorado DJ-10/DJ-20 (new)" },       \
-  { 0x011c5,  84, wake_up_colorado,  "HP Colorado T1000" },                \
-  { 0x011c6,  90, wake_up_colorado,  "HP Colorado T3000" },                \
-  { 0x00005,  45, wake_up_mountain,  "Archive 5580i" },                            \
-  { 0x10005,  50, wake_up_insight,   "Insight 80Mb, Irwin 80SX" },         \
-  { 0x00140,  74, wake_up_mountain,  "Archive S.Hornet [Identity/Escom]" }, \
-  { 0x00146,  72, wake_up_mountain,  "Archive 31250Q [Escom]" },           \
-  { 0x0014a, 100, wake_up_mountain,  "Archive XL9250i [Conner/Escom]" },    \
-  { 0x0014c,  98, wake_up_mountain,  "Conner C250MQT" },                   \
-  { 0x0014e,  80, wake_up_mountain,  "Conner C250MQ" },                            \
-  { 0x00150,  80, wake_up_mountain,  "Conner TSM420R/TST800R" },           \
-  { 0x00152,  80, wake_up_mountain,  "Conner TSM850R" },                   \
-  { 0x00156,  80, wake_up_mountain,  "Conner TSM850R/1700R/TST3200R" },            \
-  { 0x00180,   0, wake_up_mountain,  "Summit SE 150" },                            \
-  { 0x00181,  85, wake_up_mountain,  "Summit SE 250, Mountain FS8000" },    \
-  { 0x001c1,  82, no_wake_up,        "Wangtek 3040F" },                            \
-  { 0x001c8,  64, no_wake_up,        "Wangtek 3080F" },                            \
-  { 0x001c8,  64, wake_up_colorado,  "Wangtek 3080F" },                            \
-  { 0x001ca,  67, no_wake_up,        "Wangtek 3080F (new)" },              \
-  { 0x001cc,  77, wake_up_colorado,  "Wangtek 3200 / Teac 700" },          \
-  { 0x001cd,  75, wake_up_colorado,  "Reveal TB1400" },                            \
-  { 0x00380,  85, wake_up_colorado,  "Exabyte Eagle-96" },                 \
-  { 0x00381,  85, wake_up_colorado,  "Exabyte Eagle TR-3" },               \
-  { 0x00382,  85, wake_up_colorado,  "Exabyte Eagle TR-3" },               \
-  { 0x003ce,  77, wake_up_colorado,  "Teac 800" },                         \
-  { 0x003cf,   0, wake_up_colorado,  "Teac FT3010TR" },                            \
-  { 0x08880,  64, no_wake_up,        "Iomega 250, Ditto 800" },                    \
-  { 0x08880,  64, wake_up_colorado,  "Iomega 250, Ditto 800" },                    \
-  { 0x08880,  64, wake_up_insight,   "Iomega 250, Ditto 800" },                    \
-  { 0x08881,  80, wake_up_colorado,  "Iomega 700" },                       \
-  { 0x08882,  80, wake_up_colorado,  "Iomega 3200" },                      \
-  { 0x08883,  80, wake_up_colorado,  "Iomega DITTO 2GB" },                 \
-  { 0x00021,  70, no_wake_up,        "AIWA CT-803" },                      \
-  { 0x004c0,  80, no_wake_up,        "AIWA TD-S1600" },                            \
-  { 0x00021,   0, wake_up_mountain,  "COREtape QIC80" },                   \
-  { 0x00441,   0, wake_up_mountain,  "ComByte DoublePlay" },               \
-  { 0x00481, 127, wake_up_mountain,  "PERTEC MyTape 800" },                \
-  { 0x00483, 130, wake_up_mountain,  "PERTEC MyTape 3200" },               \
-  { UNKNOWN_VENDOR, 0, no_wake_up, "unknown" }                             \
-}
-
-#define QIC117_MAKE_CODES {                    \
-  { 0, "Unassigned" },                         \
-  { 1, "Alloy Computer Products" },            \
-  { 2, "3M" },                                 \
-  { 3, "Tandberg Data" },                      \
-  { 4, "Colorado" },                           \
-  { 5, "Archive/Conner" },                     \
-  { 6, "Mountain/Summit Memory Systems" },     \
-  { 7, "Wangtek/Rexon/Tecmar" },               \
-  { 8, "Sony" },                               \
-  { 9, "Cipher Data Products" },               \
-  { 10, "Irwin Magnetic Systems" },            \
-  { 11, "Braemar" },                           \
-  { 12, "Verbatim" },                          \
-  { 13, "Core International" },                        \
-  { 14, "Exabyte" },                           \
-  { 15, "Teac" },                              \
-  { 16, "Gigatek" },                           \
-  { 17, "ComByte" },                           \
-  { 18, "PERTEC Memories" },                   \
-  { 19, "Aiwa" },                              \
-  { 71, "Colorado" },                          \
-  { 546, "Iomega Inc" },                       \
-}
-
-#endif /* _FTAPE_VENDORS_H */
diff --git a/include/linux/ftape.h b/include/linux/ftape.h
deleted file mode 100644 (file)
index 7e7038c..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef _FTAPE_H
-#define _FTAPE_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- *           (C) 1996-1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/include/linux/ftape.h,v $
- * $Revision: 1.17.6.4 $
- * $Date: 1997/11/25 01:52:54 $
- *
- *      This file contains global definitions, typedefs and macro's
- *      for the QIC-40/80/3010/3020 floppy-tape driver for Linux.
- */
-
-#define FTAPE_VERSION "ftape v3.04d 25/11/97"
-
-#ifdef __KERNEL__
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#endif
-#include <linux/types.h>
-#include <linux/mtio.h>
-
-#define FT_SECTOR(x)           (x+1)   /* sector offset into real sector */
-#define FT_SECTOR_SIZE         1024
-#define FT_SECTORS_PER_SEGMENT   32
-#define FT_ECC_SECTORS            3
-#define FT_SEGMENT_SIZE                ((FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS) * FT_SECTOR_SIZE)
-#define FT_BUFF_SIZE    (FT_SECTORS_PER_SEGMENT * FT_SECTOR_SIZE)
-
-/*
- *   bits of the minor device number that define drive selection
- *   methods. Could be used one day to access multiple tape
- *   drives on the same controller.
- */
-#define FTAPE_SEL_A     0
-#define FTAPE_SEL_B     1
-#define FTAPE_SEL_C     2
-#define FTAPE_SEL_D     3
-#define FTAPE_SEL_MASK     3
-#define FTAPE_SEL(unit) ((unit) & FTAPE_SEL_MASK)
-#define FTAPE_NO_REWIND 4      /* mask for minor nr */
-
-/* the following two may be reported when MTIOCGET is requested ... */
-typedef union {
-       struct {
-               __u8 error;
-               __u8 command;
-       } error;
-       long space;
-} ft_drive_error;
-typedef union {
-       struct {
-               __u8 drive_status;
-               __u8 drive_config;
-               __u8 tape_status;
-       } status;
-       long space;
-} ft_drive_status;
-
-#ifdef __KERNEL__
-
-#define FT_RQM_DELAY    12
-#define FT_MILLISECOND  1
-#define FT_SECOND       1000
-#define FT_FOREVER      -1
-#ifndef HZ
-#error "HZ undefined."
-#endif
-#define FT_USPT         (1000000/HZ) /* microseconds per tick */
-
-/* This defines the number of retries that the driver will allow
- * before giving up (and letting a higher level handle the error).
- */
-#ifdef TESTING
-#define FT_SOFT_RETRIES 1         /* number of low level retries */
-#define FT_RETRIES_ON_ECC_ERROR 3  /* ecc error when correcting segment */
-#else
-#define FT_SOFT_RETRIES 6         /* number of low level retries (triple) */
-#define FT_RETRIES_ON_ECC_ERROR 3  /* ecc error when correcting segment */
-#endif
-
-#ifndef THE_FTAPE_MAINTAINER
-#define THE_FTAPE_MAINTAINER "the ftape maintainer"
-#endif
-
-/* Initialize missing configuration parameters.
- */
-#ifndef CONFIG_FT_NR_BUFFERS
-# define CONFIG_FT_NR_BUFFERS 3
-#endif
-#ifndef CONFIG_FT_FDC_THR
-# define CONFIG_FT_FDC_THR 8
-#endif
-#ifndef CONFIG_FT_FDC_MAX_RATE
-# define CONFIG_FT_FDC_MAX_RATE 2000
-#endif
-#ifndef CONFIG_FT_FDC_BASE
-# define CONFIG_FT_FDC_BASE 0
-#endif
-#ifndef CONFIG_FT_FDC_IRQ
-# define CONFIG_FT_FDC_IRQ  0
-#endif
-#ifndef CONFIG_FT_FDC_DMA
-# define CONFIG_FT_FDC_DMA  0
-#endif
-
-/* Turn some booleans into numbers.
- */
-#ifdef CONFIG_FT_PROBE_FC10
-# undef CONFIG_FT_PROBE_FC10
-# define CONFIG_FT_PROBE_FC10 1
-#else
-# define CONFIG_FT_PROBE_FC10 0
-#endif
-#ifdef CONFIG_FT_MACH2
-# undef CONFIG_FT_MACH2
-# define CONFIG_FT_MACH2 1
-#else
-# define CONFIG_FT_MACH2 0
-#endif
-
-/* Insert default settings
- */
-#if CONFIG_FT_PROBE_FC10 == 1
-# if CONFIG_FT_FDC_BASE == 0
-#  undef  CONFIG_FT_FDC_BASE
-#  define CONFIG_FT_FDC_BASE 0x180
-# endif
-# if CONFIG_FT_FDC_IRQ == 0
-#  undef  CONFIG_FT_FDC_IRQ
-#  define CONFIG_FT_FDC_IRQ 9
-# endif
-# if CONFIG_FT_FDC_DMA == 0
-#  undef  CONFIG_FT_FDC_DMA
-#  define CONFIG_FT_FDC_DMA 3
-# endif
-#elif CONFIG_FT_MACH2 == 1    /* CONFIG_FT_PROBE_FC10 == 1 */
-# if CONFIG_FT_FDC_BASE == 0
-#  undef  CONFIG_FT_FDC_BASE
-#  define CONFIG_FT_FDC_BASE 0x1E0
-# endif
-# if CONFIG_FT_FDC_IRQ == 0
-#  undef  CONFIG_FT_FDC_IRQ
-#  define CONFIG_FT_FDC_IRQ 6
-# endif
-# if CONFIG_FT_FDC_DMA == 0
-#  undef  CONFIG_FT_FDC_DMA
-#  define CONFIG_FT_FDC_DMA 2
-# endif
-#elif defined(CONFIG_FT_ALT_FDC)  /* CONFIG_FT_MACH2 */
-# if CONFIG_FT_FDC_BASE == 0
-#  undef  CONFIG_FT_FDC_BASE
-#  define CONFIG_FT_FDC_BASE 0x370
-# endif
-# if CONFIG_FT_FDC_IRQ == 0
-#  undef  CONFIG_FT_FDC_IRQ
-#  define CONFIG_FT_FDC_IRQ 6
-# endif
-# if CONFIG_FT_FDC_DMA == 0
-#  undef  CONFIG_FT_FDC_DMA
-#  define CONFIG_FT_FDC_DMA 2
-# endif
-#else                          /* CONFIG_FT_ALT_FDC */
-# if CONFIG_FT_FDC_BASE == 0
-#  undef  CONFIG_FT_FDC_BASE
-#  define CONFIG_FT_FDC_BASE 0x3f0
-# endif
-# if CONFIG_FT_FDC_IRQ == 0
-#  undef  CONFIG_FT_FDC_IRQ
-#  define CONFIG_FT_FDC_IRQ 6
-# endif
-# if CONFIG_FT_FDC_DMA == 0
-#  undef  CONFIG_FT_FDC_DMA
-#  define CONFIG_FT_FDC_DMA 2
-# endif
-#endif                         /* standard FDC */
-
-/*      some useful macro's
- */
-#define NR_ITEMS(x)     (int)(sizeof(x)/ sizeof(*x))
-
-#endif  /* __KERNEL__ */
-
-#endif
diff --git a/include/linux/zftape.h b/include/linux/zftape.h
deleted file mode 100644 (file)
index b057c65..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef _ZFTAPE_H
-#define _ZFTAPE_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program 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, 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; see the file COPYING.  If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/include/linux/zftape.h,v $
- * $Revision: 1.12 $
- * $Date: 1997/10/21 11:02:37 $
- *
- *      Special ioctl and other global info for the zftape VFS
- *      interface for the QIC-40/80/3010/3020 floppy-tape driver for
- *      Linux.
- */
-
-#define ZFTAPE_VERSION  "zftape for " FTAPE_VERSION
-
-#include <linux/ftape.h>
-
-#define ZFTAPE_LABEL       "Ftape - The Linux Floppy Tape Project!"
-
-/* Bits of the minor device number that control the operation mode */
-#define ZFT_Q80_MODE           (1 << 3)
-#define ZFT_ZIP_MODE           (1 << 4)
-#define ZFT_RAW_MODE           (1 << 5)
-#define ZFT_MINOR_OP_MASK      (ZFT_Q80_MODE   |       \
-                                ZFT_ZIP_MODE   |       \
-                                ZFT_RAW_MODE)
-#define ZFT_MINOR_MASK         (FTAPE_SEL_MASK         |       \
-                                ZFT_MINOR_OP_MASK      |       \
-                                FTAPE_NO_REWIND)
-
-#ifdef ZFT_OBSOLETE
-struct mtblksz {
-       unsigned int mt_blksz;
-};
-#define MTIOC_ZFTAPE_GETBLKSZ _IOR('m', 104, struct mtblksz)
-#endif
-
-#ifdef __KERNEL__
-
-extern int zft_init(void);
-
-static inline __s64 zft_div_blksz(__s64 value, __u32 blk_sz)
-{
-       if (blk_sz == 1) {
-               return value;
-       } else {
-               return (__s64)(((__u32)(value >> 10) + (blk_sz >> 10) - 1) 
-                              / (blk_sz >> 10));
-       } 
-}
-
-static inline __s64 zft_mul_blksz(__s64 value, __u32 blk_sz)
-{
-       if (blk_sz == 1) {
-               return value;
-       } else {
-               /*  if blk_sz != 1, then it is a multiple of 1024. In
-                *  this case, `value' will also fit into 32 bits.
-                * 
-                *  Actually, this limits the capacity to 42
-                *  bits. This is (2^32)*1024, roughly a thousand
-                *  times 2GB, or 3 Terabytes. Hopefully this is enough
-                */
-               return(__s64)(((__u32)(value)*(blk_sz>>10))<<10);
-       }
-}
-
-#endif
-
-#endif