/*
 *      Copyright (C) 1994-1997 Claus-Justus Heine

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as
 published by the Free Software Foundation; either version 2, or (at
 your option) any later version.
 
 This program is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
 USA.
 
 *
 *     This file implements a "generic" interface between the *
 *     zftape-driver and a compression-algorithm. The *
 *     compression-algorithm currently used is a LZ77. I use the *
 *     implementation lzrw3 by Ross N. Williams (Renaissance *
 *     Software). The compression program itself is in the file
 *     lzrw3.c * and lzrw3.h.  To adopt another compression algorithm
 *     the functions * zft_compress() and zft_uncompress() must be
 *     changed * appropriately. See below.
 */

#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/module.h>

#include <linux/zftape.h>

#include <asm/uaccess.h>

#include "../zftape/zftape-init.h"
#include "../zftape/zftape-eof.h"
#include "../zftape/zftape-ctl.h"
#include "../zftape/zftape-write.h"
#include "../zftape/zftape-read.h"
#include "../zftape/zftape-rw.h"
#include "../compressor/zftape-compress.h"
#include "../zftape/zftape-vtbl.h"
#include "../compressor/lzrw3.h"

/*
 *   global variables
 */

/* I handle the allocation of this buffer as a special case, because
 * it's size varies depending on the tape length inserted.
 */

/* local variables 
 */
static void *zftc_wrk_mem = NULL;
static __u8 *zftc_buf     = NULL;
static void *zftc_scratch_buf  = NULL;

/* compression statistics 
 */
static unsigned int zftc_wr_uncompressed = 0;
static unsigned int zftc_wr_compressed   = 0;
static unsigned int zftc_rd_uncompressed = 0;
static unsigned int zftc_rd_compressed   = 0;

/* forward */
static int  zftc_write(int *write_cnt,
		       __u8 *dst_buf, const int seg_sz,
		       const __u8 __user *src_buf, const int req_len,
		       const zft_position *pos, const zft_volinfo *volume);
static int  zftc_read(int *read_cnt,
		      __u8  __user *dst_buf, const int to_do,
		      const __u8 *src_buf, const int seg_sz,
		      const zft_position *pos, const zft_volinfo *volume);
static int  zftc_seek(unsigned int new_block_pos, 
		      zft_position *pos, const zft_volinfo *volume,
		      __u8 *buffer);
static void zftc_lock   (void);
static void zftc_reset  (void);
static void zftc_cleanup(void);
static void zftc_stats      (void);

/* compressed segment. This conforms to QIC-80-MC, Revision K.
 * 
 * Rev. K applies to tapes with `fixed length format' which is
 * indicated by format code 2,3 and 5. See below for format code 4 and 6
 *
 * 2 bytes: offset of compression segment structure
 *          29k > offset >= 29k-18: data from previous segment ens in this
 *                                  segment and no compressed block starts
 *                                  in this segment
 *                     offset == 0: data from previous segment occupies entire
 *                                  segment and continues in next segment
 * n bytes: remainder from previous segment
 * 
 * Rev. K:  
 * 4 bytes: 4 bytes: files set byte offset
 * Post Rev. K and QIC-3020/3020:
 * 8 bytes: 8 bytes: files set byte offset
 * 2 bytes: byte count N (amount of data following)
 *          bit 15 is set if data is compressed, bit 15 is not
 *          set if data is uncompressed
 * N bytes: data (as much as specified in the byte count)
 * 2 bytes: byte count N_1 of next cluster
 * N_1 bytes: data of next cluset
 * 2 bytes: byte count N_2 of next cluster
 * N_2 bytes: ...  
 *
 * Note that the `N' byte count accounts only for the bytes that in the
 * current segment if the cluster spans to the next segment.
 */

typedef struct
{
	int cmpr_pos;             /* actual position in compression buffer */
	int cmpr_sz;              /* what is left in the compression buffer
				   * when copying the compressed data to the
				   * deblock buffer
				   */
	unsigned int first_block; /* location of header information in
				   * this segment
				   */
	unsigned int count;       /* amount of data of current block
				   * contained in current segment 
				   */
	unsigned int offset;      /* offset in current segment */
	unsigned int spans:1;     /* might continue in next segment */
	unsigned int uncmpr;      /* 0x8000 if this block contains
				   * uncompressed data 
				   */
	__s64 foffs;              /* file set byte offset, same as in 
				   * compression map segment
				   */
} cmpr_info;

static cmpr_info cseg; /* static data. Must be kept uptodate and shared by 
			* read, write and seek functions
			*/

#define DUMP_CMPR_INFO(level, msg, info)				\
	TRACE(level, msg "\n"						\
	      KERN_INFO "cmpr_pos   : %d\n"				\
	      KERN_INFO "cmpr_sz    : %d\n"				\
	      KERN_INFO "first_block: %d\n"				\
	      KERN_INFO "count      : %d\n"				\
	      KERN_INFO "offset     : %d\n"				\
	      KERN_INFO "spans      : %d\n"				\
	      KERN_INFO "uncmpr     : 0x%04x\n"				\
	      KERN_INFO "foffs      : " LL_X,				\
	      (info)->cmpr_pos, (info)->cmpr_sz, (info)->first_block,	\
	      (info)->count, (info)->offset, (info)->spans == 1,	\
	      (info)->uncmpr, LL((info)->foffs))

/*   dispatch compression segment info, return error code
 *  
 *   afterwards, cseg->offset points to start of data of the NEXT
 *   compressed block, and cseg->count contains the amount of data
 *   left in the actual compressed block. cseg->spans is set to 1 if
 *   the block is continued in the following segment. Otherwise it is
 *   set to 0. 
 */
