Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Remove long-unmaintained ftape driver subsystem.

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>

-20278
-2
Documentation/00-INDEX
··· 104 104 - request_firmware() hotplug interface info. 105 105 floppy.txt 106 106 - notes and driver options for the floppy disk driver. 107 - ftape.txt 108 - - notes about the floppy tape device driver. 109 107 hayes-esp.txt 110 108 - info on using the Hayes ESP serial driver. 111 109 highuid.txt
-8
Documentation/feature-removal-schedule.txt
··· 234 234 235 235 --------------------------- 236 236 237 - What: ftape 238 - When: 2.6.20 239 - Why: Orphaned for ages. SMP bugs long unfixed. Few users left 240 - in the world. 241 - Who: Jeff Garzik <jeff@garzik.org> 242 - 243 - --------------------------- 244 - 245 237 What: IPv4 only connection tracking/NAT/helpers 246 238 When: 2.6.22 247 239 Why: The new layer 3 independant connection tracking replaces the old
-307
Documentation/ftape.txt
··· 1 - Intro 2 - ===== 3 - 4 - This file describes some issues involved when using the "ftape" 5 - floppy tape device driver that comes with the Linux kernel. 6 - 7 - ftape has a home page at 8 - 9 - http://ftape.dot-heine.de/ 10 - 11 - which contains further information about ftape. Please cross check 12 - this WWW address against the address given (if any) in the MAINTAINERS 13 - file located in the top level directory of the Linux kernel source 14 - tree. 15 - 16 - NOTE: This is an unmaintained set of drivers, and it is not guaranteed to work. 17 - If you are interested in taking over maintenance, contact Claus-Justus Heine 18 - <ch@dot-heine.de>, the former maintainer. 19 - 20 - Contents 21 - ======== 22 - 23 - A minus 1: Ftape documentation 24 - 25 - A. Changes 26 - 1. Goal 27 - 2. I/O Block Size 28 - 3. Write Access when not at EOD (End Of Data) or BOT (Begin Of Tape) 29 - 4. Formatting 30 - 5. Interchanging cartridges with other operating systems 31 - 32 - B. Debugging Output 33 - 1. Introduction 34 - 2. Tuning the debugging output 35 - 36 - C. Boot and load time configuration 37 - 1. Setting boot time parameters 38 - 2. Module load time parameters 39 - 3. Ftape boot- and load time options 40 - 4. Example kernel parameter setting 41 - 5. Example module parameter setting 42 - 43 - D. Support and contacts 44 - 45 - ******************************************************************************* 46 - 47 - A minus 1. Ftape documentation 48 - ============================== 49 - 50 - Unluckily, the ftape-HOWTO is out of date. This really needs to be 51 - changed. Up to date documentation as well as recent development 52 - versions of ftape and useful links to related topics can be found at 53 - the ftape home page at 54 - 55 - http://ftape.dot-heine.de/ 56 - 57 - ******************************************************************************* 58 - 59 - A. Changes 60 - ========== 61 - 62 - 1. Goal 63 - ~~~~ 64 - The goal of all that incompatibilities was to give ftape an interface 65 - that resembles the interface provided by SCSI tape drives as close 66 - as possible. Thus any Unix backup program that is known to work 67 - with SCSI tape drives should also work. 68 - 69 - The concept of a fixed block size for read/write transfers is 70 - rather unrelated to this SCSI tape compatibility at the file system 71 - interface level. It developed out of a feature of zftape, a 72 - block wise user transparent on-the-fly compression. That compression 73 - support will not be dropped in future releases for compatibility 74 - reasons with previous releases of zftape. 75 - 76 - 2. I/O Block Size 77 - ~~~~~~~~~~~~~~ 78 - The block size defaults to 10k which is the default block size of 79 - GNU tar. 80 - 81 - The block size can be tuned either during kernel configuration or 82 - at runtime with the MTIOCTOP ioctl using the MTSETBLK operation 83 - (i.e. do "mt -f /dev/qft0" setblk #BLKSZ). A block size of 0 84 - switches to variable block size mode i.e. "mt setblk 0" switches 85 - off the block size restriction. However, this disables zftape's 86 - built in on-the-fly compression which doesn't work with variable 87 - block size mode. 88 - 89 - The BLKSZ parameter must be given as a byte count and must be a 90 - multiple of 32k or 0, i.e. use "mt setblk 32768" to switch to a 91 - block size of 32k. 92 - 93 - The typical symptom of a block size mismatch is an "invalid 94 - argument" error message. 95 - 96 - 3. Write Access when not at EOD (End Of Data) or BOT (Begin Of Tape) 97 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 98 - zftape (the file system interface of ftape-3.x) denies write access 99 - to the tape cartridge when it isn't positioned either at BOT or 100 - EOD. 101 - 102 - 4. Formatting 103 - ~~~~~~~~~~ 104 - ftape DOES support formatting of floppy tape cartridges. You need the 105 - `ftformat' program that is shipped with the modules version of ftape. 106 - Please get the latest version of ftape from 107 - 108 - ftp://sunsite.unc.edu/pub/Linux/kernel/tapes 109 - 110 - or from the ftape home page at 111 - 112 - http://ftape.dot-heine.de/ 113 - 114 - `ftformat' is contained in the `./contrib/' subdirectory of that 115 - separate ftape package. 116 - 117 - 5. Interchanging cartridges with other operating systems 118 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 119 - 120 - The internal emulation of Unix tape device file marks has changed 121 - completely. ftape now uses the volume table segment as specified 122 - by the QIC-40/80/3010/3020/113 standards to emulate file marks. As 123 - a consequence there is limited support to interchange cartridges 124 - with other operating systems. 125 - 126 - To be more precise: ftape will detect volumes written by other OS's 127 - programs and other OS's programs will detect volumes written by 128 - ftape. 129 - 130 - However, it isn't possible to extract the data dumped to the tape 131 - by some MSDOS program with ftape. This exceeds the scope of a 132 - kernel device driver. If you need such functionality, then go ahead 133 - and write a user space utility that is able to do that. ftape already 134 - provides all kernel level support necessary to do that. 135 - 136 - ******************************************************************************* 137 - 138 - B. Debugging Output 139 - ================ 140 - 141 - 1. Introduction 142 - ~~~~~~~~~~~~ 143 - The ftape driver can be very noisy in that is can print lots of 144 - debugging messages to the kernel log files and the system console. 145 - While this is useful for debugging it might be annoying during 146 - normal use and enlarges the size of the driver by several kilobytes. 147 - 148 - To reduce the size of the driver you can trim the maximal amount of 149 - debugging information available during kernel configuration. Please 150 - refer to the kernel configuration script and its on-line help 151 - functionality. 152 - 153 - The amount of debugging output maps to the "tracing" boot time 154 - option and the "ft_tracing" modules option as follows: 155 - 156 - 0 bugs 157 - 1 + errors (with call-stack dump) 158 - 2 + warnings 159 - 3 + information 160 - 4 + more information 161 - 5 + program flow 162 - 6 + fdc/dma info 163 - 7 + data flow 164 - 8 + everything else 165 - 166 - 2. Tuning the debugging output 167 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 168 - To reduce the amount of debugging output printed to the system 169 - console you can 170 - 171 - i) trim the debugging output at run-time with 172 - 173 - mt -f /dev/nqft0 setdensity #DBGLVL 174 - 175 - where "#DBGLVL" is a number between 0 and 9 176 - 177 - ii) trim the debugging output at module load time with 178 - 179 - modprobe ftape ft_tracing=#DBGLVL 180 - 181 - Of course, this applies only if you have configured ftape to be 182 - compiled as a module. 183 - 184 - iii) trim the debugging output during system boot time. Add the 185 - following to the kernel command line: 186 - 187 - ftape=#DBGLVL,tracing 188 - 189 - Please refer also to the next section if you don't know how to 190 - set boot time parameters. 191 - 192 - ******************************************************************************* 193 - 194 - C. Boot and load time configuration 195 - ================================ 196 - 197 - 1. Setting boot time parameters 198 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199 - Assuming that you use lilo, the LI)nux LO)ader, boot time kernel 200 - parameters can be set by adding a line 201 - 202 - append some_kernel_boot_time_parameter 203 - 204 - to `/etc/lilo.conf' or at real boot time by typing in the options 205 - at the prompt provided by LILO. I can't give you advice on how to 206 - specify those parameters with other loaders as I don't use them. 207 - 208 - For ftape, each "some_kernel_boot_time_parameter" looks like 209 - "ftape=value,option". As an example, the debugging output can be 210 - increased with 211 - 212 - ftape=4,tracing 213 - 214 - NOTE: the value precedes the option name. 215 - 216 - 2. Module load time parameters 217 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 218 - Module parameters can be specified either directly when invoking 219 - the program 'modprobe' at the shell prompt: 220 - 221 - modprobe ftape ft_tracing=4 222 - 223 - or by editing the file `/etc/modprobe.conf' in which case they take 224 - effect each time when the module is loaded with `modprobe' (please 225 - refer to the respective manual pages). Thus, you should add a line 226 - 227 - options ftape ft_tracing=4 228 - 229 - to `/etc/modprobe.conf` if you intend to increase the debugging 230 - output of the driver. 231 - 232 - 233 - 3. Ftape boot- and load time options 234 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 235 - 236 - i. Controlling the amount of debugging output 237 - DBGLVL has to be replaced by a number between 0 and 8. 238 - 239 - module | kernel command line 240 - -----------------------|---------------------- 241 - ft_tracing=DBGLVL | ftape=DBGLVL,tracing 242 - 243 - ii. Hardware setup 244 - BASE is the base address of your floppy disk controller, 245 - IRQ and DMA give its interrupt and DMA channel, respectively. 246 - BOOL is an integer, "0" means "no"; any other value means 247 - "yes". You don't need to specify anything if connecting your tape 248 - drive to the standard floppy disk controller. All of these 249 - values have reasonable defaults. The defaults can be modified 250 - during kernel configuration, i.e. while running "make config", 251 - "make menuconfig" or "make xconfig" in the top level directory 252 - of the Linux kernel source tree. Please refer also to the on 253 - line documentation provided during that kernel configuration 254 - process. 255 - 256 - ft_probe_fc10 is set to a non-zero value if you wish for ftape to 257 - probe for a Colorado FC-10 or FC-20 controller. 258 - 259 - ft_mach2 is set to a non-zero value if you wish for ftape to probe 260 - for a Mountain MACH-2 controller. 261 - 262 - module | kernel command line 263 - -----------------------|---------------------- 264 - ft_fdc_base=BASE | ftape=BASE,ioport 265 - ft_fdc_irq=IRQ | ftape=IRQ,irq 266 - ft_fdc_dma=DMA | ftape=DMA,dma 267 - ft_probe_fc10=BOOL | ftape=BOOL,fc10 268 - ft_mach2=BOOL | ftape=BOOL,mach2 269 - ft_fdc_threshold=THR | ftape=THR,threshold 270 - ft_fdc_rate_limit=RATE | ftape=RATE,datarate 271 - 272 - 4. Example kernel parameter setting 273 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 274 - To configure ftape to probe for a Colorado FC-10/FC-20 controller 275 - and to increase the amount of debugging output a little bit, add 276 - the following line to `/etc/lilo.conf': 277 - 278 - append ftape=1,fc10 ftape=4,tracing 279 - 280 - 5. Example module parameter setting 281 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 282 - To do the same, but with ftape compiled as a loadable kernel 283 - module, add the following line to `/etc/modprobe.conf': 284 - 285 - options ftape ft_probe_fc10=1 ft_tracing=4 286 - 287 - ******************************************************************************* 288 - 289 - D. Support and contacts 290 - ==================== 291 - 292 - Ftape is distributed under the GNU General Public License. There is 293 - absolutely no warranty for this software. However, you can reach 294 - the current maintainer of the ftape package under the email address 295 - given in the MAINTAINERS file which is located in the top level 296 - directory of the Linux kernel source tree. There you'll find also 297 - the relevant mailing list to use as a discussion forum and the web 298 - page to query for the most recent documentation, related work and 299 - development versions of ftape. 300 - 301 - Changelog: 302 - ========== 303 - 304 - ~1996: Original Document 305 - 306 - 10-24-2004: General cleanup and updating, noting additional module options. 307 - James Nelson <james4765@gmail.com>
-3
Documentation/kernel-parameters.txt
··· 557 557 floppy= [HW] 558 558 See Documentation/floppy.txt. 559 559 560 - ftape= [HW] Floppy Tape subsystem debugging options. 561 - See Documentation/ftape.txt. 562 - 563 560 gamecon.map[2|3]= 564 561 [HW,JOY] Multisystem joystick and NES/SNES/PSX pad 565 562 support via parallel port (up to 5 devices per port)
-5
MAINTAINERS
··· 1166 1166 M: dhowells@redhat.com 1167 1167 S: Maintained 1168 1168 1169 - FTAPE/QIC-117 1170 - L: linux-tape@vger.kernel.org 1171 - W: http://sourceforge.net/projects/ftape 1172 - S: Orphan 1173 - 1174 1169 FUSE: FILESYSTEM IN USERSPACE 1175 1170 P: Miklos Szeredi 1176 1171 M: miklos@szeredi.hu
-33
drivers/char/Kconfig
··· 855 855 depends TANBAC_TB022X 856 856 select GPIO_VR41XX 857 857 858 - menu "Ftape, the floppy tape device driver" 859 - 860 - config FTAPE 861 - tristate "Ftape (QIC-80/Travan) support" 862 - depends on BROKEN_ON_SMP && (ALPHA || X86) 863 - ---help--- 864 - If you have a tape drive that is connected to your floppy 865 - controller, say Y here. 866 - 867 - Some tape drives (like the Seagate "Tape Store 3200" or the Iomega 868 - "Ditto 3200" or the Exabyte "Eagle TR-3") come with a "high speed" 869 - controller of their own. These drives (and their companion 870 - controllers) are also supported if you say Y here. 871 - 872 - If you have a special controller (such as the CMS FC-10, FC-20, 873 - Mountain Mach-II, or any controller that is based on the Intel 82078 874 - FDC like the high speed controllers by Seagate and Exabyte and 875 - Iomega's "Ditto Dash") you must configure it by selecting the 876 - appropriate entries from the "Floppy tape controllers" sub-menu 877 - below and possibly modify the default values for the IRQ and DMA 878 - channel and the IO base in ftape's configuration menu. 879 - 880 - If you want to use your floppy tape drive on a PCI-bus based system, 881 - please read the file <file:drivers/char/ftape/README.PCI>. 882 - 883 - The ftape kernel driver is also available as a runtime loadable 884 - module. To compile this driver as a module, choose M here: the 885 - module will be called ftape. 886 - 887 - source "drivers/char/ftape/Kconfig" 888 - 889 - endmenu 890 - 891 858 source "drivers/char/agp/Kconfig" 892 859 893 860 source "drivers/char/drm/Kconfig"
-1
drivers/char/Makefile
··· 78 78 obj-$(CONFIG_I8K) += i8k.o 79 79 obj-$(CONFIG_DS1620) += ds1620.o 80 80 obj-$(CONFIG_HW_RANDOM) += hw_random/ 81 - obj-$(CONFIG_FTAPE) += ftape/ 82 81 obj-$(CONFIG_COBALT_LCD) += lcd.o 83 82 obj-$(CONFIG_PPDEV) += ppdev.o 84 83 obj-$(CONFIG_NWBUTTON) += nwbutton.o
-330
drivers/char/ftape/Kconfig
··· 1 - # 2 - # Ftape configuration 3 - # 4 - config ZFTAPE 5 - tristate "Zftape, the VFS interface" 6 - depends on FTAPE 7 - ---help--- 8 - Normally, you want to say Y or M. DON'T say N here or you 9 - WON'T BE ABLE TO USE YOUR FLOPPY TAPE DRIVE. 10 - 11 - The ftape module itself no longer contains the routines necessary 12 - to interface with the kernel VFS layer (i.e. to actually write data 13 - to and read data from the tape drive). Instead the file system 14 - interface (i.e. the hardware independent part of the driver) has 15 - been moved to a separate module. 16 - 17 - To compile this driver as a module, choose M here: the 18 - module will be called zftape. 19 - 20 - Regardless of whether you say Y or M here, an additional runtime 21 - loadable module called `zft-compressor' which contains code to 22 - support user transparent on-the-fly compression based on Ross 23 - William's lzrw3 algorithm will be produced. If you have enabled the 24 - kernel module loader (i.e. have said Y to "Kernel module loader 25 - support", above) then `zft-compressor' will be loaded 26 - automatically by zftape when needed. 27 - 28 - Despite its name, zftape does NOT use compression by default. 29 - 30 - config ZFT_DFLT_BLK_SZ 31 - int "Default block size" 32 - depends on ZFTAPE 33 - default "10240" 34 - ---help--- 35 - If unsure leave this at its default value, i.e. 10240. Note that 36 - you specify only the default block size here. The block size can be 37 - changed at run time using the MTSETBLK tape operation with the 38 - MTIOCTOP ioctl (i.e. with "mt -f /dev/qft0 setblk #BLKSZ" from the 39 - shell command line). 40 - 41 - The probably most striking difference between zftape and previous 42 - versions of ftape is the fact that all data must be written or read 43 - in multiples of a fixed block size. The block size defaults to 44 - 10240 which is what GNU tar uses. The values for the block size 45 - should be either 1 or multiples of 1024 up to a maximum value of 46 - 63488 (i.e. 62 K). If you specify `1' then zftape's builtin 47 - compression will be disabled. 48 - 49 - Reasonable values are `10240' (GNU tar's default block size), 50 - `5120' (afio's default block size), `32768' (default block size some 51 - backup programs assume for SCSI tape drives) or `1' (no restriction 52 - on block size, but disables builtin compression). 53 - 54 - comment "The compressor will be built as a module only!" 55 - depends on FTAPE && ZFTAPE 56 - 57 - config ZFT_COMPRESSOR 58 - tristate 59 - depends on FTAPE!=n && ZFTAPE!=n 60 - default m 61 - 62 - config FT_NR_BUFFERS 63 - int "Number of ftape buffers (EXPERIMENTAL)" 64 - depends on FTAPE && EXPERIMENTAL 65 - default "3" 66 - help 67 - Please leave this at `3' unless you REALLY know what you are doing. 68 - It is not necessary to change this value. Values below 3 make the 69 - proper use of ftape impossible, values greater than 3 are a waste of 70 - memory. You can change the amount of DMA memory used by ftape at 71 - runtime with "mt -f /dev/qft0 setdrvbuffer #NUMBUFFERS". Each buffer 72 - wastes 32 KB of memory. Please note that this memory cannot be 73 - swapped out. 74 - 75 - config FT_PROC_FS 76 - bool "Enable procfs status report (+2kb)" 77 - depends on FTAPE && PROC_FS 78 - ---help--- 79 - Optional. Saying Y will result in creation of a directory 80 - `/proc/ftape' under the /proc file system. The files can be viewed 81 - with your favorite pager (i.e. use "more /proc/ftape/history" or 82 - "less /proc/ftape/history" or simply "cat /proc/ftape/history"). The 83 - file will contain some status information about the inserted 84 - cartridge, the kernel driver, your tape drive, the floppy disk 85 - controller and the error history for the most recent use of the 86 - kernel driver. Saying Y will enlarge the size of the ftape driver 87 - by approximately 2 KB. 88 - 89 - WARNING: When compiling ftape as a module (i.e. saying M to "Floppy 90 - tape drive") it is dangerous to use ftape's /proc file system 91 - interface. Accessing `/proc/ftape' while the module is unloaded will 92 - result in a kernel Oops. This cannot be fixed from inside ftape. 93 - 94 - choice 95 - prompt "Debugging output" 96 - depends on FTAPE 97 - default FT_NORMAL_DEBUG 98 - 99 - config FT_NORMAL_DEBUG 100 - bool "Normal" 101 - ---help--- 102 - This option controls the amount of debugging output the ftape driver 103 - is ABLE to produce; it does not increase or diminish the debugging 104 - level itself. If unsure, leave this at its default setting, 105 - i.e. choose "Normal". 106 - 107 - Ftape can print lots of debugging messages to the system console 108 - resp. kernel log files. Reducing the amount of possible debugging 109 - output reduces the size of the kernel module by some KB, so it might 110 - be a good idea to use "None" for emergency boot floppies. 111 - 112 - If you want to save memory then the following strategy is 113 - recommended: leave this option at its default setting "Normal" until 114 - you know that the driver works as expected, afterwards reconfigure 115 - the kernel, this time specifying "Reduced" or "None" and recompile 116 - and install the kernel as usual. Note that choosing "Excessive" 117 - debugging output does not increase the amount of debugging output 118 - printed to the console but only makes it possible to produce 119 - "Excessive" debugging output. 120 - 121 - Please read <file:Documentation/ftape.txt> for a short description 122 - how to control the amount of debugging output. 123 - 124 - config FT_FULL_DEBUG 125 - bool "Excessive" 126 - help 127 - Extremely verbose output for driver debugging purposes. 128 - 129 - config FT_NO_TRACE 130 - bool "Reduced" 131 - help 132 - Reduced tape driver debugging output. 133 - 134 - config FT_NO_TRACE_AT_ALL 135 - bool "None" 136 - help 137 - Suppress all debugging output from the tape drive. 138 - 139 - endchoice 140 - 141 - comment "Hardware configuration" 142 - depends on FTAPE 143 - 144 - choice 145 - prompt "Floppy tape controllers" 146 - depends on FTAPE 147 - default FT_STD_FDC 148 - 149 - config FT_STD_FDC 150 - bool "Standard" 151 - ---help--- 152 - Only change this setting if you have a special controller. If you 153 - didn't plug any add-on card into your computer system but just 154 - plugged the floppy tape cable into the already existing floppy drive 155 - controller then you don't want to change the default setting, 156 - i.e. choose "Standard". 157 - 158 - Choose "MACH-2" if you have a Mountain Mach-2 controller. 159 - Choose "FC-10/FC-20" if you have a Colorado FC-10 or FC-20 160 - controller. 161 - Choose "Alt/82078" if you have another controller that is located at 162 - an IO base address different from the standard floppy drive 163 - controller's base address of `0x3f0', or uses an IRQ (interrupt) 164 - channel different from `6', or a DMA channel different from 165 - `2'. This is necessary for any controller card that is based on 166 - Intel's 82078 FDC such as Seagate's, Exabyte's and Iomega's "high 167 - speed" controllers. 168 - 169 - If you choose something other than "Standard" then please make 170 - sure that the settings for the IO base address and the IRQ and DMA 171 - channel in the configuration menus below are correct. Use the manual 172 - of your tape drive to determine the correct settings! 173 - 174 - If you are already successfully using your tape drive with another 175 - operating system then you definitely should use the same settings 176 - for the IO base, the IRQ and DMA channel that have proven to work 177 - with that other OS. 178 - 179 - Note that this menu lets you specify only the default setting for 180 - the hardware setup. The hardware configuration can be changed at 181 - boot time (when ftape is compiled into the kernel, i.e. if you 182 - have said Y to "Floppy tape drive") or module load time (i.e. if you 183 - have said M to "Floppy tape drive"). 184 - 185 - Please read also the file <file:Documentation/ftape.txt> which 186 - contains a short description of the parameters that can be set at 187 - boot or load time. If you want to use your floppy tape drive on a 188 - PCI-bus based system, please read the file 189 - <file:drivers/char/ftape/README.PCI>. 190 - 191 - config FT_MACH2 192 - bool "MACH-2" 193 - 194 - config FT_PROBE_FC10 195 - bool "FC-10/FC-20" 196 - 197 - config FT_ALT_FDC 198 - bool "Alt/82078" 199 - 200 - endchoice 201 - 202 - comment "Consult the manuals of your tape drive for the correct settings!" 203 - depends on FTAPE && !FT_STD_FDC 204 - 205 - config FT_FDC_BASE 206 - hex "IO base of the floppy disk controller" 207 - depends on FTAPE && !FT_STD_FDC 208 - default "0" 209 - ---help--- 210 - You don't need to specify a value if the following default 211 - settings for the base IO address are correct: 212 - <<< MACH-2 : 0x1E0 >>> 213 - <<< FC-10/FC-20: 0x180 >>> 214 - <<< Secondary : 0x370 >>> 215 - Secondary refers to a secondary FDC controller like the "high speed" 216 - controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash. 217 - Please make sure that the setting for the IO base address 218 - specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR 219 - CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already 220 - successfully using the tape drive with another operating system then 221 - you definitely should use the same settings for the IO base that has 222 - proven to work with that other OS. 223 - 224 - Note that this menu lets you specify only the default setting for 225 - the IO base. The hardware configuration can be changed at boot time 226 - (when ftape is compiled into the kernel, i.e. if you specified Y to 227 - "Floppy tape drive") or module load time (i.e. if you have said M to 228 - "Floppy tape drive"). 229 - 230 - Please read also the file <file:Documentation/ftape.txt> which 231 - contains a short description of the parameters that can be set at 232 - boot or load time. 233 - 234 - config FT_FDC_IRQ 235 - int "IRQ channel of the floppy disk controller" 236 - depends on FTAPE && !FT_STD_FDC 237 - default "0" 238 - ---help--- 239 - You don't need to specify a value if the following default 240 - settings for the interrupt channel are correct: 241 - <<< MACH-2 : 6 >>> 242 - <<< FC-10/FC-20: 9 >>> 243 - <<< Secondary : 6 >>> 244 - Secondary refers to secondary a FDC controller like the "high speed" 245 - controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash. 246 - Please make sure that the setting for the IO base address 247 - specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR 248 - CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already 249 - successfully using the tape drive with another operating system then 250 - you definitely should use the same settings for the IO base that has 251 - proven to work with that other OS. 252 - 253 - Note that this menu lets you specify only the default setting for 254 - the IRQ channel. The hardware configuration can be changed at boot 255 - time (when ftape is compiled into the kernel, i.e. if you said Y to 256 - "Floppy tape drive") or module load time (i.e. if you said M to 257 - "Floppy tape drive"). 258 - 259 - Please read also the file <file:Documentation/ftape.txt> which 260 - contains a short description of the parameters that can be set at 261 - boot or load time. 262 - 263 - config FT_FDC_DMA 264 - int "DMA channel of the floppy disk controller" 265 - depends on FTAPE && !FT_STD_FDC 266 - default "0" 267 - ---help--- 268 - You don't need to specify a value if the following default 269 - settings for the DMA channel are correct: 270 - <<< MACH-2 : 2 >>> 271 - <<< FC-10/FC-20: 3 >>> 272 - <<< Secondary : 2 >>> 273 - Secondary refers to a secondary FDC controller like the "high speed" 274 - controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash. 275 - Please make sure that the setting for the IO base address 276 - specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR 277 - CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already 278 - successfully using the tape drive with another operating system then 279 - you definitely should use the same settings for the IO base that has 280 - proven to work with that other OS. 281 - 282 - Note that this menu lets you specify only the default setting for 283 - the DMA channel. The hardware configuration can be changed at boot 284 - time (when ftape is compiled into the kernel, i.e. if you said Y to 285 - "Floppy tape drive") or module load time (i.e. if you said M to 286 - "Floppy tape drive"). 287 - 288 - Please read also the file <file:Documentation/ftape.txt> which 289 - contains a short description of the parameters that can be set at 290 - boot or load time. 291 - 292 - config FT_FDC_THR 293 - int "Default FIFO threshold (EXPERIMENTAL)" 294 - depends on FTAPE && EXPERIMENTAL 295 - default "8" 296 - help 297 - Set the FIFO threshold of the FDC. If this is higher the DMA 298 - controller may serve the FDC after a higher latency time. If this is 299 - lower, fewer DMA transfers occur leading to less bus contention. 300 - You may try to tune this if ftape annoys you with "reduced data 301 - rate because of excessive overrun errors" messages. However, this 302 - doesn't seem to have too much effect. 303 - 304 - If unsure, don't touch the initial value, i.e. leave it at "8". 305 - 306 - config FT_FDC_MAX_RATE 307 - int "Maximal data rate to use (EXPERIMENTAL)" 308 - depends on FTAPE && EXPERIMENTAL 309 - default "2000" 310 - ---help--- 311 - With some motherboard/FDC combinations ftape will not be able to 312 - run your FDC/tape drive combination at the highest available 313 - speed. If this is the case you'll encounter "reduced data rate 314 - because of excessive overrun errors" messages and lots of retries 315 - before ftape finally decides to reduce the data rate. 316 - 317 - In this case it might be desirable to tell ftape beforehand that 318 - it need not try to run the tape drive at the highest available 319 - speed. If unsure, leave this disabled, i.e. leave it at 2000 320 - bits/sec. 321 - 322 - config FT_ALPHA_CLOCK 323 - int "CPU clock frequency of your DEC Alpha" if ALPHA 324 - depends on FTAPE 325 - default "0" 326 - help 327 - On some DEC Alpha machines the CPU clock frequency cannot be 328 - determined automatically, so you need to specify it here ONLY if 329 - running a DEC Alpha, otherwise this setting has no effect. 330 -
-28
drivers/char/ftape/Makefile
··· 1 - # 2 - # Copyright (C) 1997 Claus Heine. 3 - # 4 - # This program is free software; you can redistribute it and/or modify 5 - # it under the terms of the GNU General Public License as published by 6 - # the Free Software Foundation; either version 2, or (at your option) 7 - # any later version. 8 - # 9 - # This program is distributed in the hope that it will be useful, 10 - # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - # GNU General Public License for more details. 13 - # 14 - # You should have received a copy of the GNU General Public License 15 - # along with this program; see the file COPYING. If not, write to 16 - # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - # 18 - # $Source: /homes/cvs/ftape-stacked/ftape/Makefile,v $ 19 - # $Revision: 1.4 $ 20 - # $Date: 1997/10/05 19:17:56 $ 21 - # 22 - # Makefile for the QIC-40/80/3010/3020 floppy-tape driver for 23 - # Linux. 24 - # 25 - 26 - obj-$(CONFIG_FTAPE) += lowlevel/ 27 - obj-$(CONFIG_ZFTAPE) += zftape/ 28 - obj-$(CONFIG_ZFT_COMPRESSOR) += compressor/
-81
drivers/char/ftape/README.PCI
··· 1 - Some notes for ftape users with PCI motherboards: 2 - ================================================= 3 - 4 - The problem: 5 - ------------ 6 - 7 - There have been some problem reports from people using PCI-bus based 8 - systems getting overrun errors. 9 - I wasn't able to reproduce these until I ran ftape on a Intel Plato 10 - (Premiere PCI II) motherboard with bios version 1.00.08AX1. 11 - It turned out that if GAT (Guaranteed Access Timing) is enabled (?) 12 - ftape gets a lot of overrun errors. 13 - The problem disappears when disabling GAT in the bios. 14 - Note that Intel removed this setting (permanently disabled) from the 15 - 1.00.10AX1 bios ! 16 - 17 - It looks like that if GAT is enabled there are often large periods 18 - (greater than 120 us !??) on the ISA bus that the DMA controller cannot 19 - service the floppy disk controller. 20 - I cannot imagine this being acceptable in a decent PCI implementation. 21 - Maybe this is a `feature' of the chipset. I can only speculate why 22 - Intel choose to remove the option from the latest Bios... 23 - 24 - The lesson of this all is that there may be other motherboard 25 - implementations having the same of similar problems. 26 - If you experience a lot of overrun errors during a backup to tape, 27 - see if there is some setting in the Bios that may influence the 28 - bus timing. 29 - 30 - I judge this a hardware problem and not a limitation of ftape ;-) 31 - My DOS backup software seems to be suffering from the same problems 32 - and even refuses to run at 1 Mbps ! 33 - Ftape will reduce the data-rate from 1 Mbps to 500 Kbps if the number 34 - of overrun errors on a track exceeds a threshold. 35 - 36 - 37 - Possible solutions: 38 - ------------------- 39 - 40 - Some of the problems were solved by upgrading the (flash) bios. 41 - Other suggest that it has to do with the FDC being on the PCI 42 - bus, but that is not the case with the Intel Premiere II boards. 43 - [If upgrading the bios doesn't solve the problem you could try 44 - a floppy disk controller on the isa-bus]. 45 - 46 - Here is a list of systems and recommended BIOS settings: 47 - 48 - 49 - Intel Premiere PCI (Revenge): 50 - 51 - Bios version 1.00.09.AF2 is reported to work. 52 - 53 - 54 - 55 - Intel Premiere PCI II (Plato): 56 - 57 - Bios version 1.00.10.AX1 and version 11 beta are ok. 58 - If using version 1.00.08.AX1, GAT must be disabled ! 59 - 60 - 61 - 62 - ASUS PCI/I-SP3G: 63 - 64 - Preferred settings: ISA-GAT-mode : disabled 65 - DMA-linebuffer-mode : standard 66 - ISA-masterbuffer-mode : standard 67 - 68 - 69 - DELL Dimension XPS P90 70 - 71 - Bios version A2 is reported to be broken, while bios version A5 works. 72 - You can get a flash bios upgrade from http://www.dell.com 73 - 74 - 75 - To see if you're having the GAT problem, try making a backup 76 - under DOS. If it's very slow and often repositions you're 77 - probably having this problem. 78 - 79 - --//-- 80 - LocalWords: ftape PCI bios GAT ISA DMA chipset Mbps Kbps FDC isa AF ok ASUS 81 - LocalWords: SP linebuffer masterbuffer XPS http www com
-966
drivers/char/ftape/RELEASE-NOTES
··· 1 - Hey, Emacs, we're -*-Text-*- mode! 2 - 3 - ===== Release notes for ftape-3.04d 25/11/97 ===== 4 - - The correct pre-processor statement for "else if" is "#elif" not 5 - "elsif". 6 - - Need to call zft_reset_position() when overwriting cartridges 7 - previously written with ftape-2.x, sftape, or ancient 8 - (pre-ftape-3.x) versions of zftape. 9 - 10 - ===== Release notes for ftape-3.04c 16/11/97 ===== 11 - - fdc_probe() was calling DUMPREGS with a result length of "1" which 12 - was just fine. Undo previous change. 13 - 14 - ===== Release notes for ftape-3.04b 14/11/97 ===== 15 - 16 - - patches/2.x.x/floppy.c.diff was somewhat broken, releasing i/o 17 - regions it never had allocated. 18 - - fdc_probe() was calling DUMPREGS with a result length of "1" instead 19 - of "10" 20 - - Writing deleted data marks if the first segents on track zero are 21 - should work now. 22 - - ftformat should now be able to handle those cases where the tape 23 - drive sets the read only status bit (QIC-40/80 cartridges with 24 - QIC-3010/3020 tape drives) because the header segment is damaged. 25 - - the MTIOCFTCMD ioctl may now be issued by the superuser ONLY. 26 - 27 - ===== Release notes for ftape-3.04a 12/11/97 ===== 28 - - Fix an "infinite loop can't be killed by signal" bug in 29 - ftape_get_drive_status(). Only relevant when trying to access 30 - buggy/misconfigured hardware 31 - - Try to compensate a bug in the HP Colorado T3000's firmware: it 32 - doesn't set the write protect bit for QIC80/QIC40 cartridges. 33 - 34 - ===== Release notes for ftape-3.04 06/11/97 ===== 35 - - If positioning with fast seeking fails fall back to a slow seek 36 - before giving up. 37 - - (nearly) no retries on "no data errors" when verifying after 38 - formatting. Improved tuning of the bad sector map after formatting. 39 - - the directory layout has changed again to allow for easier kernel 40 - integration 41 - - Module parameter "ftape_tracing" now is called "ft_tracing" because 42 - the "ftape_tracing" variable has the version checksum attached to it. 43 - - `/proc/ftape' interface for 2.0.* kernels. `/proc/ftape' no longer 44 - is a directory but a file that contains all the information formerly 45 - provided in separate files under the `/proc/ftape/' directory. 46 - - Most of the configuration options have been prefixed by "CONFIG_FT_" 47 - in preparation of the kernel inclusion. The Makefiles under 48 - "./ftape/" should be directly usable by the kernel. 49 - - The MODVERSIONS stuff is now auto-detected. 50 - - Broke backslashed multi line options in MCONFIG into separate lines 51 - using GNU-make's "+=" feature. 52 - - The html and dvi version of the manual is now installed under 53 - '/usr/doc/ftape` with 'make install` 54 - - New SMP define in MCONFIG. ftape works with SMP if this is defined. 55 - - attempt to cope with "excessive overrun errors" by gradually 56 - increasing FDC FIFO threshold. But this doesn't seem to have too 57 - much an effect. 58 - - New load time configuration parameter "ft_fdc_rate_limit". If you 59 - encounter too many overrun errors with a 2Mb controller then you 60 - might want to set this to 1000. 61 - - overrun errors on the last sector in a segment sometimes result in 62 - a zero DMA residue. Dunno why, but compensate for it. 63 - - there were still fdc_read() timeout errors. I think I have fixed it 64 - now, please FIXME. 65 - - Sometimes ftape_write() failed to re-start the tape drive when a 66 - segment without a good sector was reached ("wait for empty segment 67 - failed"). This is fixed. Especially important for > QIC-3010. 68 - - sftape (aka ftape-2.x) has vanished. I didn't work on it for 69 - ages. It is probably still possible to use the old code with 70 - ftape-3.04, if one really needs it (BUT RECOMPILE IT) 71 - - zftape no longer alters the contents of already existing volume 72 - table entries, which makes it possible to fill in missing fields, 73 - like time stamps using some user space program. 74 - - ./contrib/vtblc/ contains such a program. 75 - - new perl script ./contrib/scripts/listtape that list the contents of a 76 - floppy tape cartridge parsing the output of "mt volinfo" + "mt fsf" 77 - - the MTWEOF implementation has changed a little bit (after I had a 78 - look at amanda). Calling MTWEOF while the tape is still held open 79 - after writing something to the tape now will terminate the current 80 - volume, and start a new one at the current position. 81 - - the volume table maintained by zftape now is a doubly linked list 82 - that grows dynamically as needed. 83 - 84 - formatting floppy tape cartridges 85 - --------------------------------- 86 - * there is a new user space formatting program that does most of the 87 - dirty work in user space (auto-detect, computing the sector 88 - coordinates, adjusting time stamps and statistics). It has a 89 - simple command line interface. 90 - * ftape-format.o has vanished, it has been folded into the low level 91 - ftape.o module, and the ioctl interface into zftape.o. Most of the 92 - complicated stuff has been moved to user space, so there was no 93 - need for a separate module anymore. 94 - * there is a new ioctl MTIOCFTCMD that sends a bare QIC-117 command 95 - to the tape drive. 96 - * there is a new mmap() feature to map the dma buffers into user 97 - space to be used by the user level formatting program. 98 - * Formatting of yet unformatted or totally degaussed cartridges 99 - should be possible now. FIXME. 100 - 101 - ===== Release notes for ftape-3.03b, <forgot the exact date> ==== 102 - 103 - ftape-3.03b was released as a beta release only. Its main new feature 104 - was support of the DITTO-2GB drive. This was made possible by reverse 105 - engineering done by <fill in his name> after Iomega failed to support 106 - ftape. Although they had promised to do so (this makes me feel a bit 107 - sad and uncomfortable about Iomega). 108 - 109 - ===== Release notes for ftape-3.03a, 22/05/97 ==== 110 - 111 - - Finally fixed auto-un-loading of modules for kernels > 2.1.18 112 - - Add an "uninstall" target to the Makefile 113 - - removed the kdtime hack 114 - - texi2www didn't properly set the back-reference from a footnote back 115 - to the regular text. 116 - 117 - zftape specific 118 - --------------- 119 - * hide the old compression map volume. Taper doesn't accept the 120 - presence of non-Taper volumes and Taper-written volume on the same 121 - tape. 122 - * EOD (End Of Data) handling was still broken: the expected behavior 123 - is to return a zero byte count at the first attempt to read past 124 - EOD, return a zero byte count at the second attempt to read past 125 - EOD and THEN return -EIO. 126 - 127 - ftape-format specific 128 - --------------------- 129 - * Detection of QIC-40 cartridges in select_tape_format() was broken 130 - and made it impossible to format QIC-3010/3020 cartridges. 131 - * There are strange "TR-1 Extra" cartridges out there which weren't 132 - detected properly because the don't strictly conform to the 133 - QIC-80, Rev. N, spec. 134 - 135 - ===== Release notes for ftape-3.03, 30/04/97 ===== 136 - 137 - - Removed kernel integration code from the package. I plan to provide 138 - a package that can be integrated into the stock kernel separately 139 - (hopefully soon). 140 - As a result, a simple `make' command now will build everything. 141 - - ALL compile time configuration options have been moved to the file 142 - `MCONFIG'. 143 - - Quite a few `low level' changes to allow formatting of cartridges. 144 - - formatting is implemented as a separate module `ftape-format.o'. The 145 - modified `mt' program contains sample code that shows how to use it. 146 - - The VFS interface has been moved from the `ftape.o' module to the 147 - high level modules `zftape.o' resp. `sftape.o'. `ftape.o' contains 148 - the hardware support only. 149 - - A bit of /proc support for kernels > 2.1.28 150 - - Moved documentation to Doc subdir. INSTALL now contains some real 151 - installation notes. 152 - - `install' target in Makefile. 153 - 154 - zftape specific: 155 - ---------------- 156 - 157 - - zftape works for large cartridges now ( > 2^31 bytes) 158 - - MTIOCVOLINFO and MTIOCGETSIZE now return the size in KILOBYTES, 159 - NO LONGER in bytes. 160 - 161 - - permissions for write access to a cartridge have changed: 162 - * zftape now also takes the file access mode into account 163 - * zftape no longer allows writing in the middle of the recorded 164 - media. The tape has to be positioned at BOT or EOD for write 165 - access. 166 - 167 - - MTBSF has changed. It used to position at the beginning of the 168 - previous file when called with count 1. This was different from the 169 - expected behavior for other Un*x tape drivers (i.e. SCSI). MTBSF 170 - with count 1 should merely position at the beginning of the current 171 - volume. Fixed. As a result, `tar --verify' now produces the desired 172 - result: it verifies the last written volume, not the pre-last 173 - written volume. 174 - 175 - - The compression map has vanished --> no need for `mt erase' any 176 - more. Fast seeking in a compressed volume is still be possible, but 177 - takes slightly longer. As a side effect, you may experience an 178 - additional volume showing up in front of all others for old 179 - cartridges. This is the tape volume that holds the compression map. 180 - 181 - - The compression support for zftape has been moved to a separate 182 - module `zft-compressor'. DON'T forget to load it before trying to 183 - read back compressed volumes. The stock `zftape.o' module probes for 184 - the module `zft-compressor' using the kerneld message channel; you 185 - have to install `zft-compressor.o' in a place where modprobe can 186 - find it if you want to use this. 187 - 188 - - New experimental feature that tries to get the broken down GMT time 189 - from user space via a kernel daemon message channel. You need to 190 - compile and start the `kdtime' daemon contained in the contrib 191 - directory to use it. Needed (?) for time stamps in the header 192 - segments and the volume table. 193 - 194 - - variable block size mode via MTSETBLK 0 195 - 196 - - keep modules locked in memory after the block size has been changed 197 - 198 - sftape specific: 199 - ---------------- 200 - 201 - - end of tape handling should be fixed, i.e. multi volume archives 202 - written with `afio' can be read back now. 203 - 204 - 205 - ===== Release notes for ftape-3.02a, 09/01/97 ===== 206 - 207 - No big news: 208 - - call zft_init() resp. sft_init() when compiling the entire stuff 209 - into the kernel image. 210 - - fix bug in ftape-setup.c when NO_TRACE_AT_ALL was defined. 211 - - fix bug in sftape-eof.c/zftape-eof.c for old kernels (1.2.*) 212 - - add support for new module interface for recent kernels 213 - 214 - ===== Release notes for ftape-3.02, 16/12/96 ===== 215 - - Fixed the `FDC unlock command failed' bug in fdc-io.c. When the FIFO 216 - was already locked when ftape was loaded, ftape failed to unlock it. 217 - - Fixed compilation of `contrib/gnumt'. It now finds `mtio.h' even if 218 - ftape is NOT included into the kernel source tree. 219 - - fc-10.c: include <asm/io.h> for inb() and outb(). 220 - - ftape/sftape/zftape: all global variable now have either a `ftape_', 221 - a `ft_', `sft_', `zft_' or `qic_' prefix to prevent name clashes 222 - with other parts of the kernel when including ftape into the kernel 223 - source tree. 224 - - Kerneld support has changed. `ftape' now searches for a module 225 - `ftape-frontend' when none of the frontend (`sftape' or `zftape') is 226 - loaded. Please refer to the `Installation/Loading ftape' section of 227 - the TeXinfo manual. 228 - - Add load resp. boot-time configuration of ftape. There are now 229 - variables ft_fdc_base, ft_fdc_dma and ft_fdc_irq corresponding to 230 - the former FDC_BASE etc. compile time definitions. One can also use 231 - the kernel command line parameters to configure the driver if it is 232 - compiled into the kernel. Also, the FC-10/FC-20 support is load-time 233 - configurable now as well as the MACH-II hack (ft_probe_fc10, 234 - resp. ft_mach2). Please refer to the section `Installation/Configure 235 - ftape' of the TeXinfo manual. 236 - - I removed the MODVERSIONS option from `Makefile.module'. Let me alone 237 - with ftape and MODVERSIONS unless you include the ftape sources into 238 - the kernel source tree. 239 - - new vendors in `vendors.h': 240 - * HP Colorado T3000 241 - * ComByte DoublePlay (including a bug fix for their broken 242 - formatting software, thanks to whraven@njackn.com) 243 - * Iomega DITTO 2GIG. NOTE: this drive cannot work with ftape because 244 - the logical data layout of the cartridges used by this drive does 245 - NOT conform to the QIC standards, it is a special Iomega specific 246 - format. I've sent mail to Iomega but didn't receive an answer 247 - yet. If you want this drive to be supported by ftape, ask Iomega 248 - to give me information about it. 249 - - zftape: 250 - * re-introduced the MTIOC_ZFTAPE_GETBLKSZ ioctl for compatibility 251 - with zftape 1.06a and earlier. Please don't use it when writing 252 - new software, use the MTIOCVOLINFO ioctl instead. 253 - * Major overhaul of the code that updates the header segments. Never 254 - change the tape label unless erasing the tape. Thus we almost 255 - never need to write the header segments, unless we would modify 256 - the bad sector map which isn't done yet. Updating of volume table 257 - and compression map more secure now although it takes a bit 258 - longer. 259 - * Fixed bug when aborting a write operation with a signal: zftape 260 - now finishes the current volume (i.e. writes an eof marker) at the 261 - current position. It didn't before which led to somehow *strange* 262 - behavior in this cases. 263 - * Keep module locked in memory when using it with the non-rewinding 264 - devices and the tape is not logical at BOT. Needed for kerneld 265 - support. 266 - - sftape: 267 - * Keep module locked in memory when using it with the non-rewinding 268 - devices and the tape is not logical at BOT. Needed for kerneld 269 - support. 270 - 271 - ===== Release notes for ftape-3.01, 14/11/96 ===== 272 - 273 - - Fixed silly bugs in ftape-3.00: 274 - * MAKEDEV.ftape: major device number must be 27, not 23 275 - * sftape/sftape-read.c: sftape_read_header_segments() called 276 - itself recursively instead of calling ftape_read_header_segment() 277 - * zftape/qic-vtbl.h: conversion of ftape's file marks to zftape's 278 - internal volume table was broken. 279 - * patches/2.x.x/linux-2.0.21.dif: my RCS (resp. CVS) system replaced 280 - the `$Revison:' etc. macros in the `ftape.h' concerning part of the 281 - patch :-( Fixed. 282 - * info/ftape.info: Fixed misspellings (`cp' <-> `cp -r' etc.) 283 - * when ftape/sftape or ftape/zftape was compiled into the kernel the 284 - variable ftape_status was declared twice. Fixed. 285 - * removed reference to undeclared variable kernel_version when not 286 - compiling as module 287 - * fixed a bug introduced by the use of bit-fields for some flags 288 - (i.e. write_protected, no_cartridge, formatted) 289 - * flag `header_read' is now reset correctly to zero when tape is 290 - removed. 291 - - fixed a bug in sftape/sftape-eof.c that was already in the original 292 - ftape code. MTFSF/BSF was not handled correctly when positioned 293 - right before the file mark (think of tar) 294 - - Changed TRACE macros (following a suggestion of Marcin Dalecki) to use 295 - the predefined __FUNCTION__ macro of GCC. Spares about 4k of code. 296 - - added new vendor id for Iomega DITTO 2GIG 297 - - fixed a bug already present in zftape-1.06 when aborting a write 298 - with a signal: we now finish the current volume at that 299 - position. Header segments remain NOT up to date until an explicit call 300 - to MTREW or MTOFFL is done. 301 - 302 - ===== Release notes for ftape-3.00, 14/10/96 ===== 303 - 304 - - Merged ftape with zftape. There are three modules now: 305 - ftape for the hardware support, sftape for the implementation of the 306 - original ftape eof mark stuff and zftape that implements zftape's way 307 - of handling things (compression, volume table, tape blocks of 308 - constant length) 309 - - Documentation in TeXinfo format in the `info' subdirectory. 310 - - New ioctls for zftape. See zftape/zftape.h 311 - - Dummy formatting ioctl for ftape. See ftape.h 312 - - Kernel patch files for the 2.*.* series to include ftape-3.00 in the 313 - kernel source tree. These includes a kernel compatible Config.in 314 - script and fairly large online information for the kernel configure 315 - script. 316 - - Support for compiling with Linux-1.2.13. 317 - - Modified GNU mt from their cpio package that can handle the new 318 - ioctls. 319 - - ftape/sftape/zftape is kerneld save now! 320 - 321 - Notes on sftape: 322 - - sftape implements the eof handling code of the original ftape. If 323 - you like to stick with the original ftape stuff, you have to use 324 - this module, not zftape. 325 - - sftape is kerneld save, unlike the original ftape. 326 - - we keep the entire header segment now in memory, so no need to read 327 - it before updating the header segments. Additional memory 328 - consumption: 256 bytes. 329 - 330 - Notes for zftape: 331 - - zftape has support for tapes with format code 6 now, which use a 332 - slightly different volume table format compared with other floppy 333 - tapes. 334 - - new ioctls for zftape. Have a look at zftape/zftape.h 335 - - The internal volume table representation has changed for zftape. Old 336 - cartridges are converted automatically. 337 - - zftape no longer uses compression map segments, which have vanished 338 - from the QIC specs, but creates volume table entry that reserves 339 - enough space for the compression map. 340 - - zftape is kerneld save now. 341 - - we keep the entire header segment now in memory, so no need to read 342 - it before updating the header segments. Additional memory 343 - consumption: 256 bytes. 344 - 345 - Notes for contrib/gnumt: 346 - - modified mt from the GNU cpio package that supports all the new 347 - ioctls of zftape. 348 - Notes for contrib/swapout: 349 - - This contains the swapout.c program that was written by Kai 350 - Harrekilde-Pederson. I simply added a Makefile. 351 - 352 - ===== Release notes for ftape-2.10, 14/10/96 ===== 353 - 354 - The ftape maintainer has changed. 355 - Kai Harrekilde-Petersen <khp@dolphinics.no> 356 - has resigned from maintaining ftape, and I, 357 - Claus-Justus Heine <claus@momo.math.rwth-aachen.de>, 358 - have taken over. 359 - 360 - - Added support for tapes with `format code 6', i.e. QIC-3020 tapes 361 - with more than 2^16 segments. 362 - - merged changes made by Bas Laarhoven with ftape-2.09. Refer 363 - to his release notes below. I've included them into this 364 - file unchanged for your reference. 365 - - disabled call stack back trace for now. This new feature 366 - introduced by the interim release 2.0.x still seems to 367 - be buggy. 368 - - Tried to minimize differences between the ftape version 369 - to be included into the kernel source tree and the standalone 370 - module version. 371 - - Reintroduced support for Linux-1.2.13. Please refer to the 372 - Install-guide. 373 - 374 - ===== Release notes for ftape-2.09, 16/06/96 ===== 375 - 376 - There aren't any really big news in this release, mostly just that I 377 - (the maintainer) have changed my email address (due to a new job). My 378 - new address is <khp@dolphinics.no> 379 - 380 - - The CLK_48MHZ and FDC_82078SL options has gone (all 2Mbps cards seem 381 - to use a 48MHz oscillator anyway and I haven't heard of an 'SL 382 - chip out there). 383 - - The S82078B has been `downgraded' to i82077AA compability. 384 - - TESTING option revived. Right now, it'll enable the (seriously broken) 385 - 2Mbps code. If you enable it, you'll experience a tape drive that's 386 - *really* out to lunch! 387 - - Some (bold) changes in the init code. Please notify me if they 388 - break things for you. 389 - 390 - ===== Release notes for ftape-2.08, 14/03/96 ===== 391 - 392 - If you correct a problem with ftape, please send your patch to 393 - khp@dolphinics.no too. 394 - 395 - - Updated to reflect that NR_MEM_LISTS is gone in 1.3.74 396 - - Teac 700 added to list of known drives. 397 - - The registered device name is now "ft" rather than "ftape". 398 - 399 - ===== Release notes for ftape-2.07a, 14/03/96 ===== 400 - 401 - Bugfixes by Marcin Dalecki <dalecki@namu03.gwdg.de>: 402 - - In the last release it just compiled against 1.3.70; 403 - now the params to request_irq() and free_irq are() are fixed, so it also 404 - works in 1.3.73 :-) 405 - - Support for modules is now correct for newer kernels. 406 - 407 - ===== Release notes for ftape-2.07, 04/03/96 ===== 408 - 409 - 410 - - ftape updated to compile against 1.3.70. 411 - - Iomega 700 and Wangtek 3200 recognised. 412 - 413 - 414 - ===== Release notes for ftape-2.06b, 13/02/96 ===== 415 - 416 - Another simple bugfix version. 417 - 418 - - Jumbo 700 recognised. 419 - - Typo in vendors.h fixed. 420 - 421 - 422 - ===== Release notes for ftape-2.06a, 10/02/96 ===== 423 - 424 - This release is a simple bugfix version. 425 - 426 - - Linux/SMP: ftape *should* work. 427 - - FC-10/20: Only accepts IRQs 3-7, or 9. If IRQ 9, properly tell the card 428 - to use IRQ 2. Thanks to Greg Crider (gcrider@iclnet.org) for finding and 429 - locating this bug and testing the patch. 430 - - Insight drive recognised correctly again. 431 - - Motor-on wakeup version of the Iomega 250 drive added 432 - 433 - 434 - ===== Release notes for ftape-2.06, 28/01/96 ===== 435 - 436 - Special thanks go to Neal Friedman and Steven Sorbom for their 437 - help in producing and testing this release. 438 - 439 - I have continued to clean up the code, with an eye towards inclusion 440 - of ftape in Linus' official kernel (In fact, as I type this, I am 441 - running on a kernel with ftape support statically linked). I have 442 - test-compiled ftape against my 1.2.13 tree without problems. 443 - Hopefully, everything should be OK for the v1.2.x people. 444 - 445 - WARNING! Alan Cox has mailed me that ftape does *NOT* work with 446 - Linux/SMP. If you try to run ftape under Linux/SMP, it will cause a 447 - kernel deadlock (which is worse than a panic). 448 - 449 - - QIC-3020/TR-3: 1Mbps support works. Neal is capable of reading and 450 - writing data to a tape. ftape will automatically detect the type of 451 - tape (e.g. TR-3 vs QIC-80) and move the fdc in and out of 452 - "perpendicular mode" as necessary. 453 - - 2Mbps support is disabled by default, since it is not fully 454 - debugged. If you are adventurous, remove -DFDC_82078SL in the 455 - Makefile and see what happens :-) 456 - - fdc detection: silly bugs removed (Only 2Mbps fdcs were affected) 457 - and added detection of the National Semiconductors PC8744 fdc chip 458 - (used in the PC873xx "super-IO" chips). 459 - - Removed warning about incompatible types when compiling with Linux 460 - 1.2.x. 461 - - README.PCI updated with info about the DELL Dimension XPS P90. 462 - - Connor TST3200R added to detected drives. 463 - - `swapout' utility added to distribution. It will dirty 5Meg of 464 - memory, trying to swap out other programs. Just say `make swapout' 465 - to build it. ftape will do this automatically Real Soon Now (ie: 466 - when I have found out which kernel memory alloc function to call). 467 - 468 - 469 - ===== Release notes for ftape-2.05, 08/01/96 ===== 470 - 471 - - For v1.2.x Kernels, you must apply the patch linux-1.2/ksyms.patch to 472 - the kernel and rebuild it (it adds the __get_dma_pages symbol to 473 - ksyms.c). 474 - - Included new asm-i386/io.h file from v1.3.x kernel series, to enable 475 - gcc v.2.7.[12] to compile v1.2.x kernels (linux-1.2/io.h). 476 - - Module versions: If you wish to compile ftape as a versioned module, 477 - you must first compile your kernel with CONFIG_MODVERSIONS=y. 478 - Otherwise, you will get complaints that <linux/modversions.h> does not 479 - exist (if that happens, a `touch modversions.h' will help you out). 480 - - CLK_48MHZ: new define in the Makefile (default: non-zero). If you have 481 - a tape controller card that uses the i82078(-1) chip, but cannot get 482 - it to work with ftape, try set it to 0 (and please report this). 483 - - QIC-3010/3020: Complete support is still missing, but will hopefully 484 - come soon. Steven Sorbom has kindly provided me with hints about 485 - this. Writing of QIC-3020 tapes definitely does NOT work (do not try 486 - it! - the drive will not be in "perpendicular mode" and this will ruin 487 - the formatting info on the tape). 488 - - ftape_num_buffers is out of fashion: use NR_BUFFERS instead (and 489 - recompile if you want to change it :-). 490 - 491 - 492 - ===== Release notes for ftape-2.04, 01/01/96 ===== 493 - 494 - This version by Kai Harrekilde-Petersen <khp@dolphinics.no> 495 - 496 - - ALERT! Support for Kernels earlier then v1.1.85 is about to go away. 497 - I intend to clean up some of the code (getting rid of an annoyingly 498 - large numbers of #ifdef mostly), which means that support for 499 - pre-1.1.85 kernels must go as well. 500 - - NR_FTAPE_BUFFERS is gone; You can instead select the number of dma 501 - buffers by saying `insmod ftape.o ftape_num_buffer=<n>' instead. 502 - - Configure script gone. ftape will now automagically determine your 503 - kernel version by /usr/include/linux/version.h instead. 504 - - CONFIG_MODVERSIONS now work. All combinations of versioned / 505 - unversioned kernel and ftape module works (at least with my 1.3.52 506 - kernel). 507 - - If you have problems with inserting ftape into an old (1.2.x) 508 - kernel (e.g. insmod says "1.2.8 does not match 1.2.8), recompile 509 - your modules utilities with your new compiler. 510 - - Reveal TB1400 drive added to vendors.h 511 - - Support for the i82078-1 (2Mbps) chip is coming along. The 512 - biggest problem is that I don't have such a card, which makes 513 - testing / debugging somewhat problematic. The second biggest 514 - problem is that I do not have the QIC-3010/3020 standards either. 515 - Status right now is that the chip is detected, and it should be 516 - possible to put it into 2Mbps mode. However, I do not know what 517 - "extras" are needed to complete the support. Although putting the 518 - i82078 into 1Mbps mode ought to work out of the box, it doesn't 519 - (right now, ftape complains about id am errors). 520 - 521 - 522 - ===== Release notes for ftape-2.04beta5, 29/12/95 ===== 523 - 524 - Bas offline linux-tape 525 - ---------------------- 526 - For reasons only known to the majordomo mail list processor, Bas was 527 - kicked off the linux-tape list sometime during the summer. Being 528 - overworked at his for-pay job, he didn't notice it much. Instead I 529 - (Kai, khp@dolphinics.no) has worked on ftape to produce the 2.04(beta) 530 - version. 531 - 532 - zftape 533 - ------ 534 - Note that there exists a much improved version of ftape, written by 535 - Claus-Justus Heine <claus@willi.math.rwth-aachen.de> which is named 536 - zftape, which conforms to the QIC-80 specs on how to mark backups, and 537 - is capable of doing automatic compression. However, zftape makes 538 - substantial changes to ftape, and I (Kai) have therefore declined to 539 - integrate zftape into ftape. Hopefully, this will happen soon. 540 - 541 - CONFIG_QIC117 removed from the kernel 542 - ------------------------------------- 543 - The biggest change of all is that ftape now will allocate its dma 544 - buffers when it is inserted. The means that the CONFIG_QIC117 option 545 - has disappeared from the Linux kernel as of v1.3.34. If you have an 546 - earlier kernel, simply answer 'no' to the question will do the trick 547 - (if you get complains about __get_free_pages() missing, contact the 548 - linux-tape mailing list). 549 - 550 - Note that ftape-2.04beta will work equally well on kernels with and 551 - without `ftape support'. The only catch is, that you will waste 552 - around 96-128Kb of precious DMA'able memory on a box that has ftape 553 - support compiled in. 554 - 555 - Now for the real changes: 556 - 557 - - FC-20 can now use DMA channels 1, 2, and 3. Thanks to Daniel 558 - Cohen, catman@wpi.edu. 559 - - ftape no longer requires a (gigantic) 96Kb buffer to be statically 560 - allocated by the kernel. 561 - - Added new Iomega drive (8882) to vendors.h 562 - - -fno-strength-reduce added to Makefile, since GCC is broken. 563 - - i82078-1 (2Mbps) FDC support started. 564 - 565 - 566 - ===== Release notes for ftape-2.03b, 27/05/95 ===== 567 - 568 - - Prevented verify_area to return error if called with zero length. 569 - - Fixed a bug in flush_buffers that caused too much padding to be 570 - written when a final segment had bad sectors. 571 - - Increased maximum fast-seek overshoot value from 5 to 10 segments. 572 - - Breaking loop after 5 retries when positioning fails. 573 - - Fixed wrong calculation of tape length for QIC-3010 and QIC-3020 574 - tapes (densities were swapped). 575 - - Fixed wrong calculation of overshoot on seek_forward: Wrong sign 576 - of error. 577 - - Suppress (false) error message due to new tape loaded. 578 - - Added two new CMS drives (11c3 and 11c5) to vendors.h. 579 - 580 - 581 - ===== Release notes for ftape-2.03a, 09/05/95 ===== 582 - 583 - - Fixed display of old error (even if already cleared) in ftape_open. 584 - - Improved tape length detection, ioctls would fail for 425 ft tapes. 585 - Until the tape length is calculated with data from the header 586 - segment, we'll use worst-case values. 587 - - Clear eof_mark after rewinding ioctls. 588 - - Fixed wrong version message (2.03 had 2.02g id). 589 - - Fixed bug that caused the fdc to be reset very frequently. 590 - This shouldn't affect normal operation but the timing of the 591 - report routines has changed again and that may cause problems. 592 - We'll just have to find out.... 593 - - Implemented correct write precompensation setting for QIC-3010/3020. 594 - - Cleaned up fdc_interrupt_wait routine. Hope it still works :-) 595 - - Finally removed (already disabled) special eof mark handling for 596 - gnu tar. 597 - - Changed order of get_dma_residue and disable_dma in fdc-isr.c 598 - because the current order would fail on at least one system. 599 - We're back to the original order again, hope (and expect) this 600 - doesn't break any other system. 601 - 602 - 603 - ===== Release notes for ftape-2.03, 07/05/95 ===== 604 - 605 - (Changes refer to the first ftape-2.02 release) 606 - 607 - Support for wide and extended length tapes 608 - ------------------------------------------ 609 - The Conner TSM 420 and 850 drives are reported to be working. 610 - I haven't received any reports about other brands; the TSM 420 611 - and 850 seem to be the most widely used wide drives. 612 - Extended length tapes (425 ft) with normal QIC-80 drives 613 - are operating too (At least I've had no reports stating otherwise). 614 - _Not_ yet completely supported (although they may work) are 615 - QIC-3020 drives and 2 Mbps floppy disk controllers won't work at 616 - the highest speed. 617 - If someone is kind enough to send me one of these, I'll include 618 - support for it too ;-) 619 - 620 - Easier configuration 621 - -------------------- 622 - Problems due to wrong settings in the Makefile are prevented 623 - by using a configuration script that sets the necessary (kernel 624 - version dependent) compile time options. 625 - This kernel version is now determined from the sources found 626 - at /usr/src/linux, or if not found, the old way using 627 - /proc/version. 628 - Versioned modules will be used automatically when supported 629 - by- and configured in- the kernel. 630 - Note that the current modules code (1.1.87) is still broken 631 - and _needs_ the fix included in the insmod directory. 632 - Please don't send me any more Oops reports caused by insmod :-( 633 - 634 - Reduced module size 635 - ------------------- 636 - The standard module size is much reduced and some compile time 637 - options can even reduce it further. (I don't recommend this 638 - for normal use but it can be handy for rescue diskettes) 639 - 640 - Option: Approx. module size: 641 - 642 - <standard> 150 Kb 643 - NO_TRACE 125 Kb 644 - NO_TRACE_AT_ALL 67 Kb 645 - 646 - 647 - Much improved driver interruption 648 - --------------------------------- 649 - Most possible loops have been broken and signal detection 650 - has been improved. 651 - In most cases the driver can be aborted by ^C (SIGINT) and 652 - SIGKILL (kill -9) will generate be a sure kill. 653 - (Note that aborting a tape operation may damage the last 654 - data written to tape) 655 - 656 - Improved error recovery 657 - ----------------------- 658 - Ftape now returns an error (ENODATA) to the application if 659 - a segment proves to be unrecoverable and then skips the 660 - bad segment. 661 - This causes most applications to continue to work (tar 662 - and afio) loosing only a small amount (up to 29 Kb) of data. 663 - Retried read operations will now be done slightly off-track 664 - to improve the chance of success. Serious head off-track 665 - errors will be detected. 666 - 667 - FC-10 and FC-20 controllers 668 - --------------------------- 669 - Ftape now supports both the old CMS FC-10 and the newer FC-20 670 - controllers. 671 - Because the operation of these cards is still undocumented, 672 - thus far they will only work with the default settings (See 673 - Makefile). Any feed-back on how to use them with other settings 674 - will be welcome ! 675 - Compilation will fail if one changes the settings to illegal 676 - values. 677 - 678 - Kernels and compilers 679 - --------------------- 680 - Ftape is currently being developed using the 2.5.8 compiler. 681 - The older 2.4.5 probably works too (Set option in Makefile!). 682 - I have no experience with any later compilers nor Elf support. 683 - Any information on this is welcome. 684 - The latest kernel I have tested ftape with is 1.2.6. 685 - 686 - Compression 687 - ----------- 688 - An impressive collection of changes for ftape including 689 - on-the-fly compression is still lying on my desk. 690 - If 2.03 proves to be reliable I might start integrating these 691 - but as usual, I'm short in time :-( 692 - 693 - Formatting 694 - ---------- 695 - There is still no way to format tapes under Linux. As far as 696 - I know all attempts to write such a program have died now. 697 - Since formatted tapes are rather common now, I think all we 698 - need is a utility that writes a worst case pattern and verifies 699 - that with the drive put in verify mode, reducing margins. 700 - Any takers ? 701 - 702 - Furthermore 703 - ----------- 704 - Cleaned up messages. 705 - Prepared to support multiple tape drives on one fdc. 706 - Thanks to all the people who sent bug reports and helped me 707 - improve the driver. Without trying to be complete I'll mention 708 - Gary Anderson (without his accurate reports and unreliable 709 - hardware there wouldn't be a 2.03), Stefan Kneifel (FC-20), 710 - Robert Broughton (FC-20, you were almost there ;-), Bjorn 711 - Ekwall (for the versioned modules and buggy insmod ;-), Peter 712 - Fox, Christopher Oliver, Ralph Whittaker and not the least 713 - Linus Torvalds (for Linux and keeping me busy because of 714 - changes to the kernel ;-) 715 - Thanks to anyone I forgot, for the bug reports, the ftape 716 - bashing and the mental support... 717 - 718 - 719 - That's it for now. Have Fun, 720 - 721 - Bas. 722 - 723 - 724 - ===== Release notes for ftape-2.02g, 06/05/95 ===== 725 - 726 - - Added extra test to break read-id loop with signal. 727 - - Changed rewind code to handle negative overshoot for drives 728 - that take very long to start or stop. 729 - - Let use of get/set i/o-regions depend on kernel version. 730 - - Changed code to use a more general test for conditional 731 - compilations depending on kernel version. 732 - - Improved micro-step functionality to go off-track only 733 - while reading (id & data). 734 - - Added failure on tape-not-referenced bit in ftape_command. 735 - - Added FOREVER option to read-wait routine. 736 - - Changed read-id to use shorter timeout causing smaller 737 - rewinds on timeout. 738 - - Made kernel-interface functions static. 739 - 740 - 741 - ===== Release notes for ftape-2.02f, 03/05/95 ===== 742 - 743 - - Added support for dual tape drives on my system, extended Configure 744 - script to detect host 'dodo'. 745 - - Log media defect in history if ecc failed and no data was returned. 746 - - Fixed Configure script that was failing for kernel versions with 747 - double digit version or revision numbers. 748 - 749 - 750 - ===== Release notes for ftape-2.02e, 01/05/95 ===== 751 - 752 - - Fixed reposition loop at logical eot (failing read_id). 753 - - Fixed 34 segment offset when rewinding. 754 - - Added fast seek capability for more than 255 segments. 755 - - Fixed wrong busy result from ftape_command causing reverse 756 - seek to fail. 757 - - Added breakout from infinite rewind loop (if something fails). 758 - 759 - 760 - ===== Release notes for ftape-2.02d, 30/04/95 ===== 761 - 762 - - Improved abortion on signals: Interrupt will make a graceful 763 - exit, Kill will be less nice and should be used if everything 764 - else fails. 765 - - Included check for tape-head off track. 766 - - Implemented exit from tape-start loop. 767 - - Added kernel io-port registration. 768 - - Implemented skip of failing segment (ENODATA) on ecc failure. 769 - This allows afio and tar to continue when the tape is damaged. 770 - - Made distinction between drive names with different codes. 771 - 772 - 773 - ===== Release notes for ftape-2.02c, 22/04/95 ===== 774 - 775 - - Fixed too tight command queueing after tape stop/pause command 776 - issued from within interrupt service routine (Showed as timeout 777 - on Acknowledge errors during retries on some systems) 778 - - Tried to fix timeouts when using 425 ft tape because the extended 779 - length doesn't seem to be detected by the hardware. 780 - We now use the format code from the header segment so adjust the 781 - timing after reading the header segment. 782 - - Fixed some messages stating 'unexpected something...' being not 783 - unexpected anymore. 784 - - Started preparations for merge of dynamic buffer allocation and 785 - compression code. 786 - - Changed some debug messages to include relevant segment information 787 - at level 4. 788 - - Included early bail-out when drive offline, preventing a lot of 789 - false messages. 790 - - Moved ftape_parameter_xxx() offsets into function instead of in calls. 791 - - Removed 'weird, drive busy but no data' error when caused by 792 - an error during a read-id. 793 - - Improved 'timeout on acknowledge' diagnostics. 794 - - Moved MODULE option into Configure. 795 - - Reduced code size when no tracing at all was set (Claus Heine). 796 - - No longer log error code 0 (no error) as an error. 797 - 798 - 799 - ===== Release notes for ftape-2.02b, 09/04/95 ===== 800 - 801 - - Relaxed timing for status operation and displaying 802 - abnormal results. Hopefully this shows what's going 803 - wrong with the Conner TSM850R drives. 804 - - Created script for configuration, using version number 805 - of kernel source if available, otherwise /proc/version. 806 - - Fixed conditionals in kernel-interface.c. 807 - - Removed unavoidable TRACE output. 808 - 809 - 810 - ===== Release notes for ftape-2.02a, 01/04/95 ===== 811 - 812 - - Implemented `new-style' (versioned) modules support for new 813 - kernels. 814 - - Reduced size of module by moving static data to bss. 815 - - Now using version number of kernel source instead of running 816 - kernel for kernel versions >= 1.1.82 817 - - Added feedback on drive speeds to vendor information. 818 - - Included fixed insmod sources to distribution (Let's hope 819 - the modules distribution get fixed soon :-/). 820 - 821 - Note that I haven't yet implemented any of the code extension I 822 - received. I hope to find some time to do this soon. 823 - 824 - 825 - ===== Release notes for ftape-2.02, 15/01/95 ===== 826 - 827 - 828 - - Fixed failing repositioning when overshoot was incremented. 829 - - Fixed rate selection: Because of a deficiency in the QIC-117 830 - specification one cannot distinguish between a not implemented 831 - and a failing command. Therefor we now try to find out if the 832 - drive does support this command before usage. 833 - - Fixed error retry using wrong offset in fdc-isr. 834 - - Improved retry code to retry only once on a single no-data 835 - error in a segment. 836 - - Validate sector number extracted from eof mark because an 837 - invalid file mark (due to ???) could cause kernel panic. 838 - - Split ftape-io.c into ftape-io.c and ftape-ctl.c files. 839 - - Corrected too high media error count after writing to 840 - a bad tape. 841 - - Added #include <asm/segment.h> again because old kernel versions 842 - need it. 843 - - Fixed fdc not being disabled when open failed because no tape 844 - drive was found. 845 - - Fixed problem with soft error in sector 32 (shift operator with 846 - shiftcount 32 is not defined). 847 - 848 - 849 - ===== Release notes for ftape-2.01, 08/01/95 ===== 850 - 851 - 852 - - Removed TESTING setting from distributed Makefile. 853 - - Fixed `mt asf' failure: Rewind was deferred to close which 854 - overruled the fsf ioctl. 855 - - Prevented non-interruptible commands being interrupted. 856 - - Added missing timeout.pause setting. 857 - - Maximum tape speed read from drive type information table. 858 - If the information is not in the table (0) the drive will 859 - determine the speed itself and put a message in the logfile. 860 - This information should then be added to the table in the 861 - vendors.h file (and reported to me). 862 - - Added call to ftape_init_drive after soft reset for those 863 - (antique) drives that don't do an implicit seek_load_point 864 - after a reset or power up. 865 - - Don't try to set data rate if reset failed. 866 - - Prevent update of seek variables when starting from the 867 - beginning or the end of the tape. 868 - - Fixed wrong adjustment of overshoot in seek_forward(). 869 - - Added sync to Makefile (again). 870 - - Added code to diagnose timer problems (calibr.c). 871 - - Replaced time differences by timediff calls. 872 - - Removed reference to do_floppy from object for recent kernels. 873 - - Fixed wrong display of 'failing dma controller' message. 874 - - Removed various no longer used #include statements. 875 - - Added max. tape speed value to vendor-struct. 876 - - Changed ftape-command to check pre-conditions and wait 877 - if needed. 878 - - Further updated qic117.h to rev G. 879 - - Combined command name table and restrictions table to one. 880 - Extended this table with some new fields. 881 - - Increased timeout on Ack timer value and included code to 882 - report out of spec behaviour. 883 - - Increased rewind timeout margin to calculated + 20%. 884 - - Improved data rate selection so it won't fail on some 885 - older (pre standard) drives. 886 - - Changed initialisation code so drive will be rewound if the 887 - driver is reloaded and the tape is not at bot. 888 - - Moved some of the flush operations from close to the ioctls. 889 - - Added exit code value to failing verify area message. 890 - - Loop until tape halted in smart-stop. 891 - - Fast seek handled specially if located at bot or eot. 892 - - Being more conservative on overshoot value. 893 - 894 - 895 - ===== Release notes for ftape-2.00, 31/12/94 ===== 896 - 897 - The Install-guide is completely rewritten and now also includes 898 - some information on how to use the driver. If you're either new 899 - to ftape or new to Unix tape devices make sure to read it ! 900 - 901 - If you own a pci system and experience problems with the 902 - ftape driver make sure to read the README.PCI file. It contains 903 - some hints on how to fix your hardware. 904 - 905 - For anybody who hasn't noticed: The version number of the 906 - driver has been incremented (The latest released version has 907 - been version 1.14d). 908 - This has been done for two major reasons: 909 - 910 - o A new (better) error recovery scheme is implemented. 911 - o Support for new drive types has been added. 912 - 913 - All these improvements/changes will probably include a couple 914 - of new (and old?) bugs. If you encounter any problems that you think 915 - I'm not yet aware of, feel free to send a report to <bas@vimec.nl>. 916 - I recommend keeping a version of ftape-1.14d available, just 917 - in case ;-) 918 - 919 - This version should work with all kernel versions from 1.0.9 up 920 - to 1.1.72 (and probably earlier and later versions too). 921 - 922 - 923 - Major new features: 924 - 925 - - Better handling of tapes with defects: When a sector repeatedly 926 - (SOFT_RETRIES in ftape.h) cannot be written to or read from it is 927 - marked as an hard error and gets skipped. 928 - The error correction code can handle up to three of these hard 929 - errors provided there are no other errors in that segment (32 Kb). 930 - 931 - - Allows writing to tapes with defects (although the risk of loosing 932 - data increases !) 933 - Look for the media-defects entry printed with the statistics when 934 - the tape is closed. A non-zero value here shows a bad tape. 935 - [the actual count is wrong (too high), this is a known bug]. 936 - 937 - - Use of backup header segment if first one is failing. 938 - 939 - - Support for extended length tapes with QIC-80: both 425 and 1100 ft. 940 - 0.25 inch tapes are now recognized and handled. 941 - 942 - - Support for new QIC-80 drives with 8 mm `wide' tapes (e.g. Conner 943 - TSM 420). 944 - 945 - - Support for new QIC-3010 and QIC-3020 drives (experimental) with 946 - both 0.25 inch and 8 mm tapes. 947 - 948 - Some minor features were added, a couple of small bugs were fixed and 949 - probably some new ones introduced ;-). 950 - 951 - [lseek() didn't make it into this version] 952 - 953 - Have fun, 954 - 955 - Bas. 956 - ---- 957 - LocalWords: ftape MCONFIG mt VFS zftape resp sftape proc subdir MTIOCVOLINFO 958 - LocalWords: MTIOCGETSIZE BOT EOD MTBSF zft kerneld modprobe kdtime contrib TR 959 - LocalWords: MTSETBLK afio uninstall texi www EIO QIC init sft eof aka dma GB 960 - LocalWords: SIGKILL MTIOCFTCMD mmap Iomega FDC fdc io gnumt mtio fc asm inb 961 - LocalWords: outb ft qic frontend TeXinfo irq mach MODVERSIONS CONFIG html dvi 962 - LocalWords: usr doc SMP Mb Dunno FIXME vtblc perl listtape volinfo fsf MTWEOF 963 - LocalWords: amanda degaussed ComByte DoublePlay whraven njackn com MTIOC vtbl 964 - LocalWords: GETBLKSZ MAKEDEV zftape's linux dif CVS Revison cp MTREW MTOFFL 965 - LocalWords: MTFSF BSF Marcin Dalecki GCC Config cpio swapout Kai Harrekilde 966 - LocalWords: Pederson khp dolphinics Justus claus momo rwth aachen Laarhoven
-31
drivers/char/ftape/compressor/Makefile
··· 1 - # 2 - # Copyright (C) 1997 Claus-Justus Heine. 3 - # 4 - # This program is free software; you can redistribute it and/or modify 5 - # it under the terms of the GNU General Public License as published by 6 - # the Free Software Foundation; either version 2, or (at your option) 7 - # any later version. 8 - # 9 - # This program is distributed in the hope that it will be useful, 10 - # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - # GNU General Public License for more details. 13 - # 14 - # You should have received a copy of the GNU General Public License 15 - # along with this program; see the file COPYING. If not, write to 16 - # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - # 18 - # $Source: /homes/cvs/ftape-stacked/ftape/compressor/Makefile,v $ 19 - # $Revision: 1.1 $ 20 - # $Date: 1997/10/05 19:12:28 $ 21 - # 22 - # Makefile for the optional compressor for th zftape VFS 23 - # interface to the QIC-40/80/3010/3020 floppy-tape driver for 24 - # Linux. 25 - # 26 - 27 - obj-$(CONFIG_ZFT_COMPRESSOR) += zft-compressor.o 28 - 29 - zft-compressor-objs := zftape-compress.o lzrw3.o 30 - 31 - CFLAGS_lzrw3.o := -O6 -funroll-all-loops
-743
drivers/char/ftape/compressor/lzrw3.c
··· 1 - /* 2 - * $Source: /homes/cvs/ftape-stacked/ftape/compressor/lzrw3.c,v $ 3 - * $Revision: 1.1 $ 4 - * $Date: 1997/10/05 19:12:29 $ 5 - * 6 - * Implementation of Ross Williams lzrw3 algorithm. Adaption for zftape. 7 - * 8 - */ 9 - 10 - #include "../compressor/lzrw3.h" /* Defines single exported function "compress". */ 11 - 12 - /******************************************************************************/ 13 - /* */ 14 - /* LZRW3.C */ 15 - /* */ 16 - /******************************************************************************/ 17 - /* */ 18 - /* Author : Ross Williams. */ 19 - /* Date : 30-Jun-1991. */ 20 - /* Release : 1. */ 21 - /* */ 22 - /******************************************************************************/ 23 - /* */ 24 - /* This file contains an implementation of the LZRW3 data compression */ 25 - /* algorithm in C. */ 26 - /* */ 27 - /* The algorithm is a general purpose compression algorithm that runs fast */ 28 - /* and gives reasonable compression. The algorithm is a member of the Lempel */ 29 - /* Ziv family of algorithms and bases its compression on the presence in the */ 30 - /* data of repeated substrings. */ 31 - /* */ 32 - /* This algorithm is unpatented and the code is public domain. As the */ 33 - /* algorithm is based on the LZ77 class of algorithms, it is unlikely to be */ 34 - /* the subject of a patent challenge. */ 35 - /* */ 36 - /* Unlike the LZRW1 and LZRW1-A algorithms, the LZRW3 algorithm is */ 37 - /* deterministic and is guaranteed to yield the same compressed */ 38 - /* representation for a given file each time it is run. */ 39 - /* */ 40 - /* The LZRW3 algorithm was originally designed and implemented */ 41 - /* by Ross Williams on 31-Dec-1990. */ 42 - /* */ 43 - /* Here are the results of applying this code, compiled under THINK C 4.0 */ 44 - /* and running on a Mac-SE (8MHz 68000), to the standard calgary corpus. */ 45 - /* */ 46 - /* +----------------------------------------------------------------+ */ 47 - /* | DATA COMPRESSION TEST | */ 48 - /* | ===================== | */ 49 - /* | Time of run : Sun 30-Jun-1991 09:31PM | */ 50 - /* | Timing accuracy : One part in 100 | */ 51 - /* | Context length : 262144 bytes (= 256.0000K) | */ 52 - /* | Test suite : Calgary Corpus Suite | */ 53 - /* | Files in suite : 14 | */ 54 - /* | Algorithm : LZRW3 | */ 55 - /* | Note: All averages are calculated from the un-rounded values. | */ 56 - /* +----------------------------------------------------------------+ */ 57 - /* | File Name Length CxB ComLen %Remn Bits Com K/s Dec K/s | */ 58 - /* | ---------- ------ --- ------ ----- ---- ------- ------- | */ 59 - /* | rpus:Bib.D 111261 1 55033 49.5 3.96 19.46 32.27 | */ 60 - /* | us:Book1.D 768771 3 467962 60.9 4.87 17.03 31.07 | */ 61 - /* | us:Book2.D 610856 3 317102 51.9 4.15 19.39 34.15 | */ 62 - /* | rpus:Geo.D 102400 1 82424 80.5 6.44 11.65 18.18 | */ 63 - /* | pus:News.D 377109 2 205670 54.5 4.36 17.14 27.47 | */ 64 - /* | pus:Obj1.D 21504 1 13027 60.6 4.85 13.40 18.95 | */ 65 - /* | pus:Obj2.D 246814 1 116286 47.1 3.77 19.31 30.10 | */ 66 - /* | s:Paper1.D 53161 1 27522 51.8 4.14 18.60 31.15 | */ 67 - /* | s:Paper2.D 82199 1 45160 54.9 4.40 18.45 32.84 | */ 68 - /* | rpus:Pic.D 513216 2 122388 23.8 1.91 35.29 51.05 | */ 69 - /* | us:Progc.D 39611 1 19669 49.7 3.97 18.87 30.64 | */ 70 - /* | us:Progl.D 71646 1 28247 39.4 3.15 24.34 40.66 | */ 71 - /* | us:Progp.D 49379 1 19377 39.2 3.14 23.91 39.23 | */ 72 - /* | us:Trans.D 93695 1 33481 35.7 2.86 25.48 40.37 | */ 73 - /* +----------------------------------------------------------------+ */ 74 - /* | Average 224401 1 110953 50.0 4.00 20.17 32.72 | */ 75 - /* +----------------------------------------------------------------+ */ 76 - /* */ 77 - /******************************************************************************/ 78 - 79 - /******************************************************************************/ 80 - 81 - /* The following structure is returned by the "compress" function below when */ 82 - /* the user asks the function to return identifying information. */ 83 - /* The most important field in the record is the working memory field which */ 84 - /* tells the calling program how much working memory should be passed to */ 85 - /* "compress" when it is called to perform a compression or decompression. */ 86 - /* LZRW3 uses the same amount of memory during compression and decompression. */ 87 - /* For more information on this structure see "compress.h". */ 88 - 89 - #define U(X) ((ULONG) X) 90 - #define SIZE_P_BYTE (U(sizeof(UBYTE *))) 91 - #define SIZE_WORD (U(sizeof(UWORD ))) 92 - #define ALIGNMENT_FUDGE (U(16)) 93 - #define MEM_REQ ( U(4096)*(SIZE_P_BYTE) + ALIGNMENT_FUDGE ) 94 - 95 - static struct compress_identity identity = 96 - { 97 - U(0x032DDEA8), /* Algorithm identification number. */ 98 - MEM_REQ, /* Working memory (bytes) required. */ 99 - "LZRW3", /* Name of algorithm. */ 100 - "1.0", /* Version number of algorithm. */ 101 - "31-Dec-1990", /* Date of algorithm. */ 102 - "Public Domain", /* Copyright notice. */ 103 - "Ross N. Williams", /* Author of algorithm. */ 104 - "Renaissance Software", /* Affiliation of author. */ 105 - "Public Domain" /* Vendor of algorithm. */ 106 - }; 107 - 108 - LOCAL void compress_compress (UBYTE *,UBYTE *,ULONG,UBYTE *, LONG *); 109 - LOCAL void compress_decompress(UBYTE *,UBYTE *,LONG, UBYTE *, ULONG *); 110 - 111 - /******************************************************************************/ 112 - 113 - /* This function is the only function exported by this module. */ 114 - /* Depending on its first parameter, the function can be requested to */ 115 - /* compress a block of memory, decompress a block of memory, or to identify */ 116 - /* itself. For more information, see the specification file "compress.h". */ 117 - 118 - EXPORT void lzrw3_compress( 119 - UWORD action, /* Action to be performed. */ 120 - UBYTE *wrk_mem, /* Address of working memory we can use.*/ 121 - UBYTE *src_adr, /* Address of input data. */ 122 - LONG src_len, /* Length of input data. */ 123 - UBYTE *dst_adr, /* Address to put output data. */ 124 - void *p_dst_len /* Address of longword for length of output data.*/ 125 - ) 126 - { 127 - switch (action) 128 - { 129 - case COMPRESS_ACTION_IDENTITY: 130 - *((struct compress_identity **)p_dst_len)= &identity; 131 - break; 132 - case COMPRESS_ACTION_COMPRESS: 133 - compress_compress(wrk_mem,src_adr,src_len,dst_adr,(LONG *)p_dst_len); 134 - break; 135 - case COMPRESS_ACTION_DECOMPRESS: 136 - compress_decompress(wrk_mem,src_adr,src_len,dst_adr,(LONG *)p_dst_len); 137 - break; 138 - } 139 - } 140 - 141 - /******************************************************************************/ 142 - /* */ 143 - /* BRIEF DESCRIPTION OF THE LZRW3 ALGORITHM */ 144 - /* ======================================== */ 145 - /* The LZRW3 algorithm is identical to the LZRW1-A algorithm except that */ 146 - /* instead of transmitting history offsets, it transmits hash table indexes. */ 147 - /* In order to decode the indexes, the decompressor must maintain an */ 148 - /* identical hash table. Copy items are straightforward:when the decompressor */ 149 - /* receives a copy item, it simply looks up the hash table to translate the */ 150 - /* index into a pointer into the data already decompressed. To update the */ 151 - /* hash table, it replaces the same table entry with a pointer to the start */ 152 - /* of the newly decoded phrase. The tricky part is with literal items, for at */ 153 - /* the time that the decompressor receives a literal item the decompressor */ 154 - /* does not have the three bytes in the Ziv (that the compressor has) to */ 155 - /* perform the three-byte hash. To solve this problem, in LZRW3, both the */ 156 - /* compressor and decompressor are wired up so that they "buffer" these */ 157 - /* literals and update their hash tables only when three bytes are available. */ 158 - /* This makes the maximum buffering 2 bytes. */ 159 - /* */ 160 - /* Replacement of offsets by hash table indexes yields a few percent extra */ 161 - /* compression at the cost of some speed. LZRW3 is slower than LZRW1, LZRW1-A */ 162 - /* and LZRW2, but yields better compression. */ 163 - /* */ 164 - /* Extra compression could be obtained by using a hash table of depth two. */ 165 - /* However, increasing the depth above one incurs a significant decrease in */ 166 - /* compression speed which was not considered worthwhile. Another reason for */ 167 - /* keeping the depth down to one was to allow easy comparison with the */ 168 - /* LZRW1-A and LZRW2 algorithms so as to demonstrate the exact effect of the */ 169 - /* use of direct hash indexes. */ 170 - /* */ 171 - /* +---+ */ 172 - /* |___|4095 */ 173 - /* |___| */ 174 - /* +---------------------*_|<---+ /----+---\ */ 175 - /* | |___| +---|Hash | */ 176 - /* | |___| |Function| */ 177 - /* | |___| \--------/ */ 178 - /* | |___|0 ^ */ 179 - /* | +---+ | */ 180 - /* | Hash +-----+ */ 181 - /* | Table | */ 182 - /* | --- */ 183 - /* v ^^^ */ 184 - /* +-------------------------------------|----------------+ */ 185 - /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||| */ 186 - /* +-------------------------------------|----------------+ */ 187 - /* | |1......18| | */ 188 - /* |<------- Lempel=History ------------>|<--Ziv-->| | */ 189 - /* | (=bytes already processed) |<-Still to go-->| */ 190 - /* |<-------------------- INPUT BLOCK ------------------->| */ 191 - /* */ 192 - /* The diagram above for LZRW3 looks almost identical to the diagram for */ 193 - /* LZRW1. The difference is that in LZRW3, the compressor transmits hash */ 194 - /* table indices instead of Lempel offsets. For this to work, the */ 195 - /* decompressor must maintain a hash table as well as the compressor and both */ 196 - /* compressor and decompressor must "buffer" literals, as the decompressor */ 197 - /* cannot hash phrases commencing with a literal until another two bytes have */ 198 - /* arrived. */ 199 - /* */ 200 - /* LZRW3 Algorithm Execution Summary */ 201 - /* --------------------------------- */ 202 - /* 1. Hash the first three bytes of the Ziv to yield a hash table index h. */ 203 - /* 2. Look up the hash table yielding history pointer p. */ 204 - /* 3. Match where p points with the Ziv. If there is a match of three or */ 205 - /* more bytes, code those bytes (in the Ziv) as a copy item, otherwise */ 206 - /* code the next byte in the Ziv as a literal item. */ 207 - /* 4. Update the hash table as possible subject to the constraint that only */ 208 - /* phrases commencing three bytes back from the Ziv can be hashed and */ 209 - /* entered into the hash table. (This enables the decompressor to keep */ 210 - /* pace). See the description and code for more details. */ 211 - /* */ 212 - /******************************************************************************/ 213 - /* */ 214 - /* DEFINITION OF COMPRESSED FILE FORMAT */ 215 - /* ==================================== */ 216 - /* * A compressed file consists of a COPY FLAG followed by a REMAINDER. */ 217 - /* * The copy flag CF uses up four bytes with the first byte being the */ 218 - /* least significant. */ 219 - /* * If CF=1, then the compressed file represents the remainder of the file */ 220 - /* exactly. Otherwise CF=0 and the remainder of the file consists of zero */ 221 - /* or more GROUPS, each of which represents one or more bytes. */ 222 - /* * Each group consists of two bytes of CONTROL information followed by */ 223 - /* sixteen ITEMs except for the last group which can contain from one */ 224 - /* to sixteen items. */ 225 - /* * An item can be either a LITERAL item or a COPY item. */ 226 - /* * Each item corresponds to a bit in the control bytes. */ 227 - /* * The first control byte corresponds to the first 8 items in the group */ 228 - /* with bit 0 corresponding to the first item in the group and bit 7 to */ 229 - /* the eighth item in the group. */ 230 - /* * The second control byte corresponds to the second 8 items in the group */ 231 - /* with bit 0 corresponding to the ninth item in the group and bit 7 to */ 232 - /* the sixteenth item in the group. */ 233 - /* * A zero bit in a control word means that the corresponding item is a */ 234 - /* literal item. A one bit corresponds to a copy item. */ 235 - /* * A literal item consists of a single byte which represents itself. */ 236 - /* * A copy item consists of two bytes that represent from 3 to 18 bytes. */ 237 - /* * The first byte in a copy item will be denoted C1. */ 238 - /* * The second byte in a copy item will be denoted C2. */ 239 - /* * Bits will be selected using square brackets. */ 240 - /* For example: C1[0..3] is the low nibble of the first control byte. */ 241 - /* of copy item C1. */ 242 - /* * The LENGTH of a copy item is defined to be C1[0..3]+3 which is a number */ 243 - /* in the range [3,18]. */ 244 - /* * The INDEX of a copy item is defined to be C1[4..7]*256+C2[0..8] which */ 245 - /* is a number in the range [0,4095]. */ 246 - /* * A copy item represents the sequence of bytes */ 247 - /* text[POS-OFFSET..POS-OFFSET+LENGTH-1] where */ 248 - /* text is the entire text of the uncompressed string. */ 249 - /* POS is the index in the text of the character following the */ 250 - /* string represented by all the items preceeding the item */ 251 - /* being defined. */ 252 - /* OFFSET is obtained from INDEX by looking up the hash table. */ 253 - /* */ 254 - /******************************************************************************/ 255 - 256 - /* The following #define defines the length of the copy flag that appears at */ 257 - /* the start of the compressed file. The value of four bytes was chosen */ 258 - /* because the fast_copy routine on my Macintosh runs faster if the source */ 259 - /* and destination blocks are relatively longword aligned. */ 260 - /* The actual flag data appears in the first byte. The rest are zeroed so as */ 261 - /* to normalize the compressed representation (i.e. not non-deterministic). */ 262 - #define FLAG_BYTES 4 263 - 264 - /* The following #defines define the meaning of the values of the copy */ 265 - /* flag at the start of the compressed file. */ 266 - #define FLAG_COMPRESS 0 /* Signals that output was result of compression. */ 267 - #define FLAG_COPY 1 /* Signals that output was simply copied over. */ 268 - 269 - /* The 68000 microprocessor (on which this algorithm was originally developed */ 270 - /* is fussy about non-aligned arrays of words. To avoid these problems the */ 271 - /* following macro can be used to "waste" from 0 to 3 bytes so as to align */ 272 - /* the argument pointer. */ 273 - #define ULONG_ALIGN_UP(X) ((((ULONG)X)+sizeof(ULONG)-1)&~(sizeof(ULONG)-1)) 274 - 275 - 276 - /* The following constant defines the maximum length of an uncompressed item. */ 277 - /* This definition must not be changed; its value is hardwired into the code. */ 278 - /* The longest number of bytes that can be spanned by a single item is 18 */ 279 - /* for the longest copy item. */ 280 - #define MAX_RAW_ITEM (18) 281 - 282 - /* The following constant defines the maximum length of an uncompressed group.*/ 283 - /* This definition must not be changed; its value is hardwired into the code. */ 284 - /* A group contains at most 16 items which explains this definition. */ 285 - #define MAX_RAW_GROUP (16*MAX_RAW_ITEM) 286 - 287 - /* The following constant defines the maximum length of a compressed group. */ 288 - /* This definition must not be changed; its value is hardwired into the code. */ 289 - /* A compressed group consists of two control bytes followed by up to 16 */ 290 - /* compressed items each of which can have a maximum length of two bytes. */ 291 - #define MAX_CMP_GROUP (2+16*2) 292 - 293 - /* The following constant defines the number of entries in the hash table. */ 294 - /* This definition must not be changed; its value is hardwired into the code. */ 295 - #define HASH_TABLE_LENGTH (4096) 296 - 297 - /* LZRW3, unlike LZRW1(-A), must initialize its hash table so as to enable */ 298 - /* the compressor and decompressor to stay in step maintaining identical hash */ 299 - /* tables. In an early version of the algorithm, the tables were simply */ 300 - /* initialized to zero and a check for zero was included just before the */ 301 - /* matching code. However, this test costs time. A better solution is to */ 302 - /* initialize all the entries in the hash table to point to a constant */ 303 - /* string. The decompressor does the same. This solution requires no extra */ 304 - /* test. The contents of the string do not matter so long as the string is */ 305 - /* the same for the compressor and decompressor and contains at least */ 306 - /* MAX_RAW_ITEM bytes. I chose consecutive decimal digits because they do not */ 307 - /* have white space problems (e.g. there is no chance that the compiler will */ 308 - /* replace more than one space by a TAB) and because they make the length of */ 309 - /* the string obvious by inspection. */ 310 - #define START_STRING_18 ((UBYTE *) "123456789012345678") 311 - 312 - /* In this algorithm, hash values have to be calculated at more than one */ 313 - /* point. The following macro neatens the code up for this. */ 314 - #define HASH(PTR) \ 315 - (((40543*(((*(PTR))<<8)^((*((PTR)+1))<<4)^(*((PTR)+2))))>>4) & 0xFFF) 316 - 317 - /******************************************************************************/ 318 - 319 - /* Input : Hand over the required amount of working memory in p_wrk_mem. */ 320 - /* Input : Specify input block using p_src_first and src_len. */ 321 - /* Input : Point p_dst_first to the start of the output zone (OZ). */ 322 - /* Input : Point p_dst_len to a ULONG to receive the output length. */ 323 - /* Input : Input block and output zone must not overlap. */ 324 - /* Output : Length of output block written to *p_dst_len. */ 325 - /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. May */ 326 - /* Output : write in OZ=Mem[p_dst_first..p_dst_first+src_len+MAX_CMP_GROUP-1].*/ 327 - /* Output : Upon completion guaranteed *p_dst_len<=src_len+FLAG_BYTES. */ 328 - LOCAL void compress_compress(UBYTE *p_wrk_mem, 329 - UBYTE *p_src_first, ULONG src_len, 330 - UBYTE *p_dst_first, LONG *p_dst_len) 331 - { 332 - /* p_src and p_dst step through the source and destination blocks. */ 333 - register UBYTE *p_src = p_src_first; 334 - register UBYTE *p_dst = p_dst_first; 335 - 336 - /* The following variables are never modified and are used in the */ 337 - /* calculations that determine when the main loop terminates. */ 338 - UBYTE *p_src_post = p_src_first+src_len; 339 - UBYTE *p_dst_post = p_dst_first+src_len; 340 - UBYTE *p_src_max1 = p_src_first+src_len-MAX_RAW_ITEM; 341 - UBYTE *p_src_max16 = p_src_first+src_len-MAX_RAW_ITEM*16; 342 - 343 - /* The variables 'p_control' and 'control' are used to buffer control bits. */ 344 - /* Before each group is processed, the next two bytes of the output block */ 345 - /* are set aside for the control word for the group about to be processed. */ 346 - /* 'p_control' is set to point to the first byte of that word. Meanwhile, */ 347 - /* 'control' buffers the control bits being generated during the processing */ 348 - /* of the group. Instead of having a counter to keep track of how many items */ 349 - /* have been processed (=the number of bits in the control word), at the */ 350 - /* start of each group, the top word of 'control' is filled with 1 bits. */ 351 - /* As 'control' is shifted for each item, the 1 bits in the top word are */ 352 - /* absorbed or destroyed. When they all run out (i.e. when the top word is */ 353 - /* all zero bits, we know that we are at the end of a group. */ 354 - # define TOPWORD 0xFFFF0000 355 - UBYTE *p_control; 356 - register ULONG control=TOPWORD; 357 - 358 - /* THe variable 'hash' always points to the first element of the hash table. */ 359 - UBYTE **hash= (UBYTE **) ULONG_ALIGN_UP(p_wrk_mem); 360 - 361 - /* The following two variables represent the literal buffer. p_h1 points to */ 362 - /* the hash table entry corresponding to the youngest literal. p_h2 points */ 363 - /* to the hash table entry corresponding to the second youngest literal. */ 364 - /* Note: p_h1=0=>p_h2=0 because zero values denote absence of a pending */ 365 - /* literal. The variables are initialized to zero meaning an empty "buffer". */ 366 - UBYTE **p_h1=NULL; 367 - UBYTE **p_h2=NULL; 368 - 369 - /* To start, we write the flag bytes. Being optimistic, we set the flag to */ 370 - /* FLAG_COMPRESS. The remaining flag bytes are zeroed so as to keep the */ 371 - /* algorithm deterministic. */ 372 - *p_dst++=FLAG_COMPRESS; 373 - {UWORD i; for (i=2;i<=FLAG_BYTES;i++) *p_dst++=0;} 374 - 375 - /* Reserve the first word of output as the control word for the first group. */ 376 - /* Note: This is undone at the end if the input block is empty. */ 377 - p_control=p_dst; p_dst+=2; 378 - 379 - /* Initialize all elements of the hash table to point to a constant string. */ 380 - /* Use of an unrolled loop speeds this up considerably. */ 381 - {UWORD i; UBYTE **p_h=hash; 382 - # define ZH *p_h++=START_STRING_18 383 - for (i=0;i<256;i++) /* 256=HASH_TABLE_LENGTH/16. */ 384 - {ZH;ZH;ZH;ZH; 385 - ZH;ZH;ZH;ZH; 386 - ZH;ZH;ZH;ZH; 387 - ZH;ZH;ZH;ZH;} 388 - } 389 - 390 - /* The main loop processes either 1 or 16 items per iteration. As its */ 391 - /* termination logic is complicated, I have opted for an infinite loop */ 392 - /* structure containing 'break' and 'goto' statements. */ 393 - while (TRUE) 394 - {/* Begin main processing loop. */ 395 - 396 - /* Note: All the variables here except unroll should be defined within */ 397 - /* the inner loop. Unfortunately the loop hasn't got a block. */ 398 - register UBYTE *p; /* Scans through targ phrase during matching. */ 399 - register UBYTE *p_ziv= NULL ; /* Points to first byte of current Ziv. */ 400 - register UWORD unroll; /* Loop counter for unrolled inner loop. */ 401 - register UWORD index; /* Index of current hash table entry. */ 402 - register UBYTE **p_h0 = NULL ; /* Pointer to current hash table entry. */ 403 - 404 - /* Test for overrun and jump to overrun code if necessary. */ 405 - if (p_dst>p_dst_post) 406 - goto overrun; 407 - 408 - /* The following cascade of if statements efficiently catches and deals */ 409 - /* with varying degrees of closeness to the end of the input block. */ 410 - /* When we get very close to the end, we stop updating the table and */ 411 - /* code the remaining bytes as literals. This makes the code simpler. */ 412 - unroll=16; 413 - if (p_src>p_src_max16) 414 - { 415 - unroll=1; 416 - if (p_src>p_src_max1) 417 - { 418 - if (p_src==p_src_post) 419 - break; 420 - else 421 - goto literal; 422 - } 423 - } 424 - 425 - /* This inner unrolled loop processes 'unroll' (whose value is either 1 */ 426 - /* or 16) items. I have chosen to implement this loop with labels and */ 427 - /* gotos to heighten the ease with which the loop may be implemented with */ 428 - /* a single decrement and branch instruction in assembly language and */ 429 - /* also because the labels act as highly readable place markers. */ 430 - /* (Also because we jump into the loop for endgame literals (see above)). */ 431 - 432 - begin_unrolled_loop: 433 - 434 - /* To process the next phrase, we hash the next three bytes and use */ 435 - /* the resultant hash table index to look up the hash table. A pointer */ 436 - /* to the entry is stored in p_h0 so as to avoid an array lookup. The */ 437 - /* hash table entry *p_h0 is looked up yielding a pointer p to a */ 438 - /* potential match of the Ziv in the history. */ 439 - index=HASH(p_src); 440 - p_h0=&hash[index]; 441 - p=*p_h0; 442 - 443 - /* Having looked up the candidate position, we are in a position to */ 444 - /* attempt a match. The match loop has been unrolled using the PS */ 445 - /* macro so that failure within the first three bytes automatically */ 446 - /* results in the literal branch being taken. The coding is simple. */ 447 - /* p_ziv saves p_src so we can let p_src wander. */ 448 - # define PS *p++!=*p_src++ 449 - p_ziv=p_src; 450 - if (PS || PS || PS) 451 - { 452 - /* Literal. */ 453 - 454 - /* Code the literal byte as itself and a zero control bit. */ 455 - p_src=p_ziv; literal: *p_dst++=*p_src++; control&=0xFFFEFFFF; 456 - 457 - /* We have just coded a literal. If we had two pending ones, that */ 458 - /* makes three and we can update the hash table. */ 459 - if (p_h2!=0) 460 - {*p_h2=p_ziv-2;} 461 - 462 - /* In any case, rotate the hash table pointers for next time. */ 463 - p_h2=p_h1; p_h1=p_h0; 464 - 465 - } 466 - else 467 - { 468 - /* Copy */ 469 - 470 - /* Match up to 15 remaining bytes using an unrolled loop and code. */ 471 - #if 0 472 - PS || PS || PS || PS || PS || PS || PS || PS || 473 - PS || PS || PS || PS || PS || PS || PS || p_src++; 474 - #else 475 - if ( 476 - !( PS || PS || PS || PS || PS || PS || PS || PS || 477 - PS || PS || PS || PS || PS || PS || PS ) 478 - ) p_src++; 479 - #endif 480 - *p_dst++=((index&0xF00)>>4)|(--p_src-p_ziv-3); 481 - *p_dst++=index&0xFF; 482 - 483 - /* As we have just coded three bytes, we are now in a position to */ 484 - /* update the hash table with the literal bytes that were pending */ 485 - /* upon the arrival of extra context bytes. */ 486 - if (p_h1!=0) 487 - { 488 - if (p_h2) 489 - {*p_h2=p_ziv-2; p_h2=NULL;} 490 - *p_h1=p_ziv-1; p_h1=NULL; 491 - } 492 - 493 - /* In any case, we can update the hash table based on the current */ 494 - /* position as we just coded at least three bytes in a copy items. */ 495 - *p_h0=p_ziv; 496 - 497 - } 498 - control>>=1; 499 - 500 - /* This loop is all set up for a decrement and jump instruction! */ 501 - #ifndef linux 502 - ` end_unrolled_loop: if (--unroll) goto begin_unrolled_loop; 503 - #else 504 - /* end_unrolled_loop: */ if (--unroll) goto begin_unrolled_loop; 505 - #endif 506 - 507 - /* At this point it will nearly always be the end of a group in which */ 508 - /* case, we have to do some control-word processing. However, near the */ 509 - /* end of the input block, the inner unrolled loop is only executed once. */ 510 - /* This necessitates the 'if' test. */ 511 - if ((control&TOPWORD)==0) 512 - { 513 - /* Write the control word to the place we saved for it in the output. */ 514 - *p_control++= control &0xFF; 515 - *p_control = (control>>8) &0xFF; 516 - 517 - /* Reserve the next word in the output block for the control word */ 518 - /* for the group about to be processed. */ 519 - p_control=p_dst; p_dst+=2; 520 - 521 - /* Reset the control bits buffer. */ 522 - control=TOPWORD; 523 - } 524 - 525 - } /* End main processing loop. */ 526 - 527 - /* After the main processing loop has executed, all the input bytes have */ 528 - /* been processed. However, the control word has still to be written to the */ 529 - /* word reserved for it in the output at the start of the most recent group. */ 530 - /* Before writing, the control word has to be shifted so that all the bits */ 531 - /* are in the right place. The "empty" bit positions are filled with 1s */ 532 - /* which partially fill the top word. */ 533 - while(control&TOPWORD) control>>=1; 534 - *p_control++= control &0xFF; 535 - *p_control++=(control>>8) &0xFF; 536 - 537 - /* If the last group contained no items, delete the control word too. */ 538 - if (p_control==p_dst) p_dst-=2; 539 - 540 - /* Write the length of the output block to the dst_len parameter and return. */ 541 - *p_dst_len=p_dst-p_dst_first; 542 - return; 543 - 544 - /* Jump here as soon as an overrun is detected. An overrun is defined to */ 545 - /* have occurred if p_dst>p_dst_first+src_len. That is, the moment the */ 546 - /* length of the output written so far exceeds the length of the input block.*/ 547 - /* The algorithm checks for overruns at least at the end of each group */ 548 - /* which means that the maximum overrun is MAX_CMP_GROUP bytes. */ 549 - /* Once an overrun occurs, the only thing to do is to set the copy flag and */ 550 - /* copy the input over. */ 551 - overrun: 552 - #if 0 553 - *p_dst_first=FLAG_COPY; 554 - fast_copy(p_src_first,p_dst_first+FLAG_BYTES,src_len); 555 - *p_dst_len=src_len+FLAG_BYTES; 556 - #else 557 - fast_copy(p_src_first,p_dst_first,src_len); 558 - *p_dst_len= -src_len; /* return a negative number to indicate uncompressed data */ 559 - #endif 560 - } 561 - 562 - /******************************************************************************/ 563 - 564 - /* Input : Hand over the required amount of working memory in p_wrk_mem. */ 565 - /* Input : Specify input block using p_src_first and src_len. */ 566 - /* Input : Point p_dst_first to the start of the output zone. */ 567 - /* Input : Point p_dst_len to a ULONG to receive the output length. */ 568 - /* Input : Input block and output zone must not overlap. User knows */ 569 - /* Input : upperbound on output block length from earlier compression. */ 570 - /* Input : In any case, maximum expansion possible is nine times. */ 571 - /* Output : Length of output block written to *p_dst_len. */ 572 - /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */ 573 - /* Output : Writes only in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */ 574 - LOCAL void compress_decompress( UBYTE *p_wrk_mem, 575 - UBYTE *p_src_first, LONG src_len, 576 - UBYTE *p_dst_first, ULONG *p_dst_len) 577 - { 578 - /* Byte pointers p_src and p_dst scan through the input and output blocks. */ 579 - register UBYTE *p_src = p_src_first+FLAG_BYTES; 580 - register UBYTE *p_dst = p_dst_first; 581 - /* we need to avoid a SEGV when trying to uncompress corrupt data */ 582 - register UBYTE *p_dst_post = p_dst_first + *p_dst_len; 583 - 584 - /* The following two variables are never modified and are used to control */ 585 - /* the main loop. */ 586 - UBYTE *p_src_post = p_src_first+src_len; 587 - UBYTE *p_src_max16 = p_src_first+src_len-(MAX_CMP_GROUP-2); 588 - 589 - /* The hash table is the only resident of the working memory. The hash table */ 590 - /* contains HASH_TABLE_LENGTH=4096 pointers to positions in the history. To */ 591 - /* keep Macintoshes happy, it is longword aligned. */ 592 - UBYTE **hash = (UBYTE **) ULONG_ALIGN_UP(p_wrk_mem); 593 - 594 - /* The variable 'control' is used to buffer the control bits which appear in */ 595 - /* groups of 16 bits (control words) at the start of each compressed group. */ 596 - /* When each group is read, bit 16 of the register is set to one. Whenever */ 597 - /* a new bit is needed, the register is shifted right. When the value of the */ 598 - /* register becomes 1, we know that we have reached the end of a group. */ 599 - /* Initializing the register to 1 thus instructs the code to follow that it */ 600 - /* should read a new control word immediately. */ 601 - register ULONG control=1; 602 - 603 - /* The value of 'literals' is always in the range 0..3. It is the number of */ 604 - /* consecutive literal items just seen. We have to record this number so as */ 605 - /* to know when to update the hash table. When literals gets to 3, there */ 606 - /* have been three consecutive literals and we can update at the position of */ 607 - /* the oldest of the three. */ 608 - register UWORD literals=0; 609 - 610 - /* Check the leading copy flag to see if the compressor chose to use a copy */ 611 - /* operation instead of a compression operation. If a copy operation was */ 612 - /* used, then all we need to do is copy the data over, set the output length */ 613 - /* and return. */ 614 - #if 0 615 - if (*p_src_first==FLAG_COPY) 616 - { 617 - fast_copy(p_src_first+FLAG_BYTES,p_dst_first,src_len-FLAG_BYTES); 618 - *p_dst_len=src_len-FLAG_BYTES; 619 - return; 620 - } 621 - #else 622 - if ( src_len < 0 ) 623 - { 624 - fast_copy(p_src_first,p_dst_first,-src_len ); 625 - *p_dst_len = (ULONG)-src_len; 626 - return; 627 - } 628 - #endif 629 - 630 - /* Initialize all elements of the hash table to point to a constant string. */ 631 - /* Use of an unrolled loop speeds this up considerably. */ 632 - {UWORD i; UBYTE **p_h=hash; 633 - # define ZJ *p_h++=START_STRING_18 634 - for (i=0;i<256;i++) /* 256=HASH_TABLE_LENGTH/16. */ 635 - {ZJ;ZJ;ZJ;ZJ; 636 - ZJ;ZJ;ZJ;ZJ; 637 - ZJ;ZJ;ZJ;ZJ; 638 - ZJ;ZJ;ZJ;ZJ;} 639 - } 640 - 641 - /* The outer loop processes either 1 or 16 items per iteration depending on */ 642 - /* how close p_src is to the end of the input block. */ 643 - while (p_src!=p_src_post) 644 - {/* Start of outer loop */ 645 - 646 - register UWORD unroll; /* Counts unrolled loop executions. */ 647 - 648 - /* When 'control' has the value 1, it means that the 16 buffered control */ 649 - /* bits that were read in at the start of the current group have all been */ 650 - /* shifted out and that all that is left is the 1 bit that was injected */ 651 - /* into bit 16 at the start of the current group. When we reach the end */ 652 - /* of a group, we have to load a new control word and inject a new 1 bit. */ 653 - if (control==1) 654 - { 655 - control=0x10000|*p_src++; 656 - control|=(*p_src++)<<8; 657 - } 658 - 659 - /* If it is possible that we are within 16 groups from the end of the */ 660 - /* input, execute the unrolled loop only once, else process a whole group */ 661 - /* of 16 items by looping 16 times. */ 662 - unroll= p_src<=p_src_max16 ? 16 : 1; 663 - 664 - /* This inner loop processes one phrase (item) per iteration. */ 665 - while (unroll--) 666 - { /* Begin unrolled inner loop. */ 667 - 668 - /* Process a literal or copy item depending on the next control bit. */ 669 - if (control&1) 670 - { 671 - /* Copy item. */ 672 - 673 - register UBYTE *p; /* Points to place from which to copy. */ 674 - register UWORD lenmt; /* Length of copy item minus three. */ 675 - register UBYTE **p_hte; /* Pointer to current hash table entry.*/ 676 - register UBYTE *p_ziv=p_dst; /* Pointer to start of current Ziv. */ 677 - 678 - /* Read and dismantle the copy word. Work out from where to copy. */ 679 - lenmt=*p_src++; 680 - p_hte=&hash[((lenmt&0xF0)<<4)|*p_src++]; 681 - p=*p_hte; 682 - lenmt&=0xF; 683 - 684 - /* Now perform the copy using a half unrolled loop. */ 685 - *p_dst++=*p++; 686 - *p_dst++=*p++; 687 - *p_dst++=*p++; 688 - while (lenmt--) 689 - *p_dst++=*p++; 690 - 691 - /* Because we have just received 3 or more bytes in a copy item */ 692 - /* (whose bytes we have just installed in the output), we are now */ 693 - /* in a position to flush all the pending literal hashings that had */ 694 - /* been postponed for lack of bytes. */ 695 - if (literals>0) 696 - { 697 - register UBYTE *r=p_ziv-literals; 698 - hash[HASH(r)]=r; 699 - if (literals==2) 700 - {r++; hash[HASH(r)]=r;} 701 - literals=0; 702 - } 703 - 704 - /* In any case, we can immediately update the hash table with the */ 705 - /* current position. We don't need to do a HASH(...) to work out */ 706 - /* where to put the pointer, as the compressor just told us!!! */ 707 - *p_hte=p_ziv; 708 - 709 - } 710 - else 711 - { 712 - /* Literal item. */ 713 - 714 - /* Copy over the literal byte. */ 715 - *p_dst++=*p_src++; 716 - 717 - /* If we now have three literals waiting to be hashed into the hash */ 718 - /* table, we can do one of them now (because there are three). */ 719 - if (++literals == 3) 720 - {register UBYTE *p=p_dst-3; hash[HASH(p)]=p; literals=2;} 721 - } 722 - 723 - /* Shift the control buffer so the next control bit is in bit 0. */ 724 - control>>=1; 725 - #if 1 726 - if (p_dst > p_dst_post) 727 - { 728 - /* Shit: we tried to decompress corrupt data */ 729 - *p_dst_len = 0; 730 - return; 731 - } 732 - #endif 733 - } /* End unrolled inner loop. */ 734 - 735 - } /* End of outer loop */ 736 - 737 - /* Write the length of the decompressed data before returning. */ 738 - *p_dst_len=p_dst-p_dst_first; 739 - } 740 - 741 - /******************************************************************************/ 742 - /* End of LZRW3.C */ 743 - /******************************************************************************/
-253
drivers/char/ftape/compressor/lzrw3.h
··· 1 - #ifndef _LZRW3_H 2 - #define _LZRW3_H 3 - /* 4 - * $Source: /homes/cvs/ftape-stacked/ftape/compressor/lzrw3.h,v $ 5 - * $Revision: 1.1 $ 6 - * $Date: 1997/10/05 19:12:30 $ 7 - * 8 - * include files for lzrw3. Only slighty modified from the original 9 - * version. Assembles the three include files compress.h, port.h and 10 - * fastcopy.h from the original lzrw3 package. 11 - * 12 - */ 13 - 14 - #include <linux/types.h> 15 - #include <linux/string.h> 16 - 17 - /******************************************************************************/ 18 - /* */ 19 - /* COMPRESS.H */ 20 - /* */ 21 - /******************************************************************************/ 22 - /* */ 23 - /* Author : Ross Williams. */ 24 - /* Date : December 1989. */ 25 - /* */ 26 - /* This header file defines the interface to a set of functions called */ 27 - /* 'compress', each member of which implements a particular data compression */ 28 - /* algorithm. */ 29 - /* */ 30 - /* Normally in C programming, for each .H file, there is a corresponding .C */ 31 - /* file that implements the functions promised in the .H file. */ 32 - /* Here, there are many .C files corresponding to this header file. */ 33 - /* Each comforming implementation file contains a single function */ 34 - /* called 'compress' that implements a single data compression */ 35 - /* algorithm that conforms with the interface specified in this header file. */ 36 - /* Only one algorithm can be linked in at a time in this organization. */ 37 - /* */ 38 - /******************************************************************************/ 39 - /* */ 40 - /* DEFINITION OF FUNCTION COMPRESS */ 41 - /* =============================== */ 42 - /* */ 43 - /* Summary of Function Compress */ 44 - /* ---------------------------- */ 45 - /* The action that 'compress' takes depends on its first argument called */ 46 - /* 'action'. The function provides three actions: */ 47 - /* */ 48 - /* - Return information about the algorithm. */ 49 - /* - Compress a block of memory. */ 50 - /* - Decompress a block of memory. */ 51 - /* */ 52 - /* Parameters */ 53 - /* ---------- */ 54 - /* See the formal C definition later for a description of the parameters. */ 55 - /* */ 56 - /* Constants */ 57 - /* --------- */ 58 - /* COMPRESS_OVERRUN: The constant COMPRESS_OVERRUN defines by how many bytes */ 59 - /* an algorithm is allowed to expand a block during a compression operation. */ 60 - /* */ 61 - /* Although compression algorithms usually compress data, there will always */ 62 - /* be data that a given compressor will expand (this can be proven). */ 63 - /* Fortunately, the degree of expansion can be limited to a single bit, by */ 64 - /* copying over the input data if the data gets bigger during compression. */ 65 - /* To allow for this possibility, the first bit of a compressed */ 66 - /* representation can be used as a flag indicating whether the */ 67 - /* input data was copied over, or truly compressed. In practice, the first */ 68 - /* byte would be used to store this bit so as to maintain byte alignment. */ 69 - /* */ 70 - /* Unfortunately, in general, the only way to tell if an algorithm will */ 71 - /* expand a particular block of data is to run the algorithm on the data. */ 72 - /* If the algorithm does not continuously monitor how many output bytes it */ 73 - /* has written, it might write an output block far larger than the input */ 74 - /* block before realizing that it has done so. */ 75 - /* On the other hand, continuous checks on output length are inefficient. */ 76 - /* */ 77 - /* To cater for all these problems, this interface definition: */ 78 - /* > Allows a compression algorithm to return an output block that is up to */ 79 - /* COMPRESS_OVERRUN bytes longer than the input block. */ 80 - /* > Allows a compression algorithm to write up to COMPRESS_OVERRUN bytes */ 81 - /* more than the length of the input block to the memory of the output */ 82 - /* block regardless of the length of the output block eventually returned. */ 83 - /* This allows an algorithm to overrun the length of the input block in the */ 84 - /* output block by up to COMPRESS_OVERRUN bytes between expansion checks. */ 85 - /* */ 86 - /* The problem does not arise for decompression. */ 87 - /* */ 88 - /* Identity Action */ 89 - /* --------------- */ 90 - /* > action must be COMPRESS_ACTION_IDENTITY. */ 91 - /* > p_dst_len must point to a longword to receive a longword address. */ 92 - /* > The value of the other parameters does not matter. */ 93 - /* > After execution, the longword that p_dst_len points to will be a pointer */ 94 - /* to a structure of type compress_identity. */ 95 - /* Thus, for example, after the call, (*p_dst_len)->memory will return the */ 96 - /* number of bytes of working memory that the algorithm requires to run. */ 97 - /* > The values of the identity structure returned are fixed constant */ 98 - /* attributes of the algorithm and must not vary from call to call. */ 99 - /* */ 100 - /* Common Requirements for Compression and Decompression Actions */ 101 - /* ------------------------------------------------------------- */ 102 - /* > wrk_mem must point to an unused block of memory of a length specified in */ 103 - /* the algorithm's identity block. The identity block can be obtained by */ 104 - /* making a separate call to compress, specifying the identity action. */ 105 - /* > The INPUT BLOCK is defined to be Memory[src_addr,src_addr+src_len-1]. */ 106 - /* > dst_len will be used to denote *p_dst_len. */ 107 - /* > dst_len is not read by compress, only written. */ 108 - /* > The value of dst_len is defined only upon termination. */ 109 - /* > The OUTPUT BLOCK is defined to be Memory[dst_addr,dst_addr+dst_len-1]. */ 110 - /* */ 111 - /* Compression Action */ 112 - /* ------------------ */ 113 - /* > action must be COMPRESS_ACTION_COMPRESS. */ 114 - /* > src_len must be in the range [0,COMPRESS_MAX_ORG]. */ 115 - /* > The OUTPUT ZONE is defined to be */ 116 - /* Memory[dst_addr,dst_addr+src_len-1+COMPRESS_OVERRUN]. */ 117 - /* > The function can modify any part of the output zone regardless of the */ 118 - /* final length of the output block. */ 119 - /* > The input block and the output zone must not overlap. */ 120 - /* > dst_len will be in the range [0,src_len+COMPRESS_OVERRUN]. */ 121 - /* > dst_len will be in the range [0,COMPRESS_MAX_COM] (from prev fact). */ 122 - /* > The output block will consist of a representation of the input block. */ 123 - /* */ 124 - /* Decompression Action */ 125 - /* -------------------- */ 126 - /* > action must be COMPRESS_ACTION_DECOMPRESS. */ 127 - /* > The input block must be the result of an earlier compression operation. */ 128 - /* > If the previous fact is true, the following facts must also be true: */ 129 - /* > src_len will be in the range [0,COMPRESS_MAX_COM]. */ 130 - /* > dst_len will be in the range [0,COMPRESS_MAX_ORG]. */ 131 - /* > The input and output blocks must not overlap. */ 132 - /* > Only the output block is modified. */ 133 - /* > Upon termination, the output block will consist of the bytes contained */ 134 - /* in the input block passed to the earlier compression operation. */ 135 - /* */ 136 - /******************************************************************************/ 137 - 138 - /******************************************************************************/ 139 - /* */ 140 - /* PORT.H */ 141 - /* */ 142 - /******************************************************************************/ 143 - /* */ 144 - /* This module contains macro definitions and types that are likely to */ 145 - /* change between computers. */ 146 - /* */ 147 - /******************************************************************************/ 148 - 149 - #ifndef DONE_PORT /* Only do this if not previously done. */ 150 - 151 - #ifdef THINK_C 152 - #define UBYTE unsigned char /* Unsigned byte */ 153 - #define UWORD unsigned int /* Unsigned word (2 bytes) */ 154 - #define ULONG unsigned long /* Unsigned word (4 bytes) */ 155 - #define BOOL unsigned char /* Boolean */ 156 - #define FOPEN_BINARY_READ "rb" /* Mode string for binary reading. */ 157 - #define FOPEN_BINARY_WRITE "wb" /* Mode string for binary writing. */ 158 - #define FOPEN_TEXT_APPEND "a" /* Mode string for text appending. */ 159 - #define REAL double /* USed for floating point stuff. */ 160 - #endif 161 - #if defined(LINUX) || defined(linux) 162 - #define UBYTE __u8 /* Unsigned byte */ 163 - #define UWORD __u16 /* Unsigned word (2 bytes) */ 164 - #define ULONG __u32 /* Unsigned word (4 bytes) */ 165 - #define LONG __s32 /* Signed word (4 bytes) */ 166 - #define BOOL is not used here /* Boolean */ 167 - #define FOPEN_BINARY_READ not used /* Mode string for binary reading. */ 168 - #define FOPEN_BINARY_WRITE not used /* Mode string for binary writing. */ 169 - #define FOPEN_TEXT_APPEND not used /* Mode string for text appending. */ 170 - #define REAL not used /* USed for floating point stuff. */ 171 - #ifndef TRUE 172 - #define TRUE 1 173 - #endif 174 - #endif 175 - 176 - #define DONE_PORT /* Don't do all this again. */ 177 - #define MALLOC_FAIL NULL /* Failure status from malloc() */ 178 - #define LOCAL static /* For non-exported routines. */ 179 - #define EXPORT /* Signals exported function. */ 180 - #define then /* Useful for aligning ifs. */ 181 - 182 - #endif 183 - 184 - /******************************************************************************/ 185 - /* End of PORT.H */ 186 - /******************************************************************************/ 187 - 188 - #define COMPRESS_ACTION_IDENTITY 0 189 - #define COMPRESS_ACTION_COMPRESS 1 190 - #define COMPRESS_ACTION_DECOMPRESS 2 191 - 192 - #define COMPRESS_OVERRUN 1024 193 - #define COMPRESS_MAX_COM 0x70000000 194 - #define COMPRESS_MAX_ORG (COMPRESS_MAX_COM-COMPRESS_OVERRUN) 195 - 196 - #define COMPRESS_MAX_STRLEN 255 197 - 198 - /* The following structure provides information about the algorithm. */ 199 - /* > The top bit of id must be zero. The remaining bits must be chosen by */ 200 - /* the author of the algorithm by tossing a coin 31 times. */ 201 - /* > The amount of memory requested by the algorithm is specified in bytes */ 202 - /* and must be in the range [0,0x70000000]. */ 203 - /* > All strings s must be such that strlen(s)<=COMPRESS_MAX_STRLEN. */ 204 - struct compress_identity 205 - { 206 - ULONG id; /* Identifying number of algorithm. */ 207 - ULONG memory; /* Number of bytes of working memory required. */ 208 - 209 - char *name; /* Name of algorithm. */ 210 - char *version; /* Version number. */ 211 - char *date; /* Date of release of this version. */ 212 - char *copyright; /* Copyright message. */ 213 - 214 - char *author; /* Author of algorithm. */ 215 - char *affiliation; /* Affiliation of author. */ 216 - char *vendor; /* Where the algorithm can be obtained. */ 217 - }; 218 - 219 - void lzrw3_compress( /* Single function interface to compression algorithm. */ 220 - UWORD action, /* Action to be performed. */ 221 - UBYTE *wrk_mem, /* Working memory temporarily given to routine to use. */ 222 - UBYTE *src_adr, /* Address of input data. */ 223 - LONG src_len, /* Length of input data. */ 224 - UBYTE *dst_adr, /* Address of output data. */ 225 - void *p_dst_len /* Pointer to a longword where routine will write: */ 226 - /* If action=..IDENTITY => Adr of id structure. */ 227 - /* If action=..COMPRESS => Length of output data. */ 228 - /* If action=..DECOMPRESS => Length of output data. */ 229 - ); 230 - 231 - /******************************************************************************/ 232 - /* End of COMPRESS.H */ 233 - /******************************************************************************/ 234 - 235 - 236 - /******************************************************************************/ 237 - /* fast_copy.h */ 238 - /******************************************************************************/ 239 - 240 - /* This function copies a block of memory very quickly. */ 241 - /* The exact speed depends on the relative alignment of the blocks of memory. */ 242 - /* PRE : 0<=src_len<=(2^32)-1 . */ 243 - /* PRE : Source and destination blocks must not overlap. */ 244 - /* POST : MEM[dst_adr,dst_adr+src_len-1]=MEM[src_adr,src_adr+src_len-1]. */ 245 - /* POST : MEM[dst_adr,dst_adr+src_len-1] is the only memory changed. */ 246 - 247 - #define fast_copy(src,dst,len) memcpy(dst,src,len) 248 - 249 - /******************************************************************************/ 250 - /* End of fast_copy.h */ 251 - /******************************************************************************/ 252 - 253 - #endif
-1203
drivers/char/ftape/compressor/zftape-compress.c
··· 1 - /* 2 - * Copyright (C) 1994-1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or 5 - modify it under the terms of the GNU General Public License as 6 - published by the Free Software Foundation; either version 2, or (at 7 - your option) any later version. 8 - 9 - This program is distributed in the hope that it will be useful, but 10 - WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 - General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 17 - USA. 18 - 19 - * 20 - * This file implements a "generic" interface between the * 21 - * zftape-driver and a compression-algorithm. The * 22 - * compression-algorithm currently used is a LZ77. I use the * 23 - * implementation lzrw3 by Ross N. Williams (Renaissance * 24 - * Software). The compression program itself is in the file 25 - * lzrw3.c * and lzrw3.h. To adopt another compression algorithm 26 - * the functions * zft_compress() and zft_uncompress() must be 27 - * changed * appropriately. See below. 28 - */ 29 - 30 - #include <linux/errno.h> 31 - #include <linux/mm.h> 32 - #include <linux/module.h> 33 - 34 - #include <linux/zftape.h> 35 - 36 - #include <asm/uaccess.h> 37 - 38 - #include "../zftape/zftape-init.h" 39 - #include "../zftape/zftape-eof.h" 40 - #include "../zftape/zftape-ctl.h" 41 - #include "../zftape/zftape-write.h" 42 - #include "../zftape/zftape-read.h" 43 - #include "../zftape/zftape-rw.h" 44 - #include "../compressor/zftape-compress.h" 45 - #include "../zftape/zftape-vtbl.h" 46 - #include "../compressor/lzrw3.h" 47 - 48 - /* 49 - * global variables 50 - */ 51 - 52 - /* I handle the allocation of this buffer as a special case, because 53 - * it's size varies depending on the tape length inserted. 54 - */ 55 - 56 - /* local variables 57 - */ 58 - static void *zftc_wrk_mem = NULL; 59 - static __u8 *zftc_buf = NULL; 60 - static void *zftc_scratch_buf = NULL; 61 - 62 - /* compression statistics 63 - */ 64 - static unsigned int zftc_wr_uncompressed = 0; 65 - static unsigned int zftc_wr_compressed = 0; 66 - static unsigned int zftc_rd_uncompressed = 0; 67 - static unsigned int zftc_rd_compressed = 0; 68 - 69 - /* forward */ 70 - static int zftc_write(int *write_cnt, 71 - __u8 *dst_buf, const int seg_sz, 72 - const __u8 __user *src_buf, const int req_len, 73 - const zft_position *pos, const zft_volinfo *volume); 74 - static int zftc_read(int *read_cnt, 75 - __u8 __user *dst_buf, const int to_do, 76 - const __u8 *src_buf, const int seg_sz, 77 - const zft_position *pos, const zft_volinfo *volume); 78 - static int zftc_seek(unsigned int new_block_pos, 79 - zft_position *pos, const zft_volinfo *volume, 80 - __u8 *buffer); 81 - static void zftc_lock (void); 82 - static void zftc_reset (void); 83 - static void zftc_cleanup(void); 84 - static void zftc_stats (void); 85 - 86 - /* compressed segment. This conforms to QIC-80-MC, Revision K. 87 - * 88 - * Rev. K applies to tapes with `fixed length format' which is 89 - * indicated by format code 2,3 and 5. See below for format code 4 and 6 90 - * 91 - * 2 bytes: offset of compression segment structure 92 - * 29k > offset >= 29k-18: data from previous segment ens in this 93 - * segment and no compressed block starts 94 - * in this segment 95 - * offset == 0: data from previous segment occupies entire 96 - * segment and continues in next segment 97 - * n bytes: remainder from previous segment 98 - * 99 - * Rev. K: 100 - * 4 bytes: 4 bytes: files set byte offset 101 - * Post Rev. K and QIC-3020/3020: 102 - * 8 bytes: 8 bytes: files set byte offset 103 - * 2 bytes: byte count N (amount of data following) 104 - * bit 15 is set if data is compressed, bit 15 is not 105 - * set if data is uncompressed 106 - * N bytes: data (as much as specified in the byte count) 107 - * 2 bytes: byte count N_1 of next cluster 108 - * N_1 bytes: data of next cluset 109 - * 2 bytes: byte count N_2 of next cluster 110 - * N_2 bytes: ... 111 - * 112 - * Note that the `N' byte count accounts only for the bytes that in the 113 - * current segment if the cluster spans to the next segment. 114 - */ 115 - 116 - typedef struct 117 - { 118 - int cmpr_pos; /* actual position in compression buffer */ 119 - int cmpr_sz; /* what is left in the compression buffer 120 - * when copying the compressed data to the 121 - * deblock buffer 122 - */ 123 - unsigned int first_block; /* location of header information in 124 - * this segment 125 - */ 126 - unsigned int count; /* amount of data of current block 127 - * contained in current segment 128 - */ 129 - unsigned int offset; /* offset in current segment */ 130 - unsigned int spans:1; /* might continue in next segment */ 131 - unsigned int uncmpr; /* 0x8000 if this block contains 132 - * uncompressed data 133 - */ 134 - __s64 foffs; /* file set byte offset, same as in 135 - * compression map segment 136 - */ 137 - } cmpr_info; 138 - 139 - static cmpr_info cseg; /* static data. Must be kept uptodate and shared by 140 - * read, write and seek functions 141 - */ 142 - 143 - #define DUMP_CMPR_INFO(level, msg, info) \ 144 - TRACE(level, msg "\n" \ 145 - KERN_INFO "cmpr_pos : %d\n" \ 146 - KERN_INFO "cmpr_sz : %d\n" \ 147 - KERN_INFO "first_block: %d\n" \ 148 - KERN_INFO "count : %d\n" \ 149 - KERN_INFO "offset : %d\n" \ 150 - KERN_INFO "spans : %d\n" \ 151 - KERN_INFO "uncmpr : 0x%04x\n" \ 152 - KERN_INFO "foffs : " LL_X, \ 153 - (info)->cmpr_pos, (info)->cmpr_sz, (info)->first_block, \ 154 - (info)->count, (info)->offset, (info)->spans == 1, \ 155 - (info)->uncmpr, LL((info)->foffs)) 156 - 157 - /* dispatch compression segment info, return error code 158 - * 159 - * afterwards, cseg->offset points to start of data of the NEXT 160 - * compressed block, and cseg->count contains the amount of data 161 - * left in the actual compressed block. cseg->spans is set to 1 if 162 - * the block is continued in the following segment. Otherwise it is 163 - * set to 0. 164 - */ 165 - static int get_cseg (cmpr_info *cinfo, const __u8 *buff, 166 - const unsigned int seg_sz, 167 - const zft_volinfo *volume) 168 - { 169 - TRACE_FUN(ft_t_flow); 170 - 171 - cinfo->first_block = GET2(buff, 0); 172 - if (cinfo->first_block == 0) { /* data spans to next segment */ 173 - cinfo->count = seg_sz - sizeof(__u16); 174 - cinfo->offset = seg_sz; 175 - cinfo->spans = 1; 176 - } else { /* cluster definetely ends in this segment */ 177 - if (cinfo->first_block > seg_sz) { 178 - /* data corrupted */ 179 - TRACE_ABORT(-EIO, ft_t_err, "corrupted data:\n" 180 - KERN_INFO "segment size: %d\n" 181 - KERN_INFO "first block : %d", 182 - seg_sz, cinfo->first_block); 183 - } 184 - cinfo->count = cinfo->first_block - sizeof(__u16); 185 - cinfo->offset = cinfo->first_block; 186 - cinfo->spans = 0; 187 - } 188 - /* now get the offset the first block should have in the 189 - * uncompressed data stream. 190 - * 191 - * For this magic `18' refer to CRF-3 standard or QIC-80MC, 192 - * Rev. K. 193 - */ 194 - if ((seg_sz - cinfo->offset) > 18) { 195 - if (volume->qic113) { /* > revision K */ 196 - TRACE(ft_t_data_flow, "New QIC-113 compliance"); 197 - cinfo->foffs = GET8(buff, cinfo->offset); 198 - cinfo->offset += sizeof(__s64); 199 - } else { 200 - TRACE(/* ft_t_data_flow */ ft_t_noise, "pre QIC-113 version"); 201 - cinfo->foffs = (__s64)GET4(buff, cinfo->offset); 202 - cinfo->offset += sizeof(__u32); 203 - } 204 - } 205 - if (cinfo->foffs > volume->size) { 206 - TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n" 207 - KERN_INFO "offset in current volume: %d\n" 208 - KERN_INFO "size of current volume : %d", 209 - (int)(cinfo->foffs>>10), (int)(volume->size>>10)); 210 - } 211 - if (cinfo->cmpr_pos + cinfo->count > volume->blk_sz) { 212 - TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n" 213 - KERN_INFO "block size : %d\n" 214 - KERN_INFO "data record: %d", 215 - volume->blk_sz, cinfo->cmpr_pos + cinfo->count); 216 - } 217 - DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", cinfo); 218 - TRACE_EXIT 0; 219 - } 220 - 221 - /* This one is called, when a new cluster starts in same segment. 222 - * 223 - * Note: if this is the first cluster in the current segment, we must 224 - * not check whether there are more than 18 bytes available because 225 - * this have already been done in get_cseg() and there may be less 226 - * than 18 bytes available due to header information. 227 - * 228 - */ 229 - static void get_next_cluster(cmpr_info *cluster, const __u8 *buff, 230 - const int seg_sz, const int finish) 231 - { 232 - TRACE_FUN(ft_t_flow); 233 - 234 - if (seg_sz - cluster->offset > 18 || cluster->foffs != 0) { 235 - cluster->count = GET2(buff, cluster->offset); 236 - cluster->uncmpr = cluster->count & 0x8000; 237 - cluster->count -= cluster->uncmpr; 238 - cluster->offset += sizeof(__u16); 239 - cluster->foffs = 0; 240 - if ((cluster->offset + cluster->count) < seg_sz) { 241 - cluster->spans = 0; 242 - } else if (cluster->offset + cluster->count == seg_sz) { 243 - cluster->spans = !finish; 244 - } else { 245 - /* either an error or a volume written by an 246 - * old version. If this is a data error, then we'll 247 - * catch it later. 248 - */ 249 - TRACE(ft_t_data_flow, "Either error or old volume"); 250 - cluster->spans = 1; 251 - cluster->count = seg_sz - cluster->offset; 252 - } 253 - } else { 254 - cluster->count = 0; 255 - cluster->spans = 0; 256 - cluster->foffs = 0; 257 - } 258 - DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */ , "", cluster); 259 - TRACE_EXIT; 260 - } 261 - 262 - static void zftc_lock(void) 263 - { 264 - } 265 - 266 - /* this function is needed for zftape_reset_position in zftape-io.c 267 - */ 268 - static void zftc_reset(void) 269 - { 270 - TRACE_FUN(ft_t_flow); 271 - 272 - memset((void *)&cseg, '\0', sizeof(cseg)); 273 - zftc_stats(); 274 - TRACE_EXIT; 275 - } 276 - 277 - static int cmpr_mem_initialized = 0; 278 - static unsigned int alloc_blksz = 0; 279 - 280 - static int zft_allocate_cmpr_mem(unsigned int blksz) 281 - { 282 - TRACE_FUN(ft_t_flow); 283 - 284 - if (cmpr_mem_initialized && blksz == alloc_blksz) { 285 - TRACE_EXIT 0; 286 - } 287 - TRACE_CATCH(zft_vmalloc_once(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE), 288 - zftc_cleanup()); 289 - TRACE_CATCH(zft_vmalloc_always(&zftc_buf, blksz + CMPR_OVERRUN), 290 - zftc_cleanup()); 291 - alloc_blksz = blksz; 292 - TRACE_CATCH(zft_vmalloc_always(&zftc_scratch_buf, blksz+CMPR_OVERRUN), 293 - zftc_cleanup()); 294 - cmpr_mem_initialized = 1; 295 - TRACE_EXIT 0; 296 - } 297 - 298 - static void zftc_cleanup(void) 299 - { 300 - TRACE_FUN(ft_t_flow); 301 - 302 - zft_vfree(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE); 303 - zft_vfree(&zftc_buf, alloc_blksz + CMPR_OVERRUN); 304 - zft_vfree(&zftc_scratch_buf, alloc_blksz + CMPR_OVERRUN); 305 - cmpr_mem_initialized = alloc_blksz = 0; 306 - TRACE_EXIT; 307 - } 308 - 309 - /***************************************************************************** 310 - * * 311 - * The following two functions "ftape_compress()" and * 312 - * "ftape_uncompress()" are the interface to the actual compression * 313 - * algorithm (i.e. they are calling the "compress()" function from * 314 - * the lzrw3 package for now). These routines could quite easily be * 315 - * changed to adopt another compression algorithm instead of lzrw3, * 316 - * which currently is used. * 317 - * * 318 - *****************************************************************************/ 319 - 320 - /* called by zft_compress_write() to perform the compression. Must 321 - * return the size of the compressed data. 322 - * 323 - * NOTE: The size of the compressed data should not exceed the size of 324 - * the uncompressed data. Most compression algorithms have means 325 - * to store data unchanged if the "compressed" data amount would 326 - * exceed the original one. Mostly this is done by storing some 327 - * flag-bytes in front of the compressed data to indicate if it 328 - * is compressed or not. Thus the worst compression result 329 - * length is the original length plus those flag-bytes. 330 - * 331 - * We don't want that, as the QIC-80 standard provides a means 332 - * of marking uncompressed blocks by simply setting bit 15 of 333 - * the compressed block's length. Thus a compessed block can 334 - * have at most a length of 2^15-1 bytes. The QIC-80 standard 335 - * restricts the block-length even further, allowing only 29k - 336 - * 6 bytes. 337 - * 338 - * Currently, the maximum blocksize used by zftape is 28k. 339 - * 340 - * In short: don't exceed the length of the input-package, set 341 - * bit 15 of the compressed size to 1 if you have copied data 342 - * instead of compressing it. 343 - */ 344 - static int zft_compress(__u8 *in_buffer, unsigned int in_sz, __u8 *out_buffer) 345 - { 346 - __s32 compressed_sz; 347 - TRACE_FUN(ft_t_flow); 348 - 349 - 350 - lzrw3_compress(COMPRESS_ACTION_COMPRESS, zftc_wrk_mem, 351 - in_buffer, in_sz, out_buffer, &compressed_sz); 352 - if (TRACE_LEVEL >= ft_t_info) { 353 - /* the compiler will optimize this away when 354 - * compiled with NO_TRACE_AT_ALL option 355 - */ 356 - TRACE(ft_t_data_flow, "\n" 357 - KERN_INFO "before compression: %d bytes\n" 358 - KERN_INFO "after compresison : %d bytes", 359 - in_sz, 360 - (int)(compressed_sz < 0 361 - ? -compressed_sz : compressed_sz)); 362 - /* for statistical purposes 363 - */ 364 - zftc_wr_compressed += (compressed_sz < 0 365 - ? -compressed_sz : compressed_sz); 366 - zftc_wr_uncompressed += in_sz; 367 - } 368 - TRACE_EXIT (int)compressed_sz; 369 - } 370 - 371 - /* called by zft_compress_read() to decompress the data. Must 372 - * return the size of the decompressed data for sanity checks 373 - * (compared with zft_blk_sz) 374 - * 375 - * NOTE: Read the note for zft_compress() above! If bit 15 of the 376 - * parameter in_sz is set, then the data in in_buffer isn't 377 - * compressed, which must be handled by the un-compression 378 - * algorithm. (I changed lzrw3 to handle this.) 379 - * 380 - * The parameter max_out_sz is needed to prevent buffer overruns when 381 - * uncompressing corrupt data. 382 - */ 383 - static unsigned int zft_uncompress(__u8 *in_buffer, 384 - int in_sz, 385 - __u8 *out_buffer, 386 - unsigned int max_out_sz) 387 - { 388 - TRACE_FUN(ft_t_flow); 389 - 390 - lzrw3_compress(COMPRESS_ACTION_DECOMPRESS, zftc_wrk_mem, 391 - in_buffer, (__s32)in_sz, 392 - out_buffer, (__u32 *)&max_out_sz); 393 - 394 - if (TRACE_LEVEL >= ft_t_info) { 395 - TRACE(ft_t_data_flow, "\n" 396 - KERN_INFO "before decompression: %d bytes\n" 397 - KERN_INFO "after decompression : %d bytes", 398 - in_sz < 0 ? -in_sz : in_sz,(int)max_out_sz); 399 - /* for statistical purposes 400 - */ 401 - zftc_rd_compressed += in_sz < 0 ? -in_sz : in_sz; 402 - zftc_rd_uncompressed += max_out_sz; 403 - } 404 - TRACE_EXIT (unsigned int)max_out_sz; 405 - } 406 - 407 - /* print some statistics about the efficiency of the compression to 408 - * the kernel log 409 - */ 410 - static void zftc_stats(void) 411 - { 412 - TRACE_FUN(ft_t_flow); 413 - 414 - if (TRACE_LEVEL < ft_t_info) { 415 - TRACE_EXIT; 416 - } 417 - if (zftc_wr_uncompressed != 0) { 418 - if (zftc_wr_compressed > (1<<14)) { 419 - TRACE(ft_t_info, "compression statistics (writing):\n" 420 - KERN_INFO " compr./uncmpr. : %3d %%", 421 - (((zftc_wr_compressed>>10) * 100) 422 - / (zftc_wr_uncompressed>>10))); 423 - } else { 424 - TRACE(ft_t_info, "compression statistics (writing):\n" 425 - KERN_INFO " compr./uncmpr. : %3d %%", 426 - ((zftc_wr_compressed * 100) 427 - / zftc_wr_uncompressed)); 428 - } 429 - } 430 - if (zftc_rd_uncompressed != 0) { 431 - if (zftc_rd_compressed > (1<<14)) { 432 - TRACE(ft_t_info, "compression statistics (reading):\n" 433 - KERN_INFO " compr./uncmpr. : %3d %%", 434 - (((zftc_rd_compressed>>10) * 100) 435 - / (zftc_rd_uncompressed>>10))); 436 - } else { 437 - TRACE(ft_t_info, "compression statistics (reading):\n" 438 - KERN_INFO " compr./uncmpr. : %3d %%", 439 - ((zftc_rd_compressed * 100) 440 - / zftc_rd_uncompressed)); 441 - } 442 - } 443 - /* only print it once: */ 444 - zftc_wr_uncompressed = 445 - zftc_wr_compressed = 446 - zftc_rd_uncompressed = 447 - zftc_rd_compressed = 0; 448 - TRACE_EXIT; 449 - } 450 - 451 - /* start new compressed block 452 - */ 453 - static int start_new_cseg(cmpr_info *cluster, 454 - char *dst_buf, 455 - const zft_position *pos, 456 - const unsigned int blk_sz, 457 - const char *src_buf, 458 - const int this_segs_sz, 459 - const int qic113) 460 - { 461 - int size_left; 462 - int cp_cnt; 463 - int buf_pos; 464 - TRACE_FUN(ft_t_flow); 465 - 466 - size_left = this_segs_sz - sizeof(__u16) - cluster->cmpr_sz; 467 - TRACE(ft_t_data_flow,"\n" 468 - KERN_INFO "segment size : %d\n" 469 - KERN_INFO "compressed_sz: %d\n" 470 - KERN_INFO "size_left : %d", 471 - this_segs_sz, cluster->cmpr_sz, size_left); 472 - if (size_left > 18) { /* start a new cluseter */ 473 - cp_cnt = cluster->cmpr_sz; 474 - cluster->cmpr_sz = 0; 475 - buf_pos = cp_cnt + sizeof(__u16); 476 - PUT2(dst_buf, 0, buf_pos); 477 - 478 - if (qic113) { 479 - __s64 foffs = pos->volume_pos; 480 - if (cp_cnt) foffs += (__s64)blk_sz; 481 - 482 - TRACE(ft_t_data_flow, "new style QIC-113 header"); 483 - PUT8(dst_buf, buf_pos, foffs); 484 - buf_pos += sizeof(__s64); 485 - } else { 486 - __u32 foffs = (__u32)pos->volume_pos; 487 - if (cp_cnt) foffs += (__u32)blk_sz; 488 - 489 - TRACE(ft_t_data_flow, "old style QIC-80MC header"); 490 - PUT4(dst_buf, buf_pos, foffs); 491 - buf_pos += sizeof(__u32); 492 - } 493 - } else if (size_left >= 0) { 494 - cp_cnt = cluster->cmpr_sz; 495 - cluster->cmpr_sz = 0; 496 - buf_pos = cp_cnt + sizeof(__u16); 497 - PUT2(dst_buf, 0, buf_pos); 498 - /* zero unused part of segment. */ 499 - memset(dst_buf + buf_pos, '\0', size_left); 500 - buf_pos = this_segs_sz; 501 - } else { /* need entire segment and more space */ 502 - PUT2(dst_buf, 0, 0); 503 - cp_cnt = this_segs_sz - sizeof(__u16); 504 - cluster->cmpr_sz -= cp_cnt; 505 - buf_pos = this_segs_sz; 506 - } 507 - memcpy(dst_buf + sizeof(__u16), src_buf + cluster->cmpr_pos, cp_cnt); 508 - cluster->cmpr_pos += cp_cnt; 509 - TRACE_EXIT buf_pos; 510 - } 511 - 512 - /* return-value: the number of bytes removed from the user-buffer 513 - * `src_buf' or error code 514 - * 515 - * int *write_cnt : how much actually has been moved to the 516 - * dst_buf. Need not be initialized when 517 - * function returns with an error code 518 - * (negativ return value) 519 - * __u8 *dst_buf : kernel space buffer where the has to be 520 - * copied to. The contents of this buffers 521 - * goes to a specific segment. 522 - * const int seg_sz : the size of the segment dst_buf will be 523 - * copied to. 524 - * const zft_position *pos : struct containing the coordinates in 525 - * the current volume (byte position, 526 - * segment id of current segment etc) 527 - * const zft_volinfo *volume: information about the current volume, 528 - * size etc. 529 - * const __u8 *src_buf : user space buffer that contains the 530 - * data the user wants to be written to 531 - * tape. 532 - * const int req_len : the amount of data the user wants to be 533 - * written to tape. 534 - */ 535 - static int zftc_write(int *write_cnt, 536 - __u8 *dst_buf, const int seg_sz, 537 - const __u8 __user *src_buf, const int req_len, 538 - const zft_position *pos, const zft_volinfo *volume) 539 - { 540 - int req_len_left = req_len; 541 - int result; 542 - int len_left; 543 - int buf_pos_write = pos->seg_byte_pos; 544 - TRACE_FUN(ft_t_flow); 545 - 546 - /* Note: we do not unlock the module because 547 - * there are some values cached in that `cseg' variable. We 548 - * don't don't want to use this information when being 549 - * unloaded by kerneld even when the tape is full or when we 550 - * cannot allocate enough memory. 551 - */ 552 - if (pos->tape_pos > (volume->size-volume->blk_sz-ZFT_CMPR_OVERHEAD)) { 553 - TRACE_EXIT -ENOSPC; 554 - } 555 - if (zft_allocate_cmpr_mem(volume->blk_sz) < 0) { 556 - /* should we unlock the module? But it shouldn't 557 - * be locked anyway ... 558 - */ 559 - TRACE_EXIT -ENOMEM; 560 - } 561 - if (buf_pos_write == 0) { /* fill a new segment */ 562 - *write_cnt = buf_pos_write = start_new_cseg(&cseg, 563 - dst_buf, 564 - pos, 565 - volume->blk_sz, 566 - zftc_buf, 567 - seg_sz, 568 - volume->qic113); 569 - if (cseg.cmpr_sz == 0 && cseg.cmpr_pos != 0) { 570 - req_len_left -= result = volume->blk_sz; 571 - cseg.cmpr_pos = 0; 572 - } else { 573 - result = 0; 574 - } 575 - } else { 576 - *write_cnt = result = 0; 577 - } 578 - 579 - len_left = seg_sz - buf_pos_write; 580 - while ((req_len_left > 0) && (len_left > 18)) { 581 - /* now we have some size left for a new compressed 582 - * block. We know, that the compression buffer is 583 - * empty (else there wouldn't be any space left). 584 - */ 585 - if (copy_from_user(zftc_scratch_buf, src_buf + result, 586 - volume->blk_sz) != 0) { 587 - TRACE_EXIT -EFAULT; 588 - } 589 - req_len_left -= volume->blk_sz; 590 - cseg.cmpr_sz = zft_compress(zftc_scratch_buf, volume->blk_sz, 591 - zftc_buf); 592 - if (cseg.cmpr_sz < 0) { 593 - cseg.uncmpr = 0x8000; 594 - cseg.cmpr_sz = -cseg.cmpr_sz; 595 - } else { 596 - cseg.uncmpr = 0; 597 - } 598 - /* increment "result" iff we copied the entire 599 - * compressed block to the zft_deblock_buf 600 - */ 601 - len_left -= sizeof(__u16); 602 - if (len_left >= cseg.cmpr_sz) { 603 - len_left -= cseg.count = cseg.cmpr_sz; 604 - cseg.cmpr_pos = cseg.cmpr_sz = 0; 605 - result += volume->blk_sz; 606 - } else { 607 - cseg.cmpr_sz -= 608 - cseg.cmpr_pos = 609 - cseg.count = len_left; 610 - len_left = 0; 611 - } 612 - PUT2(dst_buf, buf_pos_write, cseg.uncmpr | cseg.count); 613 - buf_pos_write += sizeof(__u16); 614 - memcpy(dst_buf + buf_pos_write, zftc_buf, cseg.count); 615 - buf_pos_write += cseg.count; 616 - *write_cnt += cseg.count + sizeof(__u16); 617 - FT_SIGNAL_EXIT(_DONT_BLOCK); 618 - } 619 - /* erase the remainder of the segment if less than 18 bytes 620 - * left (18 bytes is due to the QIC-80 standard) 621 - */ 622 - if (len_left <= 18) { 623 - memset(dst_buf + buf_pos_write, '\0', len_left); 624 - (*write_cnt) += len_left; 625 - } 626 - TRACE(ft_t_data_flow, "returning %d", result); 627 - TRACE_EXIT result; 628 - } 629 - 630 - /* out: 631 - * 632 - * int *read_cnt: the number of bytes we removed from the zft_deblock_buf 633 - * (result) 634 - * int *to_do : the remaining size of the read-request. 635 - * 636 - * in: 637 - * 638 - * char *buff : buff is the address of the upper part of the user 639 - * buffer, that hasn't been filled with data yet. 640 - 641 - * int buf_pos_read : copy of from _ftape_read() 642 - * int buf_len_read : copy of buf_len_rd from _ftape_read() 643 - * char *zft_deblock_buf: zft_deblock_buf 644 - * unsigned short blk_sz: the block size valid for this volume, may differ 645 - * from zft_blk_sz. 646 - * int finish: if != 0 means that this is the last segment belonging 647 - * to this volume 648 - * returns the amount of data actually copied to the user-buffer 649 - * 650 - * to_do MUST NOT SHRINK except to indicate an EOF. In this case *to_do has to 651 - * be set to 0 652 - */ 653 - static int zftc_read (int *read_cnt, 654 - __u8 __user *dst_buf, const int to_do, 655 - const __u8 *src_buf, const int seg_sz, 656 - const zft_position *pos, const zft_volinfo *volume) 657 - { 658 - int uncompressed_sz; 659 - int result = 0; 660 - int remaining = to_do; 661 - TRACE_FUN(ft_t_flow); 662 - 663 - TRACE_CATCH(zft_allocate_cmpr_mem(volume->blk_sz),); 664 - if (pos->seg_byte_pos == 0) { 665 - /* new segment just read 666 - */ 667 - TRACE_CATCH(get_cseg(&cseg, src_buf, seg_sz, volume), 668 - *read_cnt = 0); 669 - memcpy(zftc_buf + cseg.cmpr_pos, src_buf + sizeof(__u16), 670 - cseg.count); 671 - cseg.cmpr_pos += cseg.count; 672 - *read_cnt = cseg.offset; 673 - DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", &cseg); 674 - } else { 675 - *read_cnt = 0; 676 - } 677 - /* loop and uncompress until user buffer full or 678 - * deblock-buffer empty 679 - */ 680 - TRACE(ft_t_data_flow, "compressed_sz: %d, compos : %d, *read_cnt: %d", 681 - cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt); 682 - while ((cseg.spans == 0) && (remaining > 0)) { 683 - if (cseg.cmpr_pos != 0) { /* cmpr buf is not empty */ 684 - uncompressed_sz = 685 - zft_uncompress(zftc_buf, 686 - cseg.uncmpr == 0x8000 ? 687 - -cseg.cmpr_pos : cseg.cmpr_pos, 688 - zftc_scratch_buf, 689 - volume->blk_sz); 690 - if (uncompressed_sz != volume->blk_sz) { 691 - *read_cnt = 0; 692 - TRACE_ABORT(-EIO, ft_t_warn, 693 - "Uncompressed blk (%d) != blk size (%d)", 694 - uncompressed_sz, volume->blk_sz); 695 - } 696 - if (copy_to_user(dst_buf + result, 697 - zftc_scratch_buf, 698 - uncompressed_sz) != 0 ) { 699 - TRACE_EXIT -EFAULT; 700 - } 701 - remaining -= uncompressed_sz; 702 - result += uncompressed_sz; 703 - cseg.cmpr_pos = 0; 704 - } 705 - if (remaining > 0) { 706 - get_next_cluster(&cseg, src_buf, seg_sz, 707 - volume->end_seg == pos->seg_pos); 708 - if (cseg.count != 0) { 709 - memcpy(zftc_buf, src_buf + cseg.offset, 710 - cseg.count); 711 - cseg.cmpr_pos = cseg.count; 712 - cseg.offset += cseg.count; 713 - *read_cnt += cseg.count + sizeof(__u16); 714 - } else { 715 - remaining = 0; 716 - } 717 - } 718 - TRACE(ft_t_data_flow, "\n" 719 - KERN_INFO "compressed_sz: %d\n" 720 - KERN_INFO "compos : %d\n" 721 - KERN_INFO "*read_cnt : %d", 722 - cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt); 723 - } 724 - if (seg_sz - cseg.offset <= 18) { 725 - *read_cnt += seg_sz - cseg.offset; 726 - TRACE(ft_t_data_flow, "expanding read cnt to: %d", *read_cnt); 727 - } 728 - TRACE(ft_t_data_flow, "\n" 729 - KERN_INFO "segment size : %d\n" 730 - KERN_INFO "read count : %d\n" 731 - KERN_INFO "buf_pos_read : %d\n" 732 - KERN_INFO "remaining : %d", 733 - seg_sz, *read_cnt, pos->seg_byte_pos, 734 - seg_sz - *read_cnt - pos->seg_byte_pos); 735 - TRACE(ft_t_data_flow, "returning: %d", result); 736 - TRACE_EXIT result; 737 - } 738 - 739 - /* seeks to the new data-position. Reads sometimes a segment. 740 - * 741 - * start_seg and end_seg give the boundaries of the current volume 742 - * blk_sz is the blk_sz of the current volume as stored in the 743 - * volume label 744 - * 745 - * We don't allow blocksizes less than 1024 bytes, therefore we don't need 746 - * a 64 bit argument for new_block_pos. 747 - */ 748 - 749 - static int seek_in_segment(const unsigned int to_do, cmpr_info *c_info, 750 - const char *src_buf, const int seg_sz, 751 - const int seg_pos, const zft_volinfo *volume); 752 - static int slow_seek_forward_until_error(const unsigned int distance, 753 - cmpr_info *c_info, zft_position *pos, 754 - const zft_volinfo *volume, __u8 *buf); 755 - static int search_valid_segment(unsigned int segment, 756 - const unsigned int end_seg, 757 - const unsigned int max_foffs, 758 - zft_position *pos, cmpr_info *c_info, 759 - const zft_volinfo *volume, __u8 *buf); 760 - static int slow_seek_forward(unsigned int dest, cmpr_info *c_info, 761 - zft_position *pos, const zft_volinfo *volume, 762 - __u8 *buf); 763 - static int compute_seg_pos(unsigned int dest, zft_position *pos, 764 - const zft_volinfo *volume); 765 - 766 - #define ZFT_SLOW_SEEK_THRESHOLD 10 /* segments */ 767 - #define ZFT_FAST_SEEK_MAX_TRIALS 10 /* times */ 768 - #define ZFT_FAST_SEEK_BACKUP 10 /* segments */ 769 - 770 - static int zftc_seek(unsigned int new_block_pos, 771 - zft_position *pos, const zft_volinfo *volume, __u8 *buf) 772 - { 773 - unsigned int dest; 774 - int limit; 775 - int distance; 776 - int result = 0; 777 - int seg_dist; 778 - int new_seg; 779 - int old_seg = 0; 780 - int fast_seek_trials = 0; 781 - TRACE_FUN(ft_t_flow); 782 - 783 - if (new_block_pos == 0) { 784 - pos->seg_pos = volume->start_seg; 785 - pos->seg_byte_pos = 0; 786 - pos->volume_pos = 0; 787 - zftc_reset(); 788 - TRACE_EXIT 0; 789 - } 790 - dest = new_block_pos * (volume->blk_sz >> 10); 791 - distance = dest - (pos->volume_pos >> 10); 792 - while (distance != 0) { 793 - seg_dist = compute_seg_pos(dest, pos, volume); 794 - TRACE(ft_t_noise, "\n" 795 - KERN_INFO "seg_dist: %d\n" 796 - KERN_INFO "distance: %d\n" 797 - KERN_INFO "dest : %d\n" 798 - KERN_INFO "vpos : %d\n" 799 - KERN_INFO "seg_pos : %d\n" 800 - KERN_INFO "trials : %d", 801 - seg_dist, distance, dest, 802 - (unsigned int)(pos->volume_pos>>10), pos->seg_pos, 803 - fast_seek_trials); 804 - if (distance > 0) { 805 - if (seg_dist < 0) { 806 - TRACE(ft_t_bug, "BUG: distance %d > 0, " 807 - "segment difference %d < 0", 808 - distance, seg_dist); 809 - result = -EIO; 810 - break; 811 - } 812 - new_seg = pos->seg_pos + seg_dist; 813 - if (new_seg > volume->end_seg) { 814 - new_seg = volume->end_seg; 815 - } 816 - if (old_seg == new_seg || /* loop */ 817 - seg_dist <= ZFT_SLOW_SEEK_THRESHOLD || 818 - fast_seek_trials >= ZFT_FAST_SEEK_MAX_TRIALS) { 819 - TRACE(ft_t_noise, "starting slow seek:\n" 820 - KERN_INFO "fast seek failed too often: %s\n" 821 - KERN_INFO "near target position : %s\n" 822 - KERN_INFO "looping between two segs : %s", 823 - (fast_seek_trials >= 824 - ZFT_FAST_SEEK_MAX_TRIALS) 825 - ? "yes" : "no", 826 - (seg_dist <= ZFT_SLOW_SEEK_THRESHOLD) 827 - ? "yes" : "no", 828 - (old_seg == new_seg) 829 - ? "yes" : "no"); 830 - result = slow_seek_forward(dest, &cseg, 831 - pos, volume, buf); 832 - break; 833 - } 834 - old_seg = new_seg; 835 - limit = volume->end_seg; 836 - fast_seek_trials ++; 837 - for (;;) { 838 - result = search_valid_segment(new_seg, limit, 839 - volume->size, 840 - pos, &cseg, 841 - volume, buf); 842 - if (result == 0 || result == -EINTR) { 843 - break; 844 - } 845 - if (new_seg == volume->start_seg) { 846 - result = -EIO; /* set errror 847 - * condition 848 - */ 849 - break; 850 - } 851 - limit = new_seg; 852 - new_seg -= ZFT_FAST_SEEK_BACKUP; 853 - if (new_seg < volume->start_seg) { 854 - new_seg = volume->start_seg; 855 - } 856 - } 857 - if (result < 0) { 858 - TRACE(ft_t_warn, 859 - "Couldn't find a readable segment"); 860 - break; 861 - } 862 - } else /* if (distance < 0) */ { 863 - if (seg_dist > 0) { 864 - TRACE(ft_t_bug, "BUG: distance %d < 0, " 865 - "segment difference %d >0", 866 - distance, seg_dist); 867 - result = -EIO; 868 - break; 869 - } 870 - new_seg = pos->seg_pos + seg_dist; 871 - if (fast_seek_trials > 0 && seg_dist == 0) { 872 - /* this avoids sticking to the same 873 - * segment all the time. On the other hand: 874 - * if we got here for the first time, and the 875 - * deblock_buffer still contains a valid 876 - * segment, then there is no need to skip to 877 - * the previous segment if the desired position 878 - * is inside this segment. 879 - */ 880 - new_seg --; 881 - } 882 - if (new_seg < volume->start_seg) { 883 - new_seg = volume->start_seg; 884 - } 885 - limit = pos->seg_pos; 886 - fast_seek_trials ++; 887 - for (;;) { 888 - result = search_valid_segment(new_seg, limit, 889 - pos->volume_pos, 890 - pos, &cseg, 891 - volume, buf); 892 - if (result == 0 || result == -EINTR) { 893 - break; 894 - } 895 - if (new_seg == volume->start_seg) { 896 - result = -EIO; /* set errror 897 - * condition 898 - */ 899 - break; 900 - } 901 - limit = new_seg; 902 - new_seg -= ZFT_FAST_SEEK_BACKUP; 903 - if (new_seg < volume->start_seg) { 904 - new_seg = volume->start_seg; 905 - } 906 - } 907 - if (result < 0) { 908 - TRACE(ft_t_warn, 909 - "Couldn't find a readable segment"); 910 - break; 911 - } 912 - } 913 - distance = dest - (pos->volume_pos >> 10); 914 - } 915 - TRACE_EXIT result; 916 - } 917 - 918 - 919 - /* advance inside the given segment at most to_do bytes. 920 - * of kilobytes moved 921 - */ 922 - 923 - static int seek_in_segment(const unsigned int to_do, 924 - cmpr_info *c_info, 925 - const char *src_buf, 926 - const int seg_sz, 927 - const int seg_pos, 928 - const zft_volinfo *volume) 929 - { 930 - int result = 0; 931 - int blk_sz = volume->blk_sz >> 10; 932 - int remaining = to_do; 933 - TRACE_FUN(ft_t_flow); 934 - 935 - if (c_info->offset == 0) { 936 - /* new segment just read 937 - */ 938 - TRACE_CATCH(get_cseg(c_info, src_buf, seg_sz, volume),); 939 - c_info->cmpr_pos += c_info->count; 940 - DUMP_CMPR_INFO(ft_t_noise, "", c_info); 941 - } 942 - /* loop and uncompress until user buffer full or 943 - * deblock-buffer empty 944 - */ 945 - TRACE(ft_t_noise, "compressed_sz: %d, compos : %d", 946 - c_info->cmpr_sz, c_info->cmpr_pos); 947 - while (c_info->spans == 0 && remaining > 0) { 948 - if (c_info->cmpr_pos != 0) { /* cmpr buf is not empty */ 949 - result += blk_sz; 950 - remaining -= blk_sz; 951 - c_info->cmpr_pos = 0; 952 - } 953 - if (remaining > 0) { 954 - get_next_cluster(c_info, src_buf, seg_sz, 955 - volume->end_seg == seg_pos); 956 - if (c_info->count != 0) { 957 - c_info->cmpr_pos = c_info->count; 958 - c_info->offset += c_info->count; 959 - } else { 960 - break; 961 - } 962 - } 963 - /* Allow escape from this loop on signal! 964 - */ 965 - FT_SIGNAL_EXIT(_DONT_BLOCK); 966 - DUMP_CMPR_INFO(ft_t_noise, "", c_info); 967 - TRACE(ft_t_noise, "to_do: %d", remaining); 968 - } 969 - if (seg_sz - c_info->offset <= 18) { 970 - c_info->offset = seg_sz; 971 - } 972 - TRACE(ft_t_noise, "\n" 973 - KERN_INFO "segment size : %d\n" 974 - KERN_INFO "buf_pos_read : %d\n" 975 - KERN_INFO "remaining : %d", 976 - seg_sz, c_info->offset, 977 - seg_sz - c_info->offset); 978 - TRACE_EXIT result; 979 - } 980 - 981 - static int slow_seek_forward_until_error(const unsigned int distance, 982 - cmpr_info *c_info, 983 - zft_position *pos, 984 - const zft_volinfo *volume, 985 - __u8 *buf) 986 - { 987 - unsigned int remaining = distance; 988 - int seg_sz; 989 - int seg_pos; 990 - int result; 991 - TRACE_FUN(ft_t_flow); 992 - 993 - seg_pos = pos->seg_pos; 994 - do { 995 - TRACE_CATCH(seg_sz = zft_fetch_segment(seg_pos, buf, 996 - FT_RD_AHEAD),); 997 - /* now we have the contents of the actual segment in 998 - * the deblock buffer 999 - */ 1000 - TRACE_CATCH(result = seek_in_segment(remaining, c_info, buf, 1001 - seg_sz, seg_pos,volume),); 1002 - remaining -= result; 1003 - pos->volume_pos += result<<10; 1004 - pos->seg_pos = seg_pos; 1005 - pos->seg_byte_pos = c_info->offset; 1006 - seg_pos ++; 1007 - if (seg_pos <= volume->end_seg && c_info->offset == seg_sz) { 1008 - pos->seg_pos ++; 1009 - pos->seg_byte_pos = 0; 1010 - c_info->offset = 0; 1011 - } 1012 - /* Allow escape from this loop on signal! 1013 - */ 1014 - FT_SIGNAL_EXIT(_DONT_BLOCK); 1015 - TRACE(ft_t_noise, "\n" 1016 - KERN_INFO "remaining: %d\n" 1017 - KERN_INFO "seg_pos: %d\n" 1018 - KERN_INFO "end_seg: %d\n" 1019 - KERN_INFO "result: %d", 1020 - remaining, seg_pos, volume->end_seg, result); 1021 - } while (remaining > 0 && seg_pos <= volume->end_seg); 1022 - TRACE_EXIT 0; 1023 - } 1024 - 1025 - /* return segment id of next segment containing valid data, -EIO otherwise 1026 - */ 1027 - static int search_valid_segment(unsigned int segment, 1028 - const unsigned int end_seg, 1029 - const unsigned int max_foffs, 1030 - zft_position *pos, 1031 - cmpr_info *c_info, 1032 - const zft_volinfo *volume, 1033 - __u8 *buf) 1034 - { 1035 - cmpr_info tmp_info; 1036 - int seg_sz; 1037 - TRACE_FUN(ft_t_flow); 1038 - 1039 - memset(&tmp_info, 0, sizeof(cmpr_info)); 1040 - while (segment <= end_seg) { 1041 - FT_SIGNAL_EXIT(_DONT_BLOCK); 1042 - TRACE(ft_t_noise, 1043 - "Searching readable segment between %d and %d", 1044 - segment, end_seg); 1045 - seg_sz = zft_fetch_segment(segment, buf, FT_RD_AHEAD); 1046 - if ((seg_sz > 0) && 1047 - (get_cseg (&tmp_info, buf, seg_sz, volume) >= 0) && 1048 - (tmp_info.foffs != 0 || segment == volume->start_seg)) { 1049 - if ((tmp_info.foffs>>10) > max_foffs) { 1050 - TRACE_ABORT(-EIO, ft_t_noise, "\n" 1051 - KERN_INFO "cseg.foff: %d\n" 1052 - KERN_INFO "dest : %d", 1053 - (int)(tmp_info.foffs >> 10), 1054 - max_foffs); 1055 - } 1056 - DUMP_CMPR_INFO(ft_t_noise, "", &tmp_info); 1057 - *c_info = tmp_info; 1058 - pos->seg_pos = segment; 1059 - pos->volume_pos = c_info->foffs; 1060 - pos->seg_byte_pos = c_info->offset; 1061 - TRACE(ft_t_noise, "found segment at %d", segment); 1062 - TRACE_EXIT 0; 1063 - } 1064 - segment++; 1065 - } 1066 - TRACE_EXIT -EIO; 1067 - } 1068 - 1069 - static int slow_seek_forward(unsigned int dest, 1070 - cmpr_info *c_info, 1071 - zft_position *pos, 1072 - const zft_volinfo *volume, 1073 - __u8 *buf) 1074 - { 1075 - unsigned int distance; 1076 - int result = 0; 1077 - TRACE_FUN(ft_t_flow); 1078 - 1079 - distance = dest - (pos->volume_pos >> 10); 1080 - while ((distance > 0) && 1081 - (result = slow_seek_forward_until_error(distance, 1082 - c_info, 1083 - pos, 1084 - volume, 1085 - buf)) < 0) { 1086 - if (result == -EINTR) { 1087 - break; 1088 - } 1089 - TRACE(ft_t_noise, "seg_pos: %d", pos->seg_pos); 1090 - /* the failing segment is either pos->seg_pos or 1091 - * pos->seg_pos + 1. There is no need to further try 1092 - * that segment, because ftape_read_segment() already 1093 - * has tried very much to read it. So we start with 1094 - * following segment, which is pos->seg_pos + 1 1095 - */ 1096 - if(search_valid_segment(pos->seg_pos+1, volume->end_seg, dest, 1097 - pos, c_info, 1098 - volume, buf) < 0) { 1099 - TRACE(ft_t_noise, "search_valid_segment() failed"); 1100 - result = -EIO; 1101 - break; 1102 - } 1103 - distance = dest - (pos->volume_pos >> 10); 1104 - result = 0; 1105 - TRACE(ft_t_noise, "segment: %d", pos->seg_pos); 1106 - /* found valid segment, retry the seek */ 1107 - } 1108 - TRACE_EXIT result; 1109 - } 1110 - 1111 - static int compute_seg_pos(const unsigned int dest, 1112 - zft_position *pos, 1113 - const zft_volinfo *volume) 1114 - { 1115 - int segment; 1116 - int distance = dest - (pos->volume_pos >> 10); 1117 - unsigned int raw_size; 1118 - unsigned int virt_size; 1119 - unsigned int factor; 1120 - TRACE_FUN(ft_t_flow); 1121 - 1122 - if (distance >= 0) { 1123 - raw_size = volume->end_seg - pos->seg_pos + 1; 1124 - virt_size = ((unsigned int)(volume->size>>10) 1125 - - (unsigned int)(pos->volume_pos>>10) 1126 - + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1); 1127 - virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS; 1128 - if (virt_size == 0 || raw_size == 0) { 1129 - TRACE_EXIT 0; 1130 - } 1131 - if (raw_size >= (1<<25)) { 1132 - factor = raw_size/(virt_size>>7); 1133 - } else { 1134 - factor = (raw_size<<7)/virt_size; 1135 - } 1136 - segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS); 1137 - segment = (segment * factor)>>7; 1138 - } else { 1139 - raw_size = pos->seg_pos - volume->start_seg + 1; 1140 - virt_size = ((unsigned int)(pos->volume_pos>>10) 1141 - + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1); 1142 - virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS; 1143 - if (virt_size == 0 || raw_size == 0) { 1144 - TRACE_EXIT 0; 1145 - } 1146 - if (raw_size >= (1<<25)) { 1147 - factor = raw_size/(virt_size>>7); 1148 - } else { 1149 - factor = (raw_size<<7)/virt_size; 1150 - } 1151 - segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS); 1152 - } 1153 - TRACE(ft_t_noise, "factor: %d/%d", factor, 1<<7); 1154 - TRACE_EXIT segment; 1155 - } 1156 - 1157 - static struct zft_cmpr_ops cmpr_ops = { 1158 - zftc_write, 1159 - zftc_read, 1160 - zftc_seek, 1161 - zftc_lock, 1162 - zftc_reset, 1163 - zftc_cleanup 1164 - }; 1165 - 1166 - int zft_compressor_init(void) 1167 - { 1168 - TRACE_FUN(ft_t_flow); 1169 - 1170 - #ifdef MODULE 1171 - printk(KERN_INFO "zftape compressor v1.00a 970514 for " FTAPE_VERSION "\n"); 1172 - if (TRACE_LEVEL >= ft_t_info) { 1173 - printk( 1174 - KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" 1175 - KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n"); 1176 - } 1177 - #else /* !MODULE */ 1178 - /* print a short no-nonsense boot message */ 1179 - printk(KERN_INFO "zftape compressor v1.00a 970514\n"); 1180 - printk(KERN_INFO "For use with " FTAPE_VERSION "\n"); 1181 - #endif /* MODULE */ 1182 - TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init); 1183 - TRACE(ft_t_info, "installing compressor for zftape ..."); 1184 - TRACE_CATCH(zft_cmpr_register(&cmpr_ops),); 1185 - TRACE_EXIT 0; 1186 - } 1187 - 1188 - #ifdef MODULE 1189 - 1190 - MODULE_AUTHOR( 1191 - "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de"); 1192 - MODULE_DESCRIPTION( 1193 - "Compression routines for zftape. Uses the lzrw3 algorithm by Ross Williams"); 1194 - MODULE_LICENSE("GPL"); 1195 - 1196 - /* Called by modules package when installing the driver 1197 - */ 1198 - int init_module(void) 1199 - { 1200 - return zft_compressor_init(); 1201 - } 1202 - 1203 - #endif /* MODULE */
-83
drivers/char/ftape/compressor/zftape-compress.h
··· 1 - #ifndef _ZFTAPE_COMPRESS_H 2 - #define _ZFTAPE_COMPRESS_H 3 - /* 4 - * Copyright (c) 1994-1997 Claus-Justus Heine 5 - 6 - This program is free software; you can redistribute it and/or 7 - modify it under the terms of the GNU General Public License as 8 - published by the Free Software Foundation; either version 2, or (at 9 - your option) any later version. 10 - 11 - This program is distributed in the hope that it will be useful, but 12 - WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 - General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with this program; see the file COPYING. If not, write to 18 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 19 - USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/compressor/zftape-compress.h,v $ 23 - * $Revision: 1.1 $ 24 - * $Date: 1997/10/05 19:12:32 $ 25 - * 26 - * This file contains macros and definitions for zftape's 27 - * builtin compression code. 28 - * 29 - */ 30 - 31 - #include "../zftape/zftape-buffers.h" 32 - #include "../zftape/zftape-vtbl.h" 33 - #include "../compressor/lzrw3.h" 34 - 35 - /* CMPR_WRK_MEM_SIZE gives the size of the compression wrk_mem */ 36 - /* I got these out of lzrw3.c */ 37 - #define U(X) ((__u32) X) 38 - #define SIZE_P_BYTE (U(sizeof(__u8 *))) 39 - #define ALIGNMENT_FUDGE (U(16)) 40 - 41 - #define CMPR_WRK_MEM_SIZE (U(4096)*(SIZE_P_BYTE) + ALIGNMENT_FUDGE) 42 - 43 - /* the maximum number of bytes the size of the "compressed" data can 44 - * exceed the uncompressed data. As it is quite useless to compress 45 - * data twice it is sometimes the case that it is more efficient to 46 - * copy a block of data but to feed it to the "compression" 47 - * algorithm. In this case there are some flag bytes or the like 48 - * proceding the "compressed" data. THAT MUST NOT BE THE CASE for the 49 - * algorithm we use for this driver. Instead, the high bit 15 of 50 - * compressed_size: 51 - * 52 - * compressed_size = ftape_compress() 53 - * 54 - * must be set in such a case. 55 - * 56 - * Nevertheless, it might also be as for lzrw3 that there is an 57 - * "intermediate" overrun that exceeds the amount of the compressed 58 - * data that is actually produced. During the algorithm we need in the 59 - * worst case MAX_CMP_GROUP bytes more than the input-size. 60 - */ 61 - #define MAX_CMP_GROUP (2+16*2) /* from lzrw3.c */ 62 - 63 - #define CMPR_OVERRUN MAX_CMP_GROUP /* during compression */ 64 - 65 - /****************************************************/ 66 - 67 - #define CMPR_BUFFER_SIZE (MAX_BLOCK_SIZE + CMPR_OVERRUN) 68 - 69 - /* the compression map stores the byte offset compressed blocks within 70 - * the current volume for catridges with format code 2,3 and 5 71 - * (and old versions of zftape) and the offset measured in kilobytes for 72 - * format code 4 and 6. This gives us a possible max. size of a 73 - * compressed volume of 1024*4GIG which should be enough. 74 - */ 75 - typedef __u32 CmprMap; 76 - 77 - /* globals 78 - */ 79 - 80 - /* exported functions 81 - */ 82 - 83 - #endif /* _ZFTAPE_COMPRESS_H */
-43
drivers/char/ftape/lowlevel/Makefile
··· 1 - # 2 - # Copyright (C) 1996, 1997 Clau-Justus Heine. 3 - # 4 - # This program is free software; you can redistribute it and/or modify 5 - # it under the terms of the GNU General Public License as published by 6 - # the Free Software Foundation; either version 2, or (at your option) 7 - # any later version. 8 - # 9 - # This program is distributed in the hope that it will be useful, 10 - # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - # GNU General Public License for more details. 13 - # 14 - # You should have received a copy of the GNU General Public License 15 - # along with this program; see the file COPYING. If not, write to 16 - # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - # 18 - # $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/Makefile,v $ 19 - # $Revision: 1.4 $ 20 - # $Date: 1997/10/07 09:26:02 $ 21 - # 22 - # Makefile for the lowlevel part QIC-40/80/3010/3020 floppy-tape 23 - # driver for Linux. 24 - # 25 - 26 - obj-$(CONFIG_FTAPE) += ftape.o 27 - 28 - ftape-objs := ftape-init.o fdc-io.o fdc-isr.o \ 29 - ftape-bsm.o ftape-ctl.o ftape-read.o ftape-rw.o \ 30 - ftape-write.o ftape-io.o ftape-calibr.o ftape-ecc.o fc-10.o \ 31 - ftape-buffer.o ftape-format.o ftape_syms.o 32 - 33 - ifeq ($(CONFIG_FTAPE),y) 34 - ftape-objs += ftape-setup.o 35 - endif 36 - 37 - ifndef CONFIG_FT_NO_TRACE_AT_ALL 38 - ftape-objs += ftape-tracing.o 39 - endif 40 - 41 - ifeq ($(CONFIG_FT_PROC_FS),y) 42 - ftape-objs += ftape-proc.o 43 - endif
-175
drivers/char/ftape/lowlevel/fc-10.c
··· 1 - /* 2 - * 3 - 4 - Copyright (C) 1993,1994 Jon Tombs. 5 - 6 - This program is distributed in the hope that it will be useful, 7 - but WITHOUT ANY WARRANTY; without even the implied warranty of 8 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 - GNU General Public License for more details. 10 - 11 - The entire guts of this program was written by dosemu, modified to 12 - record reads and writes to the ports in the 0x180-0x188 address space, 13 - while running the CMS program TAPE.EXE V2.0.5 supplied with the drive. 14 - 15 - Modified to use an array of addresses and generally cleaned up (made 16 - much shorter) 4 June 94, dosemu isn't that good at writing short code it 17 - would seem :-). Made independent of 0x180, but I doubt it will work 18 - at any other address. 19 - 20 - Modified for distribution with ftape source. 21 June 94, SJL. 21 - 22 - Modifications on 20 October 95, by Daniel Cohen (catman@wpi.edu): 23 - Modified to support different DMA, IRQ, and IO Ports. Borland's 24 - Turbo Debugger in virtual 8086 mode (TD386.EXE with hardware breakpoints 25 - provided by the TDH386.SYS Device Driver) was used on the CMS program 26 - TAPE V4.0.5. I set breakpoints on I/O to ports 0x180-0x187. Note that 27 - CMS's program will not successfully configure the tape drive if you set 28 - breakpoints on IO Reads, but you can set them on IO Writes without problems. 29 - Known problems: 30 - - You can not use DMA Channels 5 or 7. 31 - 32 - Modification on 29 January 96, by Daniel Cohen (catman@wpi.edu): 33 - Modified to only accept IRQs 3 - 7, or 9. Since we can only send a 3 bit 34 - number representing the IRQ to the card, special handling is required when 35 - IRQ 9 is selected. IRQ 2 and 9 are the same, and we should request IRQ 9 36 - from the kernel while telling the card to use IRQ 2. Thanks to Greg 37 - Crider (gcrider@iclnet.org) for finding and locating this bug, as well as 38 - testing the patch. 39 - 40 - Modification on 11 December 96, by Claus Heine (claus@momo.math.rwth-aachen.de): 41 - Modified a little to use variahle ft_fdc_base, ft_fdc_irq, ft_fdc_dma 42 - instead of preprocessor symbols. Thus we can compile this into the module 43 - or kernel and let the user specify the options as command line arguments. 44 - 45 - * 46 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fc-10.c,v $ 47 - * $Revision: 1.2 $ 48 - * $Date: 1997/10/05 19:18:04 $ 49 - * 50 - * This file contains code for the CMS FC-10/FC-20 card. 51 - */ 52 - 53 - #include <asm/io.h> 54 - #include <linux/ftape.h> 55 - #include "../lowlevel/ftape-tracing.h" 56 - #include "../lowlevel/fdc-io.h" 57 - #include "../lowlevel/fc-10.h" 58 - 59 - static __u16 inbs_magic[] = { 60 - 0x3, 0x3, 0x0, 0x4, 0x7, 0x2, 0x5, 0x3, 0x1, 0x4, 61 - 0x3, 0x5, 0x2, 0x0, 0x3, 0x7, 0x4, 0x2, 62 - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 63 - }; 64 - 65 - static __u16 fc10_ports[] = { 66 - 0x180, 0x210, 0x2A0, 0x300, 0x330, 0x340, 0x370 67 - }; 68 - 69 - int fc10_enable(void) 70 - { 71 - int i; 72 - __u8 cardConfig = 0x00; 73 - __u8 x; 74 - TRACE_FUN(ft_t_flow); 75 - 76 - /* This code will only work if the FC-10 (or FC-20) is set to 77 - * use DMA channels 1, 2, or 3. DMA channels 5 and 7 seem to be 78 - * initialized by the same command as channels 1 and 3, respectively. 79 - */ 80 - if (ft_fdc_dma > 3) { 81 - TRACE_ABORT(0, ft_t_err, 82 - "Error: The FC-10/20 must be set to use DMA channels 1, 2, or 3!"); 83 - } 84 - /* Only allow the FC-10/20 to use IRQ 3-7, or 9. Note that CMS's program 85 - * only accepts IRQ's 2-7, but in linux, IRQ 2 is the same as IRQ 9. 86 - */ 87 - if (ft_fdc_irq < 3 || ft_fdc_irq == 8 || ft_fdc_irq > 9) { 88 - TRACE_ABORT(0, ft_t_err, 89 - "Error: The FC-10/20 must be set to use IRQ levels 3 - 7, or 9!\n" 90 - KERN_INFO "Note: IRQ 9 is the same as IRQ 2"); 91 - } 92 - /* Clear state machine ??? 93 - */ 94 - for (i = 0; i < NR_ITEMS(inbs_magic); i++) { 95 - inb(ft_fdc_base + inbs_magic[i]); 96 - } 97 - outb(0x0, ft_fdc_base); 98 - 99 - x = inb(ft_fdc_base); 100 - if (x == 0x13 || x == 0x93) { 101 - for (i = 1; i < 8; i++) { 102 - if (inb(ft_fdc_base + i) != x) { 103 - TRACE_EXIT 0; 104 - } 105 - } 106 - } else { 107 - TRACE_EXIT 0; 108 - } 109 - 110 - outb(0x8, ft_fdc_base); 111 - 112 - for (i = 0; i < 8; i++) { 113 - if (inb(ft_fdc_base + i) != 0x0) { 114 - TRACE_EXIT 0; 115 - } 116 - } 117 - outb(0x10, ft_fdc_base); 118 - 119 - for (i = 0; i < 8; i++) { 120 - if (inb(ft_fdc_base + i) != 0xff) { 121 - TRACE_EXIT 0; 122 - } 123 - } 124 - 125 - /* Okay, we found a FC-10 card ! ??? 126 - */ 127 - outb(0x0, fdc.ccr); 128 - 129 - /* Clear state machine again ??? 130 - */ 131 - for (i = 0; i < NR_ITEMS(inbs_magic); i++) { 132 - inb(ft_fdc_base + inbs_magic[i]); 133 - } 134 - /* Send io port */ 135 - for (i = 0; i < NR_ITEMS(fc10_ports); i++) 136 - if (ft_fdc_base == fc10_ports[i]) 137 - cardConfig = i + 1; 138 - if (cardConfig == 0) { 139 - TRACE_EXIT 0; /* Invalid I/O Port */ 140 - } 141 - /* and IRQ - If using IRQ 9, tell the FC card it is actually IRQ 2 */ 142 - if (ft_fdc_irq != 9) 143 - cardConfig |= ft_fdc_irq << 3; 144 - else 145 - cardConfig |= 2 << 3; 146 - 147 - /* and finally DMA Channel */ 148 - cardConfig |= ft_fdc_dma << 6; 149 - outb(cardConfig, ft_fdc_base); /* DMA [2 bits]/IRQ [3 bits]/BASE [3 bits] */ 150 - 151 - /* Enable FC-10 ??? 152 - */ 153 - outb(0, fdc.ccr); 154 - outb(0, fdc.dor2); 155 - outb(FDC_DMA_MODE /* 8 */, fdc.dor); 156 - outb(FDC_DMA_MODE /* 8 */, fdc.dor); 157 - outb(1, fdc.dor2); 158 - 159 - /************************************* 160 - * 161 - * cH: why the hell should this be necessary? This is done 162 - * by fdc_reset()!!! 163 - * 164 - *************************************/ 165 - /* Initialize fdc, select drive B: 166 - */ 167 - outb(FDC_DMA_MODE, fdc.dor); /* assert reset, dma & irq enabled */ 168 - /* 0x08 */ 169 - outb(FDC_DMA_MODE|FDC_RESET_NOT, fdc.dor); /* release reset */ 170 - /* 0x08 | 0x04 = 0x0c */ 171 - outb(FDC_DMA_MODE|FDC_RESET_NOT|FDC_MOTOR_1|FTAPE_SEL_B, fdc.dor); 172 - /* 0x08 | 0x04 | 0x20 | 0x01 = 0x2d */ 173 - /* select drive 1 */ /* why not drive 0 ???? */ 174 - TRACE_EXIT (x == 0x93) ? 2 : 1; 175 - }
-39
drivers/char/ftape/lowlevel/fc-10.h
··· 1 - #ifndef _FC_10_H 2 - #define _FC_10_H 3 - 4 - /* 5 - * Copyright (C) 1994-1996 Bas Laarhoven. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fc-10.h,v $ 23 - * $Revision: 1.1 $ 24 - * $Date: 1997/09/19 09:05:22 $ 25 - * 26 - * This file contains definitions for the FC-10 code 27 - * of the QIC-40/80 floppy-tape driver for Linux. 28 - */ 29 - 30 - /* 31 - * fc-10.c defined global vars. 32 - */ 33 - 34 - /* 35 - * fc-10.c defined global functions. 36 - */ 37 - extern int fc10_enable(void); 38 - 39 - #endif
-1349
drivers/char/ftape/lowlevel/fdc-io.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven, 3 - * (C) 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.c,v $ 21 - * $Revision: 1.7.4.2 $ 22 - * $Date: 1997/11/16 14:48:17 $ 23 - * 24 - * This file contains the low-level floppy disk interface code 25 - * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for 26 - * Linux. 27 - */ 28 - 29 - #include <linux/errno.h> 30 - #include <linux/sched.h> 31 - #include <linux/ioport.h> 32 - #include <linux/interrupt.h> 33 - #include <linux/kernel.h> 34 - #include <asm/system.h> 35 - #include <asm/io.h> 36 - #include <asm/dma.h> 37 - #include <asm/irq.h> 38 - 39 - #include <linux/ftape.h> 40 - #include <linux/qic117.h> 41 - #include "../lowlevel/ftape-tracing.h" 42 - #include "../lowlevel/fdc-io.h" 43 - #include "../lowlevel/fdc-isr.h" 44 - #include "../lowlevel/ftape-io.h" 45 - #include "../lowlevel/ftape-rw.h" 46 - #include "../lowlevel/ftape-ctl.h" 47 - #include "../lowlevel/ftape-calibr.h" 48 - #include "../lowlevel/fc-10.h" 49 - 50 - /* Global vars. 51 - */ 52 - static int ftape_motor; 53 - volatile int ftape_current_cylinder = -1; 54 - volatile fdc_mode_enum fdc_mode = fdc_idle; 55 - fdc_config_info fdc; 56 - DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr); 57 - 58 - unsigned int ft_fdc_base = CONFIG_FT_FDC_BASE; 59 - unsigned int ft_fdc_irq = CONFIG_FT_FDC_IRQ; 60 - unsigned int ft_fdc_dma = CONFIG_FT_FDC_DMA; 61 - unsigned int ft_fdc_threshold = CONFIG_FT_FDC_THR; /* bytes */ 62 - unsigned int ft_fdc_rate_limit = CONFIG_FT_FDC_MAX_RATE; /* bits/sec */ 63 - int ft_probe_fc10 = CONFIG_FT_PROBE_FC10; 64 - int ft_mach2 = CONFIG_FT_MACH2; 65 - 66 - /* Local vars. 67 - */ 68 - static spinlock_t fdc_io_lock; 69 - static unsigned int fdc_calibr_count; 70 - static unsigned int fdc_calibr_time; 71 - static int fdc_status; 72 - volatile __u8 fdc_head; /* FDC head from sector id */ 73 - volatile __u8 fdc_cyl; /* FDC track from sector id */ 74 - volatile __u8 fdc_sect; /* FDC sector from sector id */ 75 - static int fdc_data_rate = 500; /* data rate (Kbps) */ 76 - static int fdc_rate_code; /* data rate code (0 == 500 Kbps) */ 77 - static int fdc_seek_rate = 2; /* step rate (msec) */ 78 - static void (*do_ftape) (void); 79 - static int fdc_fifo_state; /* original fifo setting - fifo enabled */ 80 - static int fdc_fifo_thr; /* original fifo setting - threshold */ 81 - static int fdc_lock_state; /* original lock setting - locked */ 82 - static int fdc_fifo_locked; /* has fifo && lock set ? */ 83 - static __u8 fdc_precomp; /* default precomp. value (nsec) */ 84 - static __u8 fdc_prec_code; /* fdc precomp. select code */ 85 - 86 - static char ftape_id[] = "ftape"; /* used by request irq and free irq */ 87 - 88 - static int fdc_set_seek_rate(int seek_rate); 89 - 90 - void fdc_catch_stray_interrupts(int count) 91 - { 92 - unsigned long flags; 93 - 94 - spin_lock_irqsave(&fdc_io_lock, flags); 95 - if (count == 0) { 96 - ft_expected_stray_interrupts = 0; 97 - } else { 98 - ft_expected_stray_interrupts += count; 99 - } 100 - spin_unlock_irqrestore(&fdc_io_lock, flags); 101 - } 102 - 103 - /* Wait during a timeout period for a given FDC status. 104 - * If usecs == 0 then just test status, else wait at least for usecs. 105 - * Returns -ETIME on timeout. Function must be calibrated first ! 106 - */ 107 - static int fdc_wait(unsigned int usecs, __u8 mask, __u8 state) 108 - { 109 - int count_1 = (fdc_calibr_count * usecs + 110 - fdc_calibr_count - 1) / fdc_calibr_time; 111 - 112 - do { 113 - fdc_status = inb_p(fdc.msr); 114 - if ((fdc_status & mask) == state) { 115 - return 0; 116 - } 117 - } while (count_1-- >= 0); 118 - return -ETIME; 119 - } 120 - 121 - int fdc_ready_wait(unsigned int usecs) 122 - { 123 - return fdc_wait(usecs, FDC_DATA_READY | FDC_BUSY, FDC_DATA_READY); 124 - } 125 - 126 - /* Why can't we just use udelay()? 127 - */ 128 - static void fdc_usec_wait(unsigned int usecs) 129 - { 130 - fdc_wait(usecs, 0, 1); /* will always timeout ! */ 131 - } 132 - 133 - static int fdc_ready_out_wait(unsigned int usecs) 134 - { 135 - fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */ 136 - return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_OUT_READY); 137 - } 138 - 139 - void fdc_wait_calibrate(void) 140 - { 141 - ftape_calibrate("fdc_wait", 142 - fdc_usec_wait, &fdc_calibr_count, &fdc_calibr_time); 143 - } 144 - 145 - /* Wait for a (short) while for the FDC to become ready 146 - * and transfer the next command byte. 147 - * Return -ETIME on timeout on getting ready (depends on hardware!). 148 - */ 149 - static int fdc_write(const __u8 data) 150 - { 151 - fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */ 152 - if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_IN_READY) < 0) { 153 - return -ETIME; 154 - } else { 155 - outb(data, fdc.fifo); 156 - return 0; 157 - } 158 - } 159 - 160 - /* Wait for a (short) while for the FDC to become ready 161 - * and transfer the next result byte. 162 - * Return -ETIME if timeout on getting ready (depends on hardware!). 163 - */ 164 - static int fdc_read(__u8 * data) 165 - { 166 - fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */ 167 - if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_OUT_READY) < 0) { 168 - return -ETIME; 169 - } else { 170 - *data = inb(fdc.fifo); 171 - return 0; 172 - } 173 - } 174 - 175 - /* Output a cmd_len long command string to the FDC. 176 - * The FDC should be ready to receive a new command or 177 - * an error (EBUSY or ETIME) will occur. 178 - */ 179 - int fdc_command(const __u8 * cmd_data, int cmd_len) 180 - { 181 - int result = 0; 182 - unsigned long flags; 183 - int count = cmd_len; 184 - int retry = 0; 185 - #ifdef TESTING 186 - static unsigned int last_time; 187 - unsigned int time; 188 - #endif 189 - TRACE_FUN(ft_t_any); 190 - 191 - fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */ 192 - spin_lock_irqsave(&fdc_io_lock, flags); 193 - if (!in_interrupt()) 194 - /* Yes, I know, too much comments inside this function 195 - * ... 196 - * 197 - * Yet another bug in the original driver. All that 198 - * havoc is caused by the fact that the isr() sends 199 - * itself a command to the floppy tape driver (pause, 200 - * micro step pause). Now, the problem is that 201 - * commands are transmitted via the fdc_seek 202 - * command. But: the fdc performs seeks in the 203 - * background i.e. it doesn't signal busy while 204 - * sending the step pulses to the drive. Therefore the 205 - * non-interrupt level driver has no chance to tell 206 - * whether the isr() just has issued a seek. Therefore 207 - * we HAVE TO have a look at the ft_hide_interrupt 208 - * flag: it signals the non-interrupt level part of 209 - * the driver that it has to wait for the fdc until it 210 - * has completet seeking. 211 - * 212 - * THIS WAS PRESUMABLY THE REASON FOR ALL THAT 213 - * "fdc_read timeout" errors, I HOPE :-) 214 - */ 215 - if (ft_hide_interrupt) { 216 - restore_flags(flags); 217 - TRACE(ft_t_info, 218 - "Waiting for the isr() completing fdc_seek()"); 219 - if (fdc_interrupt_wait(2 * FT_SECOND) < 0) { 220 - TRACE(ft_t_warn, 221 - "Warning: timeout waiting for isr() seek to complete"); 222 - } 223 - if (ft_hide_interrupt || !ft_seek_completed) { 224 - /* There cannot be another 225 - * interrupt. The isr() only stops 226 - * the tape and the next interrupt 227 - * won't come until we have send our 228 - * command to the drive. 229 - */ 230 - TRACE_ABORT(-EIO, ft_t_bug, 231 - "BUG? isr() is still seeking?\n" 232 - KERN_INFO "hide: %d\n" 233 - KERN_INFO "seek: %d", 234 - ft_hide_interrupt, 235 - ft_seek_completed); 236 - 237 - } 238 - fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */ 239 - spin_lock_irqsave(&fdc_io_lock, flags); 240 - } 241 - fdc_status = inb(fdc.msr); 242 - if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) { 243 - spin_unlock_irqrestore(&fdc_io_lock, flags); 244 - TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready"); 245 - } 246 - fdc_mode = *cmd_data; /* used by isr */ 247 - #ifdef TESTING 248 - if (fdc_mode == FDC_SEEK) { 249 - time = ftape_timediff(last_time, ftape_timestamp()); 250 - if (time < 6000) { 251 - TRACE(ft_t_bug,"Warning: short timeout between seek commands: %d", 252 - time); 253 - } 254 - } 255 - #endif 256 - if (!in_interrupt()) { 257 - /* shouldn't be cleared if called from isr 258 - */ 259 - ft_interrupt_seen = 0; 260 - } 261 - while (count) { 262 - result = fdc_write(*cmd_data); 263 - if (result < 0) { 264 - TRACE(ft_t_fdc_dma, 265 - "fdc_mode = %02x, status = %02x at index %d", 266 - (int) fdc_mode, (int) fdc_status, 267 - cmd_len - count); 268 - if (++retry <= 3) { 269 - TRACE(ft_t_warn, "fdc_write timeout, retry"); 270 - } else { 271 - TRACE(ft_t_err, "fdc_write timeout, fatal"); 272 - /* recover ??? */ 273 - break; 274 - } 275 - } else { 276 - --count; 277 - ++cmd_data; 278 - } 279 - } 280 - #ifdef TESTING 281 - if (fdc_mode == FDC_SEEK) { 282 - last_time = ftape_timestamp(); 283 - } 284 - #endif 285 - spin_unlock_irqrestore(&fdc_io_lock, flags); 286 - TRACE_EXIT result; 287 - } 288 - 289 - /* Input a res_len long result string from the FDC. 290 - * The FDC should be ready to send the result or an error 291 - * (EBUSY or ETIME) will occur. 292 - */ 293 - int fdc_result(__u8 * res_data, int res_len) 294 - { 295 - int result = 0; 296 - unsigned long flags; 297 - int count = res_len; 298 - int retry = 0; 299 - TRACE_FUN(ft_t_any); 300 - 301 - spin_lock_irqsave(&fdc_io_lock, flags); 302 - fdc_status = inb(fdc.msr); 303 - if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) { 304 - TRACE(ft_t_err, "fdc not ready"); 305 - result = -EBUSY; 306 - } else while (count) { 307 - if (!(fdc_status & FDC_BUSY)) { 308 - spin_unlock_irqrestore(&fdc_io_lock, flags); 309 - TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase"); 310 - } 311 - result = fdc_read(res_data); 312 - if (result < 0) { 313 - TRACE(ft_t_fdc_dma, 314 - "fdc_mode = %02x, status = %02x at index %d", 315 - (int) fdc_mode, 316 - (int) fdc_status, 317 - res_len - count); 318 - if (++retry <= 3) { 319 - TRACE(ft_t_warn, "fdc_read timeout, retry"); 320 - } else { 321 - TRACE(ft_t_err, "fdc_read timeout, fatal"); 322 - /* recover ??? */ 323 - break; 324 - ++retry; 325 - } 326 - } else { 327 - --count; 328 - ++res_data; 329 - } 330 - } 331 - spin_unlock_irqrestore(&fdc_io_lock, flags); 332 - fdc_usec_wait(FT_RQM_DELAY); /* allow FDC to negate BSY */ 333 - TRACE_EXIT result; 334 - } 335 - 336 - /* Handle command and result phases for 337 - * commands without data phase. 338 - */ 339 - static int fdc_issue_command(const __u8 * out_data, int out_count, 340 - __u8 * in_data, int in_count) 341 - { 342 - TRACE_FUN(ft_t_any); 343 - 344 - if (out_count > 0) { 345 - TRACE_CATCH(fdc_command(out_data, out_count),); 346 - } 347 - /* will take 24 - 30 usec for fdc_sense_drive_status and 348 - * fdc_sense_interrupt_status commands. 349 - * 35 fails sometimes (5/9/93 SJL) 350 - * On a loaded system it incidentally takes longer than 351 - * this for the fdc to get ready ! ?????? WHY ?????? 352 - * So until we know what's going on use a very long timeout. 353 - */ 354 - TRACE_CATCH(fdc_ready_out_wait(500 /* usec */),); 355 - if (in_count > 0) { 356 - TRACE_CATCH(fdc_result(in_data, in_count), 357 - TRACE(ft_t_err, "result phase aborted")); 358 - } 359 - TRACE_EXIT 0; 360 - } 361 - 362 - /* Wait for FDC interrupt with timeout (in milliseconds). 363 - * Signals are blocked so the wait will not be aborted. 364 - * Note: interrupts must be enabled ! (23/05/93 SJL) 365 - */ 366 - int fdc_interrupt_wait(unsigned int time) 367 - { 368 - DECLARE_WAITQUEUE(wait,current); 369 - sigset_t old_sigmask; 370 - static int resetting; 371 - long timeout; 372 - 373 - TRACE_FUN(ft_t_fdc_dma); 374 - 375 - if (waitqueue_active(&ftape_wait_intr)) { 376 - TRACE_ABORT(-EIO, ft_t_err, "error: nested call"); 377 - } 378 - /* timeout time will be up to USPT microseconds too long ! */ 379 - timeout = (1000 * time + FT_USPT - 1) / FT_USPT; 380 - 381 - spin_lock_irq(&current->sighand->siglock); 382 - old_sigmask = current->blocked; 383 - sigfillset(&current->blocked); 384 - recalc_sigpending(); 385 - spin_unlock_irq(&current->sighand->siglock); 386 - 387 - set_current_state(TASK_INTERRUPTIBLE); 388 - add_wait_queue(&ftape_wait_intr, &wait); 389 - while (!ft_interrupt_seen && timeout) 390 - timeout = schedule_timeout_interruptible(timeout); 391 - 392 - spin_lock_irq(&current->sighand->siglock); 393 - current->blocked = old_sigmask; 394 - recalc_sigpending(); 395 - spin_unlock_irq(&current->sighand->siglock); 396 - 397 - remove_wait_queue(&ftape_wait_intr, &wait); 398 - /* the following IS necessary. True: as well 399 - * wake_up_interruptible() as the schedule() set TASK_RUNNING 400 - * when they wakeup a task, BUT: it may very well be that 401 - * ft_interrupt_seen is already set to 1 when we enter here 402 - * in which case schedule() gets never called, and 403 - * TASK_RUNNING never set. This has the funny effect that we 404 - * execute all the code until we leave kernel space, but then 405 - * the task is stopped (a task CANNOT be preempted while in 406 - * kernel mode. Sending a pair of SIGSTOP/SIGCONT to the 407 - * tasks wakes it up again. Funny! :-) 408 - */ 409 - current->state = TASK_RUNNING; 410 - if (ft_interrupt_seen) { /* woken up by interrupt */ 411 - ft_interrupt_seen = 0; 412 - TRACE_EXIT 0; 413 - } 414 - /* Original comment: 415 - * In first instance, next statement seems unnecessary since 416 - * it will be cleared in fdc_command. However, a small part of 417 - * the software seems to rely on this being cleared here 418 - * (ftape_close might fail) so stick to it until things get fixed ! 419 - */ 420 - /* My deeply sought of knowledge: 421 - * Behold NO! It is obvious. fdc_reset() doesn't call fdc_command() 422 - * but nevertheless uses fdc_interrupt_wait(). OF COURSE this needs to 423 - * be reset here. 424 - */ 425 - ft_interrupt_seen = 0; /* clear for next call */ 426 - if (!resetting) { 427 - resetting = 1; /* break infinite recursion if reset fails */ 428 - TRACE(ft_t_any, "cleanup reset"); 429 - fdc_reset(); 430 - resetting = 0; 431 - } 432 - TRACE_EXIT (signal_pending(current)) ? -EINTR : -ETIME; 433 - } 434 - 435 - /* Start/stop drive motor. Enable DMA mode. 436 - */ 437 - void fdc_motor(int motor) 438 - { 439 - int unit = ft_drive_sel; 440 - int data = unit | FDC_RESET_NOT | FDC_DMA_MODE; 441 - TRACE_FUN(ft_t_any); 442 - 443 - ftape_motor = motor; 444 - if (ftape_motor) { 445 - data |= FDC_MOTOR_0 << unit; 446 - TRACE(ft_t_noise, "turning motor %d on", unit); 447 - } else { 448 - TRACE(ft_t_noise, "turning motor %d off", unit); 449 - } 450 - if (ft_mach2) { 451 - outb_p(data, fdc.dor2); 452 - } else { 453 - outb_p(data, fdc.dor); 454 - } 455 - ftape_sleep(10 * FT_MILLISECOND); 456 - TRACE_EXIT; 457 - } 458 - 459 - static void fdc_update_dsr(void) 460 - { 461 - TRACE_FUN(ft_t_any); 462 - 463 - TRACE(ft_t_flow, "rate = %d Kbps, precomp = %d ns", 464 - fdc_data_rate, fdc_precomp); 465 - if (fdc.type >= i82077) { 466 - outb_p((fdc_rate_code & 0x03) | fdc_prec_code, fdc.dsr); 467 - } else { 468 - outb_p(fdc_rate_code & 0x03, fdc.ccr); 469 - } 470 - TRACE_EXIT; 471 - } 472 - 473 - void fdc_set_write_precomp(int precomp) 474 - { 475 - TRACE_FUN(ft_t_any); 476 - 477 - TRACE(ft_t_noise, "New precomp: %d nsec", precomp); 478 - fdc_precomp = precomp; 479 - /* write precompensation can be set in multiples of 41.67 nsec. 480 - * round the parameter to the nearest multiple and convert it 481 - * into a fdc setting. Note that 0 means default to the fdc, 482 - * 7 is used instead of that. 483 - */ 484 - fdc_prec_code = ((fdc_precomp + 21) / 42) << 2; 485 - if (fdc_prec_code == 0 || fdc_prec_code > (6 << 2)) { 486 - fdc_prec_code = 7 << 2; 487 - } 488 - fdc_update_dsr(); 489 - TRACE_EXIT; 490 - } 491 - 492 - /* Reprogram the 82078 registers to use Data Rate Table 1 on all drives. 493 - */ 494 - static void fdc_set_drive_specs(void) 495 - { 496 - __u8 cmd[] = { FDC_DRIVE_SPEC, 0x00, 0x00, 0x00, 0x00, 0xc0}; 497 - int result; 498 - TRACE_FUN(ft_t_any); 499 - 500 - TRACE(ft_t_flow, "Setting of drive specs called"); 501 - if (fdc.type >= i82078_1) { 502 - cmd[1] = (0 << 5) | (2 << 2); 503 - cmd[2] = (1 << 5) | (2 << 2); 504 - cmd[3] = (2 << 5) | (2 << 2); 505 - cmd[4] = (3 << 5) | (2 << 2); 506 - result = fdc_command(cmd, NR_ITEMS(cmd)); 507 - if (result < 0) { 508 - TRACE(ft_t_err, "Setting of drive specs failed"); 509 - } 510 - } 511 - TRACE_EXIT; 512 - } 513 - 514 - /* Select clock for fdc, must correspond with tape drive setting ! 515 - * This also influences the fdc timing so we must adjust some values. 516 - */ 517 - int fdc_set_data_rate(int rate) 518 - { 519 - int bad_rate = 0; 520 - TRACE_FUN(ft_t_any); 521 - 522 - /* Select clock for fdc, must correspond with tape drive setting ! 523 - * This also influences the fdc timing so we must adjust some values. 524 - */ 525 - TRACE(ft_t_fdc_dma, "new rate = %d", rate); 526 - switch (rate) { 527 - case 250: 528 - fdc_rate_code = fdc_data_rate_250; 529 - break; 530 - case 500: 531 - fdc_rate_code = fdc_data_rate_500; 532 - break; 533 - case 1000: 534 - if (fdc.type < i82077) { 535 - bad_rate = 1; 536 - } else { 537 - fdc_rate_code = fdc_data_rate_1000; 538 - } 539 - break; 540 - case 2000: 541 - if (fdc.type < i82078_1) { 542 - bad_rate = 1; 543 - } else { 544 - fdc_rate_code = fdc_data_rate_2000; 545 - } 546 - break; 547 - default: 548 - bad_rate = 1; 549 - } 550 - if (bad_rate) { 551 - TRACE_ABORT(-EIO, 552 - ft_t_fdc_dma, "%d is not a valid data rate", rate); 553 - } 554 - fdc_data_rate = rate; 555 - fdc_update_dsr(); 556 - fdc_set_seek_rate(fdc_seek_rate); /* clock changed! */ 557 - ftape_udelay(1000); 558 - TRACE_EXIT 0; 559 - } 560 - 561 - /* keep the unit select if keep_select is != 0, 562 - */ 563 - static void fdc_dor_reset(int keep_select) 564 - { 565 - __u8 fdc_ctl = ft_drive_sel; 566 - 567 - if (keep_select != 0) { 568 - fdc_ctl |= FDC_DMA_MODE; 569 - if (ftape_motor) { 570 - fdc_ctl |= FDC_MOTOR_0 << ft_drive_sel; 571 - } 572 - } 573 - ftape_udelay(10); /* ??? but seems to be necessary */ 574 - if (ft_mach2) { 575 - outb_p(fdc_ctl & 0x0f, fdc.dor); 576 - outb_p(fdc_ctl, fdc.dor2); 577 - } else { 578 - outb_p(fdc_ctl, fdc.dor); 579 - } 580 - fdc_usec_wait(10); /* delay >= 14 fdc clocks */ 581 - if (keep_select == 0) { 582 - fdc_ctl = 0; 583 - } 584 - fdc_ctl |= FDC_RESET_NOT; 585 - if (ft_mach2) { 586 - outb_p(fdc_ctl & 0x0f, fdc.dor); 587 - outb_p(fdc_ctl, fdc.dor2); 588 - } else { 589 - outb_p(fdc_ctl, fdc.dor); 590 - } 591 - } 592 - 593 - /* Reset the floppy disk controller. Leave the ftape_unit selected. 594 - */ 595 - void fdc_reset(void) 596 - { 597 - int st0; 598 - int i; 599 - int dummy; 600 - unsigned long flags; 601 - TRACE_FUN(ft_t_any); 602 - 603 - spin_lock_irqsave(&fdc_io_lock, flags); 604 - 605 - fdc_dor_reset(1); /* keep unit selected */ 606 - 607 - fdc_mode = fdc_idle; 608 - 609 - /* maybe the spin_lock_irq* pair is not necessary, BUT: 610 - * the following line MUST be here. Otherwise fdc_interrupt_wait() 611 - * won't wait. Note that fdc_reset() is called from 612 - * ftape_dumb_stop() when the fdc is busy transferring data. In this 613 - * case fdc_isr() MOST PROBABLY sets ft_interrupt_seen, and tries 614 - * to get the result bytes from the fdc etc. CLASH. 615 - */ 616 - ft_interrupt_seen = 0; 617 - 618 - /* Program data rate 619 - */ 620 - fdc_update_dsr(); /* restore data rate and precomp */ 621 - 622 - spin_unlock_irqrestore(&fdc_io_lock, flags); 623 - 624 - /* 625 - * Wait for first polling cycle to complete 626 - */ 627 - if (fdc_interrupt_wait(1 * FT_SECOND) < 0) { 628 - TRACE(ft_t_err, "no drive polling interrupt!"); 629 - } else { /* clear all disk-changed statuses */ 630 - for (i = 0; i < 4; ++i) { 631 - if(fdc_sense_interrupt_status(&st0, &dummy) != 0) { 632 - TRACE(ft_t_err, "sense failed for %d", i); 633 - } 634 - if (i == ft_drive_sel) { 635 - ftape_current_cylinder = dummy; 636 - } 637 - } 638 - TRACE(ft_t_noise, "drive polling completed"); 639 - } 640 - /* 641 - * SPECIFY COMMAND 642 - */ 643 - fdc_set_seek_rate(fdc_seek_rate); 644 - /* 645 - * DRIVE SPECIFICATION COMMAND (if fdc type known) 646 - */ 647 - if (fdc.type >= i82078_1) { 648 - fdc_set_drive_specs(); 649 - } 650 - TRACE_EXIT; 651 - } 652 - 653 - #if !defined(CLK_48MHZ) 654 - # define CLK_48MHZ 1 655 - #endif 656 - 657 - /* When we're done, put the fdc into reset mode so that the regular 658 - * floppy disk driver will figure out that something is wrong and 659 - * initialize the controller the way it wants. 660 - */ 661 - void fdc_disable(void) 662 - { 663 - __u8 cmd1[] = {FDC_CONFIGURE, 0x00, 0x00, 0x00}; 664 - __u8 cmd2[] = {FDC_LOCK}; 665 - __u8 cmd3[] = {FDC_UNLOCK}; 666 - __u8 stat[1]; 667 - TRACE_FUN(ft_t_flow); 668 - 669 - if (!fdc_fifo_locked) { 670 - fdc_reset(); 671 - TRACE_EXIT; 672 - } 673 - if (fdc_issue_command(cmd3, 1, stat, 1) < 0 || stat[0] != 0x00) { 674 - fdc_dor_reset(0); 675 - TRACE_ABORT(/**/, ft_t_bug, 676 - "couldn't unlock fifo, configuration remains changed"); 677 - } 678 - fdc_fifo_locked = 0; 679 - if (CLK_48MHZ && fdc.type >= i82078) { 680 - cmd1[0] |= FDC_CLK48_BIT; 681 - } 682 - cmd1[2] = ((fdc_fifo_state) ? 0 : 0x20) + (fdc_fifo_thr - 1); 683 - if (fdc_command(cmd1, NR_ITEMS(cmd1)) < 0) { 684 - fdc_dor_reset(0); 685 - TRACE_ABORT(/**/, ft_t_bug, 686 - "couldn't reconfigure fifo to old state"); 687 - } 688 - if (fdc_lock_state && 689 - fdc_issue_command(cmd2, 1, stat, 1) < 0) { 690 - fdc_dor_reset(0); 691 - TRACE_ABORT(/**/, ft_t_bug, "couldn't lock old state again"); 692 - } 693 - TRACE(ft_t_noise, "fifo restored: %sabled, thr. %d, %slocked", 694 - fdc_fifo_state ? "en" : "dis", 695 - fdc_fifo_thr, (fdc_lock_state) ? "" : "not "); 696 - fdc_dor_reset(0); 697 - TRACE_EXIT; 698 - } 699 - 700 - /* Specify FDC seek-rate (milliseconds) 701 - */ 702 - static int fdc_set_seek_rate(int seek_rate) 703 - { 704 - /* set step rate, dma mode, and minimal head load and unload times 705 - */ 706 - __u8 in[3] = { FDC_SPECIFY, 1, (1 << 1)}; 707 - 708 - fdc_seek_rate = seek_rate; 709 - in[1] |= (16 - (fdc_data_rate * fdc_seek_rate) / 500) << 4; 710 - 711 - return fdc_command(in, 3); 712 - } 713 - 714 - /* Sense drive status: get unit's drive status (ST3) 715 - */ 716 - int fdc_sense_drive_status(int *st3) 717 - { 718 - __u8 out[2]; 719 - __u8 in[1]; 720 - TRACE_FUN(ft_t_any); 721 - 722 - out[0] = FDC_SENSED; 723 - out[1] = ft_drive_sel; 724 - TRACE_CATCH(fdc_issue_command(out, 2, in, 1),); 725 - *st3 = in[0]; 726 - TRACE_EXIT 0; 727 - } 728 - 729 - /* Sense Interrupt Status command: 730 - * should be issued at the end of each seek. 731 - * get ST0 and current cylinder. 732 - */ 733 - int fdc_sense_interrupt_status(int *st0, int *current_cylinder) 734 - { 735 - __u8 out[1]; 736 - __u8 in[2]; 737 - TRACE_FUN(ft_t_any); 738 - 739 - out[0] = FDC_SENSEI; 740 - TRACE_CATCH(fdc_issue_command(out, 1, in, 2),); 741 - *st0 = in[0]; 742 - *current_cylinder = in[1]; 743 - TRACE_EXIT 0; 744 - } 745 - 746 - /* step to track 747 - */ 748 - int fdc_seek(int track) 749 - { 750 - __u8 out[3]; 751 - int st0, pcn; 752 - #ifdef TESTING 753 - unsigned int time; 754 - #endif 755 - TRACE_FUN(ft_t_any); 756 - 757 - out[0] = FDC_SEEK; 758 - out[1] = ft_drive_sel; 759 - out[2] = track; 760 - #ifdef TESTING 761 - time = ftape_timestamp(); 762 - #endif 763 - /* We really need this command to work ! 764 - */ 765 - ft_seek_completed = 0; 766 - TRACE_CATCH(fdc_command(out, 3), 767 - fdc_reset(); 768 - TRACE(ft_t_noise, "destination was: %d, resetting FDC...", 769 - track)); 770 - /* Handle interrupts until ft_seek_completed or timeout. 771 - */ 772 - for (;;) { 773 - TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),); 774 - if (ft_seek_completed) { 775 - TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),); 776 - if ((st0 & ST0_SEEK_END) == 0) { 777 - TRACE_ABORT(-EIO, ft_t_err, 778 - "no seek-end after seek completion !??"); 779 - } 780 - break; 781 - } 782 - } 783 - #ifdef TESTING 784 - time = ftape_timediff(time, ftape_timestamp()) / abs(track - ftape_current_cylinder); 785 - if ((time < 900 || time > 3100) && abs(track - ftape_current_cylinder) > 5) { 786 - TRACE(ft_t_warn, "Wrong FDC STEP interval: %d usecs (%d)", 787 - time, track - ftape_current_cylinder); 788 - } 789 - #endif 790 - /* Verify whether we issued the right tape command. 791 - */ 792 - /* Verify that we seek to the proper track. */ 793 - if (pcn != track) { 794 - TRACE_ABORT(-EIO, ft_t_err, "bad seek.."); 795 - } 796 - ftape_current_cylinder = track; 797 - TRACE_EXIT 0; 798 - } 799 - 800 - static int perpend_mode; /* set if fdc is in perpendicular mode */ 801 - 802 - static int perpend_off(void) 803 - { 804 - __u8 perpend[] = {FDC_PERPEND, 0x00}; 805 - TRACE_FUN(ft_t_any); 806 - 807 - if (perpend_mode) { 808 - /* Turn off perpendicular mode */ 809 - perpend[1] = 0x80; 810 - TRACE_CATCH(fdc_command(perpend, 2), 811 - TRACE(ft_t_err,"Perpendicular mode exit failed!")); 812 - perpend_mode = 0; 813 - } 814 - TRACE_EXIT 0; 815 - } 816 - 817 - static int handle_perpend(int segment_id) 818 - { 819 - __u8 perpend[] = {FDC_PERPEND, 0x00}; 820 - TRACE_FUN(ft_t_any); 821 - 822 - /* When writing QIC-3020 tapes, turn on perpendicular mode 823 - * if tape is moving in forward direction (even tracks). 824 - */ 825 - if (ft_qic_std == QIC_TAPE_QIC3020 && 826 - ((segment_id / ft_segments_per_track) & 1) == 0) { 827 - /* FIXME: some i82077 seem to support perpendicular mode as 828 - * well. 829 - */ 830 - #if 0 831 - if (fdc.type < i82077AA) {} 832 - #else 833 - if (fdc.type < i82077 && ft_data_rate < 1000) { 834 - #endif 835 - /* fdc does not support perpendicular mode: complain 836 - */ 837 - TRACE_ABORT(-EIO, ft_t_err, 838 - "Your FDC does not support QIC-3020."); 839 - } 840 - perpend[1] = 0x03 /* 0x83 + (0x4 << ft_drive_sel) */ ; 841 - TRACE_CATCH(fdc_command(perpend, 2), 842 - TRACE(ft_t_err,"Perpendicular mode entry failed!")); 843 - TRACE(ft_t_flow, "Perpendicular mode set"); 844 - perpend_mode = 1; 845 - TRACE_EXIT 0; 846 - } 847 - TRACE_EXIT perpend_off(); 848 - } 849 - 850 - static inline void fdc_setup_dma(char mode, 851 - volatile void *addr, unsigned int count) 852 - { 853 - /* Program the DMA controller. 854 - */ 855 - disable_dma(fdc.dma); 856 - clear_dma_ff(fdc.dma); 857 - set_dma_mode(fdc.dma, mode); 858 - set_dma_addr(fdc.dma, virt_to_bus((void*)addr)); 859 - set_dma_count(fdc.dma, count); 860 - enable_dma(fdc.dma); 861 - } 862 - 863 - /* Setup fdc and dma for formatting the next segment 864 - */ 865 - int fdc_setup_formatting(buffer_struct * buff) 866 - { 867 - unsigned long flags; 868 - __u8 out[6] = { 869 - FDC_FORMAT, 0x00, 3, 4 * FT_SECTORS_PER_SEGMENT, 0x00, 0x6b 870 - }; 871 - TRACE_FUN(ft_t_any); 872 - 873 - TRACE_CATCH(handle_perpend(buff->segment_id),); 874 - /* Program the DMA controller. 875 - */ 876 - TRACE(ft_t_fdc_dma, 877 - "phys. addr. = %lx", virt_to_bus((void*) buff->ptr)); 878 - spin_lock_irqsave(&fdc_io_lock, flags); 879 - fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4); 880 - /* Issue FDC command to start reading/writing. 881 - */ 882 - out[1] = ft_drive_sel; 883 - out[4] = buff->gap3; 884 - TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)), 885 - restore_flags(flags); fdc_mode = fdc_idle); 886 - spin_unlock_irqrestore(&fdc_io_lock, flags); 887 - TRACE_EXIT 0; 888 - } 889 - 890 - 891 - /* Setup Floppy Disk Controller and DMA to read or write the next cluster 892 - * of good sectors from or to the current segment. 893 - */ 894 - int fdc_setup_read_write(buffer_struct * buff, __u8 operation) 895 - { 896 - unsigned long flags; 897 - __u8 out[9]; 898 - int dma_mode; 899 - TRACE_FUN(ft_t_any); 900 - 901 - switch(operation) { 902 - case FDC_VERIFY: 903 - if (fdc.type < i82077) { 904 - operation = FDC_READ; 905 - } 906 - case FDC_READ: 907 - case FDC_READ_DELETED: 908 - dma_mode = DMA_MODE_READ; 909 - TRACE(ft_t_fdc_dma, "xfer %d sectors to 0x%p", 910 - buff->sector_count, buff->ptr); 911 - TRACE_CATCH(perpend_off(),); 912 - break; 913 - case FDC_WRITE_DELETED: 914 - TRACE(ft_t_noise, "deleting segment %d", buff->segment_id); 915 - case FDC_WRITE: 916 - dma_mode = DMA_MODE_WRITE; 917 - /* When writing QIC-3020 tapes, turn on perpendicular mode 918 - * if tape is moving in forward direction (even tracks). 919 - */ 920 - TRACE_CATCH(handle_perpend(buff->segment_id),); 921 - TRACE(ft_t_fdc_dma, "xfer %d sectors from 0x%p", 922 - buff->sector_count, buff->ptr); 923 - break; 924 - default: 925 - TRACE_ABORT(-EIO, 926 - ft_t_bug, "bug: invalid operation parameter"); 927 - } 928 - TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr)); 929 - spin_lock_irqsave(&fdc_io_lock, flags); 930 - if (operation != FDC_VERIFY) { 931 - fdc_setup_dma(dma_mode, buff->ptr, 932 - FT_SECTOR_SIZE * buff->sector_count); 933 - } 934 - /* Issue FDC command to start reading/writing. 935 - */ 936 - out[0] = operation; 937 - out[1] = ft_drive_sel; 938 - out[2] = buff->cyl; 939 - out[3] = buff->head; 940 - out[4] = buff->sect + buff->sector_offset; 941 - out[5] = 3; /* Sector size of 1K. */ 942 - out[6] = out[4] + buff->sector_count - 1; /* last sector */ 943 - out[7] = 109; /* Gap length. */ 944 - out[8] = 0xff; /* No limit to transfer size. */ 945 - TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x", 946 - out[2], out[3], out[4], out[6] - out[4] + 1); 947 - spin_unlock_irqrestore(&fdc_io_lock, flags); 948 - TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle); 949 - TRACE_EXIT 0; 950 - } 951 - 952 - int fdc_fifo_threshold(__u8 threshold, 953 - int *fifo_state, int *lock_state, int *fifo_thr) 954 - { 955 - const __u8 cmd0[] = {FDC_DUMPREGS}; 956 - __u8 cmd1[] = {FDC_CONFIGURE, 0, (0x0f & (threshold - 1)), 0}; 957 - const __u8 cmd2[] = {FDC_LOCK}; 958 - const __u8 cmd3[] = {FDC_UNLOCK}; 959 - __u8 reg[10]; 960 - __u8 stat; 961 - int i; 962 - int result; 963 - TRACE_FUN(ft_t_any); 964 - 965 - if (CLK_48MHZ && fdc.type >= i82078) { 966 - cmd1[0] |= FDC_CLK48_BIT; 967 - } 968 - /* Dump fdc internal registers for examination 969 - */ 970 - TRACE_CATCH(fdc_command(cmd0, NR_ITEMS(cmd0)), 971 - TRACE(ft_t_warn, "dumpreg cmd failed, fifo unchanged")); 972 - /* Now read fdc internal registers from fifo 973 - */ 974 - for (i = 0; i < (int)NR_ITEMS(reg); ++i) { 975 - fdc_read(&reg[i]); 976 - TRACE(ft_t_fdc_dma, "Register %d = 0x%02x", i, reg[i]); 977 - } 978 - if (fifo_state && lock_state && fifo_thr) { 979 - *fifo_state = (reg[8] & 0x20) == 0; 980 - *lock_state = reg[7] & 0x80; 981 - *fifo_thr = 1 + (reg[8] & 0x0f); 982 - } 983 - TRACE(ft_t_noise, 984 - "original fifo state: %sabled, threshold %d, %slocked", 985 - ((reg[8] & 0x20) == 0) ? "en" : "dis", 986 - 1 + (reg[8] & 0x0f), (reg[7] & 0x80) ? "" : "not "); 987 - /* If fdc is already locked, unlock it first ! */ 988 - if (reg[7] & 0x80) { 989 - fdc_ready_wait(100); 990 - TRACE_CATCH(fdc_issue_command(cmd3, NR_ITEMS(cmd3), &stat, 1), 991 - TRACE(ft_t_bug, "FDC unlock command failed, " 992 - "configuration unchanged")); 993 - } 994 - fdc_fifo_locked = 0; 995 - /* Enable fifo and set threshold at xx bytes to allow a 996 - * reasonably large latency and reduce number of dma bursts. 997 - */ 998 - fdc_ready_wait(100); 999 - if ((result = fdc_command(cmd1, NR_ITEMS(cmd1))) < 0) { 1000 - TRACE(ft_t_bug, "configure cmd failed, fifo unchanged"); 1001 - } 1002 - /* Now lock configuration so reset will not change it 1003 - */ 1004 - if(fdc_issue_command(cmd2, NR_ITEMS(cmd2), &stat, 1) < 0 || 1005 - stat != 0x10) { 1006 - TRACE_ABORT(-EIO, ft_t_bug, 1007 - "FDC lock command failed, stat = 0x%02x", stat); 1008 - } 1009 - fdc_fifo_locked = 1; 1010 - TRACE_EXIT result; 1011 - } 1012 - 1013 - static int fdc_fifo_enable(void) 1014 - { 1015 - TRACE_FUN(ft_t_any); 1016 - 1017 - if (fdc_fifo_locked) { 1018 - TRACE_ABORT(0, ft_t_warn, "Fifo not enabled because locked"); 1019 - } 1020 - TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */, 1021 - &fdc_fifo_state, 1022 - &fdc_lock_state, 1023 - &fdc_fifo_thr),); 1024 - TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */, 1025 - NULL, NULL, NULL),); 1026 - TRACE_EXIT 0; 1027 - } 1028 - 1029 - /* Determine fd controller type 1030 - */ 1031 - static __u8 fdc_save_state[2]; 1032 - 1033 - static int fdc_probe(void) 1034 - { 1035 - __u8 cmd[1]; 1036 - __u8 stat[16]; /* must be able to hold dumpregs & save results */ 1037 - int i; 1038 - TRACE_FUN(ft_t_any); 1039 - 1040 - /* Try to find out what kind of fd controller we have to deal with 1041 - * Scheme borrowed from floppy driver: 1042 - * first try if FDC_DUMPREGS command works 1043 - * (this indicates that we have a 82072 or better) 1044 - * then try the FDC_VERSION command (82072 doesn't support this) 1045 - * then try the FDC_UNLOCK command (some older 82077's don't support this) 1046 - * then try the FDC_PARTID command (82078's support this) 1047 - */ 1048 - cmd[0] = FDC_DUMPREGS; 1049 - if (fdc_issue_command(cmd, 1, stat, 1) != 0) { 1050 - TRACE_ABORT(no_fdc, ft_t_bug, "No FDC found"); 1051 - } 1052 - if (stat[0] == 0x80) { 1053 - /* invalid command: must be pre 82072 */ 1054 - TRACE_ABORT(i8272, 1055 - ft_t_warn, "Type 8272A/765A compatible FDC found"); 1056 - } 1057 - fdc_result(&stat[1], 9); 1058 - fdc_save_state[0] = stat[7]; 1059 - fdc_save_state[1] = stat[8]; 1060 - cmd[0] = FDC_VERSION; 1061 - if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) { 1062 - TRACE_ABORT(i8272, ft_t_warn, "Type 82072 FDC found"); 1063 - } 1064 - if (*stat != 0x90) { 1065 - TRACE_ABORT(i8272, ft_t_warn, "Unknown FDC found"); 1066 - } 1067 - cmd[0] = FDC_UNLOCK; 1068 - if(fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] != 0x00) { 1069 - TRACE_ABORT(i8272, ft_t_warn, 1070 - "Type pre-1991 82077 FDC found, " 1071 - "treating it like a 82072"); 1072 - } 1073 - if (fdc_save_state[0] & 0x80) { /* was locked */ 1074 - cmd[0] = FDC_LOCK; /* restore lock */ 1075 - (void)fdc_issue_command(cmd, 1, stat, 1); 1076 - TRACE(ft_t_warn, "FDC is already locked"); 1077 - } 1078 - /* Test for a i82078 FDC */ 1079 - cmd[0] = FDC_PARTID; 1080 - if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) { 1081 - /* invalid command: not a i82078xx type FDC */ 1082 - for (i = 0; i < 4; ++i) { 1083 - outb_p(i, fdc.tdr); 1084 - if ((inb_p(fdc.tdr) & 0x03) != i) { 1085 - TRACE_ABORT(i82077, 1086 - ft_t_warn, "Type 82077 FDC found"); 1087 - } 1088 - } 1089 - TRACE_ABORT(i82077AA, ft_t_warn, "Type 82077AA FDC found"); 1090 - } 1091 - /* FDC_PARTID cmd succeeded */ 1092 - switch (stat[0] >> 5) { 1093 - case 0x0: 1094 - /* i82078SL or i82078-1. The SL part cannot run at 1095 - * 2Mbps (the SL and -1 dies are identical; they are 1096 - * speed graded after production, according to Intel). 1097 - * Some SL's can be detected by doing a SAVE cmd and 1098 - * look at bit 7 of the first byte (the SEL3V# bit). 1099 - * If it is 0, the part runs off 3Volts, and hence it 1100 - * is a SL. 1101 - */ 1102 - cmd[0] = FDC_SAVE; 1103 - if(fdc_issue_command(cmd, 1, stat, 16) < 0) { 1104 - TRACE(ft_t_err, "FDC_SAVE failed. Dunno why"); 1105 - /* guess we better claim the fdc to be a i82078 */ 1106 - TRACE_ABORT(i82078, 1107 - ft_t_warn, 1108 - "Type i82078 FDC (i suppose) found"); 1109 - } 1110 - if ((stat[0] & FDC_SEL3V_BIT)) { 1111 - /* fdc running off 5Volts; Pray that it's a i82078-1 1112 - */ 1113 - TRACE_ABORT(i82078_1, ft_t_warn, 1114 - "Type i82078-1 or 5Volt i82078SL FDC found"); 1115 - } 1116 - TRACE_ABORT(i82078, ft_t_warn, 1117 - "Type 3Volt i82078SL FDC (1Mbps) found"); 1118 - case 0x1: 1119 - case 0x2: /* S82078B */ 1120 - /* The '78B isn't '78 compatible. Detect it as a '77AA */ 1121 - TRACE_ABORT(i82077AA, ft_t_warn, "Type i82077AA FDC found"); 1122 - case 0x3: /* NSC PC8744 core; used in several super-IO chips */ 1123 - TRACE_ABORT(i82077AA, 1124 - ft_t_warn, "Type 82077AA compatible FDC found"); 1125 - default: 1126 - TRACE(ft_t_warn, "A previously undetected FDC found"); 1127 - TRACE_ABORT(i82077AA, ft_t_warn, 1128 - "Treating it as a 82077AA. Please report partid= %d", 1129 - stat[0]); 1130 - } /* switch(stat[ 0] >> 5) */ 1131 - TRACE_EXIT no_fdc; 1132 - } 1133 - 1134 - static int fdc_request_regions(void) 1135 - { 1136 - TRACE_FUN(ft_t_flow); 1137 - 1138 - if (ft_mach2 || ft_probe_fc10) { 1139 - if (!request_region(fdc.sra, 8, "fdc (ft)")) { 1140 - #ifndef BROKEN_FLOPPY_DRIVER 1141 - TRACE_EXIT -EBUSY; 1142 - #else 1143 - TRACE(ft_t_warn, 1144 - "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra); 1145 - #endif 1146 - } 1147 - } else { 1148 - if (!request_region(fdc.sra, 6, "fdc (ft)")) { 1149 - #ifndef BROKEN_FLOPPY_DRIVER 1150 - TRACE_EXIT -EBUSY; 1151 - #else 1152 - TRACE(ft_t_warn, 1153 - "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra); 1154 - #endif 1155 - } 1156 - if (!request_region(fdc.sra + 7, 1, "fdc (ft)")) { 1157 - #ifndef BROKEN_FLOPPY_DRIVER 1158 - release_region(fdc.sra, 6); 1159 - TRACE_EXIT -EBUSY; 1160 - #else 1161 - TRACE(ft_t_warn, 1162 - "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra + 7); 1163 - #endif 1164 - } 1165 - } 1166 - TRACE_EXIT 0; 1167 - } 1168 - 1169 - void fdc_release_regions(void) 1170 - { 1171 - TRACE_FUN(ft_t_flow); 1172 - 1173 - if (fdc.sra != 0) { 1174 - if (fdc.dor2 != 0) { 1175 - release_region(fdc.sra, 8); 1176 - } else { 1177 - release_region(fdc.sra, 6); 1178 - release_region(fdc.dir, 1); 1179 - } 1180 - } 1181 - TRACE_EXIT; 1182 - } 1183 - 1184 - static int fdc_config_regs(unsigned int fdc_base, 1185 - unsigned int fdc_irq, 1186 - unsigned int fdc_dma) 1187 - { 1188 - TRACE_FUN(ft_t_flow); 1189 - 1190 - fdc.irq = fdc_irq; 1191 - fdc.dma = fdc_dma; 1192 - fdc.sra = fdc_base; 1193 - fdc.srb = fdc_base + 1; 1194 - fdc.dor = fdc_base + 2; 1195 - fdc.tdr = fdc_base + 3; 1196 - fdc.msr = fdc.dsr = fdc_base + 4; 1197 - fdc.fifo = fdc_base + 5; 1198 - fdc.dir = fdc.ccr = fdc_base + 7; 1199 - fdc.dor2 = (ft_mach2 || ft_probe_fc10) ? fdc_base + 6 : 0; 1200 - TRACE_CATCH(fdc_request_regions(), fdc.sra = 0); 1201 - TRACE_EXIT 0; 1202 - } 1203 - 1204 - static int fdc_config(void) 1205 - { 1206 - static int already_done; 1207 - TRACE_FUN(ft_t_any); 1208 - 1209 - if (already_done) { 1210 - TRACE_CATCH(fdc_request_regions(),); 1211 - *(fdc.hook) = fdc_isr; /* hook our handler in */ 1212 - TRACE_EXIT 0; 1213 - } 1214 - if (ft_probe_fc10) { 1215 - int fc_type; 1216 - 1217 - TRACE_CATCH(fdc_config_regs(ft_fdc_base, 1218 - ft_fdc_irq, ft_fdc_dma),); 1219 - fc_type = fc10_enable(); 1220 - if (fc_type != 0) { 1221 - TRACE(ft_t_warn, "FC-%c0 controller found", '0' + fc_type); 1222 - fdc.type = fc10; 1223 - fdc.hook = &do_ftape; 1224 - *(fdc.hook) = fdc_isr; /* hook our handler in */ 1225 - already_done = 1; 1226 - TRACE_EXIT 0; 1227 - } else { 1228 - TRACE(ft_t_warn, "FC-10/20 controller not found"); 1229 - fdc_release_regions(); 1230 - fdc.type = no_fdc; 1231 - ft_probe_fc10 = 0; 1232 - ft_fdc_base = 0x3f0; 1233 - ft_fdc_irq = 6; 1234 - ft_fdc_dma = 2; 1235 - } 1236 - } 1237 - TRACE(ft_t_warn, "fdc base: 0x%x, irq: %d, dma: %d", 1238 - ft_fdc_base, ft_fdc_irq, ft_fdc_dma); 1239 - TRACE_CATCH(fdc_config_regs(ft_fdc_base, ft_fdc_irq, ft_fdc_dma),); 1240 - fdc.hook = &do_ftape; 1241 - *(fdc.hook) = fdc_isr; /* hook our handler in */ 1242 - already_done = 1; 1243 - TRACE_EXIT 0; 1244 - } 1245 - 1246 - static irqreturn_t ftape_interrupt(int irq, void *dev_id) 1247 - { 1248 - void (*handler) (void) = *fdc.hook; 1249 - int handled = 0; 1250 - TRACE_FUN(ft_t_any); 1251 - 1252 - *fdc.hook = NULL; 1253 - if (handler) { 1254 - handled = 1; 1255 - handler(); 1256 - } else { 1257 - TRACE(ft_t_bug, "Unexpected ftape interrupt"); 1258 - } 1259 - TRACE_EXIT IRQ_RETVAL(handled); 1260 - } 1261 - 1262 - static int fdc_grab_irq_and_dma(void) 1263 - { 1264 - TRACE_FUN(ft_t_any); 1265 - 1266 - if (fdc.hook == &do_ftape) { 1267 - /* Get fast interrupt handler. 1268 - */ 1269 - if (request_irq(fdc.irq, ftape_interrupt, 1270 - IRQF_DISABLED, "ft", ftape_id)) { 1271 - TRACE_ABORT(-EIO, ft_t_bug, 1272 - "Unable to grab IRQ%d for ftape driver", 1273 - fdc.irq); 1274 - } 1275 - if (request_dma(fdc.dma, ftape_id)) { 1276 - free_irq(fdc.irq, ftape_id); 1277 - TRACE_ABORT(-EIO, ft_t_bug, 1278 - "Unable to grab DMA%d for ftape driver", 1279 - fdc.dma); 1280 - } 1281 - } 1282 - if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) { 1283 - /* Using same dma channel or irq as standard fdc, need 1284 - * to disable the dma-gate on the std fdc. This 1285 - * couldn't be done in the floppy driver as some 1286 - * laptops are using the dma-gate to enter a low power 1287 - * or even suspended state :-( 1288 - */ 1289 - outb_p(FDC_RESET_NOT, 0x3f2); 1290 - TRACE(ft_t_noise, "DMA-gate on standard fdc disabled"); 1291 - } 1292 - TRACE_EXIT 0; 1293 - } 1294 - 1295 - int fdc_release_irq_and_dma(void) 1296 - { 1297 - TRACE_FUN(ft_t_any); 1298 - 1299 - if (fdc.hook == &do_ftape) { 1300 - disable_dma(fdc.dma); /* just in case... */ 1301 - free_dma(fdc.dma); 1302 - free_irq(fdc.irq, ftape_id); 1303 - } 1304 - if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) { 1305 - /* Using same dma channel as standard fdc, need to 1306 - * disable the dma-gate on the std fdc. This couldn't 1307 - * be done in the floppy driver as some laptops are 1308 - * using the dma-gate to enter a low power or even 1309 - * suspended state :-( 1310 - */ 1311 - outb_p(FDC_RESET_NOT | FDC_DMA_MODE, 0x3f2); 1312 - TRACE(ft_t_noise, "DMA-gate on standard fdc enabled again"); 1313 - } 1314 - TRACE_EXIT 0; 1315 - } 1316 - 1317 - int fdc_init(void) 1318 - { 1319 - TRACE_FUN(ft_t_any); 1320 - 1321 - /* find a FDC to use */ 1322 - TRACE_CATCH(fdc_config(),); 1323 - TRACE_CATCH(fdc_grab_irq_and_dma(), fdc_release_regions()); 1324 - ftape_motor = 0; 1325 - fdc_catch_stray_interrupts(0); /* clear number of awainted 1326 - * stray interrupte 1327 - */ 1328 - fdc_catch_stray_interrupts(1); /* one always comes (?) */ 1329 - TRACE(ft_t_flow, "resetting fdc"); 1330 - fdc_set_seek_rate(2); /* use nominal QIC step rate */ 1331 - fdc_reset(); /* init fdc & clear track counters */ 1332 - if (fdc.type == no_fdc) { /* no FC-10 or FC-20 found */ 1333 - fdc.type = fdc_probe(); 1334 - fdc_reset(); /* update with new knowledge */ 1335 - } 1336 - if (fdc.type == no_fdc) { 1337 - fdc_release_irq_and_dma(); 1338 - fdc_release_regions(); 1339 - TRACE_EXIT -ENXIO; 1340 - } 1341 - if (fdc.type >= i82077) { 1342 - if (fdc_fifo_enable() < 0) { 1343 - TRACE(ft_t_warn, "couldn't enable fdc fifo !"); 1344 - } else { 1345 - TRACE(ft_t_flow, "fdc fifo enabled and locked"); 1346 - } 1347 - } 1348 - TRACE_EXIT 0; 1349 - }
-252
drivers/char/ftape/lowlevel/fdc-io.h
··· 1 - #ifndef _FDC_IO_H 2 - #define _FDC_IO_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.h,v $ 24 - * $Revision: 1.3 $ 25 - * $Date: 1997/10/05 19:18:06 $ 26 - * 27 - * This file contains the declarations for the low level 28 - * functions that communicate with the floppy disk controller, 29 - * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for 30 - * Linux. 31 - */ 32 - 33 - #include <linux/fdreg.h> 34 - 35 - #include "../lowlevel/ftape-bsm.h" 36 - 37 - #define FDC_SK_BIT (0x20) 38 - #define FDC_MT_BIT (0x80) 39 - 40 - #define FDC_READ (FD_READ & ~(FDC_SK_BIT | FDC_MT_BIT)) 41 - #define FDC_WRITE (FD_WRITE & ~FDC_MT_BIT) 42 - #define FDC_READ_DELETED (0x4c) 43 - #define FDC_WRITE_DELETED (0x49) 44 - #define FDC_VERIFY (0x56) 45 - #define FDC_READID (0x4a) 46 - #define FDC_SENSED (0x04) 47 - #define FDC_SENSEI (FD_SENSEI) 48 - #define FDC_FORMAT (FD_FORMAT) 49 - #define FDC_RECAL (FD_RECALIBRATE) 50 - #define FDC_SEEK (FD_SEEK) 51 - #define FDC_SPECIFY (FD_SPECIFY) 52 - #define FDC_RECALIBR (FD_RECALIBRATE) 53 - #define FDC_VERSION (FD_VERSION) 54 - #define FDC_PERPEND (FD_PERPENDICULAR) 55 - #define FDC_DUMPREGS (FD_DUMPREGS) 56 - #define FDC_LOCK (FD_LOCK) 57 - #define FDC_UNLOCK (FD_UNLOCK) 58 - #define FDC_CONFIGURE (FD_CONFIGURE) 59 - #define FDC_DRIVE_SPEC (0x8e) /* i82078 has this (any others?) */ 60 - #define FDC_PARTID (0x18) /* i82078 has this */ 61 - #define FDC_SAVE (0x2e) /* i82078 has this (any others?) */ 62 - #define FDC_RESTORE (0x4e) /* i82078 has this (any others?) */ 63 - 64 - #define FDC_STATUS_MASK (STATUS_BUSY | STATUS_DMA | STATUS_DIR | STATUS_READY) 65 - #define FDC_DATA_READY (STATUS_READY) 66 - #define FDC_DATA_OUTPUT (STATUS_DIR) 67 - #define FDC_DATA_READY_MASK (STATUS_READY | STATUS_DIR) 68 - #define FDC_DATA_OUT_READY (STATUS_READY | STATUS_DIR) 69 - #define FDC_DATA_IN_READY (STATUS_READY) 70 - #define FDC_BUSY (STATUS_BUSY) 71 - #define FDC_CLK48_BIT (0x80) 72 - #define FDC_SEL3V_BIT (0x40) 73 - 74 - #define ST0_INT_MASK (ST0_INTR) 75 - #define FDC_INT_NORMAL (ST0_INTR & 0x00) 76 - #define FDC_INT_ABNORMAL (ST0_INTR & 0x40) 77 - #define FDC_INT_INVALID (ST0_INTR & 0x80) 78 - #define FDC_INT_READYCH (ST0_INTR & 0xC0) 79 - #define ST0_SEEK_END (ST0_SE) 80 - #define ST3_TRACK_0 (ST3_TZ) 81 - 82 - #define FDC_RESET_NOT (0x04) 83 - #define FDC_DMA_MODE (0x08) 84 - #define FDC_MOTOR_0 (0x10) 85 - #define FDC_MOTOR_1 (0x20) 86 - 87 - typedef struct { 88 - void (**hook) (void); /* our wedge into the isr */ 89 - enum { 90 - no_fdc, i8272, i82077, i82077AA, fc10, 91 - i82078, i82078_1 92 - } type; /* FDC type */ 93 - unsigned int irq; /* FDC irq nr */ 94 - unsigned int dma; /* FDC dma channel nr */ 95 - __u16 sra; /* Status register A (PS/2 only) */ 96 - __u16 srb; /* Status register B (PS/2 only) */ 97 - __u16 dor; /* Digital output register */ 98 - __u16 tdr; /* Tape Drive Register (82077SL-1 & 99 - 82078 only) */ 100 - __u16 msr; /* Main Status Register */ 101 - __u16 dsr; /* Datarate Select Register (8207x only) */ 102 - __u16 fifo; /* Data register / Fifo on 8207x */ 103 - __u16 dir; /* Digital Input Register */ 104 - __u16 ccr; /* Configuration Control Register */ 105 - __u16 dor2; /* Alternate dor on MACH-2 controller, 106 - also used with FC-10, meaning unknown */ 107 - } fdc_config_info; 108 - 109 - typedef enum { 110 - fdc_data_rate_250 = 2, 111 - fdc_data_rate_300 = 1, /* any fdc in default configuration */ 112 - fdc_data_rate_500 = 0, 113 - fdc_data_rate_1000 = 3, 114 - fdc_data_rate_2000 = 1, /* i82078-1: when using Data Rate Table #2 */ 115 - } fdc_data_rate_type; 116 - 117 - typedef enum { 118 - fdc_idle = 0, 119 - fdc_reading_data = FDC_READ, 120 - fdc_seeking = FDC_SEEK, 121 - fdc_writing_data = FDC_WRITE, 122 - fdc_deleting = FDC_WRITE_DELETED, 123 - fdc_reading_id = FDC_READID, 124 - fdc_recalibrating = FDC_RECAL, 125 - fdc_formatting = FDC_FORMAT, 126 - fdc_verifying = FDC_VERIFY 127 - } fdc_mode_enum; 128 - 129 - typedef enum { 130 - waiting = 0, 131 - reading, 132 - writing, 133 - formatting, 134 - verifying, 135 - deleting, 136 - done, 137 - error, 138 - mmapped, 139 - } buffer_state_enum; 140 - 141 - typedef struct { 142 - __u8 *address; 143 - volatile buffer_state_enum status; 144 - volatile __u8 *ptr; 145 - volatile unsigned int bytes; 146 - volatile unsigned int segment_id; 147 - 148 - /* bitmap for remainder of segment not yet handled. 149 - * one bit set for each bad sector that must be skipped. 150 - */ 151 - volatile SectorMap bad_sector_map; 152 - 153 - /* bitmap with bad data blocks in data buffer. 154 - * the errors in this map may be retried. 155 - */ 156 - volatile SectorMap soft_error_map; 157 - 158 - /* bitmap with bad data blocks in data buffer 159 - * the errors in this map may not be retried. 160 - */ 161 - volatile SectorMap hard_error_map; 162 - 163 - /* retry counter for soft errors. 164 - */ 165 - volatile int retry; 166 - 167 - /* sectors to skip on retry ??? 168 - */ 169 - volatile unsigned int skip; 170 - 171 - /* nr of data blocks in data buffer 172 - */ 173 - volatile unsigned int data_offset; 174 - 175 - /* offset in segment for first sector to be handled. 176 - */ 177 - volatile unsigned int sector_offset; 178 - 179 - /* size of cluster of good sectors to be handled. 180 - */ 181 - volatile unsigned int sector_count; 182 - 183 - /* size of remaining part of segment to be handled. 184 - */ 185 - volatile unsigned int remaining; 186 - 187 - /* points to next segment (contiguous) to be handled, 188 - * or is zero if no read-ahead is allowed. 189 - */ 190 - volatile unsigned int next_segment; 191 - 192 - /* flag being set if deleted data was read. 193 - */ 194 - volatile int deleted; 195 - 196 - /* floppy coordinates of first sector in segment */ 197 - volatile __u8 head; 198 - volatile __u8 cyl; 199 - volatile __u8 sect; 200 - 201 - /* gap to use when formatting */ 202 - __u8 gap3; 203 - /* flag set when buffer is mmaped */ 204 - int mmapped; 205 - } buffer_struct; 206 - 207 - /* 208 - * fdc-io.c defined public variables 209 - */ 210 - extern volatile fdc_mode_enum fdc_mode; 211 - extern int fdc_setup_error; /* outdated ??? */ 212 - extern wait_queue_head_t ftape_wait_intr; 213 - extern volatile int ftape_current_cylinder; /* track nr FDC thinks we're on */ 214 - extern volatile __u8 fdc_head; /* FDC head */ 215 - extern volatile __u8 fdc_cyl; /* FDC track */ 216 - extern volatile __u8 fdc_sect; /* FDC sector */ 217 - extern fdc_config_info fdc; /* FDC hardware configuration */ 218 - 219 - extern unsigned int ft_fdc_base; 220 - extern unsigned int ft_fdc_irq; 221 - extern unsigned int ft_fdc_dma; 222 - extern unsigned int ft_fdc_threshold; 223 - extern unsigned int ft_fdc_rate_limit; 224 - extern int ft_probe_fc10; 225 - extern int ft_mach2; 226 - /* 227 - * fdc-io.c defined public functions 228 - */ 229 - extern void fdc_catch_stray_interrupts(int count); 230 - extern int fdc_ready_wait(unsigned int timeout); 231 - extern int fdc_command(const __u8 * cmd_data, int cmd_len); 232 - extern int fdc_result(__u8 * res_data, int res_len); 233 - extern int fdc_interrupt_wait(unsigned int time); 234 - extern int fdc_seek(int track); 235 - extern int fdc_sense_drive_status(int *st3); 236 - extern void fdc_motor(int motor); 237 - extern void fdc_reset(void); 238 - extern void fdc_disable(void); 239 - extern int fdc_fifo_threshold(__u8 threshold, 240 - int *fifo_state, int *lock_state, int *fifo_thr); 241 - extern void fdc_wait_calibrate(void); 242 - extern int fdc_sense_interrupt_status(int *st0, int *current_cylinder); 243 - extern void fdc_save_drive_specs(void); 244 - extern void fdc_restore_drive_specs(void); 245 - extern int fdc_set_data_rate(int rate); 246 - extern void fdc_set_write_precomp(int precomp); 247 - extern int fdc_release_irq_and_dma(void); 248 - extern void fdc_release_regions(void); 249 - extern int fdc_init(void); 250 - extern int fdc_setup_read_write(buffer_struct * buff, __u8 operation); 251 - extern int fdc_setup_formatting(buffer_struct * buff); 252 - #endif
-1170
drivers/char/ftape/lowlevel/fdc-isr.c
··· 1 - /* 2 - * Copyright (C) 1994-1996 Bas Laarhoven, 3 - * (C) 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-isr.c,v $ 21 - * $Revision: 1.9 $ 22 - * $Date: 1997/10/17 23:01:53 $ 23 - * 24 - * This file contains the interrupt service routine and 25 - * associated code for the QIC-40/80/3010/3020 floppy-tape driver 26 - * "ftape" for Linux. 27 - */ 28 - 29 - #include <asm/io.h> 30 - #include <asm/dma.h> 31 - 32 - #define volatile /* */ 33 - 34 - #include <linux/ftape.h> 35 - #include <linux/qic117.h> 36 - #include "../lowlevel/ftape-tracing.h" 37 - #include "../lowlevel/fdc-isr.h" 38 - #include "../lowlevel/fdc-io.h" 39 - #include "../lowlevel/ftape-ctl.h" 40 - #include "../lowlevel/ftape-rw.h" 41 - #include "../lowlevel/ftape-io.h" 42 - #include "../lowlevel/ftape-calibr.h" 43 - #include "../lowlevel/ftape-bsm.h" 44 - 45 - /* Global vars. 46 - */ 47 - volatile int ft_expected_stray_interrupts; 48 - volatile int ft_interrupt_seen; 49 - volatile int ft_seek_completed; 50 - volatile int ft_hide_interrupt; 51 - /* Local vars. 52 - */ 53 - typedef enum { 54 - no_error = 0, id_am_error = 0x01, id_crc_error = 0x02, 55 - data_am_error = 0x04, data_crc_error = 0x08, 56 - no_data_error = 0x10, overrun_error = 0x20, 57 - } error_cause; 58 - static int stop_read_ahead; 59 - 60 - 61 - static void print_error_cause(int cause) 62 - { 63 - TRACE_FUN(ft_t_any); 64 - 65 - switch (cause) { 66 - case no_data_error: 67 - TRACE(ft_t_noise, "no data error"); 68 - break; 69 - case id_am_error: 70 - TRACE(ft_t_noise, "id am error"); 71 - break; 72 - case id_crc_error: 73 - TRACE(ft_t_noise, "id crc error"); 74 - break; 75 - case data_am_error: 76 - TRACE(ft_t_noise, "data am error"); 77 - break; 78 - case data_crc_error: 79 - TRACE(ft_t_noise, "data crc error"); 80 - break; 81 - case overrun_error: 82 - TRACE(ft_t_noise, "overrun error"); 83 - break; 84 - default:; 85 - } 86 - TRACE_EXIT; 87 - } 88 - 89 - static char *fdc_mode_txt(fdc_mode_enum mode) 90 - { 91 - switch (mode) { 92 - case fdc_idle: 93 - return "fdc_idle"; 94 - case fdc_reading_data: 95 - return "fdc_reading_data"; 96 - case fdc_seeking: 97 - return "fdc_seeking"; 98 - case fdc_writing_data: 99 - return "fdc_writing_data"; 100 - case fdc_reading_id: 101 - return "fdc_reading_id"; 102 - case fdc_recalibrating: 103 - return "fdc_recalibrating"; 104 - case fdc_formatting: 105 - return "fdc_formatting"; 106 - case fdc_verifying: 107 - return "fdc_verifying"; 108 - default: 109 - return "unknown"; 110 - } 111 - } 112 - 113 - static inline error_cause decode_irq_cause(fdc_mode_enum mode, __u8 st[]) 114 - { 115 - error_cause cause = no_error; 116 - TRACE_FUN(ft_t_any); 117 - 118 - /* Valid st[], decode cause of interrupt. 119 - */ 120 - switch (st[0] & ST0_INT_MASK) { 121 - case FDC_INT_NORMAL: 122 - TRACE(ft_t_fdc_dma,"normal completion: %s",fdc_mode_txt(mode)); 123 - break; 124 - case FDC_INT_ABNORMAL: 125 - TRACE(ft_t_flow, "abnormal completion %s", fdc_mode_txt(mode)); 126 - TRACE(ft_t_fdc_dma, "ST0: 0x%02x, ST1: 0x%02x, ST2: 0x%02x", 127 - st[0], st[1], st[2]); 128 - TRACE(ft_t_fdc_dma, 129 - "C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x", 130 - st[3], st[4], st[5], st[6]); 131 - if (st[1] & 0x01) { 132 - if (st[2] & 0x01) { 133 - cause = data_am_error; 134 - } else { 135 - cause = id_am_error; 136 - } 137 - } else if (st[1] & 0x20) { 138 - if (st[2] & 0x20) { 139 - cause = data_crc_error; 140 - } else { 141 - cause = id_crc_error; 142 - } 143 - } else if (st[1] & 0x04) { 144 - cause = no_data_error; 145 - } else if (st[1] & 0x10) { 146 - cause = overrun_error; 147 - } 148 - print_error_cause(cause); 149 - break; 150 - case FDC_INT_INVALID: 151 - TRACE(ft_t_flow, "invalid completion %s", fdc_mode_txt(mode)); 152 - break; 153 - case FDC_INT_READYCH: 154 - if (st[0] & ST0_SEEK_END) { 155 - TRACE(ft_t_flow, "drive poll completed"); 156 - } else { 157 - TRACE(ft_t_flow, "ready change %s",fdc_mode_txt(mode)); 158 - } 159 - break; 160 - default: 161 - break; 162 - } 163 - TRACE_EXIT cause; 164 - } 165 - 166 - static void update_history(error_cause cause) 167 - { 168 - switch (cause) { 169 - case id_am_error: 170 - ft_history.id_am_errors++; 171 - break; 172 - case id_crc_error: 173 - ft_history.id_crc_errors++; 174 - break; 175 - case data_am_error: 176 - ft_history.data_am_errors++; 177 - break; 178 - case data_crc_error: 179 - ft_history.data_crc_errors++; 180 - break; 181 - case overrun_error: 182 - ft_history.overrun_errors++; 183 - break; 184 - case no_data_error: 185 - ft_history.no_data_errors++; 186 - break; 187 - default:; 188 - } 189 - } 190 - 191 - static void skip_bad_sector(buffer_struct * buff) 192 - { 193 - TRACE_FUN(ft_t_any); 194 - 195 - /* Mark sector as soft error and skip it 196 - */ 197 - if (buff->remaining > 0) { 198 - ++buff->sector_offset; 199 - ++buff->data_offset; 200 - --buff->remaining; 201 - buff->ptr += FT_SECTOR_SIZE; 202 - buff->bad_sector_map >>= 1; 203 - } else { 204 - /* Hey, what is this????????????? C code: if we shift 205 - * more than 31 bits, we get no shift. That's bad!!!!!! 206 - */ 207 - ++buff->sector_offset; /* hack for error maps */ 208 - TRACE(ft_t_warn, "skipping last sector in segment"); 209 - } 210 - TRACE_EXIT; 211 - } 212 - 213 - static void update_error_maps(buffer_struct * buff, unsigned int error_offset) 214 - { 215 - int hard = 0; 216 - TRACE_FUN(ft_t_any); 217 - 218 - if (buff->retry < FT_SOFT_RETRIES) { 219 - buff->soft_error_map |= (1 << error_offset); 220 - } else { 221 - buff->hard_error_map |= (1 << error_offset); 222 - buff->soft_error_map &= ~buff->hard_error_map; 223 - buff->retry = -1; /* will be set to 0 in setup_segment */ 224 - hard = 1; 225 - } 226 - TRACE(ft_t_noise, "sector %d : %s error\n" 227 - KERN_INFO "hard map: 0x%08lx\n" 228 - KERN_INFO "soft map: 0x%08lx", 229 - FT_SECTOR(error_offset), hard ? "hard" : "soft", 230 - (long) buff->hard_error_map, (long) buff->soft_error_map); 231 - TRACE_EXIT; 232 - } 233 - 234 - static void print_progress(buffer_struct *buff, error_cause cause) 235 - { 236 - TRACE_FUN(ft_t_any); 237 - 238 - switch (cause) { 239 - case no_error: 240 - TRACE(ft_t_flow,"%d Sector(s) transferred", buff->sector_count); 241 - break; 242 - case no_data_error: 243 - TRACE(ft_t_flow, "Sector %d not found", 244 - FT_SECTOR(buff->sector_offset)); 245 - break; 246 - case overrun_error: 247 - /* got an overrun error on the first byte, must be a 248 - * hardware problem 249 - */ 250 - TRACE(ft_t_bug, 251 - "Unexpected error: failing DMA or FDC controller ?"); 252 - break; 253 - case data_crc_error: 254 - TRACE(ft_t_flow, "Error in sector %d", 255 - FT_SECTOR(buff->sector_offset - 1)); 256 - break; 257 - case id_crc_error: 258 - case id_am_error: 259 - case data_am_error: 260 - TRACE(ft_t_flow, "Error in sector %d", 261 - FT_SECTOR(buff->sector_offset)); 262 - break; 263 - default: 264 - TRACE(ft_t_flow, "Unexpected error at sector %d", 265 - FT_SECTOR(buff->sector_offset)); 266 - break; 267 - } 268 - TRACE_EXIT; 269 - } 270 - 271 - /* 272 - * Error cause: Amount xferred: Action: 273 - * 274 - * id_am_error 0 mark bad and skip 275 - * id_crc_error 0 mark bad and skip 276 - * data_am_error 0 mark bad and skip 277 - * data_crc_error % 1024 mark bad and skip 278 - * no_data_error 0 retry on write 279 - * mark bad and skip on read 280 - * overrun_error [ 0..all-1 ] mark bad and skip 281 - * no_error all continue 282 - */ 283 - 284 - /* the arg `sector' is returned by the fdc and tells us at which sector we 285 - * are positioned at (relative to starting sector of segment) 286 - */ 287 - static void determine_verify_progress(buffer_struct *buff, 288 - error_cause cause, 289 - __u8 sector) 290 - { 291 - TRACE_FUN(ft_t_any); 292 - 293 - if (cause == no_error && sector == 1) { 294 - buff->sector_offset = FT_SECTORS_PER_SEGMENT; 295 - buff->remaining = 0; 296 - if (TRACE_LEVEL >= ft_t_flow) { 297 - print_progress(buff, cause); 298 - } 299 - } else { 300 - buff->sector_offset = sector - buff->sect; 301 - buff->remaining = FT_SECTORS_PER_SEGMENT - buff->sector_offset; 302 - TRACE(ft_t_noise, "%ssector offset: 0x%04x", 303 - (cause == no_error) ? "unexpected " : "", 304 - buff->sector_offset); 305 - switch (cause) { 306 - case overrun_error: 307 - break; 308 - #if 0 309 - case no_data_error: 310 - buff->retry = FT_SOFT_RETRIES; 311 - if (buff->hard_error_map && 312 - buff->sector_offset > 1 && 313 - (buff->hard_error_map & 314 - (1 << (buff->sector_offset-2)))) { 315 - buff->retry --; 316 - } 317 - break; 318 - #endif 319 - default: 320 - buff->retry = FT_SOFT_RETRIES; 321 - break; 322 - } 323 - if (TRACE_LEVEL >= ft_t_flow) { 324 - print_progress(buff, cause); 325 - } 326 - /* Sector_offset points to the problem area Now adjust 327 - * sector_offset so it always points one past he failing 328 - * sector. I.e. skip the bad sector. 329 - */ 330 - ++buff->sector_offset; 331 - --buff->remaining; 332 - update_error_maps(buff, buff->sector_offset - 1); 333 - } 334 - TRACE_EXIT; 335 - } 336 - 337 - static void determine_progress(buffer_struct *buff, 338 - error_cause cause, 339 - __u8 sector) 340 - { 341 - unsigned int dma_residue; 342 - TRACE_FUN(ft_t_any); 343 - 344 - /* Using less preferred order of disable_dma and 345 - * get_dma_residue because this seems to fail on at least one 346 - * system if reversed! 347 - */ 348 - dma_residue = get_dma_residue(fdc.dma); 349 - disable_dma(fdc.dma); 350 - if (cause != no_error || dma_residue != 0) { 351 - TRACE(ft_t_noise, "%sDMA residue: 0x%04x", 352 - (cause == no_error) ? "unexpected " : "", 353 - dma_residue); 354 - /* adjust to actual value: */ 355 - if (dma_residue == 0) { 356 - /* this happens sometimes with overrun errors. 357 - * I don't know whether we could ignore the 358 - * overrun error. Play save. 359 - */ 360 - buff->sector_count --; 361 - } else { 362 - buff->sector_count -= ((dma_residue + 363 - (FT_SECTOR_SIZE - 1)) / 364 - FT_SECTOR_SIZE); 365 - } 366 - } 367 - /* Update var's influenced by the DMA operation. 368 - */ 369 - if (buff->sector_count > 0) { 370 - buff->sector_offset += buff->sector_count; 371 - buff->data_offset += buff->sector_count; 372 - buff->ptr += (buff->sector_count * 373 - FT_SECTOR_SIZE); 374 - buff->remaining -= buff->sector_count; 375 - buff->bad_sector_map >>= buff->sector_count; 376 - } 377 - if (TRACE_LEVEL >= ft_t_flow) { 378 - print_progress(buff, cause); 379 - } 380 - if (cause != no_error) { 381 - if (buff->remaining == 0) { 382 - TRACE(ft_t_warn, "foo?\n" 383 - KERN_INFO "count : %d\n" 384 - KERN_INFO "offset: %d\n" 385 - KERN_INFO "soft : %08x\n" 386 - KERN_INFO "hard : %08x", 387 - buff->sector_count, 388 - buff->sector_offset, 389 - buff->soft_error_map, 390 - buff->hard_error_map); 391 - } 392 - /* Sector_offset points to the problem area, except if we got 393 - * a data_crc_error. In that case it points one past the 394 - * failing sector. 395 - * 396 - * Now adjust sector_offset so it always points one past he 397 - * failing sector. I.e. skip the bad sector. 398 - */ 399 - if (cause != data_crc_error) { 400 - skip_bad_sector(buff); 401 - } 402 - update_error_maps(buff, buff->sector_offset - 1); 403 - } 404 - TRACE_EXIT; 405 - } 406 - 407 - static int calc_steps(int cmd) 408 - { 409 - if (ftape_current_cylinder > cmd) { 410 - return ftape_current_cylinder - cmd; 411 - } else { 412 - return ftape_current_cylinder + cmd; 413 - } 414 - } 415 - 416 - static void pause_tape(int retry, int mode) 417 - { 418 - int result; 419 - __u8 out[3] = {FDC_SEEK, ft_drive_sel, 0}; 420 - TRACE_FUN(ft_t_any); 421 - 422 - /* We'll use a raw seek command to get the tape to rewind and 423 - * stop for a retry. 424 - */ 425 - ++ft_history.rewinds; 426 - if (qic117_cmds[ftape_current_command].non_intr) { 427 - TRACE(ft_t_warn, "motion command may be issued too soon"); 428 - } 429 - if (retry && (mode == fdc_reading_data || 430 - mode == fdc_reading_id || 431 - mode == fdc_verifying)) { 432 - ftape_current_command = QIC_MICRO_STEP_PAUSE; 433 - ftape_might_be_off_track = 1; 434 - } else { 435 - ftape_current_command = QIC_PAUSE; 436 - } 437 - out[2] = calc_steps(ftape_current_command); 438 - result = fdc_command(out, 3); /* issue QIC_117 command */ 439 - ftape_current_cylinder = out[ 2]; 440 - if (result < 0) { 441 - TRACE(ft_t_noise, "qic-pause failed, status = %d", result); 442 - } else { 443 - ft_location.known = 0; 444 - ft_runner_status = idle; 445 - ft_hide_interrupt = 1; 446 - ftape_tape_running = 0; 447 - } 448 - TRACE_EXIT; 449 - } 450 - 451 - static void continue_xfer(buffer_struct *buff, 452 - fdc_mode_enum mode, 453 - unsigned int skip) 454 - { 455 - int write = 0; 456 - TRACE_FUN(ft_t_any); 457 - 458 - if (mode == fdc_writing_data || mode == fdc_deleting) { 459 - write = 1; 460 - } 461 - /* This part can be removed if it never happens 462 - */ 463 - if (skip > 0 && 464 - (ft_runner_status != running || 465 - (write && (buff->status != writing)) || 466 - (!write && (buff->status != reading && 467 - buff->status != verifying)))) { 468 - TRACE(ft_t_err, "unexpected runner/buffer state %d/%d", 469 - ft_runner_status, buff->status); 470 - buff->status = error; 471 - /* finish this buffer: */ 472 - (void)ftape_next_buffer(ft_queue_head); 473 - ft_runner_status = aborting; 474 - fdc_mode = fdc_idle; 475 - } else if (buff->remaining > 0 && ftape_calc_next_cluster(buff) > 0) { 476 - /* still sectors left in current segment, continue 477 - * with this segment 478 - */ 479 - if (fdc_setup_read_write(buff, mode) < 0) { 480 - /* failed, abort operation 481 - */ 482 - buff->bytes = buff->ptr - buff->address; 483 - buff->status = error; 484 - /* finish this buffer: */ 485 - (void)ftape_next_buffer(ft_queue_head); 486 - ft_runner_status = aborting; 487 - fdc_mode = fdc_idle; 488 - } 489 - } else { 490 - /* current segment completed 491 - */ 492 - unsigned int last_segment = buff->segment_id; 493 - int eot = ((last_segment + 1) % ft_segments_per_track) == 0; 494 - unsigned int next = buff->next_segment; /* 0 means stop ! */ 495 - 496 - buff->bytes = buff->ptr - buff->address; 497 - buff->status = done; 498 - buff = ftape_next_buffer(ft_queue_head); 499 - if (eot) { 500 - /* finished last segment on current track, 501 - * can't continue 502 - */ 503 - ft_runner_status = logical_eot; 504 - fdc_mode = fdc_idle; 505 - TRACE_EXIT; 506 - } 507 - if (next <= 0) { 508 - /* don't continue with next segment 509 - */ 510 - TRACE(ft_t_noise, "no %s allowed, stopping tape", 511 - (write) ? "write next" : "read ahead"); 512 - pause_tape(0, mode); 513 - ft_runner_status = idle; /* not quite true until 514 - * next irq 515 - */ 516 - TRACE_EXIT; 517 - } 518 - /* continue with next segment 519 - */ 520 - if (buff->status != waiting) { 521 - TRACE(ft_t_noise, "all input buffers %s, pausing tape", 522 - (write) ? "empty" : "full"); 523 - pause_tape(0, mode); 524 - ft_runner_status = idle; /* not quite true until 525 - * next irq 526 - */ 527 - TRACE_EXIT; 528 - } 529 - if (write && next != buff->segment_id) { 530 - TRACE(ft_t_noise, 531 - "segments out of order, aborting write"); 532 - ft_runner_status = do_abort; 533 - fdc_mode = fdc_idle; 534 - TRACE_EXIT; 535 - } 536 - ftape_setup_new_segment(buff, next, 0); 537 - if (stop_read_ahead) { 538 - buff->next_segment = 0; 539 - stop_read_ahead = 0; 540 - } 541 - if (ftape_calc_next_cluster(buff) == 0 || 542 - fdc_setup_read_write(buff, mode) != 0) { 543 - TRACE(ft_t_err, "couldn't start %s-ahead", 544 - write ? "write" : "read"); 545 - ft_runner_status = do_abort; 546 - fdc_mode = fdc_idle; 547 - } else { 548 - /* keep on going */ 549 - switch (ft_driver_state) { 550 - case reading: buff->status = reading; break; 551 - case verifying: buff->status = verifying; break; 552 - case writing: buff->status = writing; break; 553 - case deleting: buff->status = deleting; break; 554 - default: 555 - TRACE(ft_t_err, 556 - "BUG: ft_driver_state %d should be one out of " 557 - "{reading, writing, verifying, deleting}", 558 - ft_driver_state); 559 - buff->status = write ? writing : reading; 560 - break; 561 - } 562 - } 563 - } 564 - TRACE_EXIT; 565 - } 566 - 567 - static void retry_sector(buffer_struct *buff, 568 - int mode, 569 - unsigned int skip) 570 - { 571 - TRACE_FUN(ft_t_any); 572 - 573 - TRACE(ft_t_noise, "%s error, will retry", 574 - (mode == fdc_writing_data || mode == fdc_deleting) ? "write" : "read"); 575 - pause_tape(1, mode); 576 - ft_runner_status = aborting; 577 - buff->status = error; 578 - buff->skip = skip; 579 - TRACE_EXIT; 580 - } 581 - 582 - static unsigned int find_resume_point(buffer_struct *buff) 583 - { 584 - int i = 0; 585 - SectorMap mask; 586 - SectorMap map; 587 - TRACE_FUN(ft_t_any); 588 - 589 - /* This function is to be called after all variables have been 590 - * updated to point past the failing sector. 591 - * If there are any soft errors before the failing sector, 592 - * find the first soft error and return the sector offset. 593 - * Otherwise find the last hard error. 594 - * Note: there should always be at least one hard or soft error ! 595 - */ 596 - if (buff->sector_offset < 1 || buff->sector_offset > 32) { 597 - TRACE(ft_t_bug, "BUG: sector_offset = %d", 598 - buff->sector_offset); 599 - TRACE_EXIT 0; 600 - } 601 - if (buff->sector_offset >= 32) { /* C-limitation on shift ! */ 602 - mask = 0xffffffff; 603 - } else { 604 - mask = (1 << buff->sector_offset) - 1; 605 - } 606 - map = buff->soft_error_map & mask; 607 - if (map) { 608 - while ((map & (1 << i)) == 0) { 609 - ++i; 610 - } 611 - TRACE(ft_t_noise, "at sector %d", FT_SECTOR(i)); 612 - } else { 613 - map = buff->hard_error_map & mask; 614 - i = buff->sector_offset - 1; 615 - if (map) { 616 - while ((map & (1 << i)) == 0) { 617 - --i; 618 - } 619 - TRACE(ft_t_noise, "after sector %d", FT_SECTOR(i)); 620 - ++i; /* first sector after last hard error */ 621 - } else { 622 - TRACE(ft_t_bug, "BUG: no soft or hard errors"); 623 - } 624 - } 625 - TRACE_EXIT i; 626 - } 627 - 628 - /* check possible dma residue when formatting, update position record in 629 - * buffer struct. This is, of course, modelled after determine_progress(), but 630 - * we don't need to set up for retries because the format process cannot be 631 - * interrupted (except at the end of the tape track). 632 - */ 633 - static int determine_fmt_progress(buffer_struct *buff, error_cause cause) 634 - { 635 - unsigned int dma_residue; 636 - TRACE_FUN(ft_t_any); 637 - 638 - /* Using less preferred order of disable_dma and 639 - * get_dma_residue because this seems to fail on at least one 640 - * system if reversed! 641 - */ 642 - dma_residue = get_dma_residue(fdc.dma); 643 - disable_dma(fdc.dma); 644 - if (cause != no_error || dma_residue != 0) { 645 - TRACE(ft_t_info, "DMA residue = 0x%04x", dma_residue); 646 - fdc_mode = fdc_idle; 647 - switch(cause) { 648 - case no_error: 649 - ft_runner_status = aborting; 650 - buff->status = idle; 651 - break; 652 - case overrun_error: 653 - /* got an overrun error on the first byte, must be a 654 - * hardware problem 655 - */ 656 - TRACE(ft_t_bug, 657 - "Unexpected error: failing DMA controller ?"); 658 - ft_runner_status = do_abort; 659 - buff->status = error; 660 - break; 661 - default: 662 - TRACE(ft_t_noise, "Unexpected error at segment %d", 663 - buff->segment_id); 664 - ft_runner_status = do_abort; 665 - buff->status = error; 666 - break; 667 - } 668 - TRACE_EXIT -EIO; /* can only retry entire track in format mode 669 - */ 670 - } 671 - /* Update var's influenced by the DMA operation. 672 - */ 673 - buff->ptr += FT_SECTORS_PER_SEGMENT * 4; 674 - buff->bytes -= FT_SECTORS_PER_SEGMENT * 4; 675 - buff->remaining -= FT_SECTORS_PER_SEGMENT; 676 - buff->segment_id ++; /* done with segment */ 677 - TRACE_EXIT 0; 678 - } 679 - 680 - /* 681 - * Continue formatting, switch buffers if there is no data left in 682 - * current buffer. This is, of course, modelled after 683 - * continue_xfer(), but we don't need to set up for retries because 684 - * the format process cannot be interrupted (except at the end of the 685 - * tape track). 686 - */ 687 - static void continue_formatting(buffer_struct *buff) 688 - { 689 - TRACE_FUN(ft_t_any); 690 - 691 - if (buff->remaining <= 0) { /* no space left in dma buffer */ 692 - unsigned int next = buff->next_segment; 693 - 694 - if (next == 0) { /* end of tape track */ 695 - buff->status = done; 696 - ft_runner_status = logical_eot; 697 - fdc_mode = fdc_idle; 698 - TRACE(ft_t_noise, "Done formatting track %d", 699 - ft_location.track); 700 - TRACE_EXIT; 701 - } 702 - /* 703 - * switch to next buffer! 704 - */ 705 - buff->status = done; 706 - buff = ftape_next_buffer(ft_queue_head); 707 - 708 - if (buff->status != waiting || next != buff->segment_id) { 709 - goto format_setup_error; 710 - } 711 - } 712 - if (fdc_setup_formatting(buff) < 0) { 713 - goto format_setup_error; 714 - } 715 - buff->status = formatting; 716 - TRACE(ft_t_fdc_dma, "Formatting segment %d on track %d", 717 - buff->segment_id, ft_location.track); 718 - TRACE_EXIT; 719 - format_setup_error: 720 - ft_runner_status = do_abort; 721 - fdc_mode = fdc_idle; 722 - buff->status = error; 723 - TRACE(ft_t_err, "Error setting up for segment %d on track %d", 724 - buff->segment_id, ft_location.track); 725 - TRACE_EXIT; 726 - 727 - } 728 - 729 - /* this handles writing, read id, reading and formatting 730 - */ 731 - static void handle_fdc_busy(buffer_struct *buff) 732 - { 733 - static int no_data_error_count; 734 - int retry = 0; 735 - error_cause cause; 736 - __u8 in[7]; 737 - int skip; 738 - fdc_mode_enum fmode = fdc_mode; 739 - TRACE_FUN(ft_t_any); 740 - 741 - if (fdc_result(in, 7) < 0) { /* better get it fast ! */ 742 - TRACE(ft_t_err, 743 - "Probably fatal error during FDC Result Phase\n" 744 - KERN_INFO 745 - "drive may hang until (power on) reset :-("); 746 - /* what to do next ???? 747 - */ 748 - TRACE_EXIT; 749 - } 750 - cause = decode_irq_cause(fdc_mode, in); 751 - #ifdef TESTING 752 - { int i; 753 - for (i = 0; i < (int)ft_nr_buffers; ++i) 754 - TRACE(ft_t_any, "buffer[%d] status: %d, segment_id: %d", 755 - i, ft_buffer[i]->status, ft_buffer[i]->segment_id); 756 - } 757 - #endif 758 - if (fmode == fdc_reading_data && ft_driver_state == verifying) { 759 - fmode = fdc_verifying; 760 - } 761 - switch (fmode) { 762 - case fdc_verifying: 763 - if (ft_runner_status == aborting || 764 - ft_runner_status == do_abort) { 765 - TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode)); 766 - break; 767 - } 768 - if (buff->retry > 0) { 769 - TRACE(ft_t_flow, "this is retry nr %d", buff->retry); 770 - } 771 - switch (cause) { 772 - case no_error: 773 - no_data_error_count = 0; 774 - determine_verify_progress(buff, cause, in[5]); 775 - if (in[2] & 0x40) { 776 - /* This should not happen when verifying 777 - */ 778 - TRACE(ft_t_warn, 779 - "deleted data in segment %d/%d", 780 - buff->segment_id, 781 - FT_SECTOR(buff->sector_offset - 1)); 782 - buff->remaining = 0; /* abort transfer */ 783 - buff->hard_error_map = EMPTY_SEGMENT; 784 - skip = 1; 785 - } else { 786 - skip = 0; 787 - } 788 - continue_xfer(buff, fdc_mode, skip); 789 - break; 790 - case no_data_error: 791 - no_data_error_count ++; 792 - case overrun_error: 793 - retry ++; 794 - case id_am_error: 795 - case id_crc_error: 796 - case data_am_error: 797 - case data_crc_error: 798 - determine_verify_progress(buff, cause, in[5]); 799 - if (cause == no_data_error) { 800 - if (no_data_error_count >= 2) { 801 - TRACE(ft_t_warn, 802 - "retrying because of successive " 803 - "no data errors"); 804 - no_data_error_count = 0; 805 - } else { 806 - retry --; 807 - } 808 - } else { 809 - no_data_error_count = 0; 810 - } 811 - if (retry) { 812 - skip = find_resume_point(buff); 813 - } else { 814 - skip = buff->sector_offset; 815 - } 816 - if (retry && skip < 32) { 817 - retry_sector(buff, fdc_mode, skip); 818 - } else { 819 - continue_xfer(buff, fdc_mode, skip); 820 - } 821 - update_history(cause); 822 - break; 823 - default: 824 - /* Don't know why this could happen 825 - * but find out. 826 - */ 827 - determine_verify_progress(buff, cause, in[5]); 828 - retry_sector(buff, fdc_mode, 0); 829 - TRACE(ft_t_err, "Error: unexpected error"); 830 - break; 831 - } 832 - break; 833 - case fdc_reading_data: 834 - #ifdef TESTING 835 - /* I'm sorry, but: NOBODY ever used this trace 836 - * messages for ages. I guess that Bas was the last person 837 - * that ever really used this (thank you, between the lines) 838 - */ 839 - if (cause == no_error) { 840 - TRACE(ft_t_flow,"reading segment %d",buff->segment_id); 841 - } else { 842 - TRACE(ft_t_noise, "error reading segment %d", 843 - buff->segment_id); 844 - TRACE(ft_t_noise, "\n" 845 - KERN_INFO 846 - "IRQ:C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x\n" 847 - KERN_INFO 848 - "BUF:C: 0x%02x, H: 0x%02x, R: 0x%02x", 849 - in[3], in[4], in[5], in[6], 850 - buff->cyl, buff->head, buff->sect); 851 - } 852 - #endif 853 - if (ft_runner_status == aborting || 854 - ft_runner_status == do_abort) { 855 - TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode)); 856 - break; 857 - } 858 - if (buff->bad_sector_map == FAKE_SEGMENT) { 859 - /* This condition occurs when reading a `fake' 860 - * sector that's not accessible. Doesn't 861 - * really matter as we would have ignored it 862 - * anyway ! 863 - * 864 - * Chance is that we're past the next segment 865 - * now, so the next operation may fail and 866 - * result in a retry. 867 - */ 868 - buff->remaining = 0; /* skip failing sector */ 869 - /* buff->ptr = buff->address; */ 870 - /* fake success: */ 871 - continue_xfer(buff, fdc_mode, 1); 872 - /* trace calls are expensive: place them AFTER 873 - * the real stuff has been done. 874 - * 875 - */ 876 - TRACE(ft_t_noise, "skipping empty segment %d (read), size? %d", 877 - buff->segment_id, buff->ptr - buff->address); 878 - TRACE_EXIT; 879 - } 880 - if (buff->retry > 0) { 881 - TRACE(ft_t_flow, "this is retry nr %d", buff->retry); 882 - } 883 - switch (cause) { 884 - case no_error: 885 - determine_progress(buff, cause, in[5]); 886 - if (in[2] & 0x40) { 887 - /* Handle deleted data in header segments. 888 - * Skip segment and force read-ahead. 889 - */ 890 - TRACE(ft_t_warn, 891 - "deleted data in segment %d/%d", 892 - buff->segment_id, 893 - FT_SECTOR(buff->sector_offset - 1)); 894 - buff->deleted = 1; 895 - buff->remaining = 0;/*abort transfer */ 896 - buff->soft_error_map |= 897 - (-1L << buff->sector_offset); 898 - if (buff->segment_id == 0) { 899 - /* stop on next segment */ 900 - stop_read_ahead = 1; 901 - } 902 - /* force read-ahead: */ 903 - buff->next_segment = 904 - buff->segment_id + 1; 905 - skip = (FT_SECTORS_PER_SEGMENT - 906 - buff->sector_offset); 907 - } else { 908 - skip = 0; 909 - } 910 - continue_xfer(buff, fdc_mode, skip); 911 - break; 912 - case no_data_error: 913 - /* Tape started too far ahead of or behind the 914 - * right sector. This may also happen in the 915 - * middle of a segment ! 916 - * 917 - * Handle no-data as soft error. If next 918 - * sector fails too, a retry (with needed 919 - * reposition) will follow. 920 - */ 921 - retry ++; 922 - case id_am_error: 923 - case id_crc_error: 924 - case data_am_error: 925 - case data_crc_error: 926 - case overrun_error: 927 - retry += (buff->soft_error_map != 0 || 928 - buff->hard_error_map != 0); 929 - determine_progress(buff, cause, in[5]); 930 - #if 1 || defined(TESTING) 931 - if (cause == overrun_error) retry ++; 932 - #endif 933 - if (retry) { 934 - skip = find_resume_point(buff); 935 - } else { 936 - skip = buff->sector_offset; 937 - } 938 - /* Try to resume with next sector on single 939 - * errors (let ecc correct it), but retry on 940 - * no_data (we'll be past the target when we 941 - * get here so we cannot retry) or on 942 - * multiple errors (reduce chance on ecc 943 - * failure). 944 - */ 945 - /* cH: 23/02/97: if the last sector in the 946 - * segment was a hard error, then there is 947 - * no sense in a retry. This occasion seldom 948 - * occurs but ... @:���`@%&�$ 949 - */ 950 - if (retry && skip < 32) { 951 - retry_sector(buff, fdc_mode, skip); 952 - } else { 953 - continue_xfer(buff, fdc_mode, skip); 954 - } 955 - update_history(cause); 956 - break; 957 - default: 958 - /* Don't know why this could happen 959 - * but find out. 960 - */ 961 - determine_progress(buff, cause, in[5]); 962 - retry_sector(buff, fdc_mode, 0); 963 - TRACE(ft_t_err, "Error: unexpected error"); 964 - break; 965 - } 966 - break; 967 - case fdc_reading_id: 968 - if (cause == no_error) { 969 - fdc_cyl = in[3]; 970 - fdc_head = in[4]; 971 - fdc_sect = in[5]; 972 - TRACE(ft_t_fdc_dma, 973 - "id read: C: 0x%02x, H: 0x%02x, R: 0x%02x", 974 - fdc_cyl, fdc_head, fdc_sect); 975 - } else { /* no valid information, use invalid sector */ 976 - fdc_cyl = fdc_head = fdc_sect = 0; 977 - TRACE(ft_t_flow, "Didn't find valid sector Id"); 978 - } 979 - fdc_mode = fdc_idle; 980 - break; 981 - case fdc_deleting: 982 - case fdc_writing_data: 983 - #ifdef TESTING 984 - if (cause == no_error) { 985 - TRACE(ft_t_flow, "writing segment %d", buff->segment_id); 986 - } else { 987 - TRACE(ft_t_noise, "error writing segment %d", 988 - buff->segment_id); 989 - } 990 - #endif 991 - if (ft_runner_status == aborting || 992 - ft_runner_status == do_abort) { 993 - TRACE(ft_t_flow, "aborting %s",fdc_mode_txt(fdc_mode)); 994 - break; 995 - } 996 - if (buff->retry > 0) { 997 - TRACE(ft_t_flow, "this is retry nr %d", buff->retry); 998 - } 999 - if (buff->bad_sector_map == FAKE_SEGMENT) { 1000 - /* This condition occurs when trying to write to a 1001 - * `fake' sector that's not accessible. Doesn't really 1002 - * matter as it isn't used anyway ! Might be located 1003 - * at wrong segment, then we'll fail on the next 1004 - * segment. 1005 - */ 1006 - TRACE(ft_t_noise, "skipping empty segment (write)"); 1007 - buff->remaining = 0; /* skip failing sector */ 1008 - /* fake success: */ 1009 - continue_xfer(buff, fdc_mode, 1); 1010 - break; 1011 - } 1012 - switch (cause) { 1013 - case no_error: 1014 - determine_progress(buff, cause, in[5]); 1015 - continue_xfer(buff, fdc_mode, 0); 1016 - break; 1017 - case no_data_error: 1018 - case id_am_error: 1019 - case id_crc_error: 1020 - case data_am_error: 1021 - case overrun_error: 1022 - update_history(cause); 1023 - determine_progress(buff, cause, in[5]); 1024 - skip = find_resume_point(buff); 1025 - retry_sector(buff, fdc_mode, skip); 1026 - break; 1027 - default: 1028 - if (in[1] & 0x02) { 1029 - TRACE(ft_t_err, "media not writable"); 1030 - } else { 1031 - TRACE(ft_t_bug, "unforeseen write error"); 1032 - } 1033 - fdc_mode = fdc_idle; 1034 - break; 1035 - } 1036 - break; /* fdc_deleting || fdc_writing_data */ 1037 - case fdc_formatting: 1038 - /* The interrupt comes after formatting a segment. We then 1039 - * have to set up QUICKLY for the next segment. But 1040 - * afterwards, there is plenty of time. 1041 - */ 1042 - switch (cause) { 1043 - case no_error: 1044 - /* would like to keep most of the formatting stuff 1045 - * outside the isr code, but timing is too critical 1046 - */ 1047 - if (determine_fmt_progress(buff, cause) >= 0) { 1048 - continue_formatting(buff); 1049 - } 1050 - break; 1051 - case no_data_error: 1052 - case id_am_error: 1053 - case id_crc_error: 1054 - case data_am_error: 1055 - case overrun_error: 1056 - default: 1057 - determine_fmt_progress(buff, cause); 1058 - update_history(cause); 1059 - if (in[1] & 0x02) { 1060 - TRACE(ft_t_err, "media not writable"); 1061 - } else { 1062 - TRACE(ft_t_bug, "unforeseen write error"); 1063 - } 1064 - break; 1065 - } /* cause */ 1066 - break; 1067 - default: 1068 - TRACE(ft_t_warn, "Warning: unexpected irq during: %s", 1069 - fdc_mode_txt(fdc_mode)); 1070 - fdc_mode = fdc_idle; 1071 - break; 1072 - } 1073 - TRACE_EXIT; 1074 - } 1075 - 1076 - /* FDC interrupt service routine. 1077 - */ 1078 - void fdc_isr(void) 1079 - { 1080 - static int isr_active; 1081 - #ifdef TESTING 1082 - unsigned int t0 = ftape_timestamp(); 1083 - #endif 1084 - TRACE_FUN(ft_t_any); 1085 - 1086 - if (isr_active++) { 1087 - --isr_active; 1088 - TRACE(ft_t_bug, "BUG: nested interrupt, not good !"); 1089 - *fdc.hook = fdc_isr; /* hook our handler into the fdc 1090 - * code again 1091 - */ 1092 - TRACE_EXIT; 1093 - } 1094 - sti(); 1095 - if (inb_p(fdc.msr) & FDC_BUSY) { /* Entering Result Phase */ 1096 - ft_hide_interrupt = 0; 1097 - handle_fdc_busy(ftape_get_buffer(ft_queue_head)); 1098 - if (ft_runner_status == do_abort) { 1099 - /* cease operation, remember tape position 1100 - */ 1101 - TRACE(ft_t_flow, "runner aborting"); 1102 - ft_runner_status = aborting; 1103 - ++ft_expected_stray_interrupts; 1104 - } 1105 - } else { /* !FDC_BUSY */ 1106 - /* clear interrupt, cause should be gotten by issuing 1107 - * a Sense Interrupt Status command. 1108 - */ 1109 - if (fdc_mode == fdc_recalibrating || fdc_mode == fdc_seeking) { 1110 - if (ft_hide_interrupt) { 1111 - int st0; 1112 - int pcn; 1113 - 1114 - if (fdc_sense_interrupt_status(&st0, &pcn) < 0) 1115 - TRACE(ft_t_err, 1116 - "sense interrupt status failed"); 1117 - ftape_current_cylinder = pcn; 1118 - TRACE(ft_t_flow, "handled hidden interrupt"); 1119 - } 1120 - ft_seek_completed = 1; 1121 - fdc_mode = fdc_idle; 1122 - } else if (!waitqueue_active(&ftape_wait_intr)) { 1123 - if (ft_expected_stray_interrupts == 0) { 1124 - TRACE(ft_t_warn, "unexpected stray interrupt"); 1125 - } else { 1126 - TRACE(ft_t_flow, "expected stray interrupt"); 1127 - --ft_expected_stray_interrupts; 1128 - } 1129 - } else { 1130 - if (fdc_mode == fdc_reading_data || 1131 - fdc_mode == fdc_verifying || 1132 - fdc_mode == fdc_writing_data || 1133 - fdc_mode == fdc_deleting || 1134 - fdc_mode == fdc_formatting || 1135 - fdc_mode == fdc_reading_id) { 1136 - if (inb_p(fdc.msr) & FDC_BUSY) { 1137 - TRACE(ft_t_bug, 1138 - "***** FDC failure, busy too late"); 1139 - } else { 1140 - TRACE(ft_t_bug, 1141 - "***** FDC failure, no busy"); 1142 - } 1143 - } else { 1144 - TRACE(ft_t_fdc_dma, "awaited stray interrupt"); 1145 - } 1146 - } 1147 - ft_hide_interrupt = 0; 1148 - } 1149 - /* Handle sleep code. 1150 - */ 1151 - if (!ft_hide_interrupt) { 1152 - ft_interrupt_seen ++; 1153 - if (waitqueue_active(&ftape_wait_intr)) { 1154 - wake_up_interruptible(&ftape_wait_intr); 1155 - } 1156 - } else { 1157 - TRACE(ft_t_flow, "hiding interrupt while %s", 1158 - waitqueue_active(&ftape_wait_intr) ? "waiting":"active"); 1159 - } 1160 - #ifdef TESTING 1161 - t0 = ftape_timediff(t0, ftape_timestamp()); 1162 - if (t0 >= 1000) { 1163 - /* only tell us about long calls */ 1164 - TRACE(ft_t_noise, "isr() duration: %5d usec", t0); 1165 - } 1166 - #endif 1167 - *fdc.hook = fdc_isr; /* hook our handler into the fdc code again */ 1168 - --isr_active; 1169 - TRACE_EXIT; 1170 - }
-55
drivers/char/ftape/lowlevel/fdc-isr.h
··· 1 - #ifndef _FDC_ISR_H 2 - #define _FDC_ISR_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-isr.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:07 $ 26 - * 27 - * This file declares the global variables necessary to 28 - * synchronize the interrupt service routine (isr) with the 29 - * remainder of the QIC-40/80/3010/3020 floppy-tape driver 30 - * "ftape" for Linux. 31 - */ 32 - 33 - /* 34 - * fdc-isr.c defined public variables 35 - */ 36 - extern volatile int ft_expected_stray_interrupts; /* masks stray interrupts */ 37 - extern volatile int ft_seek_completed; /* flag set by isr */ 38 - extern volatile int ft_interrupt_seen; /* flag set by isr */ 39 - extern volatile int ft_hide_interrupt; /* flag set by isr */ 40 - 41 - /* 42 - * fdc-io.c defined public functions 43 - */ 44 - extern void fdc_isr(void); 45 - 46 - /* 47 - * A kernel hook that steals one interrupt from the floppy 48 - * driver (Should be fixed when the new fdc driver gets ready) 49 - * See the linux kernel source files: 50 - * drivers/block/floppy.c & drivers/block/blk.h 51 - * for the details. 52 - */ 53 - extern void (*do_floppy) (void); 54 - 55 - #endif
-491
drivers/char/ftape/lowlevel/ftape-bsm.c
··· 1 - /* 2 - * Copyright (C) 1994-1996 Bas Laarhoven, 3 - * (C) 1996-1997 Claus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-bsm.c,v $ 21 - * $Revision: 1.3 $ 22 - * $Date: 1997/10/05 19:15:15 $ 23 - * 24 - * This file contains the bad-sector map handling code for 25 - * the QIC-117 floppy tape driver for Linux. 26 - * QIC-40, QIC-80, QIC-3010 and QIC-3020 maps are implemented. 27 - */ 28 - 29 - #include <linux/string.h> 30 - 31 - #include <linux/ftape.h> 32 - #include "../lowlevel/ftape-tracing.h" 33 - #include "../lowlevel/ftape-bsm.h" 34 - #include "../lowlevel/ftape-ctl.h" 35 - #include "../lowlevel/ftape-rw.h" 36 - 37 - /* Global vars. 38 - */ 39 - 40 - /* Local vars. 41 - */ 42 - static __u8 *bad_sector_map; 43 - static SectorCount *bsm_hash_ptr; 44 - 45 - typedef enum { 46 - forward, backward 47 - } mode_type; 48 - 49 - #if 0 50 - static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map); 51 - #endif 52 - 53 - #if 0 54 - /* fix_tape converts a normal QIC-80 tape into a 'wide' tape. 55 - * For testing purposes only ! 56 - */ 57 - void fix_tape(__u8 * buffer, ft_format_type new_code) 58 - { 59 - static __u8 list[BAD_SECTOR_MAP_SIZE]; 60 - SectorMap *src_ptr = (SectorMap *) list; 61 - __u8 *dst_ptr = bad_sector_map; 62 - SectorMap map; 63 - unsigned int sector = 1; 64 - int i; 65 - 66 - if (format_code != fmt_var && format_code != fmt_big) { 67 - memcpy(list, bad_sector_map, sizeof(list)); 68 - memset(bad_sector_map, 0, sizeof(bad_sector_map)); 69 - while ((__u8 *) src_ptr - list < sizeof(list)) { 70 - map = *src_ptr++; 71 - if (map == EMPTY_SEGMENT) { 72 - *(SectorMap *) dst_ptr = 0x800000 + sector; 73 - dst_ptr += 3; 74 - sector += SECTORS_PER_SEGMENT; 75 - } else { 76 - for (i = 0; i < SECTORS_PER_SEGMENT; ++i) { 77 - if (map & 1) { 78 - *(SewctorMap *) dst_ptr = sector; 79 - dst_ptr += 3; 80 - } 81 - map >>= 1; 82 - ++sector; 83 - } 84 - } 85 - } 86 - } 87 - bad_sector_map_changed = 1; 88 - *(buffer + 4) = new_code; /* put new format code */ 89 - if (format_code != fmt_var && new_code == fmt_big) { 90 - PUT4(buffer, FT_6_HSEG_1, (__u32)GET2(buffer, 6)); 91 - PUT4(buffer, FT_6_HSEG_2, (__u32)GET2(buffer, 8)); 92 - PUT4(buffer, FT_6_FRST_SEG, (__u32)GET2(buffer, 10)); 93 - PUT4(buffer, FT_6_LAST_SEG, (__u32)GET2(buffer, 12)); 94 - memset(buffer+6, '\0', 8); 95 - } 96 - format_code = new_code; 97 - } 98 - 99 - #endif 100 - 101 - /* given buffer that contains a header segment, find the end of 102 - * of the bsm list 103 - */ 104 - __u8 * ftape_find_end_of_bsm_list(__u8 * address) 105 - { 106 - __u8 *ptr = address + FT_HEADER_END; /* start of bsm list */ 107 - __u8 *limit = address + FT_SEGMENT_SIZE; 108 - while (ptr + 2 < limit) { 109 - if (ptr[0] || ptr[1] || ptr[2]) { 110 - ptr += 3; 111 - } else { 112 - return ptr; 113 - } 114 - } 115 - return NULL; 116 - } 117 - 118 - static inline void put_sector(SectorCount *ptr, unsigned int sector) 119 - { 120 - ptr->bytes[0] = sector & 0xff; 121 - sector >>= 8; 122 - ptr->bytes[1] = sector & 0xff; 123 - sector >>= 8; 124 - ptr->bytes[2] = sector & 0xff; 125 - } 126 - 127 - static inline unsigned int get_sector(SectorCount *ptr) 128 - { 129 - #if 1 130 - unsigned int sector; 131 - 132 - sector = ptr->bytes[0]; 133 - sector += ptr->bytes[1] << 8; 134 - sector += ptr->bytes[2] << 16; 135 - 136 - return sector; 137 - #else 138 - /* GET4 gets the next four bytes in Intel little endian order 139 - * and converts them to host byte order and handles unaligned 140 - * access. 141 - */ 142 - return (GET4(ptr, 0) & 0x00ffffff); /* back to host byte order */ 143 - #endif 144 - } 145 - 146 - static void bsm_debug_fake(void) 147 - { 148 - /* for testing of bad sector handling at end of tape 149 - */ 150 - #if 0 151 - ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 3, 152 - 0x000003e0; 153 - ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 2, 154 - 0xff3fffff; 155 - ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 1, 156 - 0xffffe000; 157 - #endif 158 - /* Enable to test bad sector handling 159 - */ 160 - #if 0 161 - ftape_put_bad_sector_entry(30, 0xfffffffe) 162 - ftape_put_bad_sector_entry(32, 0x7fffffff); 163 - ftape_put_bad_sector_entry(34, 0xfffeffff); 164 - ftape_put_bad_sector_entry(36, 0x55555555); 165 - ftape_put_bad_sector_entry(38, 0xffffffff); 166 - ftape_put_bad_sector_entry(50, 0xffff0000); 167 - ftape_put_bad_sector_entry(51, 0xffffffff); 168 - ftape_put_bad_sector_entry(52, 0xffffffff); 169 - ftape_put_bad_sector_entry(53, 0x0000ffff); 170 - #endif 171 - /* Enable when testing multiple volume tar dumps. 172 - */ 173 - #if 0 174 - { 175 - int i; 176 - 177 - for (i = ft_first_data_segment; 178 - i <= ft_last_data_segment - 7; ++i) { 179 - ftape_put_bad_sector_entry(i, EMPTY_SEGMENT); 180 - } 181 - } 182 - #endif 183 - /* Enable when testing bit positions in *_error_map 184 - */ 185 - #if 0 186 - { 187 - int i; 188 - 189 - for (i = first_data_segment; i <= last_data_segment; ++i) { 190 - ftape_put_bad_sector_entry(i, 191 - ftape_get_bad_sector_entry(i) 192 - | 0x00ff00ff); 193 - } 194 - } 195 - #endif 196 - } 197 - 198 - static void print_bad_sector_map(void) 199 - { 200 - unsigned int good_sectors; 201 - unsigned int total_bad = 0; 202 - int i; 203 - TRACE_FUN(ft_t_flow); 204 - 205 - if (ft_format_code == fmt_big || 206 - ft_format_code == fmt_var || 207 - ft_format_code == fmt_1100ft) { 208 - SectorCount *ptr = (SectorCount *)bad_sector_map; 209 - unsigned int sector; 210 - __u16 *ptr16; 211 - 212 - while((sector = get_sector(ptr++)) != 0) { 213 - if ((ft_format_code == fmt_big || 214 - ft_format_code == fmt_var) && 215 - sector & 0x800000) { 216 - total_bad += FT_SECTORS_PER_SEGMENT - 3; 217 - TRACE(ft_t_noise, "bad segment at sector: %6d", 218 - sector & 0x7fffff); 219 - } else { 220 - ++total_bad; 221 - TRACE(ft_t_noise, "bad sector: %6d", sector); 222 - } 223 - } 224 - /* Display old ftape's end-of-file marks 225 - */ 226 - ptr16 = (__u16*)ptr; 227 - while ((sector = get_unaligned(ptr16++)) != 0) { 228 - TRACE(ft_t_noise, "Old ftape eof mark: %4d/%2d", 229 - sector, get_unaligned(ptr16++)); 230 - } 231 - } else { /* fixed size format */ 232 - for (i = ft_first_data_segment; 233 - i < (int)(ft_segments_per_track * ft_tracks_per_tape); ++i) { 234 - SectorMap map = ((SectorMap *) bad_sector_map)[i]; 235 - 236 - if (map) { 237 - TRACE(ft_t_noise, 238 - "bsm for segment %4d: 0x%08x", i, (unsigned int)map); 239 - total_bad += ((map == EMPTY_SEGMENT) 240 - ? FT_SECTORS_PER_SEGMENT - 3 241 - : count_ones(map)); 242 - } 243 - } 244 - } 245 - good_sectors = 246 - ((ft_segments_per_track * ft_tracks_per_tape - ft_first_data_segment) 247 - * (FT_SECTORS_PER_SEGMENT - 3)) - total_bad; 248 - TRACE(ft_t_info, "%d Kb usable on this tape", good_sectors); 249 - if (total_bad == 0) { 250 - TRACE(ft_t_info, 251 - "WARNING: this tape has no bad blocks registered !"); 252 - } else { 253 - TRACE(ft_t_info, "%d bad sectors", total_bad); 254 - } 255 - TRACE_EXIT; 256 - } 257 - 258 - 259 - void ftape_extract_bad_sector_map(__u8 * buffer) 260 - { 261 - TRACE_FUN(ft_t_any); 262 - 263 - /* Fill the bad sector map with the contents of buffer. 264 - */ 265 - if (ft_format_code == fmt_var || ft_format_code == fmt_big) { 266 - /* QIC-3010/3020 and wide QIC-80 tapes no longer have a failed 267 - * sector log but use this area to extend the bad sector map. 268 - */ 269 - bad_sector_map = &buffer[FT_HEADER_END]; 270 - } else { 271 - /* non-wide QIC-80 tapes have a failed sector log area that 272 - * mustn't be included in the bad sector map. 273 - */ 274 - bad_sector_map = &buffer[FT_FSL + FT_FSL_SIZE]; 275 - } 276 - if (ft_format_code == fmt_1100ft || 277 - ft_format_code == fmt_var || 278 - ft_format_code == fmt_big) { 279 - bsm_hash_ptr = (SectorCount *)bad_sector_map; 280 - } else { 281 - bsm_hash_ptr = NULL; 282 - } 283 - bsm_debug_fake(); 284 - if (TRACE_LEVEL >= ft_t_info) { 285 - print_bad_sector_map(); 286 - } 287 - TRACE_EXIT; 288 - } 289 - 290 - static inline SectorMap cvt2map(unsigned int sector) 291 - { 292 - return 1 << (((sector & 0x7fffff) - 1) % FT_SECTORS_PER_SEGMENT); 293 - } 294 - 295 - static inline int cvt2segment(unsigned int sector) 296 - { 297 - return ((sector & 0x7fffff) - 1) / FT_SECTORS_PER_SEGMENT; 298 - } 299 - 300 - static int forward_seek_entry(int segment_id, 301 - SectorCount **ptr, 302 - SectorMap *map) 303 - { 304 - unsigned int sector; 305 - int segment; 306 - 307 - do { 308 - sector = get_sector((*ptr)++); 309 - segment = cvt2segment(sector); 310 - } while (sector != 0 && segment < segment_id); 311 - (*ptr) --; /* point to first sector >= segment_id */ 312 - /* Get all sectors in segment_id 313 - */ 314 - if (sector == 0 || segment != segment_id) { 315 - *map = 0; 316 - return 0; 317 - } else if ((sector & 0x800000) && 318 - (ft_format_code == fmt_var || ft_format_code == fmt_big)) { 319 - *map = EMPTY_SEGMENT; 320 - return FT_SECTORS_PER_SEGMENT; 321 - } else { 322 - int count = 1; 323 - SectorCount *tmp_ptr = (*ptr) + 1; 324 - 325 - *map = cvt2map(sector); 326 - while ((sector = get_sector(tmp_ptr++)) != 0 && 327 - (segment = cvt2segment(sector)) == segment_id) { 328 - *map |= cvt2map(sector); 329 - ++count; 330 - } 331 - return count; 332 - } 333 - } 334 - 335 - static int backwards_seek_entry(int segment_id, 336 - SectorCount **ptr, 337 - SectorMap *map) 338 - { 339 - unsigned int sector; 340 - int segment; /* max unsigned int */ 341 - 342 - if (*ptr <= (SectorCount *)bad_sector_map) { 343 - *map = 0; 344 - return 0; 345 - } 346 - do { 347 - sector = get_sector(--(*ptr)); 348 - segment = cvt2segment(sector); 349 - } while (*ptr > (SectorCount *)bad_sector_map && segment > segment_id); 350 - if (segment > segment_id) { /* at start of list, no entry found */ 351 - *map = 0; 352 - return 0; 353 - } else if (segment < segment_id) { 354 - /* before smaller entry, adjust for overshoot */ 355 - (*ptr) ++; 356 - *map = 0; 357 - return 0; 358 - } else if ((sector & 0x800000) && 359 - (ft_format_code == fmt_big || ft_format_code == fmt_var)) { 360 - *map = EMPTY_SEGMENT; 361 - return FT_SECTORS_PER_SEGMENT; 362 - } else { /* get all sectors in segment_id */ 363 - int count = 1; 364 - 365 - *map = cvt2map(sector); 366 - while(*ptr > (SectorCount *)bad_sector_map) { 367 - sector = get_sector(--(*ptr)); 368 - segment = cvt2segment(sector); 369 - if (segment != segment_id) { 370 - break; 371 - } 372 - *map |= cvt2map(sector); 373 - ++count; 374 - } 375 - if (segment < segment_id) { 376 - (*ptr) ++; 377 - } 378 - return count; 379 - } 380 - } 381 - 382 - #if 0 383 - static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map) 384 - { 385 - SectorCount *ptr = (SectorCount *)bad_sector_map; 386 - int count; 387 - int new_count; 388 - SectorMap map; 389 - TRACE_FUN(ft_t_any); 390 - 391 - if (ft_format_code == fmt_1100ft || 392 - ft_format_code == fmt_var || 393 - ft_format_code == fmt_big) { 394 - count = forward_seek_entry(segment_id, &ptr, &map); 395 - new_count = count_ones(new_map); 396 - /* If format code == 4 put empty segment instead of 32 397 - * bad sectors. 398 - */ 399 - if (ft_format_code == fmt_var || ft_format_code == fmt_big) { 400 - if (new_count == FT_SECTORS_PER_SEGMENT) { 401 - new_count = 1; 402 - } 403 - if (count == FT_SECTORS_PER_SEGMENT) { 404 - count = 1; 405 - } 406 - } 407 - if (count != new_count) { 408 - /* insert (or delete if < 0) new_count - count 409 - * entries. Move trailing part of list 410 - * including terminating 0. 411 - */ 412 - SectorCount *hi_ptr = ptr; 413 - 414 - do { 415 - } while (get_sector(hi_ptr++) != 0); 416 - /* Note: ptr is of type byte *, and each bad sector 417 - * consumes 3 bytes. 418 - */ 419 - memmove(ptr + new_count, ptr + count, 420 - (size_t)(hi_ptr - (ptr + count))*sizeof(SectorCount)); 421 - } 422 - TRACE(ft_t_noise, "putting map 0x%08x at %p, segment %d", 423 - (unsigned int)new_map, ptr, segment_id); 424 - if (new_count == 1 && new_map == EMPTY_SEGMENT) { 425 - put_sector(ptr++, (0x800001 + 426 - segment_id * 427 - FT_SECTORS_PER_SEGMENT)); 428 - } else { 429 - int i = 0; 430 - 431 - while (new_map) { 432 - if (new_map & 1) { 433 - put_sector(ptr++, 434 - 1 + segment_id * 435 - FT_SECTORS_PER_SEGMENT + i); 436 - } 437 - ++i; 438 - new_map >>= 1; 439 - } 440 - } 441 - } else { 442 - ((SectorMap *) bad_sector_map)[segment_id] = new_map; 443 - } 444 - TRACE_EXIT; 445 - } 446 - #endif /* 0 */ 447 - 448 - SectorMap ftape_get_bad_sector_entry(int segment_id) 449 - { 450 - if (ft_used_header_segment == -1) { 451 - /* When reading header segment we'll need a blank map. 452 - */ 453 - return 0; 454 - } else if (bsm_hash_ptr != NULL) { 455 - /* Invariants: 456 - * map - mask value returned on last call. 457 - * bsm_hash_ptr - points to first sector greater or equal to 458 - * first sector in last_referenced segment. 459 - * last_referenced - segment id used in the last call, 460 - * sector and map belong to this id. 461 - * This code is designed for sequential access and retries. 462 - * For true random access it may have to be redesigned. 463 - */ 464 - static int last_reference = -1; 465 - static SectorMap map; 466 - 467 - if (segment_id > last_reference) { 468 - /* Skip all sectors before segment_id 469 - */ 470 - forward_seek_entry(segment_id, &bsm_hash_ptr, &map); 471 - } else if (segment_id < last_reference) { 472 - /* Skip backwards until begin of buffer or 473 - * first sector in segment_id 474 - */ 475 - backwards_seek_entry(segment_id, &bsm_hash_ptr, &map); 476 - } /* segment_id == last_reference : keep map */ 477 - last_reference = segment_id; 478 - return map; 479 - } else { 480 - return ((SectorMap *) bad_sector_map)[segment_id]; 481 - } 482 - } 483 - 484 - /* This is simply here to prevent us from overwriting other kernel 485 - * data. Writes will result in NULL Pointer dereference. 486 - */ 487 - void ftape_init_bsm(void) 488 - { 489 - bad_sector_map = NULL; 490 - bsm_hash_ptr = NULL; 491 - }
-66
drivers/char/ftape/lowlevel/ftape-bsm.h
··· 1 - #ifndef _FTAPE_BSM_H 2 - #define _FTAPE_BSM_H 3 - 4 - /* 5 - * Copyright (C) 1994-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-bsm.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:07 $ 26 - * 27 - * This file contains definitions for the bad sector map handling 28 - * routines for the QIC-117 floppy-tape driver for Linux. 29 - */ 30 - 31 - #include <linux/ftape.h> 32 - #include <linux/ftape-header-segment.h> 33 - 34 - #define EMPTY_SEGMENT (0xffffffff) 35 - #define FAKE_SEGMENT (0xfffffffe) 36 - 37 - /* maximum (format code 4) bad sector map size (bytes). 38 - */ 39 - #define BAD_SECTOR_MAP_SIZE (29 * SECTOR_SIZE - 256) 40 - 41 - /* format code 4 bad sector entry, ftape uses this 42 - * internally for all format codes 43 - */ 44 - typedef __u32 SectorMap; 45 - /* variable and 1100 ft bad sector map entry. These three bytes represent 46 - * a single sector address measured from BOT. 47 - */ 48 - typedef struct NewSectorMap { 49 - __u8 bytes[3]; 50 - } SectorCount; 51 - 52 - 53 - /* 54 - * ftape-bsm.c defined global vars. 55 - */ 56 - 57 - /* 58 - * ftape-bsm.c defined global functions. 59 - */ 60 - extern void update_bad_sector_map(__u8 * buffer); 61 - extern void ftape_extract_bad_sector_map(__u8 * buffer); 62 - extern SectorMap ftape_get_bad_sector_entry(int segment_id); 63 - extern __u8 *ftape_find_end_of_bsm_list(__u8 * address); 64 - extern void ftape_init_bsm(void); 65 - 66 - #endif
-130
drivers/char/ftape/lowlevel/ftape-buffer.c
··· 1 - /* 2 - * Copyright (C) 1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-buffer.c,v $ 20 - * $Revision: 1.3 $ 21 - * $Date: 1997/10/16 23:33:11 $ 22 - * 23 - * This file contains the allocator/dealloctor for ftape's dynamic dma 24 - * buffer. 25 - */ 26 - 27 - #include <linux/slab.h> 28 - #include <linux/mm.h> 29 - #include <linux/mman.h> 30 - #include <asm/dma.h> 31 - 32 - #include <linux/ftape.h> 33 - #include "../lowlevel/ftape-rw.h" 34 - #include "../lowlevel/ftape-read.h" 35 - #include "../lowlevel/ftape-tracing.h" 36 - #include "../lowlevel/ftape-buffer.h" 37 - 38 - /* DMA'able memory allocation stuff. 39 - */ 40 - 41 - static inline void *dmaalloc(size_t size) 42 - { 43 - unsigned long addr; 44 - 45 - if (size == 0) { 46 - return NULL; 47 - } 48 - addr = __get_dma_pages(GFP_KERNEL, get_order(size)); 49 - if (addr) { 50 - struct page *page; 51 - 52 - for (page = virt_to_page(addr); page < virt_to_page(addr+size); page++) 53 - SetPageReserved(page); 54 - } 55 - return (void *)addr; 56 - } 57 - 58 - static inline void dmafree(void *addr, size_t size) 59 - { 60 - if (size > 0) { 61 - struct page *page; 62 - 63 - for (page = virt_to_page((unsigned long)addr); 64 - page < virt_to_page((unsigned long)addr+size); page++) 65 - ClearPageReserved(page); 66 - free_pages((unsigned long) addr, get_order(size)); 67 - } 68 - } 69 - 70 - static int add_one_buffer(void) 71 - { 72 - TRACE_FUN(ft_t_flow); 73 - 74 - if (ft_nr_buffers >= FT_MAX_NR_BUFFERS) { 75 - TRACE_EXIT -ENOMEM; 76 - } 77 - ft_buffer[ft_nr_buffers] = kmalloc(sizeof(buffer_struct), GFP_KERNEL); 78 - if (ft_buffer[ft_nr_buffers] == NULL) { 79 - TRACE_EXIT -ENOMEM; 80 - } 81 - memset(ft_buffer[ft_nr_buffers], 0, sizeof(buffer_struct)); 82 - ft_buffer[ft_nr_buffers]->address = dmaalloc(FT_BUFF_SIZE); 83 - if (ft_buffer[ft_nr_buffers]->address == NULL) { 84 - kfree(ft_buffer[ft_nr_buffers]); 85 - ft_buffer[ft_nr_buffers] = NULL; 86 - TRACE_EXIT -ENOMEM; 87 - } 88 - ft_nr_buffers ++; 89 - TRACE(ft_t_info, "buffer nr #%d @ %p, dma area @ %p", 90 - ft_nr_buffers, 91 - ft_buffer[ft_nr_buffers-1], 92 - ft_buffer[ft_nr_buffers-1]->address); 93 - TRACE_EXIT 0; 94 - } 95 - 96 - static void del_one_buffer(void) 97 - { 98 - TRACE_FUN(ft_t_flow); 99 - if (ft_nr_buffers > 0) { 100 - TRACE(ft_t_info, "releasing buffer nr #%d @ %p, dma area @ %p", 101 - ft_nr_buffers, 102 - ft_buffer[ft_nr_buffers-1], 103 - ft_buffer[ft_nr_buffers-1]->address); 104 - ft_nr_buffers --; 105 - dmafree(ft_buffer[ft_nr_buffers]->address, FT_BUFF_SIZE); 106 - kfree(ft_buffer[ft_nr_buffers]); 107 - ft_buffer[ft_nr_buffers] = NULL; 108 - } 109 - TRACE_EXIT; 110 - } 111 - 112 - int ftape_set_nr_buffers(int cnt) 113 - { 114 - int delta = cnt - ft_nr_buffers; 115 - TRACE_FUN(ft_t_flow); 116 - 117 - if (delta > 0) { 118 - while (delta--) { 119 - if (add_one_buffer() < 0) { 120 - TRACE_EXIT -ENOMEM; 121 - } 122 - } 123 - } else if (delta < 0) { 124 - while (delta++) { 125 - del_one_buffer(); 126 - } 127 - } 128 - ftape_zap_read_buffers(); 129 - TRACE_EXIT 0; 130 - }
-32
drivers/char/ftape/lowlevel/ftape-buffer.h
··· 1 - #ifndef _FTAPE_BUFFER_H 2 - #define _FTAPE_BUFFER_H 3 - 4 - /* 5 - * Copyright (C) 1997 Claus-Justus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-buffer.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:18:08 $ 25 - * 26 - * This file contains the allocator/dealloctor for ftape's dynamic dma 27 - * buffer. 28 - */ 29 - 30 - extern int ftape_set_nr_buffers(int cnt); 31 - 32 - #endif
-275
drivers/char/ftape/lowlevel/ftape-calibr.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven. 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-calibr.c,v $ 20 - * $Revision: 1.2 $ 21 - * $Date: 1997/10/05 19:18:08 $ 22 - * 23 - * GP calibration routine for processor speed dependent 24 - * functions. 25 - */ 26 - 27 - #include <linux/errno.h> 28 - #include <linux/jiffies.h> 29 - #include <asm/system.h> 30 - #include <asm/io.h> 31 - #if defined(__alpha__) 32 - # include <asm/hwrpb.h> 33 - #elif defined(__x86_64__) 34 - # include <asm/msr.h> 35 - # include <asm/timex.h> 36 - #elif defined(__i386__) 37 - # include <linux/timex.h> 38 - #endif 39 - #include <linux/ftape.h> 40 - #include "../lowlevel/ftape-tracing.h" 41 - #include "../lowlevel/ftape-calibr.h" 42 - #include "../lowlevel/fdc-io.h" 43 - 44 - #undef DEBUG 45 - 46 - #if !defined(__alpha__) && !defined(__i386__) && !defined(__x86_64__) 47 - # error Ftape is not implemented for this architecture! 48 - #endif 49 - 50 - #if defined(__alpha__) || defined(__x86_64__) 51 - static unsigned long ps_per_cycle = 0; 52 - #endif 53 - 54 - static spinlock_t calibr_lock; 55 - 56 - /* 57 - * Note: On Intel PCs, the clock ticks at 100 Hz (HZ==100) which is 58 - * too slow for certain timeouts (and that clock doesn't even tick 59 - * when interrupts are disabled). For that reason, the 8254 timer is 60 - * used directly to implement fine-grained timeouts. However, on 61 - * Alpha PCs, the 8254 is *not* used to implement the clock tick 62 - * (which is 1024 Hz, normally) and the 8254 timer runs at some 63 - * "random" frequency (it seems to run at 18Hz, but it's not safe to 64 - * rely on this value). Instead, we use the Alpha's "rpcc" 65 - * instruction to read cycle counts. As this is a 32 bit counter, 66 - * it will overflow only once per 30 seconds (on a 200MHz machine), 67 - * which is plenty. 68 - */ 69 - 70 - unsigned int ftape_timestamp(void) 71 - { 72 - #if defined(__alpha__) 73 - unsigned long r; 74 - 75 - asm volatile ("rpcc %0" : "=r" (r)); 76 - return r; 77 - #elif defined(__x86_64__) 78 - unsigned long r; 79 - rdtscl(r); 80 - return r; 81 - #elif defined(__i386__) 82 - 83 - /* 84 - * Note that there is some time between counter underflowing and jiffies 85 - * increasing, so the code below won't always give correct output. 86 - * -Vojtech 87 - */ 88 - 89 - unsigned long flags; 90 - __u16 lo; 91 - __u16 hi; 92 - 93 - spin_lock_irqsave(&calibr_lock, flags); 94 - outb_p(0x00, 0x43); /* latch the count ASAP */ 95 - lo = inb_p(0x40); /* read the latched count */ 96 - lo |= inb(0x40) << 8; 97 - hi = jiffies; 98 - spin_unlock_irqrestore(&calibr_lock, flags); 99 - return ((hi + 1) * (unsigned int) LATCH) - lo; /* downcounter ! */ 100 - #endif 101 - } 102 - 103 - static unsigned int short_ftape_timestamp(void) 104 - { 105 - #if defined(__alpha__) || defined(__x86_64__) 106 - return ftape_timestamp(); 107 - #elif defined(__i386__) 108 - unsigned int count; 109 - unsigned long flags; 110 - 111 - spin_lock_irqsave(&calibr_lock, flags); 112 - outb_p(0x00, 0x43); /* latch the count ASAP */ 113 - count = inb_p(0x40); /* read the latched count */ 114 - count |= inb(0x40) << 8; 115 - spin_unlock_irqrestore(&calibr_lock, flags); 116 - return (LATCH - count); /* normal: downcounter */ 117 - #endif 118 - } 119 - 120 - static unsigned int diff(unsigned int t0, unsigned int t1) 121 - { 122 - #if defined(__alpha__) || defined(__x86_64__) 123 - return (t1 - t0); 124 - #elif defined(__i386__) 125 - /* 126 - * This is tricky: to work for both short and full ftape_timestamps 127 - * we'll have to discriminate between these. 128 - * If it _looks_ like short stamps with wrapping around we'll 129 - * asume it are. This will generate a small error if it really 130 - * was a (very large) delta from full ftape_timestamps. 131 - */ 132 - return (t1 <= t0 && t0 <= LATCH) ? t1 + LATCH - t0 : t1 - t0; 133 - #endif 134 - } 135 - 136 - static unsigned int usecs(unsigned int count) 137 - { 138 - #if defined(__alpha__) || defined(__x86_64__) 139 - return (ps_per_cycle * count) / 1000000UL; 140 - #elif defined(__i386__) 141 - return (10000 * count) / ((CLOCK_TICK_RATE + 50) / 100); 142 - #endif 143 - } 144 - 145 - unsigned int ftape_timediff(unsigned int t0, unsigned int t1) 146 - { 147 - /* 148 - * Calculate difference in usec for ftape_timestamp results t0 & t1. 149 - * Note that on the i386 platform with short time-stamps, the 150 - * maximum allowed timespan is 1/HZ or we'll lose ticks! 151 - */ 152 - return usecs(diff(t0, t1)); 153 - } 154 - 155 - /* To get an indication of the I/O performance, 156 - * measure the duration of the inb() function. 157 - */ 158 - static void time_inb(void) 159 - { 160 - int i; 161 - int t0, t1; 162 - unsigned long flags; 163 - int status; 164 - TRACE_FUN(ft_t_any); 165 - 166 - spin_lock_irqsave(&calibr_lock, flags); 167 - t0 = short_ftape_timestamp(); 168 - for (i = 0; i < 1000; ++i) { 169 - status = inb(fdc.msr); 170 - } 171 - t1 = short_ftape_timestamp(); 172 - spin_unlock_irqrestore(&calibr_lock, flags); 173 - TRACE(ft_t_info, "inb() duration: %d nsec", ftape_timediff(t0, t1)); 174 - TRACE_EXIT; 175 - } 176 - 177 - static void init_clock(void) 178 - { 179 - TRACE_FUN(ft_t_any); 180 - 181 - #if defined(__x86_64__) 182 - ps_per_cycle = 1000000000UL / cpu_khz; 183 - #elif defined(__alpha__) 184 - extern struct hwrpb_struct *hwrpb; 185 - ps_per_cycle = (1000*1000*1000*1000UL) / hwrpb->cycle_freq; 186 - #endif 187 - TRACE_EXIT; 188 - } 189 - 190 - /* 191 - * Input: function taking int count as parameter. 192 - * pointers to calculated calibration variables. 193 - */ 194 - void ftape_calibrate(char *name, 195 - void (*fun) (unsigned int), 196 - unsigned int *calibr_count, 197 - unsigned int *calibr_time) 198 - { 199 - static int first_time = 1; 200 - int i; 201 - unsigned int tc = 0; 202 - unsigned int count; 203 - unsigned int time; 204 - #if defined(__i386__) 205 - unsigned int old_tc = 0; 206 - unsigned int old_count = 1; 207 - unsigned int old_time = 1; 208 - #endif 209 - TRACE_FUN(ft_t_flow); 210 - 211 - if (first_time) { /* get idea of I/O performance */ 212 - init_clock(); 213 - time_inb(); 214 - first_time = 0; 215 - } 216 - /* value of timeout must be set so that on very slow systems 217 - * it will give a time less than one jiffy, and on 218 - * very fast systems it'll give reasonable precision. 219 - */ 220 - 221 - count = 40; 222 - for (i = 0; i < 15; ++i) { 223 - unsigned int t0; 224 - unsigned int t1; 225 - unsigned int once; 226 - unsigned int multiple; 227 - unsigned long flags; 228 - 229 - *calibr_count = 230 - *calibr_time = count; /* set TC to 1 */ 231 - spin_lock_irqsave(&calibr_lock, flags); 232 - fun(0); /* dummy, get code into cache */ 233 - t0 = short_ftape_timestamp(); 234 - fun(0); /* overhead + one test */ 235 - t1 = short_ftape_timestamp(); 236 - once = diff(t0, t1); 237 - t0 = short_ftape_timestamp(); 238 - fun(count); /* overhead + count tests */ 239 - t1 = short_ftape_timestamp(); 240 - multiple = diff(t0, t1); 241 - spin_unlock_irqrestore(&calibr_lock, flags); 242 - time = ftape_timediff(0, multiple - once); 243 - tc = (1000 * time) / (count - 1); 244 - TRACE(ft_t_any, "once:%3d us,%6d times:%6d us, TC:%5d ns", 245 - usecs(once), count - 1, usecs(multiple), tc); 246 - #if defined(__alpha__) || defined(__x86_64__) 247 - /* 248 - * Increase the calibration count exponentially until the 249 - * calibration time exceeds 100 ms. 250 - */ 251 - if (time >= 100*1000) { 252 - break; 253 - } 254 - #elif defined(__i386__) 255 - /* 256 - * increase the count until the resulting time nears 2/HZ, 257 - * then the tc will drop sharply because we lose LATCH counts. 258 - */ 259 - if (tc <= old_tc / 2) { 260 - time = old_time; 261 - count = old_count; 262 - break; 263 - } 264 - old_tc = tc; 265 - old_count = count; 266 - old_time = time; 267 - #endif 268 - count *= 2; 269 - } 270 - *calibr_count = count - 1; 271 - *calibr_time = time; 272 - TRACE(ft_t_info, "TC for `%s()' = %d nsec (at %d counts)", 273 - name, (1000 * *calibr_time) / *calibr_count, *calibr_count); 274 - TRACE_EXIT; 275 - }
-37
drivers/char/ftape/lowlevel/ftape-calibr.h
··· 1 - #ifndef _FTAPE_CALIBR_H 2 - #define _FTAPE_CALIBR_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-calibr.h,v $ 23 - * $Revision: 1.1 $ 24 - * $Date: 1997/09/19 09:05:26 $ 25 - * 26 - * This file contains a gp calibration routine for 27 - * hardware dependent timeout functions. 28 - */ 29 - 30 - extern void ftape_calibrate(char *name, 31 - void (*fun) (unsigned int), 32 - unsigned int *calibr_count, 33 - unsigned int *calibr_time); 34 - extern unsigned int ftape_timestamp(void); 35 - extern unsigned int ftape_timediff(unsigned int t0, unsigned int t1); 36 - 37 - #endif /* _FTAPE_CALIBR_H */
-896
drivers/char/ftape/lowlevel/ftape-ctl.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven, 3 - * 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.c,v $ 21 - * $Revision: 1.4 $ 22 - * $Date: 1997/11/11 14:37:44 $ 23 - * 24 - * This file contains the non-read/write ftape functions for the 25 - * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. 26 - */ 27 - 28 - #include <linux/errno.h> 29 - #include <linux/mm.h> 30 - #include <linux/mman.h> 31 - 32 - #include <linux/ftape.h> 33 - #include <linux/qic117.h> 34 - #include <asm/uaccess.h> 35 - #include <asm/io.h> 36 - 37 - /* ease porting between pre-2.4.x and later kernels */ 38 - #define vma_get_pgoff(v) ((v)->vm_pgoff) 39 - 40 - #include "../lowlevel/ftape-tracing.h" 41 - #include "../lowlevel/ftape-io.h" 42 - #include "../lowlevel/ftape-ctl.h" 43 - #include "../lowlevel/ftape-write.h" 44 - #include "../lowlevel/ftape-read.h" 45 - #include "../lowlevel/ftape-rw.h" 46 - #include "../lowlevel/ftape-bsm.h" 47 - 48 - /* Global vars. 49 - */ 50 - ftape_info ftape_status = { 51 - /* vendor information */ 52 - { 0, }, /* drive type */ 53 - /* data rates */ 54 - 500, /* used data rate */ 55 - 500, /* drive max rate */ 56 - 500, /* fdc max rate */ 57 - /* drive selection, either FTAPE_SEL_A/B/C/D */ 58 - -1, /* drive selection */ 59 - /* flags set after decode the drive and tape status */ 60 - 0, /* formatted */ 61 - 1, /* no tape */ 62 - 1, /* write protected */ 63 - 1, /* new tape */ 64 - /* values of last queried drive/tape status and error */ 65 - {{0,}}, /* last error code */ 66 - {{0,}}, /* drive status, configuration, tape status */ 67 - /* cartridge geometry */ 68 - 20, /* tracks_per_tape */ 69 - 102, /* segments_per_track */ 70 - /* location of header segments, etc. */ 71 - -1, /* used_header_segment */ 72 - -1, /* header_segment_1 */ 73 - -1, /* header_segment_2 */ 74 - -1, /* first_data_segment */ 75 - -1, /* last_data_segment */ 76 - /* the format code as stored in the header segment */ 77 - fmt_normal, /* format code */ 78 - /* the default for the qic std: unknown */ 79 - -1, 80 - /* is tape running? */ 81 - idle, /* runner_state */ 82 - /* is tape reading/writing/verifying/formatting/deleting */ 83 - idle, /* driver state */ 84 - /* flags fatal hardware error */ 85 - 1, /* failure */ 86 - /* history record */ 87 - { 0, } /* history record */ 88 - }; 89 - 90 - int ftape_segments_per_head = 1020; 91 - int ftape_segments_per_cylinder = 4; 92 - int ftape_init_drive_needed = 1; /* need to be global for ftape_reset_drive() 93 - * in ftape-io.c 94 - */ 95 - 96 - /* Local vars. 97 - */ 98 - static const vendor_struct vendors[] = QIC117_VENDORS; 99 - static const wakeup_method methods[] = WAKEUP_METHODS; 100 - 101 - const ftape_info *ftape_get_status(void) 102 - { 103 - #if defined(STATUS_PARANOYA) 104 - static ftape_info get_status; 105 - 106 - get_status = ftape_status; 107 - return &get_status; 108 - #else 109 - return &ftape_status; /* maybe return only a copy of it to assure 110 - * read only access 111 - */ 112 - #endif 113 - } 114 - 115 - static int ftape_not_operational(int status) 116 - { 117 - /* return true if status indicates tape can not be used. 118 - */ 119 - return ((status ^ QIC_STATUS_CARTRIDGE_PRESENT) & 120 - (QIC_STATUS_ERROR | 121 - QIC_STATUS_CARTRIDGE_PRESENT | 122 - QIC_STATUS_NEW_CARTRIDGE)); 123 - } 124 - 125 - int ftape_seek_to_eot(void) 126 - { 127 - int status; 128 - TRACE_FUN(ft_t_any); 129 - 130 - TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),); 131 - while ((status & QIC_STATUS_AT_EOT) == 0) { 132 - if (ftape_not_operational(status)) { 133 - TRACE_EXIT -EIO; 134 - } 135 - TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD, 136 - ftape_timeout.rewind,&status),); 137 - } 138 - TRACE_EXIT 0; 139 - } 140 - 141 - int ftape_seek_to_bot(void) 142 - { 143 - int status; 144 - TRACE_FUN(ft_t_any); 145 - 146 - TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),); 147 - while ((status & QIC_STATUS_AT_BOT) == 0) { 148 - if (ftape_not_operational(status)) { 149 - TRACE_EXIT -EIO; 150 - } 151 - TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE, 152 - ftape_timeout.rewind,&status),); 153 - } 154 - TRACE_EXIT 0; 155 - } 156 - 157 - static int ftape_new_cartridge(void) 158 - { 159 - ft_location.track = -1; /* force seek on first access */ 160 - ftape_zap_read_buffers(); 161 - ftape_zap_write_buffers(); 162 - return 0; 163 - } 164 - 165 - int ftape_abort_operation(void) 166 - { 167 - int result = 0; 168 - int status; 169 - TRACE_FUN(ft_t_flow); 170 - 171 - if (ft_runner_status == running) { 172 - TRACE(ft_t_noise, "aborting runner, waiting"); 173 - 174 - ft_runner_status = do_abort; 175 - /* set timeout so that the tape will run to logical EOT 176 - * if we missed the last sector and there are no queue pulses. 177 - */ 178 - result = ftape_dumb_stop(); 179 - } 180 - if (ft_runner_status != idle) { 181 - if (ft_runner_status == do_abort) { 182 - TRACE(ft_t_noise, "forcing runner abort"); 183 - } 184 - TRACE(ft_t_noise, "stopping tape"); 185 - result = ftape_stop_tape(&status); 186 - ft_location.known = 0; 187 - ft_runner_status = idle; 188 - } 189 - ftape_reset_buffer(); 190 - ftape_zap_read_buffers(); 191 - ftape_set_state(idle); 192 - TRACE_EXIT result; 193 - } 194 - 195 - static int lookup_vendor_id(unsigned int vendor_id) 196 - { 197 - int i = 0; 198 - 199 - while (vendors[i].vendor_id != vendor_id) { 200 - if (++i >= NR_ITEMS(vendors)) { 201 - return -1; 202 - } 203 - } 204 - return i; 205 - } 206 - 207 - static void ftape_detach_drive(void) 208 - { 209 - TRACE_FUN(ft_t_any); 210 - 211 - TRACE(ft_t_flow, "disabling tape drive and fdc"); 212 - ftape_put_drive_to_sleep(ft_drive_type.wake_up); 213 - fdc_catch_stray_interrupts(1); /* one always comes */ 214 - fdc_disable(); 215 - fdc_release_irq_and_dma(); 216 - fdc_release_regions(); 217 - TRACE_EXIT; 218 - } 219 - 220 - static void clear_history(void) 221 - { 222 - ft_history.used = 0; 223 - ft_history.id_am_errors = 224 - ft_history.id_crc_errors = 225 - ft_history.data_am_errors = 226 - ft_history.data_crc_errors = 227 - ft_history.overrun_errors = 228 - ft_history.no_data_errors = 229 - ft_history.retries = 230 - ft_history.crc_errors = 231 - ft_history.crc_failures = 232 - ft_history.ecc_failures = 233 - ft_history.corrected = 234 - ft_history.defects = 235 - ft_history.rewinds = 0; 236 - } 237 - 238 - static int ftape_activate_drive(vendor_struct * drive_type) 239 - { 240 - int result = 0; 241 - TRACE_FUN(ft_t_flow); 242 - 243 - /* If we already know the drive type, wake it up. 244 - * Else try to find out what kind of drive is attached. 245 - */ 246 - if (drive_type->wake_up != unknown_wake_up) { 247 - TRACE(ft_t_flow, "enabling tape drive and fdc"); 248 - result = ftape_wakeup_drive(drive_type->wake_up); 249 - if (result < 0) { 250 - TRACE(ft_t_err, "known wakeup method failed"); 251 - } 252 - } else { 253 - wake_up_types method; 254 - const ft_trace_t old_tracing = TRACE_LEVEL; 255 - if (TRACE_LEVEL < ft_t_flow) { 256 - SET_TRACE_LEVEL(ft_t_bug); 257 - } 258 - 259 - /* Try to awaken the drive using all known methods. 260 - * Lower tracing for a while. 261 - */ 262 - for (method=no_wake_up; method < NR_ITEMS(methods); ++method) { 263 - drive_type->wake_up = method; 264 - #ifdef CONFIG_FT_TWO_DRIVES 265 - /* Test setup for dual drive configuration. 266 - * /dev/rft2 uses mountain wakeup 267 - * /dev/rft3 uses colorado wakeup 268 - * Other systems will use the normal scheme. 269 - */ 270 - if ((ft_drive_sel < 2) || 271 - (ft_drive_sel == 2 && method == FT_WAKE_UP_1) || 272 - (ft_drive_sel == 3 && method == FT_WAKE_UP_2)) { 273 - result=ftape_wakeup_drive(drive_type->wake_up); 274 - } else { 275 - result = -EIO; 276 - } 277 - #else 278 - result = ftape_wakeup_drive(drive_type->wake_up); 279 - #endif 280 - if (result >= 0) { 281 - TRACE(ft_t_warn, "drive wakeup method: %s", 282 - methods[drive_type->wake_up].name); 283 - break; 284 - } 285 - } 286 - SET_TRACE_LEVEL(old_tracing); 287 - 288 - if (method >= NR_ITEMS(methods)) { 289 - /* no response at all, cannot open this drive */ 290 - drive_type->wake_up = unknown_wake_up; 291 - TRACE(ft_t_err, "no tape drive found !"); 292 - result = -ENODEV; 293 - } 294 - } 295 - TRACE_EXIT result; 296 - } 297 - 298 - static int ftape_get_drive_status(void) 299 - { 300 - int result; 301 - int status; 302 - TRACE_FUN(ft_t_flow); 303 - 304 - ft_no_tape = ft_write_protected = 0; 305 - /* Tape drive is activated now. 306 - * First clear error status if present. 307 - */ 308 - do { 309 - result = ftape_ready_wait(ftape_timeout.reset, &status); 310 - if (result < 0) { 311 - if (result == -ETIME) { 312 - TRACE(ft_t_err, "ftape_ready_wait timeout"); 313 - } else if (result == -EINTR) { 314 - TRACE(ft_t_err, "ftape_ready_wait aborted"); 315 - } else { 316 - TRACE(ft_t_err, "ftape_ready_wait failed"); 317 - } 318 - TRACE_EXIT -EIO; 319 - } 320 - /* Clear error condition (drive is ready !) 321 - */ 322 - if (status & QIC_STATUS_ERROR) { 323 - unsigned int error; 324 - qic117_cmd_t command; 325 - 326 - TRACE(ft_t_err, "error status set"); 327 - result = ftape_report_error(&error, &command, 1); 328 - if (result < 0) { 329 - TRACE(ft_t_err, 330 - "report_error_code failed: %d", result); 331 - /* hope it's working next time */ 332 - ftape_reset_drive(); 333 - TRACE_EXIT -EIO; 334 - } else if (error != 0) { 335 - TRACE(ft_t_noise, "error code : %d", error); 336 - TRACE(ft_t_noise, "error command: %d", command); 337 - } 338 - } 339 - if (status & QIC_STATUS_NEW_CARTRIDGE) { 340 - unsigned int error; 341 - qic117_cmd_t command; 342 - const ft_trace_t old_tracing = TRACE_LEVEL; 343 - SET_TRACE_LEVEL(ft_t_bug); 344 - 345 - /* Undocumented feature: Must clear (not present!) 346 - * error here or we'll fail later. 347 - */ 348 - ftape_report_error(&error, &command, 1); 349 - 350 - SET_TRACE_LEVEL(old_tracing); 351 - TRACE(ft_t_info, "status: new cartridge"); 352 - ft_new_tape = 1; 353 - } else { 354 - ft_new_tape = 0; 355 - } 356 - FT_SIGNAL_EXIT(_DONT_BLOCK); 357 - } while (status & QIC_STATUS_ERROR); 358 - 359 - ft_no_tape = !(status & QIC_STATUS_CARTRIDGE_PRESENT); 360 - ft_write_protected = (status & QIC_STATUS_WRITE_PROTECT) != 0; 361 - if (ft_no_tape) { 362 - TRACE(ft_t_warn, "no cartridge present"); 363 - } else { 364 - if (ft_write_protected) { 365 - TRACE(ft_t_noise, "Write protected cartridge"); 366 - } 367 - } 368 - TRACE_EXIT 0; 369 - } 370 - 371 - static void ftape_log_vendor_id(void) 372 - { 373 - int vendor_index; 374 - TRACE_FUN(ft_t_flow); 375 - 376 - ftape_report_vendor_id(&ft_drive_type.vendor_id); 377 - vendor_index = lookup_vendor_id(ft_drive_type.vendor_id); 378 - if (ft_drive_type.vendor_id == UNKNOWN_VENDOR && 379 - ft_drive_type.wake_up == wake_up_colorado) { 380 - vendor_index = 0; 381 - /* hack to get rid of all this mail */ 382 - ft_drive_type.vendor_id = 0; 383 - } 384 - if (vendor_index < 0) { 385 - /* Unknown vendor id, first time opening device. The 386 - * drive_type remains set to type found at wakeup 387 - * time, this will probably keep the driver operating 388 - * for this new vendor. 389 - */ 390 - TRACE(ft_t_warn, "\n" 391 - KERN_INFO "============ unknown vendor id ===========\n" 392 - KERN_INFO "A new, yet unsupported tape drive is found\n" 393 - KERN_INFO "Please report the following values:\n" 394 - KERN_INFO " Vendor id : 0x%04x\n" 395 - KERN_INFO " Wakeup method : %s\n" 396 - KERN_INFO "And a description of your tape drive\n" 397 - KERN_INFO "to "THE_FTAPE_MAINTAINER"\n" 398 - KERN_INFO "==========================================", 399 - ft_drive_type.vendor_id, 400 - methods[ft_drive_type.wake_up].name); 401 - ft_drive_type.speed = 0; /* unknown */ 402 - } else { 403 - ft_drive_type.name = vendors[vendor_index].name; 404 - ft_drive_type.speed = vendors[vendor_index].speed; 405 - TRACE(ft_t_info, "tape drive type: %s", ft_drive_type.name); 406 - /* scan all methods for this vendor_id in table */ 407 - while(ft_drive_type.wake_up != vendors[vendor_index].wake_up) { 408 - if (vendor_index < NR_ITEMS(vendors) - 1 && 409 - vendors[vendor_index + 1].vendor_id 410 - == 411 - ft_drive_type.vendor_id) { 412 - ++vendor_index; 413 - } else { 414 - break; 415 - } 416 - } 417 - if (ft_drive_type.wake_up != vendors[vendor_index].wake_up) { 418 - TRACE(ft_t_warn, "\n" 419 - KERN_INFO "==========================================\n" 420 - KERN_INFO "wakeup type mismatch:\n" 421 - KERN_INFO "found: %s, expected: %s\n" 422 - KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n" 423 - KERN_INFO "==========================================", 424 - methods[ft_drive_type.wake_up].name, 425 - methods[vendors[vendor_index].wake_up].name); 426 - } 427 - } 428 - TRACE_EXIT; 429 - } 430 - 431 - void ftape_calc_timeouts(unsigned int qic_std, 432 - unsigned int data_rate, 433 - unsigned int tape_len) 434 - { 435 - int speed; /* deci-ips ! */ 436 - int ff_speed; 437 - int length; 438 - TRACE_FUN(ft_t_any); 439 - 440 - /* tape transport speed 441 - * data rate: QIC-40 QIC-80 QIC-3010 QIC-3020 442 - * 443 - * 250 Kbps 25 ips n/a n/a n/a 444 - * 500 Kbps 50 ips 34 ips 22.6 ips n/a 445 - * 1 Mbps n/a 68 ips 45.2 ips 22.6 ips 446 - * 2 Mbps n/a n/a n/a 45.2 ips 447 - * 448 - * fast tape transport speed is at least 68 ips. 449 - */ 450 - switch (qic_std) { 451 - case QIC_TAPE_QIC40: 452 - speed = (data_rate == 250) ? 250 : 500; 453 - break; 454 - case QIC_TAPE_QIC80: 455 - speed = (data_rate == 500) ? 340 : 680; 456 - break; 457 - case QIC_TAPE_QIC3010: 458 - speed = (data_rate == 500) ? 226 : 452; 459 - break; 460 - case QIC_TAPE_QIC3020: 461 - speed = (data_rate == 1000) ? 226 : 452; 462 - break; 463 - default: 464 - TRACE(ft_t_bug, "Unknown qic_std (bug) ?"); 465 - speed = 500; 466 - break; 467 - } 468 - if (ft_drive_type.speed == 0) { 469 - unsigned long t0; 470 - static int dt = 0; /* keep gcc from complaining */ 471 - static int first_time = 1; 472 - 473 - /* Measure the time it takes to wind to EOT and back to BOT. 474 - * If the tape length is known, calculate the rewind speed. 475 - * Else keep the time value for calculation of the rewind 476 - * speed later on, when the length _is_ known. 477 - * Ask for a report only when length and speed are both known. 478 - */ 479 - if (first_time) { 480 - ftape_seek_to_bot(); 481 - t0 = jiffies; 482 - ftape_seek_to_eot(); 483 - ftape_seek_to_bot(); 484 - dt = (int) (((jiffies - t0) * FT_USPT) / 1000); 485 - if (dt < 1) { 486 - dt = 1; /* prevent div by zero on failures */ 487 - } 488 - first_time = 0; 489 - TRACE(ft_t_info, 490 - "trying to determine seek timeout, got %d msec", 491 - dt); 492 - } 493 - if (tape_len != 0) { 494 - ft_drive_type.speed = 495 - (2 * 12 * tape_len * 1000) / dt; 496 - TRACE(ft_t_warn, "\n" 497 - KERN_INFO "==========================================\n" 498 - KERN_INFO "drive type: %s\n" 499 - KERN_INFO "delta time = %d ms, length = %d ft\n" 500 - KERN_INFO "has a maximum tape speed of %d ips\n" 501 - KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n" 502 - KERN_INFO "==========================================", 503 - ft_drive_type.name, dt, tape_len, 504 - ft_drive_type.speed); 505 - } 506 - } 507 - /* Handle unknown length tapes as very long ones. We'll 508 - * determine the actual length from a header segment later. 509 - * This is normal for all modern (Wide,TR1/2/3) formats. 510 - */ 511 - if (tape_len <= 0) { 512 - TRACE(ft_t_noise, 513 - "Unknown tape length, using maximal timeouts"); 514 - length = QIC_TOP_TAPE_LEN; /* use worst case values */ 515 - } else { 516 - length = tape_len; /* use actual values */ 517 - } 518 - if (ft_drive_type.speed == 0) { 519 - ff_speed = speed; 520 - } else { 521 - ff_speed = ft_drive_type.speed; 522 - } 523 - /* time to go from bot to eot at normal speed (data rate): 524 - * time = (1+delta) * length (ft) * 12 (inch/ft) / speed (ips) 525 - * delta = 10 % for seek speed, 20 % for rewind speed. 526 - */ 527 - ftape_timeout.seek = (length * 132 * FT_SECOND) / speed; 528 - ftape_timeout.rewind = (length * 144 * FT_SECOND) / (10 * ff_speed); 529 - ftape_timeout.reset = 20 * FT_SECOND + ftape_timeout.rewind; 530 - TRACE(ft_t_noise, "timeouts for speed = %d, length = %d\n" 531 - KERN_INFO "seek timeout : %d sec\n" 532 - KERN_INFO "rewind timeout: %d sec\n" 533 - KERN_INFO "reset timeout : %d sec", 534 - speed, length, 535 - (ftape_timeout.seek + 500) / 1000, 536 - (ftape_timeout.rewind + 500) / 1000, 537 - (ftape_timeout.reset + 500) / 1000); 538 - TRACE_EXIT; 539 - } 540 - 541 - /* This function calibrates the datarate (i.e. determines the maximal 542 - * usable data rate) and sets the global variable ft_qic_std to qic_std 543 - * 544 - */ 545 - int ftape_calibrate_data_rate(unsigned int qic_std) 546 - { 547 - int rate = ft_fdc_rate_limit; 548 - int result; 549 - TRACE_FUN(ft_t_flow); 550 - 551 - ft_qic_std = qic_std; 552 - 553 - if (ft_qic_std == -1) { 554 - TRACE_ABORT(-EIO, ft_t_err, 555 - "Unable to determine data rate if QIC standard is unknown"); 556 - } 557 - 558 - /* Select highest rate supported by both fdc and drive. 559 - * Start with highest rate supported by the fdc. 560 - */ 561 - while (fdc_set_data_rate(rate) < 0 && rate > 250) { 562 - rate /= 2; 563 - } 564 - TRACE(ft_t_info, 565 - "Highest FDC supported data rate: %d Kbps", rate); 566 - ft_fdc_max_rate = rate; 567 - do { 568 - result = ftape_set_data_rate(rate, ft_qic_std); 569 - } while (result == -EINVAL && (rate /= 2) > 250); 570 - if (result < 0) { 571 - TRACE_ABORT(-EIO, ft_t_err, "set datarate failed"); 572 - } 573 - ft_data_rate = rate; 574 - TRACE_EXIT 0; 575 - } 576 - 577 - static int ftape_init_drive(void) 578 - { 579 - int status; 580 - qic_model model; 581 - unsigned int qic_std; 582 - unsigned int data_rate; 583 - TRACE_FUN(ft_t_flow); 584 - 585 - ftape_init_drive_needed = 0; /* don't retry if this fails ? */ 586 - TRACE_CATCH(ftape_report_raw_drive_status(&status),); 587 - if (status & QIC_STATUS_CARTRIDGE_PRESENT) { 588 - if (!(status & QIC_STATUS_AT_BOT)) { 589 - /* Antique drives will get here after a soft reset, 590 - * modern ones only if the driver is loaded when the 591 - * tape wasn't rewound properly. 592 - */ 593 - /* Tape should be at bot if new cartridge ! */ 594 - ftape_seek_to_bot(); 595 - } 596 - if (!(status & QIC_STATUS_REFERENCED)) { 597 - TRACE(ft_t_flow, "starting seek_load_point"); 598 - TRACE_CATCH(ftape_command_wait(QIC_SEEK_LOAD_POINT, 599 - ftape_timeout.reset, 600 - &status),); 601 - } 602 - } 603 - ft_formatted = (status & QIC_STATUS_REFERENCED) != 0; 604 - if (!ft_formatted) { 605 - TRACE(ft_t_warn, "Warning: tape is not formatted !"); 606 - } 607 - 608 - /* report configuration aborts when ftape_tape_len == -1 609 - * unknown qic_std is okay if not formatted. 610 - */ 611 - TRACE_CATCH(ftape_report_configuration(&model, 612 - &data_rate, 613 - &qic_std, 614 - &ftape_tape_len),); 615 - 616 - /* Maybe add the following to the /proc entry 617 - */ 618 - TRACE(ft_t_info, "%s drive @ %d Kbps", 619 - (model == prehistoric) ? "prehistoric" : 620 - ((model == pre_qic117c) ? "pre QIC-117C" : 621 - ((model == post_qic117b) ? "post QIC-117B" : 622 - "post QIC-117D")), data_rate); 623 - 624 - if (ft_formatted) { 625 - /* initialize ft_used_data_rate to maximum value 626 - * and set ft_qic_std 627 - */ 628 - TRACE_CATCH(ftape_calibrate_data_rate(qic_std),); 629 - if (ftape_tape_len == 0) { 630 - TRACE(ft_t_info, "unknown length QIC-%s tape", 631 - (ft_qic_std == QIC_TAPE_QIC40) ? "40" : 632 - ((ft_qic_std == QIC_TAPE_QIC80) ? "80" : 633 - ((ft_qic_std == QIC_TAPE_QIC3010) 634 - ? "3010" : "3020"))); 635 - } else { 636 - TRACE(ft_t_info, "%d ft. QIC-%s tape", ftape_tape_len, 637 - (ft_qic_std == QIC_TAPE_QIC40) ? "40" : 638 - ((ft_qic_std == QIC_TAPE_QIC80) ? "80" : 639 - ((ft_qic_std == QIC_TAPE_QIC3010) 640 - ? "3010" : "3020"))); 641 - } 642 - ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len); 643 - /* soft write-protect QIC-40/QIC-80 cartridges used with a 644 - * Colorado T3000 drive. Buggy hardware! 645 - */ 646 - if ((ft_drive_type.vendor_id == 0x011c6) && 647 - ((ft_qic_std == QIC_TAPE_QIC40 || 648 - ft_qic_std == QIC_TAPE_QIC80) && 649 - !ft_write_protected)) { 650 - TRACE(ft_t_warn, "\n" 651 - KERN_INFO "The famous Colorado T3000 bug:\n" 652 - KERN_INFO "%s drives can't write QIC40 and QIC80\n" 653 - KERN_INFO "cartridges but don't set the write-protect flag!", 654 - ft_drive_type.name); 655 - ft_write_protected = 1; 656 - } 657 - } else { 658 - /* Doesn't make too much sense to set the data rate 659 - * because we don't know what to use for the write 660 - * precompensation. 661 - * Need to do this again when formatting the cartridge. 662 - */ 663 - ft_data_rate = data_rate; 664 - ftape_calc_timeouts(QIC_TAPE_QIC40, 665 - data_rate, 666 - ftape_tape_len); 667 - } 668 - ftape_new_cartridge(); 669 - TRACE_EXIT 0; 670 - } 671 - 672 - static void ftape_munmap(void) 673 - { 674 - int i; 675 - TRACE_FUN(ft_t_flow); 676 - 677 - for (i = 0; i < ft_nr_buffers; i++) { 678 - ft_buffer[i]->mmapped = 0; 679 - } 680 - TRACE_EXIT; 681 - } 682 - 683 - /* Map the dma buffers into the virtual address range given by vma. 684 - * We only check the caller doesn't map non-existent buffers. We 685 - * don't check for multiple mappings. 686 - */ 687 - int ftape_mmap(struct vm_area_struct *vma) 688 - { 689 - int num_buffers; 690 - int i; 691 - TRACE_FUN(ft_t_flow); 692 - 693 - if (ft_failure) { 694 - TRACE_EXIT -ENODEV; 695 - } 696 - if (!(vma->vm_flags & (VM_READ|VM_WRITE))) { 697 - TRACE_ABORT(-EINVAL, ft_t_err, "Undefined mmap() access"); 698 - } 699 - if (vma_get_pgoff(vma) != 0) { 700 - TRACE_ABORT(-EINVAL, ft_t_err, "page offset must be 0"); 701 - } 702 - if ((vma->vm_end - vma->vm_start) % FT_BUFF_SIZE != 0) { 703 - TRACE_ABORT(-EINVAL, ft_t_err, 704 - "size = %ld, should be a multiple of %d", 705 - vma->vm_end - vma->vm_start, 706 - FT_BUFF_SIZE); 707 - } 708 - num_buffers = (vma->vm_end - vma->vm_start) / FT_BUFF_SIZE; 709 - if (num_buffers > ft_nr_buffers) { 710 - TRACE_ABORT(-EINVAL, 711 - ft_t_err, "size = %ld, should be less than %d", 712 - vma->vm_end - vma->vm_start, 713 - ft_nr_buffers * FT_BUFF_SIZE); 714 - } 715 - if (ft_driver_state != idle) { 716 - /* this also clears the buffer states 717 - */ 718 - ftape_abort_operation(); 719 - } else { 720 - ftape_reset_buffer(); 721 - } 722 - for (i = 0; i < num_buffers; i++) { 723 - unsigned long pfn; 724 - 725 - pfn = virt_to_phys(ft_buffer[i]->address) >> PAGE_SHIFT; 726 - TRACE_CATCH(remap_pfn_range(vma, vma->vm_start + 727 - i * FT_BUFF_SIZE, 728 - pfn, 729 - FT_BUFF_SIZE, 730 - vma->vm_page_prot), 731 - _res = -EAGAIN); 732 - TRACE(ft_t_noise, "remapped dma buffer @ %p to location @ %p", 733 - ft_buffer[i]->address, 734 - (void *)(vma->vm_start + i * FT_BUFF_SIZE)); 735 - } 736 - for (i = 0; i < num_buffers; i++) { 737 - memset(ft_buffer[i]->address, 0xAA, FT_BUFF_SIZE); 738 - ft_buffer[i]->mmapped++; 739 - } 740 - TRACE_EXIT 0; 741 - } 742 - 743 - static void ftape_init_driver(void); /* forward declaration */ 744 - 745 - /* OPEN routine called by kernel-interface code 746 - */ 747 - int ftape_enable(int drive_selection) 748 - { 749 - TRACE_FUN(ft_t_any); 750 - 751 - if (ft_drive_sel == -1 || ft_drive_sel != drive_selection) { 752 - /* Other selection than last time 753 - */ 754 - ftape_init_driver(); 755 - } 756 - ft_drive_sel = FTAPE_SEL(drive_selection); 757 - ft_failure = 0; 758 - TRACE_CATCH(fdc_init(),); /* init & detect fdc */ 759 - TRACE_CATCH(ftape_activate_drive(&ft_drive_type), 760 - fdc_disable(); 761 - fdc_release_irq_and_dma(); 762 - fdc_release_regions()); 763 - TRACE_CATCH(ftape_get_drive_status(), ftape_detach_drive()); 764 - if (ft_drive_type.vendor_id == UNKNOWN_VENDOR) { 765 - ftape_log_vendor_id(); 766 - } 767 - if (ft_new_tape) { 768 - ftape_init_drive_needed = 1; 769 - } 770 - if (!ft_no_tape && ftape_init_drive_needed) { 771 - TRACE_CATCH(ftape_init_drive(), ftape_detach_drive()); 772 - } 773 - ftape_munmap(); /* clear the mmap flag */ 774 - clear_history(); 775 - TRACE_EXIT 0; 776 - } 777 - 778 - /* release routine called by the high level interface modules 779 - * zftape or sftape. 780 - */ 781 - void ftape_disable(void) 782 - { 783 - int i; 784 - TRACE_FUN(ft_t_any); 785 - 786 - for (i = 0; i < ft_nr_buffers; i++) { 787 - if (ft_buffer[i]->mmapped) { 788 - TRACE(ft_t_noise, "first byte of buffer %d: 0x%02x", 789 - i, *ft_buffer[i]->address); 790 - } 791 - } 792 - if (sigtestsetmask(&current->pending.signal, _DONT_BLOCK) && 793 - !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)) && 794 - ftape_tape_running) { 795 - TRACE(ft_t_warn, 796 - "Interrupted by fatal signal and tape still running"); 797 - ftape_dumb_stop(); 798 - ftape_abort_operation(); /* it's annoying */ 799 - } else { 800 - ftape_set_state(idle); 801 - } 802 - ftape_detach_drive(); 803 - if (ft_history.used) { 804 - TRACE(ft_t_info, "== Non-fatal errors this run: =="); 805 - TRACE(ft_t_info, "fdc isr statistics:\n" 806 - KERN_INFO " id_am_errors : %3d\n" 807 - KERN_INFO " id_crc_errors : %3d\n" 808 - KERN_INFO " data_am_errors : %3d\n" 809 - KERN_INFO " data_crc_errors : %3d\n" 810 - KERN_INFO " overrun_errors : %3d\n" 811 - KERN_INFO " no_data_errors : %3d\n" 812 - KERN_INFO " retries : %3d", 813 - ft_history.id_am_errors, ft_history.id_crc_errors, 814 - ft_history.data_am_errors, ft_history.data_crc_errors, 815 - ft_history.overrun_errors, ft_history.no_data_errors, 816 - ft_history.retries); 817 - if (ft_history.used & 1) { 818 - TRACE(ft_t_info, "ecc statistics:\n" 819 - KERN_INFO " crc_errors : %3d\n" 820 - KERN_INFO " crc_failures : %3d\n" 821 - KERN_INFO " ecc_failures : %3d\n" 822 - KERN_INFO " sectors corrected: %3d", 823 - ft_history.crc_errors, ft_history.crc_failures, 824 - ft_history.ecc_failures, ft_history.corrected); 825 - } 826 - if (ft_history.defects > 0) { 827 - TRACE(ft_t_warn, "Warning: %d media defects!", 828 - ft_history.defects); 829 - } 830 - if (ft_history.rewinds > 0) { 831 - TRACE(ft_t_info, "tape motion statistics:\n" 832 - KERN_INFO "repositions : %3d", 833 - ft_history.rewinds); 834 - } 835 - } 836 - ft_failure = 1; 837 - TRACE_EXIT; 838 - } 839 - 840 - static void ftape_init_driver(void) 841 - { 842 - TRACE_FUN(ft_t_flow); 843 - 844 - ft_drive_type.vendor_id = UNKNOWN_VENDOR; 845 - ft_drive_type.speed = 0; 846 - ft_drive_type.wake_up = unknown_wake_up; 847 - ft_drive_type.name = "Unknown"; 848 - 849 - ftape_timeout.seek = 650 * FT_SECOND; 850 - ftape_timeout.reset = 670 * FT_SECOND; 851 - ftape_timeout.rewind = 650 * FT_SECOND; 852 - ftape_timeout.head_seek = 15 * FT_SECOND; 853 - ftape_timeout.stop = 5 * FT_SECOND; 854 - ftape_timeout.pause = 16 * FT_SECOND; 855 - 856 - ft_qic_std = -1; 857 - ftape_tape_len = 0; /* unknown */ 858 - ftape_current_command = 0; 859 - ftape_current_cylinder = -1; 860 - 861 - ft_segments_per_track = 102; 862 - ftape_segments_per_head = 1020; 863 - ftape_segments_per_cylinder = 4; 864 - ft_tracks_per_tape = 20; 865 - 866 - ft_failure = 1; 867 - 868 - ft_formatted = 0; 869 - ft_no_tape = 1; 870 - ft_write_protected = 1; 871 - ft_new_tape = 1; 872 - 873 - ft_driver_state = idle; 874 - 875 - ft_data_rate = 876 - ft_fdc_max_rate = 500; 877 - ft_drive_max_rate = 0; /* triggers set_rate_test() */ 878 - 879 - ftape_init_drive_needed = 1; 880 - 881 - ft_header_segment_1 = -1; 882 - ft_header_segment_2 = -1; 883 - ft_used_header_segment = -1; 884 - ft_first_data_segment = -1; 885 - ft_last_data_segment = -1; 886 - 887 - ft_location.track = -1; 888 - ft_location.known = 0; 889 - 890 - ftape_tape_running = 0; 891 - ftape_might_be_off_track = 1; 892 - 893 - ftape_new_cartridge(); /* init some tape related variables */ 894 - ftape_init_bsm(); 895 - TRACE_EXIT; 896 - }
-162
drivers/char/ftape/lowlevel/ftape-ctl.h
··· 1 - #ifndef _FTAPE_CTL_H 2 - #define _FTAPE_CTL_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:09 $ 26 - * 27 - * This file contains the non-standard IOCTL related definitions 28 - * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for 29 - * Linux. 30 - */ 31 - 32 - #include <linux/ioctl.h> 33 - #include <linux/mtio.h> 34 - #include <linux/ftape-vendors.h> 35 - 36 - #include "../lowlevel/ftape-rw.h" 37 - #include <linux/ftape-header-segment.h> 38 - 39 - typedef struct { 40 - int used; /* any reading or writing done */ 41 - /* isr statistics */ 42 - unsigned int id_am_errors; /* id address mark not found */ 43 - unsigned int id_crc_errors; /* crc error in id address mark */ 44 - unsigned int data_am_errors; /* data address mark not found */ 45 - unsigned int data_crc_errors; /* crc error in data field */ 46 - unsigned int overrun_errors; /* fdc access timing problem */ 47 - unsigned int no_data_errors; /* sector not found */ 48 - unsigned int retries; /* number of tape retries */ 49 - /* ecc statistics */ 50 - unsigned int crc_errors; /* crc error in data */ 51 - unsigned int crc_failures; /* bad data without crc error */ 52 - unsigned int ecc_failures; /* failed to correct */ 53 - unsigned int corrected; /* total sectors corrected */ 54 - /* general statistics */ 55 - unsigned int rewinds; /* number of tape rewinds */ 56 - unsigned int defects; /* bad sectors due to media defects */ 57 - } history_record; 58 - 59 - /* this structure contains * ALL * information that we want 60 - * our child modules to know about, but don't want them to 61 - * modify. 62 - */ 63 - typedef struct { 64 - /* vendor information */ 65 - vendor_struct fti_drive_type; 66 - /* data rates */ 67 - unsigned int fti_used_data_rate; 68 - unsigned int fti_drive_max_rate; 69 - unsigned int fti_fdc_max_rate; 70 - /* drive selection, either FTAPE_SEL_A/B/C/D */ 71 - int fti_drive_sel; 72 - /* flags set after decode the drive and tape status */ 73 - unsigned int fti_formatted :1; 74 - unsigned int fti_no_tape :1; 75 - unsigned int fti_write_protected:1; 76 - unsigned int fti_new_tape :1; 77 - /* values of last queried drive/tape status and error */ 78 - ft_drive_error fti_last_error; 79 - ft_drive_status fti_last_status; 80 - /* cartridge geometry */ 81 - unsigned int fti_tracks_per_tape; 82 - unsigned int fti_segments_per_track; 83 - /* location of header segments, etc. */ 84 - int fti_used_header_segment; 85 - int fti_header_segment_1; 86 - int fti_header_segment_2; 87 - int fti_first_data_segment; 88 - int fti_last_data_segment; 89 - /* the format code as stored in the header segment */ 90 - ft_format_type fti_format_code; 91 - /* the following is the sole reason for the ftape_set_status() call */ 92 - unsigned int fti_qic_std; 93 - /* is tape running? */ 94 - volatile enum runner_status_enum fti_runner_status; 95 - /* is tape reading/writing/verifying/formatting/deleting */ 96 - buffer_state_enum fti_state; 97 - /* flags fatal hardware error */ 98 - unsigned int fti_failure:1; 99 - /* history record */ 100 - history_record fti_history; 101 - } ftape_info; 102 - 103 - /* vendor information */ 104 - #define ft_drive_type ftape_status.fti_drive_type 105 - /* data rates */ 106 - #define ft_data_rate ftape_status.fti_used_data_rate 107 - #define ft_drive_max_rate ftape_status.fti_drive_max_rate 108 - #define ft_fdc_max_rate ftape_status.fti_fdc_max_rate 109 - /* drive selection, either FTAPE_SEL_A/B/C/D */ 110 - #define ft_drive_sel ftape_status.fti_drive_sel 111 - /* flags set after decode the drive and tape status */ 112 - #define ft_formatted ftape_status.fti_formatted 113 - #define ft_no_tape ftape_status.fti_no_tape 114 - #define ft_write_protected ftape_status.fti_write_protected 115 - #define ft_new_tape ftape_status.fti_new_tape 116 - /* values of last queried drive/tape status and error */ 117 - #define ft_last_error ftape_status.fti_last_error 118 - #define ft_last_status ftape_status.fti_last_status 119 - /* cartridge geometry */ 120 - #define ft_tracks_per_tape ftape_status.fti_tracks_per_tape 121 - #define ft_segments_per_track ftape_status.fti_segments_per_track 122 - /* the format code as stored in the header segment */ 123 - #define ft_format_code ftape_status.fti_format_code 124 - /* the qic status as returned by report drive configuration */ 125 - #define ft_qic_std ftape_status.fti_qic_std 126 - #define ft_used_header_segment ftape_status.fti_used_header_segment 127 - #define ft_header_segment_1 ftape_status.fti_header_segment_1 128 - #define ft_header_segment_2 ftape_status.fti_header_segment_2 129 - #define ft_first_data_segment ftape_status.fti_first_data_segment 130 - #define ft_last_data_segment ftape_status.fti_last_data_segment 131 - /* is tape running? */ 132 - #define ft_runner_status ftape_status.fti_runner_status 133 - /* is tape reading/writing/verifying/formatting/deleting */ 134 - #define ft_driver_state ftape_status.fti_state 135 - /* flags fatal hardware error */ 136 - #define ft_failure ftape_status.fti_failure 137 - /* history record */ 138 - #define ft_history ftape_status.fti_history 139 - 140 - /* 141 - * ftape-ctl.c defined global vars. 142 - */ 143 - extern ftape_info ftape_status; 144 - extern int ftape_segments_per_head; 145 - extern int ftape_segments_per_cylinder; 146 - extern int ftape_init_drive_needed; 147 - 148 - /* 149 - * ftape-ctl.c defined global functions. 150 - */ 151 - extern int ftape_mmap(struct vm_area_struct *vma); 152 - extern int ftape_enable(int drive_selection); 153 - extern void ftape_disable(void); 154 - extern int ftape_seek_to_bot(void); 155 - extern int ftape_seek_to_eot(void); 156 - extern int ftape_abort_operation(void); 157 - extern void ftape_calc_timeouts(unsigned int qic_std, 158 - unsigned int data_rate, 159 - unsigned int tape_len); 160 - extern int ftape_calibrate_data_rate(unsigned int qic_std); 161 - extern const ftape_info *ftape_get_status(void); 162 - #endif
-853
drivers/char/ftape/lowlevel/ftape-ecc.c
··· 1 - /* 2 - * 3 - * Copyright (c) 1993 Ning and David Mosberger. 4 - 5 - This is based on code originally written by Bas Laarhoven (bas@vimec.nl) 6 - and David L. Brown, Jr., and incorporates improvements suggested by 7 - Kai Harrekilde-Petersen. 8 - 9 - This program is free software; you can redistribute it and/or 10 - modify it under the terms of the GNU General Public License as 11 - published by the Free Software Foundation; either version 2, or (at 12 - your option) any later version. 13 - 14 - This program is distributed in the hope that it will be useful, but 15 - WITHOUT ANY WARRANTY; without even the implied warranty of 16 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 - General Public License for more details. 18 - 19 - You should have received a copy of the GNU General Public License 20 - along with this program; see the file COPYING. If not, write to 21 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 22 - USA. 23 - 24 - * 25 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ecc.c,v $ 26 - * $Revision: 1.3 $ 27 - * $Date: 1997/10/05 19:18:10 $ 28 - * 29 - * This file contains the Reed-Solomon error correction code 30 - * for the QIC-40/80 floppy-tape driver for Linux. 31 - */ 32 - 33 - #include <linux/ftape.h> 34 - 35 - #include "../lowlevel/ftape-tracing.h" 36 - #include "../lowlevel/ftape-ecc.h" 37 - 38 - /* Machines that are big-endian should define macro BIG_ENDIAN. 39 - * Unfortunately, there doesn't appear to be a standard include file 40 - * that works for all OSs. 41 - */ 42 - 43 - #if defined(__sparc__) || defined(__hppa) 44 - #define BIG_ENDIAN 45 - #endif /* __sparc__ || __hppa */ 46 - 47 - #if defined(__mips__) 48 - #error Find a smart way to determine the Endianness of the MIPS CPU 49 - #endif 50 - 51 - /* Notice: to minimize the potential for confusion, we use r to 52 - * denote the independent variable of the polynomials in the 53 - * Galois Field GF(2^8). We reserve x for polynomials that 54 - * that have coefficients in GF(2^8). 55 - * 56 - * The Galois Field in which coefficient arithmetic is performed are 57 - * the polynomials over Z_2 (i.e., 0 and 1) modulo the irreducible 58 - * polynomial f(r), where f(r)=r^8 + r^7 + r^2 + r + 1. A polynomial 59 - * is represented as a byte with the MSB as the coefficient of r^7 and 60 - * the LSB as the coefficient of r^0. For example, the binary 61 - * representation of f(x) is 0x187 (of course, this doesn't fit into 8 62 - * bits). In this field, the polynomial r is a primitive element. 63 - * That is, r^i with i in 0,...,255 enumerates all elements in the 64 - * field. 65 - * 66 - * The generator polynomial for the QIC-80 ECC is 67 - * 68 - * g(x) = x^3 + r^105*x^2 + r^105*x + 1 69 - * 70 - * which can be factored into: 71 - * 72 - * g(x) = (x-r^-1)(x-r^0)(x-r^1) 73 - * 74 - * the byte representation of the coefficients are: 75 - * 76 - * r^105 = 0xc0 77 - * r^-1 = 0xc3 78 - * r^0 = 0x01 79 - * r^1 = 0x02 80 - * 81 - * Notice that r^-1 = r^254 as exponent arithmetic is performed 82 - * modulo 2^8-1 = 255. 83 - * 84 - * For more information on Galois Fields and Reed-Solomon codes, refer 85 - * to any good book. I found _An Introduction to Error Correcting 86 - * Codes with Applications_ by S. A. Vanstone and P. C. van Oorschot 87 - * to be a good introduction into the former. _CODING THEORY: The 88 - * Essentials_ I found very useful for its concise description of 89 - * Reed-Solomon encoding/decoding. 90 - * 91 - */ 92 - 93 - typedef __u8 Matrix[3][3]; 94 - 95 - /* 96 - * gfpow[] is defined such that gfpow[i] returns r^i if 97 - * i is in the range [0..255]. 98 - */ 99 - static const __u8 gfpow[] = 100 - { 101 - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 102 - 0x87, 0x89, 0x95, 0xad, 0xdd, 0x3d, 0x7a, 0xf4, 103 - 0x6f, 0xde, 0x3b, 0x76, 0xec, 0x5f, 0xbe, 0xfb, 104 - 0x71, 0xe2, 0x43, 0x86, 0x8b, 0x91, 0xa5, 0xcd, 105 - 0x1d, 0x3a, 0x74, 0xe8, 0x57, 0xae, 0xdb, 0x31, 106 - 0x62, 0xc4, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0x67, 107 - 0xce, 0x1b, 0x36, 0x6c, 0xd8, 0x37, 0x6e, 0xdc, 108 - 0x3f, 0x7e, 0xfc, 0x7f, 0xfe, 0x7b, 0xf6, 0x6b, 109 - 0xd6, 0x2b, 0x56, 0xac, 0xdf, 0x39, 0x72, 0xe4, 110 - 0x4f, 0x9e, 0xbb, 0xf1, 0x65, 0xca, 0x13, 0x26, 111 - 0x4c, 0x98, 0xb7, 0xe9, 0x55, 0xaa, 0xd3, 0x21, 112 - 0x42, 0x84, 0x8f, 0x99, 0xb5, 0xed, 0x5d, 0xba, 113 - 0xf3, 0x61, 0xc2, 0x03, 0x06, 0x0c, 0x18, 0x30, 114 - 0x60, 0xc0, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 115 - 0x47, 0x8e, 0x9b, 0xb1, 0xe5, 0x4d, 0x9a, 0xb3, 116 - 0xe1, 0x45, 0x8a, 0x93, 0xa1, 0xc5, 0x0d, 0x1a, 117 - 0x34, 0x68, 0xd0, 0x27, 0x4e, 0x9c, 0xbf, 0xf9, 118 - 0x75, 0xea, 0x53, 0xa6, 0xcb, 0x11, 0x22, 0x44, 119 - 0x88, 0x97, 0xa9, 0xd5, 0x2d, 0x5a, 0xb4, 0xef, 120 - 0x59, 0xb2, 0xe3, 0x41, 0x82, 0x83, 0x81, 0x85, 121 - 0x8d, 0x9d, 0xbd, 0xfd, 0x7d, 0xfa, 0x73, 0xe6, 122 - 0x4b, 0x96, 0xab, 0xd1, 0x25, 0x4a, 0x94, 0xaf, 123 - 0xd9, 0x35, 0x6a, 0xd4, 0x2f, 0x5e, 0xbc, 0xff, 124 - 0x79, 0xf2, 0x63, 0xc6, 0x0b, 0x16, 0x2c, 0x58, 125 - 0xb0, 0xe7, 0x49, 0x92, 0xa3, 0xc1, 0x05, 0x0a, 126 - 0x14, 0x28, 0x50, 0xa0, 0xc7, 0x09, 0x12, 0x24, 127 - 0x48, 0x90, 0xa7, 0xc9, 0x15, 0x2a, 0x54, 0xa8, 128 - 0xd7, 0x29, 0x52, 0xa4, 0xcf, 0x19, 0x32, 0x64, 129 - 0xc8, 0x17, 0x2e, 0x5c, 0xb8, 0xf7, 0x69, 0xd2, 130 - 0x23, 0x46, 0x8c, 0x9f, 0xb9, 0xf5, 0x6d, 0xda, 131 - 0x33, 0x66, 0xcc, 0x1f, 0x3e, 0x7c, 0xf8, 0x77, 132 - 0xee, 0x5b, 0xb6, 0xeb, 0x51, 0xa2, 0xc3, 0x01 133 - }; 134 - 135 - /* 136 - * This is a log table. That is, gflog[r^i] returns i (modulo f(r)). 137 - * gflog[0] is undefined and the first element is therefore not valid. 138 - */ 139 - static const __u8 gflog[256] = 140 - { 141 - 0xff, 0x00, 0x01, 0x63, 0x02, 0xc6, 0x64, 0x6a, 142 - 0x03, 0xcd, 0xc7, 0xbc, 0x65, 0x7e, 0x6b, 0x2a, 143 - 0x04, 0x8d, 0xce, 0x4e, 0xc8, 0xd4, 0xbd, 0xe1, 144 - 0x66, 0xdd, 0x7f, 0x31, 0x6c, 0x20, 0x2b, 0xf3, 145 - 0x05, 0x57, 0x8e, 0xe8, 0xcf, 0xac, 0x4f, 0x83, 146 - 0xc9, 0xd9, 0xd5, 0x41, 0xbe, 0x94, 0xe2, 0xb4, 147 - 0x67, 0x27, 0xde, 0xf0, 0x80, 0xb1, 0x32, 0x35, 148 - 0x6d, 0x45, 0x21, 0x12, 0x2c, 0x0d, 0xf4, 0x38, 149 - 0x06, 0x9b, 0x58, 0x1a, 0x8f, 0x79, 0xe9, 0x70, 150 - 0xd0, 0xc2, 0xad, 0xa8, 0x50, 0x75, 0x84, 0x48, 151 - 0xca, 0xfc, 0xda, 0x8a, 0xd6, 0x54, 0x42, 0x24, 152 - 0xbf, 0x98, 0x95, 0xf9, 0xe3, 0x5e, 0xb5, 0x15, 153 - 0x68, 0x61, 0x28, 0xba, 0xdf, 0x4c, 0xf1, 0x2f, 154 - 0x81, 0xe6, 0xb2, 0x3f, 0x33, 0xee, 0x36, 0x10, 155 - 0x6e, 0x18, 0x46, 0xa6, 0x22, 0x88, 0x13, 0xf7, 156 - 0x2d, 0xb8, 0x0e, 0x3d, 0xf5, 0xa4, 0x39, 0x3b, 157 - 0x07, 0x9e, 0x9c, 0x9d, 0x59, 0x9f, 0x1b, 0x08, 158 - 0x90, 0x09, 0x7a, 0x1c, 0xea, 0xa0, 0x71, 0x5a, 159 - 0xd1, 0x1d, 0xc3, 0x7b, 0xae, 0x0a, 0xa9, 0x91, 160 - 0x51, 0x5b, 0x76, 0x72, 0x85, 0xa1, 0x49, 0xeb, 161 - 0xcb, 0x7c, 0xfd, 0xc4, 0xdb, 0x1e, 0x8b, 0xd2, 162 - 0xd7, 0x92, 0x55, 0xaa, 0x43, 0x0b, 0x25, 0xaf, 163 - 0xc0, 0x73, 0x99, 0x77, 0x96, 0x5c, 0xfa, 0x52, 164 - 0xe4, 0xec, 0x5f, 0x4a, 0xb6, 0xa2, 0x16, 0x86, 165 - 0x69, 0xc5, 0x62, 0xfe, 0x29, 0x7d, 0xbb, 0xcc, 166 - 0xe0, 0xd3, 0x4d, 0x8c, 0xf2, 0x1f, 0x30, 0xdc, 167 - 0x82, 0xab, 0xe7, 0x56, 0xb3, 0x93, 0x40, 0xd8, 168 - 0x34, 0xb0, 0xef, 0x26, 0x37, 0x0c, 0x11, 0x44, 169 - 0x6f, 0x78, 0x19, 0x9a, 0x47, 0x74, 0xa7, 0xc1, 170 - 0x23, 0x53, 0x89, 0xfb, 0x14, 0x5d, 0xf8, 0x97, 171 - 0x2e, 0x4b, 0xb9, 0x60, 0x0f, 0xed, 0x3e, 0xe5, 172 - 0xf6, 0x87, 0xa5, 0x17, 0x3a, 0xa3, 0x3c, 0xb7 173 - }; 174 - 175 - /* This is a multiplication table for the factor 0xc0 (i.e., r^105 (mod f(r)). 176 - * gfmul_c0[f] returns r^105 * f(r) (modulo f(r)). 177 - */ 178 - static const __u8 gfmul_c0[256] = 179 - { 180 - 0x00, 0xc0, 0x07, 0xc7, 0x0e, 0xce, 0x09, 0xc9, 181 - 0x1c, 0xdc, 0x1b, 0xdb, 0x12, 0xd2, 0x15, 0xd5, 182 - 0x38, 0xf8, 0x3f, 0xff, 0x36, 0xf6, 0x31, 0xf1, 183 - 0x24, 0xe4, 0x23, 0xe3, 0x2a, 0xea, 0x2d, 0xed, 184 - 0x70, 0xb0, 0x77, 0xb7, 0x7e, 0xbe, 0x79, 0xb9, 185 - 0x6c, 0xac, 0x6b, 0xab, 0x62, 0xa2, 0x65, 0xa5, 186 - 0x48, 0x88, 0x4f, 0x8f, 0x46, 0x86, 0x41, 0x81, 187 - 0x54, 0x94, 0x53, 0x93, 0x5a, 0x9a, 0x5d, 0x9d, 188 - 0xe0, 0x20, 0xe7, 0x27, 0xee, 0x2e, 0xe9, 0x29, 189 - 0xfc, 0x3c, 0xfb, 0x3b, 0xf2, 0x32, 0xf5, 0x35, 190 - 0xd8, 0x18, 0xdf, 0x1f, 0xd6, 0x16, 0xd1, 0x11, 191 - 0xc4, 0x04, 0xc3, 0x03, 0xca, 0x0a, 0xcd, 0x0d, 192 - 0x90, 0x50, 0x97, 0x57, 0x9e, 0x5e, 0x99, 0x59, 193 - 0x8c, 0x4c, 0x8b, 0x4b, 0x82, 0x42, 0x85, 0x45, 194 - 0xa8, 0x68, 0xaf, 0x6f, 0xa6, 0x66, 0xa1, 0x61, 195 - 0xb4, 0x74, 0xb3, 0x73, 0xba, 0x7a, 0xbd, 0x7d, 196 - 0x47, 0x87, 0x40, 0x80, 0x49, 0x89, 0x4e, 0x8e, 197 - 0x5b, 0x9b, 0x5c, 0x9c, 0x55, 0x95, 0x52, 0x92, 198 - 0x7f, 0xbf, 0x78, 0xb8, 0x71, 0xb1, 0x76, 0xb6, 199 - 0x63, 0xa3, 0x64, 0xa4, 0x6d, 0xad, 0x6a, 0xaa, 200 - 0x37, 0xf7, 0x30, 0xf0, 0x39, 0xf9, 0x3e, 0xfe, 201 - 0x2b, 0xeb, 0x2c, 0xec, 0x25, 0xe5, 0x22, 0xe2, 202 - 0x0f, 0xcf, 0x08, 0xc8, 0x01, 0xc1, 0x06, 0xc6, 203 - 0x13, 0xd3, 0x14, 0xd4, 0x1d, 0xdd, 0x1a, 0xda, 204 - 0xa7, 0x67, 0xa0, 0x60, 0xa9, 0x69, 0xae, 0x6e, 205 - 0xbb, 0x7b, 0xbc, 0x7c, 0xb5, 0x75, 0xb2, 0x72, 206 - 0x9f, 0x5f, 0x98, 0x58, 0x91, 0x51, 0x96, 0x56, 207 - 0x83, 0x43, 0x84, 0x44, 0x8d, 0x4d, 0x8a, 0x4a, 208 - 0xd7, 0x17, 0xd0, 0x10, 0xd9, 0x19, 0xde, 0x1e, 209 - 0xcb, 0x0b, 0xcc, 0x0c, 0xc5, 0x05, 0xc2, 0x02, 210 - 0xef, 0x2f, 0xe8, 0x28, 0xe1, 0x21, 0xe6, 0x26, 211 - 0xf3, 0x33, 0xf4, 0x34, 0xfd, 0x3d, 0xfa, 0x3a 212 - }; 213 - 214 - 215 - /* Returns V modulo 255 provided V is in the range -255,-254,...,509. 216 - */ 217 - static inline __u8 mod255(int v) 218 - { 219 - if (v > 0) { 220 - if (v < 255) { 221 - return v; 222 - } else { 223 - return v - 255; 224 - } 225 - } else { 226 - return v + 255; 227 - } 228 - } 229 - 230 - 231 - /* Add two numbers in the field. Addition in this field is equivalent 232 - * to a bit-wise exclusive OR operation---subtraction is therefore 233 - * identical to addition. 234 - */ 235 - static inline __u8 gfadd(__u8 a, __u8 b) 236 - { 237 - return a ^ b; 238 - } 239 - 240 - 241 - /* Add two vectors of numbers in the field. Each byte in A and B gets 242 - * added individually. 243 - */ 244 - static inline unsigned long gfadd_long(unsigned long a, unsigned long b) 245 - { 246 - return a ^ b; 247 - } 248 - 249 - 250 - /* Multiply two numbers in the field: 251 - */ 252 - static inline __u8 gfmul(__u8 a, __u8 b) 253 - { 254 - if (a && b) { 255 - return gfpow[mod255(gflog[a] + gflog[b])]; 256 - } else { 257 - return 0; 258 - } 259 - } 260 - 261 - 262 - /* Just like gfmul, except we have already looked up the log of the 263 - * second number. 264 - */ 265 - static inline __u8 gfmul_exp(__u8 a, int b) 266 - { 267 - if (a) { 268 - return gfpow[mod255(gflog[a] + b)]; 269 - } else { 270 - return 0; 271 - } 272 - } 273 - 274 - 275 - /* Just like gfmul_exp, except that A is a vector of numbers. That 276 - * is, each byte in A gets multiplied by gfpow[mod255(B)]. 277 - */ 278 - static inline unsigned long gfmul_exp_long(unsigned long a, int b) 279 - { 280 - __u8 t; 281 - 282 - if (sizeof(long) == 4) { 283 - return ( 284 - ((t = (__u32)a >> 24 & 0xff) ? 285 - (((__u32) gfpow[mod255(gflog[t] + b)]) << 24) : 0) | 286 - ((t = (__u32)a >> 16 & 0xff) ? 287 - (((__u32) gfpow[mod255(gflog[t] + b)]) << 16) : 0) | 288 - ((t = (__u32)a >> 8 & 0xff) ? 289 - (((__u32) gfpow[mod255(gflog[t] + b)]) << 8) : 0) | 290 - ((t = (__u32)a >> 0 & 0xff) ? 291 - (((__u32) gfpow[mod255(gflog[t] + b)]) << 0) : 0)); 292 - } else if (sizeof(long) == 8) { 293 - return ( 294 - ((t = (__u64)a >> 56 & 0xff) ? 295 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 56) : 0) | 296 - ((t = (__u64)a >> 48 & 0xff) ? 297 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 48) : 0) | 298 - ((t = (__u64)a >> 40 & 0xff) ? 299 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 40) : 0) | 300 - ((t = (__u64)a >> 32 & 0xff) ? 301 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 32) : 0) | 302 - ((t = (__u64)a >> 24 & 0xff) ? 303 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 24) : 0) | 304 - ((t = (__u64)a >> 16 & 0xff) ? 305 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 16) : 0) | 306 - ((t = (__u64)a >> 8 & 0xff) ? 307 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 8) : 0) | 308 - ((t = (__u64)a >> 0 & 0xff) ? 309 - (((__u64) gfpow[mod255(gflog[t] + b)]) << 0) : 0)); 310 - } else { 311 - TRACE_FUN(ft_t_any); 312 - TRACE_ABORT(-1, ft_t_err, "Error: size of long is %d bytes", 313 - (int)sizeof(long)); 314 - } 315 - } 316 - 317 - 318 - /* Divide two numbers in the field. Returns a/b (modulo f(x)). 319 - */ 320 - static inline __u8 gfdiv(__u8 a, __u8 b) 321 - { 322 - if (!b) { 323 - TRACE_FUN(ft_t_any); 324 - TRACE_ABORT(0xff, ft_t_bug, "Error: division by zero"); 325 - } else if (a == 0) { 326 - return 0; 327 - } else { 328 - return gfpow[mod255(gflog[a] - gflog[b])]; 329 - } 330 - } 331 - 332 - 333 - /* The following functions return the inverse of the matrix of the 334 - * linear system that needs to be solved to determine the error 335 - * magnitudes. The first deals with matrices of rank 3, while the 336 - * second deals with matrices of rank 2. The error indices are passed 337 - * in arguments L0,..,L2 (0=first sector, 31=last sector). The error 338 - * indices must be sorted in ascending order, i.e., L0<L1<L2. 339 - * 340 - * The linear system that needs to be solved for the error magnitudes 341 - * is A * b = s, where s is the known vector of syndromes, b is the 342 - * vector of error magnitudes and A in the ORDER=3 case: 343 - * 344 - * A_3 = {{1/r^L[0], 1/r^L[1], 1/r^L[2]}, 345 - * { 1, 1, 1}, 346 - * { r^L[0], r^L[1], r^L[2]}} 347 - */ 348 - static inline int gfinv3(__u8 l0, 349 - __u8 l1, 350 - __u8 l2, 351 - Matrix Ainv) 352 - { 353 - __u8 det; 354 - __u8 t20, t10, t21, t12, t01, t02; 355 - int log_det; 356 - 357 - /* compute some intermediate results: */ 358 - t20 = gfpow[l2 - l0]; /* t20 = r^l2/r^l0 */ 359 - t10 = gfpow[l1 - l0]; /* t10 = r^l1/r^l0 */ 360 - t21 = gfpow[l2 - l1]; /* t21 = r^l2/r^l1 */ 361 - t12 = gfpow[l1 - l2 + 255]; /* t12 = r^l1/r^l2 */ 362 - t01 = gfpow[l0 - l1 + 255]; /* t01 = r^l0/r^l1 */ 363 - t02 = gfpow[l0 - l2 + 255]; /* t02 = r^l0/r^l2 */ 364 - /* Calculate the determinant of matrix A_3^-1 (sometimes 365 - * called the Vandermonde determinant): 366 - */ 367 - det = gfadd(t20, gfadd(t10, gfadd(t21, gfadd(t12, gfadd(t01, t02))))); 368 - if (!det) { 369 - TRACE_FUN(ft_t_any); 370 - TRACE_ABORT(0, ft_t_err, 371 - "Inversion failed (3 CRC errors, >0 CRC failures)"); 372 - } 373 - log_det = 255 - gflog[det]; 374 - 375 - /* Now, calculate all of the coefficients: 376 - */ 377 - Ainv[0][0]= gfmul_exp(gfadd(gfpow[l1], gfpow[l2]), log_det); 378 - Ainv[0][1]= gfmul_exp(gfadd(t21, t12), log_det); 379 - Ainv[0][2]= gfmul_exp(gfadd(gfpow[255 - l1], gfpow[255 - l2]),log_det); 380 - 381 - Ainv[1][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l2]), log_det); 382 - Ainv[1][1]= gfmul_exp(gfadd(t20, t02), log_det); 383 - Ainv[1][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l2]),log_det); 384 - 385 - Ainv[2][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l1]), log_det); 386 - Ainv[2][1]= gfmul_exp(gfadd(t10, t01), log_det); 387 - Ainv[2][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l1]),log_det); 388 - 389 - return 1; 390 - } 391 - 392 - 393 - static inline int gfinv2(__u8 l0, __u8 l1, Matrix Ainv) 394 - { 395 - __u8 det; 396 - __u8 t1, t2; 397 - int log_det; 398 - 399 - t1 = gfpow[255 - l0]; 400 - t2 = gfpow[255 - l1]; 401 - det = gfadd(t1, t2); 402 - if (!det) { 403 - TRACE_FUN(ft_t_any); 404 - TRACE_ABORT(0, ft_t_err, 405 - "Inversion failed (2 CRC errors, >0 CRC failures)"); 406 - } 407 - log_det = 255 - gflog[det]; 408 - 409 - /* Now, calculate all of the coefficients: 410 - */ 411 - Ainv[0][0] = Ainv[1][0] = gfpow[log_det]; 412 - 413 - Ainv[0][1] = gfmul_exp(t2, log_det); 414 - Ainv[1][1] = gfmul_exp(t1, log_det); 415 - 416 - return 1; 417 - } 418 - 419 - 420 - /* Multiply matrix A by vector S and return result in vector B. M is 421 - * assumed to be of order NxN, S and B of order Nx1. 422 - */ 423 - static inline void gfmat_mul(int n, Matrix A, 424 - __u8 *s, __u8 *b) 425 - { 426 - int i, j; 427 - __u8 dot_prod; 428 - 429 - for (i = 0; i < n; ++i) { 430 - dot_prod = 0; 431 - for (j = 0; j < n; ++j) { 432 - dot_prod = gfadd(dot_prod, gfmul(A[i][j], s[j])); 433 - } 434 - b[i] = dot_prod; 435 - } 436 - } 437 - 438 - 439 - 440 - /* The Reed Solomon ECC codes are computed over the N-th byte of each 441 - * block, where N=SECTOR_SIZE. There are up to 29 blocks of data, and 442 - * 3 blocks of ECC. The blocks are stored contiguously in memory. A 443 - * segment, consequently, is assumed to have at least 4 blocks: one or 444 - * more data blocks plus three ECC blocks. 445 - * 446 - * Notice: In QIC-80 speak, a CRC error is a sector with an incorrect 447 - * CRC. A CRC failure is a sector with incorrect data, but 448 - * a valid CRC. In the error control literature, the former 449 - * is usually called "erasure", the latter "error." 450 - */ 451 - /* Compute the parity bytes for C columns of data, where C is the 452 - * number of bytes that fit into a long integer. We use a linear 453 - * feed-back register to do this. The parity bytes P[0], P[STRIDE], 454 - * P[2*STRIDE] are computed such that: 455 - * 456 - * x^k * p(x) + m(x) = 0 (modulo g(x)) 457 - * 458 - * where k = NBLOCKS, 459 - * p(x) = P[0] + P[STRIDE]*x + P[2*STRIDE]*x^2, and 460 - * m(x) = sum_{i=0}^k m_i*x^i. 461 - * m_i = DATA[i*SECTOR_SIZE] 462 - */ 463 - static inline void set_parity(unsigned long *data, 464 - int nblocks, 465 - unsigned long *p, 466 - int stride) 467 - { 468 - unsigned long p0, p1, p2, t1, t2, *end; 469 - 470 - end = data + nblocks * (FT_SECTOR_SIZE / sizeof(long)); 471 - p0 = p1 = p2 = 0; 472 - while (data < end) { 473 - /* The new parity bytes p0_i, p1_i, p2_i are computed 474 - * from the old values p0_{i-1}, p1_{i-1}, p2_{i-1} 475 - * recursively as: 476 - * 477 - * p0_i = p1_{i-1} + r^105 * (m_{i-1} - p0_{i-1}) 478 - * p1_i = p2_{i-1} + r^105 * (m_{i-1} - p0_{i-1}) 479 - * p2_i = (m_{i-1} - p0_{i-1}) 480 - * 481 - * With the initial condition: p0_0 = p1_0 = p2_0 = 0. 482 - */ 483 - t1 = gfadd_long(*data, p0); 484 - /* 485 - * Multiply each byte in t1 by 0xc0: 486 - */ 487 - if (sizeof(long) == 4) { 488 - t2= (((__u32) gfmul_c0[(__u32)t1 >> 24 & 0xff]) << 24 | 489 - ((__u32) gfmul_c0[(__u32)t1 >> 16 & 0xff]) << 16 | 490 - ((__u32) gfmul_c0[(__u32)t1 >> 8 & 0xff]) << 8 | 491 - ((__u32) gfmul_c0[(__u32)t1 >> 0 & 0xff]) << 0); 492 - } else if (sizeof(long) == 8) { 493 - t2= (((__u64) gfmul_c0[(__u64)t1 >> 56 & 0xff]) << 56 | 494 - ((__u64) gfmul_c0[(__u64)t1 >> 48 & 0xff]) << 48 | 495 - ((__u64) gfmul_c0[(__u64)t1 >> 40 & 0xff]) << 40 | 496 - ((__u64) gfmul_c0[(__u64)t1 >> 32 & 0xff]) << 32 | 497 - ((__u64) gfmul_c0[(__u64)t1 >> 24 & 0xff]) << 24 | 498 - ((__u64) gfmul_c0[(__u64)t1 >> 16 & 0xff]) << 16 | 499 - ((__u64) gfmul_c0[(__u64)t1 >> 8 & 0xff]) << 8 | 500 - ((__u64) gfmul_c0[(__u64)t1 >> 0 & 0xff]) << 0); 501 - } else { 502 - TRACE_FUN(ft_t_any); 503 - TRACE(ft_t_err, "Error: long is of size %d", 504 - (int) sizeof(long)); 505 - TRACE_EXIT; 506 - } 507 - p0 = gfadd_long(t2, p1); 508 - p1 = gfadd_long(t2, p2); 509 - p2 = t1; 510 - data += FT_SECTOR_SIZE / sizeof(long); 511 - } 512 - *p = p0; 513 - p += stride; 514 - *p = p1; 515 - p += stride; 516 - *p = p2; 517 - return; 518 - } 519 - 520 - 521 - /* Compute the 3 syndrome values. DATA should point to the first byte 522 - * of the column for which the syndromes are desired. The syndromes 523 - * are computed over the first NBLOCKS of rows. The three bytes will 524 - * be placed in S[0], S[1], and S[2]. 525 - * 526 - * S[i] is the value of the "message" polynomial m(x) evaluated at the 527 - * i-th root of the generator polynomial g(x). 528 - * 529 - * As g(x)=(x-r^-1)(x-1)(x-r^1) we evaluate the message polynomial at 530 - * x=r^-1 to get S[0], at x=r^0=1 to get S[1], and at x=r to get S[2]. 531 - * This could be done directly and efficiently via the Horner scheme. 532 - * However, it would require multiplication tables for the factors 533 - * r^-1 (0xc3) and r (0x02). The following scheme does not require 534 - * any multiplication tables beyond what's needed for set_parity() 535 - * anyway and is slightly faster if there are no errors and slightly 536 - * slower if there are errors. The latter is hopefully the infrequent 537 - * case. 538 - * 539 - * To understand the alternative algorithm, notice that set_parity(m, 540 - * k, p) computes parity bytes such that: 541 - * 542 - * x^k * p(x) = m(x) (modulo g(x)). 543 - * 544 - * That is, to evaluate m(r^m), where r^m is a root of g(x), we can 545 - * simply evaluate (r^m)^k*p(r^m). Also, notice that p is 0 if and 546 - * only if s is zero. That is, if all parity bytes are 0, we know 547 - * there is no error in the data and consequently there is no need to 548 - * compute s(x) at all! In all other cases, we compute s(x) from p(x) 549 - * by evaluating (r^m)^k*p(r^m) for m=-1, m=0, and m=1. The p(x) 550 - * polynomial is evaluated via the Horner scheme. 551 - */ 552 - static int compute_syndromes(unsigned long *data, int nblocks, unsigned long *s) 553 - { 554 - unsigned long p[3]; 555 - 556 - set_parity(data, nblocks, p, 1); 557 - if (p[0] | p[1] | p[2]) { 558 - /* Some of the checked columns do not have a zero 559 - * syndrome. For simplicity, we compute the syndromes 560 - * for all columns that we have computed the 561 - * remainders for. 562 - */ 563 - s[0] = gfmul_exp_long( 564 - gfadd_long(p[0], 565 - gfmul_exp_long( 566 - gfadd_long(p[1], 567 - gfmul_exp_long(p[2], -1)), 568 - -1)), 569 - -nblocks); 570 - s[1] = gfadd_long(gfadd_long(p[2], p[1]), p[0]); 571 - s[2] = gfmul_exp_long( 572 - gfadd_long(p[0], 573 - gfmul_exp_long( 574 - gfadd_long(p[1], 575 - gfmul_exp_long(p[2], 1)), 576 - 1)), 577 - nblocks); 578 - return 0; 579 - } else { 580 - return 1; 581 - } 582 - } 583 - 584 - 585 - /* Correct the block in the column pointed to by DATA. There are NBAD 586 - * CRC errors and their indices are in BAD_LOC[0], up to 587 - * BAD_LOC[NBAD-1]. If NBAD>1, Ainv holds the inverse of the matrix 588 - * of the linear system that needs to be solved to determine the error 589 - * magnitudes. S[0], S[1], and S[2] are the syndrome values. If row 590 - * j gets corrected, then bit j will be set in CORRECTION_MAP. 591 - */ 592 - static inline int correct_block(__u8 *data, int nblocks, 593 - int nbad, int *bad_loc, Matrix Ainv, 594 - __u8 *s, 595 - SectorMap * correction_map) 596 - { 597 - int ncorrected = 0; 598 - int i; 599 - __u8 t1, t2; 600 - __u8 c0, c1, c2; /* check bytes */ 601 - __u8 error_mag[3], log_error_mag; 602 - __u8 *dp, l, e; 603 - TRACE_FUN(ft_t_any); 604 - 605 - switch (nbad) { 606 - case 0: 607 - /* might have a CRC failure: */ 608 - if (s[0] == 0) { 609 - /* more than one error */ 610 - TRACE_ABORT(-1, ft_t_err, 611 - "ECC failed (0 CRC errors, >1 CRC failures)"); 612 - } 613 - t1 = gfdiv(s[1], s[0]); 614 - if ((bad_loc[nbad++] = gflog[t1]) >= nblocks) { 615 - TRACE(ft_t_err, 616 - "ECC failed (0 CRC errors, >1 CRC failures)"); 617 - TRACE_ABORT(-1, ft_t_err, 618 - "attempt to correct data at %d", bad_loc[0]); 619 - } 620 - error_mag[0] = s[1]; 621 - break; 622 - case 1: 623 - t1 = gfadd(gfmul_exp(s[1], bad_loc[0]), s[2]); 624 - t2 = gfadd(gfmul_exp(s[0], bad_loc[0]), s[1]); 625 - if (t1 == 0 && t2 == 0) { 626 - /* one erasure, no error: */ 627 - Ainv[0][0] = gfpow[bad_loc[0]]; 628 - } else if (t1 == 0 || t2 == 0) { 629 - /* one erasure and more than one error: */ 630 - TRACE_ABORT(-1, ft_t_err, 631 - "ECC failed (1 erasure, >1 error)"); 632 - } else { 633 - /* one erasure, one error: */ 634 - if ((bad_loc[nbad++] = gflog[gfdiv(t1, t2)]) 635 - >= nblocks) { 636 - TRACE(ft_t_err, "ECC failed " 637 - "(1 CRC errors, >1 CRC failures)"); 638 - TRACE_ABORT(-1, ft_t_err, 639 - "attempt to correct data at %d", 640 - bad_loc[1]); 641 - } 642 - if (!gfinv2(bad_loc[0], bad_loc[1], Ainv)) { 643 - /* inversion failed---must have more 644 - * than one error 645 - */ 646 - TRACE_EXIT -1; 647 - } 648 - } 649 - /* FALL THROUGH TO ERROR MAGNITUDE COMPUTATION: 650 - */ 651 - case 2: 652 - case 3: 653 - /* compute error magnitudes: */ 654 - gfmat_mul(nbad, Ainv, s, error_mag); 655 - break; 656 - 657 - default: 658 - TRACE_ABORT(-1, ft_t_err, 659 - "Internal Error: number of CRC errors > 3"); 660 - } 661 - 662 - /* Perform correction by adding ERROR_MAG[i] to the byte at 663 - * offset BAD_LOC[i]. Also add the value of the computed 664 - * error polynomial to the syndrome values. If the correction 665 - * was successful, the resulting check bytes should be zero 666 - * (i.e., the corrected data is a valid code word). 667 - */ 668 - c0 = s[0]; 669 - c1 = s[1]; 670 - c2 = s[2]; 671 - for (i = 0; i < nbad; ++i) { 672 - e = error_mag[i]; 673 - if (e) { 674 - /* correct the byte at offset L by magnitude E: */ 675 - l = bad_loc[i]; 676 - dp = &data[l * FT_SECTOR_SIZE]; 677 - *dp = gfadd(*dp, e); 678 - *correction_map |= 1 << l; 679 - ++ncorrected; 680 - 681 - log_error_mag = gflog[e]; 682 - c0 = gfadd(c0, gfpow[mod255(log_error_mag - l)]); 683 - c1 = gfadd(c1, e); 684 - c2 = gfadd(c2, gfpow[mod255(log_error_mag + l)]); 685 - } 686 - } 687 - if (c0 || c1 || c2) { 688 - TRACE_ABORT(-1, ft_t_err, 689 - "ECC self-check failed, too many errors"); 690 - } 691 - TRACE_EXIT ncorrected; 692 - } 693 - 694 - 695 - #if defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID) 696 - 697 - /* Perform a sanity check on the computed parity bytes: 698 - */ 699 - static int sanity_check(unsigned long *data, int nblocks) 700 - { 701 - TRACE_FUN(ft_t_any); 702 - unsigned long s[3]; 703 - 704 - if (!compute_syndromes(data, nblocks, s)) { 705 - TRACE_ABORT(0, ft_bug, 706 - "Internal Error: syndrome self-check failed"); 707 - } 708 - TRACE_EXIT 1; 709 - } 710 - 711 - #endif /* defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID) */ 712 - 713 - /* Compute the parity for an entire segment of data. 714 - */ 715 - int ftape_ecc_set_segment_parity(struct memory_segment *mseg) 716 - { 717 - int i; 718 - __u8 *parity_bytes; 719 - 720 - parity_bytes = &mseg->data[(mseg->blocks - 3) * FT_SECTOR_SIZE]; 721 - for (i = 0; i < FT_SECTOR_SIZE; i += sizeof(long)) { 722 - set_parity((unsigned long *) &mseg->data[i], mseg->blocks - 3, 723 - (unsigned long *) &parity_bytes[i], 724 - FT_SECTOR_SIZE / sizeof(long)); 725 - #ifdef ECC_PARANOID 726 - if (!sanity_check((unsigned long *) &mseg->data[i], 727 - mseg->blocks)) { 728 - return -1; 729 - } 730 - #endif /* ECC_PARANOID */ 731 - } 732 - return 0; 733 - } 734 - 735 - 736 - /* Checks and corrects (if possible) the segment MSEG. Returns one of 737 - * ECC_OK, ECC_CORRECTED, and ECC_FAILED. 738 - */ 739 - int ftape_ecc_correct_data(struct memory_segment *mseg) 740 - { 741 - int col, i, result; 742 - int ncorrected = 0; 743 - int nerasures = 0; /* # of erasures (CRC errors) */ 744 - int erasure_loc[3]; /* erasure locations */ 745 - unsigned long ss[3]; 746 - __u8 s[3]; 747 - Matrix Ainv; 748 - TRACE_FUN(ft_t_flow); 749 - 750 - mseg->corrected = 0; 751 - 752 - /* find first column that has non-zero syndromes: */ 753 - for (col = 0; col < FT_SECTOR_SIZE; col += sizeof(long)) { 754 - if (!compute_syndromes((unsigned long *) &mseg->data[col], 755 - mseg->blocks, ss)) { 756 - /* something is wrong---have to fix things */ 757 - break; 758 - } 759 - } 760 - if (col >= FT_SECTOR_SIZE) { 761 - /* all syndromes are ok, therefore nothing to correct */ 762 - TRACE_EXIT ECC_OK; 763 - } 764 - /* count the number of CRC errors if there were any: */ 765 - if (mseg->read_bad) { 766 - for (i = 0; i < mseg->blocks; i++) { 767 - if (BAD_CHECK(mseg->read_bad, i)) { 768 - if (nerasures >= 3) { 769 - /* this is too much for ECC */ 770 - TRACE_ABORT(ECC_FAILED, ft_t_err, 771 - "ECC failed (>3 CRC errors)"); 772 - } /* if */ 773 - erasure_loc[nerasures++] = i; 774 - } 775 - } 776 - } 777 - /* 778 - * If there are at least 2 CRC errors, determine inverse of matrix 779 - * of linear system to be solved: 780 - */ 781 - switch (nerasures) { 782 - case 2: 783 - if (!gfinv2(erasure_loc[0], erasure_loc[1], Ainv)) { 784 - TRACE_EXIT ECC_FAILED; 785 - } 786 - break; 787 - case 3: 788 - if (!gfinv3(erasure_loc[0], erasure_loc[1], 789 - erasure_loc[2], Ainv)) { 790 - TRACE_EXIT ECC_FAILED; 791 - } 792 - break; 793 - default: 794 - /* this is not an error condition... */ 795 - break; 796 - } 797 - 798 - do { 799 - for (i = 0; i < sizeof(long); ++i) { 800 - s[0] = ss[0]; 801 - s[1] = ss[1]; 802 - s[2] = ss[2]; 803 - if (s[0] | s[1] | s[2]) { 804 - #ifdef BIG_ENDIAN 805 - result = correct_block( 806 - &mseg->data[col + sizeof(long) - 1 - i], 807 - mseg->blocks, 808 - nerasures, 809 - erasure_loc, 810 - Ainv, 811 - s, 812 - &mseg->corrected); 813 - #else 814 - result = correct_block(&mseg->data[col + i], 815 - mseg->blocks, 816 - nerasures, 817 - erasure_loc, 818 - Ainv, 819 - s, 820 - &mseg->corrected); 821 - #endif 822 - if (result < 0) { 823 - TRACE_EXIT ECC_FAILED; 824 - } 825 - ncorrected += result; 826 - } 827 - ss[0] >>= 8; 828 - ss[1] >>= 8; 829 - ss[2] >>= 8; 830 - } 831 - 832 - #ifdef ECC_SANITY_CHECK 833 - if (!sanity_check((unsigned long *) &mseg->data[col], 834 - mseg->blocks)) { 835 - TRACE_EXIT ECC_FAILED; 836 - } 837 - #endif /* ECC_SANITY_CHECK */ 838 - 839 - /* find next column with non-zero syndromes: */ 840 - while ((col += sizeof(long)) < FT_SECTOR_SIZE) { 841 - if (!compute_syndromes((unsigned long *) 842 - &mseg->data[col], mseg->blocks, ss)) { 843 - /* something is wrong---have to fix things */ 844 - break; 845 - } 846 - } 847 - } while (col < FT_SECTOR_SIZE); 848 - if (ncorrected && nerasures == 0) { 849 - TRACE(ft_t_warn, "block contained error not caught by CRC"); 850 - } 851 - TRACE((ncorrected > 0) ? ft_t_noise : ft_t_any, "number of corrections: %d", ncorrected); 852 - TRACE_EXIT ncorrected ? ECC_CORRECTED : ECC_OK; 853 - }
-84
drivers/char/ftape/lowlevel/ftape-ecc.h
··· 1 - #ifndef _FTAPE_ECC_H_ 2 - #define _FTAPE_ECC_H_ 3 - 4 - /* 5 - * Copyright (C) 1993 Ning and David Mosberger. 6 - * Original: 7 - * Copyright (C) 1993 Bas Laarhoven. 8 - * Copyright (C) 1992 David L. Brown, Jr. 9 - 10 - This program is free software; you can redistribute it and/or 11 - modify it under the terms of the GNU General Public License as 12 - published by the Free Software Foundation; either version 2, or (at 13 - your option) any later version. 14 - 15 - This program is distributed in the hope that it will be useful, but 16 - WITHOUT ANY WARRANTY; without even the implied warranty of 17 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 - General Public License for more details. 19 - 20 - You should have received a copy of the GNU General Public License 21 - along with this program; see the file COPYING. If not, write to 22 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 23 - USA. 24 - 25 - * 26 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ecc.h,v $ 27 - * $Revision: 1.2 $ 28 - * $Date: 1997/10/05 19:18:11 $ 29 - * 30 - * This file contains the definitions for the 31 - * Reed-Solomon error correction code 32 - * for the QIC-40/80 tape streamer device driver. 33 - */ 34 - 35 - #include "../lowlevel/ftape-bsm.h" 36 - 37 - #define BAD_CLEAR(entry) ((entry)=0) 38 - #define BAD_SET(entry,sector) ((entry)|=(1<<(sector))) 39 - #define BAD_CHECK(entry,sector) ((entry)&(1<<(sector))) 40 - 41 - /* 42 - * Return values for ecc_correct_data: 43 - */ 44 - enum { 45 - ECC_OK, /* Data was correct. */ 46 - ECC_CORRECTED, /* Correctable error in data. */ 47 - ECC_FAILED, /* Could not correct data. */ 48 - }; 49 - 50 - /* 51 - * Representation of an in memory segment. MARKED_BAD lists the 52 - * sectors that were marked bad during formatting. If the N-th sector 53 - * in a segment is marked bad, bit 1<<N will be set in MARKED_BAD. 54 - * The sectors should be read in from the disk and packed, as if the 55 - * bad sectors were not there, and the segment just contained fewer 56 - * sectors. READ_SECTORS is a bitmap of errors encountered while 57 - * reading the data. These offsets are relative to the packed data. 58 - * BLOCKS is a count of the sectors not marked bad. This is just to 59 - * prevent having to count the zero bits in MARKED_BAD each time this 60 - * is needed. DATA is the actual sector packed data from (or to) the 61 - * tape. 62 - */ 63 - struct memory_segment { 64 - SectorMap marked_bad; 65 - SectorMap read_bad; 66 - int blocks; 67 - __u8 *data; 68 - SectorMap corrected; 69 - }; 70 - 71 - /* 72 - * ecc.c defined global variables: 73 - */ 74 - #ifdef TEST 75 - extern int ftape_ecc_tracing; 76 - #endif 77 - 78 - /* 79 - * ecc.c defined global functions: 80 - */ 81 - extern int ftape_ecc_correct_data(struct memory_segment *data); 82 - extern int ftape_ecc_set_segment_parity(struct memory_segment *data); 83 - 84 - #endif /* _FTAPE_ECC_H_ */
-344
drivers/char/ftape/lowlevel/ftape-format.c
··· 1 - /* 2 - * Copyright (C) 1997 Claus-Justus Heine. 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-format.c,v $ 20 - * $Revision: 1.2.4.1 $ 21 - * $Date: 1997/11/14 16:05:39 $ 22 - * 23 - * This file contains the code to support formatting of floppy 24 - * tape cartridges with the QIC-40/80/3010/3020 floppy-tape 25 - * driver "ftape" for Linux. 26 - */ 27 - 28 - #include <linux/string.h> 29 - #include <linux/errno.h> 30 - 31 - #include <linux/ftape.h> 32 - #include <linux/qic117.h> 33 - #include "../lowlevel/ftape-tracing.h" 34 - #include "../lowlevel/ftape-io.h" 35 - #include "../lowlevel/ftape-ctl.h" 36 - #include "../lowlevel/ftape-rw.h" 37 - #include "../lowlevel/ftape-ecc.h" 38 - #include "../lowlevel/ftape-bsm.h" 39 - #include "../lowlevel/ftape-format.h" 40 - 41 - #if defined(TESTING) 42 - #define FT_FMT_SEGS_PER_BUF 50 43 - #else 44 - #define FT_FMT_SEGS_PER_BUF (FT_BUFF_SIZE/(4*FT_SECTORS_PER_SEGMENT)) 45 - #endif 46 - 47 - static spinlock_t ftape_format_lock; 48 - 49 - /* 50 - * first segment of the new buffer 51 - */ 52 - static int switch_segment; 53 - 54 - /* 55 - * at most 256 segments fit into one 32 kb buffer. Even TR-1 cartridges have 56 - * more than this many segments per track, so better be careful. 57 - * 58 - * buffer_struct *buff: buffer to store the formatting coordinates in 59 - * int start: starting segment for this buffer. 60 - * int spt: segments per track 61 - * 62 - * Note: segment ids are relative to the start of the track here. 63 - */ 64 - static void setup_format_buffer(buffer_struct *buff, int start, int spt, 65 - __u8 gap3) 66 - { 67 - int to_do = spt - start; 68 - TRACE_FUN(ft_t_flow); 69 - 70 - if (to_do > FT_FMT_SEGS_PER_BUF) { 71 - to_do = FT_FMT_SEGS_PER_BUF; 72 - } 73 - buff->ptr = buff->address; 74 - buff->remaining = to_do * FT_SECTORS_PER_SEGMENT; /* # sectors */ 75 - buff->bytes = buff->remaining * 4; /* need 4 bytes per sector */ 76 - buff->gap3 = gap3; 77 - buff->segment_id = start; 78 - buff->next_segment = start + to_do; 79 - if (buff->next_segment >= spt) { 80 - buff->next_segment = 0; /* 0 means: stop runner */ 81 - } 82 - buff->status = waiting; /* tells the isr that it can use 83 - * this buffer 84 - */ 85 - TRACE_EXIT; 86 - } 87 - 88 - 89 - /* 90 - * start formatting a new track. 91 - */ 92 - int ftape_format_track(const unsigned int track, const __u8 gap3) 93 - { 94 - unsigned long flags; 95 - buffer_struct *tail, *head; 96 - int status; 97 - TRACE_FUN(ft_t_flow); 98 - 99 - TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),); 100 - if (track & 1) { 101 - if (!(status & QIC_STATUS_AT_EOT)) { 102 - TRACE_CATCH(ftape_seek_to_eot(),); 103 - } 104 - } else { 105 - if (!(status & QIC_STATUS_AT_BOT)) { 106 - TRACE_CATCH(ftape_seek_to_bot(),); 107 - } 108 - } 109 - ftape_abort_operation(); /* this sets ft_head = ft_tail = 0 */ 110 - ftape_set_state(formatting); 111 - 112 - TRACE(ft_t_noise, 113 - "Formatting track %d, logical: from segment %d to %d", 114 - track, track * ft_segments_per_track, 115 - (track + 1) * ft_segments_per_track - 1); 116 - 117 - /* 118 - * initialize the buffer switching protocol for this track 119 - */ 120 - head = ftape_get_buffer(ft_queue_head); /* tape isn't running yet */ 121 - tail = ftape_get_buffer(ft_queue_tail); /* tape isn't running yet */ 122 - switch_segment = 0; 123 - do { 124 - FT_SIGNAL_EXIT(_DONT_BLOCK); 125 - setup_format_buffer(tail, switch_segment, 126 - ft_segments_per_track, gap3); 127 - switch_segment = tail->next_segment; 128 - } while ((switch_segment != 0) && 129 - ((tail = ftape_next_buffer(ft_queue_tail)) != head)); 130 - /* go */ 131 - head->status = formatting; 132 - TRACE_CATCH(ftape_seek_head_to_track(track),); 133 - TRACE_CATCH(ftape_command(QIC_LOGICAL_FORWARD),); 134 - spin_lock_irqsave(&ftape_format_lock, flags); 135 - TRACE_CATCH(fdc_setup_formatting(head), restore_flags(flags)); 136 - spin_unlock_irqrestore(&ftape_format_lock, flags); 137 - TRACE_EXIT 0; 138 - } 139 - 140 - /* return segment id of segment currently being formatted and do the 141 - * buffer switching stuff. 142 - */ 143 - int ftape_format_status(unsigned int *segment_id) 144 - { 145 - buffer_struct *tail = ftape_get_buffer(ft_queue_tail); 146 - int result; 147 - TRACE_FUN(ft_t_flow); 148 - 149 - while (switch_segment != 0 && 150 - ftape_get_buffer(ft_queue_head) != tail) { 151 - FT_SIGNAL_EXIT(_DONT_BLOCK); 152 - /* need more buffers, first wait for empty buffer 153 - */ 154 - TRACE_CATCH(ftape_wait_segment(formatting),); 155 - /* don't worry for gap3. If we ever hit this piece of code, 156 - * then all buffer already have the correct gap3 set! 157 - */ 158 - setup_format_buffer(tail, switch_segment, 159 - ft_segments_per_track, tail->gap3); 160 - switch_segment = tail->next_segment; 161 - if (switch_segment != 0) { 162 - tail = ftape_next_buffer(ft_queue_tail); 163 - } 164 - } 165 - /* should runner stop ? 166 - */ 167 - if (ft_runner_status == aborting || ft_runner_status == do_abort) { 168 - buffer_struct *head = ftape_get_buffer(ft_queue_head); 169 - TRACE(ft_t_warn, "Error formatting segment %d", 170 - ftape_get_buffer(ft_queue_head)->segment_id); 171 - (void)ftape_abort_operation(); 172 - TRACE_EXIT (head->status != error) ? -EAGAIN : -EIO; 173 - } 174 - /* 175 - * don't care if the timer expires, this is just kind of a 176 - * "select" operation that lets the calling process sleep 177 - * until something has happened 178 - */ 179 - if (fdc_interrupt_wait(5 * FT_SECOND) < 0) { 180 - TRACE(ft_t_noise, "End of track %d at segment %d", 181 - ft_location.track, 182 - ftape_get_buffer(ft_queue_head)->segment_id); 183 - result = 1; /* end of track, unlock module */ 184 - } else { 185 - result = 0; 186 - } 187 - /* 188 - * the calling process should use the seg id to determine 189 - * which parts of the dma buffers can be safely overwritten 190 - * with new data. 191 - */ 192 - *segment_id = ftape_get_buffer(ft_queue_head)->segment_id; 193 - /* 194 - * Internally we start counting segment ids from the start of 195 - * each track when formatting, but externally we keep them 196 - * relative to the start of the tape: 197 - */ 198 - *segment_id += ft_location.track * ft_segments_per_track; 199 - TRACE_EXIT result; 200 - } 201 - 202 - /* 203 - * The segment id is relative to the start of the tape 204 - */ 205 - int ftape_verify_segment(const unsigned int segment_id, SectorMap *bsm) 206 - { 207 - int result; 208 - int verify_done = 0; 209 - TRACE_FUN(ft_t_flow); 210 - 211 - TRACE(ft_t_noise, "Verifying segment %d", segment_id); 212 - 213 - if (ft_driver_state != verifying) { 214 - TRACE(ft_t_noise, "calling ftape_abort_operation"); 215 - if (ftape_abort_operation() < 0) { 216 - TRACE(ft_t_err, "ftape_abort_operation failed"); 217 - TRACE_EXIT -EIO; 218 - } 219 - } 220 - *bsm = 0x00000000; 221 - ftape_set_state(verifying); 222 - for (;;) { 223 - buffer_struct *tail; 224 - /* 225 - * Allow escape from this loop on signal 226 - */ 227 - FT_SIGNAL_EXIT(_DONT_BLOCK); 228 - /* 229 - * Search all full buffers for the first matching the 230 - * wanted segment. Clear other buffers on the fly. 231 - */ 232 - tail = ftape_get_buffer(ft_queue_tail); 233 - while (!verify_done && tail->status == done) { 234 - /* 235 - * Allow escape from this loop on signal ! 236 - */ 237 - FT_SIGNAL_EXIT(_DONT_BLOCK); 238 - if (tail->segment_id == segment_id) { 239 - /* If out buffer is already full, 240 - * return its contents. 241 - */ 242 - TRACE(ft_t_flow, "found segment in cache: %d", 243 - segment_id); 244 - if ((tail->soft_error_map | 245 - tail->hard_error_map) != 0) { 246 - TRACE(ft_t_info,"bsm[%d] = 0x%08lx", 247 - segment_id, 248 - (unsigned long) 249 - (tail->soft_error_map | 250 - tail->hard_error_map)); 251 - *bsm = (tail->soft_error_map | 252 - tail->hard_error_map); 253 - } 254 - verify_done = 1; 255 - } else { 256 - TRACE(ft_t_flow,"zapping segment in cache: %d", 257 - tail->segment_id); 258 - } 259 - tail->status = waiting; 260 - tail = ftape_next_buffer(ft_queue_tail); 261 - } 262 - if (!verify_done && tail->status == verifying) { 263 - if (tail->segment_id == segment_id) { 264 - switch(ftape_wait_segment(verifying)) { 265 - case 0: 266 - break; 267 - case -EINTR: 268 - TRACE_ABORT(-EINTR, ft_t_warn, 269 - "interrupted by " 270 - "non-blockable signal"); 271 - break; 272 - default: 273 - ftape_abort_operation(); 274 - ftape_set_state(verifying); 275 - /* be picky */ 276 - TRACE_ABORT(-EIO, ft_t_warn, 277 - "wait_segment failed"); 278 - } 279 - } else { 280 - /* We're reading the wrong segment, 281 - * stop runner. 282 - */ 283 - TRACE(ft_t_noise, "verifying wrong segment"); 284 - ftape_abort_operation(); 285 - ftape_set_state(verifying); 286 - } 287 - } 288 - /* should runner stop ? 289 - */ 290 - if (ft_runner_status == aborting) { 291 - buffer_struct *head = ftape_get_buffer(ft_queue_head); 292 - if (head->status == error || 293 - head->status == verifying) { 294 - /* no data or overrun error */ 295 - head->status = waiting; 296 - } 297 - TRACE_CATCH(ftape_dumb_stop(),); 298 - } else { 299 - /* If just passed last segment on tape: wait 300 - * for BOT or EOT mark. Sets ft_runner_status to 301 - * idle if at lEOT and successful 302 - */ 303 - TRACE_CATCH(ftape_handle_logical_eot(),); 304 - } 305 - if (verify_done) { 306 - TRACE_EXIT 0; 307 - } 308 - /* Now at least one buffer is idle! 309 - * Restart runner & tape if needed. 310 - */ 311 - /* We could optimize the following a little bit. We know that 312 - * the bad sector map is empty. 313 - */ 314 - tail = ftape_get_buffer(ft_queue_tail); 315 - if (tail->status == waiting) { 316 - buffer_struct *head = ftape_get_buffer(ft_queue_head); 317 - 318 - ftape_setup_new_segment(head, segment_id, -1); 319 - ftape_calc_next_cluster(head); 320 - if (ft_runner_status == idle) { 321 - result = ftape_start_tape(segment_id, 322 - head->sector_offset); 323 - switch(result) { 324 - case 0: 325 - break; 326 - case -ETIME: 327 - case -EINTR: 328 - TRACE_ABORT(result, ft_t_err, "Error: " 329 - "segment %d unreachable", 330 - segment_id); 331 - break; 332 - default: 333 - *bsm = EMPTY_SEGMENT; 334 - TRACE_EXIT 0; 335 - break; 336 - } 337 - } 338 - head->status = verifying; 339 - fdc_setup_read_write(head, FDC_VERIFY); 340 - } 341 - } 342 - /* not reached */ 343 - TRACE_EXIT -EIO; 344 - }
-37
drivers/char/ftape/lowlevel/ftape-format.h
··· 1 - #ifndef _FTAPE_FORMAT_H 2 - #define _FTAPE_FORMAT_H 3 - 4 - /* 5 - * Copyright (C) 1996-1997 Claus-Justus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-format.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:18:13 $ 25 - * 26 - * This file contains the low level definitions for the 27 - * formatting support for the QIC-40/80/3010/3020 floppy-tape 28 - * driver "ftape" for Linux. 29 - */ 30 - 31 - #ifdef __KERNEL__ 32 - extern int ftape_format_track(const unsigned int track, const __u8 gap3); 33 - extern int ftape_format_status(unsigned int *segment_id); 34 - extern int ftape_verify_segment(const unsigned int segment_id, SectorMap *bsm); 35 - #endif /* __KERNEL__ */ 36 - 37 - #endif
-160
drivers/char/ftape/lowlevel/ftape-init.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven, 3 - * (C) 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * This file contains the code that interfaces the kernel 21 - * for the QIC-40/80/3010/3020 floppy-tape driver for Linux. 22 - */ 23 - 24 - #include <linux/module.h> 25 - #include <linux/errno.h> 26 - #include <linux/fs.h> 27 - #include <linux/kernel.h> 28 - #include <linux/signal.h> 29 - #include <linux/major.h> 30 - 31 - #include <linux/ftape.h> 32 - #include <linux/init.h> 33 - #include <linux/qic117.h> 34 - #ifdef CONFIG_ZFTAPE 35 - #include <linux/zftape.h> 36 - #endif 37 - 38 - #include "../lowlevel/ftape-init.h" 39 - #include "../lowlevel/ftape-io.h" 40 - #include "../lowlevel/ftape-read.h" 41 - #include "../lowlevel/ftape-write.h" 42 - #include "../lowlevel/ftape-ctl.h" 43 - #include "../lowlevel/ftape-rw.h" 44 - #include "../lowlevel/fdc-io.h" 45 - #include "../lowlevel/ftape-buffer.h" 46 - #include "../lowlevel/ftape-proc.h" 47 - #include "../lowlevel/ftape-tracing.h" 48 - 49 - 50 - #if defined(MODULE) && !defined(CONFIG_FT_NO_TRACE_AT_ALL) 51 - static int ft_tracing = -1; 52 - #endif 53 - 54 - 55 - /* Called by modules package when installing the driver 56 - * or by kernel during the initialization phase 57 - */ 58 - static int __init ftape_init(void) 59 - { 60 - TRACE_FUN(ft_t_flow); 61 - 62 - #ifdef MODULE 63 - #ifndef CONFIG_FT_NO_TRACE_AT_ALL 64 - if (ft_tracing != -1) { 65 - ftape_tracing = ft_tracing; 66 - } 67 - #endif 68 - printk(KERN_INFO FTAPE_VERSION "\n"); 69 - if (TRACE_LEVEL >= ft_t_info) { 70 - printk( 71 - KERN_INFO "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl)\n" 72 - KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n" 73 - KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" 74 - KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n"); 75 - } 76 - #else /* !MODULE */ 77 - /* print a short no-nonsense boot message */ 78 - printk(KERN_INFO FTAPE_VERSION "\n"); 79 - #endif /* MODULE */ 80 - TRACE(ft_t_info, "installing QIC-117 floppy tape hardware drive ... "); 81 - TRACE(ft_t_info, "ftape_init @ 0x%p", ftape_init); 82 - /* Allocate the DMA buffers. They are deallocated at cleanup() time. 83 - */ 84 - #ifdef TESTING 85 - #ifdef MODULE 86 - while (ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS) < 0) { 87 - ftape_sleep(FT_SECOND/20); 88 - if (signal_pending(current)) { 89 - (void)ftape_set_nr_buffers(0); 90 - TRACE(ft_t_bug, 91 - "Killed by signal while allocating buffers."); 92 - TRACE_ABORT(-EINTR, 93 - ft_t_bug, "Free up memory and retry"); 94 - } 95 - } 96 - #else 97 - TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS), 98 - (void)ftape_set_nr_buffers(0)); 99 - #endif 100 - #else 101 - TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS), 102 - (void)ftape_set_nr_buffers(0)); 103 - #endif 104 - ft_drive_sel = -1; 105 - ft_failure = 1; /* inhibit any operation but open */ 106 - ftape_udelay_calibrate(); /* must be before fdc_wait_calibrate ! */ 107 - fdc_wait_calibrate(); 108 - #if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) 109 - (void)ftape_proc_init(); 110 - #endif 111 - #ifdef CONFIG_ZFTAPE 112 - (void)zft_init(); 113 - #endif 114 - TRACE_EXIT 0; 115 - } 116 - 117 - module_param(ft_fdc_base, uint, 0); 118 - MODULE_PARM_DESC(ft_fdc_base, "Base address of FDC controller."); 119 - module_param(ft_fdc_irq, uint, 0); 120 - MODULE_PARM_DESC(ft_fdc_irq, "IRQ (interrupt channel) to use."); 121 - module_param(ft_fdc_dma, uint, 0); 122 - MODULE_PARM_DESC(ft_fdc_dma, "DMA channel to use."); 123 - module_param(ft_fdc_threshold, uint, 0); 124 - MODULE_PARM_DESC(ft_fdc_threshold, "Threshold of the FDC Fifo."); 125 - module_param(ft_fdc_rate_limit, uint, 0); 126 - MODULE_PARM_DESC(ft_fdc_rate_limit, "Maximal data rate for FDC."); 127 - module_param(ft_probe_fc10, bool, 0); 128 - MODULE_PARM_DESC(ft_probe_fc10, 129 - "If non-zero, probe for a Colorado FC-10/FC-20 controller."); 130 - module_param(ft_mach2, bool, 0); 131 - MODULE_PARM_DESC(ft_mach2, 132 - "If non-zero, probe for a Mountain MACH-2 controller."); 133 - #if defined(MODULE) && !defined(CONFIG_FT_NO_TRACE_AT_ALL) 134 - module_param(ft_tracing, int, 0644); 135 - MODULE_PARM_DESC(ft_tracing, 136 - "Amount of debugging output, 0 <= tracing <= 8, default 3."); 137 - #endif 138 - 139 - MODULE_AUTHOR( 140 - "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl), " 141 - "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no), " 142 - "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)"); 143 - MODULE_DESCRIPTION( 144 - "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives."); 145 - MODULE_LICENSE("GPL"); 146 - 147 - static void __exit ftape_exit(void) 148 - { 149 - TRACE_FUN(ft_t_flow); 150 - 151 - #if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) 152 - ftape_proc_destroy(); 153 - #endif 154 - (void)ftape_set_nr_buffers(0); 155 - printk(KERN_INFO "ftape: unloaded.\n"); 156 - TRACE_EXIT; 157 - } 158 - 159 - module_init(ftape_init); 160 - module_exit(ftape_exit);
-43
drivers/char/ftape/lowlevel/ftape-init.h
··· 1 - #ifndef _FTAPE_INIT_H 2 - #define _FTAPE_INIT_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-init.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:16 $ 26 - * 27 - * This file contains the definitions for the interface to 28 - * the Linux kernel for floppy tape driver ftape. 29 - * 30 - */ 31 - 32 - #include <linux/linkage.h> 33 - #include <linux/signal.h> 34 - 35 - #define _NEVER_BLOCK (sigmask(SIGKILL) | sigmask(SIGSTOP)) 36 - #define _DONT_BLOCK (_NEVER_BLOCK | sigmask(SIGINT)) 37 - #define _DO_BLOCK (sigmask(SIGPIPE)) 38 - 39 - #ifndef QIC117_TAPE_MAJOR 40 - #define QIC117_TAPE_MAJOR 27 41 - #endif 42 - 43 - #endif
-992
drivers/char/ftape/lowlevel/ftape-io.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven, 3 - * (C) 1996 Kai Harrekilde-Petersen, 4 - * (C) 1997 Claus-Justus Heine. 5 - 6 - This program is free software; you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation; either version 2, or (at your option) 9 - any later version. 10 - 11 - This program is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with this program; see the file COPYING. If not, write to 18 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 - 20 - * 21 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.c,v $ 22 - * $Revision: 1.4 $ 23 - * $Date: 1997/11/11 14:02:36 $ 24 - * 25 - * This file contains the general control functions for the 26 - * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. 27 - */ 28 - 29 - #include <linux/errno.h> 30 - #include <linux/sched.h> 31 - #include <linux/mm.h> 32 - #include <asm/system.h> 33 - #include <linux/ioctl.h> 34 - #include <linux/mtio.h> 35 - #include <linux/delay.h> 36 - 37 - #include <linux/ftape.h> 38 - #include <linux/qic117.h> 39 - #include "../lowlevel/ftape-tracing.h" 40 - #include "../lowlevel/fdc-io.h" 41 - #include "../lowlevel/ftape-io.h" 42 - #include "../lowlevel/ftape-ctl.h" 43 - #include "../lowlevel/ftape-rw.h" 44 - #include "../lowlevel/ftape-write.h" 45 - #include "../lowlevel/ftape-read.h" 46 - #include "../lowlevel/ftape-init.h" 47 - #include "../lowlevel/ftape-calibr.h" 48 - 49 - /* Global vars. 50 - */ 51 - /* NOTE: sectors start numbering at 1, all others at 0 ! */ 52 - ft_timeout_table ftape_timeout; 53 - unsigned int ftape_tape_len; 54 - volatile qic117_cmd_t ftape_current_command; 55 - const struct qic117_command_table qic117_cmds[] = QIC117_COMMANDS; 56 - int ftape_might_be_off_track; 57 - 58 - /* Local vars. 59 - */ 60 - static int diagnostic_mode; 61 - static unsigned int ftape_udelay_count; 62 - static unsigned int ftape_udelay_time; 63 - 64 - void ftape_udelay(unsigned int usecs) 65 - { 66 - volatile int count = (ftape_udelay_count * usecs + 67 - ftape_udelay_count - 1) / ftape_udelay_time; 68 - volatile int i; 69 - 70 - while (count-- > 0) { 71 - for (i = 0; i < 20; ++i); 72 - } 73 - } 74 - 75 - void ftape_udelay_calibrate(void) 76 - { 77 - ftape_calibrate("ftape_udelay", 78 - ftape_udelay, &ftape_udelay_count, &ftape_udelay_time); 79 - } 80 - 81 - /* Delay (msec) routine. 82 - */ 83 - void ftape_sleep(unsigned int time) 84 - { 85 - TRACE_FUN(ft_t_any); 86 - 87 - time *= 1000; /* msecs -> usecs */ 88 - if (time < FT_USPT) { 89 - /* Time too small for scheduler, do a busy wait ! */ 90 - ftape_udelay(time); 91 - } else { 92 - long timeout; 93 - unsigned long flags; 94 - unsigned int ticks = (time + FT_USPT - 1) / FT_USPT; 95 - 96 - TRACE(ft_t_any, "%d msec, %d ticks", time/1000, ticks); 97 - timeout = ticks; 98 - save_flags(flags); 99 - sti(); 100 - msleep_interruptible(jiffies_to_msecs(timeout)); 101 - /* Mmm. Isn't current->blocked == 0xffffffff ? 102 - */ 103 - if (signal_pending(current)) { 104 - TRACE(ft_t_err, "awoken by non-blocked signal :-("); 105 - } 106 - restore_flags(flags); 107 - } 108 - TRACE_EXIT; 109 - } 110 - 111 - /* send a command or parameter to the drive 112 - * Generates # of step pulses. 113 - */ 114 - static inline int ft_send_to_drive(int arg) 115 - { 116 - /* Always wait for a command_timeout period to separate 117 - * individuals commands and/or parameters. 118 - */ 119 - ftape_sleep(3 * FT_MILLISECOND); 120 - /* Keep cylinder nr within range, step towards home if possible. 121 - */ 122 - if (ftape_current_cylinder >= arg) { 123 - return fdc_seek(ftape_current_cylinder - arg); 124 - } else { 125 - return fdc_seek(ftape_current_cylinder + arg); 126 - } 127 - } 128 - 129 - /* forward */ int ftape_report_raw_drive_status(int *status); 130 - 131 - static int ft_check_cmd_restrictions(qic117_cmd_t command) 132 - { 133 - int status = -1; 134 - TRACE_FUN(ft_t_any); 135 - 136 - TRACE(ft_t_flow, "%s", qic117_cmds[command].name); 137 - /* A new motion command during an uninterruptible (motion) 138 - * command requires a ready status before the new command can 139 - * be issued. Otherwise a new motion command needs to be 140 - * checked against required status. 141 - */ 142 - if (qic117_cmds[command].cmd_type == motion && 143 - qic117_cmds[ftape_current_command].non_intr) { 144 - ftape_report_raw_drive_status(&status); 145 - if ((status & QIC_STATUS_READY) == 0) { 146 - TRACE(ft_t_noise, 147 - "motion cmd (%d) during non-intr cmd (%d)", 148 - command, ftape_current_command); 149 - TRACE(ft_t_noise, "waiting until drive gets ready"); 150 - ftape_ready_wait(ftape_timeout.seek, 151 - &status); 152 - } 153 - } 154 - if (qic117_cmds[command].mask != 0) { 155 - __u8 difference; 156 - /* Some commands do require a certain status: 157 - */ 158 - if (status == -1) { /* not yet set */ 159 - ftape_report_raw_drive_status(&status); 160 - } 161 - difference = ((status ^ qic117_cmds[command].state) & 162 - qic117_cmds[command].mask); 163 - /* Wait until the drive gets 164 - * ready. This may last forever if 165 - * the drive never gets ready... 166 - */ 167 - while ((difference & QIC_STATUS_READY) != 0) { 168 - TRACE(ft_t_noise, "command %d issued while not ready", 169 - command); 170 - TRACE(ft_t_noise, "waiting until drive gets ready"); 171 - if (ftape_ready_wait(ftape_timeout.seek, 172 - &status) == -EINTR) { 173 - /* Bail out on signal ! 174 - */ 175 - TRACE_ABORT(-EINTR, ft_t_warn, 176 - "interrupted by non-blockable signal"); 177 - } 178 - difference = ((status ^ qic117_cmds[command].state) & 179 - qic117_cmds[command].mask); 180 - } 181 - while ((difference & QIC_STATUS_ERROR) != 0) { 182 - int err; 183 - qic117_cmd_t cmd; 184 - 185 - TRACE(ft_t_noise, 186 - "command %d issued while error pending", 187 - command); 188 - TRACE(ft_t_noise, "clearing error status"); 189 - ftape_report_error(&err, &cmd, 1); 190 - ftape_report_raw_drive_status(&status); 191 - difference = ((status ^ qic117_cmds[command].state) & 192 - qic117_cmds[command].mask); 193 - if ((difference & QIC_STATUS_ERROR) != 0) { 194 - /* Bail out on fatal signal ! 195 - */ 196 - FT_SIGNAL_EXIT(_NEVER_BLOCK); 197 - } 198 - } 199 - if (difference) { 200 - /* Any remaining difference can't be solved 201 - * here. 202 - */ 203 - if (difference & (QIC_STATUS_CARTRIDGE_PRESENT | 204 - QIC_STATUS_NEW_CARTRIDGE | 205 - QIC_STATUS_REFERENCED)) { 206 - TRACE(ft_t_warn, 207 - "Fatal: tape removed or reinserted !"); 208 - ft_failure = 1; 209 - } else { 210 - TRACE(ft_t_err, "wrong state: 0x%02x should be: 0x%02x", 211 - status & qic117_cmds[command].mask, 212 - qic117_cmds[command].state); 213 - } 214 - TRACE_EXIT -EIO; 215 - } 216 - if (~status & QIC_STATUS_READY & qic117_cmds[command].mask) { 217 - TRACE_ABORT(-EBUSY, ft_t_err, "Bad: still busy!"); 218 - } 219 - } 220 - TRACE_EXIT 0; 221 - } 222 - 223 - /* Issue a tape command: 224 - */ 225 - int ftape_command(qic117_cmd_t command) 226 - { 227 - int result = 0; 228 - static int level; 229 - TRACE_FUN(ft_t_any); 230 - 231 - if ((unsigned int)command > NR_ITEMS(qic117_cmds)) { 232 - /* This is a bug we'll want to know about too. 233 - */ 234 - TRACE_ABORT(-EIO, ft_t_bug, "bug - bad command: %d", command); 235 - } 236 - if (++level > 5) { /* This is a bug we'll want to know about. */ 237 - --level; 238 - TRACE_ABORT(-EIO, ft_t_bug, "bug - recursion for command: %d", 239 - command); 240 - } 241 - /* disable logging and restriction check for some commands, 242 - * check all other commands that have a prescribed starting 243 - * status. 244 - */ 245 - if (diagnostic_mode) { 246 - TRACE(ft_t_flow, "diagnostic command %d", command); 247 - } else if (command == QIC_REPORT_DRIVE_STATUS || 248 - command == QIC_REPORT_NEXT_BIT) { 249 - TRACE(ft_t_any, "%s", qic117_cmds[command].name); 250 - } else { 251 - TRACE_CATCH(ft_check_cmd_restrictions(command), --level); 252 - } 253 - /* Now all conditions are met or result was < 0. 254 - */ 255 - result = ft_send_to_drive((unsigned int)command); 256 - if (qic117_cmds[command].cmd_type == motion && 257 - command != QIC_LOGICAL_FORWARD && command != QIC_STOP_TAPE) { 258 - ft_location.known = 0; 259 - } 260 - ftape_current_command = command; 261 - --level; 262 - TRACE_EXIT result; 263 - } 264 - 265 - /* Send a tape command parameter: 266 - * Generates command # of step pulses. 267 - * Skips tape-status call ! 268 - */ 269 - int ftape_parameter(unsigned int parameter) 270 - { 271 - TRACE_FUN(ft_t_any); 272 - 273 - TRACE(ft_t_flow, "called with parameter = %d", parameter); 274 - TRACE_EXIT ft_send_to_drive(parameter + 2); 275 - } 276 - 277 - /* Wait for the drive to get ready. 278 - * timeout time in milli-seconds 279 - * Returned status is valid if result != -EIO 280 - * 281 - * Should we allow to be killed by SIGINT? (^C) 282 - * Would be nice at least for large timeouts. 283 - */ 284 - int ftape_ready_wait(unsigned int timeout, int *status) 285 - { 286 - unsigned long t0; 287 - unsigned int poll_delay; 288 - int signal_retries; 289 - TRACE_FUN(ft_t_any); 290 - 291 - /* the following ** REALLY ** reduces the system load when 292 - * e.g. one simply rewinds or retensions. The tape is slow 293 - * anyway. It is really not necessary to detect error 294 - * conditions with 1/10 seconds granularity 295 - * 296 - * On my AMD 133MHZ 486: 100 ms: 23% system load 297 - * 1 sec: 5% 298 - * 5 sec: 0.6%, yeah 299 - */ 300 - if (timeout <= FT_SECOND) { 301 - poll_delay = 100 * FT_MILLISECOND; 302 - signal_retries = 20; /* two seconds */ 303 - } else if (timeout < 20 * FT_SECOND) { 304 - TRACE(ft_t_flow, "setting poll delay to 1 second"); 305 - poll_delay = FT_SECOND; 306 - signal_retries = 2; /* two seconds */ 307 - } else { 308 - TRACE(ft_t_flow, "setting poll delay to 5 seconds"); 309 - poll_delay = 5 * FT_SECOND; 310 - signal_retries = 1; /* five seconds */ 311 - } 312 - for (;;) { 313 - t0 = jiffies; 314 - TRACE_CATCH(ftape_report_raw_drive_status(status),); 315 - if (*status & QIC_STATUS_READY) { 316 - TRACE_EXIT 0; 317 - } 318 - if (!signal_retries--) { 319 - FT_SIGNAL_EXIT(_NEVER_BLOCK); 320 - } 321 - if ((int)timeout >= 0) { 322 - /* this will fail when jiffies wraps around about 323 - * once every year :-) 324 - */ 325 - timeout -= ((jiffies - t0) * FT_SECOND) / HZ; 326 - if (timeout <= 0) { 327 - TRACE_ABORT(-ETIME, ft_t_err, "timeout"); 328 - } 329 - ftape_sleep(poll_delay); 330 - timeout -= poll_delay; 331 - } else { 332 - ftape_sleep(poll_delay); 333 - } 334 - } 335 - TRACE_EXIT -ETIME; 336 - } 337 - 338 - /* Issue command and wait up to timeout milli seconds for drive ready 339 - */ 340 - int ftape_command_wait(qic117_cmd_t command, unsigned int timeout, int *status) 341 - { 342 - int result; 343 - 344 - /* Drive should be ready, issue command 345 - */ 346 - result = ftape_command(command); 347 - if (result >= 0) { 348 - result = ftape_ready_wait(timeout, status); 349 - } 350 - return result; 351 - } 352 - 353 - static int ftape_parameter_wait(unsigned int parm, unsigned int timeout, int *status) 354 - { 355 - int result; 356 - 357 - /* Drive should be ready, issue command 358 - */ 359 - result = ftape_parameter(parm); 360 - if (result >= 0) { 361 - result = ftape_ready_wait(timeout, status); 362 - } 363 - return result; 364 - } 365 - 366 - /*-------------------------------------------------------------------------- 367 - * Report operations 368 - */ 369 - 370 - /* Query the drive about its status. The command is sent and 371 - result_length bits of status are returned (2 extra bits are read 372 - for start and stop). */ 373 - 374 - int ftape_report_operation(int *status, 375 - qic117_cmd_t command, 376 - int result_length) 377 - { 378 - int i, st3; 379 - unsigned int t0; 380 - unsigned int dt; 381 - TRACE_FUN(ft_t_any); 382 - 383 - TRACE_CATCH(ftape_command(command),); 384 - t0 = ftape_timestamp(); 385 - i = 0; 386 - do { 387 - ++i; 388 - ftape_sleep(3 * FT_MILLISECOND); /* see remark below */ 389 - TRACE_CATCH(fdc_sense_drive_status(&st3),); 390 - dt = ftape_timediff(t0, ftape_timestamp()); 391 - /* Ack should be asserted within Ttimout + Tack = 6 msec. 392 - * Looks like some drives fail to do this so extend this 393 - * period to 300 msec. 394 - */ 395 - } while (!(st3 & ST3_TRACK_0) && dt < 300000); 396 - if (!(st3 & ST3_TRACK_0)) { 397 - TRACE(ft_t_err, 398 - "No acknowledge after %u msec. (%i iter)", dt / 1000, i); 399 - TRACE_ABORT(-EIO, ft_t_err, "timeout on Acknowledge"); 400 - } 401 - /* dt may be larger than expected because of other tasks 402 - * scheduled while we were sleeping. 403 - */ 404 - if (i > 1 && dt > 6000) { 405 - TRACE(ft_t_err, "Acknowledge after %u msec. (%i iter)", 406 - dt / 1000, i); 407 - } 408 - *status = 0; 409 - for (i = 0; i < result_length + 1; i++) { 410 - TRACE_CATCH(ftape_command(QIC_REPORT_NEXT_BIT),); 411 - TRACE_CATCH(fdc_sense_drive_status(&st3),); 412 - if (i < result_length) { 413 - *status |= ((st3 & ST3_TRACK_0) ? 1 : 0) << i; 414 - } else if ((st3 & ST3_TRACK_0) == 0) { 415 - TRACE_ABORT(-EIO, ft_t_err, "missing status stop bit"); 416 - } 417 - } 418 - /* this command will put track zero and index back into normal state */ 419 - (void)ftape_command(QIC_REPORT_NEXT_BIT); 420 - TRACE_EXIT 0; 421 - } 422 - 423 - /* Report the current drive status. */ 424 - 425 - int ftape_report_raw_drive_status(int *status) 426 - { 427 - int result; 428 - int count = 0; 429 - TRACE_FUN(ft_t_any); 430 - 431 - do { 432 - result = ftape_report_operation(status, 433 - QIC_REPORT_DRIVE_STATUS, 8); 434 - } while (result < 0 && ++count <= 3); 435 - if (result < 0) { 436 - TRACE_ABORT(-EIO, ft_t_err, 437 - "report_operation failed after %d trials", count); 438 - } 439 - if ((*status & 0xff) == 0xff) { 440 - TRACE_ABORT(-EIO, ft_t_err, 441 - "impossible drive status 0xff"); 442 - } 443 - if (*status & QIC_STATUS_READY) { 444 - ftape_current_command = QIC_NO_COMMAND; /* completed */ 445 - } 446 - ft_last_status.status.drive_status = (__u8)(*status & 0xff); 447 - TRACE_EXIT 0; 448 - } 449 - 450 - int ftape_report_drive_status(int *status) 451 - { 452 - TRACE_FUN(ft_t_any); 453 - 454 - TRACE_CATCH(ftape_report_raw_drive_status(status),); 455 - if (*status & QIC_STATUS_NEW_CARTRIDGE || 456 - !(*status & QIC_STATUS_CARTRIDGE_PRESENT)) { 457 - ft_failure = 1; /* will inhibit further operations */ 458 - TRACE_EXIT -EIO; 459 - } 460 - if (*status & QIC_STATUS_READY && *status & QIC_STATUS_ERROR) { 461 - /* Let caller handle all errors */ 462 - TRACE_ABORT(1, ft_t_warn, "warning: error status set!"); 463 - } 464 - TRACE_EXIT 0; 465 - } 466 - 467 - int ftape_report_error(unsigned int *error, 468 - qic117_cmd_t *command, int report) 469 - { 470 - static const ftape_error ftape_errors[] = QIC117_ERRORS; 471 - int code; 472 - TRACE_FUN(ft_t_any); 473 - 474 - TRACE_CATCH(ftape_report_operation(&code, QIC_REPORT_ERROR_CODE, 16),); 475 - *error = (unsigned int)(code & 0xff); 476 - *command = (qic117_cmd_t)((code>>8)&0xff); 477 - /* remember hardware status, maybe useful for status ioctls 478 - */ 479 - ft_last_error.error.command = (__u8)*command; 480 - ft_last_error.error.error = (__u8)*error; 481 - if (!report) { 482 - TRACE_EXIT 0; 483 - } 484 - if (*error == 0) { 485 - TRACE_ABORT(0, ft_t_info, "No error"); 486 - } 487 - TRACE(ft_t_info, "errorcode: %d", *error); 488 - if (*error < NR_ITEMS(ftape_errors)) { 489 - TRACE(ft_t_noise, "%sFatal ERROR:", 490 - (ftape_errors[*error].fatal ? "" : "Non-")); 491 - TRACE(ft_t_noise, "%s ...", ftape_errors[*error].message); 492 - } else { 493 - TRACE(ft_t_noise, "Unknown ERROR !"); 494 - } 495 - if ((unsigned int)*command < NR_ITEMS(qic117_cmds) && 496 - qic117_cmds[*command].name != NULL) { 497 - TRACE(ft_t_noise, "... caused by command \'%s\'", 498 - qic117_cmds[*command].name); 499 - } else { 500 - TRACE(ft_t_noise, "... caused by unknown command %d", 501 - *command); 502 - } 503 - TRACE_EXIT 0; 504 - } 505 - 506 - int ftape_report_configuration(qic_model *model, 507 - unsigned int *rate, 508 - int *qic_std, 509 - int *tape_len) 510 - { 511 - int result; 512 - int config; 513 - int status; 514 - static const unsigned int qic_rates[ 4] = { 250, 2000, 500, 1000 }; 515 - TRACE_FUN(ft_t_any); 516 - 517 - result = ftape_report_operation(&config, 518 - QIC_REPORT_DRIVE_CONFIGURATION, 8); 519 - if (result < 0) { 520 - ft_last_status.status.drive_config = (__u8)0x00; 521 - *model = prehistoric; 522 - *rate = 500; 523 - *qic_std = QIC_TAPE_QIC40; 524 - *tape_len = 205; 525 - TRACE_EXIT 0; 526 - } else { 527 - ft_last_status.status.drive_config = (__u8)(config & 0xff); 528 - } 529 - *rate = qic_rates[(config & QIC_CONFIG_RATE_MASK) >> QIC_CONFIG_RATE_SHIFT]; 530 - result = ftape_report_operation(&status, QIC_REPORT_TAPE_STATUS, 8); 531 - if (result < 0) { 532 - ft_last_status.status.tape_status = (__u8)0x00; 533 - /* pre- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is valid. 534 - */ 535 - *qic_std = (config & QIC_CONFIG_80) ? 536 - QIC_TAPE_QIC80 : QIC_TAPE_QIC40; 537 - /* ?? how's about 425ft tapes? */ 538 - *tape_len = (config & QIC_CONFIG_LONG) ? 307 : 0; 539 - *model = pre_qic117c; 540 - result = 0; 541 - } else { 542 - ft_last_status.status.tape_status = (__u8)(status & 0xff); 543 - *model = post_qic117b; 544 - TRACE(ft_t_any, "report tape status result = %02x", status); 545 - /* post- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is 546 - * invalid. 547 - */ 548 - switch (status & QIC_TAPE_STD_MASK) { 549 - case QIC_TAPE_QIC40: 550 - case QIC_TAPE_QIC80: 551 - case QIC_TAPE_QIC3020: 552 - case QIC_TAPE_QIC3010: 553 - *qic_std = status & QIC_TAPE_STD_MASK; 554 - break; 555 - default: 556 - *qic_std = -1; 557 - break; 558 - } 559 - switch (status & QIC_TAPE_LEN_MASK) { 560 - case QIC_TAPE_205FT: 561 - /* 205 or 425+ ft 550 Oe tape */ 562 - *tape_len = 0; 563 - break; 564 - case QIC_TAPE_307FT: 565 - /* 307.5 ft 550 Oe Extended Length (XL) tape */ 566 - *tape_len = 307; 567 - break; 568 - case QIC_TAPE_VARIABLE: 569 - /* Variable length 550 Oe tape */ 570 - *tape_len = 0; 571 - break; 572 - case QIC_TAPE_1100FT: 573 - /* 1100 ft 550 Oe tape */ 574 - *tape_len = 1100; 575 - break; 576 - case QIC_TAPE_FLEX: 577 - /* Variable length 900 Oe tape */ 578 - *tape_len = 0; 579 - break; 580 - default: 581 - *tape_len = -1; 582 - break; 583 - } 584 - if (*qic_std == -1 || *tape_len == -1) { 585 - TRACE(ft_t_any, 586 - "post qic-117b spec drive with unknown tape"); 587 - } 588 - result = *tape_len == -1 ? -EIO : 0; 589 - if (status & QIC_TAPE_WIDE) { 590 - switch (*qic_std) { 591 - case QIC_TAPE_QIC80: 592 - TRACE(ft_t_info, "TR-1 tape detected"); 593 - break; 594 - case QIC_TAPE_QIC3010: 595 - TRACE(ft_t_info, "TR-2 tape detected"); 596 - break; 597 - case QIC_TAPE_QIC3020: 598 - TRACE(ft_t_info, "TR-3 tape detected"); 599 - break; 600 - default: 601 - TRACE(ft_t_warn, 602 - "Unknown Travan tape type detected"); 603 - break; 604 - } 605 - } 606 - } 607 - TRACE_EXIT (result < 0) ? -EIO : 0; 608 - } 609 - 610 - static int ftape_report_rom_version(int *version) 611 - { 612 - 613 - if (ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8) < 0) { 614 - return -EIO; 615 - } else { 616 - return 0; 617 - } 618 - } 619 - 620 - void ftape_report_vendor_id(unsigned int *id) 621 - { 622 - int result; 623 - TRACE_FUN(ft_t_any); 624 - 625 - /* We'll try to get a vendor id from the drive. First 626 - * according to the QIC-117 spec, a 16-bit id is requested. 627 - * If that fails we'll try an 8-bit version, otherwise we'll 628 - * try an undocumented query. 629 - */ 630 - result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 16); 631 - if (result < 0) { 632 - result = ftape_report_operation((int *) id, 633 - QIC_REPORT_VENDOR_ID, 8); 634 - if (result < 0) { 635 - /* The following is an undocumented call found 636 - * in the CMS code. 637 - */ 638 - result = ftape_report_operation((int *) id, 24, 8); 639 - if (result < 0) { 640 - *id = UNKNOWN_VENDOR; 641 - } else { 642 - TRACE(ft_t_noise, "got old 8 bit id: %04x", 643 - *id); 644 - *id |= 0x20000; 645 - } 646 - } else { 647 - TRACE(ft_t_noise, "got 8 bit id: %04x", *id); 648 - *id |= 0x10000; 649 - } 650 - } else { 651 - TRACE(ft_t_noise, "got 16 bit id: %04x", *id); 652 - } 653 - if (*id == 0x0047) { 654 - int version; 655 - int sign; 656 - 657 - if (ftape_report_rom_version(&version) < 0) { 658 - TRACE(ft_t_bug, "report rom version failed"); 659 - TRACE_EXIT; 660 - } 661 - TRACE(ft_t_noise, "CMS rom version: %d", version); 662 - ftape_command(QIC_ENTER_DIAGNOSTIC_1); 663 - ftape_command(QIC_ENTER_DIAGNOSTIC_1); 664 - diagnostic_mode = 1; 665 - if (ftape_report_operation(&sign, 9, 8) < 0) { 666 - unsigned int error; 667 - qic117_cmd_t command; 668 - 669 - ftape_report_error(&error, &command, 1); 670 - ftape_command(QIC_ENTER_PRIMARY_MODE); 671 - diagnostic_mode = 0; 672 - TRACE_EXIT; /* failure ! */ 673 - } else { 674 - TRACE(ft_t_noise, "CMS signature: %02x", sign); 675 - } 676 - if (sign == 0xa5) { 677 - result = ftape_report_operation(&sign, 37, 8); 678 - if (result < 0) { 679 - if (version >= 63) { 680 - *id = 0x8880; 681 - TRACE(ft_t_noise, 682 - "This is an Iomega drive !"); 683 - } else { 684 - *id = 0x0047; 685 - TRACE(ft_t_noise, 686 - "This is a real CMS drive !"); 687 - } 688 - } else { 689 - *id = 0x0047; 690 - TRACE(ft_t_noise, "CMS status: %d", sign); 691 - } 692 - } else { 693 - *id = UNKNOWN_VENDOR; 694 - } 695 - ftape_command(QIC_ENTER_PRIMARY_MODE); 696 - diagnostic_mode = 0; 697 - } 698 - TRACE_EXIT; 699 - } 700 - 701 - static int qic_rate_code(unsigned int rate) 702 - { 703 - switch (rate) { 704 - case 250: 705 - return QIC_CONFIG_RATE_250; 706 - case 500: 707 - return QIC_CONFIG_RATE_500; 708 - case 1000: 709 - return QIC_CONFIG_RATE_1000; 710 - case 2000: 711 - return QIC_CONFIG_RATE_2000; 712 - default: 713 - return QIC_CONFIG_RATE_500; 714 - } 715 - } 716 - 717 - static int ftape_set_rate_test(unsigned int *max_rate) 718 - { 719 - unsigned int error; 720 - qic117_cmd_t command; 721 - int status; 722 - int supported = 0; 723 - TRACE_FUN(ft_t_any); 724 - 725 - /* Check if the drive does support the select rate command 726 - * by testing all different settings. If any one is accepted 727 - * we assume the command is supported, else not. 728 - */ 729 - for (*max_rate = 2000; *max_rate >= 250; *max_rate /= 2) { 730 - if (ftape_command(QIC_SELECT_RATE) < 0) { 731 - continue; 732 - } 733 - if (ftape_parameter_wait(qic_rate_code(*max_rate), 734 - 1 * FT_SECOND, &status) < 0) { 735 - continue; 736 - } 737 - if (status & QIC_STATUS_ERROR) { 738 - ftape_report_error(&error, &command, 0); 739 - continue; 740 - } 741 - supported = 1; /* did accept a request */ 742 - break; 743 - } 744 - TRACE(ft_t_noise, "Select Rate command is%s supported", 745 - supported ? "" : " not"); 746 - TRACE_EXIT supported; 747 - } 748 - 749 - int ftape_set_data_rate(unsigned int new_rate /* Kbps */, unsigned int qic_std) 750 - { 751 - int status; 752 - int result = 0; 753 - unsigned int data_rate = new_rate; 754 - static int supported; 755 - int rate_changed = 0; 756 - qic_model dummy_model; 757 - unsigned int dummy_qic_std, dummy_tape_len; 758 - TRACE_FUN(ft_t_any); 759 - 760 - if (ft_drive_max_rate == 0) { /* first time */ 761 - supported = ftape_set_rate_test(&ft_drive_max_rate); 762 - } 763 - if (supported) { 764 - ftape_command(QIC_SELECT_RATE); 765 - result = ftape_parameter_wait(qic_rate_code(new_rate), 766 - 1 * FT_SECOND, &status); 767 - if (result >= 0 && !(status & QIC_STATUS_ERROR)) { 768 - rate_changed = 1; 769 - } 770 - } 771 - TRACE_CATCH(result = ftape_report_configuration(&dummy_model, 772 - &data_rate, 773 - &dummy_qic_std, 774 - &dummy_tape_len),); 775 - if (data_rate != new_rate) { 776 - if (!supported) { 777 - TRACE(ft_t_warn, "Rate change not supported!"); 778 - } else if (rate_changed) { 779 - TRACE(ft_t_warn, "Requested: %d, got %d", 780 - new_rate, data_rate); 781 - } else { 782 - TRACE(ft_t_warn, "Rate change failed!"); 783 - } 784 - result = -EINVAL; 785 - } 786 - /* 787 - * Set data rate and write precompensation as specified: 788 - * 789 - * | QIC-40/80 | QIC-3010/3020 790 - * rate | precomp | precomp 791 - * ----------+-------------+-------------- 792 - * 250 Kbps. | 250 ns. | 0 ns. 793 - * 500 Kbps. | 125 ns. | 0 ns. 794 - * 1 Mbps. | 42 ns. | 0 ns. 795 - * 2 Mbps | N/A | 0 ns. 796 - */ 797 - if ((qic_std == QIC_TAPE_QIC40 && data_rate > 500) || 798 - (qic_std == QIC_TAPE_QIC80 && data_rate > 1000)) { 799 - TRACE_ABORT(-EINVAL, 800 - ft_t_warn, "Datarate too high for QIC-mode"); 801 - } 802 - TRACE_CATCH(fdc_set_data_rate(data_rate),_res = -EINVAL); 803 - ft_data_rate = data_rate; 804 - if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) { 805 - switch (data_rate) { 806 - case 250: 807 - fdc_set_write_precomp(250); 808 - break; 809 - default: 810 - case 500: 811 - fdc_set_write_precomp(125); 812 - break; 813 - case 1000: 814 - fdc_set_write_precomp(42); 815 - break; 816 - } 817 - } else { 818 - fdc_set_write_precomp(0); 819 - } 820 - TRACE_EXIT result; 821 - } 822 - 823 - /* The next two functions are used to cope with excessive overrun errors 824 - */ 825 - int ftape_increase_threshold(void) 826 - { 827 - TRACE_FUN(ft_t_flow); 828 - 829 - if (fdc.type < i82077 || ft_fdc_threshold >= 12) { 830 - TRACE_ABORT(-EIO, ft_t_err, "cannot increase fifo threshold"); 831 - } 832 - if (fdc_fifo_threshold(++ft_fdc_threshold, NULL, NULL, NULL) < 0) { 833 - TRACE(ft_t_err, "cannot increase fifo threshold"); 834 - ft_fdc_threshold --; 835 - fdc_reset(); 836 - } 837 - TRACE(ft_t_info, "New FIFO threshold: %d", ft_fdc_threshold); 838 - TRACE_EXIT 0; 839 - } 840 - 841 - int ftape_half_data_rate(void) 842 - { 843 - if (ft_data_rate < 500) { 844 - return -1; 845 - } 846 - if (ftape_set_data_rate(ft_data_rate / 2, ft_qic_std) < 0) { 847 - return -EIO; 848 - } 849 - ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len); 850 - return 0; 851 - } 852 - 853 - /* Seek the head to the specified track. 854 - */ 855 - int ftape_seek_head_to_track(unsigned int track) 856 - { 857 - int status; 858 - TRACE_FUN(ft_t_any); 859 - 860 - ft_location.track = -1; /* remains set in case of error */ 861 - if (track >= ft_tracks_per_tape) { 862 - TRACE_ABORT(-EINVAL, ft_t_bug, "track out of bounds"); 863 - } 864 - TRACE(ft_t_flow, "seeking track %d", track); 865 - TRACE_CATCH(ftape_command(QIC_SEEK_HEAD_TO_TRACK),); 866 - TRACE_CATCH(ftape_parameter_wait(track, ftape_timeout.head_seek, 867 - &status),); 868 - ft_location.track = track; 869 - ftape_might_be_off_track = 0; 870 - TRACE_EXIT 0; 871 - } 872 - 873 - int ftape_wakeup_drive(wake_up_types method) 874 - { 875 - int status; 876 - int motor_on = 0; 877 - TRACE_FUN(ft_t_any); 878 - 879 - switch (method) { 880 - case wake_up_colorado: 881 - TRACE_CATCH(ftape_command(QIC_PHANTOM_SELECT),); 882 - TRACE_CATCH(ftape_parameter(0 /* ft_drive_sel ?? */),); 883 - break; 884 - case wake_up_mountain: 885 - TRACE_CATCH(ftape_command(QIC_SOFT_SELECT),); 886 - ftape_sleep(FT_MILLISECOND); /* NEEDED */ 887 - TRACE_CATCH(ftape_parameter(18),); 888 - break; 889 - case wake_up_insight: 890 - ftape_sleep(100 * FT_MILLISECOND); 891 - motor_on = 1; 892 - fdc_motor(motor_on); /* enable is done by motor-on */ 893 - case no_wake_up: 894 - break; 895 - default: 896 - TRACE_EXIT -ENODEV; /* unknown wakeup method */ 897 - break; 898 - } 899 - /* If wakeup succeeded we shouldn't get an error here.. 900 - */ 901 - TRACE_CATCH(ftape_report_raw_drive_status(&status), 902 - if (motor_on) { 903 - fdc_motor(0); 904 - }); 905 - TRACE_EXIT 0; 906 - } 907 - 908 - int ftape_put_drive_to_sleep(wake_up_types method) 909 - { 910 - TRACE_FUN(ft_t_any); 911 - 912 - switch (method) { 913 - case wake_up_colorado: 914 - TRACE_CATCH(ftape_command(QIC_PHANTOM_DESELECT),); 915 - break; 916 - case wake_up_mountain: 917 - TRACE_CATCH(ftape_command(QIC_SOFT_DESELECT),); 918 - break; 919 - case wake_up_insight: 920 - fdc_motor(0); /* enable is done by motor-on */ 921 - case no_wake_up: /* no wakeup / no sleep ! */ 922 - break; 923 - default: 924 - TRACE_EXIT -ENODEV; /* unknown wakeup method */ 925 - } 926 - TRACE_EXIT 0; 927 - } 928 - 929 - int ftape_reset_drive(void) 930 - { 931 - int result = 0; 932 - int status; 933 - unsigned int err_code; 934 - qic117_cmd_t err_command; 935 - int i; 936 - TRACE_FUN(ft_t_any); 937 - 938 - /* We want to re-establish contact with our drive. Fire a 939 - * number of reset commands (single step pulses) and pray for 940 - * success. 941 - */ 942 - for (i = 0; i < 2; ++i) { 943 - TRACE(ft_t_flow, "Resetting fdc"); 944 - fdc_reset(); 945 - ftape_sleep(10 * FT_MILLISECOND); 946 - TRACE(ft_t_flow, "Reset command to drive"); 947 - result = ftape_command(QIC_RESET); 948 - if (result == 0) { 949 - ftape_sleep(1 * FT_SECOND); /* drive not 950 - * accessible 951 - * during 1 second 952 - */ 953 - TRACE(ft_t_flow, "Re-selecting drive"); 954 - 955 - /* Strange, the QIC-117 specs don't mention 956 - * this but the drive gets deselected after a 957 - * soft reset ! So we need to enable it 958 - * again. 959 - */ 960 - if (ftape_wakeup_drive(ft_drive_type.wake_up) < 0) { 961 - TRACE(ft_t_err, "Wakeup failed !"); 962 - } 963 - TRACE(ft_t_flow, "Waiting until drive gets ready"); 964 - result= ftape_ready_wait(ftape_timeout.reset, &status); 965 - if (result == 0 && (status & QIC_STATUS_ERROR)) { 966 - result = ftape_report_error(&err_code, 967 - &err_command, 1); 968 - if (result == 0 && err_code == 27) { 969 - /* Okay, drive saw reset 970 - * command and responded as it 971 - * should 972 - */ 973 - break; 974 - } else { 975 - result = -EIO; 976 - } 977 - } else { 978 - result = -EIO; 979 - } 980 - } 981 - FT_SIGNAL_EXIT(_DONT_BLOCK); 982 - } 983 - if (result != 0) { 984 - TRACE(ft_t_err, "General failure to reset tape drive"); 985 - } else { 986 - /* Restore correct settings: keep original rate 987 - */ 988 - ftape_set_data_rate(ft_data_rate, ft_qic_std); 989 - } 990 - ftape_init_drive_needed = 1; 991 - TRACE_EXIT result; 992 - }
-90
drivers/char/ftape/lowlevel/ftape-io.h
··· 1 - #ifndef _FTAPE_IO_H 2 - #define _FTAPE_IO_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven, 6 - * (C) 1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:18 $ 26 - * 27 - * This file contains definitions for the glue part of the 28 - * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. 29 - */ 30 - 31 - #include <linux/qic117.h> 32 - #include <linux/ftape-vendors.h> 33 - 34 - typedef struct { 35 - unsigned int seek; 36 - unsigned int reset; 37 - unsigned int rewind; 38 - unsigned int head_seek; 39 - unsigned int stop; 40 - unsigned int pause; 41 - } ft_timeout_table; 42 - 43 - typedef enum { 44 - prehistoric, pre_qic117c, post_qic117b, post_qic117d 45 - } qic_model; 46 - 47 - /* 48 - * ftape-io.c defined global vars. 49 - */ 50 - extern ft_timeout_table ftape_timeout; 51 - extern unsigned int ftape_tape_len; 52 - extern volatile qic117_cmd_t ftape_current_command; 53 - extern const struct qic117_command_table qic117_cmds[]; 54 - extern int ftape_might_be_off_track; 55 - 56 - /* 57 - * ftape-io.c defined global functions. 58 - */ 59 - extern void ftape_udelay(unsigned int usecs); 60 - extern void ftape_udelay_calibrate(void); 61 - extern void ftape_sleep(unsigned int time); 62 - extern void ftape_report_vendor_id(unsigned int *id); 63 - extern int ftape_command(qic117_cmd_t command); 64 - extern int ftape_command_wait(qic117_cmd_t command, 65 - unsigned int timeout, 66 - int *status); 67 - extern int ftape_parameter(unsigned int parameter); 68 - extern int ftape_report_operation(int *status, 69 - qic117_cmd_t command, 70 - int result_length); 71 - extern int ftape_report_configuration(qic_model *model, 72 - unsigned int *rate, 73 - int *qic_std, 74 - int *tape_len); 75 - extern int ftape_report_drive_status(int *status); 76 - extern int ftape_report_raw_drive_status(int *status); 77 - extern int ftape_report_status(int *status); 78 - extern int ftape_ready_wait(unsigned int timeout, int *status); 79 - extern int ftape_seek_head_to_track(unsigned int track); 80 - extern int ftape_set_data_rate(unsigned int new_rate, unsigned int qic_std); 81 - extern int ftape_report_error(unsigned int *error, 82 - qic117_cmd_t *command, 83 - int report); 84 - extern int ftape_reset_drive(void); 85 - extern int ftape_put_drive_to_sleep(wake_up_types method); 86 - extern int ftape_wakeup_drive(wake_up_types method); 87 - extern int ftape_increase_threshold(void); 88 - extern int ftape_half_data_rate(void); 89 - 90 - #endif
-214
drivers/char/ftape/lowlevel/ftape-proc.c
··· 1 - /* 2 - * Copyright (C) 1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-proc.c,v $ 20 - * $Revision: 1.11 $ 21 - * $Date: 1997/10/24 14:47:37 $ 22 - * 23 - * This file contains the procfs interface for the 24 - * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. 25 - 26 - * Old code removed, switched to dynamic proc entry. 27 - */ 28 - 29 - 30 - #if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) 31 - 32 - #include <linux/proc_fs.h> 33 - 34 - #include <linux/ftape.h> 35 - #include <linux/init.h> 36 - #include <linux/qic117.h> 37 - 38 - #include "../lowlevel/ftape-io.h" 39 - #include "../lowlevel/ftape-ctl.h" 40 - #include "../lowlevel/ftape-proc.h" 41 - #include "../lowlevel/ftape-tracing.h" 42 - 43 - static size_t get_driver_info(char *buf) 44 - { 45 - const char *debug_level[] = { "bugs" , 46 - "errors", 47 - "warnings", 48 - "informational", 49 - "noisy", 50 - "program flow", 51 - "fdc and dma", 52 - "data flow", 53 - "anything" }; 54 - 55 - return sprintf(buf, 56 - "version : %s\n" 57 - "used data rate: %d kbit/sec\n" 58 - "dma memory : %d kb\n" 59 - "debug messages: %s\n", 60 - FTAPE_VERSION, 61 - ft_data_rate, 62 - FT_BUFF_SIZE * ft_nr_buffers >> 10, 63 - debug_level[TRACE_LEVEL]); 64 - } 65 - 66 - static size_t get_tapedrive_info(char *buf) 67 - { 68 - return sprintf(buf, 69 - "vendor id : 0x%04x\n" 70 - "drive name: %s\n" 71 - "wind speed: %d ips\n" 72 - "wakeup : %s\n" 73 - "max. rate : %d kbit/sec\n", 74 - ft_drive_type.vendor_id, 75 - ft_drive_type.name, 76 - ft_drive_type.speed, 77 - ((ft_drive_type.wake_up == no_wake_up) 78 - ? "No wakeup needed" : 79 - ((ft_drive_type.wake_up == wake_up_colorado) 80 - ? "Colorado" : 81 - ((ft_drive_type.wake_up == wake_up_mountain) 82 - ? "Mountain" : 83 - ((ft_drive_type.wake_up == wake_up_insight) 84 - ? "Motor on" : 85 - "Unknown")))), 86 - ft_drive_max_rate); 87 - } 88 - 89 - static size_t get_cartridge_info(char *buf) 90 - { 91 - if (ftape_init_drive_needed) { 92 - return sprintf(buf, "uninitialized\n"); 93 - } 94 - if (ft_no_tape) { 95 - return sprintf(buf, "no cartridge inserted\n"); 96 - } 97 - return sprintf(buf, 98 - "segments : %5d\n" 99 - "tracks : %5d\n" 100 - "length : %5dft\n" 101 - "formatted : %3s\n" 102 - "writable : %3s\n" 103 - "QIC spec. : QIC-%s\n" 104 - "fmt-code : %1d\n", 105 - ft_segments_per_track, 106 - ft_tracks_per_tape, 107 - ftape_tape_len, 108 - (ft_formatted == 1) ? "yes" : "no", 109 - (ft_write_protected == 1) ? "no" : "yes", 110 - ((ft_qic_std == QIC_TAPE_QIC40) ? "40" : 111 - ((ft_qic_std == QIC_TAPE_QIC80) ? "80" : 112 - ((ft_qic_std == QIC_TAPE_QIC3010) ? "3010" : 113 - ((ft_qic_std == QIC_TAPE_QIC3020) ? "3020" : 114 - "???")))), 115 - ft_format_code); 116 - } 117 - 118 - static size_t get_controller_info(char *buf) 119 - { 120 - const char *fdc_name[] = { "no fdc", 121 - "i8272", 122 - "i82077", 123 - "i82077AA", 124 - "Colorado FC-10 or FC-20", 125 - "i82078", 126 - "i82078_1" }; 127 - 128 - return sprintf(buf, 129 - "FDC type : %s\n" 130 - "FDC base : 0x%03x\n" 131 - "FDC irq : %d\n" 132 - "FDC dma : %d\n" 133 - "FDC thr. : %d\n" 134 - "max. rate : %d kbit/sec\n", 135 - ft_mach2 ? "Mountain MACH-2" : fdc_name[fdc.type], 136 - fdc.sra, fdc.irq, fdc.dma, 137 - ft_fdc_threshold, ft_fdc_max_rate); 138 - } 139 - 140 - static size_t get_history_info(char *buf) 141 - { 142 - size_t len; 143 - 144 - len = sprintf(buf, 145 - "\nFDC isr statistics\n" 146 - " id_am_errors : %3d\n" 147 - " id_crc_errors : %3d\n" 148 - " data_am_errors : %3d\n" 149 - " data_crc_errors : %3d\n" 150 - " overrun_errors : %3d\n" 151 - " no_data_errors : %3d\n" 152 - " retries : %3d\n", 153 - ft_history.id_am_errors, ft_history.id_crc_errors, 154 - ft_history.data_am_errors, ft_history.data_crc_errors, 155 - ft_history.overrun_errors, ft_history.no_data_errors, 156 - ft_history.retries); 157 - len += sprintf(buf + len, 158 - "\nECC statistics\n" 159 - " crc_errors : %3d\n" 160 - " crc_failures : %3d\n" 161 - " ecc_failures : %3d\n" 162 - " sectors corrected: %3d\n", 163 - ft_history.crc_errors, ft_history.crc_failures, 164 - ft_history.ecc_failures, ft_history.corrected); 165 - len += sprintf(buf + len, 166 - "\ntape quality statistics\n" 167 - " media defects : %3d\n", 168 - ft_history.defects); 169 - len += sprintf(buf + len, 170 - "\ntape motion statistics\n" 171 - " repositions : %3d\n", 172 - ft_history.rewinds); 173 - return len; 174 - } 175 - 176 - static int ftape_read_proc(char *page, char **start, off_t off, 177 - int count, int *eof, void *data) 178 - { 179 - char *ptr = page; 180 - size_t len; 181 - 182 - ptr += sprintf(ptr, "Kernel Driver\n\n"); 183 - ptr += get_driver_info(ptr); 184 - ptr += sprintf(ptr, "\nTape Drive\n\n"); 185 - ptr += get_tapedrive_info(ptr); 186 - ptr += sprintf(ptr, "\nFDC Controller\n\n"); 187 - ptr += get_controller_info(ptr); 188 - ptr += sprintf(ptr, "\nTape Cartridge\n\n"); 189 - ptr += get_cartridge_info(ptr); 190 - ptr += sprintf(ptr, "\nHistory Record\n\n"); 191 - ptr += get_history_info(ptr); 192 - 193 - len = strlen(page); 194 - *start = NULL; 195 - if (off+count >= len) { 196 - *eof = 1; 197 - } else { 198 - *eof = 0; 199 - } 200 - return len; 201 - } 202 - 203 - int __init ftape_proc_init(void) 204 - { 205 - return create_proc_read_entry("ftape", 0, &proc_root, 206 - ftape_read_proc, NULL) != NULL; 207 - } 208 - 209 - void ftape_proc_destroy(void) 210 - { 211 - remove_proc_entry("ftape", &proc_root); 212 - } 213 - 214 - #endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) */
-35
drivers/char/ftape/lowlevel/ftape-proc.h
··· 1 - #ifndef _FTAPE_PROC_H 2 - #define _FTAPE_PROC_H 3 - 4 - /* 5 - * Copyright (C) 1997 Claus-Justus Heine 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-proc.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:18:20 $ 25 - * 26 - * This file contains definitions for the procfs interface of the 27 - * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. 28 - */ 29 - 30 - #include <linux/proc_fs.h> 31 - 32 - extern int ftape_proc_init(void); 33 - extern void ftape_proc_destroy(void); 34 - 35 - #endif
-621
drivers/char/ftape/lowlevel/ftape-read.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven, 3 - * (C) 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.c,v $ 21 - * $Revision: 1.6 $ 22 - * $Date: 1997/10/21 14:39:22 $ 23 - * 24 - * This file contains the reading code 25 - * for the QIC-117 floppy-tape driver for Linux. 26 - * 27 - */ 28 - 29 - #include <linux/string.h> 30 - #include <linux/errno.h> 31 - #include <linux/mm.h> 32 - 33 - #include <linux/ftape.h> 34 - #include <linux/qic117.h> 35 - #include "../lowlevel/ftape-tracing.h" 36 - #include "../lowlevel/ftape-read.h" 37 - #include "../lowlevel/ftape-io.h" 38 - #include "../lowlevel/ftape-ctl.h" 39 - #include "../lowlevel/ftape-rw.h" 40 - #include "../lowlevel/ftape-write.h" 41 - #include "../lowlevel/ftape-ecc.h" 42 - #include "../lowlevel/ftape-bsm.h" 43 - 44 - /* Global vars. 45 - */ 46 - 47 - /* Local vars. 48 - */ 49 - 50 - void ftape_zap_read_buffers(void) 51 - { 52 - int i; 53 - 54 - for (i = 0; i < ft_nr_buffers; ++i) { 55 - /* changed to "fit" with dynamic allocation of tape_buffer. --khp */ 56 - ft_buffer[i]->status = waiting; 57 - ft_buffer[i]->bytes = 0; 58 - ft_buffer[i]->skip = 0; 59 - ft_buffer[i]->retry = 0; 60 - } 61 - /* ftape_reset_buffer(); */ 62 - } 63 - 64 - static SectorMap convert_sector_map(buffer_struct * buff) 65 - { 66 - int i = 0; 67 - SectorMap bad_map = ftape_get_bad_sector_entry(buff->segment_id); 68 - SectorMap src_map = buff->soft_error_map | buff->hard_error_map; 69 - SectorMap dst_map = 0; 70 - TRACE_FUN(ft_t_any); 71 - 72 - if (bad_map || src_map) { 73 - TRACE(ft_t_flow, "bad_map = 0x%08lx", (long) bad_map); 74 - TRACE(ft_t_flow, "src_map = 0x%08lx", (long) src_map); 75 - } 76 - while (bad_map) { 77 - while ((bad_map & 1) == 0) { 78 - if (src_map & 1) { 79 - dst_map |= (1 << i); 80 - } 81 - src_map >>= 1; 82 - bad_map >>= 1; 83 - ++i; 84 - } 85 - /* (bad_map & 1) == 1 */ 86 - src_map >>= 1; 87 - bad_map >>= 1; 88 - } 89 - if (src_map) { 90 - dst_map |= (src_map << i); 91 - } 92 - if (dst_map) { 93 - TRACE(ft_t_flow, "dst_map = 0x%08lx", (long) dst_map); 94 - } 95 - TRACE_EXIT dst_map; 96 - } 97 - 98 - static int correct_and_copy_fraction(buffer_struct *buff, __u8 * destination, 99 - int start, int size) 100 - { 101 - struct memory_segment mseg; 102 - int result; 103 - SectorMap read_bad; 104 - TRACE_FUN(ft_t_any); 105 - 106 - mseg.read_bad = convert_sector_map(buff); 107 - mseg.marked_bad = 0; /* not used... */ 108 - mseg.blocks = buff->bytes / FT_SECTOR_SIZE; 109 - mseg.data = buff->address; 110 - /* If there are no data sectors we can skip this segment. 111 - */ 112 - if (mseg.blocks <= 3) { 113 - TRACE_ABORT(0, ft_t_noise, "empty segment"); 114 - } 115 - read_bad = mseg.read_bad; 116 - ft_history.crc_errors += count_ones(read_bad); 117 - result = ftape_ecc_correct_data(&mseg); 118 - if (read_bad != 0 || mseg.corrected != 0) { 119 - TRACE(ft_t_noise, "crc error map: 0x%08lx", (unsigned long)read_bad); 120 - TRACE(ft_t_noise, "corrected map: 0x%08lx", (unsigned long)mseg.corrected); 121 - ft_history.corrected += count_ones(mseg.corrected); 122 - } 123 - if (result == ECC_CORRECTED || result == ECC_OK) { 124 - if (result == ECC_CORRECTED) { 125 - TRACE(ft_t_info, "ecc corrected segment: %d", buff->segment_id); 126 - } 127 - if(start < 0) { 128 - start= 0; 129 - } 130 - if((start+size) > ((mseg.blocks - 3) * FT_SECTOR_SIZE)) { 131 - size = (mseg.blocks - 3) * FT_SECTOR_SIZE - start; 132 - } 133 - if (size < 0) { 134 - size= 0; 135 - } 136 - if(size > 0) { 137 - memcpy(destination + start, mseg.data + start, size); 138 - } 139 - if ((read_bad ^ mseg.corrected) & mseg.corrected) { 140 - /* sectors corrected without crc errors set */ 141 - ft_history.crc_failures++; 142 - } 143 - TRACE_EXIT size; /* (mseg.blocks - 3) * FT_SECTOR_SIZE; */ 144 - } else { 145 - ft_history.ecc_failures++; 146 - TRACE_ABORT(-EAGAIN, 147 - ft_t_err, "ecc failure on segment %d", 148 - buff->segment_id); 149 - } 150 - TRACE_EXIT 0; 151 - } 152 - 153 - /* Read given segment into buffer at address. 154 - */ 155 - int ftape_read_segment_fraction(const int segment_id, 156 - void *address, 157 - const ft_read_mode_t read_mode, 158 - const int start, 159 - const int size) 160 - { 161 - int result = 0; 162 - int retry = 0; 163 - int bytes_read = 0; 164 - int read_done = 0; 165 - TRACE_FUN(ft_t_flow); 166 - 167 - ft_history.used |= 1; 168 - TRACE(ft_t_data_flow, "segment_id = %d", segment_id); 169 - if (ft_driver_state != reading) { 170 - TRACE(ft_t_noise, "calling ftape_abort_operation"); 171 - TRACE_CATCH(ftape_abort_operation(),); 172 - ftape_set_state(reading); 173 - } 174 - for(;;) { 175 - buffer_struct *tail; 176 - /* Allow escape from this loop on signal ! 177 - */ 178 - FT_SIGNAL_EXIT(_DONT_BLOCK); 179 - /* Search all full buffers for the first matching the 180 - * wanted segment. Clear other buffers on the fly. 181 - */ 182 - tail = ftape_get_buffer(ft_queue_tail); 183 - while (!read_done && tail->status == done) { 184 - /* Allow escape from this loop on signal ! 185 - */ 186 - FT_SIGNAL_EXIT(_DONT_BLOCK); 187 - if (tail->segment_id == segment_id) { 188 - /* If out buffer is already full, 189 - * return its contents. 190 - */ 191 - TRACE(ft_t_flow, "found segment in cache: %d", 192 - segment_id); 193 - if (tail->deleted) { 194 - /* Return a value that 195 - * read_header_segment 196 - * understands. As this 197 - * should only occur when 198 - * searching for the header 199 - * segments it shouldn't be 200 - * misinterpreted elsewhere. 201 - */ 202 - TRACE_EXIT 0; 203 - } 204 - result = correct_and_copy_fraction( 205 - tail, 206 - address, 207 - start, 208 - size); 209 - TRACE(ft_t_flow, "segment contains (bytes): %d", 210 - result); 211 - if (result < 0) { 212 - if (result != -EAGAIN) { 213 - TRACE_EXIT result; 214 - } 215 - /* keep read_done == 0, will 216 - * trigger 217 - * ftape_abort_operation 218 - * because reading wrong 219 - * segment. 220 - */ 221 - TRACE(ft_t_err, "ecc failed, retry"); 222 - ++retry; 223 - } else { 224 - read_done = 1; 225 - bytes_read = result; 226 - } 227 - } else { 228 - TRACE(ft_t_flow,"zapping segment in cache: %d", 229 - tail->segment_id); 230 - } 231 - tail->status = waiting; 232 - tail = ftape_next_buffer(ft_queue_tail); 233 - } 234 - if (!read_done && tail->status == reading) { 235 - if (tail->segment_id == segment_id) { 236 - switch(ftape_wait_segment(reading)) { 237 - case 0: 238 - break; 239 - case -EINTR: 240 - TRACE_ABORT(-EINTR, ft_t_warn, 241 - "interrupted by " 242 - "non-blockable signal"); 243 - break; 244 - default: 245 - TRACE(ft_t_noise, 246 - "wait_segment failed"); 247 - ftape_abort_operation(); 248 - ftape_set_state(reading); 249 - break; 250 - } 251 - } else { 252 - /* We're reading the wrong segment, 253 - * stop runner. 254 - */ 255 - TRACE(ft_t_noise, "reading wrong segment"); 256 - ftape_abort_operation(); 257 - ftape_set_state(reading); 258 - } 259 - } 260 - /* should runner stop ? 261 - */ 262 - if (ft_runner_status == aborting) { 263 - buffer_struct *head = ftape_get_buffer(ft_queue_head); 264 - switch(head->status) { 265 - case error: 266 - ft_history.defects += 267 - count_ones(head->hard_error_map); 268 - case reading: 269 - head->status = waiting; 270 - break; 271 - default: 272 - break; 273 - } 274 - TRACE_CATCH(ftape_dumb_stop(),); 275 - } else { 276 - /* If just passed last segment on tape: wait 277 - * for BOT or EOT mark. Sets ft_runner_status to 278 - * idle if at lEOT and successful 279 - */ 280 - TRACE_CATCH(ftape_handle_logical_eot(),); 281 - } 282 - /* If we got a segment: quit, or else retry up to limit. 283 - * 284 - * If segment to read is empty, do not start runner for it, 285 - * but wait for next read call. 286 - */ 287 - if (read_done || 288 - ftape_get_bad_sector_entry(segment_id) == EMPTY_SEGMENT ) { 289 - /* bytes_read = 0; should still be zero */ 290 - TRACE_EXIT bytes_read; 291 - 292 - } 293 - if (retry > FT_RETRIES_ON_ECC_ERROR) { 294 - ft_history.defects++; 295 - TRACE_ABORT(-ENODATA, ft_t_err, 296 - "too many retries on ecc failure"); 297 - } 298 - /* Now at least one buffer is empty ! 299 - * Restart runner & tape if needed. 300 - */ 301 - TRACE(ft_t_any, "head: %d, tail: %d, ft_runner_status: %d", 302 - ftape_buffer_id(ft_queue_head), 303 - ftape_buffer_id(ft_queue_tail), 304 - ft_runner_status); 305 - TRACE(ft_t_any, "buffer[].status, [head]: %d, [tail]: %d", 306 - ftape_get_buffer(ft_queue_head)->status, 307 - ftape_get_buffer(ft_queue_tail)->status); 308 - tail = ftape_get_buffer(ft_queue_tail); 309 - if (tail->status == waiting) { 310 - buffer_struct *head = ftape_get_buffer(ft_queue_head); 311 - 312 - ftape_setup_new_segment(head, segment_id, -1); 313 - if (read_mode == FT_RD_SINGLE) { 314 - /* disable read-ahead */ 315 - head->next_segment = 0; 316 - } 317 - ftape_calc_next_cluster(head); 318 - if (ft_runner_status == idle) { 319 - result = ftape_start_tape(segment_id, 320 - head->sector_offset); 321 - if (result < 0) { 322 - TRACE_ABORT(result, ft_t_err, "Error: " 323 - "segment %d unreachable", 324 - segment_id); 325 - } 326 - } 327 - head->status = reading; 328 - fdc_setup_read_write(head, FDC_READ); 329 - } 330 - } 331 - /* not reached */ 332 - TRACE_EXIT -EIO; 333 - } 334 - 335 - int ftape_read_header_segment(__u8 *address) 336 - { 337 - int result; 338 - int header_segment; 339 - int first_failed = 0; 340 - int status; 341 - TRACE_FUN(ft_t_flow); 342 - 343 - ft_used_header_segment = -1; 344 - TRACE_CATCH(ftape_report_drive_status(&status),); 345 - TRACE(ft_t_flow, "reading..."); 346 - /* We're looking for the first header segment. 347 - * A header segment cannot contain bad sectors, therefor at the 348 - * tape start, segments with bad sectors are (according to QIC-40/80) 349 - * written with deleted data marks and must be skipped. 350 - */ 351 - memset(address, '\0', (FT_SECTORS_PER_SEGMENT - 3) * FT_SECTOR_SIZE); 352 - result = 0; 353 - #define HEADER_SEGMENT_BOUNDARY 68 /* why not 42? */ 354 - for (header_segment = 0; 355 - header_segment < HEADER_SEGMENT_BOUNDARY && result == 0; 356 - ++header_segment) { 357 - /* Set no read-ahead, the isr will force read-ahead whenever 358 - * it encounters deleted data ! 359 - */ 360 - result = ftape_read_segment(header_segment, 361 - address, 362 - FT_RD_SINGLE); 363 - if (result < 0 && !first_failed) { 364 - TRACE(ft_t_err, "header segment damaged, trying backup"); 365 - first_failed = 1; 366 - result = 0; /* force read of next (backup) segment */ 367 - } 368 - } 369 - if (result < 0 || header_segment >= HEADER_SEGMENT_BOUNDARY) { 370 - TRACE_ABORT(-EIO, ft_t_err, 371 - "no readable header segment found"); 372 - } 373 - TRACE_CATCH(ftape_abort_operation(),); 374 - ft_used_header_segment = header_segment; 375 - result = ftape_decode_header_segment(address); 376 - TRACE_EXIT result; 377 - } 378 - 379 - int ftape_decode_header_segment(__u8 *address) 380 - { 381 - unsigned int max_floppy_side; 382 - unsigned int max_floppy_track; 383 - unsigned int max_floppy_sector; 384 - unsigned int new_tape_len; 385 - TRACE_FUN(ft_t_flow); 386 - 387 - if (GET4(address, FT_SIGNATURE) == FT_D2G_MAGIC) { 388 - /* Ditto 2GB header segment. They encrypt the bad sector map. 389 - * We decrypt it and store them in normal format. 390 - * I hope this is correct. 391 - */ 392 - int i; 393 - TRACE(ft_t_warn, 394 - "Found Ditto 2GB tape, " 395 - "trying to decrypt bad sector map"); 396 - for (i=256; i < 29 * FT_SECTOR_SIZE; i++) { 397 - address[i] = ~(address[i] - (i&0xff)); 398 - } 399 - PUT4(address, 0,FT_HSEG_MAGIC); 400 - } else if (GET4(address, FT_SIGNATURE) != FT_HSEG_MAGIC) { 401 - TRACE_ABORT(-EIO, ft_t_err, 402 - "wrong signature in header segment"); 403 - } 404 - ft_format_code = (ft_format_type) address[FT_FMT_CODE]; 405 - if (ft_format_code != fmt_big) { 406 - ft_header_segment_1 = GET2(address, FT_HSEG_1); 407 - ft_header_segment_2 = GET2(address, FT_HSEG_2); 408 - ft_first_data_segment = GET2(address, FT_FRST_SEG); 409 - ft_last_data_segment = GET2(address, FT_LAST_SEG); 410 - } else { 411 - ft_header_segment_1 = GET4(address, FT_6_HSEG_1); 412 - ft_header_segment_2 = GET4(address, FT_6_HSEG_2); 413 - ft_first_data_segment = GET4(address, FT_6_FRST_SEG); 414 - ft_last_data_segment = GET4(address, FT_6_LAST_SEG); 415 - } 416 - TRACE(ft_t_noise, "first data segment: %d", ft_first_data_segment); 417 - TRACE(ft_t_noise, "last data segment: %d", ft_last_data_segment); 418 - TRACE(ft_t_noise, "header segments are %d and %d", 419 - ft_header_segment_1, ft_header_segment_2); 420 - 421 - /* Verify tape parameters... 422 - * QIC-40/80 spec: tape_parameters: 423 - * 424 - * segments-per-track segments_per_track 425 - * tracks-per-cartridge tracks_per_tape 426 - * max-floppy-side (segments_per_track * 427 - * tracks_per_tape - 1) / 428 - * ftape_segments_per_head 429 - * max-floppy-track ftape_segments_per_head / 430 - * ftape_segments_per_cylinder - 1 431 - * max-floppy-sector ftape_segments_per_cylinder * 432 - * FT_SECTORS_PER_SEGMENT 433 - */ 434 - ft_segments_per_track = GET2(address, FT_SPT); 435 - ft_tracks_per_tape = address[FT_TPC]; 436 - max_floppy_side = address[FT_FHM]; 437 - max_floppy_track = address[FT_FTM]; 438 - max_floppy_sector = address[FT_FSM]; 439 - TRACE(ft_t_noise, "(fmt/spt/tpc/fhm/ftm/fsm) = %d/%d/%d/%d/%d/%d", 440 - ft_format_code, ft_segments_per_track, ft_tracks_per_tape, 441 - max_floppy_side, max_floppy_track, max_floppy_sector); 442 - new_tape_len = ftape_tape_len; 443 - switch (ft_format_code) { 444 - case fmt_425ft: 445 - new_tape_len = 425; 446 - break; 447 - case fmt_normal: 448 - if (ftape_tape_len == 0) { /* otherwise 307 ft */ 449 - new_tape_len = 205; 450 - } 451 - break; 452 - case fmt_1100ft: 453 - new_tape_len = 1100; 454 - break; 455 - case fmt_var:{ 456 - int segments_per_1000_inch = 1; /* non-zero default for switch */ 457 - switch (ft_qic_std) { 458 - case QIC_TAPE_QIC40: 459 - segments_per_1000_inch = 332; 460 - break; 461 - case QIC_TAPE_QIC80: 462 - segments_per_1000_inch = 488; 463 - break; 464 - case QIC_TAPE_QIC3010: 465 - segments_per_1000_inch = 730; 466 - break; 467 - case QIC_TAPE_QIC3020: 468 - segments_per_1000_inch = 1430; 469 - break; 470 - } 471 - new_tape_len = (1000 * ft_segments_per_track + 472 - (segments_per_1000_inch - 1)) / segments_per_1000_inch; 473 - break; 474 - } 475 - case fmt_big:{ 476 - int segments_per_1000_inch = 1; /* non-zero default for switch */ 477 - switch (ft_qic_std) { 478 - case QIC_TAPE_QIC40: 479 - segments_per_1000_inch = 332; 480 - break; 481 - case QIC_TAPE_QIC80: 482 - segments_per_1000_inch = 488; 483 - break; 484 - case QIC_TAPE_QIC3010: 485 - segments_per_1000_inch = 730; 486 - break; 487 - case QIC_TAPE_QIC3020: 488 - segments_per_1000_inch = 1430; 489 - break; 490 - default: 491 - TRACE_ABORT(-EIO, ft_t_bug, 492 - "%x QIC-standard with fmt-code %d, please report", 493 - ft_qic_std, ft_format_code); 494 - } 495 - new_tape_len = ((1000 * ft_segments_per_track + 496 - (segments_per_1000_inch - 1)) / 497 - segments_per_1000_inch); 498 - break; 499 - } 500 - default: 501 - TRACE_ABORT(-EIO, ft_t_err, 502 - "unknown tape format, please report !"); 503 - } 504 - if (new_tape_len != ftape_tape_len) { 505 - ftape_tape_len = new_tape_len; 506 - TRACE(ft_t_info, "calculated tape length is %d ft", 507 - ftape_tape_len); 508 - ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len); 509 - } 510 - if (ft_segments_per_track == 0 && ft_tracks_per_tape == 0 && 511 - max_floppy_side == 0 && max_floppy_track == 0 && 512 - max_floppy_sector == 0) { 513 - /* QIC-40 Rev E and earlier has no values in the header. 514 - */ 515 - ft_segments_per_track = 68; 516 - ft_tracks_per_tape = 20; 517 - max_floppy_side = 1; 518 - max_floppy_track = 169; 519 - max_floppy_sector = 128; 520 - } 521 - /* This test will compensate for the wrong parameter on tapes 522 - * formatted by Conner software. 523 - */ 524 - if (ft_segments_per_track == 150 && 525 - ft_tracks_per_tape == 28 && 526 - max_floppy_side == 7 && 527 - max_floppy_track == 149 && 528 - max_floppy_sector == 128) { 529 - TRACE(ft_t_info, "the famous CONNER bug: max_floppy_side off by one !"); 530 - max_floppy_side = 6; 531 - } 532 - /* These tests will compensate for the wrong parameter on tapes 533 - * formatted by ComByte Windows software. 534 - * 535 - * First, for 205 foot tapes 536 - */ 537 - if (ft_segments_per_track == 100 && 538 - ft_tracks_per_tape == 28 && 539 - max_floppy_side == 9 && 540 - max_floppy_track == 149 && 541 - max_floppy_sector == 128) { 542 - TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!"); 543 - max_floppy_side = 4; 544 - } 545 - /* Next, for 307 foot tapes. */ 546 - if (ft_segments_per_track == 150 && 547 - ft_tracks_per_tape == 28 && 548 - max_floppy_side == 9 && 549 - max_floppy_track == 149 && 550 - max_floppy_sector == 128) { 551 - TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!"); 552 - max_floppy_side = 6; 553 - } 554 - /* This test will compensate for the wrong parameter on tapes 555 - * formatted by Colorado Windows software. 556 - */ 557 - if (ft_segments_per_track == 150 && 558 - ft_tracks_per_tape == 28 && 559 - max_floppy_side == 6 && 560 - max_floppy_track == 150 && 561 - max_floppy_sector == 128) { 562 - TRACE(ft_t_info, "the famous Colorado bug: max_floppy_track off by one !"); 563 - max_floppy_track = 149; 564 - } 565 - ftape_segments_per_head = ((max_floppy_sector/FT_SECTORS_PER_SEGMENT) * 566 - (max_floppy_track + 1)); 567 - /* This test will compensate for some bug reported by Dima 568 - * Brodsky. Seems to be a Colorado bug, either. (freebee 569 - * Imation tape shipped together with Colorado T3000 570 - */ 571 - if ((ft_format_code == fmt_var || ft_format_code == fmt_big) && 572 - ft_tracks_per_tape == 50 && 573 - max_floppy_side == 54 && 574 - max_floppy_track == 255 && 575 - max_floppy_sector == 128) { 576 - TRACE(ft_t_info, "the famous ??? bug: max_floppy_track off by one !"); 577 - max_floppy_track = 254; 578 - } 579 - /* 580 - * Verify drive_configuration with tape parameters 581 - */ 582 - if (ftape_segments_per_head == 0 || ftape_segments_per_cylinder == 0 || 583 - ((ft_segments_per_track * ft_tracks_per_tape - 1) / ftape_segments_per_head 584 - != max_floppy_side) || 585 - (ftape_segments_per_head / ftape_segments_per_cylinder - 1 != max_floppy_track) || 586 - (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT != max_floppy_sector) 587 - #ifdef TESTING 588 - || ((ft_format_code == fmt_var || ft_format_code == fmt_big) && 589 - (max_floppy_track != 254 || max_floppy_sector != 128)) 590 - #endif 591 - ) { 592 - char segperheadz = ftape_segments_per_head ? ' ' : '?'; 593 - char segpercylz = ftape_segments_per_cylinder ? ' ' : '?'; 594 - TRACE(ft_t_err,"Tape parameters inconsistency, please report"); 595 - TRACE(ft_t_err, "reported = %d/%d/%d/%d/%d/%d", 596 - ft_format_code, 597 - ft_segments_per_track, 598 - ft_tracks_per_tape, 599 - max_floppy_side, 600 - max_floppy_track, 601 - max_floppy_sector); 602 - TRACE(ft_t_err, "required = %d/%d/%d/%d%c/%d%c/%d", 603 - ft_format_code, 604 - ft_segments_per_track, 605 - ft_tracks_per_tape, 606 - ftape_segments_per_head ? 607 - ((ft_segments_per_track * ft_tracks_per_tape -1) / 608 - ftape_segments_per_head ) : 609 - (ft_segments_per_track * ft_tracks_per_tape -1), 610 - segperheadz, 611 - ftape_segments_per_cylinder ? 612 - (ftape_segments_per_head / 613 - ftape_segments_per_cylinder - 1 ) : 614 - ftape_segments_per_head - 1, 615 - segpercylz, 616 - (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT)); 617 - TRACE_EXIT -EIO; 618 - } 619 - ftape_extract_bad_sector_map(address); 620 - TRACE_EXIT 0; 621 - }
-51
drivers/char/ftape/lowlevel/ftape-read.h
··· 1 - #ifndef _FTAPE_READ_H 2 - #define _FTAPE_READ_H 3 - 4 - /* 5 - * Copyright (C) 1994-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:22 $ 26 - * 27 - * This file contains the definitions for the read functions 28 - * for the QIC-117 floppy-tape driver for Linux. 29 - * 30 - */ 31 - 32 - /* ftape-read.c defined global functions. 33 - */ 34 - typedef enum { 35 - FT_RD_SINGLE = 0, 36 - FT_RD_AHEAD = 1, 37 - } ft_read_mode_t; 38 - 39 - extern int ftape_read_header_segment(__u8 *address); 40 - extern int ftape_decode_header_segment(__u8 *address); 41 - extern int ftape_read_segment_fraction(const int segment, 42 - void *address, 43 - const ft_read_mode_t read_mode, 44 - const int start, 45 - const int size); 46 - #define ftape_read_segment(segment, address, read_mode) \ 47 - ftape_read_segment_fraction(segment, address, read_mode, \ 48 - 0, FT_SEGMENT_SIZE) 49 - extern void ftape_zap_read_buffers(void); 50 - 51 - #endif /* _FTAPE_READ_H */
-1092
drivers/char/ftape/lowlevel/ftape-rw.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven, 3 - * (C) 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-rw.c,v $ 21 - * $Revision: 1.7 $ 22 - * $Date: 1997/10/28 14:26:49 $ 23 - * 24 - * This file contains some common code for the segment read and 25 - * segment write routines for the QIC-117 floppy-tape driver for 26 - * Linux. 27 - */ 28 - 29 - #include <linux/string.h> 30 - #include <linux/errno.h> 31 - 32 - #include <linux/ftape.h> 33 - #include <linux/qic117.h> 34 - #include "../lowlevel/ftape-tracing.h" 35 - #include "../lowlevel/ftape-rw.h" 36 - #include "../lowlevel/fdc-io.h" 37 - #include "../lowlevel/ftape-init.h" 38 - #include "../lowlevel/ftape-io.h" 39 - #include "../lowlevel/ftape-ctl.h" 40 - #include "../lowlevel/ftape-read.h" 41 - #include "../lowlevel/ftape-ecc.h" 42 - #include "../lowlevel/ftape-bsm.h" 43 - 44 - /* Global vars. 45 - */ 46 - int ft_nr_buffers; 47 - buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS]; 48 - static volatile int ft_head; 49 - static volatile int ft_tail; /* not volatile but need same type as head */ 50 - int fdc_setup_error; 51 - location_record ft_location = {-1, 0}; 52 - volatile int ftape_tape_running; 53 - 54 - /* Local vars. 55 - */ 56 - static int overrun_count_offset; 57 - static int inhibit_correction; 58 - 59 - /* maxmimal allowed overshoot when fast seeking 60 - */ 61 - #define OVERSHOOT_LIMIT 10 62 - 63 - /* Increment cyclic buffer nr. 64 - */ 65 - buffer_struct *ftape_next_buffer(ft_buffer_queue_t pos) 66 - { 67 - switch (pos) { 68 - case ft_queue_head: 69 - if (++ft_head >= ft_nr_buffers) { 70 - ft_head = 0; 71 - } 72 - return ft_buffer[ft_head]; 73 - case ft_queue_tail: 74 - if (++ft_tail >= ft_nr_buffers) { 75 - ft_tail = 0; 76 - } 77 - return ft_buffer[ft_tail]; 78 - default: 79 - return NULL; 80 - } 81 - } 82 - int ftape_buffer_id(ft_buffer_queue_t pos) 83 - { 84 - switch(pos) { 85 - case ft_queue_head: return ft_head; 86 - case ft_queue_tail: return ft_tail; 87 - default: return -1; 88 - } 89 - } 90 - buffer_struct *ftape_get_buffer(ft_buffer_queue_t pos) 91 - { 92 - switch(pos) { 93 - case ft_queue_head: return ft_buffer[ft_head]; 94 - case ft_queue_tail: return ft_buffer[ft_tail]; 95 - default: return NULL; 96 - } 97 - } 98 - void ftape_reset_buffer(void) 99 - { 100 - ft_head = ft_tail = 0; 101 - } 102 - 103 - buffer_state_enum ftape_set_state(buffer_state_enum new_state) 104 - { 105 - buffer_state_enum old_state = ft_driver_state; 106 - 107 - ft_driver_state = new_state; 108 - return old_state; 109 - } 110 - /* Calculate Floppy Disk Controller and DMA parameters for a segment. 111 - * head: selects buffer struct in array. 112 - * offset: number of physical sectors to skip (including bad ones). 113 - * count: number of physical sectors to handle (including bad ones). 114 - */ 115 - static int setup_segment(buffer_struct * buff, 116 - int segment_id, 117 - unsigned int sector_offset, 118 - unsigned int sector_count, 119 - int retry) 120 - { 121 - SectorMap offset_mask; 122 - SectorMap mask; 123 - TRACE_FUN(ft_t_any); 124 - 125 - buff->segment_id = segment_id; 126 - buff->sector_offset = sector_offset; 127 - buff->remaining = sector_count; 128 - buff->head = segment_id / ftape_segments_per_head; 129 - buff->cyl = (segment_id % ftape_segments_per_head) / ftape_segments_per_cylinder; 130 - buff->sect = (segment_id % ftape_segments_per_cylinder) * FT_SECTORS_PER_SEGMENT + 1; 131 - buff->deleted = 0; 132 - offset_mask = (1 << buff->sector_offset) - 1; 133 - mask = ftape_get_bad_sector_entry(segment_id) & offset_mask; 134 - while (mask) { 135 - if (mask & 1) { 136 - offset_mask >>= 1; /* don't count bad sector */ 137 - } 138 - mask >>= 1; 139 - } 140 - buff->data_offset = count_ones(offset_mask); /* good sectors to skip */ 141 - buff->ptr = buff->address + buff->data_offset * FT_SECTOR_SIZE; 142 - TRACE(ft_t_flow, "data offset = %d sectors", buff->data_offset); 143 - if (retry) { 144 - buff->soft_error_map &= offset_mask; /* keep skipped part */ 145 - } else { 146 - buff->hard_error_map = buff->soft_error_map = 0; 147 - } 148 - buff->bad_sector_map = ftape_get_bad_sector_entry(buff->segment_id); 149 - if (buff->bad_sector_map != 0) { 150 - TRACE(ft_t_noise, "segment: %d, bad sector map: %08lx", 151 - buff->segment_id, (long)buff->bad_sector_map); 152 - } else { 153 - TRACE(ft_t_flow, "segment: %d", buff->segment_id); 154 - } 155 - if (buff->sector_offset > 0) { 156 - buff->bad_sector_map >>= buff->sector_offset; 157 - } 158 - if (buff->sector_offset != 0 || buff->remaining != FT_SECTORS_PER_SEGMENT) { 159 - TRACE(ft_t_flow, "sector offset = %d, count = %d", 160 - buff->sector_offset, buff->remaining); 161 - } 162 - /* Segments with 3 or less sectors are not written with valid 163 - * data because there is no space left for the ecc. The 164 - * data written is whatever happens to be in the buffer. 165 - * Reading such a segment will return a zero byte-count. 166 - * To allow us to read/write segments with all bad sectors 167 - * we fake one readable sector in the segment. This 168 - * prevents having to handle these segments in a very 169 - * special way. It is not important if the reading of this 170 - * bad sector fails or not (the data is ignored). It is 171 - * only read to keep the driver running. 172 - * 173 - * The QIC-40/80 spec. has no information on how to handle 174 - * this case, so this is my interpretation. 175 - */ 176 - if (buff->bad_sector_map == EMPTY_SEGMENT) { 177 - TRACE(ft_t_flow, "empty segment %d, fake first sector good", 178 - buff->segment_id); 179 - if (buff->ptr != buff->address) { 180 - TRACE(ft_t_bug, "This is a bug: %p/%p", 181 - buff->ptr, buff->address); 182 - } 183 - buff->bad_sector_map = FAKE_SEGMENT; 184 - } 185 - fdc_setup_error = 0; 186 - buff->next_segment = segment_id + 1; 187 - TRACE_EXIT 0; 188 - } 189 - 190 - /* Calculate Floppy Disk Controller and DMA parameters for a new segment. 191 - */ 192 - int ftape_setup_new_segment(buffer_struct * buff, int segment_id, int skip) 193 - { 194 - int result = 0; 195 - static int old_segment_id = -1; 196 - static buffer_state_enum old_ft_driver_state = idle; 197 - int retry = 0; 198 - unsigned offset = 0; 199 - int count = FT_SECTORS_PER_SEGMENT; 200 - TRACE_FUN(ft_t_flow); 201 - 202 - TRACE(ft_t_flow, "%s segment %d (old = %d)", 203 - (ft_driver_state == reading || ft_driver_state == verifying) 204 - ? "reading" : "writing", 205 - segment_id, old_segment_id); 206 - if (ft_driver_state != old_ft_driver_state) { /* when verifying */ 207 - old_segment_id = -1; 208 - old_ft_driver_state = ft_driver_state; 209 - } 210 - if (segment_id == old_segment_id) { 211 - ++buff->retry; 212 - ++ft_history.retries; 213 - TRACE(ft_t_flow, "setting up for retry nr %d", buff->retry); 214 - retry = 1; 215 - if (skip && buff->skip > 0) { /* allow skip on retry */ 216 - offset = buff->skip; 217 - count -= offset; 218 - TRACE(ft_t_flow, "skipping %d sectors", offset); 219 - } 220 - } else { 221 - buff->retry = 0; 222 - buff->skip = 0; 223 - old_segment_id = segment_id; 224 - } 225 - result = setup_segment(buff, segment_id, offset, count, retry); 226 - TRACE_EXIT result; 227 - } 228 - 229 - /* Determine size of next cluster of good sectors. 230 - */ 231 - int ftape_calc_next_cluster(buffer_struct * buff) 232 - { 233 - /* Skip bad sectors. 234 - */ 235 - while (buff->remaining > 0 && (buff->bad_sector_map & 1) != 0) { 236 - buff->bad_sector_map >>= 1; 237 - ++buff->sector_offset; 238 - --buff->remaining; 239 - } 240 - /* Find next cluster of good sectors 241 - */ 242 - if (buff->bad_sector_map == 0) { /* speed up */ 243 - buff->sector_count = buff->remaining; 244 - } else { 245 - SectorMap map = buff->bad_sector_map; 246 - 247 - buff->sector_count = 0; 248 - while (buff->sector_count < buff->remaining && (map & 1) == 0) { 249 - ++buff->sector_count; 250 - map >>= 1; 251 - } 252 - } 253 - return buff->sector_count; 254 - } 255 - 256 - /* if just passed the last segment on a track, wait for BOT 257 - * or EOT mark. 258 - */ 259 - int ftape_handle_logical_eot(void) 260 - { 261 - TRACE_FUN(ft_t_flow); 262 - 263 - if (ft_runner_status == logical_eot) { 264 - int status; 265 - 266 - TRACE(ft_t_noise, "tape at logical EOT"); 267 - TRACE_CATCH(ftape_ready_wait(ftape_timeout.seek, &status),); 268 - if ((status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) == 0) { 269 - TRACE_ABORT(-EIO, ft_t_err, "eot/bot not reached"); 270 - } 271 - ft_runner_status = end_of_tape; 272 - } 273 - if (ft_runner_status == end_of_tape) { 274 - TRACE(ft_t_noise, "runner stopped because of logical EOT"); 275 - ft_runner_status = idle; 276 - } 277 - TRACE_EXIT 0; 278 - } 279 - 280 - static int check_bot_eot(int status) 281 - { 282 - TRACE_FUN(ft_t_flow); 283 - 284 - if (status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) { 285 - ft_location.bot = ((ft_location.track & 1) == 0 ? 286 - (status & QIC_STATUS_AT_BOT) != 0: 287 - (status & QIC_STATUS_AT_EOT) != 0); 288 - ft_location.eot = !ft_location.bot; 289 - ft_location.segment = (ft_location.track + 290 - (ft_location.bot ? 0 : 1)) * ft_segments_per_track - 1; 291 - ft_location.sector = -1; 292 - ft_location.known = 1; 293 - TRACE(ft_t_flow, "tape at logical %s", 294 - ft_location.bot ? "bot" : "eot"); 295 - TRACE(ft_t_flow, "segment = %d", ft_location.segment); 296 - } else { 297 - ft_location.known = 0; 298 - } 299 - TRACE_EXIT ft_location.known; 300 - } 301 - 302 - /* Read Id of first sector passing tape head. 303 - */ 304 - static int ftape_read_id(void) 305 - { 306 - int status; 307 - __u8 out[2]; 308 - TRACE_FUN(ft_t_any); 309 - 310 - /* Assume tape is running on entry, be able to handle 311 - * situation where it stopped or is stopping. 312 - */ 313 - ft_location.known = 0; /* default is location not known */ 314 - out[0] = FDC_READID; 315 - out[1] = ft_drive_sel; 316 - TRACE_CATCH(fdc_command(out, 2),); 317 - switch (fdc_interrupt_wait(20 * FT_SECOND)) { 318 - case 0: 319 - if (fdc_sect == 0) { 320 - if (ftape_report_drive_status(&status) >= 0 && 321 - (status & QIC_STATUS_READY)) { 322 - ftape_tape_running = 0; 323 - TRACE(ft_t_flow, "tape has stopped"); 324 - check_bot_eot(status); 325 - } 326 - } else { 327 - ft_location.known = 1; 328 - ft_location.segment = (ftape_segments_per_head 329 - * fdc_head 330 - + ftape_segments_per_cylinder 331 - * fdc_cyl 332 - + (fdc_sect - 1) 333 - / FT_SECTORS_PER_SEGMENT); 334 - ft_location.sector = ((fdc_sect - 1) 335 - % FT_SECTORS_PER_SEGMENT); 336 - ft_location.eot = ft_location.bot = 0; 337 - } 338 - break; 339 - case -ETIME: 340 - /* Didn't find id on tape, must be near end: Wait 341 - * until stopped. 342 - */ 343 - if (ftape_ready_wait(FT_FOREVER, &status) >= 0) { 344 - ftape_tape_running = 0; 345 - TRACE(ft_t_flow, "tape has stopped"); 346 - check_bot_eot(status); 347 - } 348 - break; 349 - default: 350 - /* Interrupted or otherwise failing 351 - * fdc_interrupt_wait() 352 - */ 353 - TRACE(ft_t_err, "fdc_interrupt_wait failed"); 354 - break; 355 - } 356 - if (!ft_location.known) { 357 - TRACE_ABORT(-EIO, ft_t_flow, "no id found"); 358 - } 359 - if (ft_location.sector == 0) { 360 - TRACE(ft_t_flow, "passing segment %d/%d", 361 - ft_location.segment, ft_location.sector); 362 - } else { 363 - TRACE(ft_t_fdc_dma, "passing segment %d/%d", 364 - ft_location.segment, ft_location.sector); 365 - } 366 - TRACE_EXIT 0; 367 - } 368 - 369 - static int logical_forward(void) 370 - { 371 - ftape_tape_running = 1; 372 - return ftape_command(QIC_LOGICAL_FORWARD); 373 - } 374 - 375 - int ftape_stop_tape(int *pstatus) 376 - { 377 - int retry = 0; 378 - int result; 379 - TRACE_FUN(ft_t_flow); 380 - 381 - do { 382 - result = ftape_command_wait(QIC_STOP_TAPE, 383 - ftape_timeout.stop, pstatus); 384 - if (result == 0) { 385 - if ((*pstatus & QIC_STATUS_READY) == 0) { 386 - result = -EIO; 387 - } else { 388 - ftape_tape_running = 0; 389 - } 390 - } 391 - } while (result < 0 && ++retry <= 3); 392 - if (result < 0) { 393 - TRACE(ft_t_err, "failed ! (fatal)"); 394 - } 395 - TRACE_EXIT result; 396 - } 397 - 398 - int ftape_dumb_stop(void) 399 - { 400 - int result; 401 - int status; 402 - TRACE_FUN(ft_t_flow); 403 - 404 - /* Abort current fdc operation if it's busy (probably read 405 - * or write operation pending) with a reset. 406 - */ 407 - if (fdc_ready_wait(100 /* usec */) < 0) { 408 - TRACE(ft_t_noise, "aborting fdc operation"); 409 - fdc_reset(); 410 - } 411 - /* Reading id's after the last segment on a track may fail 412 - * but eventually the drive will become ready (logical eot). 413 - */ 414 - result = ftape_report_drive_status(&status); 415 - ft_location.known = 0; 416 - do { 417 - if (result == 0 && status & QIC_STATUS_READY) { 418 - /* Tape is not running any more. 419 - */ 420 - TRACE(ft_t_noise, "tape already halted"); 421 - check_bot_eot(status); 422 - ftape_tape_running = 0; 423 - } else if (ftape_tape_running) { 424 - /* Tape is (was) still moving. 425 - */ 426 - #ifdef TESTING 427 - ftape_read_id(); 428 - #endif 429 - result = ftape_stop_tape(&status); 430 - } else { 431 - /* Tape not yet ready but stopped. 432 - */ 433 - result = ftape_ready_wait(ftape_timeout.pause,&status); 434 - } 435 - } while (ftape_tape_running 436 - && !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK))); 437 - #ifndef TESTING 438 - ft_location.known = 0; 439 - #endif 440 - if (ft_runner_status == aborting || ft_runner_status == do_abort) { 441 - ft_runner_status = idle; 442 - } 443 - TRACE_EXIT result; 444 - } 445 - 446 - /* Wait until runner has finished tail buffer. 447 - * 448 - */ 449 - int ftape_wait_segment(buffer_state_enum state) 450 - { 451 - int status; 452 - int result = 0; 453 - TRACE_FUN(ft_t_flow); 454 - 455 - while (ft_buffer[ft_tail]->status == state) { 456 - TRACE(ft_t_flow, "state: %d", ft_buffer[ft_tail]->status); 457 - /* First buffer still being worked on, wait up to timeout. 458 - * 459 - * Note: we check two times for being killed. 50 460 - * seconds are quite long. Note that 461 - * fdc_interrupt_wait() is not killable by any 462 - * means. ftape_read_segment() wants us to return 463 - * -EINTR in case of a signal. 464 - */ 465 - FT_SIGNAL_EXIT(_DONT_BLOCK); 466 - result = fdc_interrupt_wait(50 * FT_SECOND); 467 - FT_SIGNAL_EXIT(_DONT_BLOCK); 468 - if (result < 0) { 469 - TRACE_ABORT(result, 470 - ft_t_err, "fdc_interrupt_wait failed"); 471 - } 472 - if (fdc_setup_error) { 473 - /* recover... FIXME */ 474 - TRACE_ABORT(-EIO, ft_t_err, "setup error"); 475 - } 476 - } 477 - if (ft_buffer[ft_tail]->status != error) { 478 - TRACE_EXIT 0; 479 - } 480 - TRACE_CATCH(ftape_report_drive_status(&status),); 481 - TRACE(ft_t_noise, "ftape_report_drive_status: 0x%02x", status); 482 - if ((status & QIC_STATUS_READY) && 483 - (status & QIC_STATUS_ERROR)) { 484 - unsigned int error; 485 - qic117_cmd_t command; 486 - 487 - /* Report and clear error state. 488 - * In case the drive can't operate at the selected 489 - * rate, select the next lower data rate. 490 - */ 491 - ftape_report_error(&error, &command, 1); 492 - if (error == 31 && command == QIC_LOGICAL_FORWARD) { 493 - /* drive does not accept this data rate */ 494 - if (ft_data_rate > 250) { 495 - TRACE(ft_t_info, 496 - "Probable data rate conflict"); 497 - TRACE(ft_t_info, 498 - "Lowering data rate to %d Kbps", 499 - ft_data_rate / 2); 500 - ftape_half_data_rate(); 501 - if (ft_buffer[ft_tail]->retry > 0) { 502 - /* give it a chance */ 503 - --ft_buffer[ft_tail]->retry; 504 - } 505 - } else { 506 - /* no rate is accepted... */ 507 - TRACE(ft_t_err, "We're dead :("); 508 - } 509 - } else { 510 - TRACE(ft_t_err, "Unknown error"); 511 - } 512 - TRACE_EXIT -EIO; /* g.p. error */ 513 - } 514 - TRACE_EXIT 0; 515 - } 516 - 517 - /* forward */ static int seek_forward(int segment_id, int fast); 518 - 519 - static int fast_seek(int count, int reverse) 520 - { 521 - int result = 0; 522 - int status; 523 - TRACE_FUN(ft_t_flow); 524 - 525 - if (count > 0) { 526 - /* If positioned at begin or end of tape, fast seeking needs 527 - * special treatment. 528 - * Starting from logical bot needs a (slow) seek to the first 529 - * segment before the high speed seek. Most drives do this 530 - * automatically but some older don't, so we treat them 531 - * all the same. 532 - * Starting from logical eot is even more difficult because 533 - * we cannot (slow) reverse seek to the last segment. 534 - * TO BE IMPLEMENTED. 535 - */ 536 - inhibit_correction = 0; 537 - if (ft_location.known && 538 - ((ft_location.bot && !reverse) || 539 - (ft_location.eot && reverse))) { 540 - if (!reverse) { 541 - /* (slow) skip to first segment on a track 542 - */ 543 - seek_forward(ft_location.track * ft_segments_per_track, 0); 544 - --count; 545 - } else { 546 - /* When seeking backwards from 547 - * end-of-tape the number of erased 548 - * gaps found seems to be higher than 549 - * expected. Therefor the drive must 550 - * skip some more segments than 551 - * calculated, but we don't know how 552 - * many. Thus we will prevent the 553 - * re-calculation of offset and 554 - * overshoot when seeking backwards. 555 - */ 556 - inhibit_correction = 1; 557 - count += 3; /* best guess */ 558 - } 559 - } 560 - } else { 561 - TRACE(ft_t_flow, "warning: zero or negative count: %d", count); 562 - } 563 - if (count > 0) { 564 - int i; 565 - int nibbles = count > 255 ? 3 : 2; 566 - 567 - if (count > 4095) { 568 - TRACE(ft_t_noise, "skipping clipped at 4095 segment"); 569 - count = 4095; 570 - } 571 - /* Issue this tape command first. */ 572 - if (!reverse) { 573 - TRACE(ft_t_noise, "skipping %d segment(s)", count); 574 - result = ftape_command(nibbles == 3 ? 575 - QIC_SKIP_EXTENDED_FORWARD : QIC_SKIP_FORWARD); 576 - } else { 577 - TRACE(ft_t_noise, "backing up %d segment(s)", count); 578 - result = ftape_command(nibbles == 3 ? 579 - QIC_SKIP_EXTENDED_REVERSE : QIC_SKIP_REVERSE); 580 - } 581 - if (result < 0) { 582 - TRACE(ft_t_noise, "Skip command failed"); 583 - } else { 584 - --count; /* 0 means one gap etc. */ 585 - for (i = 0; i < nibbles; ++i) { 586 - if (result >= 0) { 587 - result = ftape_parameter(count & 15); 588 - count /= 16; 589 - } 590 - } 591 - result = ftape_ready_wait(ftape_timeout.rewind, &status); 592 - if (result >= 0) { 593 - ftape_tape_running = 0; 594 - } 595 - } 596 - } 597 - TRACE_EXIT result; 598 - } 599 - 600 - static int validate(int id) 601 - { 602 - /* Check to see if position found is off-track as reported 603 - * once. Because all tracks in one direction lie next to 604 - * each other, if off-track the error will be approximately 605 - * 2 * ft_segments_per_track. 606 - */ 607 - if (ft_location.track == -1) { 608 - return 1; /* unforseen situation, don't generate error */ 609 - } else { 610 - /* Use margin of ft_segments_per_track on both sides 611 - * because ftape needs some margin and the error we're 612 - * looking for is much larger ! 613 - */ 614 - int lo = (ft_location.track - 1) * ft_segments_per_track; 615 - int hi = (ft_location.track + 2) * ft_segments_per_track; 616 - 617 - return (id >= lo && id < hi); 618 - } 619 - } 620 - 621 - static int seek_forward(int segment_id, int fast) 622 - { 623 - int failures = 0; 624 - int count; 625 - static int margin = 1; /* fixed: stop this before target */ 626 - static int overshoot = 1; 627 - static int min_count = 8; 628 - int expected = -1; 629 - int target = segment_id - margin; 630 - int fast_seeking; 631 - int prev_segment = ft_location.segment; 632 - TRACE_FUN(ft_t_flow); 633 - 634 - if (!ft_location.known) { 635 - TRACE_ABORT(-EIO, ft_t_err, 636 - "fatal: cannot seek from unknown location"); 637 - } 638 - if (!validate(segment_id)) { 639 - ftape_sleep(1 * FT_SECOND); 640 - ft_failure = 1; 641 - TRACE_ABORT(-EIO, ft_t_err, 642 - "fatal: head off track (bad hardware?)"); 643 - } 644 - TRACE(ft_t_noise, "from %d/%d to %d/0 - %d", 645 - ft_location.segment, ft_location.sector,segment_id,margin); 646 - count = target - ft_location.segment - overshoot; 647 - fast_seeking = (fast && 648 - count > (min_count + (ft_location.bot ? 1 : 0))); 649 - if (fast_seeking) { 650 - TRACE(ft_t_noise, "fast skipping %d segments", count); 651 - expected = segment_id - margin; 652 - fast_seek(count, 0); 653 - } 654 - if (!ftape_tape_running) { 655 - logical_forward(); 656 - } 657 - while (ft_location.segment < segment_id) { 658 - /* This requires at least one sector in a (bad) segment to 659 - * have a valid and readable sector id ! 660 - * It looks like this is not guaranteed, so we must try 661 - * to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!! 662 - */ 663 - if (ftape_read_id() < 0 || !ft_location.known || 664 - sigtestsetmask(&current->pending.signal, _DONT_BLOCK)) { 665 - ft_location.known = 0; 666 - if (!ftape_tape_running || 667 - ++failures > FT_SECTORS_PER_SEGMENT) { 668 - TRACE_ABORT(-EIO, ft_t_err, 669 - "read_id failed completely"); 670 - } 671 - FT_SIGNAL_EXIT(_DONT_BLOCK); 672 - TRACE(ft_t_flow, "read_id failed, retry (%d)", 673 - failures); 674 - continue; 675 - } 676 - if (fast_seeking) { 677 - TRACE(ft_t_noise, "ended at %d/%d (%d,%d)", 678 - ft_location.segment, ft_location.sector, 679 - overshoot, inhibit_correction); 680 - if (!inhibit_correction && 681 - (ft_location.segment < expected || 682 - ft_location.segment > expected + margin)) { 683 - int error = ft_location.segment - expected; 684 - TRACE(ft_t_noise, 685 - "adjusting overshoot from %d to %d", 686 - overshoot, overshoot + error); 687 - overshoot += error; 688 - /* All overshoots have the same 689 - * direction, so it should never 690 - * become negative, but who knows. 691 - */ 692 - if (overshoot < -5 || 693 - overshoot > OVERSHOOT_LIMIT) { 694 - if (overshoot < 0) { 695 - /* keep sane value */ 696 - overshoot = -5; 697 - } else { 698 - /* keep sane value */ 699 - overshoot = OVERSHOOT_LIMIT; 700 - } 701 - TRACE(ft_t_noise, 702 - "clipped overshoot to %d", 703 - overshoot); 704 - } 705 - } 706 - fast_seeking = 0; 707 - } 708 - if (ft_location.known) { 709 - if (ft_location.segment > prev_segment + 1) { 710 - TRACE(ft_t_noise, 711 - "missed segment %d while skipping", 712 - prev_segment + 1); 713 - } 714 - prev_segment = ft_location.segment; 715 - } 716 - } 717 - if (ft_location.segment > segment_id) { 718 - TRACE_ABORT(-EIO, 719 - ft_t_noise, "failed: skip ended at segment %d/%d", 720 - ft_location.segment, ft_location.sector); 721 - } 722 - TRACE_EXIT 0; 723 - } 724 - 725 - static int skip_reverse(int segment_id, int *pstatus) 726 - { 727 - int failures = 0; 728 - static int overshoot = 1; 729 - static int min_rewind = 2; /* 1 + overshoot */ 730 - static const int margin = 1; /* stop this before target */ 731 - int expected = 0; 732 - int count = 1; 733 - int short_seek; 734 - int target = segment_id - margin; 735 - TRACE_FUN(ft_t_flow); 736 - 737 - if (ft_location.known && !validate(segment_id)) { 738 - ftape_sleep(1 * FT_SECOND); 739 - ft_failure = 1; 740 - TRACE_ABORT(-EIO, ft_t_err, 741 - "fatal: head off track (bad hardware?)"); 742 - } 743 - do { 744 - if (!ft_location.known) { 745 - TRACE(ft_t_warn, "warning: location not known"); 746 - } 747 - TRACE(ft_t_noise, "from %d/%d to %d/0 - %d", 748 - ft_location.segment, ft_location.sector, 749 - segment_id, margin); 750 - /* min_rewind == 1 + overshoot_when_doing_minimum_rewind 751 - * overshoot == overshoot_when_doing_larger_rewind 752 - * Initially min_rewind == 1 + overshoot, optimization 753 - * of both values will be done separately. 754 - * overshoot and min_rewind can be negative as both are 755 - * sums of three components: 756 - * any_overshoot == rewind_overshoot - 757 - * stop_overshoot - 758 - * start_overshoot 759 - */ 760 - if (ft_location.segment - target - (min_rewind - 1) < 1) { 761 - short_seek = 1; 762 - } else { 763 - count = ft_location.segment - target - overshoot; 764 - short_seek = (count < 1); 765 - } 766 - if (short_seek) { 767 - count = 1; /* do shortest rewind */ 768 - expected = ft_location.segment - min_rewind; 769 - if (expected/ft_segments_per_track != ft_location.track) { 770 - expected = (ft_location.track * 771 - ft_segments_per_track); 772 - } 773 - } else { 774 - expected = target; 775 - } 776 - fast_seek(count, 1); 777 - logical_forward(); 778 - if (ftape_read_id() < 0 || !ft_location.known || 779 - (sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) { 780 - if ((!ftape_tape_running && !ft_location.known) || 781 - ++failures > FT_SECTORS_PER_SEGMENT) { 782 - TRACE_ABORT(-EIO, ft_t_err, 783 - "read_id failed completely"); 784 - } 785 - FT_SIGNAL_EXIT(_DONT_BLOCK); 786 - TRACE_CATCH(ftape_report_drive_status(pstatus),); 787 - TRACE(ft_t_noise, "ftape_read_id failed, retry (%d)", 788 - failures); 789 - continue; 790 - } 791 - TRACE(ft_t_noise, "ended at %d/%d (%d,%d,%d)", 792 - ft_location.segment, ft_location.sector, 793 - min_rewind, overshoot, inhibit_correction); 794 - if (!inhibit_correction && 795 - (ft_location.segment < expected || 796 - ft_location.segment > expected + margin)) { 797 - int error = expected - ft_location.segment; 798 - if (short_seek) { 799 - TRACE(ft_t_noise, 800 - "adjusting min_rewind from %d to %d", 801 - min_rewind, min_rewind + error); 802 - min_rewind += error; 803 - if (min_rewind < -5) { 804 - /* is this right ? FIXME ! */ 805 - /* keep sane value */ 806 - min_rewind = -5; 807 - TRACE(ft_t_noise, 808 - "clipped min_rewind to %d", 809 - min_rewind); 810 - } 811 - } else { 812 - TRACE(ft_t_noise, 813 - "adjusting overshoot from %d to %d", 814 - overshoot, overshoot + error); 815 - overshoot += error; 816 - if (overshoot < -5 || 817 - overshoot > OVERSHOOT_LIMIT) { 818 - if (overshoot < 0) { 819 - /* keep sane value */ 820 - overshoot = -5; 821 - } else { 822 - /* keep sane value */ 823 - overshoot = OVERSHOOT_LIMIT; 824 - } 825 - TRACE(ft_t_noise, 826 - "clipped overshoot to %d", 827 - overshoot); 828 - } 829 - } 830 - } 831 - } while (ft_location.segment > segment_id); 832 - if (ft_location.known) { 833 - TRACE(ft_t_noise, "current location: %d/%d", 834 - ft_location.segment, ft_location.sector); 835 - } 836 - TRACE_EXIT 0; 837 - } 838 - 839 - static int determine_position(void) 840 - { 841 - int retry = 0; 842 - int status; 843 - int result; 844 - TRACE_FUN(ft_t_flow); 845 - 846 - if (!ftape_tape_running) { 847 - /* This should only happen if tape is stopped by isr. 848 - */ 849 - TRACE(ft_t_flow, "waiting for tape stop"); 850 - if (ftape_ready_wait(ftape_timeout.pause, &status) < 0) { 851 - TRACE(ft_t_flow, "drive still running (fatal)"); 852 - ftape_tape_running = 1; /* ? */ 853 - } 854 - } else { 855 - ftape_report_drive_status(&status); 856 - } 857 - if (status & QIC_STATUS_READY) { 858 - /* Drive must be ready to check error state ! 859 - */ 860 - TRACE(ft_t_flow, "drive is ready"); 861 - if (status & QIC_STATUS_ERROR) { 862 - unsigned int error; 863 - qic117_cmd_t command; 864 - 865 - /* Report and clear error state, try to continue. 866 - */ 867 - TRACE(ft_t_flow, "error status set"); 868 - ftape_report_error(&error, &command, 1); 869 - ftape_ready_wait(ftape_timeout.reset, &status); 870 - ftape_tape_running = 0; /* ? */ 871 - } 872 - if (check_bot_eot(status)) { 873 - if (ft_location.bot) { 874 - if ((status & QIC_STATUS_READY) == 0) { 875 - /* tape moving away from 876 - * bot/eot, let's see if we 877 - * can catch up with the first 878 - * segment on this track. 879 - */ 880 - } else { 881 - TRACE(ft_t_flow, 882 - "start tape from logical bot"); 883 - logical_forward(); /* start moving */ 884 - } 885 - } else { 886 - if ((status & QIC_STATUS_READY) == 0) { 887 - TRACE(ft_t_noise, "waiting for logical end of track"); 888 - result = ftape_ready_wait(ftape_timeout.reset, &status); 889 - /* error handling needed ? */ 890 - } else { 891 - TRACE(ft_t_noise, 892 - "tape at logical end of track"); 893 - } 894 - } 895 - } else { 896 - TRACE(ft_t_flow, "start tape"); 897 - logical_forward(); /* start moving */ 898 - ft_location.known = 0; /* not cleared by logical forward ! */ 899 - } 900 - } 901 - /* tape should be moving now, start reading id's 902 - */ 903 - while (!ft_location.known && 904 - retry++ < FT_SECTORS_PER_SEGMENT && 905 - (result = ftape_read_id()) < 0) { 906 - 907 - TRACE(ft_t_flow, "location unknown"); 908 - 909 - /* exit on signal 910 - */ 911 - FT_SIGNAL_EXIT(_DONT_BLOCK); 912 - 913 - /* read-id somehow failed, tape may 914 - * have reached end or some other 915 - * error happened. 916 - */ 917 - TRACE(ft_t_flow, "read-id failed"); 918 - TRACE_CATCH(ftape_report_drive_status(&status),); 919 - TRACE(ft_t_err, "ftape_report_drive_status: 0x%02x", status); 920 - if (status & QIC_STATUS_READY) { 921 - ftape_tape_running = 0; 922 - TRACE(ft_t_noise, "tape stopped for unknown reason! " 923 - "status = 0x%02x", status); 924 - if (status & QIC_STATUS_ERROR || 925 - !check_bot_eot(status)) { 926 - /* oops, tape stopped but not at end! 927 - */ 928 - TRACE_EXIT -EIO; 929 - } 930 - } 931 - } 932 - TRACE(ft_t_flow, 933 - "tape is positioned at segment %d", ft_location.segment); 934 - TRACE_EXIT ft_location.known ? 0 : -EIO; 935 - } 936 - 937 - /* Get the tape running and position it just before the 938 - * requested segment. 939 - * Seek tape-track and reposition as needed. 940 - */ 941 - int ftape_start_tape(int segment_id, int sector_offset) 942 - { 943 - int track = segment_id / ft_segments_per_track; 944 - int result = -EIO; 945 - int status; 946 - static int last_segment = -1; 947 - static int bad_bus_timing = 0; 948 - /* number of segments passing the head between starting the tape 949 - * and being able to access the first sector. 950 - */ 951 - static int start_offset = 1; 952 - int retry; 953 - TRACE_FUN(ft_t_flow); 954 - 955 - /* If sector_offset > 0, seek into wanted segment instead of 956 - * into previous. 957 - * This allows error recovery if a part of the segment is bad 958 - * (erased) causing the tape drive to generate an index pulse 959 - * thus causing a no-data error before the requested sector 960 - * is reached. 961 - */ 962 - ftape_tape_running = 0; 963 - TRACE(ft_t_noise, "target segment: %d/%d%s", segment_id, sector_offset, 964 - ft_buffer[ft_head]->retry > 0 ? " retry" : ""); 965 - if (ft_buffer[ft_head]->retry > 0) { /* this is a retry */ 966 - int dist = segment_id - last_segment; 967 - 968 - if ((int)ft_history.overrun_errors < overrun_count_offset) { 969 - overrun_count_offset = ft_history.overrun_errors; 970 - } else if (dist < 0 || dist > 50) { 971 - overrun_count_offset = ft_history.overrun_errors; 972 - } else if ((ft_history.overrun_errors - 973 - overrun_count_offset) >= 8) { 974 - if (ftape_increase_threshold() >= 0) { 975 - --ft_buffer[ft_head]->retry; 976 - overrun_count_offset = 977 - ft_history.overrun_errors; 978 - TRACE(ft_t_warn, "increased threshold because " 979 - "of excessive overrun errors"); 980 - } else if (!bad_bus_timing && ft_data_rate >= 1000) { 981 - ftape_half_data_rate(); 982 - --ft_buffer[ft_head]->retry; 983 - bad_bus_timing = 1; 984 - overrun_count_offset = 985 - ft_history.overrun_errors; 986 - TRACE(ft_t_warn, "reduced datarate because " 987 - "of excessive overrun errors"); 988 - } 989 - } 990 - } 991 - last_segment = segment_id; 992 - if (ft_location.track != track || 993 - (ftape_might_be_off_track && ft_buffer[ft_head]->retry== 0)) { 994 - /* current track unknown or not equal to destination 995 - */ 996 - ftape_ready_wait(ftape_timeout.seek, &status); 997 - ftape_seek_head_to_track(track); 998 - /* overrun_count_offset = ft_history.overrun_errors; */ 999 - } 1000 - result = -EIO; 1001 - retry = 0; 1002 - while (result < 0 && 1003 - retry++ <= 5 && 1004 - !ft_failure && 1005 - !(sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) { 1006 - 1007 - if (retry && start_offset < 5) { 1008 - start_offset ++; 1009 - } 1010 - /* Check if we are able to catch the requested 1011 - * segment in time. 1012 - */ 1013 - if ((ft_location.known || (determine_position() == 0)) && 1014 - ft_location.segment >= 1015 - (segment_id - 1016 - ((ftape_tape_running || ft_location.bot) 1017 - ? 0 : start_offset))) { 1018 - /* Too far ahead (in or past target segment). 1019 - */ 1020 - if (ftape_tape_running) { 1021 - if ((result = ftape_stop_tape(&status)) < 0) { 1022 - TRACE(ft_t_err, 1023 - "stop tape failed with code %d", 1024 - result); 1025 - break; 1026 - } 1027 - TRACE(ft_t_noise, "tape stopped"); 1028 - ftape_tape_running = 0; 1029 - } 1030 - TRACE(ft_t_noise, "repositioning"); 1031 - ++ft_history.rewinds; 1032 - if (segment_id % ft_segments_per_track < start_offset){ 1033 - TRACE(ft_t_noise, "end of track condition\n" 1034 - KERN_INFO "segment_id : %d\n" 1035 - KERN_INFO "ft_segments_per_track: %d\n" 1036 - KERN_INFO "start_offset : %d", 1037 - segment_id, ft_segments_per_track, 1038 - start_offset); 1039 - 1040 - /* If seeking to first segments on 1041 - * track better do a complete rewind 1042 - * to logical begin of track to get a 1043 - * more steady tape motion. 1044 - */ 1045 - result = ftape_command_wait( 1046 - (ft_location.track & 1) 1047 - ? QIC_PHYSICAL_FORWARD 1048 - : QIC_PHYSICAL_REVERSE, 1049 - ftape_timeout.rewind, &status); 1050 - check_bot_eot(status); /* update location */ 1051 - } else { 1052 - result= skip_reverse(segment_id - start_offset, 1053 - &status); 1054 - } 1055 - } 1056 - if (!ft_location.known) { 1057 - TRACE(ft_t_bug, "panic: location not known"); 1058 - result = -EIO; 1059 - continue; /* while() will check for failure */ 1060 - } 1061 - TRACE(ft_t_noise, "current segment: %d/%d", 1062 - ft_location.segment, ft_location.sector); 1063 - /* We're on the right track somewhere before the 1064 - * wanted segment. Start tape movement if needed and 1065 - * skip to just before or inside the requested 1066 - * segment. Keep tape running. 1067 - */ 1068 - result = 0; 1069 - if (ft_location.segment < 1070 - (segment_id - ((ftape_tape_running || ft_location.bot) 1071 - ? 0 : start_offset))) { 1072 - if (sector_offset > 0) { 1073 - result = seek_forward(segment_id, 1074 - retry <= 3); 1075 - } else { 1076 - result = seek_forward(segment_id - 1, 1077 - retry <= 3); 1078 - } 1079 - } 1080 - if (result == 0 && 1081 - ft_location.segment != 1082 - (segment_id - (sector_offset > 0 ? 0 : 1))) { 1083 - result = -EIO; 1084 - } 1085 - } 1086 - if (result < 0) { 1087 - TRACE(ft_t_err, "failed to reposition"); 1088 - } else { 1089 - ft_runner_status = running; 1090 - } 1091 - TRACE_EXIT result; 1092 - }
-111
drivers/char/ftape/lowlevel/ftape-rw.h
··· 1 - #ifndef _FTAPE_RW_H 2 - #define _FTAPE_RW_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-rw.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:25 $ 26 - * 27 - * This file contains the definitions for the read and write 28 - * functions for the QIC-117 floppy-tape driver for Linux. 29 - * 30 - * Claus-Justus Heine (1996/09/20): Add definition of format code 6 31 - * Claus-Justus Heine (1996/10/04): Changed GET/PUT macros to cast to (__u8 *) 32 - * 33 - */ 34 - 35 - #include "../lowlevel/fdc-io.h" 36 - #include "../lowlevel/ftape-init.h" 37 - #include "../lowlevel/ftape-bsm.h" 38 - 39 - #include <asm/unaligned.h> 40 - 41 - #define GET2(address, offset) get_unaligned((__u16*)((__u8 *)address + offset)) 42 - #define GET4(address, offset) get_unaligned((__u32*)((__u8 *)address + offset)) 43 - #define GET8(address, offset) get_unaligned((__u64*)((__u8 *)address + offset)) 44 - #define PUT2(address, offset , value) put_unaligned((value), (__u16*)((__u8 *)address + offset)) 45 - #define PUT4(address, offset , value) put_unaligned((value), (__u32*)((__u8 *)address + offset)) 46 - #define PUT8(address, offset , value) put_unaligned((value), (__u64*)((__u8 *)address + offset)) 47 - 48 - enum runner_status_enum { 49 - idle = 0, 50 - running, 51 - do_abort, 52 - aborting, 53 - logical_eot, 54 - end_of_tape, 55 - }; 56 - 57 - typedef enum ft_buffer_queue { 58 - ft_queue_head = 0, 59 - ft_queue_tail = 1 60 - } ft_buffer_queue_t; 61 - 62 - 63 - typedef struct { 64 - int track; /* tape head position */ 65 - volatile int segment; /* current segment */ 66 - volatile int sector; /* sector offset within current segment */ 67 - volatile unsigned int bot; /* logical begin of track */ 68 - volatile unsigned int eot; /* logical end of track */ 69 - volatile unsigned int known; /* validates bot, segment, sector */ 70 - } location_record; 71 - 72 - /* Count nr of 1's in pattern. 73 - */ 74 - static inline int count_ones(unsigned long mask) 75 - { 76 - int bits; 77 - 78 - for (bits = 0; mask != 0; mask >>= 1) { 79 - if (mask & 1) { 80 - ++bits; 81 - } 82 - } 83 - return bits; 84 - } 85 - 86 - #define FT_MAX_NR_BUFFERS 16 /* arbitrary value */ 87 - /* ftape-rw.c defined global vars. 88 - */ 89 - extern buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS]; 90 - extern int ft_nr_buffers; 91 - extern location_record ft_location; 92 - extern volatile int ftape_tape_running; 93 - 94 - /* ftape-rw.c defined global functions. 95 - */ 96 - extern int ftape_setup_new_segment(buffer_struct * buff, 97 - int segment_id, 98 - int offset); 99 - extern int ftape_calc_next_cluster(buffer_struct * buff); 100 - extern buffer_struct *ftape_next_buffer (ft_buffer_queue_t pos); 101 - extern buffer_struct *ftape_get_buffer (ft_buffer_queue_t pos); 102 - extern int ftape_buffer_id (ft_buffer_queue_t pos); 103 - extern void ftape_reset_buffer(void); 104 - extern void ftape_tape_parameters(__u8 drive_configuration); 105 - extern int ftape_wait_segment(buffer_state_enum state); 106 - extern int ftape_dumb_stop(void); 107 - extern int ftape_start_tape(int segment_id, int offset); 108 - extern int ftape_stop_tape(int *pstatus); 109 - extern int ftape_handle_logical_eot(void); 110 - extern buffer_state_enum ftape_set_state(buffer_state_enum new_state); 111 - #endif /* _FTAPE_RW_H */
-104
drivers/char/ftape/lowlevel/ftape-setup.c
··· 1 - /* 2 - * Copyright (C) 1996, 1997 Claus-Justus Heine. 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-setup.c,v $ 20 - * $Revision: 1.7 $ 21 - * $Date: 1997/10/10 09:57:06 $ 22 - * 23 - * This file contains the code for processing the kernel command 24 - * line options for the QIC-40/80/3010/3020 floppy-tape driver 25 - * "ftape" for Linux. 26 - */ 27 - 28 - #include <linux/string.h> 29 - #include <linux/errno.h> 30 - #include <linux/mm.h> 31 - 32 - #include <linux/ftape.h> 33 - #include <linux/init.h> 34 - #include "../lowlevel/ftape-tracing.h" 35 - #include "../lowlevel/fdc-io.h" 36 - 37 - static struct param_table { 38 - const char *name; 39 - int *var; 40 - int def_param; 41 - int min; 42 - int max; 43 - } config_params[] __initdata = { 44 - #ifndef CONFIG_FT_NO_TRACE_AT_ALL 45 - { "tracing", &ftape_tracing, 3, ft_t_bug, ft_t_any}, 46 - #endif 47 - { "ioport", &ft_fdc_base, CONFIG_FT_FDC_BASE, 0x0, 0xfff}, 48 - { "irq", &ft_fdc_irq, CONFIG_FT_FDC_IRQ, 2, 15}, 49 - { "dma", &ft_fdc_dma, CONFIG_FT_FDC_DMA, 0, 3}, 50 - { "threshold", &ft_fdc_threshold, CONFIG_FT_FDC_THR, 1, 16}, 51 - { "datarate", &ft_fdc_rate_limit, CONFIG_FT_FDC_MAX_RATE, 500, 2000}, 52 - { "fc10", &ft_probe_fc10, CONFIG_FT_PROBE_FC10, 0, 1}, 53 - { "mach2", &ft_mach2, CONFIG_FT_MACH2, 0, 1} 54 - }; 55 - 56 - static int __init ftape_setup(char *str) 57 - { 58 - int i; 59 - int param; 60 - int ints[2]; 61 - 62 - TRACE_FUN(ft_t_flow); 63 - 64 - str = get_options(str, ARRAY_SIZE(ints), ints); 65 - if (str) { 66 - for (i=0; i < NR_ITEMS(config_params); i++) { 67 - if (strcmp(str,config_params[i].name) == 0){ 68 - if (ints[0]) { 69 - param = ints[1]; 70 - } else { 71 - param = config_params[i].def_param; 72 - } 73 - if (param < config_params[i].min || 74 - param > config_params[i].max) { 75 - TRACE(ft_t_err, 76 - "parameter %s out of range %d ... %d", 77 - config_params[i].name, 78 - config_params[i].min, 79 - config_params[i].max); 80 - goto out; 81 - } 82 - if(config_params[i].var) { 83 - TRACE(ft_t_info, "%s=%d", str, param); 84 - *config_params[i].var = param; 85 - } 86 - goto out; 87 - } 88 - } 89 - } 90 - if (str) { 91 - TRACE(ft_t_err, "unknown ftape option [%s]", str); 92 - 93 - TRACE(ft_t_err, "allowed options are:"); 94 - for (i=0; i < NR_ITEMS(config_params); i++) { 95 - TRACE(ft_t_err, " %s",config_params[i].name); 96 - } 97 - } else { 98 - TRACE(ft_t_err, "botched ftape option"); 99 - } 100 - out: 101 - TRACE_EXIT 1; 102 - } 103 - 104 - __setup("ftape=", ftape_setup);
-118
drivers/char/ftape/lowlevel/ftape-tracing.c
··· 1 - /* 2 - * Copyright (C) 1993-1996 Bas Laarhoven, 3 - * (C) 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-tracing.c,v $ 21 - * $Revision: 1.2 $ 22 - * $Date: 1997/10/05 19:18:27 $ 23 - * 24 - * This file contains the reading code 25 - * for the QIC-117 floppy-tape driver for Linux. 26 - */ 27 - 28 - #include <linux/ftape.h> 29 - #include "../lowlevel/ftape-tracing.h" 30 - 31 - /* Global vars. 32 - */ 33 - /* tracing 34 - * set it to: to log : 35 - * 0 bugs 36 - * 1 + errors 37 - * 2 + warnings 38 - * 3 + information 39 - * 4 + more information 40 - * 5 + program flow 41 - * 6 + fdc/dma info 42 - * 7 + data flow 43 - * 8 + everything else 44 - */ 45 - ft_trace_t ftape_tracing = ft_t_info; /* Default level: information and up */ 46 - int ftape_function_nest_level; 47 - 48 - /* Local vars. 49 - */ 50 - static __u8 trace_id; 51 - static char spacing[] = "* "; 52 - 53 - void ftape_trace_call(const char *file, const char *name) 54 - { 55 - char *indent; 56 - 57 - /* Since printk seems not to work with "%*s" format 58 - * we'll use this work-around. 59 - */ 60 - if (ftape_function_nest_level < 0) { 61 - printk(KERN_INFO "function nest level (%d) < 0\n", 62 - ftape_function_nest_level); 63 - ftape_function_nest_level = 0; 64 - } 65 - if (ftape_function_nest_level < sizeof(spacing)) { 66 - indent = (spacing + 67 - sizeof(spacing) - 1 - 68 - ftape_function_nest_level); 69 - } else { 70 - indent = spacing; 71 - } 72 - printk(KERN_INFO "[%03d]%s+%s (%s)\n", 73 - (int) trace_id++, indent, file, name); 74 - } 75 - 76 - void ftape_trace_exit(const char *file, const char *name) 77 - { 78 - char *indent; 79 - 80 - /* Since printk seems not to work with "%*s" format 81 - * we'll use this work-around. 82 - */ 83 - if (ftape_function_nest_level < 0) { 84 - printk(KERN_INFO "function nest level (%d) < 0\n", ftape_function_nest_level); 85 - ftape_function_nest_level = 0; 86 - } 87 - if (ftape_function_nest_level < sizeof(spacing)) { 88 - indent = (spacing + 89 - sizeof(spacing) - 1 - 90 - ftape_function_nest_level); 91 - } else { 92 - indent = spacing; 93 - } 94 - printk(KERN_INFO "[%03d]%s-%s (%s)\n", 95 - (int) trace_id++, indent, file, name); 96 - } 97 - 98 - void ftape_trace_log(const char *file, const char *function) 99 - { 100 - char *indent; 101 - 102 - /* Since printk seems not to work with "%*s" format 103 - * we'll use this work-around. 104 - */ 105 - if (ftape_function_nest_level < 0) { 106 - printk(KERN_INFO "function nest level (%d) < 0\n", ftape_function_nest_level); 107 - ftape_function_nest_level = 0; 108 - } 109 - if (ftape_function_nest_level < sizeof(spacing)) { 110 - indent = (spacing + 111 - sizeof(spacing) - 1 - 112 - ftape_function_nest_level); 113 - } else { 114 - indent = spacing; 115 - } 116 - printk(KERN_INFO "[%03d]%s%s (%s) - ", 117 - (int) trace_id++, indent, file, function); 118 - }
-179
drivers/char/ftape/lowlevel/ftape-tracing.h
··· 1 - #ifndef _FTAPE_TRACING_H 2 - #define _FTAPE_TRACING_H 3 - 4 - /* 5 - * Copyright (C) 1994-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-tracing.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:18:28 $ 26 - * 27 - * This file contains definitions that eases the debugging of the 28 - * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. 29 - */ 30 - 31 - #include <linux/kernel.h> 32 - 33 - /* 34 - * Be very careful with TRACE_EXIT and TRACE_ABORT. 35 - * 36 - * if (something) TRACE_EXIT error; 37 - * 38 - * will NOT work. Use 39 - * 40 - * if (something) { 41 - * TRACE_EXIT error; 42 - * } 43 - * 44 - * instead. Maybe a bit dangerous, but save lots of lines of code. 45 - */ 46 - 47 - #define LL_X "%d/%d KB" 48 - #define LL(x) (unsigned int)((__u64)(x)>>10), (unsigned int)((x)&1023) 49 - 50 - typedef enum { 51 - ft_t_nil = -1, 52 - ft_t_bug, 53 - ft_t_err, 54 - ft_t_warn, 55 - ft_t_info, 56 - ft_t_noise, 57 - ft_t_flow, 58 - ft_t_fdc_dma, 59 - ft_t_data_flow, 60 - ft_t_any 61 - } ft_trace_t; 62 - 63 - #ifdef CONFIG_FT_NO_TRACE_AT_ALL 64 - /* the compiler will optimize away most TRACE() macros 65 - */ 66 - #define FT_TRACE_TOP_LEVEL ft_t_bug 67 - #define TRACE_FUN(level) do {} while(0) 68 - #define TRACE_EXIT return 69 - #define TRACE(l, m, i...) \ 70 - { \ 71 - if ((ft_trace_t)(l) == FT_TRACE_TOP_LEVEL) { \ 72 - printk(KERN_INFO"ftape%s(%s):\n" \ 73 - KERN_INFO m".\n" ,__FILE__, __FUNCTION__ , ##i); \ 74 - } \ 75 - } 76 - #define SET_TRACE_LEVEL(l) if ((l) == (l)) do {} while(0) 77 - #define TRACE_LEVEL FT_TRACE_TOP_LEVEL 78 - 79 - #else 80 - 81 - #ifdef CONFIG_FT_NO_TRACE 82 - /* the compiler will optimize away many TRACE() macros 83 - * the ftape_simple_trace_call() function simply increments 84 - * the function nest level. 85 - */ 86 - #define FT_TRACE_TOP_LEVEL ft_t_warn 87 - #define TRACE_FUN(level) ftape_function_nest_level++ 88 - #define TRACE_EXIT ftape_function_nest_level--; return 89 - 90 - #else 91 - #ifdef CONFIG_FT_FULL_DEBUG 92 - #define FT_TRACE_TOP_LEVEL ft_t_any 93 - #else 94 - #define FT_TRACE_TOP_LEVEL ft_t_flow 95 - #endif 96 - #define TRACE_FUN(level) \ 97 - const ft_trace_t _tracing = level; \ 98 - if (ftape_tracing >= (ft_trace_t)(level) && \ 99 - (ft_trace_t)(level) <= FT_TRACE_TOP_LEVEL) \ 100 - ftape_trace_call(__FILE__, __FUNCTION__); \ 101 - ftape_function_nest_level ++; 102 - 103 - #define TRACE_EXIT \ 104 - --ftape_function_nest_level; \ 105 - if (ftape_tracing >= (ft_trace_t)(_tracing) && \ 106 - (ft_trace_t)(_tracing) <= FT_TRACE_TOP_LEVEL) \ 107 - ftape_trace_exit(__FILE__, __FUNCTION__); \ 108 - return 109 - 110 - #endif 111 - 112 - #define TRACE(l, m, i...) \ 113 - { \ 114 - if (ftape_tracing >= (ft_trace_t)(l) && \ 115 - (ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) { \ 116 - ftape_trace_log(__FILE__, __FUNCTION__); \ 117 - printk(m".\n" ,##i); \ 118 - } \ 119 - } 120 - 121 - #define SET_TRACE_LEVEL(l) \ 122 - { \ 123 - if ((ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) { \ 124 - ftape_tracing = (ft_trace_t)(l); \ 125 - } else { \ 126 - ftape_tracing = FT_TRACE_TOP_LEVEL; \ 127 - } \ 128 - } 129 - #define TRACE_LEVEL \ 130 - ((ftape_tracing <= FT_TRACE_TOP_LEVEL) ? ftape_tracing : FT_TRACE_TOP_LEVEL) 131 - 132 - 133 - /* Global variables declared in tracing.c 134 - */ 135 - extern ft_trace_t ftape_tracing; /* sets default level */ 136 - extern int ftape_function_nest_level; 137 - 138 - /* Global functions declared in tracing.c 139 - */ 140 - extern void ftape_trace_call(const char *file, const char *name); 141 - extern void ftape_trace_exit(const char *file, const char *name); 142 - extern void ftape_trace_log (const char *file, const char *name); 143 - 144 - #endif /* !defined(CONFIG_FT_NO_TRACE_AT_ALL) */ 145 - 146 - /* 147 - * Abort with a message. 148 - */ 149 - #define TRACE_ABORT(res, i...) \ 150 - { \ 151 - TRACE(i); \ 152 - TRACE_EXIT res; \ 153 - } 154 - 155 - /* The following transforms the common "if(result < 0) ... " into a 156 - * one-liner. 157 - */ 158 - #define _TRACE_CATCH(level, fun, action) \ 159 - { \ 160 - int _res = (fun); \ 161 - if (_res < 0) { \ 162 - do { action /* */ ; } while(0); \ 163 - TRACE_ABORT(_res, level, "%s failed: %d", #fun, _res); \ 164 - } \ 165 - } 166 - 167 - #define TRACE_CATCH(fun, fail) _TRACE_CATCH(ft_t_err, fun, fail) 168 - 169 - /* Abort the current function when signalled. This doesn't belong here, 170 - * but rather into ftape-rw.h (maybe) 171 - */ 172 - #define FT_SIGNAL_EXIT(sig_mask) \ 173 - if (sigtestsetmask(&current->pending.signal, sig_mask)) { \ 174 - TRACE_ABORT(-EINTR, \ 175 - ft_t_warn, \ 176 - "interrupted by non-blockable signal"); \ 177 - } 178 - 179 - #endif /* _FTAPE_TRACING_H */
-336
drivers/char/ftape/lowlevel/ftape-write.c
··· 1 - /* 2 - * Copyright (C) 1993-1995 Bas Laarhoven, 3 - * (C) 1996-1997 Claus-Justus Heine. 4 - 5 - This program is free software; you can redistribute it and/or modify 6 - it under the terms of the GNU General Public License as published by 7 - the Free Software Foundation; either version 2, or (at your option) 8 - any later version. 9 - 10 - This program is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - GNU General Public License for more details. 14 - 15 - You should have received a copy of the GNU General Public License 16 - along with this program; see the file COPYING. If not, write to 17 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-write.c,v $ 21 - * $Revision: 1.3.4.1 $ 22 - * $Date: 1997/11/14 18:07:04 $ 23 - * 24 - * This file contains the writing code 25 - * for the QIC-117 floppy-tape driver for Linux. 26 - */ 27 - 28 - #include <linux/string.h> 29 - #include <linux/errno.h> 30 - #include <linux/mm.h> 31 - 32 - #include <linux/ftape.h> 33 - #include <linux/qic117.h> 34 - #include "../lowlevel/ftape-tracing.h" 35 - #include "../lowlevel/ftape-write.h" 36 - #include "../lowlevel/ftape-read.h" 37 - #include "../lowlevel/ftape-io.h" 38 - #include "../lowlevel/ftape-ctl.h" 39 - #include "../lowlevel/ftape-rw.h" 40 - #include "../lowlevel/ftape-ecc.h" 41 - #include "../lowlevel/ftape-bsm.h" 42 - #include "../lowlevel/fdc-isr.h" 43 - 44 - /* Global vars. 45 - */ 46 - 47 - /* Local vars. 48 - */ 49 - static int last_write_failed; 50 - 51 - void ftape_zap_write_buffers(void) 52 - { 53 - int i; 54 - 55 - for (i = 0; i < ft_nr_buffers; ++i) { 56 - ft_buffer[i]->status = done; 57 - } 58 - ftape_reset_buffer(); 59 - } 60 - 61 - static int copy_and_gen_ecc(void *destination, 62 - const void *source, 63 - const SectorMap bad_sector_map) 64 - { 65 - int result; 66 - struct memory_segment mseg; 67 - int bads = count_ones(bad_sector_map); 68 - TRACE_FUN(ft_t_any); 69 - 70 - if (bads > 0) { 71 - TRACE(ft_t_noise, "bad sectors in map: %d", bads); 72 - } 73 - if (bads + 3 >= FT_SECTORS_PER_SEGMENT) { 74 - TRACE(ft_t_noise, "empty segment"); 75 - mseg.blocks = 0; /* skip entire segment */ 76 - result = 0; /* nothing written */ 77 - } else { 78 - mseg.blocks = FT_SECTORS_PER_SEGMENT - bads; 79 - mseg.data = destination; 80 - memcpy(mseg.data, source, (mseg.blocks - 3) * FT_SECTOR_SIZE); 81 - result = ftape_ecc_set_segment_parity(&mseg); 82 - if (result < 0) { 83 - TRACE(ft_t_err, "ecc_set_segment_parity failed"); 84 - } else { 85 - result = (mseg.blocks - 3) * FT_SECTOR_SIZE; 86 - } 87 - } 88 - TRACE_EXIT result; 89 - } 90 - 91 - 92 - int ftape_start_writing(const ft_write_mode_t mode) 93 - { 94 - buffer_struct *head = ftape_get_buffer(ft_queue_head); 95 - int segment_id = head->segment_id; 96 - int result; 97 - buffer_state_enum wanted_state = (mode == FT_WR_DELETE 98 - ? deleting 99 - : writing); 100 - TRACE_FUN(ft_t_flow); 101 - 102 - if ((ft_driver_state != wanted_state) || head->status != waiting) { 103 - TRACE_EXIT 0; 104 - } 105 - ftape_setup_new_segment(head, segment_id, 1); 106 - if (mode == FT_WR_SINGLE) { 107 - /* stop tape instead of pause */ 108 - head->next_segment = 0; 109 - } 110 - ftape_calc_next_cluster(head); /* prepare */ 111 - head->status = ft_driver_state; /* either writing or deleting */ 112 - if (ft_runner_status == idle) { 113 - TRACE(ft_t_noise, 114 - "starting runner for segment %d", segment_id); 115 - TRACE_CATCH(ftape_start_tape(segment_id,head->sector_offset),); 116 - } else { 117 - TRACE(ft_t_noise, "runner not idle, not starting tape"); 118 - } 119 - /* go */ 120 - result = fdc_setup_read_write(head, (mode == FT_WR_DELETE 121 - ? FDC_WRITE_DELETED : FDC_WRITE)); 122 - ftape_set_state(wanted_state); /* should not be necessary */ 123 - TRACE_EXIT result; 124 - } 125 - 126 - /* Wait until all data is actually written to tape. 127 - * 128 - * There is a problem: when the tape runs into logical EOT, then this 129 - * failes. We need to restart the runner in this case. 130 - */ 131 - int ftape_loop_until_writes_done(void) 132 - { 133 - buffer_struct *head; 134 - TRACE_FUN(ft_t_flow); 135 - 136 - while ((ft_driver_state == writing || ft_driver_state == deleting) && 137 - ftape_get_buffer(ft_queue_head)->status != done) { 138 - /* set the runner status to idle if at lEOT */ 139 - TRACE_CATCH(ftape_handle_logical_eot(), last_write_failed = 1); 140 - /* restart the tape if necessary */ 141 - if (ft_runner_status == idle) { 142 - TRACE(ft_t_noise, "runner is idle, restarting"); 143 - if (ft_driver_state == deleting) { 144 - TRACE_CATCH(ftape_start_writing(FT_WR_DELETE), 145 - last_write_failed = 1); 146 - } else { 147 - TRACE_CATCH(ftape_start_writing(FT_WR_MULTI), 148 - last_write_failed = 1); 149 - } 150 - } 151 - TRACE(ft_t_noise, "tail: %d, head: %d", 152 - ftape_buffer_id(ft_queue_tail), 153 - ftape_buffer_id(ft_queue_head)); 154 - TRACE_CATCH(fdc_interrupt_wait(5 * FT_SECOND), 155 - last_write_failed = 1); 156 - head = ftape_get_buffer(ft_queue_head); 157 - if (head->status == error) { 158 - /* Allow escape from loop when signaled ! 159 - */ 160 - FT_SIGNAL_EXIT(_DONT_BLOCK); 161 - if (head->hard_error_map != 0) { 162 - /* Implement hard write error recovery here 163 - */ 164 - } 165 - /* retry this one */ 166 - head->status = waiting; 167 - if (ft_runner_status == aborting) { 168 - ftape_dumb_stop(); 169 - } 170 - if (ft_runner_status != idle) { 171 - TRACE_ABORT(-EIO, ft_t_err, 172 - "unexpected state: " 173 - "ft_runner_status != idle"); 174 - } 175 - ftape_start_writing(ft_driver_state == deleting 176 - ? FT_WR_MULTI : FT_WR_DELETE); 177 - } 178 - TRACE(ft_t_noise, "looping until writes done"); 179 - } 180 - ftape_set_state(idle); 181 - TRACE_EXIT 0; 182 - } 183 - 184 - /* Write given segment from buffer at address to tape. 185 - */ 186 - static int write_segment(const int segment_id, 187 - const void *address, 188 - const ft_write_mode_t write_mode) 189 - { 190 - int bytes_written = 0; 191 - buffer_struct *tail; 192 - buffer_state_enum wanted_state = (write_mode == FT_WR_DELETE 193 - ? deleting : writing); 194 - TRACE_FUN(ft_t_flow); 195 - 196 - TRACE(ft_t_noise, "segment_id = %d", segment_id); 197 - if (ft_driver_state != wanted_state) { 198 - if (ft_driver_state == deleting || 199 - wanted_state == deleting) { 200 - TRACE_CATCH(ftape_loop_until_writes_done(),); 201 - } 202 - TRACE(ft_t_noise, "calling ftape_abort_operation"); 203 - TRACE_CATCH(ftape_abort_operation(),); 204 - ftape_zap_write_buffers(); 205 - ftape_set_state(wanted_state); 206 - } 207 - /* if all buffers full we'll have to wait... 208 - */ 209 - ftape_wait_segment(wanted_state); 210 - tail = ftape_get_buffer(ft_queue_tail); 211 - switch(tail->status) { 212 - case done: 213 - ft_history.defects += count_ones(tail->hard_error_map); 214 - break; 215 - case waiting: 216 - /* this could happen with multiple EMPTY_SEGMENTs, but 217 - * shouldn't happen any more as we re-start the runner even 218 - * with an empty segment. 219 - */ 220 - bytes_written = -EAGAIN; 221 - break; 222 - case error: 223 - /* setup for a retry 224 - */ 225 - tail->status = waiting; 226 - bytes_written = -EAGAIN; /* force retry */ 227 - if (tail->hard_error_map != 0) { 228 - TRACE(ft_t_warn, 229 - "warning: %d hard error(s) in written segment", 230 - count_ones(tail->hard_error_map)); 231 - TRACE(ft_t_noise, "hard_error_map = 0x%08lx", 232 - (long)tail->hard_error_map); 233 - /* Implement hard write error recovery here 234 - */ 235 - } 236 - break; 237 - default: 238 - TRACE_ABORT(-EIO, ft_t_err, 239 - "wait for empty segment failed, tail status: %d", 240 - tail->status); 241 - } 242 - /* should runner stop ? 243 - */ 244 - if (ft_runner_status == aborting) { 245 - buffer_struct *head = ftape_get_buffer(ft_queue_head); 246 - if (head->status == wanted_state) { 247 - head->status = done; /* ???? */ 248 - } 249 - /* don't call abort_operation(), we don't want to zap 250 - * the dma buffers 251 - */ 252 - TRACE_CATCH(ftape_dumb_stop(),); 253 - } else { 254 - /* If just passed last segment on tape: wait for BOT 255 - * or EOT mark. Sets ft_runner_status to idle if at lEOT 256 - * and successful 257 - */ 258 - TRACE_CATCH(ftape_handle_logical_eot(),); 259 - } 260 - if (tail->status == done) { 261 - /* now at least one buffer is empty, fill it with our 262 - * data. skip bad sectors and generate ecc. 263 - * copy_and_gen_ecc return nr of bytes written, range 264 - * 0..29 Kb inclusive! 265 - * 266 - * Empty segments are handled inside coyp_and_gen_ecc() 267 - */ 268 - if (write_mode != FT_WR_DELETE) { 269 - TRACE_CATCH(bytes_written = copy_and_gen_ecc( 270 - tail->address, address, 271 - ftape_get_bad_sector_entry(segment_id)),); 272 - } 273 - tail->segment_id = segment_id; 274 - tail->status = waiting; 275 - tail = ftape_next_buffer(ft_queue_tail); 276 - } 277 - /* Start tape only if all buffers full or flush mode. 278 - * This will give higher probability of streaming. 279 - */ 280 - if (ft_runner_status != running && 281 - ((tail->status == waiting && 282 - ftape_get_buffer(ft_queue_head) == tail) || 283 - write_mode != FT_WR_ASYNC)) { 284 - TRACE_CATCH(ftape_start_writing(write_mode),); 285 - } 286 - TRACE_EXIT bytes_written; 287 - } 288 - 289 - /* Write as much as fits from buffer to the given segment on tape 290 - * and handle retries. 291 - * Return the number of bytes written (>= 0), or: 292 - * -EIO write failed 293 - * -EINTR interrupted by signal 294 - * -ENOSPC device full 295 - */ 296 - int ftape_write_segment(const int segment_id, 297 - const void *buffer, 298 - const ft_write_mode_t flush) 299 - { 300 - int retry = 0; 301 - int result; 302 - TRACE_FUN(ft_t_flow); 303 - 304 - ft_history.used |= 2; 305 - if (segment_id >= ft_tracks_per_tape*ft_segments_per_track) { 306 - /* tape full */ 307 - TRACE_ABORT(-ENOSPC, ft_t_err, 308 - "invalid segment id: %d (max %d)", 309 - segment_id, 310 - ft_tracks_per_tape * ft_segments_per_track -1); 311 - } 312 - for (;;) { 313 - if ((result = write_segment(segment_id, buffer, flush)) >= 0) { 314 - if (result == 0) { /* empty segment */ 315 - TRACE(ft_t_noise, 316 - "empty segment, nothing written"); 317 - } 318 - TRACE_EXIT result; 319 - } 320 - if (result == -EAGAIN) { 321 - if (++retry > 100) { /* give up */ 322 - TRACE_ABORT(-EIO, ft_t_err, 323 - "write failed, >100 retries in segment"); 324 - } 325 - TRACE(ft_t_warn, "write error, retry %d (%d)", 326 - retry, 327 - ftape_get_buffer(ft_queue_tail)->segment_id); 328 - } else { 329 - TRACE_ABORT(result, ft_t_err, 330 - "write_segment failed, error: %d", result); 331 - } 332 - /* Allow escape from loop when signaled ! 333 - */ 334 - FT_SIGNAL_EXIT(_DONT_BLOCK); 335 - } 336 - }
-53
drivers/char/ftape/lowlevel/ftape-write.h
··· 1 - #ifndef _FTAPE_WRITE_H 2 - #define _FTAPE_WRITE_H 3 - 4 - /* 5 - * Copyright (C) 1994-1995 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-write.h,v $ 24 - $Author: claus $ 25 - * 26 - $Revision: 1.2 $ 27 - $Date: 1997/10/05 19:18:30 $ 28 - $State: Exp $ 29 - * 30 - * This file contains the definitions for the write functions 31 - * for the QIC-117 floppy-tape driver for Linux. 32 - * 33 - */ 34 - 35 - 36 - /* ftape-write.c defined global functions. 37 - */ 38 - typedef enum { 39 - FT_WR_ASYNC = 0, /* start tape only when all buffers are full */ 40 - FT_WR_MULTI = 1, /* start tape, but don't necessarily stop */ 41 - FT_WR_SINGLE = 2, /* write a single segment and stop afterwards */ 42 - FT_WR_DELETE = 3 /* write deleted data marks */ 43 - } ft_write_mode_t; 44 - 45 - extern int ftape_start_writing(const ft_write_mode_t mode); 46 - extern int ftape_write_segment(const int segment, 47 - const void *address, 48 - const ft_write_mode_t flushing); 49 - extern void ftape_zap_write_buffers(void); 50 - extern int ftape_loop_until_writes_done(void); 51 - 52 - #endif /* _FTAPE_WRITE_H */ 53 -
-87
drivers/char/ftape/lowlevel/ftape_syms.c
··· 1 - /* 2 - * Copyright (C) 1996-1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape_syms.c,v $ 20 - * $Revision: 1.4 $ 21 - * $Date: 1997/10/17 00:03:51 $ 22 - * 23 - * This file contains the symbols that the ftape low level 24 - * part of the QIC-40/80/3010/3020 floppy-tape driver "ftape" 25 - * exports to its high level clients 26 - */ 27 - 28 - #include <linux/module.h> 29 - 30 - #include <linux/ftape.h> 31 - #include "../lowlevel/ftape-tracing.h" 32 - #include "../lowlevel/ftape-init.h" 33 - #include "../lowlevel/fdc-io.h" 34 - #include "../lowlevel/ftape-read.h" 35 - #include "../lowlevel/ftape-write.h" 36 - #include "../lowlevel/ftape-io.h" 37 - #include "../lowlevel/ftape-ctl.h" 38 - #include "../lowlevel/ftape-rw.h" 39 - #include "../lowlevel/ftape-bsm.h" 40 - #include "../lowlevel/ftape-buffer.h" 41 - #include "../lowlevel/ftape-format.h" 42 - 43 - /* bad sector handling from ftape-bsm.c */ 44 - EXPORT_SYMBOL(ftape_get_bad_sector_entry); 45 - EXPORT_SYMBOL(ftape_find_end_of_bsm_list); 46 - /* from ftape-rw.c */ 47 - EXPORT_SYMBOL(ftape_set_state); 48 - /* from ftape-ctl.c */ 49 - EXPORT_SYMBOL(ftape_seek_to_bot); 50 - EXPORT_SYMBOL(ftape_seek_to_eot); 51 - EXPORT_SYMBOL(ftape_abort_operation); 52 - EXPORT_SYMBOL(ftape_get_status); 53 - EXPORT_SYMBOL(ftape_enable); 54 - EXPORT_SYMBOL(ftape_disable); 55 - EXPORT_SYMBOL(ftape_mmap); 56 - EXPORT_SYMBOL(ftape_calibrate_data_rate); 57 - /* from ftape-io.c */ 58 - EXPORT_SYMBOL(ftape_reset_drive); 59 - EXPORT_SYMBOL(ftape_command); 60 - EXPORT_SYMBOL(ftape_parameter); 61 - EXPORT_SYMBOL(ftape_ready_wait); 62 - EXPORT_SYMBOL(ftape_report_operation); 63 - EXPORT_SYMBOL(ftape_report_error); 64 - /* from ftape-read.c */ 65 - EXPORT_SYMBOL(ftape_read_segment_fraction); 66 - EXPORT_SYMBOL(ftape_zap_read_buffers); 67 - EXPORT_SYMBOL(ftape_read_header_segment); 68 - EXPORT_SYMBOL(ftape_decode_header_segment); 69 - /* from ftape-write.c */ 70 - EXPORT_SYMBOL(ftape_write_segment); 71 - EXPORT_SYMBOL(ftape_start_writing); 72 - EXPORT_SYMBOL(ftape_loop_until_writes_done); 73 - /* from ftape-buffer.h */ 74 - EXPORT_SYMBOL(ftape_set_nr_buffers); 75 - /* from ftape-format.h */ 76 - EXPORT_SYMBOL(ftape_format_track); 77 - EXPORT_SYMBOL(ftape_format_status); 78 - EXPORT_SYMBOL(ftape_verify_segment); 79 - /* from tracing.c */ 80 - #ifndef CONFIG_FT_NO_TRACE_AT_ALL 81 - EXPORT_SYMBOL(ftape_tracing); 82 - EXPORT_SYMBOL(ftape_function_nest_level); 83 - EXPORT_SYMBOL(ftape_trace_call); 84 - EXPORT_SYMBOL(ftape_trace_exit); 85 - EXPORT_SYMBOL(ftape_trace_log); 86 - #endif 87 -
-36
drivers/char/ftape/zftape/Makefile
··· 1 - # 2 - # Copyright (C) 1996, 1997 Claus-Justus Heine. 3 - # 4 - # This program is free software; you can redistribute it and/or modify 5 - # it under the terms of the GNU General Public License as published by 6 - # the Free Software Foundation; either version 2, or (at your option) 7 - # any later version. 8 - # 9 - # This program is distributed in the hope that it will be useful, 10 - # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - # GNU General Public License for more details. 13 - # 14 - # You should have received a copy of the GNU General Public License 15 - # along with this program; see the file COPYING. If not, write to 16 - # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - # 18 - # $Source: /homes/cvs/ftape-stacked/ftape/zftape/Makefile,v $ 19 - # $Revision: 1.4 $ 20 - # $Date: 1997/10/05 19:18:58 $ 21 - # 22 - # Makefile for the QIC-40/80/3010/3020 zftape interface VFS to 23 - # ftape 24 - # 25 - 26 - 27 - # ZFT_OBSOLETE - enable the MTIOC_ZFTAPE_GETBLKSZ ioctl. You should 28 - # leave this enabled for compatibility with taper. 29 - 30 - obj-$(CONFIG_ZFTAPE) += zftape.o 31 - 32 - zftape-objs := zftape-rw.o zftape-ctl.o zftape-read.o \ 33 - zftape-write.o zftape-vtbl.o zftape-eof.o \ 34 - zftape-init.o zftape-buffers.o zftape_syms.o 35 - 36 - EXTRA_CFLAGS := -DZFT_OBSOLETE
-149
drivers/char/ftape/zftape/zftape-buffers.c
··· 1 - /* 2 - * Copyright (C) 1995-1997 Claus-Justus Heine. 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-buffers.c,v $ 20 - * $Revision: 1.2 $ 21 - * $Date: 1997/10/05 19:18:59 $ 22 - * 23 - * This file contains the dynamic buffer allocation routines 24 - * of zftape 25 - */ 26 - 27 - #include <linux/errno.h> 28 - #include <linux/mm.h> 29 - #include <linux/slab.h> 30 - #include <linux/delay.h> 31 - 32 - #include <linux/zftape.h> 33 - 34 - #include <linux/vmalloc.h> 35 - 36 - #include "../zftape/zftape-init.h" 37 - #include "../zftape/zftape-eof.h" 38 - #include "../zftape/zftape-ctl.h" 39 - #include "../zftape/zftape-write.h" 40 - #include "../zftape/zftape-read.h" 41 - #include "../zftape/zftape-rw.h" 42 - #include "../zftape/zftape-vtbl.h" 43 - 44 - /* global variables 45 - */ 46 - 47 - /* local varibales 48 - */ 49 - static unsigned int used_memory; 50 - static unsigned int peak_memory; 51 - 52 - void zft_memory_stats(void) 53 - { 54 - TRACE_FUN(ft_t_flow); 55 - 56 - TRACE(ft_t_noise, "Memory usage (vmalloc allocations):\n" 57 - KERN_INFO "total allocated: %d\n" 58 - KERN_INFO "peak allocation: %d", 59 - used_memory, peak_memory); 60 - peak_memory = used_memory; 61 - TRACE_EXIT; 62 - } 63 - 64 - int zft_vcalloc_once(void *new, size_t size) 65 - { 66 - TRACE_FUN(ft_t_flow); 67 - if (zft_vmalloc_once(new, size) < 0) { 68 - TRACE_EXIT -ENOMEM; 69 - } 70 - memset(*(void **)new, '\0', size); 71 - TRACE_EXIT 0; 72 - } 73 - int zft_vmalloc_once(void *new, size_t size) 74 - { 75 - TRACE_FUN(ft_t_flow); 76 - 77 - if (*(void **)new != NULL || size == 0) { 78 - TRACE_EXIT 0; 79 - } 80 - if ((*(void **)new = vmalloc(size)) == NULL) { 81 - TRACE_EXIT -ENOMEM; 82 - } 83 - used_memory += size; 84 - if (peak_memory < used_memory) { 85 - peak_memory = used_memory; 86 - } 87 - TRACE_ABORT(0, ft_t_noise, 88 - "allocated buffer @ %p, %zd bytes", *(void **)new, size); 89 - } 90 - int zft_vmalloc_always(void *new, size_t size) 91 - { 92 - TRACE_FUN(ft_t_flow); 93 - 94 - zft_vfree(new, size); 95 - TRACE_EXIT zft_vmalloc_once(new, size); 96 - } 97 - void zft_vfree(void *old, size_t size) 98 - { 99 - TRACE_FUN(ft_t_flow); 100 - 101 - if (*(void **)old) { 102 - vfree(*(void **)old); 103 - used_memory -= size; 104 - TRACE(ft_t_noise, "released buffer @ %p, %zd bytes", 105 - *(void **)old, size); 106 - *(void **)old = NULL; 107 - } 108 - TRACE_EXIT; 109 - } 110 - 111 - void *zft_kmalloc(size_t size) 112 - { 113 - void *new; 114 - 115 - while ((new = kmalloc(size, GFP_KERNEL)) == NULL) { 116 - msleep_interruptible(100); 117 - } 118 - memset(new, 0, size); 119 - used_memory += size; 120 - if (peak_memory < used_memory) { 121 - peak_memory = used_memory; 122 - } 123 - return new; 124 - } 125 - 126 - void zft_kfree(void *old, size_t size) 127 - { 128 - kfree(old); 129 - used_memory -= size; 130 - } 131 - 132 - /* there are some more buffers that are allocated on demand. 133 - * cleanup_module() calles this function to be sure to have released 134 - * them 135 - */ 136 - void zft_uninit_mem(void) 137 - { 138 - TRACE_FUN(ft_t_flow); 139 - 140 - zft_vfree(&zft_hseg_buf, FT_SEGMENT_SIZE); 141 - zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE); zft_deblock_segment = -1; 142 - zft_free_vtbl(); 143 - if (zft_cmpr_lock(0 /* don't load */) == 0) { 144 - (*zft_cmpr_ops->cleanup)(); 145 - (*zft_cmpr_ops->reset)(); /* unlock it again */ 146 - } 147 - zft_memory_stats(); 148 - TRACE_EXIT; 149 - }
-55
drivers/char/ftape/zftape/zftape-buffers.h
··· 1 - #ifndef _FTAPE_DYNMEM_H 2 - #define _FTAPE_DYNMEM_H 3 - 4 - /* 5 - * Copyright (C) 1995-1997 Claus-Justus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-buffers.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:18:59 $ 25 - * 26 - * memory allocation routines. 27 - * 28 - */ 29 - 30 - /* we do not allocate all of the really large buffer memory before 31 - * someone tries to open the drive. ftape_open() may fail with 32 - * -ENOMEM, but that's better having 200k of vmalloced memory which 33 - * cannot be swapped out. 34 - */ 35 - 36 - extern void zft_memory_stats(void); 37 - extern int zft_vmalloc_once(void *new, size_t size); 38 - extern int zft_vcalloc_once(void *new, size_t size); 39 - extern int zft_vmalloc_always(void *new, size_t size); 40 - extern void zft_vfree(void *old, size_t size); 41 - extern void *zft_kmalloc(size_t size); 42 - extern void zft_kfree(void *old, size_t size); 43 - 44 - /* called by cleanup_module() 45 - */ 46 - extern void zft_uninit_mem(void); 47 - 48 - #endif 49 - 50 - 51 - 52 - 53 - 54 - 55 -
-1417
drivers/char/ftape/zftape/zftape-ctl.c
··· 1 - /* 2 - * Copyright (C) 1996, 1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-ctl.c,v $ 20 - * $Revision: 1.2.6.2 $ 21 - * $Date: 1997/11/14 18:07:33 $ 22 - * 23 - * This file contains the non-read/write zftape functions 24 - * for the QIC-40/80/3010/3020 floppy-tape driver for Linux. 25 - */ 26 - 27 - #include <linux/errno.h> 28 - #include <linux/mm.h> 29 - #include <linux/module.h> 30 - #include <linux/fcntl.h> 31 - 32 - #include <linux/zftape.h> 33 - 34 - #include <asm/uaccess.h> 35 - 36 - #include "../zftape/zftape-init.h" 37 - #include "../zftape/zftape-eof.h" 38 - #include "../zftape/zftape-ctl.h" 39 - #include "../zftape/zftape-write.h" 40 - #include "../zftape/zftape-read.h" 41 - #include "../zftape/zftape-rw.h" 42 - #include "../zftape/zftape-vtbl.h" 43 - 44 - /* Global vars. 45 - */ 46 - int zft_write_protected; /* this is when cartridge rdonly or O_RDONLY */ 47 - int zft_header_read; 48 - int zft_offline; 49 - unsigned int zft_unit; 50 - int zft_resid; 51 - int zft_mt_compression; 52 - 53 - /* Local vars. 54 - */ 55 - static int going_offline; 56 - 57 - typedef int (mt_fun)(int *argptr); 58 - typedef int (*mt_funp)(int *argptr); 59 - typedef struct 60 - { 61 - mt_funp function; 62 - unsigned offline : 1; /* op permitted if offline or no_tape */ 63 - unsigned write_protected : 1; /* op permitted if write-protected */ 64 - unsigned not_formatted : 1; /* op permitted if tape not formatted */ 65 - unsigned raw_mode : 1; /* op permitted if zft_mode == 0 */ 66 - unsigned need_idle_state : 1; /* need to call def_idle_state */ 67 - char *name; 68 - } fun_entry; 69 - 70 - static mt_fun mt_dummy, mt_reset, mt_fsr, mt_bsr, mt_rew, mt_offl, mt_nop, 71 - mt_weof, mt_erase, mt_ras2, mt_setblk, mt_setdensity, 72 - mt_seek, mt_tell, mt_reten, mt_eom, mt_fsf, mt_bsf, 73 - mt_fsfm, mt_bsfm, mt_setdrvbuffer, mt_compression; 74 - 75 - static fun_entry mt_funs[]= 76 - { 77 - {mt_reset , 1, 1, 1, 1, 0, "MT_RESET" }, /* 0 */ 78 - {mt_fsf , 0, 1, 0, 0, 1, "MT_FSF" }, 79 - {mt_bsf , 0, 1, 0, 0, 1, "MT_BSF" }, 80 - {mt_fsr , 0, 1, 0, 1, 1, "MT_FSR" }, 81 - {mt_bsr , 0, 1, 0, 1, 1, "MT_BSR" }, 82 - {mt_weof , 0, 0, 0, 0, 0, "MT_WEOF" }, /* 5 */ 83 - {mt_rew , 0, 1, 1, 1, 0, "MT_REW" }, 84 - {mt_offl , 0, 1, 1, 1, 0, "MT_OFFL" }, 85 - {mt_nop , 1, 1, 1, 1, 0, "MT_NOP" }, 86 - {mt_reten , 0, 1, 1, 1, 0, "MT_RETEN" }, 87 - {mt_bsfm , 0, 1, 0, 0, 1, "MT_BSFM" }, /* 10 */ 88 - {mt_fsfm , 0, 1, 0, 0, 1, "MT_FSFM" }, 89 - {mt_eom , 0, 1, 0, 0, 1, "MT_EOM" }, 90 - {mt_erase , 0, 0, 0, 1, 0, "MT_ERASE" }, 91 - {mt_dummy , 1, 1, 1, 1, 0, "MT_RAS1" }, 92 - {mt_ras2 , 0, 0, 0, 1, 0, "MT_RAS2" }, 93 - {mt_dummy , 1, 1, 1, 1, 0, "MT_RAS3" }, 94 - {mt_dummy , 1, 1, 1, 1, 0, "UNKNOWN" }, 95 - {mt_dummy , 1, 1, 1, 1, 0, "UNKNOWN" }, 96 - {mt_dummy , 1, 1, 1, 1, 0, "UNKNOWN" }, 97 - {mt_setblk , 1, 1, 1, 1, 1, "MT_SETBLK"}, /* 20 */ 98 - {mt_setdensity , 1, 1, 1, 1, 0, "MT_SETDENSITY"}, 99 - {mt_seek , 0, 1, 0, 1, 1, "MT_SEEK" }, 100 - {mt_dummy , 0, 1, 0, 1, 1, "MT_TELL" }, /* wr-only ?! */ 101 - {mt_setdrvbuffer, 1, 1, 1, 1, 0, "MT_SETDRVBUFFER" }, 102 - {mt_dummy , 1, 1, 1, 1, 0, "MT_FSS" }, /* 25 */ 103 - {mt_dummy , 1, 1, 1, 1, 0, "MT_BSS" }, 104 - {mt_dummy , 1, 1, 1, 1, 0, "MT_WSM" }, 105 - {mt_dummy , 1, 1, 1, 1, 0, "MT_LOCK" }, 106 - {mt_dummy , 1, 1, 1, 1, 0, "MT_UNLOCK"}, 107 - {mt_dummy , 1, 1, 1, 1, 0, "MT_LOAD" }, /* 30 */ 108 - {mt_dummy , 1, 1, 1, 1, 0, "MT_UNLOAD"}, 109 - {mt_compression , 1, 1, 1, 0, 1, "MT_COMPRESSION"}, 110 - {mt_dummy , 1, 1, 1, 1, 0, "MT_SETPART"}, 111 - {mt_dummy , 1, 1, 1, 1, 0, "MT_MKPART"} 112 - }; 113 - 114 - #define NR_MT_CMDS NR_ITEMS(mt_funs) 115 - 116 - void zft_reset_position(zft_position *pos) 117 - { 118 - TRACE_FUN(ft_t_flow); 119 - 120 - pos->seg_byte_pos = 121 - pos->volume_pos = 0; 122 - if (zft_header_read) { 123 - /* need to keep track of the volume table and 124 - * compression map. We therefor simply 125 - * position at the beginning of the first 126 - * volume. This covers old ftape archives as 127 - * well has various flavours of the 128 - * compression map segments. The worst case is 129 - * that the compression map shows up as a 130 - * additional volume in front of all others. 131 - */ 132 - pos->seg_pos = zft_find_volume(0)->start_seg; 133 - pos->tape_pos = zft_calc_tape_pos(pos->seg_pos); 134 - } else { 135 - pos->tape_pos = 0; 136 - pos->seg_pos = -1; 137 - } 138 - zft_just_before_eof = 0; 139 - zft_deblock_segment = -1; 140 - zft_io_state = zft_idle; 141 - zft_zap_read_buffers(); 142 - zft_prevent_flush(); 143 - /* unlock the compresison module if it is loaded. 144 - * The zero arg means not to try to load the module. 145 - */ 146 - if (zft_cmpr_lock(0) == 0) { 147 - (*zft_cmpr_ops->reset)(); /* unlock */ 148 - } 149 - TRACE_EXIT; 150 - } 151 - 152 - static void zft_init_driver(void) 153 - { 154 - TRACE_FUN(ft_t_flow); 155 - 156 - zft_resid = 157 - zft_header_read = 158 - zft_old_ftape = 159 - zft_offline = 160 - zft_write_protected = 161 - going_offline = 162 - zft_mt_compression = 163 - zft_header_changed = 164 - zft_volume_table_changed = 165 - zft_written_segments = 0; 166 - zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ; 167 - zft_reset_position(&zft_pos); /* does most of the stuff */ 168 - ftape_zap_read_buffers(); 169 - ftape_set_state(idle); 170 - TRACE_EXIT; 171 - } 172 - 173 - int zft_def_idle_state(void) 174 - { 175 - int result = 0; 176 - TRACE_FUN(ft_t_flow); 177 - 178 - if (!zft_header_read) { 179 - result = zft_read_header_segments(); 180 - } else if ((result = zft_flush_buffers()) >= 0 && zft_qic_mode) { 181 - /* don't move past eof 182 - */ 183 - (void)zft_close_volume(&zft_pos); 184 - } 185 - if (ftape_abort_operation() < 0) { 186 - TRACE(ft_t_warn, "ftape_abort_operation() failed"); 187 - result = -EIO; 188 - } 189 - /* clear remaining read buffers */ 190 - zft_zap_read_buffers(); 191 - zft_io_state = zft_idle; 192 - TRACE_EXIT result; 193 - } 194 - 195 - /***************************************************************************** 196 - * * 197 - * functions for the MTIOCTOP commands * 198 - * * 199 - *****************************************************************************/ 200 - 201 - static int mt_dummy(int *dummy) 202 - { 203 - TRACE_FUN(ft_t_flow); 204 - 205 - TRACE_EXIT -ENOSYS; 206 - } 207 - 208 - static int mt_reset(int *dummy) 209 - { 210 - TRACE_FUN(ft_t_flow); 211 - 212 - (void)ftape_seek_to_bot(); 213 - TRACE_CATCH(ftape_reset_drive(), 214 - zft_init_driver(); zft_uninit_mem(); zft_offline = 1); 215 - /* fake a re-open of the device. This will set all flage and 216 - * allocate buffers as appropriate. The new tape condition will 217 - * force the open routine to do anything we need. 218 - */ 219 - TRACE_CATCH(_zft_open(-1 /* fake reopen */, 0 /* dummy */),); 220 - TRACE_EXIT 0; 221 - } 222 - 223 - static int mt_fsf(int *arg) 224 - { 225 - int result; 226 - TRACE_FUN(ft_t_flow); 227 - 228 - result = zft_skip_volumes(*arg, &zft_pos); 229 - zft_just_before_eof = 0; 230 - TRACE_EXIT result; 231 - } 232 - 233 - static int mt_bsf(int *arg) 234 - { 235 - int result = 0; 236 - TRACE_FUN(ft_t_flow); 237 - 238 - if (*arg != 0) { 239 - result = zft_skip_volumes(-*arg + 1, &zft_pos); 240 - } 241 - TRACE_EXIT result; 242 - } 243 - 244 - static int seek_block(__s64 data_offset, 245 - __s64 block_increment, 246 - zft_position *pos) 247 - { 248 - int result = 0; 249 - __s64 new_block_pos; 250 - __s64 vol_block_count; 251 - const zft_volinfo *volume; 252 - int exceed; 253 - TRACE_FUN(ft_t_flow); 254 - 255 - volume = zft_find_volume(pos->seg_pos); 256 - if (volume->start_seg == 0 || volume->end_seg == 0) { 257 - TRACE_EXIT -EIO; 258 - } 259 - new_block_pos = (zft_div_blksz(data_offset, volume->blk_sz) 260 - + block_increment); 261 - vol_block_count = zft_div_blksz(volume->size, volume->blk_sz); 262 - if (new_block_pos < 0) { 263 - TRACE(ft_t_noise, 264 - "new_block_pos " LL_X " < 0", LL(new_block_pos)); 265 - zft_resid = (int)new_block_pos; 266 - new_block_pos = 0; 267 - exceed = 1; 268 - } else if (new_block_pos > vol_block_count) { 269 - TRACE(ft_t_noise, 270 - "new_block_pos " LL_X " exceeds size of volume " LL_X, 271 - LL(new_block_pos), LL(vol_block_count)); 272 - zft_resid = (int)(vol_block_count - new_block_pos); 273 - new_block_pos = vol_block_count; 274 - exceed = 1; 275 - } else { 276 - exceed = 0; 277 - } 278 - if (zft_use_compression && volume->use_compression) { 279 - TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),); 280 - result = (*zft_cmpr_ops->seek)(new_block_pos, pos, volume, 281 - zft_deblock_buf); 282 - pos->tape_pos = zft_calc_tape_pos(pos->seg_pos); 283 - pos->tape_pos += pos->seg_byte_pos; 284 - } else { 285 - pos->volume_pos = zft_mul_blksz(new_block_pos, volume->blk_sz); 286 - pos->tape_pos = zft_calc_tape_pos(volume->start_seg); 287 - pos->tape_pos += pos->volume_pos; 288 - pos->seg_pos = zft_calc_seg_byte_coord(&pos->seg_byte_pos, 289 - pos->tape_pos); 290 - } 291 - zft_just_before_eof = volume->size == pos->volume_pos; 292 - if (zft_just_before_eof) { 293 - /* why this? because zft_file_no checks agains start 294 - * and end segment of a volume. We do not want to 295 - * advance to the next volume with this function. 296 - */ 297 - TRACE(ft_t_noise, "set zft_just_before_eof"); 298 - zft_position_before_eof(pos, volume); 299 - } 300 - TRACE(ft_t_noise, "\n" 301 - KERN_INFO "new_seg_pos : %d\n" 302 - KERN_INFO "new_tape_pos: " LL_X "\n" 303 - KERN_INFO "vol_size : " LL_X "\n" 304 - KERN_INFO "seg_byte_pos: %d\n" 305 - KERN_INFO "blk_sz : %d", 306 - pos->seg_pos, LL(pos->tape_pos), 307 - LL(volume->size), pos->seg_byte_pos, 308 - volume->blk_sz); 309 - if (!exceed) { 310 - zft_resid = new_block_pos - zft_div_blksz(pos->volume_pos, 311 - volume->blk_sz); 312 - } 313 - if (zft_resid < 0) { 314 - zft_resid = -zft_resid; 315 - } 316 - TRACE_EXIT ((exceed || zft_resid != 0) && result >= 0) ? -EINVAL : result; 317 - } 318 - 319 - static int mt_fsr(int *arg) 320 - { 321 - int result; 322 - TRACE_FUN(ft_t_flow); 323 - 324 - result = seek_block(zft_pos.volume_pos, *arg, &zft_pos); 325 - TRACE_EXIT result; 326 - } 327 - 328 - static int mt_bsr(int *arg) 329 - { 330 - int result; 331 - TRACE_FUN(ft_t_flow); 332 - 333 - result = seek_block(zft_pos.volume_pos, -*arg, &zft_pos); 334 - TRACE_EXIT result; 335 - } 336 - 337 - static int mt_weof(int *arg) 338 - { 339 - int result; 340 - TRACE_FUN(ft_t_flow); 341 - 342 - TRACE_CATCH(zft_flush_buffers(),); 343 - result = zft_weof(*arg, &zft_pos); 344 - TRACE_EXIT result; 345 - } 346 - 347 - static int mt_rew(int *dummy) 348 - { 349 - int result; 350 - TRACE_FUN(ft_t_flow); 351 - 352 - if(zft_header_read) { 353 - (void)zft_def_idle_state(); 354 - } 355 - result = ftape_seek_to_bot(); 356 - zft_reset_position(&zft_pos); 357 - TRACE_EXIT result; 358 - } 359 - 360 - static int mt_offl(int *dummy) 361 - { 362 - int result; 363 - TRACE_FUN(ft_t_flow); 364 - 365 - going_offline= 1; 366 - result = mt_rew(NULL); 367 - TRACE_EXIT result; 368 - } 369 - 370 - static int mt_nop(int *dummy) 371 - { 372 - TRACE_FUN(ft_t_flow); 373 - /* should we set tape status? 374 - */ 375 - if (!zft_offline) { /* offline includes no_tape */ 376 - (void)zft_def_idle_state(); 377 - } 378 - TRACE_EXIT 0; 379 - } 380 - 381 - static int mt_reten(int *dummy) 382 - { 383 - int result; 384 - TRACE_FUN(ft_t_flow); 385 - 386 - if(zft_header_read) { 387 - (void)zft_def_idle_state(); 388 - } 389 - result = ftape_seek_to_eot(); 390 - if (result >= 0) { 391 - result = ftape_seek_to_bot(); 392 - } 393 - TRACE_EXIT(result); 394 - } 395 - 396 - static int fsfbsfm(int arg, zft_position *pos) 397 - { 398 - const zft_volinfo *vtbl; 399 - __s64 block_pos; 400 - TRACE_FUN(ft_t_flow); 401 - 402 - /* What to do? This should seek to the next file-mark and 403 - * position BEFORE. That is, a next write would just extend 404 - * the current file. Well. Let's just seek to the end of the 405 - * current file, if count == 1. If count > 1, then do a 406 - * "mt_fsf(count - 1)", and then seek to the end of that file. 407 - * If count == 0, do nothing 408 - */ 409 - if (arg == 0) { 410 - TRACE_EXIT 0; 411 - } 412 - zft_just_before_eof = 0; 413 - TRACE_CATCH(zft_skip_volumes(arg < 0 ? arg : arg-1, pos), 414 - if (arg > 0) { 415 - zft_resid ++; 416 - }); 417 - vtbl = zft_find_volume(pos->seg_pos); 418 - block_pos = zft_div_blksz(vtbl->size, vtbl->blk_sz); 419 - (void)seek_block(0, block_pos, pos); 420 - if (pos->volume_pos != vtbl->size) { 421 - zft_just_before_eof = 0; 422 - zft_resid = 1; 423 - /* we didn't managed to go there */ 424 - TRACE_ABORT(-EIO, ft_t_err, 425 - "wanted file position " LL_X ", arrived at " LL_X, 426 - LL(vtbl->size), LL(pos->volume_pos)); 427 - } 428 - zft_just_before_eof = 1; 429 - TRACE_EXIT 0; 430 - } 431 - 432 - static int mt_bsfm(int *arg) 433 - { 434 - int result; 435 - TRACE_FUN(ft_t_flow); 436 - 437 - result = fsfbsfm(-*arg, &zft_pos); 438 - TRACE_EXIT result; 439 - } 440 - 441 - static int mt_fsfm(int *arg) 442 - { 443 - int result; 444 - TRACE_FUN(ft_t_flow); 445 - 446 - result = fsfbsfm(*arg, &zft_pos); 447 - TRACE_EXIT result; 448 - } 449 - 450 - static int mt_eom(int *dummy) 451 - { 452 - TRACE_FUN(ft_t_flow); 453 - 454 - zft_skip_to_eom(&zft_pos); 455 - TRACE_EXIT 0; 456 - } 457 - 458 - static int mt_erase(int *dummy) 459 - { 460 - int result; 461 - TRACE_FUN(ft_t_flow); 462 - 463 - result = zft_erase(); 464 - TRACE_EXIT result; 465 - } 466 - 467 - static int mt_ras2(int *dummy) 468 - { 469 - int result; 470 - TRACE_FUN(ft_t_flow); 471 - 472 - result = -ENOSYS; 473 - TRACE_EXIT result; 474 - } 475 - 476 - /* Sets the new blocksize in BYTES 477 - * 478 - */ 479 - static int mt_setblk(int *new_size) 480 - { 481 - TRACE_FUN(ft_t_flow); 482 - 483 - if((unsigned int)(*new_size) > ZFT_MAX_BLK_SZ) { 484 - TRACE_ABORT(-EINVAL, ft_t_info, 485 - "desired blk_sz (%d) should be <= %d bytes", 486 - *new_size, ZFT_MAX_BLK_SZ); 487 - } 488 - if ((*new_size & (FT_SECTOR_SIZE-1)) != 0) { 489 - TRACE_ABORT(-EINVAL, ft_t_info, 490 - "desired blk_sz (%d) must be a multiple of %d bytes", 491 - *new_size, FT_SECTOR_SIZE); 492 - } 493 - if (*new_size == 0) { 494 - if (zft_use_compression) { 495 - TRACE_ABORT(-EINVAL, ft_t_info, 496 - "Variable block size not yet " 497 - "supported with compression"); 498 - } 499 - *new_size = 1; 500 - } 501 - zft_blk_sz = *new_size; 502 - TRACE_EXIT 0; 503 - } 504 - 505 - static int mt_setdensity(int *arg) 506 - { 507 - TRACE_FUN(ft_t_flow); 508 - 509 - SET_TRACE_LEVEL(*arg); 510 - TRACE(TRACE_LEVEL, "tracing set to %d", TRACE_LEVEL); 511 - if ((int)TRACE_LEVEL != *arg) { 512 - TRACE_EXIT -EINVAL; 513 - } 514 - TRACE_EXIT 0; 515 - } 516 - 517 - static int mt_seek(int *new_block_pos) 518 - { 519 - int result= 0; 520 - TRACE_FUN(ft_t_any); 521 - 522 - result = seek_block(0, (__s64)*new_block_pos, &zft_pos); 523 - TRACE_EXIT result; 524 - } 525 - 526 - /* OK, this is totally different from SCSI, but the worst thing that can 527 - * happen is that there is not enough defragmentated memory that can be 528 - * allocated. Also, there is a hardwired limit of 16 dma buffers in the 529 - * stock ftape module. This shouldn't bring the system down. 530 - * 531 - * NOTE: the argument specifies the total number of dma buffers to use. 532 - * The driver needs at least 3 buffers to function at all. 533 - * 534 - */ 535 - static int mt_setdrvbuffer(int *cnt) 536 - { 537 - TRACE_FUN(ft_t_flow); 538 - 539 - if (*cnt < 3) { 540 - TRACE_EXIT -EINVAL; 541 - } 542 - TRACE_CATCH(ftape_set_nr_buffers(*cnt),); 543 - TRACE_EXIT 0; 544 - } 545 - /* return the block position from start of volume 546 - */ 547 - static int mt_tell(int *arg) 548 - { 549 - TRACE_FUN(ft_t_flow); 550 - 551 - *arg = zft_div_blksz(zft_pos.volume_pos, 552 - zft_find_volume(zft_pos.seg_pos)->blk_sz); 553 - TRACE_EXIT 0; 554 - } 555 - 556 - static int mt_compression(int *arg) 557 - { 558 - TRACE_FUN(ft_t_flow); 559 - 560 - /* Ok. We could also check whether compression is available at 561 - * all by trying to load the compression module. We could 562 - * also check for a block size of 1 byte which is illegal 563 - * with compression. Instead of doing it here we rely on 564 - * zftape_write() to do the proper checks. 565 - */ 566 - if ((unsigned int)*arg > 1) { 567 - TRACE_EXIT -EINVAL; 568 - } 569 - if (*arg != 0 && zft_blk_sz == 1) { /* variable block size */ 570 - TRACE_ABORT(-EINVAL, ft_t_info, 571 - "Compression not yet supported " 572 - "with variable block size"); 573 - } 574 - zft_mt_compression = *arg; 575 - if ((zft_unit & ZFT_ZIP_MODE) == 0) { 576 - zft_use_compression = zft_mt_compression; 577 - } 578 - TRACE_EXIT 0; 579 - } 580 - 581 - /* check whether write access is allowed. Write access is denied when 582 - * + zft_write_protected == 1 -- this accounts for either hard write 583 - * protection of the cartridge or for 584 - * O_RDONLY access mode of the tape device 585 - * + zft_offline == 1 -- this meany that there is either no tape 586 - * or that the MTOFFLINE ioctl has been 587 - * previously issued (`soft eject') 588 - * + ft_formatted == 0 -- this means that the cartridge is not 589 - * formatted 590 - * Then we distinuguish two cases. When zft_qic_mode is TRUE, then we try 591 - * to emulate a `traditional' (aka SCSI like) UN*X tape device. Therefore we 592 - * deny writes when 593 - * + zft_qic_mode ==1 && 594 - * (!zft_tape_at_lbot() && -- tape no at logical BOT 595 - * !(zft_tape_at_eom() || -- tape not at logical EOM (or EOD) 596 - * (zft_tape_at_eom() && 597 - * zft_old_ftape()))) -- we can't add new volume to tapes 598 - * written by old ftape because ftape 599 - * don't use the volume table 600 - * 601 - * when the drive is in true raw mode (aka /dev/rawft0) then we don't 602 - * care about LBOT and EOM conditions. This device is intended for a 603 - * user level program that wants to truly implement the QIC-80 compliance 604 - * at the logical data layout level of the cartridge, i.e. implement all 605 - * that volume table and volume directory stuff etc.< 606 - */ 607 - int zft_check_write_access(zft_position *pos) 608 - { 609 - TRACE_FUN(ft_t_flow); 610 - 611 - if (zft_offline) { /* offline includes no_tape */ 612 - TRACE_ABORT(-ENXIO, 613 - ft_t_info, "tape is offline or no cartridge"); 614 - } 615 - if (!ft_formatted) { 616 - TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted"); 617 - } 618 - if (zft_write_protected) { 619 - TRACE_ABORT(-EACCES, ft_t_info, "cartridge write protected"); 620 - } 621 - if (zft_qic_mode) { 622 - /* check BOT condition */ 623 - if (!zft_tape_at_lbot(pos)) { 624 - /* protect cartridges written by old ftape if 625 - * not at BOT because they use the vtbl 626 - * segment for storing data 627 - */ 628 - if (zft_old_ftape) { 629 - TRACE_ABORT(-EACCES, ft_t_warn, 630 - "Cannot write to cartridges written by old ftape when not at BOT"); 631 - } 632 - /* not at BOT, but allow writes at EOD, of course 633 - */ 634 - if (!zft_tape_at_eod(pos)) { 635 - TRACE_ABORT(-EACCES, ft_t_info, 636 - "tape not at BOT and not at EOD"); 637 - } 638 - } 639 - /* fine. Now the tape is either at BOT or at EOD. */ 640 - } 641 - /* or in raw mode in which case we don't care about BOT and EOD */ 642 - TRACE_EXIT 0; 643 - } 644 - 645 - /* OPEN routine called by kernel-interface code 646 - * 647 - * NOTE: this is also called by mt_reset() with dev_minor == -1 648 - * to fake a reopen after a reset. 649 - */ 650 - int _zft_open(unsigned int dev_minor, unsigned int access_mode) 651 - { 652 - static unsigned int tape_unit; 653 - static unsigned int file_access_mode; 654 - int result; 655 - TRACE_FUN(ft_t_flow); 656 - 657 - if ((int)dev_minor == -1) { 658 - /* fake reopen */ 659 - zft_unit = tape_unit; 660 - access_mode = file_access_mode; 661 - zft_init_driver(); /* reset all static data to defaults */ 662 - } else { 663 - tape_unit = dev_minor; 664 - file_access_mode = access_mode; 665 - if ((result = ftape_enable(FTAPE_SEL(dev_minor))) < 0) { 666 - TRACE_ABORT(-ENXIO, ft_t_err, 667 - "ftape_enable failed: %d", result); 668 - } 669 - if (ft_new_tape || ft_no_tape || !ft_formatted || 670 - (FTAPE_SEL(zft_unit) != FTAPE_SEL(dev_minor)) || 671 - (zft_unit & ZFT_RAW_MODE) != (dev_minor & ZFT_RAW_MODE)) { 672 - /* reset all static data to defaults, 673 - */ 674 - zft_init_driver(); 675 - } 676 - zft_unit = dev_minor; 677 - } 678 - zft_set_flags(zft_unit); /* decode the minor bits */ 679 - if (zft_blk_sz == 1 && zft_use_compression) { 680 - ftape_disable(); /* resets ft_no_tape */ 681 - TRACE_ABORT(-ENODEV, ft_t_warn, "Variable block size not yet " 682 - "supported with compression"); 683 - } 684 - /* no need for most of the buffers when no tape or not 685 - * formatted. for the read/write operations, it is the 686 - * regardless whether there is no tape, a not-formatted tape 687 - * or the whether the driver is soft offline. 688 - * Nevertheless we allow some ioctls with non-formatted tapes, 689 - * like rewind and reset. 690 - */ 691 - if (ft_no_tape || !ft_formatted) { 692 - zft_uninit_mem(); 693 - } 694 - if (ft_no_tape) { 695 - zft_offline = 1; /* so we need not test two variables */ 696 - } 697 - if ((access_mode == O_WRONLY || access_mode == O_RDWR) && 698 - (ft_write_protected || ft_no_tape)) { 699 - ftape_disable(); /* resets ft_no_tape */ 700 - TRACE_ABORT(ft_no_tape ? -ENXIO : -EROFS, 701 - ft_t_warn, "wrong access mode %s cartridge", 702 - ft_no_tape ? "without a" : "with write protected"); 703 - } 704 - zft_write_protected = (access_mode == O_RDONLY || 705 - ft_write_protected != 0); 706 - if (zft_write_protected) { 707 - TRACE(ft_t_noise, 708 - "read only access mode: %d, " 709 - "drive write protected: %d", 710 - access_mode == O_RDONLY, 711 - ft_write_protected != 0); 712 - } 713 - if (!zft_offline) { 714 - TRACE_CATCH(zft_vmalloc_once(&zft_deblock_buf,FT_SEGMENT_SIZE), 715 - ftape_disable()); 716 - } 717 - /* zft_seg_pos should be greater than the vtbl segpos but not 718 - * if in compatibility mode and only after we read in the 719 - * header segments 720 - * 721 - * might also be a problem if the user makes a backup with a 722 - * *qft* device and rewinds it with a raw device. 723 - */ 724 - if (zft_qic_mode && 725 - !zft_old_ftape && 726 - zft_pos.seg_pos >= 0 && 727 - zft_header_read && 728 - zft_pos.seg_pos <= ft_first_data_segment) { 729 - TRACE(ft_t_noise, "you probably mixed up the zftape devices!"); 730 - zft_reset_position(&zft_pos); 731 - } 732 - TRACE_EXIT 0; 733 - } 734 - 735 - /* RELEASE routine called by kernel-interface code 736 - */ 737 - int _zft_close(void) 738 - { 739 - int result = 0; 740 - TRACE_FUN(ft_t_flow); 741 - 742 - if (zft_offline) { 743 - /* call the hardware release routine. Puts the drive offline */ 744 - ftape_disable(); 745 - TRACE_EXIT 0; 746 - } 747 - if (!(ft_write_protected || zft_old_ftape)) { 748 - result = zft_flush_buffers(); 749 - TRACE(ft_t_noise, "writing file mark at current position"); 750 - if (zft_qic_mode && zft_close_volume(&zft_pos) == 0) { 751 - zft_move_past_eof(&zft_pos); 752 - } 753 - if ((zft_tape_at_lbot(&zft_pos) || 754 - !(zft_unit & FTAPE_NO_REWIND))) { 755 - if (result >= 0) { 756 - result = zft_update_header_segments(); 757 - } else { 758 - TRACE(ft_t_err, 759 - "Error: unable to update header segments"); 760 - } 761 - } 762 - } 763 - ftape_abort_operation(); 764 - if (!(zft_unit & FTAPE_NO_REWIND)) { 765 - TRACE(ft_t_noise, "rewinding tape"); 766 - if (ftape_seek_to_bot() < 0 && result >= 0) { 767 - result = -EIO; /* keep old value */ 768 - } 769 - zft_reset_position(&zft_pos); 770 - } 771 - zft_zap_read_buffers(); 772 - /* now free up memory as much as possible. We don't destroy 773 - * the deblock buffer if it containes a valid segment. 774 - */ 775 - if (zft_deblock_segment == -1) { 776 - zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE); 777 - } 778 - /* high level driver status, forces creation of a new volume 779 - * when calling ftape_write again and not zft_just_before_eof 780 - */ 781 - zft_io_state = zft_idle; 782 - if (going_offline) { 783 - zft_init_driver(); 784 - zft_uninit_mem(); 785 - going_offline = 0; 786 - zft_offline = 1; 787 - } else if (zft_cmpr_lock(0 /* don't load */) == 0) { 788 - (*zft_cmpr_ops->reset)(); /* unlock it again */ 789 - } 790 - zft_memory_stats(); 791 - /* call the hardware release routine. Puts the drive offline */ 792 - ftape_disable(); 793 - TRACE_EXIT result; 794 - } 795 - 796 - /* 797 - * the wrapper function around the wrapper MTIOCTOP ioctl 798 - */ 799 - static int mtioctop(struct mtop *mtop, int arg_size) 800 - { 801 - int result = 0; 802 - fun_entry *mt_fun_entry; 803 - TRACE_FUN(ft_t_flow); 804 - 805 - if (arg_size != sizeof(struct mtop) || mtop->mt_op >= NR_MT_CMDS) { 806 - TRACE_EXIT -EINVAL; 807 - } 808 - TRACE(ft_t_noise, "calling MTIOCTOP command: %s", 809 - mt_funs[mtop->mt_op].name); 810 - mt_fun_entry= &mt_funs[mtop->mt_op]; 811 - zft_resid = mtop->mt_count; 812 - if (!mt_fun_entry->offline && zft_offline) { 813 - if (ft_no_tape) { 814 - TRACE_ABORT(-ENXIO, ft_t_info, "no tape present"); 815 - } else { 816 - TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline"); 817 - } 818 - } 819 - if (!mt_fun_entry->not_formatted && !ft_formatted) { 820 - TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted"); 821 - } 822 - if (!mt_fun_entry->write_protected) { 823 - TRACE_CATCH(zft_check_write_access(&zft_pos),); 824 - } 825 - if (mt_fun_entry->need_idle_state && !(zft_offline || !ft_formatted)) { 826 - TRACE_CATCH(zft_def_idle_state(),); 827 - } 828 - if (!zft_qic_mode && !mt_fun_entry->raw_mode) { 829 - TRACE_ABORT(-EACCES, ft_t_info, 830 - "Drive needs to be in QIC-80 compatibility mode for this command"); 831 - } 832 - result = (mt_fun_entry->function)(&mtop->mt_count); 833 - if (zft_tape_at_lbot(&zft_pos)) { 834 - TRACE_CATCH(zft_update_header_segments(),); 835 - } 836 - if (result >= 0) { 837 - zft_resid = 0; 838 - } 839 - TRACE_EXIT result; 840 - } 841 - 842 - /* 843 - * standard MTIOCGET ioctl 844 - */ 845 - static int mtiocget(struct mtget *mtget, int arg_size) 846 - { 847 - const zft_volinfo *volume; 848 - __s64 max_tape_pos; 849 - TRACE_FUN(ft_t_flow); 850 - 851 - if (arg_size != sizeof(struct mtget)) { 852 - TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d", 853 - arg_size); 854 - } 855 - mtget->mt_type = ft_drive_type.vendor_id + 0x800000; 856 - mtget->mt_dsreg = ft_last_status.space; 857 - mtget->mt_erreg = ft_last_error.space; /* error register */ 858 - mtget->mt_resid = zft_resid; /* residuum of writes, reads and 859 - * MTIOCTOP commands 860 - */ 861 - if (!zft_offline) { /* neither no_tape nor soft offline */ 862 - mtget->mt_gstat = GMT_ONLINE(~0UL); 863 - /* should rather return the status of the cartridge 864 - * than the access mode of the file, therefor use 865 - * ft_write_protected, not zft_write_protected 866 - */ 867 - if (ft_write_protected) { 868 - mtget->mt_gstat |= GMT_WR_PROT(~0UL); 869 - } 870 - if(zft_header_read) { /* this catches non-formatted */ 871 - volume = zft_find_volume(zft_pos.seg_pos); 872 - mtget->mt_fileno = volume->count; 873 - max_tape_pos = zft_capacity - zft_blk_sz; 874 - if (zft_use_compression) { 875 - max_tape_pos -= ZFT_CMPR_OVERHEAD; 876 - } 877 - if (zft_tape_at_eod(&zft_pos)) { 878 - mtget->mt_gstat |= GMT_EOD(~0UL); 879 - } 880 - if (zft_pos.tape_pos > max_tape_pos) { 881 - mtget->mt_gstat |= GMT_EOT(~0UL); 882 - } 883 - mtget->mt_blkno = zft_div_blksz(zft_pos.volume_pos, 884 - volume->blk_sz); 885 - if (zft_just_before_eof) { 886 - mtget->mt_gstat |= GMT_EOF(~0UL); 887 - } 888 - if (zft_tape_at_lbot(&zft_pos)) { 889 - mtget->mt_gstat |= GMT_BOT(~0UL); 890 - } 891 - } else { 892 - mtget->mt_fileno = mtget->mt_blkno = -1; 893 - if (mtget->mt_dsreg & QIC_STATUS_AT_BOT) { 894 - mtget->mt_gstat |= GMT_BOT(~0UL); 895 - } 896 - } 897 - } else { 898 - if (ft_no_tape) { 899 - mtget->mt_gstat = GMT_DR_OPEN(~0UL); 900 - } else { 901 - mtget->mt_gstat = 0UL; 902 - } 903 - mtget->mt_fileno = mtget->mt_blkno = -1; 904 - } 905 - TRACE_EXIT 0; 906 - } 907 - 908 - #ifdef MTIOCRDFTSEG 909 - /* 910 - * Read a floppy tape segment. This is useful for manipulating the 911 - * volume table, and read the old header segment before re-formatting 912 - * the cartridge. 913 - */ 914 - static int mtiocrdftseg(struct mtftseg * mtftseg, int arg_size) 915 - { 916 - TRACE_FUN(ft_t_flow); 917 - 918 - TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCRDFTSEG"); 919 - if (zft_qic_mode) { 920 - TRACE_ABORT(-EACCES, ft_t_info, 921 - "driver needs to be in raw mode for this ioctl"); 922 - } 923 - if (arg_size != sizeof(struct mtftseg)) { 924 - TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d", 925 - arg_size); 926 - } 927 - if (zft_offline) { 928 - TRACE_EXIT -ENXIO; 929 - } 930 - if (mtftseg->mt_mode != FT_RD_SINGLE && 931 - mtftseg->mt_mode != FT_RD_AHEAD) { 932 - TRACE_ABORT(-EINVAL, ft_t_info, "invalid read mode"); 933 - } 934 - if (!ft_formatted) { 935 - TRACE_EXIT -EACCES; /* -ENXIO ? */ 936 - 937 - } 938 - if (!zft_header_read) { 939 - TRACE_CATCH(zft_def_idle_state(),); 940 - } 941 - if (mtftseg->mt_segno > ft_last_data_segment) { 942 - TRACE_ABORT(-EINVAL, ft_t_info, "segment number is too large"); 943 - } 944 - mtftseg->mt_result = ftape_read_segment(mtftseg->mt_segno, 945 - zft_deblock_buf, 946 - mtftseg->mt_mode); 947 - if (mtftseg->mt_result < 0) { 948 - /* a negativ result is not an ioctl error. if 949 - * the user wants to read damaged tapes, 950 - * it's up to her/him 951 - */ 952 - TRACE_EXIT 0; 953 - } 954 - if (copy_to_user(mtftseg->mt_data, 955 - zft_deblock_buf, 956 - mtftseg->mt_result) != 0) { 957 - TRACE_EXIT -EFAULT; 958 - } 959 - TRACE_EXIT 0; 960 - } 961 - #endif 962 - 963 - #ifdef MTIOCWRFTSEG 964 - /* 965 - * write a floppy tape segment. This version features writing of 966 - * deleted address marks, and gracefully ignores the (software) 967 - * ft_formatted flag to support writing of header segments after 968 - * formatting. 969 - */ 970 - static int mtiocwrftseg(struct mtftseg * mtftseg, int arg_size) 971 - { 972 - int result; 973 - TRACE_FUN(ft_t_flow); 974 - 975 - TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCWRFTSEG"); 976 - if (zft_write_protected || zft_qic_mode) { 977 - TRACE_EXIT -EACCES; 978 - } 979 - if (arg_size != sizeof(struct mtftseg)) { 980 - TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d", 981 - arg_size); 982 - } 983 - if (zft_offline) { 984 - TRACE_EXIT -ENXIO; 985 - } 986 - if (mtftseg->mt_mode != FT_WR_ASYNC && 987 - mtftseg->mt_mode != FT_WR_MULTI && 988 - mtftseg->mt_mode != FT_WR_SINGLE && 989 - mtftseg->mt_mode != FT_WR_DELETE) { 990 - TRACE_ABORT(-EINVAL, ft_t_info, "invalid write mode"); 991 - } 992 - /* 993 - * We don't check for ft_formatted, because this gives 994 - * only the software status of the driver. 995 - * 996 - * We assume that the user knows what it is 997 - * doing. And rely on the low level stuff to fail 998 - * when the tape isn't formatted. We only make sure 999 - * that The header segment buffer is allocated, 1000 - * because it holds the bad sector map. 1001 - */ 1002 - if (zft_hseg_buf == NULL) { 1003 - TRACE_EXIT -ENXIO; 1004 - } 1005 - if (mtftseg->mt_mode != FT_WR_DELETE) { 1006 - if (copy_from_user(zft_deblock_buf, 1007 - mtftseg->mt_data, 1008 - FT_SEGMENT_SIZE) != 0) { 1009 - TRACE_EXIT -EFAULT; 1010 - } 1011 - } 1012 - mtftseg->mt_result = ftape_write_segment(mtftseg->mt_segno, 1013 - zft_deblock_buf, 1014 - mtftseg->mt_mode); 1015 - if (mtftseg->mt_result >= 0 && mtftseg->mt_mode == FT_WR_SINGLE) { 1016 - /* 1017 - * a negativ result is not an ioctl error. if 1018 - * the user wants to write damaged tapes, 1019 - * it's up to her/him 1020 - */ 1021 - if ((result = ftape_loop_until_writes_done()) < 0) { 1022 - mtftseg->mt_result = result; 1023 - } 1024 - } 1025 - TRACE_EXIT 0; 1026 - } 1027 - #endif 1028 - 1029 - #ifdef MTIOCVOLINFO 1030 - /* 1031 - * get information about volume positioned at. 1032 - */ 1033 - static int mtiocvolinfo(struct mtvolinfo *volinfo, int arg_size) 1034 - { 1035 - const zft_volinfo *volume; 1036 - TRACE_FUN(ft_t_flow); 1037 - 1038 - TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCVOLINFO"); 1039 - if (arg_size != sizeof(struct mtvolinfo)) { 1040 - TRACE_ABORT(-EINVAL, 1041 - ft_t_info, "bad argument size: %d", arg_size); 1042 - } 1043 - if (zft_offline) { 1044 - TRACE_EXIT -ENXIO; 1045 - } 1046 - if (!ft_formatted) { 1047 - TRACE_EXIT -EACCES; 1048 - } 1049 - TRACE_CATCH(zft_def_idle_state(),); 1050 - volume = zft_find_volume(zft_pos.seg_pos); 1051 - volinfo->mt_volno = volume->count; 1052 - volinfo->mt_blksz = volume->blk_sz == 1 ? 0 : volume->blk_sz; 1053 - volinfo->mt_size = volume->size >> 10; 1054 - volinfo->mt_rawsize = ((zft_calc_tape_pos(volume->end_seg + 1) >> 10) - 1055 - (zft_calc_tape_pos(volume->start_seg) >> 10)); 1056 - volinfo->mt_cmpr = volume->use_compression; 1057 - TRACE_EXIT 0; 1058 - } 1059 - #endif 1060 - 1061 - #ifdef ZFT_OBSOLETE 1062 - static int mtioc_zftape_getblksz(struct mtblksz *blksz, int arg_size) 1063 - { 1064 - TRACE_FUN(ft_t_flow); 1065 - 1066 - TRACE(ft_t_noise, "\n" 1067 - KERN_INFO "Mag tape ioctl command: MTIOC_ZTAPE_GETBLKSZ\n" 1068 - KERN_INFO "This ioctl is here merely for compatibility.\n" 1069 - KERN_INFO "Please use MTIOCVOLINFO instead"); 1070 - if (arg_size != sizeof(struct mtblksz)) { 1071 - TRACE_ABORT(-EINVAL, 1072 - ft_t_info, "bad argument size: %d", arg_size); 1073 - } 1074 - if (zft_offline) { 1075 - TRACE_EXIT -ENXIO; 1076 - } 1077 - if (!ft_formatted) { 1078 - TRACE_EXIT -EACCES; 1079 - } 1080 - TRACE_CATCH(zft_def_idle_state(),); 1081 - blksz->mt_blksz = zft_find_volume(zft_pos.seg_pos)->blk_sz; 1082 - TRACE_EXIT 0; 1083 - } 1084 - #endif 1085 - 1086 - #ifdef MTIOCGETSIZE 1087 - /* 1088 - * get the capacity of the tape cartridge. 1089 - */ 1090 - static int mtiocgetsize(struct mttapesize *size, int arg_size) 1091 - { 1092 - TRACE_FUN(ft_t_flow); 1093 - 1094 - TRACE(ft_t_noise, "Mag tape ioctl command: MTIOC_ZFTAPE_GETSIZE"); 1095 - if (arg_size != sizeof(struct mttapesize)) { 1096 - TRACE_ABORT(-EINVAL, 1097 - ft_t_info, "bad argument size: %d", arg_size); 1098 - } 1099 - if (zft_offline) { 1100 - TRACE_EXIT -ENXIO; 1101 - } 1102 - if (!ft_formatted) { 1103 - TRACE_EXIT -EACCES; 1104 - } 1105 - TRACE_CATCH(zft_def_idle_state(),); 1106 - size->mt_capacity = (unsigned int)(zft_capacity>>10); 1107 - size->mt_used = (unsigned int)(zft_get_eom_pos()>>10); 1108 - TRACE_EXIT 0; 1109 - } 1110 - #endif 1111 - 1112 - static int mtiocpos(struct mtpos *mtpos, int arg_size) 1113 - { 1114 - int result; 1115 - TRACE_FUN(ft_t_flow); 1116 - 1117 - TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCPOS"); 1118 - if (arg_size != sizeof(struct mtpos)) { 1119 - TRACE_ABORT(-EINVAL, 1120 - ft_t_info, "bad argument size: %d", arg_size); 1121 - } 1122 - result = mt_tell((int *)&mtpos->mt_blkno); 1123 - TRACE_EXIT result; 1124 - } 1125 - 1126 - #ifdef MTIOCFTFORMAT 1127 - /* 1128 - * formatting of floppy tape cartridges. This is intended to be used 1129 - * together with the MTIOCFTCMD ioctl and the new mmap feature 1130 - */ 1131 - 1132 - /* 1133 - * This function uses ftape_decode_header_segment() to inform the low 1134 - * level ftape module about the new parameters. 1135 - * 1136 - * It erases the hseg_buf. The calling process must specify all 1137 - * parameters to assure proper operation. 1138 - * 1139 - * return values: -EINVAL - wrong argument size 1140 - * -EINVAL - if ftape_decode_header_segment() failed. 1141 - */ 1142 - static int set_format_parms(struct ftfmtparms *p, __u8 *hseg_buf) 1143 - { 1144 - ft_trace_t old_level = TRACE_LEVEL; 1145 - TRACE_FUN(ft_t_flow); 1146 - 1147 - TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_SETPARMS"); 1148 - memset(hseg_buf, 0, FT_SEGMENT_SIZE); 1149 - PUT4(hseg_buf, FT_SIGNATURE, FT_HSEG_MAGIC); 1150 - 1151 - /* fill in user specified parameters 1152 - */ 1153 - hseg_buf[FT_FMT_CODE] = (__u8)p->ft_fmtcode; 1154 - PUT2(hseg_buf, FT_SPT, p->ft_spt); 1155 - hseg_buf[FT_TPC] = (__u8)p->ft_tpc; 1156 - hseg_buf[FT_FHM] = (__u8)p->ft_fhm; 1157 - hseg_buf[FT_FTM] = (__u8)p->ft_ftm; 1158 - 1159 - /* fill in sane defaults to make ftape happy. 1160 - */ 1161 - hseg_buf[FT_FSM] = (__u8)128; /* 128 is hard wired all over ftape */ 1162 - if (p->ft_fmtcode == fmt_big) { 1163 - PUT4(hseg_buf, FT_6_HSEG_1, 0); 1164 - PUT4(hseg_buf, FT_6_HSEG_2, 1); 1165 - PUT4(hseg_buf, FT_6_FRST_SEG, 2); 1166 - PUT4(hseg_buf, FT_6_LAST_SEG, p->ft_spt * p->ft_tpc - 1); 1167 - } else { 1168 - PUT2(hseg_buf, FT_HSEG_1, 0); 1169 - PUT2(hseg_buf, FT_HSEG_2, 1); 1170 - PUT2(hseg_buf, FT_FRST_SEG, 2); 1171 - PUT2(hseg_buf, FT_LAST_SEG, p->ft_spt * p->ft_tpc - 1); 1172 - } 1173 - 1174 - /* Synchronize with the low level module. This is particularly 1175 - * needed for unformatted cartridges as the QIC std was previously 1176 - * unknown BUT is needed to set data rate and to calculate timeouts. 1177 - */ 1178 - TRACE_CATCH(ftape_calibrate_data_rate(p->ft_qicstd&QIC_TAPE_STD_MASK), 1179 - _res = -EINVAL); 1180 - 1181 - /* The following will also recalcualte the timeouts for the tape 1182 - * length and QIC std we want to format to. 1183 - * abort with -EINVAL rather than -EIO 1184 - */ 1185 - SET_TRACE_LEVEL(ft_t_warn); 1186 - TRACE_CATCH(ftape_decode_header_segment(hseg_buf), 1187 - SET_TRACE_LEVEL(old_level); _res = -EINVAL); 1188 - SET_TRACE_LEVEL(old_level); 1189 - TRACE_EXIT 0; 1190 - } 1191 - 1192 - /* 1193 - * Return the internal SOFTWARE status of the kernel driver. This does 1194 - * NOT query the tape drive about its status. 1195 - */ 1196 - static int get_format_parms(struct ftfmtparms *p, __u8 *hseg_buffer) 1197 - { 1198 - TRACE_FUN(ft_t_flow); 1199 - 1200 - TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_GETPARMS"); 1201 - p->ft_qicstd = ft_qic_std; 1202 - p->ft_fmtcode = ft_format_code; 1203 - p->ft_fhm = hseg_buffer[FT_FHM]; 1204 - p->ft_ftm = hseg_buffer[FT_FTM]; 1205 - p->ft_spt = ft_segments_per_track; 1206 - p->ft_tpc = ft_tracks_per_tape; 1207 - TRACE_EXIT 0; 1208 - } 1209 - 1210 - static int mtiocftformat(struct mtftformat *mtftformat, int arg_size) 1211 - { 1212 - int result; 1213 - union fmt_arg *arg = &mtftformat->fmt_arg; 1214 - TRACE_FUN(ft_t_flow); 1215 - 1216 - TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTFORMAT"); 1217 - if (zft_offline) { 1218 - if (ft_no_tape) { 1219 - TRACE_ABORT(-ENXIO, ft_t_info, "no tape present"); 1220 - } else { 1221 - TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline"); 1222 - } 1223 - } 1224 - if (zft_qic_mode) { 1225 - TRACE_ABORT(-EACCES, ft_t_info, 1226 - "driver needs to be in raw mode for this ioctl"); 1227 - } 1228 - if (zft_hseg_buf == NULL) { 1229 - TRACE_CATCH(zft_vcalloc_once(&zft_hseg_buf, FT_SEGMENT_SIZE),); 1230 - } 1231 - zft_header_read = 0; 1232 - switch(mtftformat->fmt_op) { 1233 - case FTFMT_SET_PARMS: 1234 - TRACE_CATCH(set_format_parms(&arg->fmt_parms, zft_hseg_buf),); 1235 - TRACE_EXIT 0; 1236 - case FTFMT_GET_PARMS: 1237 - TRACE_CATCH(get_format_parms(&arg->fmt_parms, zft_hseg_buf),); 1238 - TRACE_EXIT 0; 1239 - case FTFMT_FORMAT_TRACK: 1240 - if ((ft_formatted && zft_check_write_access(&zft_pos) < 0) || 1241 - (!ft_formatted && zft_write_protected)) { 1242 - TRACE_ABORT(-EACCES, ft_t_info, "Write access denied"); 1243 - } 1244 - TRACE_CATCH(ftape_format_track(arg->fmt_track.ft_track, 1245 - arg->fmt_track.ft_gap3),); 1246 - TRACE_EXIT 0; 1247 - case FTFMT_STATUS: 1248 - TRACE_CATCH(ftape_format_status(&arg->fmt_status.ft_segment),); 1249 - TRACE_EXIT 0; 1250 - case FTFMT_VERIFY: 1251 - TRACE_CATCH(ftape_verify_segment(arg->fmt_verify.ft_segment, 1252 - (SectorMap *)&arg->fmt_verify.ft_bsm),); 1253 - TRACE_EXIT 0; 1254 - default: 1255 - TRACE_ABORT(-EINVAL, ft_t_err, "Invalid format operation"); 1256 - } 1257 - TRACE_EXIT result; 1258 - } 1259 - #endif 1260 - 1261 - #ifdef MTIOCFTCMD 1262 - /* 1263 - * send a QIC-117 command to the drive, with optional timeouts, 1264 - * parameter and result bits. This is intended to be used together 1265 - * with the formatting ioctl. 1266 - */ 1267 - static int mtiocftcmd(struct mtftcmd *ftcmd, int arg_size) 1268 - { 1269 - int i; 1270 - TRACE_FUN(ft_t_flow); 1271 - 1272 - TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTCMD"); 1273 - if (!capable(CAP_SYS_ADMIN)) { 1274 - TRACE_ABORT(-EPERM, ft_t_info, 1275 - "need CAP_SYS_ADMIN capability to send raw qic-117 commands"); 1276 - } 1277 - if (zft_qic_mode) { 1278 - TRACE_ABORT(-EACCES, ft_t_info, 1279 - "driver needs to be in raw mode for this ioctl"); 1280 - } 1281 - if (arg_size != sizeof(struct mtftcmd)) { 1282 - TRACE_ABORT(-EINVAL, 1283 - ft_t_info, "bad argument size: %d", arg_size); 1284 - } 1285 - if (ftcmd->ft_wait_before) { 1286 - TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_before, 1287 - &ftcmd->ft_status),); 1288 - } 1289 - if (ftcmd->ft_status & QIC_STATUS_ERROR) 1290 - goto ftmtcmd_error; 1291 - if (ftcmd->ft_result_bits != 0) { 1292 - TRACE_CATCH(ftape_report_operation(&ftcmd->ft_result, 1293 - ftcmd->ft_cmd, 1294 - ftcmd->ft_result_bits),); 1295 - } else { 1296 - TRACE_CATCH(ftape_command(ftcmd->ft_cmd),); 1297 - if (ftcmd->ft_status & QIC_STATUS_ERROR) 1298 - goto ftmtcmd_error; 1299 - for (i = 0; i < ftcmd->ft_parm_cnt; i++) { 1300 - TRACE_CATCH(ftape_parameter(ftcmd->ft_parms[i]&0x0f),); 1301 - if (ftcmd->ft_status & QIC_STATUS_ERROR) 1302 - goto ftmtcmd_error; 1303 - } 1304 - } 1305 - if (ftcmd->ft_wait_after != 0) { 1306 - TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_after, 1307 - &ftcmd->ft_status),); 1308 - } 1309 - ftmtcmd_error: 1310 - if (ftcmd->ft_status & QIC_STATUS_ERROR) { 1311 - TRACE(ft_t_noise, "error status set"); 1312 - TRACE_CATCH(ftape_report_error(&ftcmd->ft_error, 1313 - &ftcmd->ft_cmd, 1),); 1314 - } 1315 - TRACE_EXIT 0; /* this is not an i/o error */ 1316 - } 1317 - #endif 1318 - 1319 - /* IOCTL routine called by kernel-interface code 1320 - */ 1321 - int _zft_ioctl(unsigned int command, void __user * arg) 1322 - { 1323 - int result; 1324 - union { struct mtop mtop; 1325 - struct mtget mtget; 1326 - struct mtpos mtpos; 1327 - #ifdef MTIOCRDFTSEG 1328 - struct mtftseg mtftseg; 1329 - #endif 1330 - #ifdef MTIOCVOLINFO 1331 - struct mtvolinfo mtvolinfo; 1332 - #endif 1333 - #ifdef MTIOCGETSIZE 1334 - struct mttapesize mttapesize; 1335 - #endif 1336 - #ifdef MTIOCFTFORMAT 1337 - struct mtftformat mtftformat; 1338 - #endif 1339 - #ifdef ZFT_OBSOLETE 1340 - struct mtblksz mtblksz; 1341 - #endif 1342 - #ifdef MTIOCFTCMD 1343 - struct mtftcmd mtftcmd; 1344 - #endif 1345 - } krnl_arg; 1346 - int arg_size = _IOC_SIZE(command); 1347 - int dir = _IOC_DIR(command); 1348 - TRACE_FUN(ft_t_flow); 1349 - 1350 - /* This check will only catch arguments that are too large ! 1351 - */ 1352 - if (dir & (_IOC_READ | _IOC_WRITE) && arg_size > sizeof(krnl_arg)) { 1353 - TRACE_ABORT(-EINVAL, 1354 - ft_t_info, "bad argument size: %d", arg_size); 1355 - } 1356 - if (dir & _IOC_WRITE) { 1357 - if (copy_from_user(&krnl_arg, arg, arg_size) != 0) { 1358 - TRACE_EXIT -EFAULT; 1359 - } 1360 - } 1361 - TRACE(ft_t_flow, "called with ioctl command: 0x%08x", command); 1362 - switch (command) { 1363 - case MTIOCTOP: 1364 - result = mtioctop(&krnl_arg.mtop, arg_size); 1365 - break; 1366 - case MTIOCGET: 1367 - result = mtiocget(&krnl_arg.mtget, arg_size); 1368 - break; 1369 - case MTIOCPOS: 1370 - result = mtiocpos(&krnl_arg.mtpos, arg_size); 1371 - break; 1372 - #ifdef MTIOCVOLINFO 1373 - case MTIOCVOLINFO: 1374 - result = mtiocvolinfo(&krnl_arg.mtvolinfo, arg_size); 1375 - break; 1376 - #endif 1377 - #ifdef ZFT_OBSOLETE 1378 - case MTIOC_ZFTAPE_GETBLKSZ: 1379 - result = mtioc_zftape_getblksz(&krnl_arg.mtblksz, arg_size); 1380 - break; 1381 - #endif 1382 - #ifdef MTIOCRDFTSEG 1383 - case MTIOCRDFTSEG: /* read a segment via ioctl */ 1384 - result = mtiocrdftseg(&krnl_arg.mtftseg, arg_size); 1385 - break; 1386 - #endif 1387 - #ifdef MTIOCWRFTSEG 1388 - case MTIOCWRFTSEG: /* write a segment via ioctl */ 1389 - result = mtiocwrftseg(&krnl_arg.mtftseg, arg_size); 1390 - break; 1391 - #endif 1392 - #ifdef MTIOCGETSIZE 1393 - case MTIOCGETSIZE: 1394 - result = mtiocgetsize(&krnl_arg.mttapesize, arg_size); 1395 - break; 1396 - #endif 1397 - #ifdef MTIOCFTFORMAT 1398 - case MTIOCFTFORMAT: 1399 - result = mtiocftformat(&krnl_arg.mtftformat, arg_size); 1400 - break; 1401 - #endif 1402 - #ifdef MTIOCFTCMD 1403 - case MTIOCFTCMD: 1404 - result = mtiocftcmd(&krnl_arg.mtftcmd, arg_size); 1405 - break; 1406 - #endif 1407 - default: 1408 - result = -EINVAL; 1409 - break; 1410 - } 1411 - if ((result >= 0) && (dir & _IOC_READ)) { 1412 - if (copy_to_user(arg, &krnl_arg, arg_size) != 0) { 1413 - TRACE_EXIT -EFAULT; 1414 - } 1415 - } 1416 - TRACE_EXIT result; 1417 - }
-58
drivers/char/ftape/zftape/zftape-ctl.h
··· 1 - #ifndef _ZFTAPE_CTL_H 2 - #define _ZFTAPE_CTL_H 3 - 4 - /* 5 - * Copyright (C) 1996, 1997 Claus-Justus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-ctl.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:19:02 $ 25 - * 26 - * This file contains the non-standard IOCTL related definitions 27 - * for the QIC-40/80 floppy-tape driver for Linux. 28 - */ 29 - 30 - #include <linux/ioctl.h> 31 - #include <linux/mtio.h> 32 - 33 - #include "../zftape/zftape-rw.h" 34 - 35 - #ifdef CONFIG_ZFTAPE_MODULE 36 - #define ftape_status (*zft_status) 37 - #endif 38 - 39 - extern int zft_offline; 40 - extern int zft_mt_compression; 41 - extern int zft_write_protected; 42 - extern int zft_header_read; 43 - extern unsigned int zft_unit; 44 - extern int zft_resid; 45 - 46 - extern void zft_reset_position(zft_position *pos); 47 - extern int zft_check_write_access(zft_position *pos); 48 - extern int zft_def_idle_state(void); 49 - 50 - /* hooks for the VFS interface 51 - */ 52 - extern int _zft_open(unsigned int dev_minor, unsigned int access_mode); 53 - extern int _zft_close(void); 54 - extern int _zft_ioctl(unsigned int command, void __user *arg); 55 - #endif 56 - 57 - 58 -
-199
drivers/char/ftape/zftape/zftape-eof.c
··· 1 - /* 2 - * I use these routines just to decide when I have to fake a 3 - * volume-table to preserve compatibility to original ftape. 4 - */ 5 - /* 6 - * Copyright (C) 1994-1995 Bas Laarhoven. 7 - * 8 - * Modified for zftape 1996, 1997 Claus Heine. 9 - 10 - This program is free software; you can redistribute it and/or modify 11 - it under the terms of the GNU General Public License as published by 12 - the Free Software Foundation; either version 2, or (at your option) 13 - any later version. 14 - 15 - This program is distributed in the hope that it will be useful, 16 - but WITHOUT ANY WARRANTY; without even the implied warranty of 17 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 - GNU General Public License for more details. 19 - 20 - You should have received a copy of the GNU General Public License 21 - along with this program; see the file COPYING. If not, write to 22 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 - 24 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-eof.c,v $ 25 - * $Revision: 1.2 $ 26 - * $Date: 1997/10/05 19:19:02 $ 27 - * 28 - * This file contains the eof mark handling code 29 - * for the QIC-40/80 floppy-tape driver for Linux. 30 - */ 31 - 32 - #include <linux/string.h> 33 - #include <linux/errno.h> 34 - 35 - #include <linux/zftape.h> 36 - 37 - #include "../zftape/zftape-init.h" 38 - #include "../zftape/zftape-rw.h" 39 - #include "../zftape/zftape-eof.h" 40 - 41 - /* Global vars. 42 - */ 43 - 44 - /* a copy of the failed sector log from the header segment. 45 - */ 46 - eof_mark_union *zft_eof_map; 47 - 48 - /* number of eof marks (entries in bad sector log) on tape. 49 - */ 50 - int zft_nr_eof_marks = -1; 51 - 52 - 53 - /* Local vars. 54 - */ 55 - 56 - static char linux_tape_label[] = "Linux raw format V"; 57 - enum { 58 - min_fmt_version = 1, max_fmt_version = 2 59 - }; 60 - static unsigned ftape_fmt_version = 0; 61 - 62 - 63 - /* Ftape (mis)uses the bad sector log to record end-of-file marks. 64 - * Initially (when the tape is erased) all entries in the bad sector 65 - * log are added to the tape's bad sector map. The bad sector log then 66 - * is cleared. 67 - * 68 - * The bad sector log normally contains entries of the form: 69 - * even 16-bit word: segment number of bad sector 70 - * odd 16-bit word: encoded date 71 - * There can be a total of 448 entries (1792 bytes). 72 - * 73 - * My guess is that no program is using this bad sector log (the * 74 - * format seems useless as there is no indication of the bad sector 75 - * itself, only the segment) However, if any program does use the bad 76 - * sector log, the format used by ftape will let the program think 77 - * there are some bad sectors and no harm is done. 78 - * 79 - * The eof mark entries that ftape stores in the bad sector log: even 80 - * 16-bit word: segment number of eof mark odd 16-bit word: sector 81 - * number of eof mark [1..32] 82 - * 83 - * The zft_eof_map as maintained is a sorted list of eof mark entries. 84 - * 85 - * 86 - * The tape name field in the header segments is used to store a linux 87 - * tape identification string and a version number. This way the tape 88 - * can be recognized as a Linux raw format tape when using tools under 89 - * other OS's. 90 - * 91 - * 'Wide' QIC tapes (format code 4) don't have a failed sector list 92 - * anymore. That space is used for the (longer) bad sector map that 93 - * now is a variable length list too. We now store our end-of-file 94 - * marker list after the bad-sector-map on tape. The list is delimited 95 - * by a (__u32) 0 entry. 96 - */ 97 - 98 - int zft_ftape_validate_label(char *label) 99 - { 100 - static char tmp_label[45]; 101 - int result = 0; 102 - TRACE_FUN(ft_t_any); 103 - 104 - memcpy(tmp_label, label, FT_LABEL_SZ); 105 - tmp_label[FT_LABEL_SZ] = '\0'; 106 - TRACE(ft_t_noise, "tape label = `%s'", tmp_label); 107 - ftape_fmt_version = 0; 108 - if (memcmp(label, linux_tape_label, strlen(linux_tape_label)) == 0) { 109 - int pos = strlen(linux_tape_label); 110 - while (label[pos] >= '0' && label[pos] <= '9') { 111 - ftape_fmt_version *= 10; 112 - ftape_fmt_version = label[ pos++] - '0'; 113 - } 114 - result = (ftape_fmt_version >= min_fmt_version && 115 - ftape_fmt_version <= max_fmt_version); 116 - } 117 - TRACE(ft_t_noise, "format version = %d", ftape_fmt_version); 118 - TRACE_EXIT result; 119 - } 120 - 121 - static __u8 * find_end_of_eof_list(__u8 * ptr, __u8 * limit) 122 - { 123 - while (ptr + 3 < limit) { 124 - 125 - if (get_unaligned((__u32*)ptr)) { 126 - ptr += sizeof(__u32); 127 - } else { 128 - return ptr; 129 - } 130 - } 131 - return NULL; 132 - } 133 - 134 - void zft_ftape_extract_file_marks(__u8* address) 135 - { 136 - int i; 137 - TRACE_FUN(ft_t_any); 138 - 139 - zft_eof_map = NULL; 140 - if (ft_format_code == fmt_var || ft_format_code == fmt_big) { 141 - __u8* end; 142 - __u8* start = ftape_find_end_of_bsm_list(address); 143 - 144 - zft_nr_eof_marks = 0; 145 - if (start) { 146 - start += 3; /* skip end of list mark */ 147 - end = find_end_of_eof_list(start, 148 - address + FT_SEGMENT_SIZE); 149 - if (end && end - start <= FT_FSL_SIZE) { 150 - zft_nr_eof_marks = ((end - start) / 151 - sizeof(eof_mark_union)); 152 - zft_eof_map = (eof_mark_union *)start; 153 - } else { 154 - TRACE(ft_t_err, 155 - "EOF Mark List is too long or damaged!"); 156 - } 157 - } else { 158 - TRACE(ft_t_err, 159 - "Bad Sector List is too long or damaged !"); 160 - } 161 - } else { 162 - zft_eof_map = (eof_mark_union *)&address[FT_FSL]; 163 - zft_nr_eof_marks = GET2(address, FT_FSL_CNT); 164 - } 165 - TRACE(ft_t_noise, "number of file marks: %d", zft_nr_eof_marks); 166 - if (ftape_fmt_version == 1) { 167 - TRACE(ft_t_info, "swapping version 1 fields"); 168 - /* version 1 format uses swapped sector and segment 169 - * fields, correct that ! 170 - */ 171 - for (i = 0; i < zft_nr_eof_marks; ++i) { 172 - __u16 tmp = GET2(&zft_eof_map[i].mark.segment,0); 173 - PUT2(&zft_eof_map[i].mark.segment, 0, 174 - GET2(&zft_eof_map[i].mark.date,0)); 175 - PUT2(&zft_eof_map[i].mark.date, 0, tmp); 176 - } 177 - } 178 - for (i = 0; i < zft_nr_eof_marks; ++i) { 179 - TRACE(ft_t_noise, "eof mark: %5d/%2d", 180 - GET2(&zft_eof_map[i].mark.segment, 0), 181 - GET2(&zft_eof_map[i].mark.date,0)); 182 - } 183 - TRACE_EXIT; 184 - } 185 - 186 - void zft_clear_ftape_file_marks(void) 187 - { 188 - TRACE_FUN(ft_t_flow); 189 - /* Clear failed sector log: remove all tape marks. We 190 - * don't use old ftape-style EOF-marks. 191 - */ 192 - TRACE(ft_t_info, "Clearing old ftape's eof map"); 193 - memset(zft_eof_map, 0, zft_nr_eof_marks * sizeof(__u32)); 194 - zft_nr_eof_marks = 0; 195 - PUT2(zft_hseg_buf, FT_FSL_CNT, 0); /* nr of eof-marks */ 196 - zft_header_changed = 1; 197 - zft_update_label(zft_hseg_buf); 198 - TRACE_EXIT; 199 - }
-52
drivers/char/ftape/zftape/zftape-eof.h
··· 1 - #ifndef _ZFTAPE_EOF_H 2 - #define _ZFTAPE_EOF_H 3 - 4 - /* 5 - * Copyright (C) 1994-1995 Bas Laarhoven. 6 - * adaptaed for zftape 1996, 1997 by Claus Heine 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-eof.h,v $ 24 - * $Revision: 1.2 $ 25 - * $Date: 1997/10/05 19:19:03 $ 26 - * 27 - * Definitions and declarations for the end of file markers 28 - * for the QIC-40/80 floppy-tape driver for Linux. 29 - */ 30 - 31 - #include <linux/ftape-header-segment.h> 32 - #include "../zftape/zftape-buffers.h" 33 - /* failed sector log size (only used if format code != 4). 34 - */ 35 - 36 - typedef union { 37 - ft_fsl_entry mark; 38 - __u32 entry; 39 - } eof_mark_union; 40 - 41 - /* ftape-eof.c defined global vars. 42 - */ 43 - extern int zft_nr_eof_marks; 44 - extern eof_mark_union *zft_eof_map; 45 - 46 - /* ftape-eof.c defined global functions. 47 - */ 48 - extern void zft_ftape_extract_file_marks(__u8* address); 49 - extern int zft_ftape_validate_label(char* label); 50 - extern void zft_clear_ftape_file_marks(void); 51 - 52 - #endif
-377
drivers/char/ftape/zftape/zftape-init.c
··· 1 - /* 2 - * Copyright (C) 1996, 1997 Claus-Justus Heine. 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * This file contains the code that registers the zftape frontend 20 - * to the ftape floppy tape driver for Linux 21 - */ 22 - 23 - #include <linux/module.h> 24 - #include <linux/errno.h> 25 - #include <linux/fs.h> 26 - #include <linux/kernel.h> 27 - #include <linux/signal.h> 28 - #include <linux/major.h> 29 - #include <linux/slab.h> 30 - #ifdef CONFIG_KMOD 31 - #include <linux/kmod.h> 32 - #endif 33 - #include <linux/fcntl.h> 34 - #include <linux/smp_lock.h> 35 - 36 - #include <linux/zftape.h> 37 - #include <linux/init.h> 38 - #include <linux/device.h> 39 - 40 - #include "../zftape/zftape-init.h" 41 - #include "../zftape/zftape-read.h" 42 - #include "../zftape/zftape-write.h" 43 - #include "../zftape/zftape-ctl.h" 44 - #include "../zftape/zftape-buffers.h" 45 - 46 - MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine " 47 - "(claus@momo.math.rwth-aachen.de)"); 48 - MODULE_DESCRIPTION(ZFTAPE_VERSION " - " 49 - "VFS interface for the Linux floppy tape driver. " 50 - "Support for QIC-113 compatible volume table " 51 - "and builtin compression (lzrw3 algorithm)"); 52 - MODULE_SUPPORTED_DEVICE("char-major-27"); 53 - MODULE_LICENSE("GPL"); 54 - 55 - /* Global vars. 56 - */ 57 - struct zft_cmpr_ops *zft_cmpr_ops = NULL; 58 - const ftape_info *zft_status; 59 - 60 - /* Local vars. 61 - */ 62 - static unsigned long busy_flag; 63 - 64 - static sigset_t orig_sigmask; 65 - 66 - /* the interface to the kernel vfs layer 67 - */ 68 - 69 - /* Note about llseek(): 70 - * 71 - * st.c and tpqic.c update fp->f_pos but don't implment llseek() and 72 - * initialize the llseek component of the file_ops struct with NULL. 73 - * This means that the user will get the default seek, but the tape 74 - * device will not respect the new position, but happily read from the 75 - * old position. Think a zftape specific llseek() function would be 76 - * better, returning -ESPIPE. TODO. 77 - */ 78 - 79 - static int zft_open (struct inode *ino, struct file *filep); 80 - static int zft_close(struct inode *ino, struct file *filep); 81 - static int zft_ioctl(struct inode *ino, struct file *filep, 82 - unsigned int command, unsigned long arg); 83 - static int zft_mmap(struct file *filep, struct vm_area_struct *vma); 84 - static ssize_t zft_read (struct file *fp, char __user *buff, 85 - size_t req_len, loff_t *ppos); 86 - static ssize_t zft_write(struct file *fp, const char __user *buff, 87 - size_t req_len, loff_t *ppos); 88 - 89 - static const struct file_operations zft_cdev = 90 - { 91 - .owner = THIS_MODULE, 92 - .read = zft_read, 93 - .write = zft_write, 94 - .ioctl = zft_ioctl, 95 - .mmap = zft_mmap, 96 - .open = zft_open, 97 - .release = zft_close, 98 - }; 99 - 100 - static struct class *zft_class; 101 - 102 - /* Open floppy tape device 103 - */ 104 - static int zft_open(struct inode *ino, struct file *filep) 105 - { 106 - int result; 107 - TRACE_FUN(ft_t_flow); 108 - 109 - nonseekable_open(ino, filep); 110 - TRACE(ft_t_flow, "called for minor %d", iminor(ino)); 111 - if ( test_and_set_bit(0,&busy_flag) ) { 112 - TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy"); 113 - } 114 - if ((iminor(ino) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND)) 115 - > 116 - FTAPE_SEL_D) { 117 - clear_bit(0,&busy_flag); 118 - TRACE_ABORT(-ENXIO, ft_t_err, "failed: invalid unit nr"); 119 - } 120 - orig_sigmask = current->blocked; 121 - sigfillset(&current->blocked); 122 - result = _zft_open(iminor(ino), filep->f_flags & O_ACCMODE); 123 - if (result < 0) { 124 - current->blocked = orig_sigmask; /* restore mask */ 125 - clear_bit(0,&busy_flag); 126 - TRACE_ABORT(result, ft_t_err, "_ftape_open failed"); 127 - } else { 128 - /* Mask signals that will disturb proper operation of the 129 - * program that is calling. 130 - */ 131 - current->blocked = orig_sigmask; 132 - sigaddsetmask (&current->blocked, _DO_BLOCK); 133 - TRACE_EXIT 0; 134 - } 135 - } 136 - 137 - /* Close floppy tape device 138 - */ 139 - static int zft_close(struct inode *ino, struct file *filep) 140 - { 141 - int result; 142 - TRACE_FUN(ft_t_flow); 143 - 144 - if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit) { 145 - TRACE(ft_t_err, "failed: not busy or wrong unit"); 146 - TRACE_EXIT 0; 147 - } 148 - sigfillset(&current->blocked); 149 - result = _zft_close(); 150 - if (result < 0) { 151 - TRACE(ft_t_err, "_zft_close failed"); 152 - } 153 - current->blocked = orig_sigmask; /* restore before open state */ 154 - clear_bit(0,&busy_flag); 155 - TRACE_EXIT 0; 156 - } 157 - 158 - /* Ioctl for floppy tape device 159 - */ 160 - static int zft_ioctl(struct inode *ino, struct file *filep, 161 - unsigned int command, unsigned long arg) 162 - { 163 - int result = -EIO; 164 - sigset_t old_sigmask; 165 - TRACE_FUN(ft_t_flow); 166 - 167 - if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) { 168 - TRACE_ABORT(-EIO, ft_t_err, 169 - "failed: not busy, failure or wrong unit"); 170 - } 171 - old_sigmask = current->blocked; /* save mask */ 172 - sigfillset(&current->blocked); 173 - /* This will work as long as sizeof(void *) == sizeof(long) */ 174 - result = _zft_ioctl(command, (void __user *) arg); 175 - current->blocked = old_sigmask; /* restore mask */ 176 - TRACE_EXIT result; 177 - } 178 - 179 - /* Ioctl for floppy tape device 180 - */ 181 - static int zft_mmap(struct file *filep, struct vm_area_struct *vma) 182 - { 183 - int result = -EIO; 184 - sigset_t old_sigmask; 185 - TRACE_FUN(ft_t_flow); 186 - 187 - if ( !test_bit(0,&busy_flag) || 188 - iminor(filep->f_dentry->d_inode) != zft_unit || 189 - ft_failure) 190 - { 191 - TRACE_ABORT(-EIO, ft_t_err, 192 - "failed: not busy, failure or wrong unit"); 193 - } 194 - old_sigmask = current->blocked; /* save mask */ 195 - sigfillset(&current->blocked); 196 - if ((result = ftape_mmap(vma)) >= 0) { 197 - #ifndef MSYNC_BUG_WAS_FIXED 198 - static struct vm_operations_struct dummy = { NULL, }; 199 - vma->vm_ops = &dummy; 200 - #endif 201 - } 202 - current->blocked = old_sigmask; /* restore mask */ 203 - TRACE_EXIT result; 204 - } 205 - 206 - /* Read from floppy tape device 207 - */ 208 - static ssize_t zft_read(struct file *fp, char __user *buff, 209 - size_t req_len, loff_t *ppos) 210 - { 211 - int result = -EIO; 212 - sigset_t old_sigmask; 213 - struct inode *ino = fp->f_dentry->d_inode; 214 - TRACE_FUN(ft_t_flow); 215 - 216 - TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len); 217 - if (!test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) { 218 - TRACE_ABORT(-EIO, ft_t_err, 219 - "failed: not busy, failure or wrong unit"); 220 - } 221 - old_sigmask = current->blocked; /* save mask */ 222 - sigfillset(&current->blocked); 223 - result = _zft_read(buff, req_len); 224 - current->blocked = old_sigmask; /* restore mask */ 225 - TRACE(ft_t_data_flow, "return with count: %d", result); 226 - TRACE_EXIT result; 227 - } 228 - 229 - /* Write to tape device 230 - */ 231 - static ssize_t zft_write(struct file *fp, const char __user *buff, 232 - size_t req_len, loff_t *ppos) 233 - { 234 - int result = -EIO; 235 - sigset_t old_sigmask; 236 - struct inode *ino = fp->f_dentry->d_inode; 237 - TRACE_FUN(ft_t_flow); 238 - 239 - TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len); 240 - if (!test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) { 241 - TRACE_ABORT(-EIO, ft_t_err, 242 - "failed: not busy, failure or wrong unit"); 243 - } 244 - old_sigmask = current->blocked; /* save mask */ 245 - sigfillset(&current->blocked); 246 - result = _zft_write(buff, req_len); 247 - current->blocked = old_sigmask; /* restore mask */ 248 - TRACE(ft_t_data_flow, "return with count: %d", result); 249 - TRACE_EXIT result; 250 - } 251 - 252 - /* END OF VFS INTERFACE 253 - * 254 - *****************************************************************************/ 255 - 256 - /* driver/module initialization 257 - */ 258 - 259 - /* the compression module has to call this function to hook into the zftape 260 - * code 261 - */ 262 - int zft_cmpr_register(struct zft_cmpr_ops *new_ops) 263 - { 264 - TRACE_FUN(ft_t_flow); 265 - 266 - if (zft_cmpr_ops != NULL) { 267 - TRACE_EXIT -EBUSY; 268 - } else { 269 - zft_cmpr_ops = new_ops; 270 - TRACE_EXIT 0; 271 - } 272 - } 273 - 274 - /* lock the zft-compressor() module. 275 - */ 276 - int zft_cmpr_lock(int try_to_load) 277 - { 278 - if (zft_cmpr_ops == NULL) { 279 - #ifdef CONFIG_KMOD 280 - if (try_to_load) { 281 - request_module("zft-compressor"); 282 - if (zft_cmpr_ops == NULL) { 283 - return -ENOSYS; 284 - } 285 - } else { 286 - return -ENOSYS; 287 - } 288 - #else 289 - return -ENOSYS; 290 - #endif 291 - } 292 - (*zft_cmpr_ops->lock)(); 293 - return 0; 294 - } 295 - 296 - #ifdef CONFIG_ZFT_COMPRESSOR 297 - extern int zft_compressor_init(void); 298 - #endif 299 - 300 - /* Called by modules package when installing the driver or by kernel 301 - * during the initialization phase 302 - */ 303 - int __init zft_init(void) 304 - { 305 - int i; 306 - TRACE_FUN(ft_t_flow); 307 - 308 - #ifdef MODULE 309 - printk(KERN_INFO ZFTAPE_VERSION "\n"); 310 - if (TRACE_LEVEL >= ft_t_info) { 311 - printk( 312 - KERN_INFO 313 - "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" 314 - KERN_INFO 315 - "vfs interface for ftape floppy tape driver.\n" 316 - KERN_INFO 317 - "Support for QIC-113 compatible volume table, dynamic memory allocation\n" 318 - KERN_INFO 319 - "and builtin compression (lzrw3 algorithm).\n"); 320 - } 321 - #else /* !MODULE */ 322 - /* print a short no-nonsense boot message */ 323 - printk(KERN_INFO ZFTAPE_VERSION "\n"); 324 - #endif /* MODULE */ 325 - TRACE(ft_t_info, "zft_init @ 0x%p", zft_init); 326 - TRACE(ft_t_info, 327 - "installing zftape VFS interface for ftape driver ..."); 328 - TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),); 329 - 330 - zft_class = class_create(THIS_MODULE, "zft"); 331 - for (i = 0; i < 4; i++) { 332 - class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); 333 - class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); 334 - class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); 335 - class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); 336 - class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); 337 - class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); 338 - } 339 - 340 - #ifdef CONFIG_ZFT_COMPRESSOR 341 - (void)zft_compressor_init(); 342 - #endif 343 - zft_status = ftape_get_status(); /* fetch global data of ftape 344 - * hardware driver 345 - */ 346 - TRACE_EXIT 0; 347 - } 348 - 349 - 350 - /* Called by modules package when removing the driver 351 - */ 352 - static void zft_exit(void) 353 - { 354 - int i; 355 - TRACE_FUN(ft_t_flow); 356 - 357 - if (unregister_chrdev(QIC117_TAPE_MAJOR, "zft") != 0) { 358 - TRACE(ft_t_warn, "failed"); 359 - } else { 360 - TRACE(ft_t_info, "successful"); 361 - } 362 - for (i = 0; i < 4; i++) { 363 - class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i)); 364 - class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4)); 365 - class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16)); 366 - class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20)); 367 - class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32)); 368 - class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36)); 369 - } 370 - class_destroy(zft_class); 371 - zft_uninit_mem(); /* release remaining memory, if any */ 372 - printk(KERN_INFO "zftape successfully unloaded.\n"); 373 - TRACE_EXIT; 374 - } 375 - 376 - module_init(zft_init); 377 - module_exit(zft_exit);
-77
drivers/char/ftape/zftape/zftape-init.h
··· 1 - #ifndef _ZFTAPE_INIT_H 2 - #define _ZFTAPE_INIT_H 3 - 4 - /* 5 - * Copyright (C) 1996, 1997 Claus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-init.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:19:05 $ 25 - * 26 - * This file contains definitions and macro for the vfs 27 - * interface defined by zftape 28 - * 29 - */ 30 - 31 - #include <linux/ftape-header-segment.h> 32 - 33 - #include "../lowlevel/ftape-tracing.h" 34 - #include "../lowlevel/ftape-ctl.h" 35 - #include "../lowlevel/ftape-read.h" 36 - #include "../lowlevel/ftape-write.h" 37 - #include "../lowlevel/ftape-bsm.h" 38 - #include "../lowlevel/ftape-io.h" 39 - #include "../lowlevel/ftape-buffer.h" 40 - #include "../lowlevel/ftape-format.h" 41 - 42 - #include "../zftape/zftape-rw.h" 43 - 44 - #ifdef MODULE 45 - #define ftape_status (*zft_status) 46 - #endif 47 - 48 - extern const ftape_info *zft_status; /* needed for zftape-vtbl.h */ 49 - 50 - #include "../zftape/zftape-vtbl.h" 51 - 52 - struct zft_cmpr_ops { 53 - int (*write)(int *write_cnt, 54 - __u8 *dst_buf, const int seg_sz, 55 - const __u8 __user *src_buf, const int req_len, 56 - const zft_position *pos, const zft_volinfo *volume); 57 - int (*read)(int *read_cnt, 58 - __u8 __user *dst_buf, const int req_len, 59 - const __u8 *src_buf, const int seg_sz, 60 - const zft_position *pos, const zft_volinfo *volume); 61 - int (*seek)(unsigned int new_block_pos, 62 - zft_position *pos, const zft_volinfo *volume, 63 - __u8 *buffer); 64 - void (*lock) (void); 65 - void (*reset) (void); 66 - void (*cleanup)(void); 67 - }; 68 - 69 - extern struct zft_cmpr_ops *zft_cmpr_ops; 70 - /* zftape-init.c defined global functions. 71 - */ 72 - extern int zft_cmpr_register(struct zft_cmpr_ops *new_ops); 73 - extern int zft_cmpr_lock(int try_to_load); 74 - 75 - #endif 76 - 77 -
-377
drivers/char/ftape/zftape/zftape-read.c
··· 1 - /* 2 - * Copyright (C) 1996, 1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-read.c,v $ 20 - * $Revision: 1.2 $ 21 - * $Date: 1997/10/05 19:19:06 $ 22 - * 23 - * This file contains the high level reading code 24 - * for the QIC-117 floppy-tape driver for Linux. 25 - */ 26 - 27 - #include <linux/errno.h> 28 - #include <linux/mm.h> 29 - 30 - #include <linux/zftape.h> 31 - 32 - #include <asm/uaccess.h> 33 - 34 - #include "../zftape/zftape-init.h" 35 - #include "../zftape/zftape-eof.h" 36 - #include "../zftape/zftape-ctl.h" 37 - #include "../zftape/zftape-write.h" 38 - #include "../zftape/zftape-read.h" 39 - #include "../zftape/zftape-rw.h" 40 - #include "../zftape/zftape-vtbl.h" 41 - 42 - /* Global vars. 43 - */ 44 - int zft_just_before_eof; 45 - 46 - /* Local vars. 47 - */ 48 - static int buf_len_rd; 49 - 50 - void zft_zap_read_buffers(void) 51 - { 52 - buf_len_rd = 0; 53 - } 54 - 55 - int zft_read_header_segments(void) 56 - { 57 - TRACE_FUN(ft_t_flow); 58 - 59 - zft_header_read = 0; 60 - TRACE_CATCH(zft_vmalloc_once(&zft_hseg_buf, FT_SEGMENT_SIZE),); 61 - TRACE_CATCH(ftape_read_header_segment(zft_hseg_buf),); 62 - TRACE(ft_t_info, "Segments written since first format: %d", 63 - (int)GET4(zft_hseg_buf, FT_SEG_CNT)); 64 - zft_qic113 = (ft_format_code != fmt_normal && 65 - ft_format_code != fmt_1100ft && 66 - ft_format_code != fmt_425ft); 67 - TRACE(ft_t_info, "ft_first_data_segment: %d, ft_last_data_segment: %d", 68 - ft_first_data_segment, ft_last_data_segment); 69 - zft_capacity = zft_get_capacity(); 70 - zft_old_ftape = zft_ftape_validate_label(&zft_hseg_buf[FT_LABEL]); 71 - if (zft_old_ftape) { 72 - TRACE(ft_t_info, 73 - "Found old ftaped tape, emulating eof marks, entering read-only mode"); 74 - zft_ftape_extract_file_marks(zft_hseg_buf); 75 - TRACE_CATCH(zft_fake_volume_headers(zft_eof_map, 76 - zft_nr_eof_marks),); 77 - } else { 78 - /* the specs say that the volume table must be 79 - * initialized with zeroes during formatting, so it 80 - * MUST be readable, i.e. contain vaid ECC 81 - * information. 82 - */ 83 - TRACE_CATCH(ftape_read_segment(ft_first_data_segment, 84 - zft_deblock_buf, 85 - FT_RD_SINGLE),); 86 - TRACE_CATCH(zft_extract_volume_headers(zft_deblock_buf),); 87 - } 88 - zft_header_read = 1; 89 - zft_set_flags(zft_unit); 90 - zft_reset_position(&zft_pos); 91 - TRACE_EXIT 0; 92 - } 93 - 94 - int zft_fetch_segment_fraction(const unsigned int segment, void *buffer, 95 - const ft_read_mode_t read_mode, 96 - const unsigned int start, 97 - const unsigned int size) 98 - { 99 - int seg_sz; 100 - TRACE_FUN(ft_t_flow); 101 - 102 - if (segment == zft_deblock_segment) { 103 - TRACE(ft_t_data_flow, 104 - "re-using segment %d already in deblock buffer", 105 - segment); 106 - seg_sz = zft_get_seg_sz(segment); 107 - if (start > seg_sz) { 108 - TRACE_ABORT(-EINVAL, ft_t_bug, 109 - "trying to read beyond end of segment:\n" 110 - KERN_INFO "seg_sz : %d\n" 111 - KERN_INFO "start : %d\n" 112 - KERN_INFO "segment: %d", 113 - seg_sz, start, segment); 114 - } 115 - if ((start + size) > seg_sz) { 116 - TRACE_EXIT seg_sz - start; 117 - } 118 - TRACE_EXIT size; 119 - } 120 - seg_sz = ftape_read_segment_fraction(segment, buffer, read_mode, 121 - start, size); 122 - TRACE(ft_t_data_flow, "segment %d, result %d", segment, seg_sz); 123 - if ((int)seg_sz >= 0 && start == 0 && size == FT_SEGMENT_SIZE) { 124 - /* this implicitly assumes that we are always called with 125 - * buffer == zft_deblock_buf 126 - */ 127 - zft_deblock_segment = segment; 128 - } else { 129 - zft_deblock_segment = -1; 130 - } 131 - TRACE_EXIT seg_sz; 132 - } 133 - 134 - /* 135 - * out: 136 - * 137 - * int *read_cnt: the number of bytes we removed from the 138 - * zft_deblock_buf (result) 139 - * 140 - * int *to_do : the remaining size of the read-request. Is changed. 141 - * 142 - * in: 143 - * 144 - * char *buff : buff is the address of the upper part of the user 145 - * buffer, that hasn't been filled with data yet. 146 - * int buf_pos_read: copy of buf_pos_rd 147 - * int buf_len_read: copy of buf_len_rd 148 - * char *zft_deblock_buf: ftape_zft_deblock_buf 149 - * 150 - * returns the amount of data actually copied to the user-buffer 151 - * 152 - * to_do MUST NOT SHRINK except to indicate an EOT. In this case to_do 153 - * has to be set to 0. We cannot return -ENOSPC, because we return the 154 - * amount of data actually * copied to the user-buffer 155 - */ 156 - static int zft_simple_read (int *read_cnt, 157 - __u8 __user *dst_buf, 158 - const int to_do, 159 - const __u8 *src_buf, 160 - const int seg_sz, 161 - const zft_position *pos, 162 - const zft_volinfo *volume) 163 - { 164 - TRACE_FUN(ft_t_flow); 165 - 166 - if (seg_sz - pos->seg_byte_pos < to_do) { 167 - *read_cnt = seg_sz - pos->seg_byte_pos; 168 - } else { 169 - *read_cnt = to_do; 170 - } 171 - if (copy_to_user(dst_buf, 172 - src_buf + pos->seg_byte_pos, *read_cnt) != 0) { 173 - TRACE_EXIT -EFAULT; 174 - } 175 - TRACE(ft_t_noise, "nr bytes just read: %d", *read_cnt); 176 - TRACE_EXIT *read_cnt; 177 - } 178 - 179 - /* req_len: gets clipped due to EOT of EOF. 180 - * req_clipped: is a flag indicating whether req_len was clipped or not 181 - * volume: contains information on current volume (blk_sz etc.) 182 - */ 183 - static int check_read_access(int *req_len, 184 - const zft_volinfo **volume, 185 - int *req_clipped, 186 - const zft_position *pos) 187 - { 188 - static __s64 remaining; 189 - static int eod; 190 - TRACE_FUN(ft_t_flow); 191 - 192 - if (zft_io_state != zft_reading) { 193 - if (zft_offline) { /* offline includes no_tape */ 194 - TRACE_ABORT(-ENXIO, ft_t_warn, 195 - "tape is offline or no cartridge"); 196 - } 197 - if (!ft_formatted) { 198 - TRACE_ABORT(-EACCES, 199 - ft_t_warn, "tape is not formatted"); 200 - } 201 - /* now enter defined state, read header segment if not 202 - * already done and flush write buffers 203 - */ 204 - TRACE_CATCH(zft_def_idle_state(),); 205 - zft_io_state = zft_reading; 206 - if (zft_tape_at_eod(pos)) { 207 - eod = 1; 208 - TRACE_EXIT 1; 209 - } 210 - eod = 0; 211 - *volume = zft_find_volume(pos->seg_pos); 212 - /* get the space left until EOF */ 213 - remaining = zft_check_for_eof(*volume, pos); 214 - buf_len_rd = 0; 215 - TRACE(ft_t_noise, "remaining: " LL_X ", vol_no: %d", 216 - LL(remaining), (*volume)->count); 217 - } else if (zft_tape_at_eod(pos)) { 218 - if (++eod > 2) { 219 - TRACE_EXIT -EIO; /* st.c also returns -EIO */ 220 - } else { 221 - TRACE_EXIT 1; 222 - } 223 - } 224 - if ((*req_len % (*volume)->blk_sz) != 0) { 225 - /* this message is informational only. The user gets the 226 - * proper return value 227 - */ 228 - TRACE_ABORT(-EINVAL, ft_t_info, 229 - "req_len %d not a multiple of block size %d", 230 - *req_len, (*volume)->blk_sz); 231 - } 232 - /* As GNU tar doesn't accept partial read counts when the 233 - * multiple volume flag is set, we make sure to return the 234 - * requested amount of data. Except, of course, at the end of 235 - * the tape or file mark. 236 - */ 237 - remaining -= *req_len; 238 - if (remaining <= 0) { 239 - TRACE(ft_t_noise, 240 - "clipped request from %d to %d.", 241 - *req_len, (int)(*req_len + remaining)); 242 - *req_len += remaining; 243 - *req_clipped = 1; 244 - } else { 245 - *req_clipped = 0; 246 - } 247 - TRACE_EXIT 0; 248 - } 249 - 250 - /* this_segs_size: the current segment's size. 251 - * buff: the USER-SPACE buffer provided by the calling function. 252 - * req_len: how much data should be read at most. 253 - * volume: contains information on current volume (blk_sz etc.) 254 - */ 255 - static int empty_deblock_buf(__u8 __user *usr_buf, const int req_len, 256 - const __u8 *src_buf, const int seg_sz, 257 - zft_position *pos, 258 - const zft_volinfo *volume) 259 - { 260 - int cnt; 261 - int result = 0; 262 - TRACE_FUN(ft_t_flow); 263 - 264 - TRACE(ft_t_data_flow, "this_segs_size: %d", seg_sz); 265 - if (zft_use_compression && volume->use_compression) { 266 - TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),); 267 - TRACE_CATCH(result= (*zft_cmpr_ops->read)(&cnt, 268 - usr_buf, req_len, 269 - src_buf, seg_sz, 270 - pos, volume),); 271 - } else { 272 - TRACE_CATCH(result= zft_simple_read (&cnt, 273 - usr_buf, req_len, 274 - src_buf, seg_sz, 275 - pos, volume),); 276 - } 277 - pos->volume_pos += result; 278 - pos->tape_pos += cnt; 279 - pos->seg_byte_pos += cnt; 280 - buf_len_rd -= cnt; /* remaining bytes in buffer */ 281 - TRACE(ft_t_data_flow, "buf_len_rd: %d, cnt: %d", buf_len_rd, cnt); 282 - if(pos->seg_byte_pos >= seg_sz) { 283 - pos->seg_pos++; 284 - pos->seg_byte_pos = 0; 285 - } 286 - TRACE(ft_t_data_flow, "bytes moved out of deblock-buffer: %d", cnt); 287 - TRACE_EXIT result; 288 - } 289 - 290 - 291 - /* note: we store the segment id of the segment that is inside the 292 - * deblock buffer. This spares a lot of ftape_read_segment()s when we 293 - * use small block-sizes. The block-size may be 1kb (SECTOR_SIZE). In 294 - * this case a MTFSR 28 maybe still inside the same segment. 295 - */ 296 - int _zft_read(char __user *buff, int req_len) 297 - { 298 - int req_clipped; 299 - int result = 0; 300 - int bytes_read = 0; 301 - static unsigned int seg_sz = 0; 302 - static const zft_volinfo *volume = NULL; 303 - TRACE_FUN(ft_t_flow); 304 - 305 - zft_resid = req_len; 306 - result = check_read_access(&req_len, &volume, 307 - &req_clipped, &zft_pos); 308 - switch(result) { 309 - case 0: 310 - break; /* nothing special */ 311 - case 1: 312 - TRACE(ft_t_noise, "EOD reached"); 313 - TRACE_EXIT 0; /* EOD */ 314 - default: 315 - TRACE_ABORT(result, ft_t_noise, 316 - "check_read_access() failed with result %d", 317 - result); 318 - TRACE_EXIT result; 319 - } 320 - while (req_len > 0) { 321 - /* Allow escape from this loop on signal ! 322 - */ 323 - FT_SIGNAL_EXIT(_DONT_BLOCK); 324 - /* buf_len_rd == 0 means that we need to read a new 325 - * segment. 326 - */ 327 - if (buf_len_rd == 0) { 328 - while((result = zft_fetch_segment(zft_pos.seg_pos, 329 - zft_deblock_buf, 330 - FT_RD_AHEAD)) == 0) { 331 - zft_pos.seg_pos ++; 332 - zft_pos.seg_byte_pos = 0; 333 - } 334 - if (result < 0) { 335 - zft_resid -= bytes_read; 336 - TRACE_ABORT(result, ft_t_noise, 337 - "zft_fetch_segment(): %d", 338 - result); 339 - } 340 - seg_sz = result; 341 - buf_len_rd = seg_sz - zft_pos.seg_byte_pos; 342 - } 343 - TRACE_CATCH(result = empty_deblock_buf(buff, 344 - req_len, 345 - zft_deblock_buf, 346 - seg_sz, 347 - &zft_pos, 348 - volume), 349 - zft_resid -= bytes_read); 350 - TRACE(ft_t_data_flow, "bytes just read: %d", result); 351 - bytes_read += result; /* what we got so far */ 352 - buff += result; /* index in user-buffer */ 353 - req_len -= result; /* what's left from req_len */ 354 - } /* while (req_len > 0) */ 355 - if (req_clipped) { 356 - TRACE(ft_t_data_flow, 357 - "maybe partial count because of eof mark"); 358 - if (zft_just_before_eof && bytes_read == 0) { 359 - /* req_len was > 0, but user didn't get 360 - * anything the user has read in the eof-mark 361 - */ 362 - zft_move_past_eof(&zft_pos); 363 - ftape_abort_operation(); 364 - } else { 365 - /* don't skip to the next file before the user 366 - * tried to read a second time past EOF Just 367 - * mark that we are at EOF and maybe decrement 368 - * zft_seg_pos to stay in the same volume; 369 - */ 370 - zft_just_before_eof = 1; 371 - zft_position_before_eof(&zft_pos, volume); 372 - TRACE(ft_t_noise, "just before eof"); 373 - } 374 - } 375 - zft_resid -= result; /* for MTSTATUS */ 376 - TRACE_EXIT bytes_read; 377 - }
-53
drivers/char/ftape/zftape/zftape-read.h
··· 1 - #ifndef _ZFTAPE_READ_H 2 - #define _ZFTAPE_READ_H 3 - 4 - /* 5 - * Copyright (C) 1996, 1997 Claus-Justus Heine 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-read.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:19:07 $ 25 - * 26 - * This file contains the definitions for the read functions 27 - * for the zftape driver for Linux. 28 - * 29 - */ 30 - 31 - #include "../lowlevel/ftape-read.h" 32 - 33 - /* ftape-read.c defined global vars. 34 - */ 35 - extern int zft_just_before_eof; 36 - 37 - /* ftape-read.c defined global functions. 38 - */ 39 - extern void zft_zap_read_buffers(void); 40 - extern int zft_read_header_segments(void); 41 - extern int zft_fetch_segment_fraction(const unsigned int segment, 42 - void *buffer, 43 - const ft_read_mode_t read_mode, 44 - const unsigned int start, 45 - const unsigned int size); 46 - #define zft_fetch_segment(segment, address, read_mode) \ 47 - zft_fetch_segment_fraction(segment, address, read_mode, \ 48 - 0, FT_SEGMENT_SIZE) 49 - /* hook for the VFS interface 50 - */ 51 - extern int _zft_read(char __user *buff, int req_len); 52 - 53 - #endif /* _ZFTAPE_READ_H */
-375
drivers/char/ftape/zftape/zftape-rw.c
··· 1 - /* 2 - * Copyright (C) 1996, 1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-rw.c,v $ 20 - * $Revision: 1.2 $ 21 - * $Date: 1997/10/05 19:19:08 $ 22 - * 23 - * This file contains some common code for the r/w code for 24 - * zftape. 25 - */ 26 - 27 - #include <linux/errno.h> 28 - #include <linux/mm.h> 29 - 30 - #include <linux/zftape.h> 31 - #include "../zftape/zftape-init.h" 32 - #include "../zftape/zftape-eof.h" 33 - #include "../zftape/zftape-ctl.h" 34 - #include "../zftape/zftape-write.h" 35 - #include "../zftape/zftape-read.h" 36 - #include "../zftape/zftape-rw.h" 37 - #include "../zftape/zftape-vtbl.h" 38 - 39 - /* Global vars. 40 - */ 41 - 42 - __u8 *zft_deblock_buf; 43 - __u8 *zft_hseg_buf; 44 - int zft_deblock_segment = -1; 45 - zft_status_enum zft_io_state = zft_idle; 46 - int zft_header_changed; 47 - int zft_qic113; /* conform to old specs. and old zftape */ 48 - int zft_use_compression; 49 - zft_position zft_pos = { 50 - -1, /* seg_pos */ 51 - 0, /* seg_byte_pos */ 52 - 0, /* tape_pos */ 53 - 0 /* volume_pos */ 54 - }; 55 - unsigned int zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ; 56 - __s64 zft_capacity; 57 - 58 - unsigned int zft_written_segments; 59 - int zft_label_changed; 60 - 61 - /* Local vars. 62 - */ 63 - 64 - unsigned int zft_get_seg_sz(unsigned int segment) 65 - { 66 - int size; 67 - TRACE_FUN(ft_t_any); 68 - 69 - size = FT_SEGMENT_SIZE - 70 - count_ones(ftape_get_bad_sector_entry(segment))*FT_SECTOR_SIZE; 71 - if (size > 0) { 72 - TRACE_EXIT (unsigned)size; 73 - } else { 74 - TRACE_EXIT 0; 75 - } 76 - } 77 - 78 - /* ftape_set_flags(). Claus-Justus Heine, 1994/1995 79 - */ 80 - void zft_set_flags(unsigned minor_unit) 81 - { 82 - TRACE_FUN(ft_t_flow); 83 - 84 - zft_use_compression = zft_qic_mode = 0; 85 - switch (minor_unit & ZFT_MINOR_OP_MASK) { 86 - case (ZFT_Q80_MODE | ZFT_ZIP_MODE): 87 - case ZFT_ZIP_MODE: 88 - zft_use_compression = 1; 89 - case 0: 90 - case ZFT_Q80_MODE: 91 - zft_qic_mode = 1; 92 - if (zft_mt_compression) { /* override the default */ 93 - zft_use_compression = 1; 94 - } 95 - break; 96 - case ZFT_RAW_MODE: 97 - TRACE(ft_t_noise, "switching to raw mode"); 98 - break; 99 - default: 100 - TRACE(ft_t_warn, "Warning:\n" 101 - KERN_INFO "Wrong combination of minor device bits.\n" 102 - KERN_INFO "Switching to raw read-only mode."); 103 - zft_write_protected = 1; 104 - break; 105 - } 106 - TRACE_EXIT; 107 - } 108 - 109 - /* computes the segment and byte offset inside the segment 110 - * corresponding to tape_pos. 111 - * 112 - * tape_pos gives the offset in bytes from the beginning of the 113 - * ft_first_data_segment *seg_byte_pos is the offset in the current 114 - * segment in bytes 115 - * 116 - * Of, if this routine was called often one should cache the last data 117 - * pos it was called with, but actually this is only needed in 118 - * ftape_seek_block(), that is, almost never. 119 - */ 120 - int zft_calc_seg_byte_coord(int *seg_byte_pos, __s64 tape_pos) 121 - { 122 - int segment; 123 - int seg_sz; 124 - TRACE_FUN(ft_t_flow); 125 - 126 - if (tape_pos == 0) { 127 - *seg_byte_pos = 0; 128 - segment = ft_first_data_segment; 129 - } else { 130 - seg_sz = 0; 131 - 132 - for (segment = ft_first_data_segment; 133 - ((tape_pos > 0) && (segment <= ft_last_data_segment)); 134 - segment++) { 135 - seg_sz = zft_get_seg_sz(segment); 136 - tape_pos -= seg_sz; 137 - } 138 - if(tape_pos >= 0) { 139 - /* the case tape_pos > != 0 means that the 140 - * argument tape_pos lies beyond the EOT. 141 - */ 142 - *seg_byte_pos= 0; 143 - } else { /* tape_pos < 0 */ 144 - segment--; 145 - *seg_byte_pos= tape_pos + seg_sz; 146 - } 147 - } 148 - TRACE_EXIT(segment); 149 - } 150 - 151 - /* ftape_calc_tape_pos(). 152 - * 153 - * computes the offset in bytes from the beginning of the 154 - * ft_first_data_segment inverse to ftape_calc_seg_byte_coord 155 - * 156 - * We should do some caching. But how: 157 - * 158 - * Each time the header segments are read in, this routine is called 159 - * with ft_tracks_per_tape*segments_per_track argumnet. So this should be 160 - * the time to reset the cache. 161 - * 162 - * Also, it might be in the future that the bad sector map gets 163 - * changed. -> reset the cache 164 - */ 165 - static int seg_pos; 166 - static __s64 tape_pos; 167 - 168 - __s64 zft_get_capacity(void) 169 - { 170 - seg_pos = ft_first_data_segment; 171 - tape_pos = 0; 172 - 173 - while (seg_pos <= ft_last_data_segment) { 174 - tape_pos += zft_get_seg_sz(seg_pos ++); 175 - } 176 - return tape_pos; 177 - } 178 - 179 - __s64 zft_calc_tape_pos(int segment) 180 - { 181 - int d1, d2, d3; 182 - TRACE_FUN(ft_t_any); 183 - 184 - if (segment > ft_last_data_segment) { 185 - TRACE_EXIT zft_capacity; 186 - } 187 - if (segment < ft_first_data_segment) { 188 - TRACE_EXIT 0; 189 - } 190 - d2 = segment - seg_pos; 191 - if (-d2 > 10) { 192 - d1 = segment - ft_first_data_segment; 193 - if (-d2 > d1) { 194 - tape_pos = 0; 195 - seg_pos = ft_first_data_segment; 196 - d2 = d1; 197 - } 198 - } 199 - if (d2 > 10) { 200 - d3 = ft_last_data_segment - segment; 201 - if (d2 > d3) { 202 - tape_pos = zft_capacity; 203 - seg_pos = ft_last_data_segment + 1; 204 - d2 = -d3; 205 - } 206 - } 207 - if (d2 > 0) { 208 - while (seg_pos < segment) { 209 - tape_pos += zft_get_seg_sz(seg_pos++); 210 - } 211 - } else { 212 - while (seg_pos > segment) { 213 - tape_pos -= zft_get_seg_sz(--seg_pos); 214 - } 215 - } 216 - TRACE(ft_t_noise, "new cached pos: %d", seg_pos); 217 - 218 - TRACE_EXIT tape_pos; 219 - } 220 - 221 - /* copy Z-label string to buffer, keeps track of the correct offset in 222 - * `buffer' 223 - */ 224 - void zft_update_label(__u8 *buffer) 225 - { 226 - TRACE_FUN(ft_t_flow); 227 - 228 - if (strncmp(&buffer[FT_LABEL], ZFTAPE_LABEL, 229 - sizeof(ZFTAPE_LABEL)-1) != 0) { 230 - TRACE(ft_t_info, "updating label from \"%s\" to \"%s\"", 231 - &buffer[FT_LABEL], ZFTAPE_LABEL); 232 - strcpy(&buffer[FT_LABEL], ZFTAPE_LABEL); 233 - memset(&buffer[FT_LABEL] + sizeof(ZFTAPE_LABEL) - 1, ' ', 234 - FT_LABEL_SZ - sizeof(ZFTAPE_LABEL + 1)); 235 - PUT4(buffer, FT_LABEL_DATE, 0); 236 - zft_label_changed = zft_header_changed = 1; /* changed */ 237 - } 238 - TRACE_EXIT; 239 - } 240 - 241 - int zft_verify_write_segments(unsigned int segment, 242 - __u8 *data, size_t size, 243 - __u8 *buffer) 244 - { 245 - int result; 246 - __u8 *write_buf; 247 - __u8 *src_buf; 248 - int single; 249 - int seg_pos; 250 - int seg_sz; 251 - int remaining; 252 - ft_write_mode_t write_mode; 253 - TRACE_FUN(ft_t_flow); 254 - 255 - seg_pos = segment; 256 - seg_sz = zft_get_seg_sz(seg_pos); 257 - src_buf = data; 258 - single = size <= seg_sz; 259 - remaining = size; 260 - do { 261 - TRACE(ft_t_noise, "\n" 262 - KERN_INFO "remaining: %d\n" 263 - KERN_INFO "seg_sz : %d\n" 264 - KERN_INFO "segment : %d", 265 - remaining, seg_sz, seg_pos); 266 - if (remaining == seg_sz) { 267 - write_buf = src_buf; 268 - write_mode = single ? FT_WR_SINGLE : FT_WR_MULTI; 269 - remaining = 0; 270 - } else if (remaining > seg_sz) { 271 - write_buf = src_buf; 272 - write_mode = FT_WR_ASYNC; /* don't start tape */ 273 - remaining -= seg_sz; 274 - } else { /* remaining < seg_sz */ 275 - write_buf = buffer; 276 - memcpy(write_buf, src_buf, remaining); 277 - memset(&write_buf[remaining],'\0',seg_sz-remaining); 278 - write_mode = single ? FT_WR_SINGLE : FT_WR_MULTI; 279 - remaining = 0; 280 - } 281 - if ((result = ftape_write_segment(seg_pos, 282 - write_buf, 283 - write_mode)) != seg_sz) { 284 - TRACE(ft_t_err, "Error: " 285 - "Couldn't write segment %d", seg_pos); 286 - TRACE_EXIT result < 0 ? result : -EIO; /* bail out */ 287 - } 288 - zft_written_segments ++; 289 - seg_sz = zft_get_seg_sz(++seg_pos); 290 - src_buf += result; 291 - } while (remaining > 0); 292 - if (ftape_get_status()->fti_state == writing) { 293 - TRACE_CATCH(ftape_loop_until_writes_done(),); 294 - TRACE_CATCH(ftape_abort_operation(),); 295 - zft_prevent_flush(); 296 - } 297 - seg_pos = segment; 298 - src_buf = data; 299 - remaining = size; 300 - do { 301 - TRACE_CATCH(result = ftape_read_segment(seg_pos, buffer, 302 - single ? FT_RD_SINGLE 303 - : FT_RD_AHEAD),); 304 - if (memcmp(src_buf, buffer, 305 - remaining > result ? result : remaining) != 0) { 306 - TRACE_ABORT(-EIO, ft_t_err, 307 - "Failed to verify written segment %d", 308 - seg_pos); 309 - } 310 - remaining -= result; 311 - TRACE(ft_t_noise, "verify successful:\n" 312 - KERN_INFO "segment : %d\n" 313 - KERN_INFO "segsize : %d\n" 314 - KERN_INFO "remaining: %d", 315 - seg_pos, result, remaining); 316 - src_buf += seg_sz; 317 - seg_pos++; 318 - } while (remaining > 0); 319 - TRACE_EXIT size; 320 - } 321 - 322 - 323 - /* zft_erase(). implemented compression-handling 324 - * 325 - * calculate the first data-segment when using/not using compression. 326 - * 327 - * update header-segment and compression-map-segment. 328 - */ 329 - int zft_erase(void) 330 - { 331 - int result = 0; 332 - TRACE_FUN(ft_t_flow); 333 - 334 - if (!zft_header_read) { 335 - TRACE_CATCH(zft_vmalloc_once((void **)&zft_hseg_buf, 336 - FT_SEGMENT_SIZE),); 337 - /* no need to read the vtbl and compression map */ 338 - TRACE_CATCH(ftape_read_header_segment(zft_hseg_buf),); 339 - if ((zft_old_ftape = 340 - zft_ftape_validate_label(&zft_hseg_buf[FT_LABEL]))) { 341 - zft_ftape_extract_file_marks(zft_hseg_buf); 342 - } 343 - TRACE(ft_t_noise, 344 - "ft_first_data_segment: %d, ft_last_data_segment: %d", 345 - ft_first_data_segment, ft_last_data_segment); 346 - zft_qic113 = (ft_format_code != fmt_normal && 347 - ft_format_code != fmt_1100ft && 348 - ft_format_code != fmt_425ft); 349 - } 350 - if (zft_old_ftape) { 351 - zft_clear_ftape_file_marks(); 352 - zft_old_ftape = 0; /* no longer old ftape */ 353 - } 354 - PUT2(zft_hseg_buf, FT_CMAP_START, 0); 355 - zft_volume_table_changed = 1; 356 - zft_capacity = zft_get_capacity(); 357 - zft_init_vtbl(); 358 - /* the rest must be done in ftape_update_header_segments 359 - */ 360 - zft_header_read = 1; 361 - zft_header_changed = 1; /* force update of timestamp */ 362 - result = zft_update_header_segments(); 363 - 364 - ftape_abort_operation(); 365 - 366 - zft_reset_position(&zft_pos); 367 - zft_set_flags (zft_unit); 368 - TRACE_EXIT result; 369 - } 370 - 371 - unsigned int zft_get_time(void) 372 - { 373 - unsigned int date = FT_TIME_STAMP(2097, 11, 30, 23, 59, 59); /* fun */ 374 - return date; 375 - }
-101
drivers/char/ftape/zftape/zftape-rw.h
··· 1 - #ifndef _ZFTAPE_RW_H 2 - #define _ZFTAPE_RW_H 3 - 4 - /* 5 - * Copyright (C) 1996, 1997 Claus-Justus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-rw.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:19:09 $ 25 - * 26 - * This file contains the definitions for the read and write 27 - * functions for the QIC-117 floppy-tape driver for Linux. 28 - * 29 - */ 30 - 31 - #include "../zftape/zftape-buffers.h" 32 - 33 - #define SEGMENTS_PER_TAPE (ft_segments_per_track * ft_tracks_per_tape) 34 - 35 - /* QIC-113 Rev. G says that `a maximum of 63488 raw bytes may be 36 - * compressed into a single frame'. 37 - * Maybe we should stick to 32kb to make it more `beautiful' 38 - */ 39 - #define ZFT_MAX_BLK_SZ (62*1024) /* bytes */ 40 - #if !defined(CONFIG_ZFT_DFLT_BLK_SZ) 41 - # define CONFIG_ZFT_DFLT_BLK_SZ (10*1024) /* bytes, default of gnu tar */ 42 - #elif CONFIG_ZFT_DFLT_BLK_SZ == 0 43 - # undef CONFIG_ZFT_DFLT_BLK_SZ 44 - # define CONFIG_ZFT_DFLT_BLK_SZ 1 45 - #elif (CONFIG_ZFT_DFLT_BLK_SZ % 1024) != 0 46 - # error CONFIG_ZFT_DFLT_BLK_SZ must be 1 or a multiple of 1024 47 - #endif 48 - /* The *optional* compression routines need some overhead per tape 49 - * block for their purposes. Instead of asking the actual compression 50 - * implementation how much it needs, we restrict this overhead to be 51 - * maximal of ZFT_CMPT_OVERHEAD size. We need this for EOT 52 - * conditions. The tape is assumed to be logical at EOT when the 53 - * distance from the physical EOT is less than 54 - * one tape block + ZFT_CMPR_OVERHEAD 55 - */ 56 - #define ZFT_CMPR_OVERHEAD 16 /* bytes */ 57 - 58 - typedef enum 59 - { 60 - zft_idle = 0, 61 - zft_reading, 62 - zft_writing, 63 - } zft_status_enum; 64 - 65 - typedef struct /* all values measured in bytes */ 66 - { 67 - int seg_pos; /* segment currently positioned at */ 68 - int seg_byte_pos; /* offset in current segment */ 69 - __s64 tape_pos; /* real offset from BOT */ 70 - __s64 volume_pos; /* pos. in uncompressed data stream in 71 - * current volume 72 - */ 73 - } zft_position; 74 - 75 - extern zft_position zft_pos; 76 - extern __u8 *zft_deblock_buf; 77 - extern __u8 *zft_hseg_buf; 78 - extern int zft_deblock_segment; 79 - extern zft_status_enum zft_io_state; 80 - extern int zft_header_changed; 81 - extern int zft_qic113; /* conform to old specs. and old zftape */ 82 - extern int zft_use_compression; 83 - extern unsigned int zft_blk_sz; 84 - extern __s64 zft_capacity; 85 - extern unsigned int zft_written_segments; 86 - extern int zft_label_changed; 87 - 88 - /* zftape-rw.c exported functions 89 - */ 90 - extern unsigned int zft_get_seg_sz(unsigned int segment); 91 - extern void zft_set_flags(unsigned int minor_unit); 92 - extern int zft_calc_seg_byte_coord(int *seg_byte_pos, __s64 tape_pos); 93 - extern __s64 zft_calc_tape_pos(int segment); 94 - extern __s64 zft_get_capacity(void); 95 - extern void zft_update_label(__u8 *buffer); 96 - extern int zft_erase(void); 97 - extern int zft_verify_write_segments(unsigned int segment, 98 - __u8 *data, size_t size, __u8 *buffer); 99 - extern unsigned int zft_get_time(void); 100 - #endif /* _ZFTAPE_RW_H */ 101 -
-757
drivers/char/ftape/zftape/zftape-vtbl.c
··· 1 - /* 2 - * Copyright (c) 1995-1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or 5 - modify it under the terms of the GNU General Public License as 6 - published by the Free Software Foundation; either version 2, or (at 7 - your option) any later version. 8 - 9 - This program is distributed in the hope that it will be useful, but 10 - WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 - General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 17 - USA. 18 - 19 - * 20 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-vtbl.c,v $ 21 - * $Revision: 1.7.6.1 $ 22 - * $Date: 1997/11/24 13:48:31 $ 23 - * 24 - * This file defines a volume table as defined in various QIC 25 - * standards. 26 - * 27 - * This is a minimal implementation, just allowing ordinary DOS 28 - * :( prgrams to identify the cartridge as used. 29 - */ 30 - 31 - #include <linux/errno.h> 32 - #include <linux/mm.h> 33 - #include <linux/slab.h> 34 - 35 - #include <linux/zftape.h> 36 - #include "../zftape/zftape-init.h" 37 - #include "../zftape/zftape-eof.h" 38 - #include "../zftape/zftape-ctl.h" 39 - #include "../zftape/zftape-write.h" 40 - #include "../zftape/zftape-read.h" 41 - #include "../zftape/zftape-rw.h" 42 - #include "../zftape/zftape-vtbl.h" 43 - 44 - #define ZFT_CMAP_HACK /* leave this defined to hide the compression map */ 45 - 46 - /* 47 - * global variables 48 - */ 49 - int zft_qic_mode = 1; /* use the vtbl */ 50 - int zft_old_ftape; /* prevents old ftaped tapes to be overwritten */ 51 - int zft_volume_table_changed; /* for write_header_segments() */ 52 - 53 - /* 54 - * private variables (only exported for inline functions) 55 - */ 56 - LIST_HEAD(zft_vtbl); 57 - 58 - /* We could also allocate these dynamically when extracting the volume table 59 - * sizeof(zft_volinfo) is about 32 or something close to that 60 - */ 61 - static zft_volinfo tape_vtbl; 62 - static zft_volinfo eot_vtbl; 63 - static zft_volinfo *cur_vtbl; 64 - 65 - static inline void zft_new_vtbl_entry(void) 66 - { 67 - struct list_head *tmp = &zft_last_vtbl->node; 68 - zft_volinfo *new = zft_kmalloc(sizeof(zft_volinfo)); 69 - 70 - list_add(&new->node, tmp); 71 - new->count = zft_eom_vtbl->count ++; 72 - } 73 - 74 - void zft_free_vtbl(void) 75 - { 76 - for (;;) { 77 - struct list_head *tmp = zft_vtbl.prev; 78 - zft_volinfo *vtbl; 79 - 80 - if (tmp == &zft_vtbl) 81 - break; 82 - list_del(tmp); 83 - vtbl = list_entry(tmp, zft_volinfo, node); 84 - zft_kfree(vtbl, sizeof(zft_volinfo)); 85 - } 86 - INIT_LIST_HEAD(&zft_vtbl); 87 - cur_vtbl = NULL; 88 - } 89 - 90 - /* initialize vtbl, called by ftape_new_cartridge() 91 - */ 92 - void zft_init_vtbl(void) 93 - { 94 - zft_volinfo *new; 95 - 96 - zft_free_vtbl(); 97 - 98 - /* Create the two dummy vtbl entries 99 - */ 100 - new = zft_kmalloc(sizeof(zft_volinfo)); 101 - list_add(&new->node, &zft_vtbl); 102 - new = zft_kmalloc(sizeof(zft_volinfo)); 103 - list_add(&new->node, &zft_vtbl); 104 - zft_head_vtbl->end_seg = ft_first_data_segment; 105 - zft_head_vtbl->blk_sz = zft_blk_sz; 106 - zft_head_vtbl->count = -1; 107 - zft_eom_vtbl->start_seg = ft_first_data_segment + 1; 108 - zft_eom_vtbl->end_seg = ft_last_data_segment + 1; 109 - zft_eom_vtbl->blk_sz = zft_blk_sz; 110 - zft_eom_vtbl->count = 0; 111 - 112 - /* Reset the pointer for zft_find_volume() 113 - */ 114 - cur_vtbl = zft_eom_vtbl; 115 - 116 - /* initialize the dummy vtbl entries for zft_qic_mode == 0 117 - */ 118 - eot_vtbl.start_seg = ft_last_data_segment + 1; 119 - eot_vtbl.end_seg = ft_last_data_segment + 1; 120 - eot_vtbl.blk_sz = zft_blk_sz; 121 - eot_vtbl.count = -1; 122 - tape_vtbl.start_seg = ft_first_data_segment; 123 - tape_vtbl.end_seg = ft_last_data_segment; 124 - tape_vtbl.blk_sz = zft_blk_sz; 125 - tape_vtbl.size = zft_capacity; 126 - tape_vtbl.count = 0; 127 - } 128 - 129 - /* check for a valid VTBL signature. 130 - */ 131 - static int vtbl_signature_valid(__u8 signature[4]) 132 - { 133 - const char *vtbl_ids[] = VTBL_IDS; /* valid signatures */ 134 - int j; 135 - 136 - for (j = 0; 137 - (j < NR_ITEMS(vtbl_ids)) && (memcmp(signature, vtbl_ids[j], 4) != 0); 138 - j++); 139 - return j < NR_ITEMS(vtbl_ids); 140 - } 141 - 142 - /* We used to store the block-size of the volume in the volume-label, 143 - * using the keyword "blocksize". The blocksize written to the 144 - * volume-label is in bytes. 145 - * 146 - * We use this now only for compatibility with old zftape version. We 147 - * store the blocksize directly as binary number in the vendor 148 - * extension part of the volume entry. 149 - */ 150 - static int check_volume_label(const char *label, int *blk_sz) 151 - { 152 - int valid_format; 153 - char *blocksize; 154 - TRACE_FUN(ft_t_flow); 155 - 156 - TRACE(ft_t_noise, "called with \"%s\" / \"%s\"", label, ZFT_VOL_NAME); 157 - if (strncmp(label, ZFT_VOL_NAME, strlen(ZFT_VOL_NAME)) != 0) { 158 - *blk_sz = 1; /* smallest block size that we allow */ 159 - valid_format = 0; 160 - } else { 161 - TRACE(ft_t_noise, "got old style zftape vtbl entry"); 162 - /* get the default blocksize */ 163 - /* use the kernel strstr() */ 164 - blocksize= strstr(label, " blocksize "); 165 - if (blocksize) { 166 - blocksize += strlen(" blocksize "); 167 - for(*blk_sz= 0; 168 - *blocksize >= '0' && *blocksize <= '9'; 169 - blocksize++) { 170 - *blk_sz *= 10; 171 - *blk_sz += *blocksize - '0'; 172 - } 173 - if (*blk_sz > ZFT_MAX_BLK_SZ) { 174 - *blk_sz= 1; 175 - valid_format= 0; 176 - } else { 177 - valid_format = 1; 178 - } 179 - } else { 180 - *blk_sz= 1; 181 - valid_format= 0; 182 - } 183 - } 184 - TRACE_EXIT valid_format; 185 - } 186 - 187 - /* check for a zftape volume 188 - */ 189 - static int check_volume(__u8 *entry, zft_volinfo *volume) 190 - { 191 - TRACE_FUN(ft_t_flow); 192 - 193 - if(strncmp(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG, 194 - strlen(ZFTAPE_SIG)) == 0) { 195 - TRACE(ft_t_noise, "got new style zftape vtbl entry"); 196 - volume->blk_sz = GET2(entry, VTBL_EXT+EXT_ZFTAPE_BLKSZ); 197 - volume->qic113 = entry[VTBL_EXT+EXT_ZFTAPE_QIC113]; 198 - TRACE_EXIT 1; 199 - } else { 200 - TRACE_EXIT check_volume_label(&entry[VTBL_DESC], &volume->blk_sz); 201 - } 202 - } 203 - 204 - 205 - /* create zftape specific vtbl entry, the volume bounds are inserted 206 - * in the calling function, zft_create_volume_headers() 207 - */ 208 - static void create_zft_volume(__u8 *entry, zft_volinfo *vtbl) 209 - { 210 - TRACE_FUN(ft_t_flow); 211 - 212 - memset(entry, 0, VTBL_SIZE); 213 - memcpy(&entry[VTBL_SIG], VTBL_ID, 4); 214 - sprintf(&entry[VTBL_DESC], ZFT_VOL_NAME" %03d", vtbl->count); 215 - entry[VTBL_FLAGS] = (VTBL_FL_NOT_VERIFIED | VTBL_FL_SEG_SPANNING); 216 - entry[VTBL_M_NO] = 1; /* multi_cartridge_count */ 217 - strcpy(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG); 218 - PUT2(entry, VTBL_EXT+EXT_ZFTAPE_BLKSZ, vtbl->blk_sz); 219 - if (zft_qic113) { 220 - PUT8(entry, VTBL_DATA_SIZE, vtbl->size); 221 - entry[VTBL_CMPR] = VTBL_CMPR_UNREG; 222 - if (vtbl->use_compression) { /* use compression: */ 223 - entry[VTBL_CMPR] |= VTBL_CMPR_USED; 224 - } 225 - entry[VTBL_EXT+EXT_ZFTAPE_QIC113] = 1; 226 - } else { 227 - PUT4(entry, VTBL_DATA_SIZE, vtbl->size); 228 - entry[VTBL_K_CMPR] = VTBL_CMPR_UNREG; 229 - if (vtbl->use_compression) { /* use compression: */ 230 - entry[VTBL_K_CMPR] |= VTBL_CMPR_USED; 231 - } 232 - } 233 - if (ft_format_code == fmt_big) { 234 - /* SCSI like vtbl, store the number of used 235 - * segments as 4 byte value 236 - */ 237 - PUT4(entry, VTBL_SCSI_SEGS, vtbl->end_seg-vtbl->start_seg + 1); 238 - } else { 239 - /* normal, QIC-80MC like vtbl 240 - */ 241 - PUT2(entry, VTBL_START, vtbl->start_seg); 242 - PUT2(entry, VTBL_END, vtbl->end_seg); 243 - } 244 - TRACE_EXIT; 245 - } 246 - 247 - /* this one creates the volume headers for each volume. It is assumed 248 - * that buffer already contains the old volume-table, so that vtbl 249 - * entries without the zft_volume flag set can savely be ignored. 250 - */ 251 - static void zft_create_volume_headers(__u8 *buffer) 252 - { 253 - __u8 *entry; 254 - struct list_head *tmp; 255 - zft_volinfo *vtbl; 256 - TRACE_FUN(ft_t_flow); 257 - 258 - #ifdef ZFT_CMAP_HACK 259 - if((strncmp(&buffer[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG, 260 - strlen(ZFTAPE_SIG)) == 0) && 261 - buffer[VTBL_EXT+EXT_ZFTAPE_CMAP] != 0) { 262 - TRACE(ft_t_noise, "deleting cmap volume"); 263 - memmove(buffer, buffer + VTBL_SIZE, 264 - FT_SEGMENT_SIZE - VTBL_SIZE); 265 - } 266 - #endif 267 - entry = buffer; 268 - for (tmp = zft_head_vtbl->node.next; 269 - tmp != &zft_eom_vtbl->node; 270 - tmp = tmp->next) { 271 - vtbl = list_entry(tmp, zft_volinfo, node); 272 - /* we now fill in the values only for newly created volumes. 273 - */ 274 - if (vtbl->new_volume) { 275 - create_zft_volume(entry, vtbl); 276 - vtbl->new_volume = 0; /* clear the flag */ 277 - } 278 - 279 - DUMP_VOLINFO(ft_t_noise, &entry[VTBL_DESC], vtbl); 280 - entry += VTBL_SIZE; 281 - } 282 - memset(entry, 0, FT_SEGMENT_SIZE - zft_eom_vtbl->count * VTBL_SIZE); 283 - TRACE_EXIT; 284 - } 285 - 286 - /* write volume table to tape. Calls zft_create_volume_headers() 287 - */ 288 - int zft_update_volume_table(unsigned int segment) 289 - { 290 - int result = 0; 291 - __u8 *verify_buf = NULL; 292 - TRACE_FUN(ft_t_flow); 293 - 294 - TRACE_CATCH(result = ftape_read_segment(ft_first_data_segment, 295 - zft_deblock_buf, 296 - FT_RD_SINGLE),); 297 - zft_create_volume_headers(zft_deblock_buf); 298 - TRACE(ft_t_noise, "writing volume table segment %d", segment); 299 - if (zft_vmalloc_once(&verify_buf, FT_SEGMENT_SIZE) == 0) { 300 - TRACE_CATCH(zft_verify_write_segments(segment, 301 - zft_deblock_buf, result, 302 - verify_buf), 303 - zft_vfree(&verify_buf, FT_SEGMENT_SIZE)); 304 - zft_vfree(&verify_buf, FT_SEGMENT_SIZE); 305 - } else { 306 - TRACE_CATCH(ftape_write_segment(segment, zft_deblock_buf, 307 - FT_WR_SINGLE),); 308 - } 309 - TRACE_EXIT 0; 310 - } 311 - 312 - /* non zftape volumes are handled in raw mode. Thus we need to 313 - * calculate the raw amount of data contained in those segments. 314 - */ 315 - static void extract_alien_volume(__u8 *entry, zft_volinfo *vtbl) 316 - { 317 - TRACE_FUN(ft_t_flow); 318 - 319 - vtbl->size = (zft_calc_tape_pos(zft_last_vtbl->end_seg+1) - 320 - zft_calc_tape_pos(zft_last_vtbl->start_seg)); 321 - vtbl->use_compression = 0; 322 - vtbl->qic113 = zft_qic113; 323 - if (vtbl->qic113) { 324 - TRACE(ft_t_noise, 325 - "Fake alien volume's size from " LL_X " to " LL_X, 326 - LL(GET8(entry, VTBL_DATA_SIZE)), LL(vtbl->size)); 327 - } else { 328 - TRACE(ft_t_noise, 329 - "Fake alien volume's size from %d to " LL_X, 330 - (int)GET4(entry, VTBL_DATA_SIZE), LL(vtbl->size)); 331 - } 332 - TRACE_EXIT; 333 - } 334 - 335 - 336 - /* extract an zftape specific volume 337 - */ 338 - static void extract_zft_volume(__u8 *entry, zft_volinfo *vtbl) 339 - { 340 - TRACE_FUN(ft_t_flow); 341 - 342 - if (vtbl->qic113) { 343 - vtbl->size = GET8(entry, VTBL_DATA_SIZE); 344 - vtbl->use_compression = 345 - (entry[VTBL_CMPR] & VTBL_CMPR_USED) != 0; 346 - } else { 347 - vtbl->size = GET4(entry, VTBL_DATA_SIZE); 348 - if (entry[VTBL_K_CMPR] & VTBL_CMPR_UNREG) { 349 - vtbl->use_compression = 350 - (entry[VTBL_K_CMPR] & VTBL_CMPR_USED) != 0; 351 - } else if (entry[VTBL_CMPR] & VTBL_CMPR_UNREG) { 352 - vtbl->use_compression = 353 - (entry[VTBL_CMPR] & VTBL_CMPR_USED) != 0; 354 - } else { 355 - TRACE(ft_t_warn, "Geeh! There is something wrong:\n" 356 - KERN_INFO "QIC compression (Rev = K): %x\n" 357 - KERN_INFO "QIC compression (Rev > K): %x", 358 - entry[VTBL_K_CMPR], entry[VTBL_CMPR]); 359 - } 360 - } 361 - TRACE_EXIT; 362 - } 363 - 364 - /* extract the volume table from buffer. "buffer" must already contain 365 - * the vtbl-segment 366 - */ 367 - int zft_extract_volume_headers(__u8 *buffer) 368 - { 369 - __u8 *entry; 370 - TRACE_FUN(ft_t_flow); 371 - 372 - zft_init_vtbl(); 373 - entry = buffer; 374 - #ifdef ZFT_CMAP_HACK 375 - if ((strncmp(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG, 376 - strlen(ZFTAPE_SIG)) == 0) && 377 - entry[VTBL_EXT+EXT_ZFTAPE_CMAP] != 0) { 378 - TRACE(ft_t_noise, "ignoring cmap volume"); 379 - entry += VTBL_SIZE; 380 - } 381 - #endif 382 - /* the end of the vtbl is indicated by an invalid signature 383 - */ 384 - while (vtbl_signature_valid(&entry[VTBL_SIG]) && 385 - (entry - buffer) < FT_SEGMENT_SIZE) { 386 - zft_new_vtbl_entry(); 387 - if (ft_format_code == fmt_big) { 388 - /* SCSI like vtbl, stores only the number of 389 - * segments used 390 - */ 391 - unsigned int num_segments= GET4(entry, VTBL_SCSI_SEGS); 392 - zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg; 393 - zft_last_vtbl->end_seg = 394 - zft_last_vtbl->start_seg + num_segments - 1; 395 - } else { 396 - /* `normal', QIC-80 like vtbl 397 - */ 398 - zft_last_vtbl->start_seg = GET2(entry, VTBL_START); 399 - zft_last_vtbl->end_seg = GET2(entry, VTBL_END); 400 - } 401 - zft_eom_vtbl->start_seg = zft_last_vtbl->end_seg + 1; 402 - /* check if we created this volume and get the 403 - * blk_sz 404 - */ 405 - zft_last_vtbl->zft_volume = check_volume(entry, zft_last_vtbl); 406 - if (zft_last_vtbl->zft_volume == 0) { 407 - extract_alien_volume(entry, zft_last_vtbl); 408 - } else { 409 - extract_zft_volume(entry, zft_last_vtbl); 410 - } 411 - DUMP_VOLINFO(ft_t_noise, &entry[VTBL_DESC], zft_last_vtbl); 412 - entry +=VTBL_SIZE; 413 - } 414 - #if 0 415 - /* 416 - * undefine to test end of tape handling 417 - */ 418 - zft_new_vtbl_entry(); 419 - zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg; 420 - zft_last_vtbl->end_seg = ft_last_data_segment - 10; 421 - zft_last_vtbl->blk_sz = zft_blk_sz; 422 - zft_last_vtbl->zft_volume = 1; 423 - zft_last_vtbl->qic113 = zft_qic113; 424 - zft_last_vtbl->size = (zft_calc_tape_pos(zft_last_vtbl->end_seg+1) 425 - - zft_calc_tape_pos(zft_last_vtbl->start_seg)); 426 - #endif 427 - TRACE_EXIT 0; 428 - } 429 - 430 - /* this functions translates the failed_sector_log, misused as 431 - * EOF-marker list, into a virtual volume table. The table mustn't be 432 - * written to tape, because this would occupy the first data segment, 433 - * which should be the volume table, but is actually the first segment 434 - * that is filled with data (when using standard ftape). We assume, 435 - * that we get a non-empty failed_sector_log. 436 - */ 437 - int zft_fake_volume_headers (eof_mark_union *eof_map, int num_failed_sectors) 438 - { 439 - unsigned int segment, sector; 440 - int have_eom = 0; 441 - int vol_no; 442 - TRACE_FUN(ft_t_flow); 443 - 444 - if ((num_failed_sectors >= 2) && 445 - (GET2(&eof_map[num_failed_sectors - 1].mark.segment, 0) 446 - == 447 - GET2(&eof_map[num_failed_sectors - 2].mark.segment, 0) + 1) && 448 - (GET2(&eof_map[num_failed_sectors - 1].mark.date, 0) == 1)) { 449 - /* this should be eom. We keep the remainder of the 450 - * tape as another volume. 451 - */ 452 - have_eom = 1; 453 - } 454 - zft_init_vtbl(); 455 - zft_eom_vtbl->start_seg = ft_first_data_segment; 456 - for(vol_no = 0; vol_no < num_failed_sectors - have_eom; vol_no ++) { 457 - zft_new_vtbl_entry(); 458 - 459 - segment = GET2(&eof_map[vol_no].mark.segment, 0); 460 - sector = GET2(&eof_map[vol_no].mark.date, 0); 461 - 462 - zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg; 463 - zft_last_vtbl->end_seg = segment; 464 - zft_eom_vtbl->start_seg = segment + 1; 465 - zft_last_vtbl->blk_sz = 1; 466 - zft_last_vtbl->size = 467 - (zft_calc_tape_pos(zft_last_vtbl->end_seg) 468 - - zft_calc_tape_pos(zft_last_vtbl->start_seg) 469 - + (sector-1) * FT_SECTOR_SIZE); 470 - TRACE(ft_t_noise, 471 - "failed sector log: segment: %d, sector: %d", 472 - segment, sector); 473 - DUMP_VOLINFO(ft_t_noise, "Faked volume", zft_last_vtbl); 474 - } 475 - if (!have_eom) { 476 - zft_new_vtbl_entry(); 477 - zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg; 478 - zft_last_vtbl->end_seg = ft_last_data_segment; 479 - zft_eom_vtbl->start_seg = ft_last_data_segment + 1; 480 - zft_last_vtbl->size = zft_capacity; 481 - zft_last_vtbl->size -= zft_calc_tape_pos(zft_last_vtbl->start_seg); 482 - zft_last_vtbl->blk_sz = 1; 483 - DUMP_VOLINFO(ft_t_noise, "Faked volume",zft_last_vtbl); 484 - } 485 - TRACE_EXIT 0; 486 - } 487 - 488 - /* update the internal volume table 489 - * 490 - * if before start of last volume: erase all following volumes if 491 - * inside a volume: set end of volume to infinity 492 - * 493 - * this function is intended to be called every time _ftape_write() is 494 - * called 495 - * 496 - * return: 0 if no new volume was created, 1 if a new volume was 497 - * created 498 - * 499 - * NOTE: we don't need to check for zft_mode as ftape_write() does 500 - * that already. This function gets never called without accessing 501 - * zftape via the *qft* devices 502 - */ 503 - 504 - int zft_open_volume(zft_position *pos, int blk_sz, int use_compression) 505 - { 506 - TRACE_FUN(ft_t_flow); 507 - 508 - if (!zft_qic_mode) { 509 - TRACE_EXIT 0; 510 - } 511 - if (zft_tape_at_lbot(pos)) { 512 - zft_init_vtbl(); 513 - if(zft_old_ftape) { 514 - /* clear old ftape's eof marks */ 515 - zft_clear_ftape_file_marks(); 516 - zft_old_ftape = 0; /* no longer old ftape */ 517 - } 518 - zft_reset_position(pos); 519 - } 520 - if (pos->seg_pos != zft_last_vtbl->end_seg + 1) { 521 - TRACE_ABORT(-EIO, ft_t_bug, 522 - "BUG: seg_pos: %d, zft_last_vtbl->end_seg: %d", 523 - pos->seg_pos, zft_last_vtbl->end_seg); 524 - } 525 - TRACE(ft_t_noise, "create new volume"); 526 - if (zft_eom_vtbl->count >= ZFT_MAX_VOLUMES) { 527 - TRACE_ABORT(-ENOSPC, ft_t_err, 528 - "Error: maxmimal number of volumes exhausted " 529 - "(maxmimum is %d)", ZFT_MAX_VOLUMES); 530 - } 531 - zft_new_vtbl_entry(); 532 - pos->volume_pos = pos->seg_byte_pos = 0; 533 - zft_last_vtbl->start_seg = pos->seg_pos; 534 - zft_last_vtbl->end_seg = ft_last_data_segment; /* infinity */ 535 - zft_last_vtbl->blk_sz = blk_sz; 536 - zft_last_vtbl->size = zft_capacity; 537 - zft_last_vtbl->zft_volume = 1; 538 - zft_last_vtbl->use_compression = use_compression; 539 - zft_last_vtbl->qic113 = zft_qic113; 540 - zft_last_vtbl->new_volume = 1; 541 - zft_last_vtbl->open = 1; 542 - zft_volume_table_changed = 1; 543 - zft_eom_vtbl->start_seg = ft_last_data_segment + 1; 544 - TRACE_EXIT 0; 545 - } 546 - 547 - /* perform mtfsf, mtbsf, not allowed without zft_qic_mode 548 - */ 549 - int zft_skip_volumes(int count, zft_position *pos) 550 - { 551 - const zft_volinfo *vtbl; 552 - TRACE_FUN(ft_t_flow); 553 - 554 - TRACE(ft_t_noise, "count: %d", count); 555 - 556 - vtbl= zft_find_volume(pos->seg_pos); 557 - while (count > 0 && vtbl != zft_eom_vtbl) { 558 - vtbl = list_entry(vtbl->node.next, zft_volinfo, node); 559 - count --; 560 - } 561 - while (count < 0 && vtbl != zft_first_vtbl) { 562 - vtbl = list_entry(vtbl->node.prev, zft_volinfo, node); 563 - count ++; 564 - } 565 - pos->seg_pos = vtbl->start_seg; 566 - pos->seg_byte_pos = 0; 567 - pos->volume_pos = 0; 568 - pos->tape_pos = zft_calc_tape_pos(pos->seg_pos); 569 - zft_just_before_eof = vtbl->size == 0; 570 - if (zft_cmpr_ops) { 571 - (*zft_cmpr_ops->reset)(); 572 - } 573 - zft_deblock_segment = -1; /* no need to keep cache */ 574 - TRACE(ft_t_noise, "repositioning to:\n" 575 - KERN_INFO "zft_seg_pos : %d\n" 576 - KERN_INFO "zft_seg_byte_pos : %d\n" 577 - KERN_INFO "zft_tape_pos : " LL_X "\n" 578 - KERN_INFO "zft_volume_pos : " LL_X "\n" 579 - KERN_INFO "file number : %d", 580 - pos->seg_pos, pos->seg_byte_pos, 581 - LL(pos->tape_pos), LL(pos->volume_pos), vtbl->count); 582 - zft_resid = count < 0 ? -count : count; 583 - TRACE_EXIT zft_resid ? -EINVAL : 0; 584 - } 585 - 586 - /* the following simply returns the raw data position of the EOM 587 - * marker, MTIOCSIZE ioctl 588 - */ 589 - __s64 zft_get_eom_pos(void) 590 - { 591 - if (zft_qic_mode) { 592 - return zft_calc_tape_pos(zft_eom_vtbl->start_seg); 593 - } else { 594 - /* there is only one volume in raw mode */ 595 - return zft_capacity; 596 - } 597 - } 598 - 599 - /* skip to eom, used for MTEOM 600 - */ 601 - void zft_skip_to_eom(zft_position *pos) 602 - { 603 - TRACE_FUN(ft_t_flow); 604 - pos->seg_pos = zft_eom_vtbl->start_seg; 605 - pos->seg_byte_pos = 606 - pos->volume_pos = 607 - zft_just_before_eof = 0; 608 - pos->tape_pos = zft_calc_tape_pos(pos->seg_pos); 609 - TRACE(ft_t_noise, "ftape positioned to segment %d, data pos " LL_X, 610 - pos->seg_pos, LL(pos->tape_pos)); 611 - TRACE_EXIT; 612 - } 613 - 614 - /* write an EOF-marker by setting zft_last_vtbl->end_seg to seg_pos. 615 - * NOTE: this function assumes that zft_last_vtbl points to a valid 616 - * vtbl entry 617 - * 618 - * NOTE: this routine always positions before the EOF marker 619 - */ 620 - int zft_close_volume(zft_position *pos) 621 - { 622 - TRACE_FUN(ft_t_any); 623 - 624 - if (zft_vtbl_empty || !zft_last_vtbl->open) { /* should not happen */ 625 - TRACE(ft_t_noise, "There are no volumes to finish"); 626 - TRACE_EXIT -EIO; 627 - } 628 - if (pos->seg_byte_pos == 0 && 629 - pos->seg_pos != zft_last_vtbl->start_seg) { 630 - pos->seg_pos --; 631 - pos->seg_byte_pos = zft_get_seg_sz(pos->seg_pos); 632 - } 633 - zft_last_vtbl->end_seg = pos->seg_pos; 634 - zft_last_vtbl->size = pos->volume_pos; 635 - zft_volume_table_changed = 1; 636 - zft_just_before_eof = 1; 637 - zft_eom_vtbl->start_seg = zft_last_vtbl->end_seg + 1; 638 - zft_last_vtbl->open = 0; /* closed */ 639 - TRACE_EXIT 0; 640 - } 641 - 642 - /* write count file-marks at current position. 643 - * 644 - * The tape is positioned after the eof-marker, that is at byte 0 of 645 - * the segment following the eof-marker 646 - * 647 - * this function is only allowed in zft_qic_mode 648 - * 649 - * Only allowed when tape is at BOT or EOD. 650 - */ 651 - int zft_weof(unsigned int count, zft_position *pos) 652 - { 653 - 654 - TRACE_FUN(ft_t_flow); 655 - 656 - if (!count) { /* write zero EOF marks should be a real no-op */ 657 - TRACE_EXIT 0; 658 - } 659 - zft_volume_table_changed = 1; 660 - if (zft_tape_at_lbot(pos)) { 661 - zft_init_vtbl(); 662 - if(zft_old_ftape) { 663 - /* clear old ftape's eof marks */ 664 - zft_clear_ftape_file_marks(); 665 - zft_old_ftape = 0; /* no longer old ftape */ 666 - } 667 - } 668 - if (zft_last_vtbl->open) { 669 - zft_close_volume(pos); 670 - zft_move_past_eof(pos); 671 - count --; 672 - } 673 - /* now it's easy, just append eof-marks, that is empty 674 - * volumes, to the end of the already recorded media. 675 - */ 676 - while (count > 0 && 677 - pos->seg_pos <= ft_last_data_segment && 678 - zft_eom_vtbl->count < ZFT_MAX_VOLUMES) { 679 - TRACE(ft_t_noise, 680 - "Writing zero sized file at segment %d", pos->seg_pos); 681 - zft_new_vtbl_entry(); 682 - zft_last_vtbl->start_seg = pos->seg_pos; 683 - zft_last_vtbl->end_seg = pos->seg_pos; 684 - zft_last_vtbl->size = 0; 685 - zft_last_vtbl->blk_sz = zft_blk_sz; 686 - zft_last_vtbl->zft_volume = 1; 687 - zft_last_vtbl->use_compression = 0; 688 - pos->tape_pos += zft_get_seg_sz(pos->seg_pos); 689 - zft_eom_vtbl->start_seg = ++ pos->seg_pos; 690 - count --; 691 - } 692 - if (count > 0) { 693 - /* there are two possibilities: end of tape, or the 694 - * maximum number of files is exhausted. 695 - */ 696 - zft_resid = count; 697 - TRACE(ft_t_noise,"Number of marks NOT written: %d", zft_resid); 698 - if (zft_eom_vtbl->count == ZFT_MAX_VOLUMES) { 699 - TRACE_ABORT(-EINVAL, ft_t_warn, 700 - "maximum allowed number of files " 701 - "exhausted: %d", ZFT_MAX_VOLUMES); 702 - } else { 703 - TRACE_ABORT(-ENOSPC, 704 - ft_t_noise, "reached end of tape"); 705 - } 706 - } 707 - TRACE_EXIT 0; 708 - } 709 - 710 - const zft_volinfo *zft_find_volume(unsigned int seg_pos) 711 - { 712 - TRACE_FUN(ft_t_flow); 713 - 714 - TRACE(ft_t_any, "called with seg_pos %d",seg_pos); 715 - if (!zft_qic_mode) { 716 - if (seg_pos > ft_last_data_segment) { 717 - TRACE_EXIT &eot_vtbl; 718 - } 719 - tape_vtbl.blk_sz = zft_blk_sz; 720 - TRACE_EXIT &tape_vtbl; 721 - } 722 - if (seg_pos < zft_first_vtbl->start_seg) { 723 - TRACE_EXIT (cur_vtbl = zft_first_vtbl); 724 - } 725 - while (seg_pos > cur_vtbl->end_seg) { 726 - cur_vtbl = list_entry(cur_vtbl->node.next, zft_volinfo, node); 727 - TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg); 728 - } 729 - while (seg_pos < cur_vtbl->start_seg) { 730 - cur_vtbl = list_entry(cur_vtbl->node.prev, zft_volinfo, node); 731 - TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg); 732 - } 733 - if (seg_pos > cur_vtbl->end_seg || seg_pos < cur_vtbl->start_seg) { 734 - TRACE(ft_t_bug, "This cannot happen"); 735 - } 736 - DUMP_VOLINFO(ft_t_noise, "", cur_vtbl); 737 - TRACE_EXIT cur_vtbl; 738 - } 739 - 740 - /* this function really assumes that we are just before eof 741 - */ 742 - void zft_move_past_eof(zft_position *pos) 743 - { 744 - TRACE_FUN(ft_t_flow); 745 - 746 - TRACE(ft_t_noise, "old seg. pos: %d", pos->seg_pos); 747 - pos->tape_pos += zft_get_seg_sz(pos->seg_pos++) - pos->seg_byte_pos; 748 - pos->seg_byte_pos = 0; 749 - pos->volume_pos = 0; 750 - if (zft_cmpr_ops) { 751 - (*zft_cmpr_ops->reset)(); 752 - } 753 - zft_just_before_eof = 0; 754 - zft_deblock_segment = -1; /* no need to cache it anymore */ 755 - TRACE(ft_t_noise, "new seg. pos: %d", pos->seg_pos); 756 - TRACE_EXIT; 757 - }
-227
drivers/char/ftape/zftape/zftape-vtbl.h
··· 1 - #ifndef _ZFTAPE_VTBL_H 2 - #define _ZFTAPE_VTBL_H 3 - 4 - /* 5 - * Copyright (c) 1995-1997 Claus-Justus Heine 6 - 7 - This program is free software; you can redistribute it and/or 8 - modify it under the terms of the GNU General Public License as 9 - published by the Free Software Foundation; either version 2, or (at 10 - your option) any later version. 11 - 12 - This program is distributed in the hope that it will be useful, but 13 - WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 - General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 20 - USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-vtbl.h,v $ 24 - * $Revision: 1.3 $ 25 - * $Date: 1997/10/28 14:30:09 $ 26 - * 27 - * This file defines a volume table as defined in the QIC-80 28 - * development standards. 29 - */ 30 - 31 - #include <linux/list.h> 32 - 33 - #include "../lowlevel/ftape-tracing.h" 34 - 35 - #include "../zftape/zftape-eof.h" 36 - #include "../zftape/zftape-ctl.h" 37 - #include "../zftape/zftape-rw.h" 38 - 39 - #define VTBL_SIZE 128 /* bytes */ 40 - 41 - /* The following are offsets in the vtbl. */ 42 - #define VTBL_SIG 0 43 - #define VTBL_START 4 44 - #define VTBL_END 6 45 - #define VTBL_DESC 8 46 - #define VTBL_DATE 52 47 - #define VTBL_FLAGS 56 48 - #define VTBL_FL_VENDOR_SPECIFIC (1<<0) 49 - #define VTBL_FL_MUTLI_CARTRIDGE (1<<1) 50 - #define VTBL_FL_NOT_VERIFIED (1<<2) 51 - #define VTBL_FL_REDIR_INHIBIT (1<<3) 52 - #define VTBL_FL_SEG_SPANNING (1<<4) 53 - #define VTBL_FL_DIRECTORY_LAST (1<<5) 54 - #define VTBL_FL_RESERVED_6 (1<<6) 55 - #define VTBL_FL_RESERVED_7 (1<<7) 56 - #define VTBL_M_NO 57 57 - #define VTBL_EXT 58 58 - #define EXT_ZFTAPE_SIG 0 59 - #define EXT_ZFTAPE_BLKSZ 10 60 - #define EXT_ZFTAPE_CMAP 12 61 - #define EXT_ZFTAPE_QIC113 13 62 - #define VTBL_PWD 84 63 - #define VTBL_DIR_SIZE 92 64 - #define VTBL_DATA_SIZE 96 65 - #define VTBL_OS_VERSION 104 66 - #define VTBL_SRC_DRIVE 106 67 - #define VTBL_DEV 122 68 - #define VTBL_RESERVED_1 123 69 - #define VTBL_CMPR 124 70 - #define VTBL_CMPR_UNREG 0x3f 71 - #define VTBL_CMPR_USED 0x80 72 - #define VTBL_FMT 125 73 - #define VTBL_RESERVED_2 126 74 - #define VTBL_RESERVED_3 127 75 - /* compatibility with pre revision K */ 76 - #define VTBL_K_CMPR 120 77 - 78 - /* the next is used by QIC-3020 tapes with format code 6 (>2^16 79 - * segments) It is specified in QIC-113, Rev. G, Section 5 (SCSI 80 - * volume table). The difference is simply, that we only store the 81 - * number of segments used, not the starting segment. 82 - */ 83 - #define VTBL_SCSI_SEGS 4 /* is a 4 byte value */ 84 - 85 - /* one vtbl is 128 bytes, that results in a maximum number of 86 - * 29*1024/128 = 232 volumes. 87 - */ 88 - #define ZFT_MAX_VOLUMES (FT_SEGMENT_SIZE/VTBL_SIZE) 89 - #define VTBL_ID "VTBL" 90 - #define VTBL_IDS { VTBL_ID, "XTBL", "UTID", "EXVT" } /* other valid ids */ 91 - #define ZFT_VOL_NAME "zftape volume" /* volume label used by me */ 92 - #define ZFTAPE_SIG "LINUX ZFT" 93 - 94 - /* global variables 95 - */ 96 - typedef struct zft_internal_vtbl 97 - { 98 - struct list_head node; 99 - int count; 100 - unsigned int start_seg; /* 32 bits are enough for now */ 101 - unsigned int end_seg; /* 32 bits are enough for now */ 102 - __s64 size; /* uncompressed size */ 103 - unsigned int blk_sz; /* block size for this volume */ 104 - unsigned int zft_volume :1; /* zftape created this volume */ 105 - unsigned int use_compression:1; /* compressed volume */ 106 - unsigned int qic113 :1; /* layout of compressed block 107 - * info and vtbl conforms to 108 - * QIC-113, Rev. G 109 - */ 110 - unsigned int new_volume :1; /* it was created by us, this 111 - * run. this allows the 112 - * fields that aren't really 113 - * used by zftape to be filled 114 - * in by some user level 115 - * program. 116 - */ 117 - unsigned int open :1; /* just in progress of being 118 - * written 119 - */ 120 - } zft_volinfo; 121 - 122 - extern struct list_head zft_vtbl; 123 - #define zft_head_vtbl list_entry(zft_vtbl.next, zft_volinfo, node) 124 - #define zft_eom_vtbl list_entry(zft_vtbl.prev, zft_volinfo, node) 125 - #define zft_last_vtbl list_entry(zft_eom_vtbl->node.prev, zft_volinfo, node) 126 - #define zft_first_vtbl list_entry(zft_head_vtbl->node.next, zft_volinfo, node) 127 - #define zft_vtbl_empty (zft_eom_vtbl->node.prev == &zft_head_vtbl->node) 128 - 129 - #define DUMP_VOLINFO(level, desc, info) \ 130 - { \ 131 - char tmp[21]; \ 132 - strlcpy(tmp, desc, sizeof(tmp)); \ 133 - TRACE(level, "Volume %d:\n" \ 134 - KERN_INFO "description : %s\n" \ 135 - KERN_INFO "first segment: %d\n" \ 136 - KERN_INFO "last segment: %d\n" \ 137 - KERN_INFO "size : " LL_X "\n" \ 138 - KERN_INFO "block size : %d\n" \ 139 - KERN_INFO "compression : %d\n" \ 140 - KERN_INFO "zftape volume: %d\n" \ 141 - KERN_INFO "QIC-113 conf.: %d", \ 142 - (info)->count, tmp, (info)->start_seg, (info)->end_seg, \ 143 - LL((info)->size), (info)->blk_sz, \ 144 - (info)->use_compression != 0, (info)->zft_volume != 0, \ 145 - (info)->qic113 != 0); \ 146 - } 147 - 148 - extern int zft_qic_mode; 149 - extern int zft_old_ftape; 150 - extern int zft_volume_table_changed; 151 - 152 - /* exported functions */ 153 - extern void zft_init_vtbl (void); 154 - extern void zft_free_vtbl (void); 155 - extern int zft_extract_volume_headers(__u8 *buffer); 156 - extern int zft_update_volume_table (unsigned int segment); 157 - extern int zft_open_volume (zft_position *pos, 158 - int blk_sz, int use_compression); 159 - extern int zft_close_volume (zft_position *pos); 160 - extern const zft_volinfo *zft_find_volume(unsigned int seg_pos); 161 - extern int zft_skip_volumes (int count, zft_position *pos); 162 - extern __s64 zft_get_eom_pos (void); 163 - extern void zft_skip_to_eom (zft_position *pos); 164 - extern int zft_fake_volume_headers (eof_mark_union *eof_map, 165 - int num_failed_sectors); 166 - extern int zft_weof (unsigned int count, zft_position *pos); 167 - extern void zft_move_past_eof (zft_position *pos); 168 - 169 - static inline int zft_tape_at_eod (const zft_position *pos); 170 - static inline int zft_tape_at_lbot (const zft_position *pos); 171 - static inline void zft_position_before_eof (zft_position *pos, 172 - const zft_volinfo *volume); 173 - static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl, 174 - const zft_position *pos); 175 - 176 - /* this function decrements the zft_seg_pos counter if we are right 177 - * at the beginning of a segment. This is to handle fsfm/bsfm -- we 178 - * need to position before the eof mark. NOTE: zft_tape_pos is not 179 - * changed 180 - */ 181 - static inline void zft_position_before_eof(zft_position *pos, 182 - const zft_volinfo *volume) 183 - { 184 - TRACE_FUN(ft_t_flow); 185 - 186 - if (pos->seg_pos == volume->end_seg + 1 && pos->seg_byte_pos == 0) { 187 - pos->seg_pos --; 188 - pos->seg_byte_pos = zft_get_seg_sz(pos->seg_pos); 189 - } 190 - TRACE_EXIT; 191 - } 192 - 193 - /* Mmmh. Is the position at the end of the last volume, that is right 194 - * before the last EOF mark also logical an EOD condition? 195 - */ 196 - static inline int zft_tape_at_eod(const zft_position *pos) 197 - { 198 - TRACE_FUN(ft_t_any); 199 - 200 - if (zft_qic_mode) { 201 - TRACE_EXIT (pos->seg_pos >= zft_eom_vtbl->start_seg || 202 - zft_last_vtbl->open); 203 - } else { 204 - TRACE_EXIT pos->seg_pos > ft_last_data_segment; 205 - } 206 - } 207 - 208 - static inline int zft_tape_at_lbot(const zft_position *pos) 209 - { 210 - if (zft_qic_mode) { 211 - return (pos->seg_pos <= zft_first_vtbl->start_seg && 212 - pos->volume_pos == 0); 213 - } else { 214 - return (pos->seg_pos <= ft_first_data_segment && 215 - pos->volume_pos == 0); 216 - } 217 - } 218 - 219 - /* This one checks for EOF. return remaing space (may be negative) 220 - */ 221 - static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl, 222 - const zft_position *pos) 223 - { 224 - return (__s64)(vtbl->size - pos->volume_pos); 225 - } 226 - 227 - #endif /* _ZFTAPE_VTBL_H */
-483
drivers/char/ftape/zftape/zftape-write.c
··· 1 - /* 2 - * Copyright (C) 1996, 1997 Claus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-write.c,v $ 20 - * $Revision: 1.3 $ 21 - * $Date: 1997/11/06 00:50:29 $ 22 - * 23 - * This file contains the writing code 24 - * for the QIC-117 floppy-tape driver for Linux. 25 - */ 26 - 27 - #include <linux/errno.h> 28 - #include <linux/mm.h> 29 - 30 - #include <linux/zftape.h> 31 - 32 - #include <asm/uaccess.h> 33 - 34 - #include "../zftape/zftape-init.h" 35 - #include "../zftape/zftape-eof.h" 36 - #include "../zftape/zftape-ctl.h" 37 - #include "../zftape/zftape-write.h" 38 - #include "../zftape/zftape-read.h" 39 - #include "../zftape/zftape-rw.h" 40 - #include "../zftape/zftape-vtbl.h" 41 - 42 - /* Global vars. 43 - */ 44 - 45 - /* Local vars. 46 - */ 47 - static int last_write_failed; 48 - static int need_flush; 49 - 50 - void zft_prevent_flush(void) 51 - { 52 - need_flush = 0; 53 - } 54 - 55 - static int zft_write_header_segments(__u8* buffer) 56 - { 57 - int header_1_ok = 0; 58 - int header_2_ok = 0; 59 - unsigned int time_stamp; 60 - TRACE_FUN(ft_t_noise); 61 - 62 - TRACE_CATCH(ftape_abort_operation(),); 63 - ftape_seek_to_bot(); /* prevents extra rewind */ 64 - if (GET4(buffer, 0) != FT_HSEG_MAGIC) { 65 - TRACE_ABORT(-EIO, ft_t_err, 66 - "wrong header signature found, aborting"); 67 - } 68 - /* Be optimistic: */ 69 - PUT4(buffer, FT_SEG_CNT, 70 - zft_written_segments + GET4(buffer, FT_SEG_CNT) + 2); 71 - if ((time_stamp = zft_get_time()) != 0) { 72 - PUT4(buffer, FT_WR_DATE, time_stamp); 73 - if (zft_label_changed) { 74 - PUT4(buffer, FT_LABEL_DATE, time_stamp); 75 - } 76 - } 77 - TRACE(ft_t_noise, 78 - "writing first header segment %d", ft_header_segment_1); 79 - header_1_ok = zft_verify_write_segments(ft_header_segment_1, 80 - buffer, FT_SEGMENT_SIZE, 81 - zft_deblock_buf) >= 0; 82 - TRACE(ft_t_noise, 83 - "writing second header segment %d", ft_header_segment_2); 84 - header_2_ok = zft_verify_write_segments(ft_header_segment_2, 85 - buffer, FT_SEGMENT_SIZE, 86 - zft_deblock_buf) >= 0; 87 - if (!header_1_ok) { 88 - TRACE(ft_t_warn, "Warning: " 89 - "update of first header segment failed"); 90 - } 91 - if (!header_2_ok) { 92 - TRACE(ft_t_warn, "Warning: " 93 - "update of second header segment failed"); 94 - } 95 - if (!header_1_ok && !header_2_ok) { 96 - TRACE_ABORT(-EIO, ft_t_err, "Error: " 97 - "update of both header segments failed."); 98 - } 99 - TRACE_EXIT 0; 100 - } 101 - 102 - int zft_update_header_segments(void) 103 - { 104 - TRACE_FUN(ft_t_noise); 105 - 106 - /* must NOT use zft_write_protected, as it also includes the 107 - * file access mode. But we also want to update when soft 108 - * write protection is enabled (O_RDONLY) 109 - */ 110 - if (ft_write_protected || zft_old_ftape) { 111 - TRACE_ABORT(0, ft_t_noise, "Tape set read-only: no update"); 112 - } 113 - if (!zft_header_read) { 114 - TRACE_ABORT(0, ft_t_noise, "Nothing to update"); 115 - } 116 - if (!zft_header_changed) { 117 - zft_header_changed = zft_written_segments > 0; 118 - } 119 - if (!zft_header_changed && !zft_volume_table_changed) { 120 - TRACE_ABORT(0, ft_t_noise, "Nothing to update"); 121 - } 122 - TRACE(ft_t_noise, "Updating header segments"); 123 - if (ftape_get_status()->fti_state == writing) { 124 - TRACE_CATCH(ftape_loop_until_writes_done(),); 125 - } 126 - TRACE_CATCH(ftape_abort_operation(),); 127 - 128 - zft_deblock_segment = -1; /* invalidate the cache */ 129 - if (zft_header_changed) { 130 - TRACE_CATCH(zft_write_header_segments(zft_hseg_buf),); 131 - } 132 - if (zft_volume_table_changed) { 133 - TRACE_CATCH(zft_update_volume_table(ft_first_data_segment),); 134 - } 135 - zft_header_changed = 136 - zft_volume_table_changed = 137 - zft_label_changed = 138 - zft_written_segments = 0; 139 - TRACE_CATCH(ftape_abort_operation(),); 140 - ftape_seek_to_bot(); 141 - TRACE_EXIT 0; 142 - } 143 - 144 - static int read_merge_buffer(int seg_pos, __u8 *buffer, int offset, int seg_sz) 145 - { 146 - int result = 0; 147 - const ft_trace_t old_tracing = TRACE_LEVEL; 148 - TRACE_FUN(ft_t_flow); 149 - 150 - if (zft_qic_mode) { 151 - /* writing in the middle of a volume is NOT allowed 152 - * 153 - */ 154 - TRACE(ft_t_noise, "No need to read a segment"); 155 - memset(buffer + offset, 0, seg_sz - offset); 156 - TRACE_EXIT 0; 157 - } 158 - TRACE(ft_t_any, "waiting"); 159 - ftape_start_writing(FT_WR_MULTI); 160 - TRACE_CATCH(ftape_loop_until_writes_done(),); 161 - 162 - TRACE(ft_t_noise, "trying to read segment %d from offset %d", 163 - seg_pos, offset); 164 - SET_TRACE_LEVEL(ft_t_bug); 165 - result = zft_fetch_segment_fraction(seg_pos, buffer, 166 - FT_RD_SINGLE, 167 - offset, seg_sz - offset); 168 - SET_TRACE_LEVEL(old_tracing); 169 - if (result != (seg_sz - offset)) { 170 - TRACE(ft_t_noise, "Ignore error: read_segment() result: %d", 171 - result); 172 - memset(buffer + offset, 0, seg_sz - offset); 173 - } 174 - TRACE_EXIT 0; 175 - } 176 - 177 - /* flush the write buffer to tape and write an eof-marker at the 178 - * current position if not in raw mode. This function always 179 - * positions the tape before the eof-marker. _ftape_close() should 180 - * then advance to the next segment. 181 - * 182 - * the parameter "finish_volume" describes whether to position before 183 - * or after the possibly created file-mark. We always position after 184 - * the file-mark when called from ftape_close() and a flush was needed 185 - * (that is ftape_write() was the last tape operation before calling 186 - * ftape_flush) But we always position before the file-mark when this 187 - * function get's called from outside ftape_close() 188 - */ 189 - int zft_flush_buffers(void) 190 - { 191 - int result; 192 - int data_remaining; 193 - int this_segs_size; 194 - TRACE_FUN(ft_t_flow); 195 - 196 - TRACE(ft_t_data_flow, 197 - "entered, ftape_state = %d", ftape_get_status()->fti_state); 198 - if (ftape_get_status()->fti_state != writing && !need_flush) { 199 - TRACE_ABORT(0, ft_t_noise, "no need for flush"); 200 - } 201 - zft_io_state = zft_idle; /* triggers some initializations for the 202 - * read and write routines 203 - */ 204 - if (last_write_failed) { 205 - ftape_abort_operation(); 206 - TRACE_EXIT -EIO; 207 - } 208 - TRACE(ft_t_noise, "flushing write buffers"); 209 - this_segs_size = zft_get_seg_sz(zft_pos.seg_pos); 210 - if (this_segs_size == zft_pos.seg_byte_pos) { 211 - zft_pos.seg_pos ++; 212 - data_remaining = zft_pos.seg_byte_pos = 0; 213 - } else { 214 - data_remaining = zft_pos.seg_byte_pos; 215 - } 216 - /* If there is any data not written to tape yet, append zero's 217 - * up to the end of the sector (if using compression) or merge 218 - * it with the data existing on the tape Then write the 219 - * segment(s) to tape. 220 - */ 221 - TRACE(ft_t_noise, "Position:\n" 222 - KERN_INFO "seg_pos : %d\n" 223 - KERN_INFO "byte pos : %d\n" 224 - KERN_INFO "remaining: %d", 225 - zft_pos.seg_pos, zft_pos.seg_byte_pos, data_remaining); 226 - if (data_remaining > 0) { 227 - do { 228 - this_segs_size = zft_get_seg_sz(zft_pos.seg_pos); 229 - if (this_segs_size > data_remaining) { 230 - TRACE_CATCH(read_merge_buffer(zft_pos.seg_pos, 231 - zft_deblock_buf, 232 - data_remaining, 233 - this_segs_size), 234 - last_write_failed = 1); 235 - } 236 - result = ftape_write_segment(zft_pos.seg_pos, 237 - zft_deblock_buf, 238 - FT_WR_MULTI); 239 - if (result != this_segs_size) { 240 - TRACE(ft_t_err, "flush buffers failed"); 241 - zft_pos.tape_pos -= zft_pos.seg_byte_pos; 242 - zft_pos.seg_byte_pos = 0; 243 - 244 - last_write_failed = 1; 245 - TRACE_EXIT result; 246 - } 247 - zft_written_segments ++; 248 - TRACE(ft_t_data_flow, 249 - "flush, moved out buffer: %d", result); 250 - /* need next segment for more data (empty segments?) 251 - */ 252 - if (result < data_remaining) { 253 - if (result > 0) { 254 - /* move remainder to buffer beginning 255 - */ 256 - memmove(zft_deblock_buf, 257 - zft_deblock_buf + result, 258 - FT_SEGMENT_SIZE - result); 259 - } 260 - } 261 - data_remaining -= result; 262 - zft_pos.seg_pos ++; 263 - } while (data_remaining > 0); 264 - TRACE(ft_t_any, "result: %d", result); 265 - zft_deblock_segment = --zft_pos.seg_pos; 266 - if (data_remaining == 0) { /* first byte next segment */ 267 - zft_pos.seg_byte_pos = this_segs_size; 268 - } else { /* after data previous segment, data_remaining < 0 */ 269 - zft_pos.seg_byte_pos = data_remaining + result; 270 - } 271 - } else { 272 - TRACE(ft_t_noise, "zft_deblock_buf empty"); 273 - zft_pos.seg_pos --; 274 - zft_pos.seg_byte_pos = zft_get_seg_sz (zft_pos.seg_pos); 275 - ftape_start_writing(FT_WR_MULTI); 276 - } 277 - TRACE(ft_t_any, "waiting"); 278 - if ((result = ftape_loop_until_writes_done()) < 0) { 279 - /* that's really bad. What to to with zft_tape_pos? 280 - */ 281 - TRACE(ft_t_err, "flush buffers failed"); 282 - } 283 - TRACE(ft_t_any, "zft_seg_pos: %d, zft_seg_byte_pos: %d", 284 - zft_pos.seg_pos, zft_pos.seg_byte_pos); 285 - last_write_failed = 286 - need_flush = 0; 287 - TRACE_EXIT result; 288 - } 289 - 290 - /* return-value: the number of bytes removed from the user-buffer 291 - * 292 - * out: 293 - * int *write_cnt: how much actually has been moved to the 294 - * zft_deblock_buf 295 - * int req_len : MUST NOT BE CHANGED, except at EOT, in 296 - * which case it may be adjusted 297 - * in : 298 - * char *buff : the user buffer 299 - * int buf_pos_write : copy of buf_len_wr int 300 - * this_segs_size : the size in bytes of the actual segment 301 - * char 302 - * *zft_deblock_buf : zft_deblock_buf 303 - */ 304 - static int zft_simple_write(int *cnt, 305 - __u8 *dst_buf, const int seg_sz, 306 - const __u8 __user *src_buf, const int req_len, 307 - const zft_position *pos,const zft_volinfo *volume) 308 - { 309 - int space_left; 310 - TRACE_FUN(ft_t_flow); 311 - 312 - /* volume->size holds the tape capacity while volume is open */ 313 - if (pos->tape_pos + volume->blk_sz > volume->size) { 314 - TRACE_EXIT -ENOSPC; 315 - } 316 - /* remaining space in this segment, NOT zft_deblock_buf 317 - */ 318 - space_left = seg_sz - pos->seg_byte_pos; 319 - *cnt = req_len < space_left ? req_len : space_left; 320 - if (copy_from_user(dst_buf + pos->seg_byte_pos, src_buf, *cnt) != 0) { 321 - TRACE_EXIT -EFAULT; 322 - } 323 - TRACE_EXIT *cnt; 324 - } 325 - 326 - static int check_write_access(int req_len, 327 - const zft_volinfo **volume, 328 - zft_position *pos, 329 - const unsigned int blk_sz) 330 - { 331 - int result; 332 - TRACE_FUN(ft_t_flow); 333 - 334 - if ((req_len % zft_blk_sz) != 0) { 335 - TRACE_ABORT(-EINVAL, ft_t_info, 336 - "write-count %d must be multiple of block-size %d", 337 - req_len, blk_sz); 338 - } 339 - if (zft_io_state == zft_writing) { 340 - /* all other error conditions have been checked earlier 341 - */ 342 - TRACE_EXIT 0; 343 - } 344 - zft_io_state = zft_idle; 345 - TRACE_CATCH(zft_check_write_access(pos),); 346 - /* If we haven't read the header segment yet, do it now. 347 - * This will verify the configuration, get the bad sector 348 - * table and read the volume table segment 349 - */ 350 - if (!zft_header_read) { 351 - TRACE_CATCH(zft_read_header_segments(),); 352 - } 353 - /* fine. Now the tape is either at BOT or at EOD, 354 - * Write start of volume now 355 - */ 356 - TRACE_CATCH(zft_open_volume(pos, blk_sz, zft_use_compression),); 357 - *volume = zft_find_volume(pos->seg_pos); 358 - DUMP_VOLINFO(ft_t_noise, "", *volume); 359 - zft_just_before_eof = 0; 360 - /* now merge with old data if necessary */ 361 - if (!zft_qic_mode && pos->seg_byte_pos != 0){ 362 - result = zft_fetch_segment(pos->seg_pos, 363 - zft_deblock_buf, 364 - FT_RD_SINGLE); 365 - if (result < 0) { 366 - if (result == -EINTR || result == -ENOSPC) { 367 - TRACE_EXIT result; 368 - } 369 - TRACE(ft_t_noise, 370 - "ftape_read_segment() result: %d. " 371 - "This might be normal when using " 372 - "a newly\nformatted tape", result); 373 - memset(zft_deblock_buf, '\0', pos->seg_byte_pos); 374 - } 375 - } 376 - zft_io_state = zft_writing; 377 - TRACE_EXIT 0; 378 - } 379 - 380 - static int fill_deblock_buf(__u8 *dst_buf, const int seg_sz, 381 - zft_position *pos, const zft_volinfo *volume, 382 - const char __user *usr_buf, const int req_len) 383 - { 384 - int cnt = 0; 385 - int result = 0; 386 - TRACE_FUN(ft_t_flow); 387 - 388 - if (seg_sz == 0) { 389 - TRACE_ABORT(0, ft_t_data_flow, "empty segment"); 390 - } 391 - TRACE(ft_t_data_flow, "\n" 392 - KERN_INFO "remaining req_len: %d\n" 393 - KERN_INFO " buf_pos: %d", 394 - req_len, pos->seg_byte_pos); 395 - /* zft_deblock_buf will not contain a valid segment any longer */ 396 - zft_deblock_segment = -1; 397 - if (zft_use_compression) { 398 - TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),); 399 - TRACE_CATCH(result= (*zft_cmpr_ops->write)(&cnt, 400 - dst_buf, seg_sz, 401 - usr_buf, req_len, 402 - pos, volume),); 403 - } else { 404 - TRACE_CATCH(result= zft_simple_write(&cnt, 405 - dst_buf, seg_sz, 406 - usr_buf, req_len, 407 - pos, volume),); 408 - } 409 - pos->volume_pos += result; 410 - pos->seg_byte_pos += cnt; 411 - pos->tape_pos += cnt; 412 - TRACE(ft_t_data_flow, "\n" 413 - KERN_INFO "removed from user-buffer : %d bytes.\n" 414 - KERN_INFO "copied to zft_deblock_buf: %d bytes.\n" 415 - KERN_INFO "zft_tape_pos : " LL_X " bytes.", 416 - result, cnt, LL(pos->tape_pos)); 417 - TRACE_EXIT result; 418 - } 419 - 420 - 421 - /* called by the kernel-interface routine "zft_write()" 422 - */ 423 - int _zft_write(const char __user *buff, int req_len) 424 - { 425 - int result = 0; 426 - int written = 0; 427 - int write_cnt; 428 - int seg_sz; 429 - static const zft_volinfo *volume = NULL; 430 - TRACE_FUN(ft_t_flow); 431 - 432 - zft_resid = req_len; 433 - last_write_failed = 1; /* reset to 0 when successful */ 434 - /* check if write is allowed 435 - */ 436 - TRACE_CATCH(check_write_access(req_len, &volume,&zft_pos,zft_blk_sz),); 437 - while (req_len > 0) { 438 - /* Allow us to escape from this loop with a signal ! 439 - */ 440 - FT_SIGNAL_EXIT(_DONT_BLOCK); 441 - seg_sz = zft_get_seg_sz(zft_pos.seg_pos); 442 - if ((write_cnt = fill_deblock_buf(zft_deblock_buf, 443 - seg_sz, 444 - &zft_pos, 445 - volume, 446 - buff, 447 - req_len)) < 0) { 448 - zft_resid -= written; 449 - if (write_cnt == -ENOSPC) { 450 - /* leave the remainder to flush_buffers() 451 - */ 452 - TRACE(ft_t_info, "No space left on device"); 453 - last_write_failed = 0; 454 - if (!need_flush) { 455 - need_flush = written > 0; 456 - } 457 - TRACE_EXIT written > 0 ? written : -ENOSPC; 458 - } else { 459 - TRACE_EXIT result; 460 - } 461 - } 462 - if (zft_pos.seg_byte_pos == seg_sz) { 463 - TRACE_CATCH(ftape_write_segment(zft_pos.seg_pos, 464 - zft_deblock_buf, 465 - FT_WR_ASYNC), 466 - zft_resid -= written); 467 - zft_written_segments ++; 468 - zft_pos.seg_byte_pos = 0; 469 - zft_deblock_segment = zft_pos.seg_pos; 470 - ++zft_pos.seg_pos; 471 - } 472 - written += write_cnt; 473 - buff += write_cnt; 474 - req_len -= write_cnt; 475 - } /* while (req_len > 0) */ 476 - TRACE(ft_t_data_flow, "remaining in blocking buffer: %d", 477 - zft_pos.seg_byte_pos); 478 - TRACE(ft_t_data_flow, "just written bytes: %d", written); 479 - last_write_failed = 0; 480 - zft_resid -= written; 481 - need_flush = need_flush || written > 0; 482 - TRACE_EXIT written; /* bytes written */ 483 - }
-38
drivers/char/ftape/zftape/zftape-write.h
··· 1 - #ifndef _ZFTAPE_WRITE_H 2 - #define _ZFTAPE_WRITE_H 3 - 4 - /* 5 - * Copyright (C) 1996, 1997 Claus-Justus Heine 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-write.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:19:13 $ 25 - * 26 - * This file contains the definitions for the write functions 27 - * for the zftape driver for Linux. 28 - * 29 - */ 30 - 31 - extern int zft_flush_buffers(void); 32 - extern int zft_update_header_segments(void); 33 - extern void zft_prevent_flush(void); 34 - 35 - /* hook for the VFS interface 36 - */ 37 - extern int _zft_write(const char __user *buff, int req_len); 38 - #endif /* _ZFTAPE_WRITE_H */
-43
drivers/char/ftape/zftape/zftape_syms.c
··· 1 - /* 2 - * Copyright (C) 1997 Claus-Justus Heine 3 - 4 - This program is free software; you can redistribute it and/or modify 5 - it under the terms of the GNU General Public License as published by 6 - the Free Software Foundation; either version 2, or (at your option) 7 - any later version. 8 - 9 - This program is distributed in the hope that it will be useful, 10 - but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - GNU General Public License for more details. 13 - 14 - You should have received a copy of the GNU General Public License 15 - along with this program; see the file COPYING. If not, write to 16 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 - 18 - * 19 - * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape_syms.c,v $ 20 - * $Revision: 1.3 $ 21 - * $Date: 1997/10/05 19:19:14 $ 22 - * 23 - * This file contains the symbols that the zftape frontend to 24 - * the ftape floppy tape driver exports 25 - */ 26 - 27 - #include <linux/module.h> 28 - 29 - #include <linux/zftape.h> 30 - 31 - #include "../zftape/zftape-init.h" 32 - #include "../zftape/zftape-read.h" 33 - #include "../zftape/zftape-buffers.h" 34 - #include "../zftape/zftape-ctl.h" 35 - 36 - /* zftape-init.c */ 37 - EXPORT_SYMBOL(zft_cmpr_register); 38 - /* zftape-read.c */ 39 - EXPORT_SYMBOL(zft_fetch_segment_fraction); 40 - /* zftape-buffers.c */ 41 - EXPORT_SYMBOL(zft_vmalloc_once); 42 - EXPORT_SYMBOL(zft_vmalloc_always); 43 - EXPORT_SYMBOL(zft_vfree);
-4
include/linux/Kbuild
··· 60 60 header-y += fd.h 61 61 header-y += fdreg.h 62 62 header-y += fib_rules.h 63 - header-y += ftape-header-segment.h 64 - header-y += ftape-vendors.h 65 63 header-y += fuse.h 66 64 header-y += futex.h 67 65 header-y += genetlink.h ··· 204 206 unifdef-y += filter.h 205 207 unifdef-y += flat.h 206 208 unifdef-y += fs.h 207 - unifdef-y += ftape.h 208 209 unifdef-y += gameport.h 209 210 unifdef-y += generic_serial.h 210 211 unifdef-y += genhd.h ··· 338 341 unifdef-y += wanrouter.h 339 342 unifdef-y += watchdog.h 340 343 unifdef-y += xfrm.h 341 - unifdef-y += zftape.h 342 344 343 345 objhdr-y += version.h
-122
include/linux/ftape-header-segment.h
··· 1 - #ifndef _FTAPE_HEADER_SEGMENT_H 2 - #define _FTAPE_HEADER_SEGMENT_H 3 - 4 - /* 5 - * Copyright (C) 1996-1997 Claus-Justus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/include/linux/ftape-header-segment.h,v $ 23 - * $Revision: 1.2 $ 24 - * $Date: 1997/10/05 19:19:28 $ 25 - * 26 - * This file defines some offsets into the header segment of a 27 - * floppy tape cartridge. For use with the QIC-40/80/3010/3020 28 - * floppy-tape driver "ftape" for Linux. 29 - */ 30 - 31 - #define FT_SIGNATURE 0 /* must be 0xaa55aa55 */ 32 - #define FT_FMT_CODE 4 33 - #define FT_REV_LEVEL 5 /* only for QIC-80 since. Rev. L (== 0x0c) */ 34 - #define FT_HSEG_1 6 /* first header segment, except for format code 6 */ 35 - #define FT_HSEG_2 8 /* second header segment, except for format code 6 */ 36 - #define FT_FRST_SEG 10 /* first data segment, except for format code 6 */ 37 - #define FT_LAST_SEG 12 /* last data segment, except for format code 6 */ 38 - #define FT_FMT_DATE 14 /* date and time of most recent format, see below */ 39 - #define FT_WR_DATE 18 /* date and time of most recent write or format */ 40 - #define FT_SPT 24 /* segments per track */ 41 - #define FT_TPC 26 /* tracks per cartridge */ 42 - #define FT_FHM 27 /* floppy drive head (maximum of it) */ 43 - #define FT_FTM 28 /* floppy track max. */ 44 - #define FT_FSM 29 /* floppy sector max. (128) */ 45 - #define FT_LABEL 30 /* floppy tape label */ 46 - #define FT_LABEL_DATE 74 /* date and time the tape label was written */ 47 - #define FT_LABEL_SZ (FT_LABEL_DATE - FT_LABEL) 48 - #define FT_CMAP_START 78 /* starting segment of compression map */ 49 - #define FT_FMT_ERROR 128 /* must be set to 0xff if remainder gets lost during 50 - * tape format 51 - */ 52 - #define FT_SEG_CNT 130 /* number of seg. written, formatted or verified 53 - * through lifetime of tape (why not read?) 54 - */ 55 - #define FT_INIT_DATE 138 /* date and time of initial tape format */ 56 - #define FT_FMT_CNT 142 /* number of times tape has been formatted */ 57 - #define FT_FSL_CNT 144 /* number of segments in failed sector log */ 58 - #define FT_MK_CODE 146 /* id string of tape manufacturer */ 59 - #define FT_LOT_CODE 190 /* tape manufacturer lot code */ 60 - #define FT_6_HSEG_1 234 /* first header segment for format code 6 */ 61 - #define FT_6_HSEG_2 238 /* second header segment for format code 6 */ 62 - #define FT_6_FRST_SEG 242 /* first data segment for format code 6 */ 63 - #define FT_6_LAST_SEG 246 /* last data segment for format code 6 */ 64 - 65 - #define FT_FSL 256 66 - #define FT_HEADER_END 256 /* space beyond this point: 67 - * format codes 2, 3 and 5: 68 - * - failed sector log until byte 2047 69 - * - bad sector map in the reamining part of segment 70 - * format codes 4 and 6: 71 - * - bad sector map starts hear 72 - */ 73 - 74 - 75 - /* value to be stored at the FT_SIGNATURE offset 76 - */ 77 - #define FT_HSEG_MAGIC 0xaa55aa55 78 - #define FT_D2G_MAGIC 0x82288228 /* Ditto 2GB */ 79 - 80 - /* data and time encoding: */ 81 - #define FT_YEAR_SHIFT 25 82 - #define FT_YEAR_MASK 0xfe000000 83 - #define FT_YEAR_0 1970 84 - #define FT_YEAR_MAX 127 85 - #define FT_YEAR(year) ((((year)-FT_YEAR_0)<<FT_YEAR_SHIFT)&FT_YEAR_MASK) 86 - 87 - #define FT_TIME_SHIFT 0 88 - #define FT_TIME_MASK 0x01FFFFFF 89 - #define FT_TIME_MAX 0x01ea6dff /* last second of a year */ 90 - #define FT_TIME(mo,d,h,m,s) \ 91 - ((((s)+60*((m)+60*((h)+24*((d)+31*(mo))))) & FT_TIME_MASK)) 92 - 93 - #define FT_TIME_STAMP(y,mo,d,h,m,s) (FT_YEAR(y) | FT_TIME(mo,d,h,m,s)) 94 - 95 - /* values for the format code field */ 96 - typedef enum { 97 - fmt_normal = 2, /* QIC-80 post Rev. B 205Ft or 307Ft tape */ 98 - fmt_1100ft = 3, /* QIC-80 post Rev. B 1100Ft tape */ 99 - fmt_var = 4, /* QIC-80 post Rev. B variabel length format */ 100 - fmt_425ft = 5, /* QIC-80 post Rev. B 425Ft tape */ 101 - fmt_big = 6 /* QIC-3010/3020 variable length tape with more 102 - * than 2^16 segments per tape 103 - */ 104 - } ft_format_type; 105 - 106 - /* definitions for the failed sector log */ 107 - #define FT_FSL_SIZE (2 * FT_SECTOR_SIZE - FT_HEADER_END) 108 - #define FT_FSL_MAX_ENTRIES (FT_FSL_SIZE/sizeof(__u32)) 109 - 110 - typedef struct ft_fsl_entry { 111 - __u16 segment; 112 - __u16 date; 113 - } __attribute__ ((packed)) ft_fsl_entry; 114 - 115 - 116 - /* date encoding for the failed sector log 117 - * month: 1..12, day: 1..31, year: 1970..2097 118 - */ 119 - #define FT_FSL_TIME_STAMP(y,m,d) \ 120 - (((((y) - FT_YEAR_0)<<9)&0xfe00) | (((m)<<5)&0x01e0) | ((d)&0x001f)) 121 - 122 - #endif /* _FTAPE_HEADER_SEGMENT_H */
-137
include/linux/ftape-vendors.h
··· 1 - #ifndef _FTAPE_VENDORS_H 2 - #define _FTAPE_VENDORS_H 3 - 4 - /* 5 - * Copyright (C) 1993-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/include/linux/ftape-vendors.h,v $ 24 - * $Revision: 1.6 $ 25 - * $Date: 1997/10/09 15:38:11 $ 26 - * 27 - * This file contains the supported drive types with their 28 - * QIC-117 spec. vendor code and drive dependent configuration 29 - * information. 30 - */ 31 - 32 - typedef enum { 33 - unknown_wake_up = 0, 34 - no_wake_up, 35 - wake_up_colorado, 36 - wake_up_mountain, 37 - wake_up_insight, 38 - } wake_up_types; 39 - 40 - typedef struct { 41 - wake_up_types wake_up; /* see wake_up_types */ 42 - char *name; /* Text describing the drive */ 43 - } wakeup_method; 44 - 45 - /* Note: order of entries in WAKEUP_METHODS must be so that a variable 46 - * of type wake_up_types can be used as an index in the array. 47 - */ 48 - #define WAKEUP_METHODS { \ 49 - { unknown_wake_up, "Unknown" }, \ 50 - { no_wake_up, "None" }, \ 51 - { wake_up_colorado, "Colorado" }, \ 52 - { wake_up_mountain, "Mountain" }, \ 53 - { wake_up_insight, "Motor-on" }, \ 54 - } 55 - 56 - typedef struct { 57 - unsigned int vendor_id; /* vendor id from drive */ 58 - int speed; /* maximum tape transport speed (ips) */ 59 - wake_up_types wake_up; /* see wake_up_types */ 60 - char *name; /* Text describing the drive */ 61 - } vendor_struct; 62 - 63 - #define UNKNOWN_VENDOR (-1) 64 - 65 - #define QIC117_VENDORS { \ 66 - /* see _vendor_struct */ \ 67 - { 0x00000, 82, wake_up_colorado, "Colorado DJ-10 (old)" }, \ 68 - { 0x00047, 90, wake_up_colorado, "Colorado DJ-10/DJ-20" }, \ 69 - { 0x011c2, 84, wake_up_colorado, "Colorado 700" }, \ 70 - { 0x011c3, 90, wake_up_colorado, "Colorado 1400" }, \ 71 - { 0x011c4, 84, wake_up_colorado, "Colorado DJ-10/DJ-20 (new)" }, \ 72 - { 0x011c5, 84, wake_up_colorado, "HP Colorado T1000" }, \ 73 - { 0x011c6, 90, wake_up_colorado, "HP Colorado T3000" }, \ 74 - { 0x00005, 45, wake_up_mountain, "Archive 5580i" }, \ 75 - { 0x10005, 50, wake_up_insight, "Insight 80Mb, Irwin 80SX" }, \ 76 - { 0x00140, 74, wake_up_mountain, "Archive S.Hornet [Identity/Escom]" }, \ 77 - { 0x00146, 72, wake_up_mountain, "Archive 31250Q [Escom]" }, \ 78 - { 0x0014a, 100, wake_up_mountain, "Archive XL9250i [Conner/Escom]" }, \ 79 - { 0x0014c, 98, wake_up_mountain, "Conner C250MQT" }, \ 80 - { 0x0014e, 80, wake_up_mountain, "Conner C250MQ" }, \ 81 - { 0x00150, 80, wake_up_mountain, "Conner TSM420R/TST800R" }, \ 82 - { 0x00152, 80, wake_up_mountain, "Conner TSM850R" }, \ 83 - { 0x00156, 80, wake_up_mountain, "Conner TSM850R/1700R/TST3200R" }, \ 84 - { 0x00180, 0, wake_up_mountain, "Summit SE 150" }, \ 85 - { 0x00181, 85, wake_up_mountain, "Summit SE 250, Mountain FS8000" }, \ 86 - { 0x001c1, 82, no_wake_up, "Wangtek 3040F" }, \ 87 - { 0x001c8, 64, no_wake_up, "Wangtek 3080F" }, \ 88 - { 0x001c8, 64, wake_up_colorado, "Wangtek 3080F" }, \ 89 - { 0x001ca, 67, no_wake_up, "Wangtek 3080F (new)" }, \ 90 - { 0x001cc, 77, wake_up_colorado, "Wangtek 3200 / Teac 700" }, \ 91 - { 0x001cd, 75, wake_up_colorado, "Reveal TB1400" }, \ 92 - { 0x00380, 85, wake_up_colorado, "Exabyte Eagle-96" }, \ 93 - { 0x00381, 85, wake_up_colorado, "Exabyte Eagle TR-3" }, \ 94 - { 0x00382, 85, wake_up_colorado, "Exabyte Eagle TR-3" }, \ 95 - { 0x003ce, 77, wake_up_colorado, "Teac 800" }, \ 96 - { 0x003cf, 0, wake_up_colorado, "Teac FT3010TR" }, \ 97 - { 0x08880, 64, no_wake_up, "Iomega 250, Ditto 800" }, \ 98 - { 0x08880, 64, wake_up_colorado, "Iomega 250, Ditto 800" }, \ 99 - { 0x08880, 64, wake_up_insight, "Iomega 250, Ditto 800" }, \ 100 - { 0x08881, 80, wake_up_colorado, "Iomega 700" }, \ 101 - { 0x08882, 80, wake_up_colorado, "Iomega 3200" }, \ 102 - { 0x08883, 80, wake_up_colorado, "Iomega DITTO 2GB" }, \ 103 - { 0x00021, 70, no_wake_up, "AIWA CT-803" }, \ 104 - { 0x004c0, 80, no_wake_up, "AIWA TD-S1600" }, \ 105 - { 0x00021, 0, wake_up_mountain, "COREtape QIC80" }, \ 106 - { 0x00441, 0, wake_up_mountain, "ComByte DoublePlay" }, \ 107 - { 0x00481, 127, wake_up_mountain, "PERTEC MyTape 800" }, \ 108 - { 0x00483, 130, wake_up_mountain, "PERTEC MyTape 3200" }, \ 109 - { UNKNOWN_VENDOR, 0, no_wake_up, "unknown" } \ 110 - } 111 - 112 - #define QIC117_MAKE_CODES { \ 113 - { 0, "Unassigned" }, \ 114 - { 1, "Alloy Computer Products" }, \ 115 - { 2, "3M" }, \ 116 - { 3, "Tandberg Data" }, \ 117 - { 4, "Colorado" }, \ 118 - { 5, "Archive/Conner" }, \ 119 - { 6, "Mountain/Summit Memory Systems" }, \ 120 - { 7, "Wangtek/Rexon/Tecmar" }, \ 121 - { 8, "Sony" }, \ 122 - { 9, "Cipher Data Products" }, \ 123 - { 10, "Irwin Magnetic Systems" }, \ 124 - { 11, "Braemar" }, \ 125 - { 12, "Verbatim" }, \ 126 - { 13, "Core International" }, \ 127 - { 14, "Exabyte" }, \ 128 - { 15, "Teac" }, \ 129 - { 16, "Gigatek" }, \ 130 - { 17, "ComByte" }, \ 131 - { 18, "PERTEC Memories" }, \ 132 - { 19, "Aiwa" }, \ 133 - { 71, "Colorado" }, \ 134 - { 546, "Iomega Inc" }, \ 135 - } 136 - 137 - #endif /* _FTAPE_VENDORS_H */
-201
include/linux/ftape.h
··· 1 - #ifndef _FTAPE_H 2 - #define _FTAPE_H 3 - 4 - /* 5 - * Copyright (C) 1994-1996 Bas Laarhoven, 6 - * (C) 1996-1997 Claus-Justus Heine. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2, or (at your option) 11 - any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; see the file COPYING. If not, write to 20 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 - 22 - * 23 - * $Source: /homes/cvs/ftape-stacked/include/linux/ftape.h,v $ 24 - * $Revision: 1.17.6.4 $ 25 - * $Date: 1997/11/25 01:52:54 $ 26 - * 27 - * This file contains global definitions, typedefs and macro's 28 - * for the QIC-40/80/3010/3020 floppy-tape driver for Linux. 29 - */ 30 - 31 - #define FTAPE_VERSION "ftape v3.04d 25/11/97" 32 - 33 - #ifdef __KERNEL__ 34 - #include <linux/interrupt.h> 35 - #include <linux/mm.h> 36 - #endif 37 - #include <linux/types.h> 38 - #include <linux/mtio.h> 39 - 40 - #define FT_SECTOR(x) (x+1) /* sector offset into real sector */ 41 - #define FT_SECTOR_SIZE 1024 42 - #define FT_SECTORS_PER_SEGMENT 32 43 - #define FT_ECC_SECTORS 3 44 - #define FT_SEGMENT_SIZE ((FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS) * FT_SECTOR_SIZE) 45 - #define FT_BUFF_SIZE (FT_SECTORS_PER_SEGMENT * FT_SECTOR_SIZE) 46 - 47 - /* 48 - * bits of the minor device number that define drive selection 49 - * methods. Could be used one day to access multiple tape 50 - * drives on the same controller. 51 - */ 52 - #define FTAPE_SEL_A 0 53 - #define FTAPE_SEL_B 1 54 - #define FTAPE_SEL_C 2 55 - #define FTAPE_SEL_D 3 56 - #define FTAPE_SEL_MASK 3 57 - #define FTAPE_SEL(unit) ((unit) & FTAPE_SEL_MASK) 58 - #define FTAPE_NO_REWIND 4 /* mask for minor nr */ 59 - 60 - /* the following two may be reported when MTIOCGET is requested ... */ 61 - typedef union { 62 - struct { 63 - __u8 error; 64 - __u8 command; 65 - } error; 66 - long space; 67 - } ft_drive_error; 68 - typedef union { 69 - struct { 70 - __u8 drive_status; 71 - __u8 drive_config; 72 - __u8 tape_status; 73 - } status; 74 - long space; 75 - } ft_drive_status; 76 - 77 - #ifdef __KERNEL__ 78 - 79 - #define FT_RQM_DELAY 12 80 - #define FT_MILLISECOND 1 81 - #define FT_SECOND 1000 82 - #define FT_FOREVER -1 83 - #ifndef HZ 84 - #error "HZ undefined." 85 - #endif 86 - #define FT_USPT (1000000/HZ) /* microseconds per tick */ 87 - 88 - /* This defines the number of retries that the driver will allow 89 - * before giving up (and letting a higher level handle the error). 90 - */ 91 - #ifdef TESTING 92 - #define FT_SOFT_RETRIES 1 /* number of low level retries */ 93 - #define FT_RETRIES_ON_ECC_ERROR 3 /* ecc error when correcting segment */ 94 - #else 95 - #define FT_SOFT_RETRIES 6 /* number of low level retries (triple) */ 96 - #define FT_RETRIES_ON_ECC_ERROR 3 /* ecc error when correcting segment */ 97 - #endif 98 - 99 - #ifndef THE_FTAPE_MAINTAINER 100 - #define THE_FTAPE_MAINTAINER "the ftape maintainer" 101 - #endif 102 - 103 - /* Initialize missing configuration parameters. 104 - */ 105 - #ifndef CONFIG_FT_NR_BUFFERS 106 - # define CONFIG_FT_NR_BUFFERS 3 107 - #endif 108 - #ifndef CONFIG_FT_FDC_THR 109 - # define CONFIG_FT_FDC_THR 8 110 - #endif 111 - #ifndef CONFIG_FT_FDC_MAX_RATE 112 - # define CONFIG_FT_FDC_MAX_RATE 2000 113 - #endif 114 - #ifndef CONFIG_FT_FDC_BASE 115 - # define CONFIG_FT_FDC_BASE 0 116 - #endif 117 - #ifndef CONFIG_FT_FDC_IRQ 118 - # define CONFIG_FT_FDC_IRQ 0 119 - #endif 120 - #ifndef CONFIG_FT_FDC_DMA 121 - # define CONFIG_FT_FDC_DMA 0 122 - #endif 123 - 124 - /* Turn some booleans into numbers. 125 - */ 126 - #ifdef CONFIG_FT_PROBE_FC10 127 - # undef CONFIG_FT_PROBE_FC10 128 - # define CONFIG_FT_PROBE_FC10 1 129 - #else 130 - # define CONFIG_FT_PROBE_FC10 0 131 - #endif 132 - #ifdef CONFIG_FT_MACH2 133 - # undef CONFIG_FT_MACH2 134 - # define CONFIG_FT_MACH2 1 135 - #else 136 - # define CONFIG_FT_MACH2 0 137 - #endif 138 - 139 - /* Insert default settings 140 - */ 141 - #if CONFIG_FT_PROBE_FC10 == 1 142 - # if CONFIG_FT_FDC_BASE == 0 143 - # undef CONFIG_FT_FDC_BASE 144 - # define CONFIG_FT_FDC_BASE 0x180 145 - # endif 146 - # if CONFIG_FT_FDC_IRQ == 0 147 - # undef CONFIG_FT_FDC_IRQ 148 - # define CONFIG_FT_FDC_IRQ 9 149 - # endif 150 - # if CONFIG_FT_FDC_DMA == 0 151 - # undef CONFIG_FT_FDC_DMA 152 - # define CONFIG_FT_FDC_DMA 3 153 - # endif 154 - #elif CONFIG_FT_MACH2 == 1 /* CONFIG_FT_PROBE_FC10 == 1 */ 155 - # if CONFIG_FT_FDC_BASE == 0 156 - # undef CONFIG_FT_FDC_BASE 157 - # define CONFIG_FT_FDC_BASE 0x1E0 158 - # endif 159 - # if CONFIG_FT_FDC_IRQ == 0 160 - # undef CONFIG_FT_FDC_IRQ 161 - # define CONFIG_FT_FDC_IRQ 6 162 - # endif 163 - # if CONFIG_FT_FDC_DMA == 0 164 - # undef CONFIG_FT_FDC_DMA 165 - # define CONFIG_FT_FDC_DMA 2 166 - # endif 167 - #elif defined(CONFIG_FT_ALT_FDC) /* CONFIG_FT_MACH2 */ 168 - # if CONFIG_FT_FDC_BASE == 0 169 - # undef CONFIG_FT_FDC_BASE 170 - # define CONFIG_FT_FDC_BASE 0x370 171 - # endif 172 - # if CONFIG_FT_FDC_IRQ == 0 173 - # undef CONFIG_FT_FDC_IRQ 174 - # define CONFIG_FT_FDC_IRQ 6 175 - # endif 176 - # if CONFIG_FT_FDC_DMA == 0 177 - # undef CONFIG_FT_FDC_DMA 178 - # define CONFIG_FT_FDC_DMA 2 179 - # endif 180 - #else /* CONFIG_FT_ALT_FDC */ 181 - # if CONFIG_FT_FDC_BASE == 0 182 - # undef CONFIG_FT_FDC_BASE 183 - # define CONFIG_FT_FDC_BASE 0x3f0 184 - # endif 185 - # if CONFIG_FT_FDC_IRQ == 0 186 - # undef CONFIG_FT_FDC_IRQ 187 - # define CONFIG_FT_FDC_IRQ 6 188 - # endif 189 - # if CONFIG_FT_FDC_DMA == 0 190 - # undef CONFIG_FT_FDC_DMA 191 - # define CONFIG_FT_FDC_DMA 2 192 - # endif 193 - #endif /* standard FDC */ 194 - 195 - /* some useful macro's 196 - */ 197 - #define NR_ITEMS(x) (int)(sizeof(x)/ sizeof(*x)) 198 - 199 - #endif /* __KERNEL__ */ 200 - 201 - #endif
-87
include/linux/zftape.h
··· 1 - #ifndef _ZFTAPE_H 2 - #define _ZFTAPE_H 3 - 4 - /* 5 - * Copyright (C) 1996, 1997 Claus-Justus Heine. 6 - 7 - This program is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - This program is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with this program; see the file COPYING. If not, write to 19 - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 - 21 - * 22 - * $Source: /homes/cvs/ftape-stacked/include/linux/zftape.h,v $ 23 - * $Revision: 1.12 $ 24 - * $Date: 1997/10/21 11:02:37 $ 25 - * 26 - * Special ioctl and other global info for the zftape VFS 27 - * interface for the QIC-40/80/3010/3020 floppy-tape driver for 28 - * Linux. 29 - */ 30 - 31 - #define ZFTAPE_VERSION "zftape for " FTAPE_VERSION 32 - 33 - #include <linux/ftape.h> 34 - 35 - #define ZFTAPE_LABEL "Ftape - The Linux Floppy Tape Project!" 36 - 37 - /* Bits of the minor device number that control the operation mode */ 38 - #define ZFT_Q80_MODE (1 << 3) 39 - #define ZFT_ZIP_MODE (1 << 4) 40 - #define ZFT_RAW_MODE (1 << 5) 41 - #define ZFT_MINOR_OP_MASK (ZFT_Q80_MODE | \ 42 - ZFT_ZIP_MODE | \ 43 - ZFT_RAW_MODE) 44 - #define ZFT_MINOR_MASK (FTAPE_SEL_MASK | \ 45 - ZFT_MINOR_OP_MASK | \ 46 - FTAPE_NO_REWIND) 47 - 48 - #ifdef ZFT_OBSOLETE 49 - struct mtblksz { 50 - unsigned int mt_blksz; 51 - }; 52 - #define MTIOC_ZFTAPE_GETBLKSZ _IOR('m', 104, struct mtblksz) 53 - #endif 54 - 55 - #ifdef __KERNEL__ 56 - 57 - extern int zft_init(void); 58 - 59 - static inline __s64 zft_div_blksz(__s64 value, __u32 blk_sz) 60 - { 61 - if (blk_sz == 1) { 62 - return value; 63 - } else { 64 - return (__s64)(((__u32)(value >> 10) + (blk_sz >> 10) - 1) 65 - / (blk_sz >> 10)); 66 - } 67 - } 68 - 69 - static inline __s64 zft_mul_blksz(__s64 value, __u32 blk_sz) 70 - { 71 - if (blk_sz == 1) { 72 - return value; 73 - } else { 74 - /* if blk_sz != 1, then it is a multiple of 1024. In 75 - * this case, `value' will also fit into 32 bits. 76 - * 77 - * Actually, this limits the capacity to 42 78 - * bits. This is (2^32)*1024, roughly a thousand 79 - * times 2GB, or 3 Terabytes. Hopefully this is enough 80 - */ 81 - return(__s64)(((__u32)(value)*(blk_sz>>10))<<10); 82 - } 83 - } 84 - 85 - #endif 86 - 87 - #endif