File: /usr/src/linux/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/config.h>
28     #include <linux/errno.h>
29     #include <linux/mm.h>
30     #define __NO_VERSION__
31     #include <linux/module.h>
32     #include <linux/fcntl.h>
33     
34     #include <linux/zftape.h>
35     
36     #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,6)
37     #include <asm/uaccess.h>
38     #else
39     #include <asm/segment.h>
40     #endif
41     
42     #include "../zftape/zftape-init.h"
43     #include "../zftape/zftape-eof.h"
44     #include "../zftape/zftape-ctl.h"
45     #include "../zftape/zftape-write.h"
46     #include "../zftape/zftape-read.h"
47     #include "../zftape/zftape-rw.h"
48     #include "../zftape/zftape-vtbl.h"
49     
50     /*      Global vars.
51      */
52     int zft_write_protected; /* this is when cartridge rdonly or O_RDONLY */
53     int zft_header_read;
54     int zft_offline;
55     unsigned int zft_unit;
56     int zft_resid;
57     int zft_mt_compression;
58     
59     /*      Local vars.
60      */
61     static int going_offline;
62     
63     typedef int (mt_fun)(int *argptr);
64     typedef int (*mt_funp)(int *argptr);
65     typedef struct
66     {
67     	mt_funp function;
68     	unsigned offline         : 1; /* op permitted if offline or no_tape */
69     	unsigned write_protected : 1; /* op permitted if write-protected    */
70     	unsigned not_formatted   : 1; /* op permitted if tape not formatted */
71     	unsigned raw_mode        : 1; /* op permitted if zft_mode == 0    */
72     	unsigned need_idle_state : 1; /* need to call def_idle_state        */
73     	char     *name;
74     } fun_entry;
75     
76     static mt_fun mt_dummy, mt_reset, mt_fsr, mt_bsr, mt_rew, mt_offl, mt_nop,
77     	mt_weof, mt_erase, mt_ras2, mt_setblk, mt_setdensity,
78     	mt_seek, mt_tell, mt_reten, mt_eom, mt_fsf, mt_bsf,
79     	mt_fsfm, mt_bsfm, mt_setdrvbuffer, mt_compression;
80     
81     static fun_entry mt_funs[]=
82     { 
83     	{mt_reset       , 1, 1, 1, 1, 0, "MT_RESET" }, /*  0 */
84     	{mt_fsf         , 0, 1, 0, 0, 1, "MT_FSF"   },
85     	{mt_bsf         , 0, 1, 0, 0, 1, "MT_BSF"   },
86     	{mt_fsr         , 0, 1, 0, 1, 1, "MT_FSR"   },
87     	{mt_bsr         , 0, 1, 0, 1, 1, "MT_BSR"   },
88     	{mt_weof        , 0, 0, 0, 0, 0, "MT_WEOF"  }, /*  5 */
89     	{mt_rew         , 0, 1, 1, 1, 0, "MT_REW"   },
90     	{mt_offl        , 0, 1, 1, 1, 0, "MT_OFFL"  },
91     	{mt_nop         , 1, 1, 1, 1, 0, "MT_NOP"   },
92     	{mt_reten       , 0, 1, 1, 1, 0, "MT_RETEN" },
93     	{mt_bsfm        , 0, 1, 0, 0, 1, "MT_BSFM"  }, /* 10 */
94     	{mt_fsfm        , 0, 1, 0, 0, 1, "MT_FSFM"  },
95     	{mt_eom         , 0, 1, 0, 0, 1, "MT_EOM"   },
96     	{mt_erase       , 0, 0, 0, 1, 0, "MT_ERASE" },
97     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_RAS1"  },
98     	{mt_ras2        , 0, 0, 0, 1, 0, "MT_RAS2"  },
99     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_RAS3"  },
100     	{mt_dummy       , 1, 1, 1, 1, 0, "UNKNOWN"  },
101     	{mt_dummy       , 1, 1, 1, 1, 0, "UNKNOWN"  },
102     	{mt_dummy       , 1, 1, 1, 1, 0, "UNKNOWN"  },
103     	{mt_setblk      , 1, 1, 1, 1, 1, "MT_SETBLK"}, /* 20 */
104     	{mt_setdensity  , 1, 1, 1, 1, 0, "MT_SETDENSITY"},
105     	{mt_seek        , 0, 1, 0, 1, 1, "MT_SEEK"  },
106     	{mt_dummy       , 0, 1, 0, 1, 1, "MT_TELL"  }, /* wr-only ?! */
107     	{mt_setdrvbuffer, 1, 1, 1, 1, 0, "MT_SETDRVBUFFER" },
108     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_FSS"   }, /* 25 */
109     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_BSS"   },
110     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_WSM"   },
111     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_LOCK"  },
112     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_UNLOCK"},
113     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_LOAD"  }, /* 30 */
114     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_UNLOAD"},
115     	{mt_compression , 1, 1, 1, 0, 1, "MT_COMPRESSION"},
116     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_SETPART"},
117     	{mt_dummy       , 1, 1, 1, 1, 0, "MT_MKPART"}
118     };  
119     
120     #define NR_MT_CMDS NR_ITEMS(mt_funs)
121     
122     void zft_reset_position(zft_position *pos)
123     {
124     	TRACE_FUN(ft_t_flow);
125     
126     	pos->seg_byte_pos =
127     		pos->volume_pos = 0;
128     	if (zft_header_read) {
129     		/* need to keep track of the volume table and
130     		 * compression map. We therefor simply
131     		 * position at the beginning of the first
132     		 * volume. This covers old ftape archives as
133     		 * well has various flavours of the
134     		 * compression map segments. The worst case is
135     		 * that the compression map shows up as a
136     		 * additional volume in front of all others.
137     		 */
138     		pos->seg_pos  = zft_find_volume(0)->start_seg;
139     		pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
140     	} else {
141     		pos->tape_pos =  0;
142     		pos->seg_pos  = -1;
143     	}
144     	zft_just_before_eof =  0;
145     	zft_deblock_segment = -1;
146     	zft_io_state        = zft_idle;
147     	zft_zap_read_buffers();
148     	zft_prevent_flush();
149     	/*  unlock the compresison module if it is loaded.
150     	 *  The zero arg means not to try to load the module.
151     	 */
152     	if (zft_cmpr_lock(0) == 0) {
153     		(*zft_cmpr_ops->reset)(); /* unlock */
154     	}
155     	TRACE_EXIT;
156     }
157     
158     static void zft_init_driver(void)
159     {
160     	TRACE_FUN(ft_t_flow);
161     
162     	zft_resid =
163     		zft_header_read          =
164     		zft_old_ftape            =
165     		zft_offline              =
166     		zft_write_protected      =
167     		going_offline            =
168     		zft_mt_compression       =
169     		zft_header_changed       =
170     		zft_volume_table_changed =
171     		zft_written_segments     = 0;
172     	zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ;
173     	zft_reset_position(&zft_pos); /* does most of the stuff */
174     	ftape_zap_read_buffers();
175     	ftape_set_state(idle);
176     	TRACE_EXIT;
177     }
178     
179     int zft_def_idle_state(void)
180     { 
181     	int result = 0;
182     	TRACE_FUN(ft_t_flow);
183     	
184     	if (!zft_header_read) {
185     		result = zft_read_header_segments();
186     	} else if ((result = zft_flush_buffers()) >= 0 && zft_qic_mode) {
187     		/*  don't move past eof
188     		 */
189     		(void)zft_close_volume(&zft_pos);
190     	}
191     	if (ftape_abort_operation() < 0) {
192     		TRACE(ft_t_warn, "ftape_abort_operation() failed");
193     		result = -EIO;
194     	}
195     	/* clear remaining read buffers */
196     	zft_zap_read_buffers();
197     	zft_io_state = zft_idle;
198     	TRACE_EXIT result;
199     }
200     
201     /*****************************************************************************
202      *                                                                           *
203      *  functions for the MTIOCTOP commands                                      *
204      *                                                                           *
205      *****************************************************************************/
206     
207     static int mt_dummy(int *dummy)
208     {
209     	TRACE_FUN(ft_t_flow);
210     	
211     	TRACE_EXIT -ENOSYS;
212     }
213     
214     static int mt_reset(int *dummy)
215     {        
216     	TRACE_FUN(ft_t_flow);
217     	
218     	(void)ftape_seek_to_bot();
219     	TRACE_CATCH(ftape_reset_drive(),
220     		    zft_init_driver(); zft_uninit_mem(); zft_offline = 1);
221     	/*  fake a re-open of the device. This will set all flage and 
222     	 *  allocate buffers as appropriate. The new tape condition will
223     	 *  force the open routine to do anything we need.
224     	 */
225     	TRACE_CATCH(_zft_open(-1 /* fake reopen */, 0 /* dummy */),);
226     	TRACE_EXIT 0;
227     }
228     
229     static int mt_fsf(int *arg)
230     {
231     	int result;
232     	TRACE_FUN(ft_t_flow);
233     
234     	result = zft_skip_volumes(*arg, &zft_pos);
235     	zft_just_before_eof = 0;
236     	TRACE_EXIT result;
237     }
238     
239     static int mt_bsf(int *arg)
240     {
241     	int result = 0;
242     	TRACE_FUN(ft_t_flow);
243     	
244     	if (*arg != 0) {
245     		result = zft_skip_volumes(-*arg + 1, &zft_pos);
246     	}
247     	TRACE_EXIT result;
248     }
249     
250     static int seek_block(__s64 data_offset,
251     		      __s64 block_increment,
252     		      zft_position *pos)
253     { 
254     	int result      = 0;
255     	__s64 new_block_pos;
256     	__s64 vol_block_count;
257     	const zft_volinfo *volume;
258     	int exceed;
259     	TRACE_FUN(ft_t_flow);
260     	
261     	volume = zft_find_volume(pos->seg_pos);
262     	if (volume->start_seg == 0 || volume->end_seg == 0) {
263     		TRACE_EXIT -EIO;
264     	}
265     	new_block_pos   = (zft_div_blksz(data_offset, volume->blk_sz)
266     			   + block_increment);
267     	vol_block_count = zft_div_blksz(volume->size, volume->blk_sz);
268     	if (new_block_pos < 0) {
269     		TRACE(ft_t_noise,
270     		      "new_block_pos " LL_X " < 0", LL(new_block_pos));
271     		zft_resid     = (int)new_block_pos;
272     		new_block_pos = 0;
273     		exceed = 1;
274     	} else if (new_block_pos > vol_block_count) {
275     		TRACE(ft_t_noise,
276     		      "new_block_pos " LL_X " exceeds size of volume " LL_X,
277     		      LL(new_block_pos), LL(vol_block_count));
278     		zft_resid     = (int)(vol_block_count - new_block_pos);
279     		new_block_pos = vol_block_count;
280     		exceed = 1;
281     	} else {
282     		exceed = 0;
283     	}
284     	if (zft_use_compression && volume->use_compression) {
285     		TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
286     		result = (*zft_cmpr_ops->seek)(new_block_pos, pos, volume,
287     					       zft_deblock_buf);
288     		pos->tape_pos  = zft_calc_tape_pos(pos->seg_pos);
289     		pos->tape_pos += pos->seg_byte_pos;
290     	} else {
291     		pos->volume_pos = zft_mul_blksz(new_block_pos, volume->blk_sz);
292     		pos->tape_pos   = zft_calc_tape_pos(volume->start_seg);
293     		pos->tape_pos  += pos->volume_pos;
294     		pos->seg_pos    = zft_calc_seg_byte_coord(&pos->seg_byte_pos,
295     							  pos->tape_pos);
296     	}
297     	zft_just_before_eof = volume->size == pos->volume_pos;
298     	if (zft_just_before_eof) {
299     		/* why this? because zft_file_no checks agains start
300     		 * and end segment of a volume. We do not want to
301     		 * advance to the next volume with this function.
302     		 */
303     		TRACE(ft_t_noise, "set zft_just_before_eof");
304     		zft_position_before_eof(pos, volume);
305     	}
306     	TRACE(ft_t_noise, "\n"
307     	      KERN_INFO "new_seg_pos : %d\n"
308     	      KERN_INFO "new_tape_pos: " LL_X "\n"
309     	      KERN_INFO "vol_size    : " LL_X "\n"
310     	      KERN_INFO "seg_byte_pos: %d\n"
311     	      KERN_INFO "blk_sz  : %d", 
312     	      pos->seg_pos, LL(pos->tape_pos),
313     	      LL(volume->size), pos->seg_byte_pos,
314     	      volume->blk_sz);
315     	if (!exceed) {
316     		zft_resid = new_block_pos - zft_div_blksz(pos->volume_pos,
317     							  volume->blk_sz);
318     	}
319     	if (zft_resid < 0) {
320     		zft_resid = -zft_resid;
321     	}
322     	TRACE_EXIT ((exceed || zft_resid != 0) && result >= 0) ? -EINVAL : result;
323     }     
324     
325     static int mt_fsr(int *arg)
326     { 
327     	int result;
328     	TRACE_FUN(ft_t_flow);
329     	
330     	result = seek_block(zft_pos.volume_pos,  *arg, &zft_pos);
331     	TRACE_EXIT result;
332     }
333     
334     static int mt_bsr(int *arg)
335     {   
336     	int result;
337     	TRACE_FUN(ft_t_flow);
338     	
339     	result = seek_block(zft_pos.volume_pos, -*arg, &zft_pos);
340     	TRACE_EXIT result;
341     }
342     
343     static int mt_weof(int *arg)
344     {
345     	int result;
346     	TRACE_FUN(ft_t_flow);
347     	
348     	TRACE_CATCH(zft_flush_buffers(),);
349     	result = zft_weof(*arg, &zft_pos);
350     	TRACE_EXIT result;
351     }
352     
353     static int mt_rew(int *dummy)
354     {          
355     	int result;
356     	TRACE_FUN(ft_t_flow);
357     	
358     	if(zft_header_read) {
359     		(void)zft_def_idle_state();
360     	}
361     	result = ftape_seek_to_bot();
362     	zft_reset_position(&zft_pos);
363     	TRACE_EXIT result;
364     }
365     
366     static int mt_offl(int *dummy)
367     {
368     	int result;
369     	TRACE_FUN(ft_t_flow);
370     	
371     	going_offline= 1;
372     	result = mt_rew(NULL);
373     	TRACE_EXIT result;
374     }
375     
376     static int mt_nop(int *dummy)
377     {
378     	TRACE_FUN(ft_t_flow);
379     	/*  should we set tape status?
380     	 */
381     	if (!zft_offline) { /* offline includes no_tape */
382     		(void)zft_def_idle_state();
383     	}
384     	TRACE_EXIT 0; 
385     }
386     
387     static int mt_reten(int *dummy)
388     {  
389     	int result;
390     	TRACE_FUN(ft_t_flow);
391     	
392     	if(zft_header_read) {
393     		(void)zft_def_idle_state();
394     	}
395     	result = ftape_seek_to_eot();
396     	if (result >= 0) {
397     		result = ftape_seek_to_bot();
398     	}
399     	TRACE_EXIT(result);
400     }
401     
402     static int fsfbsfm(int arg, zft_position *pos)
403     { 
404     	const zft_volinfo *vtbl;
405     	__s64 block_pos;
406     	TRACE_FUN(ft_t_flow);
407     	
408     	/* What to do? This should seek to the next file-mark and
409     	 * position BEFORE. That is, a next write would just extend
410     	 * the current file.  Well. Let's just seek to the end of the
411     	 * current file, if count == 1.  If count > 1, then do a
412     	 * "mt_fsf(count - 1)", and then seek to the end of that file.
413     	 * If count == 0, do nothing
414     	 */
415     	if (arg == 0) {
416     		TRACE_EXIT 0;
417     	}
418     	zft_just_before_eof = 0;
419     	TRACE_CATCH(zft_skip_volumes(arg < 0 ? arg : arg-1, pos),
420     		    if (arg > 0) {
421     			    zft_resid ++; 
422     		    });
423     	vtbl      = zft_find_volume(pos->seg_pos);
424     	block_pos = zft_div_blksz(vtbl->size, vtbl->blk_sz);
425     	(void)seek_block(0, block_pos, pos);
426     	if (pos->volume_pos != vtbl->size) {
427     		zft_just_before_eof = 0;
428     		zft_resid = 1;
429     		/* we didn't managed to go there */
430     		TRACE_ABORT(-EIO, ft_t_err, 
431     			    "wanted file position " LL_X ", arrived at " LL_X, 
432     			    LL(vtbl->size), LL(pos->volume_pos));
433     	}
434     	zft_just_before_eof = 1;
435     	TRACE_EXIT 0; 
436     }
437     
438     static int mt_bsfm(int *arg)
439     {
440     	int result;
441     	TRACE_FUN(ft_t_flow);
442     	
443     	result = fsfbsfm(-*arg, &zft_pos);
444     	TRACE_EXIT result;
445     }
446     
447     static int mt_fsfm(int *arg)
448     {
449     	int result;
450     	TRACE_FUN(ft_t_flow);
451     	
452     	result = fsfbsfm(*arg, &zft_pos);
453     	TRACE_EXIT result;
454     }
455     
456     static int mt_eom(int *dummy)
457     {              
458     	TRACE_FUN(ft_t_flow);
459     	
460     	zft_skip_to_eom(&zft_pos);
461     	TRACE_EXIT 0;
462     }
463     
464     static int mt_erase(int *dummy)
465     {
466     	int result;
467     	TRACE_FUN(ft_t_flow);
468     	
469     	result = zft_erase();
470     	TRACE_EXIT result;
471     }
472     
473     static int mt_ras2(int *dummy)
474     {
475     	int result;
476     	TRACE_FUN(ft_t_flow);
477     	
478     	result = -ENOSYS;
479     	TRACE_EXIT result;
480     } 
481     
482     /*  Sets the new blocksize in BYTES
483      *
484      */
485     static int mt_setblk(int *new_size)
486     {
487     	TRACE_FUN(ft_t_flow);
488     	
489     	if((unsigned int)(*new_size) > ZFT_MAX_BLK_SZ) {
490     		TRACE_ABORT(-EINVAL, ft_t_info,
491     			    "desired blk_sz (%d) should be <= %d bytes",
492     			    *new_size, ZFT_MAX_BLK_SZ);
493     	}
494     	if ((*new_size & (FT_SECTOR_SIZE-1)) != 0) {
495     		TRACE_ABORT(-EINVAL, ft_t_info,
496     			"desired blk_sz (%d) must be a multiple of %d bytes",
497     			    *new_size, FT_SECTOR_SIZE);
498     	}
499     	if (*new_size == 0) {
500     		if (zft_use_compression) {
501     			TRACE_ABORT(-EINVAL, ft_t_info,
502     				    "Variable block size not yet "
503     				    "supported with compression");
504     		}
505     		*new_size = 1;
506     	}
507     	zft_blk_sz = *new_size;
508     	TRACE_EXIT 0;
509     } 
510     
511     static int mt_setdensity(int *arg)
512     {
513     	TRACE_FUN(ft_t_flow);
514     	
515     	SET_TRACE_LEVEL(*arg);
516     	TRACE(TRACE_LEVEL, "tracing set to %d", TRACE_LEVEL);
517     	if ((int)TRACE_LEVEL != *arg) {
518     		TRACE_EXIT -EINVAL;
519     	}
520     	TRACE_EXIT 0;
521     }          
522     
523     static int mt_seek(int *new_block_pos)
524     { 
525     	int result= 0;        
526     	TRACE_FUN(ft_t_any);
527     	
528     	result = seek_block(0, (__s64)*new_block_pos, &zft_pos);
529     	TRACE_EXIT result;
530     }
531     
532     /*  OK, this is totally different from SCSI, but the worst thing that can 
533      *  happen is that there is not enough defragmentated memory that can be 
534      *  allocated. Also, there is a hardwired limit of 16 dma buffers in the 
535      *  stock ftape module. This shouldn't bring the system down.
536      *
537      * NOTE: the argument specifies the total number of dma buffers to use.
538      *       The driver needs at least 3 buffers to function at all.
539      * 
540      */
541     static int mt_setdrvbuffer(int *cnt)
542     {
543     	TRACE_FUN(ft_t_flow);
544     
545     	if (*cnt < 3) {
546     		TRACE_EXIT -EINVAL;
547     	}
548     	TRACE_CATCH(ftape_set_nr_buffers(*cnt),);
549     	TRACE_EXIT 0;
550     }
551     /* return the block position from start of volume 
552      */
553     static int mt_tell(int *arg)
554     {
555     	TRACE_FUN(ft_t_flow);
556     	
557     	*arg   = zft_div_blksz(zft_pos.volume_pos,
558     			       zft_find_volume(zft_pos.seg_pos)->blk_sz);
559     	TRACE_EXIT 0;
560     }
561     
562     static int mt_compression(int *arg)
563     {
564     	TRACE_FUN(ft_t_flow);
565     	
566     	/*  Ok. We could also check whether compression is available at
567     	 *  all by trying to load the compression module.  We could
568     	 *  also check for a block size of 1 byte which is illegal
569     	 *  with compression.  Instead of doing it here we rely on
570     	 *  zftape_write() to do the proper checks.
571     	 */
572     	if ((unsigned int)*arg > 1) {
573     		TRACE_EXIT -EINVAL;
574     	}
575     	if (*arg != 0 && zft_blk_sz == 1) { /* variable block size */
576     		TRACE_ABORT(-EINVAL, ft_t_info,
577     			    "Compression not yet supported "
578     			    "with variable block size");
579     	}
580     	zft_mt_compression  = *arg;
581     	if ((zft_unit & ZFT_ZIP_MODE) == 0) {
582     		zft_use_compression = zft_mt_compression;
583     	}
584     	TRACE_EXIT 0;
585     }
586     
587     /*  check whether write access is allowed. Write access is denied when
588      *  + zft_write_protected == 1 -- this accounts for either hard write 
589      *                                protection of the cartridge or for 
590      *                                O_RDONLY access mode of the tape device
591      *  + zft_offline == 1         -- this meany that there is either no tape 
592      *                                or that the MTOFFLINE ioctl has been 
593      *                                previously issued (`soft eject')
594      *  + ft_formatted == 0        -- this means that the cartridge is not
595      *                                formatted
596      *  Then we distinuguish two cases. When zft_qic_mode is TRUE, then we try
597      *  to emulate a `traditional' (aka SCSI like) UN*X tape device. Therefore we
598      *  deny writes when
599      *  + zft_qic_mode ==1 && 
600      *       (!zft_tape_at_lbot() &&   -- tape no at logical BOT
601      *        !(zft_tape_at_eom() ||   -- tape not at logical EOM (or EOD)
602      *          (zft_tape_at_eom() &&
603      *           zft_old_ftape())))    -- we can't add new volume to tapes 
604      *                                    written by old ftape because ftape
605      *                                    don't use the volume table
606      *
607      *  when the drive is in true raw mode (aka /dev/rawft0) then we don't 
608      *  care about LBOT and EOM conditions. This device is intended for a 
609      *  user level program that wants to truly implement the QIC-80 compliance
610      *  at the logical data layout level of the cartridge, i.e. implement all
611      *  that volume table and volume directory stuff etc.<
612      */
613     int zft_check_write_access(zft_position *pos)
614     {
615     	TRACE_FUN(ft_t_flow);
616     
617     	if (zft_offline) { /* offline includes no_tape */
618     		TRACE_ABORT(-ENXIO,
619     			    ft_t_info, "tape is offline or no cartridge");
620     	}
621     	if (!ft_formatted) {
622     		TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted");
623     	} 
624     	if (zft_write_protected) {
625     		TRACE_ABORT(-EACCES, ft_t_info, "cartridge write protected");
626     	} 
627     	if (zft_qic_mode) {
628     		/*  check BOT condition */
629     		if (!zft_tape_at_lbot(pos)) {
630     			/*  protect cartridges written by old ftape if
631     			 *  not at BOT because they use the vtbl
632     			 *  segment for storing data
633     			 */
634     			if (zft_old_ftape) {
635     				TRACE_ABORT(-EACCES, ft_t_warn, 
636           "Cannot write to cartridges written by old ftape when not at BOT");
637     			}
638     			/*  not at BOT, but allow writes at EOD, of course
639     			 */
640     			if (!zft_tape_at_eod(pos)) {
641     				TRACE_ABORT(-EACCES, ft_t_info,
642     					    "tape not at BOT and not at EOD");
643     			}
644     		}
645     		/*  fine. Now the tape is either at BOT or at EOD. */
646     	}
647     	/* or in raw mode in which case we don't care about BOT and EOD */
648     	TRACE_EXIT 0;
649     }
650     
651     /*  decide when we should lock the module in memory, even when calling
652      *  the release routine. This really is necessary for use with
653      *  kerneld.
654      *
655      *  NOTE: we MUST NOT use zft_write_protected, because this includes
656      *  the file access mode as well which has no meaning with our 
657      *  asynchronous update scheme.
658      *
659      *  Ugly, ugly. We need to look the module if we changed the block size.
660      *  How sad! Need persistent modules storage!
661      *
662      *  NOTE: I don't want to lock the module if the number of dma buffers 
663      *  has been changed. It's enough! Stop the story! Give me persisitent
664      *  module storage! Do it!
665      */
666     int zft_dirty(void)
667     {
668     	if (!ft_formatted || zft_offline) { 
669     		/* cannot be dirty if not formatted or offline */
670     		return 0;
671     	}
672     	if (zft_blk_sz != CONFIG_ZFT_DFLT_BLK_SZ) {
673     		/* blocksize changed, must lock */
674     		return 1;
675     	}
676     	if (zft_mt_compression != 0) {
677     		/* compression mode with /dev/qft, must lock */
678     		return 1;
679     	}
680     	if (!zft_header_read) {
681     		/* tape is logical at BOT, no lock */
682     		return 0;
683     	}
684     	if (!zft_tape_at_lbot(&zft_pos)) {
685     		/* somewhere inside a volume, lock tape */
686     		return 1;
687     	}
688     	if (zft_volume_table_changed || zft_header_changed) {
689     		/* header segments dirty if tape not write protected */
690     		return !(ft_write_protected || zft_old_ftape);
691     	}
692     	return 0;
693     }
694     
695     /*      OPEN routine called by kernel-interface code
696      *
697      *      NOTE: this is also called by mt_reset() with dev_minor == -1
698      *            to fake a reopen after a reset.
699      */
700     int _zft_open(unsigned int dev_minor, unsigned int access_mode)
701     {
702     	static unsigned int tape_unit;
703     	static unsigned int file_access_mode;
704     	int result;
705     	TRACE_FUN(ft_t_flow);
706     
707     	if ((int)dev_minor == -1) {
708     		/* fake reopen */
709     		zft_unit    = tape_unit;
710     		access_mode = file_access_mode;
711     		zft_init_driver(); /* reset all static data to defaults */
712     	} else {
713     		tape_unit        = dev_minor;
714     		file_access_mode = access_mode;
715     		if ((result = ftape_enable(FTAPE_SEL(dev_minor))) < 0) {
716     			TRACE_ABORT(-ENXIO, ft_t_err,
717     				    "ftape_enable failed: %d", result);
718     		}
719     		if (ft_new_tape || ft_no_tape || !ft_formatted ||
720     		    (FTAPE_SEL(zft_unit) != FTAPE_SEL(dev_minor)) ||
721     		    (zft_unit & ZFT_RAW_MODE) != (dev_minor & ZFT_RAW_MODE)) {
722     			/* reset all static data to defaults,
723     			 */
724     			zft_init_driver(); 
725     		}
726     		zft_unit = dev_minor;
727     	}
728     	zft_set_flags(zft_unit); /* decode the minor bits */
729     	if (zft_blk_sz == 1 && zft_use_compression) {
730     		ftape_disable(); /* resets ft_no_tape */
731     		TRACE_ABORT(-ENODEV, ft_t_warn, "Variable block size not yet "
732     			    "supported with compression");
733     	}
734     	/*  no need for most of the buffers when no tape or not
735     	 *  formatted.  for the read/write operations, it is the
736     	 *  regardless whether there is no tape, a not-formatted tape
737     	 *  or the whether the driver is soft offline.  
738     	 *  Nevertheless we allow some ioctls with non-formatted tapes, 
739     	 *  like rewind and reset.
740     	 */
741     	if (ft_no_tape || !ft_formatted) {
742     		zft_uninit_mem();
743     	}
744     	if (ft_no_tape) {
745     		zft_offline = 1; /* so we need not test two variables */
746     	}
747     	if ((access_mode == O_WRONLY || access_mode == O_RDWR) &&
748     	    (ft_write_protected || ft_no_tape)) {
749     		ftape_disable(); /* resets ft_no_tape */
750     		TRACE_ABORT(ft_no_tape ? -ENXIO : -EROFS,
751     			    ft_t_warn, "wrong access mode %s cartridge",
752     			    ft_no_tape ? "without a" : "with write protected");
753     	}
754     	zft_write_protected = (access_mode == O_RDONLY || 
755     			       ft_write_protected != 0);
756     	if (zft_write_protected) {
757     		TRACE(ft_t_noise,
758     		      "read only access mode: %d, "
759     		      "drive write protected: %d", 
760     		      access_mode == O_RDONLY,
761     		      ft_write_protected != 0);
762     	}
763     	if (!zft_offline) {
764     		TRACE_CATCH(zft_vmalloc_once(&zft_deblock_buf,FT_SEGMENT_SIZE),
765     			    ftape_disable());
766     	}
767     	/* zft_seg_pos should be greater than the vtbl segpos but not
768     	 * if in compatability mode and only after we read in the
769     	 * header segments
770     	 *
771     	 * might also be a problem if the user makes a backup with a
772     	 * *qft* device and rewinds it with a raw device.
773     	 */
774     	if (zft_qic_mode         &&
775     	    !zft_old_ftape       &&
776     	    zft_pos.seg_pos >= 0 &&
777     	    zft_header_read      && 
778     	    zft_pos.seg_pos <= ft_first_data_segment) {
779     		TRACE(ft_t_noise, "you probably mixed up the zftape devices!");
780     		zft_reset_position(&zft_pos); 
781     	}
782     	TRACE_EXIT 0;
783     }
784     
785     /*      RELEASE routine called by kernel-interface code
786      */
787     int _zft_close(void)
788     {
789     	int result = 0;
790     	TRACE_FUN(ft_t_flow);
791     	
792     	if (zft_offline) {
793     		/* call the hardware release routine. Puts the drive offline */
794     		ftape_disable();
795     		TRACE_EXIT 0;
796     	}
797     	if (!(ft_write_protected || zft_old_ftape)) {
798     		result = zft_flush_buffers();
799     		TRACE(ft_t_noise, "writing file mark at current position");
800     		if (zft_qic_mode && zft_close_volume(&zft_pos) == 0) {
801     			zft_move_past_eof(&zft_pos);
802     		}
803     		if ((zft_tape_at_lbot(&zft_pos) ||
804     		     !(zft_unit & FTAPE_NO_REWIND))) {
805     			if (result >= 0) {
806     				result = zft_update_header_segments();
807     			} else {
808     				TRACE(ft_t_err,
809     				"Error: unable to update header segments");
810     			}
811     		}
812     	}
813     	ftape_abort_operation();
814     	if (!(zft_unit & FTAPE_NO_REWIND)) {
815     		TRACE(ft_t_noise, "rewinding tape");
816     		if (ftape_seek_to_bot() < 0 && result >= 0) {
817     			result = -EIO; /* keep old value */
818     		}
819     		zft_reset_position(&zft_pos);
820     	} 
821     	zft_zap_read_buffers();
822     	/*  now free up memory as much as possible. We don't destroy
823     	 *  the deblock buffer if it containes a valid segment.
824     	 */
825     	if (zft_deblock_segment == -1) {
826     		zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE); 
827     	}
828     	/* high level driver status, forces creation of a new volume
829     	 * when calling ftape_write again and not zft_just_before_eof
830     	 */
831     	zft_io_state = zft_idle;  
832     	if (going_offline) {
833     		zft_init_driver();
834     		zft_uninit_mem();
835     		going_offline = 0;
836     		zft_offline   = 1;
837     	} else if (zft_dirty()) {
838     		TRACE(ft_t_noise, "Keeping module locked in memory because:\n"
839     		      KERN_INFO "header segments need updating: %s\n"
840     		      KERN_INFO "tape not at BOT              : %s",
841     		      (zft_volume_table_changed || zft_header_changed) 
842     		      ? "yes" : "no",
843     		      zft_tape_at_lbot(&zft_pos) ? "no" : "yes");
844     	} else if (zft_cmpr_lock(0 /* don't load */) == 0) {
845     		(*zft_cmpr_ops->reset)(); /* unlock it again */
846     	}
847     	zft_memory_stats();
848     	/* call the hardware release routine. Puts the drive offline */
849     	ftape_disable();
850     	TRACE_EXIT result;
851     }
852     
853     /*
854      *  the wrapper function around the wrapper MTIOCTOP ioctl
855      */
856     static int mtioctop(struct mtop *mtop, int arg_size)
857     {
858     	int result = 0;
859     	fun_entry *mt_fun_entry;
860     	TRACE_FUN(ft_t_flow);
861     	
862     	if (arg_size != sizeof(struct mtop) || mtop->mt_op >= NR_MT_CMDS) {
863     		TRACE_EXIT -EINVAL;
864     	}
865     	TRACE(ft_t_noise, "calling MTIOCTOP command: %s",
866     	      mt_funs[mtop->mt_op].name);
867     	mt_fun_entry= &mt_funs[mtop->mt_op];
868     	zft_resid = mtop->mt_count;
869     	if (!mt_fun_entry->offline && zft_offline) {
870     		if (ft_no_tape) {
871     			TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
872     		} else {
873     			TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline");
874     		}
875     	}
876     	if (!mt_fun_entry->not_formatted && !ft_formatted) {
877     		TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted");
878     	}
879     	if (!mt_fun_entry->write_protected) {
880     		TRACE_CATCH(zft_check_write_access(&zft_pos),);
881     	}
882     	if (mt_fun_entry->need_idle_state && !(zft_offline || !ft_formatted)) {
883     		TRACE_CATCH(zft_def_idle_state(),);
884     	}
885     	if (!zft_qic_mode && !mt_fun_entry->raw_mode) {
886     		TRACE_ABORT(-EACCES, ft_t_info, 
887     "Drive needs to be in QIC-80 compatibility mode for this command");
888     	}
889     	result = (mt_fun_entry->function)(&mtop->mt_count);
890     	if (zft_tape_at_lbot(&zft_pos)) {
891     		TRACE_CATCH(zft_update_header_segments(),);
892     	}
893     	if (result >= 0) {
894     		zft_resid = 0;
895     	}
896     	TRACE_EXIT result;
897     }
898     
899     /*
900      *  standard MTIOCGET ioctl
901      */
902     static int mtiocget(struct mtget *mtget, int arg_size)
903     {
904     	const zft_volinfo *volume;
905     	__s64 max_tape_pos;
906     	TRACE_FUN(ft_t_flow);
907     	
908     	if (arg_size != sizeof(struct mtget)) {
909     		TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
910     			    arg_size);
911     	}
912     	mtget->mt_type  = ft_drive_type.vendor_id + 0x800000;
913     	mtget->mt_dsreg = ft_last_status.space;
914     	mtget->mt_erreg = ft_last_error.space; /* error register */
915     	mtget->mt_resid = zft_resid; /* residuum of writes, reads and
916     				      * MTIOCTOP commands 
917     				      */
918     	if (!zft_offline) { /* neither no_tape nor soft offline */
919     		mtget->mt_gstat = GMT_ONLINE(~0UL);
920     		/* should rather return the status of the cartridge
921     		 * than the access mode of the file, therefor use
922     		 * ft_write_protected, not zft_write_protected 
923     		 */
924     		if (ft_write_protected) {
925     			mtget->mt_gstat |= GMT_WR_PROT(~0UL);
926     		}
927     		if(zft_header_read) { /* this catches non-formatted */
928     			volume = zft_find_volume(zft_pos.seg_pos);
929     			mtget->mt_fileno = volume->count;
930     			max_tape_pos = zft_capacity - zft_blk_sz;
931     			if (zft_use_compression) {
932     				max_tape_pos -= ZFT_CMPR_OVERHEAD;
933     			}
934     			if (zft_tape_at_eod(&zft_pos)) {
935     				mtget->mt_gstat |= GMT_EOD(~0UL);
936     			}
937     			if (zft_pos.tape_pos > max_tape_pos) {
938     				mtget->mt_gstat |= GMT_EOT(~0UL);
939     			}
940     			mtget->mt_blkno = zft_div_blksz(zft_pos.volume_pos,
941     							volume->blk_sz);
942     			if (zft_just_before_eof) {
943     				mtget->mt_gstat |= GMT_EOF(~0UL);
944     			}
945     			if (zft_tape_at_lbot(&zft_pos)) {
946     				mtget->mt_gstat |= GMT_BOT(~0UL);
947     			}
948     		} else {
949     			mtget->mt_fileno = mtget->mt_blkno = -1;
950     			if (mtget->mt_dsreg & QIC_STATUS_AT_BOT) {
951     				mtget->mt_gstat |= GMT_BOT(~0UL);
952     			}
953     		}
954     	} else {
955     		if (ft_no_tape) {
956     			mtget->mt_gstat = GMT_DR_OPEN(~0UL);
957     		} else {
958     			mtget->mt_gstat = 0UL;
959     		}
960      		mtget->mt_fileno = mtget->mt_blkno = -1;
961     	}
962     	TRACE_EXIT 0;
963     }
964     
965     #ifdef MTIOCRDFTSEG
966     /*
967      *  Read a floppy tape segment. This is useful for manipulating the
968      *  volume table, and read the old header segment before re-formatting
969      *  the cartridge.
970      */
971     static int mtiocrdftseg(struct mtftseg * mtftseg, int arg_size)
972     {
973     	TRACE_FUN(ft_t_flow);
974     	
975     	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCRDFTSEG");
976     	if (zft_qic_mode) {
977     		TRACE_ABORT(-EACCES, ft_t_info,
978     			    "driver needs to be in raw mode for this ioctl");
979     	} 
980     	if (arg_size != sizeof(struct mtftseg)) {
981     		TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
982     			    arg_size);
983     	}
984     	if (zft_offline) {
985     		TRACE_EXIT -ENXIO;
986     	}
987     	if (mtftseg->mt_mode != FT_RD_SINGLE &&
988     	    mtftseg->mt_mode != FT_RD_AHEAD) {
989     		TRACE_ABORT(-EINVAL, ft_t_info, "invalid read mode");
990     	}
991     	if (!ft_formatted) {
992     		TRACE_EXIT -EACCES; /* -ENXIO ? */
993     
994     	}
995     	if (!zft_header_read) {
996     		TRACE_CATCH(zft_def_idle_state(),);
997     	}
998     	if (mtftseg->mt_segno > ft_last_data_segment) {
999     		TRACE_ABORT(-EINVAL, ft_t_info, "segment number is too large");
1000     	}
1001     	mtftseg->mt_result = ftape_read_segment(mtftseg->mt_segno,
1002     						zft_deblock_buf,
1003     						mtftseg->mt_mode);
1004     	if (mtftseg->mt_result < 0) {
1005     		/*  a negativ result is not an ioctl error. if
1006     		 *  the user wants to read damaged tapes,
1007     		 *  it's up to her/him
1008     		 */
1009     		TRACE_EXIT 0;
1010     	}
1011     #if LINUX_VERSION_CODE > KERNEL_VER(2,1,3)
1012     	if (copy_to_user(mtftseg->mt_data,
1013     			 zft_deblock_buf,
1014     			 mtftseg->mt_result) != 0) {
1015     		TRACE_EXIT -EFAULT;
1016     	}
1017     #else
1018     	TRACE_CATCH(verify_area(VERIFY_WRITE, mtftseg->mt_data,
1019     				mtftseg->mt_result),);
1020     	memcpy_tofs(mtftseg->mt_data, zft_deblock_buf, 
1021     		    mtftseg->mt_result);
1022     #endif
1023     	TRACE_EXIT 0;
1024     }
1025     #endif
1026     
1027     #ifdef MTIOCWRFTSEG
1028     /*
1029      *  write a floppy tape segment. This version features writing of
1030      *  deleted address marks, and gracefully ignores the (software)
1031      *  ft_formatted flag to support writing of header segments after
1032      *  formatting.
1033      */
1034     static int mtiocwrftseg(struct mtftseg * mtftseg, int arg_size)
1035     {
1036     	int result;
1037     	TRACE_FUN(ft_t_flow);
1038     	
1039     	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCWRFTSEG");
1040     	if (zft_write_protected || zft_qic_mode) {
1041     		TRACE_EXIT -EACCES;
1042     	} 
1043     	if (arg_size != sizeof(struct mtftseg)) {
1044     		TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
1045     			    arg_size);
1046     	}
1047     	if (zft_offline) {
1048     		TRACE_EXIT -ENXIO;
1049     	}
1050     	if (mtftseg->mt_mode != FT_WR_ASYNC   && 
1051     	    mtftseg->mt_mode != FT_WR_MULTI   &&
1052     	    mtftseg->mt_mode != FT_WR_SINGLE  &&
1053     	    mtftseg->mt_mode != FT_WR_DELETE) {
1054     		TRACE_ABORT(-EINVAL, ft_t_info, "invalid write mode");
1055     	}
1056     	/*
1057     	 *  We don't check for ft_formatted, because this gives
1058     	 *  only the software status of the driver.
1059     	 *
1060     	 *  We assume that the user knows what it is
1061     	 *  doing. And rely on the low level stuff to fail
1062     	 *  when the tape isn't formatted. We only make sure
1063     	 *  that The header segment buffer is allocated,
1064     	 *  because it holds the bad sector map.
1065     	 */
1066     	if (zft_hseg_buf == NULL) {
1067     		TRACE_EXIT -ENXIO;
1068     	}
1069     	if (mtftseg->mt_mode != FT_WR_DELETE) {
1070     #if LINUX_VERSION_CODE > KERNEL_VER(2,1,3)
1071     		if (copy_from_user(zft_deblock_buf, 
1072     				   mtftseg->mt_data,
1073     				   FT_SEGMENT_SIZE) != 0) {
1074     			TRACE_EXIT -EFAULT;
1075     		}
1076     #else
1077     		TRACE_CATCH(verify_area(VERIFY_READ, 
1078     					mtftseg->mt_data, 
1079     					FT_SEGMENT_SIZE),);
1080     		memcpy_fromfs(zft_deblock_buf, mtftseg->mt_data,
1081     			      FT_SEGMENT_SIZE);
1082     #endif
1083     	}
1084     	mtftseg->mt_result = ftape_write_segment(mtftseg->mt_segno, 
1085     						 zft_deblock_buf,
1086     						 mtftseg->mt_mode);
1087     	if (mtftseg->mt_result >= 0 && mtftseg->mt_mode == FT_WR_SINGLE) {
1088     		/*  
1089     		 *  a negativ result is not an ioctl error. if
1090     		 *  the user wants to write damaged tapes,
1091     		 *  it's up to her/him
1092     		 */
1093     		if ((result = ftape_loop_until_writes_done()) < 0) {
1094     			mtftseg->mt_result = result;
1095     		}
1096     	}
1097     	TRACE_EXIT 0;
1098     }
1099     #endif
1100       
1101     #ifdef MTIOCVOLINFO
1102     /*
1103      *  get information about volume positioned at.
1104      */
1105     static int mtiocvolinfo(struct mtvolinfo *volinfo, int arg_size)
1106     {
1107     	const zft_volinfo *volume;
1108     	TRACE_FUN(ft_t_flow);
1109     	
1110     	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCVOLINFO");
1111     	if (arg_size != sizeof(struct mtvolinfo)) {
1112     		TRACE_ABORT(-EINVAL,
1113     			    ft_t_info, "bad argument size: %d", arg_size);
1114     	}
1115     	if (zft_offline) {
1116     		TRACE_EXIT -ENXIO;
1117     	}
1118     	if (!ft_formatted) {
1119     		TRACE_EXIT -EACCES;
1120     	}
1121     	TRACE_CATCH(zft_def_idle_state(),);
1122     	volume = zft_find_volume(zft_pos.seg_pos);
1123     	volinfo->mt_volno   = volume->count;
1124     	volinfo->mt_blksz   = volume->blk_sz == 1 ? 0 : volume->blk_sz;
1125     	volinfo->mt_size    = volume->size >> 10;
1126     	volinfo->mt_rawsize = ((zft_calc_tape_pos(volume->end_seg + 1) >> 10) -
1127     			       (zft_calc_tape_pos(volume->start_seg) >> 10));
1128     	volinfo->mt_cmpr    = volume->use_compression;
1129     	TRACE_EXIT 0;
1130     }
1131     #endif
1132     
1133     #ifdef ZFT_OBSOLETE  
1134     static int mtioc_zftape_getblksz(struct mtblksz *blksz, int arg_size)
1135     {
1136     	TRACE_FUN(ft_t_flow);
1137     	
1138     	TRACE(ft_t_noise, "\n"
1139     	      KERN_INFO "Mag tape ioctl command: MTIOC_ZTAPE_GETBLKSZ\n"
1140     	      KERN_INFO "This ioctl is here merely for compatibility.\n"
1141     	      KERN_INFO "Please use MTIOCVOLINFO instead");
1142     	if (arg_size != sizeof(struct mtblksz)) {
1143     		TRACE_ABORT(-EINVAL,
1144     			    ft_t_info, "bad argument size: %d", arg_size);
1145     	}
1146     	if (zft_offline) {
1147     		TRACE_EXIT -ENXIO;
1148     	}
1149     	if (!ft_formatted) {
1150     		TRACE_EXIT -EACCES;
1151     	}
1152     	TRACE_CATCH(zft_def_idle_state(),);
1153     	blksz->mt_blksz = zft_find_volume(zft_pos.seg_pos)->blk_sz;
1154     	TRACE_EXIT 0;
1155     }
1156     #endif
1157     
1158     #ifdef MTIOCGETSIZE
1159     /*
1160      *  get the capacity of the tape cartridge.
1161      */
1162     static int mtiocgetsize(struct mttapesize *size, int arg_size)
1163     {
1164     	TRACE_FUN(ft_t_flow);
1165     	
1166     	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOC_ZFTAPE_GETSIZE");
1167     	if (arg_size != sizeof(struct mttapesize)) {
1168     		TRACE_ABORT(-EINVAL,
1169     			    ft_t_info, "bad argument size: %d", arg_size);
1170     	}
1171     	if (zft_offline) {
1172     		TRACE_EXIT -ENXIO;
1173     	}
1174     	if (!ft_formatted) {
1175     		TRACE_EXIT -EACCES;
1176     	}
1177     	TRACE_CATCH(zft_def_idle_state(),);
1178     	size->mt_capacity = (unsigned int)(zft_capacity>>10);
1179     	size->mt_used     = (unsigned int)(zft_get_eom_pos()>>10);
1180     	TRACE_EXIT 0;
1181     }
1182     #endif
1183     
1184     static int mtiocpos(struct mtpos *mtpos, int arg_size)
1185     {
1186     	int result;
1187     	TRACE_FUN(ft_t_flow);
1188     	
1189     	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCPOS");
1190     	if (arg_size != sizeof(struct mtpos)) {
1191     		TRACE_ABORT(-EINVAL,
1192     			    ft_t_info, "bad argument size: %d", arg_size);
1193     	}
1194     	result = mt_tell((int *)&mtpos->mt_blkno);
1195     	TRACE_EXIT result;
1196     }
1197     
1198     #ifdef MTIOCFTFORMAT
1199     /*
1200      * formatting of floppy tape cartridges. This is intended to be used
1201      * together with the MTIOCFTCMD ioctl and the new mmap feature 
1202      */
1203     
1204     /* 
1205      *  This function uses ftape_decode_header_segment() to inform the low
1206      *  level ftape module about the new parameters.
1207      *
1208      *  It erases the hseg_buf. The calling process must specify all
1209      *  parameters to assure proper operation.
1210      *
1211      *  return values: -EINVAL - wrong argument size
1212      *                 -EINVAL - if ftape_decode_header_segment() failed.
1213      */
1214     static int set_format_parms(struct ftfmtparms *p, __u8 *hseg_buf)
1215     {
1216     	ft_trace_t old_level = TRACE_LEVEL;
1217     	TRACE_FUN(ft_t_flow);
1218     
1219     	TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_SETPARMS");
1220     	memset(hseg_buf, 0, FT_SEGMENT_SIZE);
1221     	PUT4(hseg_buf, FT_SIGNATURE, FT_HSEG_MAGIC);
1222     
1223     	/*  fill in user specified parameters
1224     	 */
1225     	hseg_buf[FT_FMT_CODE] = (__u8)p->ft_fmtcode;
1226     	PUT2(hseg_buf, FT_SPT, p->ft_spt);
1227     	hseg_buf[FT_TPC]      = (__u8)p->ft_tpc;
1228     	hseg_buf[FT_FHM]      = (__u8)p->ft_fhm;
1229     	hseg_buf[FT_FTM]      = (__u8)p->ft_ftm;
1230     
1231     	/*  fill in sane defaults to make ftape happy.
1232     	 */ 
1233     	hseg_buf[FT_FSM] = (__u8)128; /* 128 is hard wired all over ftape */
1234     	if (p->ft_fmtcode == fmt_big) {
1235     		PUT4(hseg_buf, FT_6_HSEG_1,   0);
1236     		PUT4(hseg_buf, FT_6_HSEG_2,   1);
1237     		PUT4(hseg_buf, FT_6_FRST_SEG, 2);
1238     		PUT4(hseg_buf, FT_6_LAST_SEG, p->ft_spt * p->ft_tpc - 1);
1239     	} else {
1240     		PUT2(hseg_buf, FT_HSEG_1,    0);
1241     		PUT2(hseg_buf, FT_HSEG_2,    1);
1242     		PUT2(hseg_buf, FT_FRST_SEG,  2);
1243     		PUT2(hseg_buf, FT_LAST_SEG, p->ft_spt * p->ft_tpc - 1);
1244     	}
1245     
1246     	/*  Synchronize with the low level module. This is particularly
1247     	 *  needed for unformatted cartridges as the QIC std was previously 
1248     	 *  unknown BUT is needed to set data rate and to calculate timeouts.
1249     	 */
1250     	TRACE_CATCH(ftape_calibrate_data_rate(p->ft_qicstd&QIC_TAPE_STD_MASK),
1251     		    _res = -EINVAL);
1252     
1253     	/*  The following will also recalcualte the timeouts for the tape
1254     	 *  length and QIC std we want to format to.
1255     	 *  abort with -EINVAL rather than -EIO
1256     	 */
1257     	SET_TRACE_LEVEL(ft_t_warn);
1258     	TRACE_CATCH(ftape_decode_header_segment(hseg_buf),
1259     		    SET_TRACE_LEVEL(old_level); _res = -EINVAL);
1260     	SET_TRACE_LEVEL(old_level);
1261     	TRACE_EXIT 0;
1262     }
1263     
1264     /*
1265      *  Return the internal SOFTWARE status of the kernel driver. This does
1266      *  NOT query the tape drive about its status.
1267      */
1268     static int get_format_parms(struct ftfmtparms *p, __u8 *hseg_buffer)
1269     {
1270     	TRACE_FUN(ft_t_flow);
1271     
1272     	TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_GETPARMS");
1273     	p->ft_qicstd  = ft_qic_std;
1274     	p->ft_fmtcode = ft_format_code;
1275     	p->ft_fhm     = hseg_buffer[FT_FHM];
1276     	p->ft_ftm     = hseg_buffer[FT_FTM];
1277     	p->ft_spt     = ft_segments_per_track;
1278     	p->ft_tpc     = ft_tracks_per_tape;
1279     	TRACE_EXIT 0;
1280     }
1281     
1282     static int mtiocftformat(struct mtftformat *mtftformat, int arg_size)
1283     {
1284     	int result;
1285     	union fmt_arg *arg = &mtftformat->fmt_arg;
1286     	TRACE_FUN(ft_t_flow);
1287     
1288     	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTFORMAT");
1289     	if (zft_offline) {
1290     		if (ft_no_tape) {
1291     			TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
1292     		} else {
1293     			TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline");
1294     		}
1295     	}
1296     	if (zft_qic_mode) {
1297     		TRACE_ABORT(-EACCES, ft_t_info,
1298     			    "driver needs to be in raw mode for this ioctl");
1299     	} 
1300     	if (zft_hseg_buf == NULL) {
1301     		TRACE_CATCH(zft_vcalloc_once(&zft_hseg_buf, FT_SEGMENT_SIZE),);
1302     	}
1303     	zft_header_read = 0;
1304     	switch(mtftformat->fmt_op) {
1305     	case FTFMT_SET_PARMS:
1306     		TRACE_CATCH(set_format_parms(&arg->fmt_parms, zft_hseg_buf),);
1307     		TRACE_EXIT 0;
1308     	case FTFMT_GET_PARMS:
1309     		TRACE_CATCH(get_format_parms(&arg->fmt_parms, zft_hseg_buf),);
1310     		TRACE_EXIT 0;
1311     	case FTFMT_FORMAT_TRACK:
1312     		if ((ft_formatted && zft_check_write_access(&zft_pos) < 0) ||
1313     		    (!ft_formatted && zft_write_protected)) {
1314     			TRACE_ABORT(-EACCES, ft_t_info, "Write access denied");
1315     		}
1316     		TRACE_CATCH(ftape_format_track(arg->fmt_track.ft_track,
1317     					       arg->fmt_track.ft_gap3),);
1318     		TRACE_EXIT 0;
1319     	case FTFMT_STATUS:
1320     		TRACE_CATCH(ftape_format_status(&arg->fmt_status.ft_segment),);
1321     		TRACE_EXIT 0;
1322     	case FTFMT_VERIFY:
1323     		TRACE_CATCH(ftape_verify_segment(arg->fmt_verify.ft_segment,
1324     				(SectorMap *)&arg->fmt_verify.ft_bsm),);
1325     		TRACE_EXIT 0;
1326     	default:
1327     		TRACE_ABORT(-EINVAL, ft_t_err, "Invalid format operation");
1328     	}
1329     	TRACE_EXIT result;
1330     }
1331     #endif
1332     
1333     #ifdef MTIOCFTCMD
1334     /*
1335      *  send a QIC-117 command to the drive, with optional timeouts,
1336      *  parameter and result bits. This is intended to be used together
1337      *  with the formatting ioctl.
1338      */
1339     static int mtiocftcmd(struct mtftcmd *ftcmd, int arg_size)
1340     {
1341     	int i;
1342     	TRACE_FUN(ft_t_flow);
1343     
1344     	TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTCMD");
1345     	if (!capable(CAP_SYS_ADMIN)) {
1346     		TRACE_ABORT(-EPERM, ft_t_info,
1347     			    "need CAP_SYS_ADMIN capability to send raw qic-117 commands");
1348     	}
1349     	if (zft_qic_mode) {
1350     		TRACE_ABORT(-EACCES, ft_t_info,
1351     			    "driver needs to be in raw mode for this ioctl");
1352     	} 
1353     	if (arg_size != sizeof(struct mtftcmd)) {
1354     		TRACE_ABORT(-EINVAL,
1355     			    ft_t_info, "bad argument size: %d", arg_size);
1356     	}
1357     	if (ftcmd->ft_wait_before) {
1358     		TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_before,
1359     					     &ftcmd->ft_status),);
1360     	}
1361     	if (ftcmd->ft_status & QIC_STATUS_ERROR)
1362     		goto ftmtcmd_error;
1363     	if (ftcmd->ft_result_bits != 0) {
1364     		TRACE_CATCH(ftape_report_operation(&ftcmd->ft_result,
1365     						   ftcmd->ft_cmd,
1366     						   ftcmd->ft_result_bits),);
1367     	} else {
1368     		TRACE_CATCH(ftape_command(ftcmd->ft_cmd),);
1369     		if (ftcmd->ft_status & QIC_STATUS_ERROR)
1370     			goto ftmtcmd_error;
1371     		for (i = 0; i < ftcmd->ft_parm_cnt; i++) {
1372     			TRACE_CATCH(ftape_parameter(ftcmd->ft_parms[i]&0x0f),);
1373     			if (ftcmd->ft_status & QIC_STATUS_ERROR)
1374     				goto ftmtcmd_error;
1375     		}
1376     	}
1377     	if (ftcmd->ft_wait_after != 0) {
1378     		TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_after,
1379     					     &ftcmd->ft_status),);
1380     	}
1381     ftmtcmd_error:	       
1382     	if (ftcmd->ft_status & QIC_STATUS_ERROR) {
1383     		TRACE(ft_t_noise, "error status set");
1384     		TRACE_CATCH(ftape_report_error(&ftcmd->ft_error,
1385     					       &ftcmd->ft_cmd, 1),);
1386     	}
1387     	TRACE_EXIT 0; /* this is not an i/o error */
1388     }
1389     #endif
1390     
1391     /*  IOCTL routine called by kernel-interface code
1392      */
1393     int _zft_ioctl(unsigned int command, void * arg)
1394     {
1395     	int result;
1396     	union { struct mtop       mtop;
1397     		struct mtget      mtget;
1398     		struct mtpos      mtpos;
1399     #ifdef MTIOCRDFTSEG
1400     		struct mtftseg    mtftseg;
1401     #endif
1402     #ifdef MTIOCVOLINFO
1403     		struct mtvolinfo  mtvolinfo;
1404     #endif
1405     #ifdef MTIOCGETSIZE
1406     		struct mttapesize mttapesize;
1407     #endif
1408     #ifdef MTIOCFTFORMAT
1409     		struct mtftformat mtftformat;
1410     #endif
1411     #ifdef ZFT_OBSOLETE
1412     		struct mtblksz mtblksz;
1413     #endif
1414     #ifdef MTIOCFTCMD
1415     		struct mtftcmd mtftcmd;
1416     #endif
1417     	} krnl_arg;
1418     	int arg_size = _IOC_SIZE(command);
1419     	int dir = _IOC_DIR(command);
1420     	TRACE_FUN(ft_t_flow);
1421     
1422     	/* This check will only catch arguments that are too large !
1423     	 */
1424     	if (dir & (_IOC_READ | _IOC_WRITE) && arg_size > sizeof(krnl_arg)) {
1425     		TRACE_ABORT(-EINVAL,
1426     			    ft_t_info, "bad argument size: %d", arg_size);
1427     	}
1428     	if (dir & _IOC_WRITE) {
1429     #if LINUX_VERSION_CODE > KERNEL_VER(2,1,3)
1430     		if (copy_from_user(&krnl_arg, arg, arg_size) != 0) {
1431     			TRACE_EXIT -EFAULT;
1432     		}
1433     #else
1434     		TRACE_CATCH(verify_area(VERIFY_READ, arg, arg_size),);
1435     		memcpy_fromfs(&krnl_arg, arg, arg_size);
1436     #endif
1437     	}
1438     	TRACE(ft_t_flow, "called with ioctl command: 0x%08x", command);
1439     	switch (command) {
1440     	case MTIOCTOP:
1441     		result = mtioctop(&krnl_arg.mtop, arg_size);
1442     		break;
1443     	case MTIOCGET:
1444     		result = mtiocget(&krnl_arg.mtget, arg_size);
1445     		break;
1446     	case MTIOCPOS:
1447     		result = mtiocpos(&krnl_arg.mtpos, arg_size);
1448     		break;
1449     #ifdef MTIOCVOLINFO
1450     	case MTIOCVOLINFO:
1451     		result = mtiocvolinfo(&krnl_arg.mtvolinfo, arg_size);
1452     		break;
1453     #endif
1454     #ifdef ZFT_OBSOLETE
1455     	case MTIOC_ZFTAPE_GETBLKSZ:
1456     		result = mtioc_zftape_getblksz(&krnl_arg.mtblksz, arg_size);
1457     		break;
1458     #endif
1459     #ifdef MTIOCRDFTSEG
1460     	case MTIOCRDFTSEG: /* read a segment via ioctl */
1461     		result = mtiocrdftseg(&krnl_arg.mtftseg, arg_size);
1462     		break;
1463     #endif
1464     #ifdef MTIOCWRFTSEG
1465     	case MTIOCWRFTSEG: /* write a segment via ioctl */
1466     		result = mtiocwrftseg(&krnl_arg.mtftseg, arg_size);
1467     		break;
1468     #endif
1469     #ifdef MTIOCGETSIZE
1470     	case MTIOCGETSIZE:
1471     		result = mtiocgetsize(&krnl_arg.mttapesize, arg_size);
1472     		break;
1473     #endif
1474     #ifdef MTIOCFTFORMAT
1475     	case MTIOCFTFORMAT:
1476     		result = mtiocftformat(&krnl_arg.mtftformat, arg_size);
1477     		break;
1478     #endif
1479     #ifdef MTIOCFTCMD
1480     	case MTIOCFTCMD:
1481     		result = mtiocftcmd(&krnl_arg.mtftcmd, arg_size);
1482     		break;
1483     #endif
1484     	default:
1485     		result = -EINVAL;
1486     		break;
1487     	}
1488     	if ((result >= 0) && (dir & _IOC_READ)) {
1489     #if LINUX_VERSION_CODE > KERNEL_VER(2,1,3)
1490     		if (copy_to_user(arg, &krnl_arg, arg_size) != 0) {
1491     			TRACE_EXIT -EFAULT;
1492     		}
1493     #else
1494     		TRACE_CATCH(verify_area(VERIFY_WRITE, arg, arg_size),);
1495     		memcpy_tofs(arg, &krnl_arg, arg_size);
1496     #endif
1497     	}
1498     	TRACE_EXIT result;
1499     }
1500