static int get_cseg (cmpr_info *cinfo, const __u8 *buff, 
		     const unsigned int seg_sz,
		     const zft_volinfo *volume)
{
	TRACE_FUN(ft_t_flow);

 	cinfo->first_block = GET2(buff, 0);
	if (cinfo->first_block == 0) { /* data spans to next segment */
		cinfo->count  = seg_sz - sizeof(__u16);
		cinfo->offset = seg_sz;
		cinfo->spans = 1;
	} else { /* cluster definetely ends in this segment */
		if (cinfo->first_block > seg_sz) {
			/* data corrupted */
			TRACE_ABORT(-EIO, ft_t_err, "corrupted data:\n"
				    KERN_INFO "segment size: %d\n"
				    KERN_INFO "first block : %d",
				    seg_sz, cinfo->first_block);
		}
	        cinfo->count  = cinfo->first_block - sizeof(__u16);
		cinfo->offset = cinfo->first_block;
		cinfo->spans = 0;
	}
	/* now get the offset the first block should have in the
	 * uncompressed data stream.
	 *
	 * For this magic `18' refer to CRF-3 standard or QIC-80MC,
	 * Rev. K.  
	 */
	if ((seg_sz - cinfo->offset) > 18) {
		if (volume->qic113) { /* > revision K */
			TRACE(ft_t_data_flow, "New QIC-113 compliance");
			cinfo->foffs = GET8(buff, cinfo->offset);
			cinfo->offset += sizeof(__s64); 
		} else {
			TRACE(/* ft_t_data_flow */ ft_t_noise, "pre QIC-113 version");
			cinfo->foffs   = (__s64)GET4(buff, cinfo->offset);
			cinfo->offset += sizeof(__u32); 
		}
	}
	if (cinfo->foffs > volume->size) {
		TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n"
			    KERN_INFO "offset in current volume: %d\n"
			    KERN_INFO "size of current volume  : %d",
			    (int)(cinfo->foffs>>10), (int)(volume->size>>10));
	}
	if (cinfo->cmpr_pos + cinfo->count > volume->blk_sz) {
		TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n"
			    KERN_INFO "block size : %d\n"
			    KERN_INFO "data record: %d",
			    volume->blk_sz, cinfo->cmpr_pos + cinfo->count);
	}
	DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", cinfo);
	TRACE_EXIT 0;
}

/*  This one is called, when a new cluster starts in same segment.
 *  
 *  Note: if this is the first cluster in the current segment, we must
 *  not check whether there are more than 18 bytes available because
 *  this have already been done in get_cseg() and there may be less
 *  than 18 bytes available due to header information.
 * 
 */
static void get_next_cluster(cmpr_info *cluster, const __u8 *buff, 
			     const int seg_sz, const int finish)
{
	TRACE_FUN(ft_t_flow);

	if (seg_sz - cluster->offset > 18 || cluster->foffs != 0) {
		cluster->count   = GET2(buff, cluster->offset);
		cluster->uncmpr  = cluster->count & 0x8000;
		cluster->count  -= cluster->uncmpr;
		cluster->offset += sizeof(__u16);
		cluster->foffs   = 0;
		if ((cluster->offset + cluster->count) < seg_sz) {
			cluster->spans = 0;
		} else if (cluster->offset + cluster->count == seg_sz) {
			cluster->spans = !finish;
		} else {
			/* either an error or a volume written by an 
			 * old version. If this is a data error, then we'll
			 * catch it later.
			 */
			TRACE(ft_t_data_flow, "Either error or old volume");
			cluster->spans = 1;
			cluster->count = seg_sz - cluster->offset;
		}
	} else {
		cluster->count = 0;
		cluster->spans = 0;
		cluster->foffs = 0;
	}
	DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */ , "", cluster);
	TRACE_EXIT;
}

static void zftc_lock(void)
{
}

/*  this function is needed for zftape_reset_position in zftape-io.c 
 */
static void zftc_reset(void)
{
	TRACE_FUN(ft_t_flow);

	memset((void *)&cseg, '\0', sizeof(cseg));
	zftc_stats();
	TRACE_EXIT;
}

static int cmpr_mem_initialized = 0;
static unsigned int alloc_blksz = 0;

static int zft_allocate_cmpr_mem(unsigned int blksz)
{
	TRACE_FUN(ft_t_flow);

	if (cmpr_mem_initialized && blksz == alloc_blksz) {
		TRACE_EXIT 0;
	}
	TRACE_CATCH(zft_vmalloc_once(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE),
		    zftc_cleanup());
	TRACE_CATCH(zft_vmalloc_always(&zftc_buf, blksz + CMPR_OVERRUN),
		    zftc_cleanup());
	alloc_blksz = blksz;
	TRACE_CATCH(zft_vmalloc_always(&zftc_scratch_buf, blksz+CMPR_OVERRUN),
		    zftc_cleanup());
	cmpr_mem_initialized = 1;
	TRACE_EXIT 0;
}

static void zftc_cleanup(void)
{
	TRACE_FUN(ft_t_flow);

	zft_vfree(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE);
	zft_vfree(&zftc_buf, alloc_blksz + CMPR_OVERRUN);
	zft_vfree(&zftc_scratch_buf, alloc_blksz + CMPR_OVERRUN);
	cmpr_mem_initialized = alloc_blksz = 0;
	TRACE_EXIT;
}

