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