2 * Copyright (C) 1996, 1997 Claus-Justus Heine
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)
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.
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.
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 $
23 * This file contains the non-read/write zftape functions
24 * for the QIC-40/80/3010/3020 floppy-tape driver for Linux.
27 #include <linux/config.h>
28 #include <linux/errno.h>
30 #include <linux/module.h>
31 #include <linux/fcntl.h>
33 #include <linux/zftape.h>
35 #include <asm/uaccess.h>
37 #include "../zftape/zftape-init.h"
38 #include "../zftape/zftape-eof.h"
39 #include "../zftape/zftape-ctl.h"
40 #include "../zftape/zftape-write.h"
41 #include "../zftape/zftape-read.h"
42 #include "../zftape/zftape-rw.h"
43 #include "../zftape/zftape-vtbl.h"
47 int zft_write_protected
; /* this is when cartridge rdonly or O_RDONLY */
50 unsigned int zft_unit
;
52 int zft_mt_compression
;
56 static int going_offline
;
58 typedef int (mt_fun
)(int *argptr
);
59 typedef int (*mt_funp
)(int *argptr
);
63 unsigned offline
: 1; /* op permitted if offline or no_tape */
64 unsigned write_protected
: 1; /* op permitted if write-protected */
65 unsigned not_formatted
: 1; /* op permitted if tape not formatted */
66 unsigned raw_mode
: 1; /* op permitted if zft_mode == 0 */
67 unsigned need_idle_state
: 1; /* need to call def_idle_state */
71 static mt_fun mt_dummy
, mt_reset
, mt_fsr
, mt_bsr
, mt_rew
, mt_offl
, mt_nop
,
72 mt_weof
, mt_erase
, mt_ras2
, mt_setblk
, mt_setdensity
,
73 mt_seek
, mt_tell
, mt_reten
, mt_eom
, mt_fsf
, mt_bsf
,
74 mt_fsfm
, mt_bsfm
, mt_setdrvbuffer
, mt_compression
;
76 static fun_entry mt_funs
[]=
78 {mt_reset
, 1, 1, 1, 1, 0, "MT_RESET" }, /* 0 */
79 {mt_fsf
, 0, 1, 0, 0, 1, "MT_FSF" },
80 {mt_bsf
, 0, 1, 0, 0, 1, "MT_BSF" },
81 {mt_fsr
, 0, 1, 0, 1, 1, "MT_FSR" },
82 {mt_bsr
, 0, 1, 0, 1, 1, "MT_BSR" },
83 {mt_weof
, 0, 0, 0, 0, 0, "MT_WEOF" }, /* 5 */
84 {mt_rew
, 0, 1, 1, 1, 0, "MT_REW" },
85 {mt_offl
, 0, 1, 1, 1, 0, "MT_OFFL" },
86 {mt_nop
, 1, 1, 1, 1, 0, "MT_NOP" },
87 {mt_reten
, 0, 1, 1, 1, 0, "MT_RETEN" },
88 {mt_bsfm
, 0, 1, 0, 0, 1, "MT_BSFM" }, /* 10 */
89 {mt_fsfm
, 0, 1, 0, 0, 1, "MT_FSFM" },
90 {mt_eom
, 0, 1, 0, 0, 1, "MT_EOM" },
91 {mt_erase
, 0, 0, 0, 1, 0, "MT_ERASE" },
92 {mt_dummy
, 1, 1, 1, 1, 0, "MT_RAS1" },
93 {mt_ras2
, 0, 0, 0, 1, 0, "MT_RAS2" },
94 {mt_dummy
, 1, 1, 1, 1, 0, "MT_RAS3" },
95 {mt_dummy
, 1, 1, 1, 1, 0, "UNKNOWN" },
96 {mt_dummy
, 1, 1, 1, 1, 0, "UNKNOWN" },
97 {mt_dummy
, 1, 1, 1, 1, 0, "UNKNOWN" },
98 {mt_setblk
, 1, 1, 1, 1, 1, "MT_SETBLK"}, /* 20 */
99 {mt_setdensity
, 1, 1, 1, 1, 0, "MT_SETDENSITY"},
100 {mt_seek
, 0, 1, 0, 1, 1, "MT_SEEK" },
101 {mt_dummy
, 0, 1, 0, 1, 1, "MT_TELL" }, /* wr-only ?! */
102 {mt_setdrvbuffer
, 1, 1, 1, 1, 0, "MT_SETDRVBUFFER" },
103 {mt_dummy
, 1, 1, 1, 1, 0, "MT_FSS" }, /* 25 */
104 {mt_dummy
, 1, 1, 1, 1, 0, "MT_BSS" },
105 {mt_dummy
, 1, 1, 1, 1, 0, "MT_WSM" },
106 {mt_dummy
, 1, 1, 1, 1, 0, "MT_LOCK" },
107 {mt_dummy
, 1, 1, 1, 1, 0, "MT_UNLOCK"},
108 {mt_dummy
, 1, 1, 1, 1, 0, "MT_LOAD" }, /* 30 */
109 {mt_dummy
, 1, 1, 1, 1, 0, "MT_UNLOAD"},
110 {mt_compression
, 1, 1, 1, 0, 1, "MT_COMPRESSION"},
111 {mt_dummy
, 1, 1, 1, 1, 0, "MT_SETPART"},
112 {mt_dummy
, 1, 1, 1, 1, 0, "MT_MKPART"}
115 #define NR_MT_CMDS NR_ITEMS(mt_funs)
117 void zft_reset_position(zft_position
*pos
)
119 TRACE_FUN(ft_t_flow
);
123 if (zft_header_read
) {
124 /* need to keep track of the volume table and
125 * compression map. We therefor simply
126 * position at the beginning of the first
127 * volume. This covers old ftape archives as
128 * well has various flavours of the
129 * compression map segments. The worst case is
130 * that the compression map shows up as a
131 * additional volume in front of all others.
133 pos
->seg_pos
= zft_find_volume(0)->start_seg
;
134 pos
->tape_pos
= zft_calc_tape_pos(pos
->seg_pos
);
139 zft_just_before_eof
= 0;
140 zft_deblock_segment
= -1;
141 zft_io_state
= zft_idle
;
142 zft_zap_read_buffers();
144 /* unlock the compresison module if it is loaded.
145 * The zero arg means not to try to load the module.
147 if (zft_cmpr_lock(0) == 0) {
148 (*zft_cmpr_ops
->reset
)(); /* unlock */
153 static void zft_init_driver(void)
155 TRACE_FUN(ft_t_flow
);
161 zft_write_protected
=
165 zft_volume_table_changed
=
166 zft_written_segments
= 0;
167 zft_blk_sz
= CONFIG_ZFT_DFLT_BLK_SZ
;
168 zft_reset_position(&zft_pos
); /* does most of the stuff */
169 ftape_zap_read_buffers();
170 ftape_set_state(idle
);
174 int zft_def_idle_state(void)
177 TRACE_FUN(ft_t_flow
);
179 if (!zft_header_read
) {
180 result
= zft_read_header_segments();
181 } else if ((result
= zft_flush_buffers()) >= 0 && zft_qic_mode
) {
182 /* don't move past eof
184 (void)zft_close_volume(&zft_pos
);
186 if (ftape_abort_operation() < 0) {
187 TRACE(ft_t_warn
, "ftape_abort_operation() failed");
190 /* clear remaining read buffers */
191 zft_zap_read_buffers();
192 zft_io_state
= zft_idle
;
196 /*****************************************************************************
198 * functions for the MTIOCTOP commands *
200 *****************************************************************************/
202 static int mt_dummy(int *dummy
)
204 TRACE_FUN(ft_t_flow
);
209 static int mt_reset(int *dummy
)
211 TRACE_FUN(ft_t_flow
);
213 (void)ftape_seek_to_bot();
214 TRACE_CATCH(ftape_reset_drive(),
215 zft_init_driver(); zft_uninit_mem(); zft_offline
= 1);
216 /* fake a re-open of the device. This will set all flage and
217 * allocate buffers as appropriate. The new tape condition will
218 * force the open routine to do anything we need.
220 TRACE_CATCH(_zft_open(-1 /* fake reopen */, 0 /* dummy */),);
224 static int mt_fsf(int *arg
)
227 TRACE_FUN(ft_t_flow
);
229 result
= zft_skip_volumes(*arg
, &zft_pos
);
230 zft_just_before_eof
= 0;
234 static int mt_bsf(int *arg
)
237 TRACE_FUN(ft_t_flow
);
240 result
= zft_skip_volumes(-*arg
+ 1, &zft_pos
);
245 static int seek_block(__s64 data_offset
,
246 __s64 block_increment
,
251 __s64 vol_block_count
;
252 const zft_volinfo
*volume
;
254 TRACE_FUN(ft_t_flow
);
256 volume
= zft_find_volume(pos
->seg_pos
);
257 if (volume
->start_seg
== 0 || volume
->end_seg
== 0) {
260 new_block_pos
= (zft_div_blksz(data_offset
, volume
->blk_sz
)
262 vol_block_count
= zft_div_blksz(volume
->size
, volume
->blk_sz
);
263 if (new_block_pos
< 0) {
265 "new_block_pos " LL_X
" < 0", LL(new_block_pos
));
266 zft_resid
= (int)new_block_pos
;
269 } else if (new_block_pos
> vol_block_count
) {
271 "new_block_pos " LL_X
" exceeds size of volume " LL_X
,
272 LL(new_block_pos
), LL(vol_block_count
));
273 zft_resid
= (int)(vol_block_count
- new_block_pos
);
274 new_block_pos
= vol_block_count
;
279 if (zft_use_compression
&& volume
->use_compression
) {
280 TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
281 result
= (*zft_cmpr_ops
->seek
)(new_block_pos
, pos
, volume
,
283 pos
->tape_pos
= zft_calc_tape_pos(pos
->seg_pos
);
284 pos
->tape_pos
+= pos
->seg_byte_pos
;
286 pos
->volume_pos
= zft_mul_blksz(new_block_pos
, volume
->blk_sz
);
287 pos
->tape_pos
= zft_calc_tape_pos(volume
->start_seg
);
288 pos
->tape_pos
+= pos
->volume_pos
;
289 pos
->seg_pos
= zft_calc_seg_byte_coord(&pos
->seg_byte_pos
,
292 zft_just_before_eof
= volume
->size
== pos
->volume_pos
;
293 if (zft_just_before_eof
) {
294 /* why this? because zft_file_no checks agains start
295 * and end segment of a volume. We do not want to
296 * advance to the next volume with this function.
298 TRACE(ft_t_noise
, "set zft_just_before_eof");
299 zft_position_before_eof(pos
, volume
);
301 TRACE(ft_t_noise
, "\n"
302 KERN_INFO
"new_seg_pos : %d\n"
303 KERN_INFO
"new_tape_pos: " LL_X
"\n"
304 KERN_INFO
"vol_size : " LL_X
"\n"
305 KERN_INFO
"seg_byte_pos: %d\n"
306 KERN_INFO
"blk_sz : %d",
307 pos
->seg_pos
, LL(pos
->tape_pos
),
308 LL(volume
->size
), pos
->seg_byte_pos
,
311 zft_resid
= new_block_pos
- zft_div_blksz(pos
->volume_pos
,
315 zft_resid
= -zft_resid
;
317 TRACE_EXIT ((exceed
|| zft_resid
!= 0) && result
>= 0) ? -EINVAL
: result
;
320 static int mt_fsr(int *arg
)
323 TRACE_FUN(ft_t_flow
);
325 result
= seek_block(zft_pos
.volume_pos
, *arg
, &zft_pos
);
329 static int mt_bsr(int *arg
)
332 TRACE_FUN(ft_t_flow
);
334 result
= seek_block(zft_pos
.volume_pos
, -*arg
, &zft_pos
);
338 static int mt_weof(int *arg
)
341 TRACE_FUN(ft_t_flow
);
343 TRACE_CATCH(zft_flush_buffers(),);
344 result
= zft_weof(*arg
, &zft_pos
);
348 static int mt_rew(int *dummy
)
351 TRACE_FUN(ft_t_flow
);
353 if(zft_header_read
) {
354 (void)zft_def_idle_state();
356 result
= ftape_seek_to_bot();
357 zft_reset_position(&zft_pos
);
361 static int mt_offl(int *dummy
)
364 TRACE_FUN(ft_t_flow
);
367 result
= mt_rew(NULL
);
371 static int mt_nop(int *dummy
)
373 TRACE_FUN(ft_t_flow
);
374 /* should we set tape status?
376 if (!zft_offline
) { /* offline includes no_tape */
377 (void)zft_def_idle_state();
382 static int mt_reten(int *dummy
)
385 TRACE_FUN(ft_t_flow
);
387 if(zft_header_read
) {
388 (void)zft_def_idle_state();
390 result
= ftape_seek_to_eot();
392 result
= ftape_seek_to_bot();
397 static int fsfbsfm(int arg
, zft_position
*pos
)
399 const zft_volinfo
*vtbl
;
401 TRACE_FUN(ft_t_flow
);
403 /* What to do? This should seek to the next file-mark and
404 * position BEFORE. That is, a next write would just extend
405 * the current file. Well. Let's just seek to the end of the
406 * current file, if count == 1. If count > 1, then do a
407 * "mt_fsf(count - 1)", and then seek to the end of that file.
408 * If count == 0, do nothing
413 zft_just_before_eof
= 0;
414 TRACE_CATCH(zft_skip_volumes(arg
< 0 ? arg
: arg
-1, pos
),
418 vtbl
= zft_find_volume(pos
->seg_pos
);
419 block_pos
= zft_div_blksz(vtbl
->size
, vtbl
->blk_sz
);
420 (void)seek_block(0, block_pos
, pos
);
421 if (pos
->volume_pos
!= vtbl
->size
) {
422 zft_just_before_eof
= 0;
424 /* we didn't managed to go there */
425 TRACE_ABORT(-EIO
, ft_t_err
,
426 "wanted file position " LL_X
", arrived at " LL_X
,
427 LL(vtbl
->size
), LL(pos
->volume_pos
));
429 zft_just_before_eof
= 1;
433 static int mt_bsfm(int *arg
)
436 TRACE_FUN(ft_t_flow
);
438 result
= fsfbsfm(-*arg
, &zft_pos
);
442 static int mt_fsfm(int *arg
)
445 TRACE_FUN(ft_t_flow
);
447 result
= fsfbsfm(*arg
, &zft_pos
);
451 static int mt_eom(int *dummy
)
453 TRACE_FUN(ft_t_flow
);
455 zft_skip_to_eom(&zft_pos
);
459 static int mt_erase(int *dummy
)
462 TRACE_FUN(ft_t_flow
);
464 result
= zft_erase();
468 static int mt_ras2(int *dummy
)
471 TRACE_FUN(ft_t_flow
);
477 /* Sets the new blocksize in BYTES
480 static int mt_setblk(int *new_size
)
482 TRACE_FUN(ft_t_flow
);
484 if((unsigned int)(*new_size
) > ZFT_MAX_BLK_SZ
) {
485 TRACE_ABORT(-EINVAL
, ft_t_info
,
486 "desired blk_sz (%d) should be <= %d bytes",
487 *new_size
, ZFT_MAX_BLK_SZ
);
489 if ((*new_size
& (FT_SECTOR_SIZE
-1)) != 0) {
490 TRACE_ABORT(-EINVAL
, ft_t_info
,
491 "desired blk_sz (%d) must be a multiple of %d bytes",
492 *new_size
, FT_SECTOR_SIZE
);
494 if (*new_size
== 0) {
495 if (zft_use_compression
) {
496 TRACE_ABORT(-EINVAL
, ft_t_info
,
497 "Variable block size not yet "
498 "supported with compression");
502 zft_blk_sz
= *new_size
;
506 static int mt_setdensity(int *arg
)
508 TRACE_FUN(ft_t_flow
);
510 SET_TRACE_LEVEL(*arg
);
511 TRACE(TRACE_LEVEL
, "tracing set to %d", TRACE_LEVEL
);
512 if ((int)TRACE_LEVEL
!= *arg
) {
518 static int mt_seek(int *new_block_pos
)
523 result
= seek_block(0, (__s64
)*new_block_pos
, &zft_pos
);
527 /* OK, this is totally different from SCSI, but the worst thing that can
528 * happen is that there is not enough defragmentated memory that can be
529 * allocated. Also, there is a hardwired limit of 16 dma buffers in the
530 * stock ftape module. This shouldn't bring the system down.
532 * NOTE: the argument specifies the total number of dma buffers to use.
533 * The driver needs at least 3 buffers to function at all.
536 static int mt_setdrvbuffer(int *cnt
)
538 TRACE_FUN(ft_t_flow
);
543 TRACE_CATCH(ftape_set_nr_buffers(*cnt
),);
546 /* return the block position from start of volume
548 static int mt_tell(int *arg
)
550 TRACE_FUN(ft_t_flow
);
552 *arg
= zft_div_blksz(zft_pos
.volume_pos
,
553 zft_find_volume(zft_pos
.seg_pos
)->blk_sz
);
557 static int mt_compression(int *arg
)
559 TRACE_FUN(ft_t_flow
);
561 /* Ok. We could also check whether compression is available at
562 * all by trying to load the compression module. We could
563 * also check for a block size of 1 byte which is illegal
564 * with compression. Instead of doing it here we rely on
565 * zftape_write() to do the proper checks.
567 if ((unsigned int)*arg
> 1) {
570 if (*arg
!= 0 && zft_blk_sz
== 1) { /* variable block size */
571 TRACE_ABORT(-EINVAL
, ft_t_info
,
572 "Compression not yet supported "
573 "with variable block size");
575 zft_mt_compression
= *arg
;
576 if ((zft_unit
& ZFT_ZIP_MODE
) == 0) {
577 zft_use_compression
= zft_mt_compression
;
582 /* check whether write access is allowed. Write access is denied when
583 * + zft_write_protected == 1 -- this accounts for either hard write
584 * protection of the cartridge or for
585 * O_RDONLY access mode of the tape device
586 * + zft_offline == 1 -- this meany that there is either no tape
587 * or that the MTOFFLINE ioctl has been
588 * previously issued (`soft eject')
589 * + ft_formatted == 0 -- this means that the cartridge is not
591 * Then we distinuguish two cases. When zft_qic_mode is TRUE, then we try
592 * to emulate a `traditional' (aka SCSI like) UN*X tape device. Therefore we
594 * + zft_qic_mode ==1 &&
595 * (!zft_tape_at_lbot() && -- tape no at logical BOT
596 * !(zft_tape_at_eom() || -- tape not at logical EOM (or EOD)
597 * (zft_tape_at_eom() &&
598 * zft_old_ftape()))) -- we can't add new volume to tapes
599 * written by old ftape because ftape
600 * don't use the volume table
602 * when the drive is in true raw mode (aka /dev/rawft0) then we don't
603 * care about LBOT and EOM conditions. This device is intended for a
604 * user level program that wants to truly implement the QIC-80 compliance
605 * at the logical data layout level of the cartridge, i.e. implement all
606 * that volume table and volume directory stuff etc.<
608 int zft_check_write_access(zft_position
*pos
)
610 TRACE_FUN(ft_t_flow
);
612 if (zft_offline
) { /* offline includes no_tape */
614 ft_t_info
, "tape is offline or no cartridge");
617 TRACE_ABORT(-EACCES
, ft_t_info
, "tape is not formatted");
619 if (zft_write_protected
) {
620 TRACE_ABORT(-EACCES
, ft_t_info
, "cartridge write protected");
623 /* check BOT condition */
624 if (!zft_tape_at_lbot(pos
)) {
625 /* protect cartridges written by old ftape if
626 * not at BOT because they use the vtbl
627 * segment for storing data
630 TRACE_ABORT(-EACCES
, ft_t_warn
,
631 "Cannot write to cartridges written by old ftape when not at BOT");
633 /* not at BOT, but allow writes at EOD, of course
635 if (!zft_tape_at_eod(pos
)) {
636 TRACE_ABORT(-EACCES
, ft_t_info
,
637 "tape not at BOT and not at EOD");
640 /* fine. Now the tape is either at BOT or at EOD. */
642 /* or in raw mode in which case we don't care about BOT and EOD */
646 /* OPEN routine called by kernel-interface code
648 * NOTE: this is also called by mt_reset() with dev_minor == -1
649 * to fake a reopen after a reset.
651 int _zft_open(unsigned int dev_minor
, unsigned int access_mode
)
653 static unsigned int tape_unit
;
654 static unsigned int file_access_mode
;
656 TRACE_FUN(ft_t_flow
);
658 if ((int)dev_minor
== -1) {
660 zft_unit
= tape_unit
;
661 access_mode
= file_access_mode
;
662 zft_init_driver(); /* reset all static data to defaults */
664 tape_unit
= dev_minor
;
665 file_access_mode
= access_mode
;
666 if ((result
= ftape_enable(FTAPE_SEL(dev_minor
))) < 0) {
667 TRACE_ABORT(-ENXIO
, ft_t_err
,
668 "ftape_enable failed: %d", result
);
670 if (ft_new_tape
|| ft_no_tape
|| !ft_formatted
||
671 (FTAPE_SEL(zft_unit
) != FTAPE_SEL(dev_minor
)) ||
672 (zft_unit
& ZFT_RAW_MODE
) != (dev_minor
& ZFT_RAW_MODE
)) {
673 /* reset all static data to defaults,
677 zft_unit
= dev_minor
;
679 zft_set_flags(zft_unit
); /* decode the minor bits */
680 if (zft_blk_sz
== 1 && zft_use_compression
) {
681 ftape_disable(); /* resets ft_no_tape */
682 TRACE_ABORT(-ENODEV
, ft_t_warn
, "Variable block size not yet "
683 "supported with compression");
685 /* no need for most of the buffers when no tape or not
686 * formatted. for the read/write operations, it is the
687 * regardless whether there is no tape, a not-formatted tape
688 * or the whether the driver is soft offline.
689 * Nevertheless we allow some ioctls with non-formatted tapes,
690 * like rewind and reset.
692 if (ft_no_tape
|| !ft_formatted
) {
696 zft_offline
= 1; /* so we need not test two variables */
698 if ((access_mode
== O_WRONLY
|| access_mode
== O_RDWR
) &&
699 (ft_write_protected
|| ft_no_tape
)) {
700 ftape_disable(); /* resets ft_no_tape */
701 TRACE_ABORT(ft_no_tape
? -ENXIO
: -EROFS
,
702 ft_t_warn
, "wrong access mode %s cartridge",
703 ft_no_tape
? "without a" : "with write protected");
705 zft_write_protected
= (access_mode
== O_RDONLY
||
706 ft_write_protected
!= 0);
707 if (zft_write_protected
) {
709 "read only access mode: %d, "
710 "drive write protected: %d",
711 access_mode
== O_RDONLY
,
712 ft_write_protected
!= 0);
715 TRACE_CATCH(zft_vmalloc_once(&zft_deblock_buf
,FT_SEGMENT_SIZE
),
718 /* zft_seg_pos should be greater than the vtbl segpos but not
719 * if in compatibility mode and only after we read in the
722 * might also be a problem if the user makes a backup with a
723 * *qft* device and rewinds it with a raw device.
727 zft_pos
.seg_pos
>= 0 &&
729 zft_pos
.seg_pos
<= ft_first_data_segment
) {
730 TRACE(ft_t_noise
, "you probably mixed up the zftape devices!");
731 zft_reset_position(&zft_pos
);
736 /* RELEASE routine called by kernel-interface code
741 TRACE_FUN(ft_t_flow
);
744 /* call the hardware release routine. Puts the drive offline */
748 if (!(ft_write_protected
|| zft_old_ftape
)) {
749 result
= zft_flush_buffers();
750 TRACE(ft_t_noise
, "writing file mark at current position");
751 if (zft_qic_mode
&& zft_close_volume(&zft_pos
) == 0) {
752 zft_move_past_eof(&zft_pos
);
754 if ((zft_tape_at_lbot(&zft_pos
) ||
755 !(zft_unit
& FTAPE_NO_REWIND
))) {
757 result
= zft_update_header_segments();
760 "Error: unable to update header segments");
764 ftape_abort_operation();
765 if (!(zft_unit
& FTAPE_NO_REWIND
)) {
766 TRACE(ft_t_noise
, "rewinding tape");
767 if (ftape_seek_to_bot() < 0 && result
>= 0) {
768 result
= -EIO
; /* keep old value */
770 zft_reset_position(&zft_pos
);
772 zft_zap_read_buffers();
773 /* now free up memory as much as possible. We don't destroy
774 * the deblock buffer if it containes a valid segment.
776 if (zft_deblock_segment
== -1) {
777 zft_vfree(&zft_deblock_buf
, FT_SEGMENT_SIZE
);
779 /* high level driver status, forces creation of a new volume
780 * when calling ftape_write again and not zft_just_before_eof
782 zft_io_state
= zft_idle
;
788 } else if (zft_cmpr_lock(0 /* don't load */) == 0) {
789 (*zft_cmpr_ops
->reset
)(); /* unlock it again */
792 /* call the hardware release routine. Puts the drive offline */
798 * the wrapper function around the wrapper MTIOCTOP ioctl
800 static int mtioctop(struct mtop
*mtop
, int arg_size
)
803 fun_entry
*mt_fun_entry
;
804 TRACE_FUN(ft_t_flow
);
806 if (arg_size
!= sizeof(struct mtop
) || mtop
->mt_op
>= NR_MT_CMDS
) {
809 TRACE(ft_t_noise
, "calling MTIOCTOP command: %s",
810 mt_funs
[mtop
->mt_op
].name
);
811 mt_fun_entry
= &mt_funs
[mtop
->mt_op
];
812 zft_resid
= mtop
->mt_count
;
813 if (!mt_fun_entry
->offline
&& zft_offline
) {
815 TRACE_ABORT(-ENXIO
, ft_t_info
, "no tape present");
817 TRACE_ABORT(-ENXIO
, ft_t_info
, "drive is offline");
820 if (!mt_fun_entry
->not_formatted
&& !ft_formatted
) {
821 TRACE_ABORT(-EACCES
, ft_t_info
, "tape is not formatted");
823 if (!mt_fun_entry
->write_protected
) {
824 TRACE_CATCH(zft_check_write_access(&zft_pos
),);
826 if (mt_fun_entry
->need_idle_state
&& !(zft_offline
|| !ft_formatted
)) {
827 TRACE_CATCH(zft_def_idle_state(),);
829 if (!zft_qic_mode
&& !mt_fun_entry
->raw_mode
) {
830 TRACE_ABORT(-EACCES
, ft_t_info
,
831 "Drive needs to be in QIC-80 compatibility mode for this command");
833 result
= (mt_fun_entry
->function
)(&mtop
->mt_count
);
834 if (zft_tape_at_lbot(&zft_pos
)) {
835 TRACE_CATCH(zft_update_header_segments(),);
844 * standard MTIOCGET ioctl
846 static int mtiocget(struct mtget
*mtget
, int arg_size
)
848 const zft_volinfo
*volume
;
850 TRACE_FUN(ft_t_flow
);
852 if (arg_size
!= sizeof(struct mtget
)) {
853 TRACE_ABORT(-EINVAL
, ft_t_info
, "bad argument size: %d",
856 mtget
->mt_type
= ft_drive_type
.vendor_id
+ 0x800000;
857 mtget
->mt_dsreg
= ft_last_status
.space
;
858 mtget
->mt_erreg
= ft_last_error
.space
; /* error register */
859 mtget
->mt_resid
= zft_resid
; /* residuum of writes, reads and
862 if (!zft_offline
) { /* neither no_tape nor soft offline */
863 mtget
->mt_gstat
= GMT_ONLINE(~0UL);
864 /* should rather return the status of the cartridge
865 * than the access mode of the file, therefor use
866 * ft_write_protected, not zft_write_protected
868 if (ft_write_protected
) {
869 mtget
->mt_gstat
|= GMT_WR_PROT(~0UL);
871 if(zft_header_read
) { /* this catches non-formatted */
872 volume
= zft_find_volume(zft_pos
.seg_pos
);
873 mtget
->mt_fileno
= volume
->count
;
874 max_tape_pos
= zft_capacity
- zft_blk_sz
;
875 if (zft_use_compression
) {
876 max_tape_pos
-= ZFT_CMPR_OVERHEAD
;
878 if (zft_tape_at_eod(&zft_pos
)) {
879 mtget
->mt_gstat
|= GMT_EOD(~0UL);
881 if (zft_pos
.tape_pos
> max_tape_pos
) {
882 mtget
->mt_gstat
|= GMT_EOT(~0UL);
884 mtget
->mt_blkno
= zft_div_blksz(zft_pos
.volume_pos
,
886 if (zft_just_before_eof
) {
887 mtget
->mt_gstat
|= GMT_EOF(~0UL);
889 if (zft_tape_at_lbot(&zft_pos
)) {
890 mtget
->mt_gstat
|= GMT_BOT(~0UL);
893 mtget
->mt_fileno
= mtget
->mt_blkno
= -1;
894 if (mtget
->mt_dsreg
& QIC_STATUS_AT_BOT
) {
895 mtget
->mt_gstat
|= GMT_BOT(~0UL);
900 mtget
->mt_gstat
= GMT_DR_OPEN(~0UL);
902 mtget
->mt_gstat
= 0UL;
904 mtget
->mt_fileno
= mtget
->mt_blkno
= -1;
911 * Read a floppy tape segment. This is useful for manipulating the
912 * volume table, and read the old header segment before re-formatting
915 static int mtiocrdftseg(struct mtftseg
* mtftseg
, int arg_size
)
917 TRACE_FUN(ft_t_flow
);
919 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCRDFTSEG");
921 TRACE_ABORT(-EACCES
, ft_t_info
,
922 "driver needs to be in raw mode for this ioctl");
924 if (arg_size
!= sizeof(struct mtftseg
)) {
925 TRACE_ABORT(-EINVAL
, ft_t_info
, "bad argument size: %d",
931 if (mtftseg
->mt_mode
!= FT_RD_SINGLE
&&
932 mtftseg
->mt_mode
!= FT_RD_AHEAD
) {
933 TRACE_ABORT(-EINVAL
, ft_t_info
, "invalid read mode");
936 TRACE_EXIT
-EACCES
; /* -ENXIO ? */
939 if (!zft_header_read
) {
940 TRACE_CATCH(zft_def_idle_state(),);
942 if (mtftseg
->mt_segno
> ft_last_data_segment
) {
943 TRACE_ABORT(-EINVAL
, ft_t_info
, "segment number is too large");
945 mtftseg
->mt_result
= ftape_read_segment(mtftseg
->mt_segno
,
948 if (mtftseg
->mt_result
< 0) {
949 /* a negativ result is not an ioctl error. if
950 * the user wants to read damaged tapes,
955 if (copy_to_user(mtftseg
->mt_data
,
957 mtftseg
->mt_result
) != 0) {
966 * write a floppy tape segment. This version features writing of
967 * deleted address marks, and gracefully ignores the (software)
968 * ft_formatted flag to support writing of header segments after
971 static int mtiocwrftseg(struct mtftseg
* mtftseg
, int arg_size
)
974 TRACE_FUN(ft_t_flow
);
976 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCWRFTSEG");
977 if (zft_write_protected
|| zft_qic_mode
) {
980 if (arg_size
!= sizeof(struct mtftseg
)) {
981 TRACE_ABORT(-EINVAL
, ft_t_info
, "bad argument size: %d",
987 if (mtftseg
->mt_mode
!= FT_WR_ASYNC
&&
988 mtftseg
->mt_mode
!= FT_WR_MULTI
&&
989 mtftseg
->mt_mode
!= FT_WR_SINGLE
&&
990 mtftseg
->mt_mode
!= FT_WR_DELETE
) {
991 TRACE_ABORT(-EINVAL
, ft_t_info
, "invalid write mode");
994 * We don't check for ft_formatted, because this gives
995 * only the software status of the driver.
997 * We assume that the user knows what it is
998 * doing. And rely on the low level stuff to fail
999 * when the tape isn't formatted. We only make sure
1000 * that The header segment buffer is allocated,
1001 * because it holds the bad sector map.
1003 if (zft_hseg_buf
== NULL
) {
1006 if (mtftseg
->mt_mode
!= FT_WR_DELETE
) {
1007 if (copy_from_user(zft_deblock_buf
,
1009 FT_SEGMENT_SIZE
) != 0) {
1013 mtftseg
->mt_result
= ftape_write_segment(mtftseg
->mt_segno
,
1016 if (mtftseg
->mt_result
>= 0 && mtftseg
->mt_mode
== FT_WR_SINGLE
) {
1018 * a negativ result is not an ioctl error. if
1019 * the user wants to write damaged tapes,
1020 * it's up to her/him
1022 if ((result
= ftape_loop_until_writes_done()) < 0) {
1023 mtftseg
->mt_result
= result
;
1032 * get information about volume positioned at.
1034 static int mtiocvolinfo(struct mtvolinfo
*volinfo
, int arg_size
)
1036 const zft_volinfo
*volume
;
1037 TRACE_FUN(ft_t_flow
);
1039 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCVOLINFO");
1040 if (arg_size
!= sizeof(struct mtvolinfo
)) {
1041 TRACE_ABORT(-EINVAL
,
1042 ft_t_info
, "bad argument size: %d", arg_size
);
1047 if (!ft_formatted
) {
1050 TRACE_CATCH(zft_def_idle_state(),);
1051 volume
= zft_find_volume(zft_pos
.seg_pos
);
1052 volinfo
->mt_volno
= volume
->count
;
1053 volinfo
->mt_blksz
= volume
->blk_sz
== 1 ? 0 : volume
->blk_sz
;
1054 volinfo
->mt_size
= volume
->size
>> 10;
1055 volinfo
->mt_rawsize
= ((zft_calc_tape_pos(volume
->end_seg
+ 1) >> 10) -
1056 (zft_calc_tape_pos(volume
->start_seg
) >> 10));
1057 volinfo
->mt_cmpr
= volume
->use_compression
;
1063 static int mtioc_zftape_getblksz(struct mtblksz
*blksz
, int arg_size
)
1065 TRACE_FUN(ft_t_flow
);
1067 TRACE(ft_t_noise
, "\n"
1068 KERN_INFO
"Mag tape ioctl command: MTIOC_ZTAPE_GETBLKSZ\n"
1069 KERN_INFO
"This ioctl is here merely for compatibility.\n"
1070 KERN_INFO
"Please use MTIOCVOLINFO instead");
1071 if (arg_size
!= sizeof(struct mtblksz
)) {
1072 TRACE_ABORT(-EINVAL
,
1073 ft_t_info
, "bad argument size: %d", arg_size
);
1078 if (!ft_formatted
) {
1081 TRACE_CATCH(zft_def_idle_state(),);
1082 blksz
->mt_blksz
= zft_find_volume(zft_pos
.seg_pos
)->blk_sz
;
1089 * get the capacity of the tape cartridge.
1091 static int mtiocgetsize(struct mttapesize
*size
, int arg_size
)
1093 TRACE_FUN(ft_t_flow
);
1095 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOC_ZFTAPE_GETSIZE");
1096 if (arg_size
!= sizeof(struct mttapesize
)) {
1097 TRACE_ABORT(-EINVAL
,
1098 ft_t_info
, "bad argument size: %d", arg_size
);
1103 if (!ft_formatted
) {
1106 TRACE_CATCH(zft_def_idle_state(),);
1107 size
->mt_capacity
= (unsigned int)(zft_capacity
>>10);
1108 size
->mt_used
= (unsigned int)(zft_get_eom_pos()>>10);
1113 static int mtiocpos(struct mtpos
*mtpos
, int arg_size
)
1116 TRACE_FUN(ft_t_flow
);
1118 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCPOS");
1119 if (arg_size
!= sizeof(struct mtpos
)) {
1120 TRACE_ABORT(-EINVAL
,
1121 ft_t_info
, "bad argument size: %d", arg_size
);
1123 result
= mt_tell((int *)&mtpos
->mt_blkno
);
1127 #ifdef MTIOCFTFORMAT
1129 * formatting of floppy tape cartridges. This is intended to be used
1130 * together with the MTIOCFTCMD ioctl and the new mmap feature
1134 * This function uses ftape_decode_header_segment() to inform the low
1135 * level ftape module about the new parameters.
1137 * It erases the hseg_buf. The calling process must specify all
1138 * parameters to assure proper operation.
1140 * return values: -EINVAL - wrong argument size
1141 * -EINVAL - if ftape_decode_header_segment() failed.
1143 static int set_format_parms(struct ftfmtparms
*p
, __u8
*hseg_buf
)
1145 ft_trace_t old_level
= TRACE_LEVEL
;
1146 TRACE_FUN(ft_t_flow
);
1148 TRACE(ft_t_noise
, "MTIOCFTFORMAT operation FTFMT_SETPARMS");
1149 memset(hseg_buf
, 0, FT_SEGMENT_SIZE
);
1150 PUT4(hseg_buf
, FT_SIGNATURE
, FT_HSEG_MAGIC
);
1152 /* fill in user specified parameters
1154 hseg_buf
[FT_FMT_CODE
] = (__u8
)p
->ft_fmtcode
;
1155 PUT2(hseg_buf
, FT_SPT
, p
->ft_spt
);
1156 hseg_buf
[FT_TPC
] = (__u8
)p
->ft_tpc
;
1157 hseg_buf
[FT_FHM
] = (__u8
)p
->ft_fhm
;
1158 hseg_buf
[FT_FTM
] = (__u8
)p
->ft_ftm
;
1160 /* fill in sane defaults to make ftape happy.
1162 hseg_buf
[FT_FSM
] = (__u8
)128; /* 128 is hard wired all over ftape */
1163 if (p
->ft_fmtcode
== fmt_big
) {
1164 PUT4(hseg_buf
, FT_6_HSEG_1
, 0);
1165 PUT4(hseg_buf
, FT_6_HSEG_2
, 1);
1166 PUT4(hseg_buf
, FT_6_FRST_SEG
, 2);
1167 PUT4(hseg_buf
, FT_6_LAST_SEG
, p
->ft_spt
* p
->ft_tpc
- 1);
1169 PUT2(hseg_buf
, FT_HSEG_1
, 0);
1170 PUT2(hseg_buf
, FT_HSEG_2
, 1);
1171 PUT2(hseg_buf
, FT_FRST_SEG
, 2);
1172 PUT2(hseg_buf
, FT_LAST_SEG
, p
->ft_spt
* p
->ft_tpc
- 1);
1175 /* Synchronize with the low level module. This is particularly
1176 * needed for unformatted cartridges as the QIC std was previously
1177 * unknown BUT is needed to set data rate and to calculate timeouts.
1179 TRACE_CATCH(ftape_calibrate_data_rate(p
->ft_qicstd
&QIC_TAPE_STD_MASK
),
1182 /* The following will also recalcualte the timeouts for the tape
1183 * length and QIC std we want to format to.
1184 * abort with -EINVAL rather than -EIO
1186 SET_TRACE_LEVEL(ft_t_warn
);
1187 TRACE_CATCH(ftape_decode_header_segment(hseg_buf
),
1188 SET_TRACE_LEVEL(old_level
); _res
= -EINVAL
);
1189 SET_TRACE_LEVEL(old_level
);
1194 * Return the internal SOFTWARE status of the kernel driver. This does
1195 * NOT query the tape drive about its status.
1197 static int get_format_parms(struct ftfmtparms
*p
, __u8
*hseg_buffer
)
1199 TRACE_FUN(ft_t_flow
);
1201 TRACE(ft_t_noise
, "MTIOCFTFORMAT operation FTFMT_GETPARMS");
1202 p
->ft_qicstd
= ft_qic_std
;
1203 p
->ft_fmtcode
= ft_format_code
;
1204 p
->ft_fhm
= hseg_buffer
[FT_FHM
];
1205 p
->ft_ftm
= hseg_buffer
[FT_FTM
];
1206 p
->ft_spt
= ft_segments_per_track
;
1207 p
->ft_tpc
= ft_tracks_per_tape
;
1211 static int mtiocftformat(struct mtftformat
*mtftformat
, int arg_size
)
1214 union fmt_arg
*arg
= &mtftformat
->fmt_arg
;
1215 TRACE_FUN(ft_t_flow
);
1217 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCFTFORMAT");
1220 TRACE_ABORT(-ENXIO
, ft_t_info
, "no tape present");
1222 TRACE_ABORT(-ENXIO
, ft_t_info
, "drive is offline");
1226 TRACE_ABORT(-EACCES
, ft_t_info
,
1227 "driver needs to be in raw mode for this ioctl");
1229 if (zft_hseg_buf
== NULL
) {
1230 TRACE_CATCH(zft_vcalloc_once(&zft_hseg_buf
, FT_SEGMENT_SIZE
),);
1232 zft_header_read
= 0;
1233 switch(mtftformat
->fmt_op
) {
1234 case FTFMT_SET_PARMS
:
1235 TRACE_CATCH(set_format_parms(&arg
->fmt_parms
, zft_hseg_buf
),);
1237 case FTFMT_GET_PARMS
:
1238 TRACE_CATCH(get_format_parms(&arg
->fmt_parms
, zft_hseg_buf
),);
1240 case FTFMT_FORMAT_TRACK
:
1241 if ((ft_formatted
&& zft_check_write_access(&zft_pos
) < 0) ||
1242 (!ft_formatted
&& zft_write_protected
)) {
1243 TRACE_ABORT(-EACCES
, ft_t_info
, "Write access denied");
1245 TRACE_CATCH(ftape_format_track(arg
->fmt_track
.ft_track
,
1246 arg
->fmt_track
.ft_gap3
),);
1249 TRACE_CATCH(ftape_format_status(&arg
->fmt_status
.ft_segment
),);
1252 TRACE_CATCH(ftape_verify_segment(arg
->fmt_verify
.ft_segment
,
1253 (SectorMap
*)&arg
->fmt_verify
.ft_bsm
),);
1256 TRACE_ABORT(-EINVAL
, ft_t_err
, "Invalid format operation");
1264 * send a QIC-117 command to the drive, with optional timeouts,
1265 * parameter and result bits. This is intended to be used together
1266 * with the formatting ioctl.
1268 static int mtiocftcmd(struct mtftcmd
*ftcmd
, int arg_size
)
1271 TRACE_FUN(ft_t_flow
);
1273 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCFTCMD");
1274 if (!capable(CAP_SYS_ADMIN
)) {
1275 TRACE_ABORT(-EPERM
, ft_t_info
,
1276 "need CAP_SYS_ADMIN capability to send raw qic-117 commands");
1279 TRACE_ABORT(-EACCES
, ft_t_info
,
1280 "driver needs to be in raw mode for this ioctl");
1282 if (arg_size
!= sizeof(struct mtftcmd
)) {
1283 TRACE_ABORT(-EINVAL
,
1284 ft_t_info
, "bad argument size: %d", arg_size
);
1286 if (ftcmd
->ft_wait_before
) {
1287 TRACE_CATCH(ftape_ready_wait(ftcmd
->ft_wait_before
,
1288 &ftcmd
->ft_status
),);
1290 if (ftcmd
->ft_status
& QIC_STATUS_ERROR
)
1292 if (ftcmd
->ft_result_bits
!= 0) {
1293 TRACE_CATCH(ftape_report_operation(&ftcmd
->ft_result
,
1295 ftcmd
->ft_result_bits
),);
1297 TRACE_CATCH(ftape_command(ftcmd
->ft_cmd
),);
1298 if (ftcmd
->ft_status
& QIC_STATUS_ERROR
)
1300 for (i
= 0; i
< ftcmd
->ft_parm_cnt
; i
++) {
1301 TRACE_CATCH(ftape_parameter(ftcmd
->ft_parms
[i
]&0x0f),);
1302 if (ftcmd
->ft_status
& QIC_STATUS_ERROR
)
1306 if (ftcmd
->ft_wait_after
!= 0) {
1307 TRACE_CATCH(ftape_ready_wait(ftcmd
->ft_wait_after
,
1308 &ftcmd
->ft_status
),);
1311 if (ftcmd
->ft_status
& QIC_STATUS_ERROR
) {
1312 TRACE(ft_t_noise
, "error status set");
1313 TRACE_CATCH(ftape_report_error(&ftcmd
->ft_error
,
1314 &ftcmd
->ft_cmd
, 1),);
1316 TRACE_EXIT
0; /* this is not an i/o error */
1320 /* IOCTL routine called by kernel-interface code
1322 int _zft_ioctl(unsigned int command
, void __user
* arg
)
1325 union { struct mtop mtop
;
1329 struct mtftseg mtftseg
;
1332 struct mtvolinfo mtvolinfo
;
1335 struct mttapesize mttapesize
;
1337 #ifdef MTIOCFTFORMAT
1338 struct mtftformat mtftformat
;
1341 struct mtblksz mtblksz
;
1344 struct mtftcmd mtftcmd
;
1347 int arg_size
= _IOC_SIZE(command
);
1348 int dir
= _IOC_DIR(command
);
1349 TRACE_FUN(ft_t_flow
);
1351 /* This check will only catch arguments that are too large !
1353 if (dir
& (_IOC_READ
| _IOC_WRITE
) && arg_size
> sizeof(krnl_arg
)) {
1354 TRACE_ABORT(-EINVAL
,
1355 ft_t_info
, "bad argument size: %d", arg_size
);
1357 if (dir
& _IOC_WRITE
) {
1358 if (copy_from_user(&krnl_arg
, arg
, arg_size
) != 0) {
1362 TRACE(ft_t_flow
, "called with ioctl command: 0x%08x", command
);
1365 result
= mtioctop(&krnl_arg
.mtop
, arg_size
);
1368 result
= mtiocget(&krnl_arg
.mtget
, arg_size
);
1371 result
= mtiocpos(&krnl_arg
.mtpos
, arg_size
);
1375 result
= mtiocvolinfo(&krnl_arg
.mtvolinfo
, arg_size
);
1379 case MTIOC_ZFTAPE_GETBLKSZ
:
1380 result
= mtioc_zftape_getblksz(&krnl_arg
.mtblksz
, arg_size
);
1384 case MTIOCRDFTSEG
: /* read a segment via ioctl */
1385 result
= mtiocrdftseg(&krnl_arg
.mtftseg
, arg_size
);
1389 case MTIOCWRFTSEG
: /* write a segment via ioctl */
1390 result
= mtiocwrftseg(&krnl_arg
.mtftseg
, arg_size
);
1395 result
= mtiocgetsize(&krnl_arg
.mttapesize
, arg_size
);
1398 #ifdef MTIOCFTFORMAT
1400 result
= mtiocftformat(&krnl_arg
.mtftformat
, arg_size
);
1405 result
= mtiocftcmd(&krnl_arg
.mtftcmd
, arg_size
);
1412 if ((result
>= 0) && (dir
& _IOC_READ
)) {
1413 if (copy_to_user(arg
, &krnl_arg
, arg_size
) != 0) {