/*****************************************************************************
 *                                                                           *
 *  The following two functions "ftape_compress()" and                       *
 *  "ftape_uncompress()" are the interface to the actual compression         *
 *  algorithm (i.e. they are calling the "compress()" function from          *
 *  the lzrw3 package for now). These routines could quite easily be         *
 *  changed to adopt another compression algorithm instead of lzrw3,         *
 *  which currently is used.                                                 *
 *                                                                           *
 *****************************************************************************/

/* called by zft_compress_write() to perform the compression. Must
 * return the size of the compressed data.
 *
 * NOTE: The size of the compressed data should not exceed the size of
 *       the uncompressed data. Most compression algorithms have means
 *       to store data unchanged if the "compressed" data amount would
 *       exceed the original one. Mostly this is done by storing some
 *       flag-bytes in front of the compressed data to indicate if it
 *       is compressed or not. Thus the worst compression result
 *       length is the original length plus those flag-bytes.
 *
 *       We don't want that, as the QIC-80 standard provides a means
 *       of marking uncompressed blocks by simply setting bit 15 of
 *       the compressed block's length. Thus a compessed block can
 *       have at most a length of 2^15-1 bytes. The QIC-80 standard
 *       restricts the block-length even further, allowing only 29k -
 *       6 bytes.
 *
 *       Currently, the maximum blocksize used by zftape is 28k.
 *
 *       In short: don't exceed the length of the input-package, set
 *       bit 15 of the compressed size to 1 if you have copied data
 *       instead of compressing it.
 */
static int zft_compress(__u8 *in_buffer, unsigned int in_sz, __u8 *out_buffer)
{ 
	__s32 compressed_sz;
	TRACE_FUN(ft_t_flow);
	

	lzrw3_compress(COMPRESS_ACTION_COMPRESS, zftc_wrk_mem,
		       in_buffer, in_sz, out_buffer, &compressed_sz);
	if (TRACE_LEVEL >= ft_t_info) {
		/*  the compiler will optimize this away when
		 *  compiled with NO_TRACE_AT_ALL option
		 */
		TRACE(ft_t_data_flow, "\n"
		      KERN_INFO "before compression: %d bytes\n"
		      KERN_INFO "after compresison : %d bytes", 
		      in_sz, 
		      (int)(compressed_sz < 0 
		      ? -compressed_sz : compressed_sz));
		/*  for statistical purposes
		 */
		zftc_wr_compressed   += (compressed_sz < 0 
					   ? -compressed_sz : compressed_sz);
		zftc_wr_uncompressed += in_sz;
	}
	TRACE_EXIT (int)compressed_sz;
}

/* called by zft_compress_read() to decompress the data. Must
 * return the size of the decompressed data for sanity checks
 * (compared with zft_blk_sz)
 *
 * NOTE: Read the note for zft_compress() above!  If bit 15 of the
 *       parameter in_sz is set, then the data in in_buffer isn't
 *       compressed, which must be handled by the un-compression
 *       algorithm. (I changed lzrw3 to handle this.)
 *
 *  The parameter max_out_sz is needed to prevent buffer overruns when 
 *  uncompressing corrupt data.
 */
static unsigned int zft_uncompress(__u8 *in_buffer, 
				   int in_sz, 
				   __u8 *out_buffer,
				   unsigned int max_out_sz)
{ 
	TRACE_FUN(ft_t_flow);
	
	lzrw3_compress(COMPRESS_ACTION_DECOMPRESS, zftc_wrk_mem,
		       in_buffer, (__s32)in_sz,
		       out_buffer, (__u32 *)&max_out_sz);
	
	if (TRACE_LEVEL >= ft_t_info) {
		TRACE(ft_t_data_flow, "\n"
		      KERN_INFO "before decompression: %d bytes\n"
		      KERN_INFO "after decompression : %d bytes", 
		      in_sz < 0 ? -in_sz : in_sz,(int)max_out_sz);
		/*  for statistical purposes
		 */
		zftc_rd_compressed   += in_sz < 0 ? -in_sz : in_sz;
		zftc_rd_uncompressed += max_out_sz;
	}
	TRACE_EXIT (unsigned int)max_out_sz;
}

/* print some statistics about the efficiency of the compression to
 * the kernel log 
 */
static void zftc_stats(void)
{
	TRACE_FUN(ft_t_flow);

	if (TRACE_LEVEL < ft_t_info) {
		TRACE_EXIT;
	}
	if (zftc_wr_uncompressed != 0) {
		if (zftc_wr_compressed > (1<<14)) {
			TRACE(ft_t_info, "compression statistics (writing):\n"
			      KERN_INFO " compr./uncmpr.   : %3d %%",
			      (((zftc_wr_compressed>>10) * 100)
			       / (zftc_wr_uncompressed>>10)));
		} else {
			TRACE(ft_t_info, "compression statistics (writing):\n"
			      KERN_INFO " compr./uncmpr.   : %3d %%",
			      ((zftc_wr_compressed * 100)
			       / zftc_wr_uncompressed));
		}
	}
	if (zftc_rd_uncompressed != 0) {
		if (zftc_rd_compressed > (1<<14)) {
			TRACE(ft_t_info, "compression statistics (reading):\n"
			      KERN_INFO " compr./uncmpr.   : %3d %%",
			      (((zftc_rd_compressed>>10) * 100)
			       / (zftc_rd_uncompressed>>10)));
		} else {
			TRACE(ft_t_info, "compression statistics (reading):\n"
			      KERN_INFO " compr./uncmpr.   : %3d %%",
			      ((zftc_rd_compressed * 100)
			       / zftc_rd_uncompressed));
		}
	}
	/* only print it once: */
	zftc_wr_uncompressed = 
		zftc_wr_compressed  =
		zftc_rd_uncompressed =
		zftc_rd_compressed   = 0;
	TRACE_EXIT;
}

/* start new compressed block 
 */
static int start_new_cseg(cmpr_info *cluster, 
			  char *dst_buf, 
			  const zft_position *pos,
			  const unsigned int blk_sz,
			  const char *src_buf,
			  const int this_segs_sz,
			  const int qic113)
{
	int size_left;
	int cp_cnt;
	int buf_pos;
	TRACE_FUN(ft_t_flow);

	size_left = this_segs_sz - sizeof(__u16) - cluster->cmpr_sz;
	TRACE(ft_t_data_flow,"\n" 
	      KERN_INFO "segment size   : %d\n"
	      KERN_INFO "compressed_sz: %d\n"
	      KERN_INFO "size_left      : %d",
	      this_segs_sz, cluster->cmpr_sz, size_left);
	if (size_left > 18) { /* start a new cluseter */
		cp_cnt = cluster->cmpr_sz;
		cluster->cmpr_sz = 0;
		buf_pos = cp_cnt + sizeof(__u16);
		PUT2(dst_buf, 0, buf_pos);

		if (qic113) {
			__s64 foffs = pos->volume_pos;
			if (cp_cnt) foffs += (__s64)blk_sz;

			TRACE(ft_t_data_flow, "new style QIC-113 header");
			PUT8(dst_buf, buf_pos, foffs);
			buf_pos += sizeof(__s64);
		} else {
			__u32 foffs = (__u32)pos->volume_pos;
			if (cp_cnt) foffs += (__u32)blk_sz;
			
			TRACE(ft_t_data_flow, "old style QIC-80MC header");
			PUT4(dst_buf, buf_pos, foffs);
			buf_pos += sizeof(__u32);
		}
	} else if (size_left >= 0) {
		cp_cnt = cluster->cmpr_sz;
		cluster->cmpr_sz = 0;
		buf_pos = cp_cnt + sizeof(__u16);
		PUT2(dst_buf, 0, buf_pos);  
		/* zero unused part of segment. */
		memset(dst_buf + buf_pos, '\0', size_left);
		buf_pos = this_segs_sz;
	} else { /* need entire segment and more space */
		PUT2(dst_buf, 0, 0); 
		cp_cnt = this_segs_sz - sizeof(__u16);
		cluster->cmpr_sz  -= cp_cnt;
		buf_pos = this_segs_sz;
	}
	memcpy(dst_buf + sizeof(__u16), src_buf + cluster->cmpr_pos, cp_cnt);
	cluster->cmpr_pos += cp_cnt;
	TRACE_EXIT buf_pos;
}

/* return-value: the number of bytes removed from the user-buffer
 *               `src_buf' or error code
 *
 *  int *write_cnt           : how much actually has been moved to the
 *                             dst_buf. Need not be initialized when
 *                             function returns with an error code
 *                             (negativ return value) 
 *  __u8 *dst_buf            : kernel space buffer where the has to be
 *                             copied to. The contents of this buffers
 *                             goes to a specific segment.
 *  const int seg_sz         : the size of the segment dst_buf will be
 *                             copied to.
 *  const zft_position *pos  : struct containing the coordinates in
 *                             the current volume (byte position,
 *                             segment id of current segment etc)
 *  const zft_volinfo *volume: information about the current volume,
 *                             size etc.
 *  const __u8 *src_buf      : user space buffer that contains the
 *                             data the user wants to be written to
 *                             tape.
 *  const int req_len        : the amount of data the user wants to be
 *                             written to tape.
 */
static int zftc_write(int *write_cnt,
		      __u8 *dst_buf, const int seg_sz,
		      const __u8 __user *src_buf, const int req_len,
		      const zft_position *pos, const zft_volinfo *volume)
{
	int req_len_left = req_len;
	int result;
	int len_left;
	int buf_pos_write = pos->seg_byte_pos;
	TRACE_FUN(ft_t_flow);
	
	/* Note: we do not unlock the module because
	 * there are some values cached in that `cseg' variable.  We
	 * don't don't want to use this information when being
	 * unloaded by kerneld even when the tape is full or when we
	 * cannot allocate enough memory.
	 */
	if (pos->tape_pos > (volume->size-volume->blk_sz-ZFT_CMPR_OVERHEAD)) {
		TRACE_EXIT -ENOSPC;
	}    
	if (zft_allocate_cmpr_mem(volume->blk_sz) < 0) {
		/* should we unlock the module? But it shouldn't 
		 * be locked anyway ...
		 */
		TRACE_EXIT -ENOMEM;
	}
	if (buf_pos_write == 0) { /* fill a new segment */
		*write_cnt = buf_pos_write = start_new_cseg(&cseg,
							    dst_buf,
							    pos,
							    volume->blk_sz,
							    zftc_buf, 
							    seg_sz,
							    volume->qic113);
		if (cseg.cmpr_sz == 0 && cseg.cmpr_pos != 0) {
			req_len_left -= result = volume->blk_sz;
			cseg.cmpr_pos  = 0;
		} else {
			result = 0;
		}
	} else {
		*write_cnt = result = 0;
	}
	
	len_left = seg_sz - buf_pos_write;
	while ((req_len_left > 0) && (len_left > 18)) {
		/* now we have some size left for a new compressed
		 * block.  We know, that the compression buffer is
		 * empty (else there wouldn't be any space left).  
		 */
		if (copy_from_user(zftc_scratch_buf, src_buf + result, 
				   volume->blk_sz) != 0) {
			TRACE_EXIT -EFAULT;
		}
		req_len_left -= volume->blk_sz;
		cseg.cmpr_sz = zft_compress(zftc_scratch_buf, volume->blk_sz, 
					    zftc_buf);
		if (cseg.cmpr_sz < 0) {
			cseg.uncmpr = 0x8000;
			cseg.cmpr_sz = -cseg.cmpr_sz;
		} else {
			cseg.uncmpr = 0;
		}
		/* increment "result" iff we copied the entire
		 * compressed block to the zft_deblock_buf 
		 */
		len_left -= sizeof(__u16);
		if (len_left >= cseg.cmpr_sz) {
			len_left -= cseg.count = cseg.cmpr_sz;
			cseg.cmpr_pos = cseg.cmpr_sz = 0;
			result += volume->blk_sz;
		} else {
			cseg.cmpr_sz       -= 
				cseg.cmpr_pos =
				cseg.count    = len_left;
			len_left = 0;
		}
		PUT2(dst_buf, buf_pos_write, cseg.uncmpr | cseg.count);
		buf_pos_write += sizeof(__u16);
		memcpy(dst_buf + buf_pos_write, zftc_buf, cseg.count);
		buf_pos_write += cseg.count;
		*write_cnt    += cseg.count + sizeof(__u16);
		FT_SIGNAL_EXIT(_DONT_BLOCK);
	}
	/* erase the remainder of the segment if less than 18 bytes
	 * left (18 bytes is due to the QIC-80 standard) 
	 */
	if (len_left <= 18) {
		memset(dst_buf + buf_pos_write, '\0', len_left);
		(*write_cnt) += len_left;
	}
	TRACE(ft_t_data_flow, "returning %d", result);
	TRACE_EXIT result;
}   

/* out:
 *
 * int *read_cnt: the number of bytes we removed from the zft_deblock_buf
 *                (result)
 * int *to_do   : the remaining size of the read-request.
 *
 * in:
 *
 * char *buff          : buff is the address of the upper part of the user
 *                       buffer, that hasn't been filled with data yet.

 * int buf_pos_read    : copy of from _ftape_read()
 * int buf_len_read    : copy of buf_len_rd from _ftape_read()
 * char *zft_deblock_buf: zft_deblock_buf
 * unsigned short blk_sz: the block size valid for this volume, may differ
 *                            from zft_blk_sz.
 * int finish: if != 0 means that this is the last segment belonging
 *  to this volume
 * returns the amount of data actually copied to the user-buffer
 *
 * to_do MUST NOT SHRINK except to indicate an EOF. In this case *to_do has to
 * be set to 0 
 */
static int zftc_read (int *read_cnt, 
		      __u8  __user *dst_buf, const int to_do, 
		      const __u8 *src_buf, const int seg_sz, 
		      const zft_position *pos, const zft_volinfo *volume)
{          
	int uncompressed_sz;         
	int result = 0;
	int remaining = to_do;
	TRACE_FUN(ft_t_flow);

	TRACE_CATCH(zft_allocate_cmpr_mem(volume->blk_sz),);
	if (pos->seg_byte_pos == 0) {
		/* new segment just read
		 */
		TRACE_CATCH(get_cseg(&cseg, src_buf, seg_sz, volume),
			    *read_cnt = 0);
		memcpy(zftc_buf + cseg.cmpr_pos, src_buf + sizeof(__u16), 
		       cseg.count);
		cseg.cmpr_pos += cseg.count;
		*read_cnt      = cseg.offset;
		DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", &cseg);
	} else {
		*read_cnt = 0;
	}
	/* loop and uncompress until user buffer full or
	 * deblock-buffer empty 
	 */
	TRACE(ft_t_data_flow, "compressed_sz: %d, compos : %d, *read_cnt: %d",
	      cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt);
	while ((cseg.spans == 0) && (remaining > 0)) {
		if (cseg.cmpr_pos  != 0) { /* cmpr buf is not empty */
			uncompressed_sz = 
				zft_uncompress(zftc_buf,
					       cseg.uncmpr == 0x8000 ?
					       -cseg.cmpr_pos : cseg.cmpr_pos,
					       zftc_scratch_buf,
					       volume->blk_sz);
			if (uncompressed_sz != volume->blk_sz) {
				*read_cnt = 0;
				TRACE_ABORT(-EIO, ft_t_warn,
				      "Uncompressed blk (%d) != blk size (%d)",
				      uncompressed_sz, volume->blk_sz);
			}       
			if (copy_to_user(dst_buf + result, 
					 zftc_scratch_buf, 
					 uncompressed_sz) != 0 ) {
				TRACE_EXIT -EFAULT;
			}
			remaining      -= uncompressed_sz;
			result     += uncompressed_sz;
			cseg.cmpr_pos  = 0;
		}                                              
		if (remaining > 0) {
			get_next_cluster(&cseg, src_buf, seg_sz, 
					 volume->end_seg == pos->seg_pos);
			if (cseg.count != 0) {
				memcpy(zftc_buf, src_buf + cseg.offset,
				       cseg.count);
				cseg.cmpr_pos = cseg.count;
				cseg.offset  += cseg.count;
				*read_cnt += cseg.count + sizeof(__u16);
			} else {
				remaining = 0;
			}
		}
		TRACE(ft_t_data_flow, "\n" 
		      KERN_INFO "compressed_sz: %d\n"
		      KERN_INFO "compos       : %d\n"
		      KERN_INFO "*read_cnt    : %d",
		      cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt);
	}
	if (seg_sz - cseg.offset <= 18) {
		*read_cnt += seg_sz - cseg.offset;
		TRACE(ft_t_data_flow, "expanding read cnt to: %d", *read_cnt);
	}
	TRACE(ft_t_data_flow, "\n"
	      KERN_INFO "segment size   : %d\n"
	      KERN_INFO "read count     : %d\n"
	      KERN_INFO "buf_pos_read   : %d\n"
	      KERN_INFO "remaining      : %d",
		seg_sz, *read_cnt, pos->seg_byte_pos, 
		seg_sz - *read_cnt - pos->seg_byte_pos);
	TRACE(ft_t_data_flow, "returning: %d", result);
	TRACE_EXIT result;
}                

/* seeks to the new data-position. Reads sometimes a segment.
 *  
 * start_seg and end_seg give the boundaries of the current volume
 * blk_sz is the blk_sz of the current volume as stored in the
 * volume label
 *
 * We don't allow blocksizes less than 1024 bytes, therefore we don't need
 * a 64 bit argument for new_block_pos.
 */

static int seek_in_segment(const unsigned int to_do, cmpr_info  *c_info,
			   const char *src_buf, const int seg_sz, 
			   const int seg_pos, const zft_volinfo *volume);
static int slow_seek_forward_until_error(const unsigned int distance,
					 cmpr_info *c_info, zft_position *pos, 
					 const zft_volinfo *volume, __u8 *buf);
static int search_valid_segment(unsigned int segment,
				const unsigned int end_seg,
				const unsigned int max_foffs,
				zft_position *pos, cmpr_info *c_info,
				const zft_volinfo *volume, __u8 *buf);
static int slow_seek_forward(unsigned int dest, cmpr_info *c_info,
			     zft_position *pos, const zft_volinfo *volume,
			     __u8 *buf);
static int compute_seg_pos(unsigned int dest, zft_position *pos,
			   const zft_volinfo *volume);

#define ZFT_SLOW_SEEK_THRESHOLD  10 /* segments */
#define ZFT_FAST_SEEK_MAX_TRIALS 10 /* times */
#define ZFT_FAST_SEEK_BACKUP     10 /* segments */

static int zftc_seek(unsigned int new_block_pos,
		     zft_position *pos, const zft_volinfo *volume, __u8 *buf)
{
	unsigned int dest;
	int limit;
	int distance;
	int result = 0;
	int seg_dist;
	int new_seg;
	int old_seg = 0;
	int fast_seek_trials = 0;
	TRACE_FUN(ft_t_flow);

	if (new_block_pos == 0) {
		pos->seg_pos      = volume->start_seg;
		pos->seg_byte_pos = 0;
		pos->volume_pos   = 0;
		zftc_reset();
		TRACE_EXIT 0;
	}
	dest = new_block_pos * (volume->blk_sz >> 10);
	distance = dest - (pos->volume_pos >> 10);
	while (distance != 0) {
		seg_dist = compute_seg_pos(dest, pos, volume);
		TRACE(ft_t_noise, "\n"
		      KERN_INFO "seg_dist: %d\n"
		      KERN_INFO "distance: %d\n"
		      KERN_INFO "dest    : %d\n"
		      KERN_INFO "vpos    : %d\n"
		      KERN_INFO "seg_pos : %d\n"
		      KERN_INFO "trials  : %d",
		      seg_dist, distance, dest,
		      (unsigned int)(pos->volume_pos>>10), pos->seg_pos,
		      fast_seek_trials);
		if (distance > 0) {
			if (seg_dist < 0) {
				TRACE(ft_t_bug, "BUG: distance %d > 0, "
				      "segment difference %d < 0",
				      distance, seg_dist);
				result = -EIO;
				break;
			}
			new_seg = pos->seg_pos + seg_dist;
			if (new_seg > volume->end_seg) {
				new_seg = volume->end_seg;
			}
			if (old_seg == new_seg || /* loop */
			    seg_dist <= ZFT_SLOW_SEEK_THRESHOLD ||
			    fast_seek_trials >= ZFT_FAST_SEEK_MAX_TRIALS) {
				TRACE(ft_t_noise, "starting slow seek:\n"
				   KERN_INFO "fast seek failed too often: %s\n"
				   KERN_INFO "near target position      : %s\n"
				   KERN_INFO "looping between two segs  : %s",
				      (fast_seek_trials >= 
				       ZFT_FAST_SEEK_MAX_TRIALS)
				      ? "yes" : "no",
				      (seg_dist <= ZFT_SLOW_SEEK_THRESHOLD) 
				      ? "yes" : "no",
				      (old_seg == new_seg)
				      ? "yes" : "no");
				result = slow_seek_forward(dest, &cseg, 
							   pos, volume, buf);
				break;
			}
			old_seg = new_seg;
			limit = volume->end_seg;
			fast_seek_trials ++;
			for (;;) {
				result = search_valid_segment(new_seg, limit,
							      volume->size,
							      pos, &cseg,
							      volume, buf);
				if (result == 0 || result == -EINTR) {
					break;
				}
				if (new_seg == volume->start_seg) {
					result = -EIO; /* set errror 
							* condition
							*/
					break;
				}
				limit    = new_seg;
				new_seg -= ZFT_FAST_SEEK_BACKUP;
				if (new_seg < volume->start_seg) {
					new_seg = volume->start_seg;
				}
			}
			if (result < 0) {
				TRACE(ft_t_warn,
				      "Couldn't find a readable segment");
				break;
			}
		} else /* if (distance < 0) */ {
			if (seg_dist > 0) {
				TRACE(ft_t_bug, "BUG: distance %d < 0, "
				      "segment difference %d >0",
				      distance, seg_dist);
				result = -EIO;
				break;
			}
			new_seg = pos->seg_pos + seg_dist;
			if (fast_seek_trials > 0 && seg_dist == 0) {
				/* this avoids sticking to the same
				 * segment all the time. On the other hand:
				 * if we got here for the first time, and the
				 * deblock_buffer still contains a valid
				 * segment, then there is no need to skip to 
				 * the previous segment if the desired position
				 * is inside this segment.
				 */
				new_seg --;
			}
			if (new_seg < volume->start_seg) {
				new_seg = volume->start_seg;
			}
			limit   = pos->seg_pos;
			fast_seek_trials ++;
			for (;;) {
				result = search_valid_segment(new_seg, limit,
							      pos->volume_pos,
							      pos, &cseg,
							      volume, buf);
				if (result == 0 || result == -EINTR) {
					break;
				}
				if (new_seg == volume->start_seg) {
					result = -EIO; /* set errror 
							* condition
							*/
					break;
				}
				limit    = new_seg;
				new_seg -= ZFT_FAST_SEEK_BACKUP;
				if (new_seg < volume->start_seg) {
					new_seg = volume->start_seg;
				}
			}
			if (result < 0) {
				TRACE(ft_t_warn,
				      "Couldn't find a readable segment");
				break;
			}
		}
		distance = dest - (pos->volume_pos >> 10);
	}
	TRACE_EXIT result;
}


/*  advance inside the given segment at most to_do bytes.
 *  of kilobytes moved
 */

static int seek_in_segment(const unsigned int to_do,
			   cmpr_info  *c_info,
			   const char *src_buf, 
			   const int seg_sz, 
			   const int seg_pos,
			   const zft_volinfo *volume)
{
	int result = 0;
	int blk_sz = volume->blk_sz >> 10;
	int remaining = to_do;
	TRACE_FUN(ft_t_flow);

	if (c_info->offset == 0) {
		/* new segment just read
		 */
		TRACE_CATCH(get_cseg(c_info, src_buf, seg_sz, volume),);
		c_info->cmpr_pos += c_info->count;
		DUMP_CMPR_INFO(ft_t_noise, "", c_info);
	}
	/* loop and uncompress until user buffer full or
	 * deblock-buffer empty 
	 */
	TRACE(ft_t_noise, "compressed_sz: %d, compos : %d",
	      c_info->cmpr_sz, c_info->cmpr_pos);
	while (c_info->spans == 0 && remaining > 0) {
		if (c_info->cmpr_pos  != 0) { /* cmpr buf is not empty */
			result       += blk_sz;
			remaining    -= blk_sz;
			c_info->cmpr_pos = 0;
		}
		if (remaining > 0) {
			get_next_cluster(c_info, src_buf, seg_sz, 
					 volume->end_seg == seg_pos);
			if (c_info->count != 0) {
				c_info->cmpr_pos = c_info->count;
				c_info->offset  += c_info->count;
			} else {
				break;
			}
		}
		/*  Allow escape from this loop on signal!
		 */
		FT_SIGNAL_EXIT(_DONT_BLOCK);
		DUMP_CMPR_INFO(ft_t_noise, "", c_info);
		TRACE(ft_t_noise, "to_do: %d", remaining);
	}
	if (seg_sz - c_info->offset <= 18) {
		c_info->offset = seg_sz;
	}
	TRACE(ft_t_noise, "\n"
	      KERN_INFO "segment size   : %d\n"
	      KERN_INFO "buf_pos_read   : %d\n"
	      KERN_INFO "remaining      : %d",
	      seg_sz, c_info->offset,
	      seg_sz - c_info->offset);
	TRACE_EXIT result;
}                

static int slow_seek_forward_until_error(const unsigned int distance,
					 cmpr_info *c_info,
					 zft_position *pos, 
					 const zft_volinfo *volume,
					 __u8 *buf)
{
	unsigned int remaining = distance;
	int seg_sz;
	int seg_pos;
	int result;
	TRACE_FUN(ft_t_flow);
	
	seg_pos = pos->seg_pos;
	do {
		TRACE_CATCH(seg_sz = zft_fetch_segment(seg_pos, buf, 
						       FT_RD_AHEAD),);
		/* now we have the contents of the actual segment in
		 * the deblock buffer
		 */
		TRACE_CATCH(result = seek_in_segment(remaining, c_info, buf,
						     seg_sz, seg_pos,volume),);
		remaining        -= result;
		pos->volume_pos  += result<<10;
		pos->seg_pos      = seg_pos;
		pos->seg_byte_pos = c_info->offset;
		seg_pos ++;
		if (seg_pos <= volume->end_seg && c_info->offset == seg_sz) {
			pos->seg_pos ++;
			pos->seg_byte_pos = 0;
			c_info->offset = 0;
		}
		/*  Allow escape from this loop on signal!
		 */
		FT_SIGNAL_EXIT(_DONT_BLOCK);
		TRACE(ft_t_noise, "\n"
		      KERN_INFO "remaining:  %d\n"
		      KERN_INFO "seg_pos:    %d\n"
		      KERN_INFO "end_seg:    %d\n"
		      KERN_INFO "result:     %d",
		      remaining, seg_pos, volume->end_seg, result);  
	} while (remaining > 0 && seg_pos <= volume->end_seg);
	TRACE_EXIT 0;
}

/* return segment id of next segment containing valid data, -EIO otherwise
 */
static int search_valid_segment(unsigned int segment,
				const unsigned int end_seg,
				const unsigned int max_foffs,
				zft_position *pos,
				cmpr_info *c_info,
				const zft_volinfo *volume,
				__u8 *buf)
{
	cmpr_info tmp_info;
	int seg_sz;
	TRACE_FUN(ft_t_flow);
	
	memset(&tmp_info, 0, sizeof(cmpr_info));
	while (segment <= end_seg) {
		FT_SIGNAL_EXIT(_DONT_BLOCK);
		TRACE(ft_t_noise,
		      "Searching readable segment between %d and %d",
		      segment, end_seg);
		seg_sz = zft_fetch_segment(segment, buf, FT_RD_AHEAD);
		if ((seg_sz > 0) &&
		    (get_cseg (&tmp_info, buf, seg_sz, volume) >= 0) &&
		    (tmp_info.foffs != 0 || segment == volume->start_seg)) {
			if ((tmp_info.foffs>>10) > max_foffs) {
				TRACE_ABORT(-EIO, ft_t_noise, "\n"
					    KERN_INFO "cseg.foff: %d\n"
					    KERN_INFO "dest     : %d",
					    (int)(tmp_info.foffs >> 10),
					    max_foffs);
			}
			DUMP_CMPR_INFO(ft_t_noise, "", &tmp_info);
			*c_info           = tmp_info;
			pos->seg_pos      = segment;
			pos->volume_pos   = c_info->foffs;
			pos->seg_byte_pos = c_info->offset;
			TRACE(ft_t_noise, "found segment at %d", segment);
			TRACE_EXIT 0;
		}
		segment++;
	}
	TRACE_EXIT -EIO;
}

static int slow_seek_forward(unsigned int dest,
			     cmpr_info *c_info,
			     zft_position *pos,
			     const zft_volinfo *volume,
			     __u8 *buf)
{
	unsigned int distance;
	int result = 0;
	TRACE_FUN(ft_t_flow);
		
	distance = dest - (pos->volume_pos >> 10);
	while ((distance > 0) &&
	       (result = slow_seek_forward_until_error(distance,
						       c_info,
						       pos,
						       volume,
						       buf)) < 0) {
		if (result == -EINTR) {
			break;
		}
		TRACE(ft_t_noise, "seg_pos: %d", pos->seg_pos);
		/* the failing segment is either pos->seg_pos or
		 * pos->seg_pos + 1. There is no need to further try
		 * that segment, because ftape_read_segment() already
		 * has tried very much to read it. So we start with
		 * following segment, which is pos->seg_pos + 1
		 */
		if(search_valid_segment(pos->seg_pos+1, volume->end_seg, dest,
					pos, c_info,
					volume, buf) < 0) {
			TRACE(ft_t_noise, "search_valid_segment() failed");
			result = -EIO;
			break;
		}
		distance = dest - (pos->volume_pos >> 10);
		result = 0;
		TRACE(ft_t_noise, "segment: %d", pos->seg_pos);
		/* found valid segment, retry the seek */
	}
	TRACE_EXIT result;
}

static int compute_seg_pos(const unsigned int dest,
			   zft_position *pos,
			   const zft_volinfo *volume)
{
	int segment;
	int distance = dest - (pos->volume_pos >> 10);
	unsigned int raw_size;
	unsigned int virt_size;
	unsigned int factor;
	TRACE_FUN(ft_t_flow);

	if (distance >= 0) {
		raw_size  = volume->end_seg - pos->seg_pos + 1;
		virt_size = ((unsigned int)(volume->size>>10) 
			     - (unsigned int)(pos->volume_pos>>10)
			     + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);
		virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;
		if (virt_size == 0 || raw_size == 0) {
			TRACE_EXIT 0;
		}
		if (raw_size >= (1<<25)) {
			factor = raw_size/(virt_size>>7);
		} else {
			factor = (raw_size<<7)/virt_size;
		}
		segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);
		segment = (segment * factor)>>7;
	} else {
		raw_size  = pos->seg_pos - volume->start_seg + 1;
		virt_size = ((unsigned int)(pos->volume_pos>>10)
			     + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);
		virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;
		if (virt_size == 0 || raw_size == 0) {
			TRACE_EXIT 0;
		}
		if (raw_size >= (1<<25)) {
			factor = raw_size/(virt_size>>7);
		} else {
			factor = (raw_size<<7)/virt_size;
		}
		segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);
	}
	TRACE(ft_t_noise, "factor: %d/%d", factor, 1<<7);
	TRACE_EXIT segment;
}

static struct zft_cmpr_ops cmpr_ops = {
	zftc_write,
	zftc_read,
	zftc_seek,
	zftc_lock,
	zftc_reset,
	zftc_cleanup
};

int zft_compressor_init(void)
{
	TRACE_FUN(ft_t_flow);
	
#ifdef MODULE
	printk(KERN_INFO "zftape compressor v1.00a 970514 for " FTAPE_VERSION "\n");
        if (TRACE_LEVEL >= ft_t_info) {
		printk(
KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
        }
#else /* !MODULE */
	/* print a short no-nonsense boot message */
	printk("zftape compressor v1.00a 970514\n");
	printk("For use with " FTAPE_VERSION "\n");
#endif /* MODULE */
	TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
	TRACE(ft_t_info, "installing compressor for zftape ...");
	TRACE_CATCH(zft_cmpr_register(&cmpr_ops),);
	TRACE_EXIT 0;
}

#ifdef MODULE

MODULE_AUTHOR(
	"(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de");
MODULE_DESCRIPTION(
"Compression routines for zftape. Uses the lzrw3 algorithm by Ross Williams");
MODULE_LICENSE("GPL");

/* Called by modules package when installing the driver
 */
int init_module(void)
{
	return zft_compressor_init();
}

#endif /* MODULE */
