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/errno.h>
29 #include <linux/module.h>
30 #include <linux/fcntl.h>
32 #include <linux/zftape.h>
34 #include <asm/uaccess.h>
36 #include "../zftape/zftape-init.h"
37 #include "../zftape/zftape-eof.h"
38 #include "../zftape/zftape-ctl.h"
39 #include "../zftape/zftape-write.h"
40 #include "../zftape/zftape-read.h"
41 #include "../zftape/zftape-rw.h"
42 #include "../zftape/zftape-vtbl.h"
46 int zft_write_protected
; /* this is when cartridge rdonly or O_RDONLY */
49 unsigned int zft_unit
;
51 int zft_mt_compression
;
55 static int going_offline
;
57 typedef int (mt_fun
)(int *argptr
);
58 typedef int (*mt_funp
)(int *argptr
);
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 */
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
;
75 static fun_entry mt_funs
[]=
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"}
114 #define NR_MT_CMDS NR_ITEMS(mt_funs)
116 void zft_reset_position(zft_position
*pos
)
118 TRACE_FUN(ft_t_flow
);
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.
132 pos
->seg_pos
= zft_find_volume(0)->start_seg
;
133 pos
->tape_pos
= zft_calc_tape_pos(pos
->seg_pos
);
138 zft_just_before_eof
= 0;
139 zft_deblock_segment
= -1;
140 zft_io_state
= zft_idle
;
141 zft_zap_read_buffers();
143 /* unlock the compresison module if it is loaded.
144 * The zero arg means not to try to load the module.
146 if (zft_cmpr_lock(0) == 0) {
147 (*zft_cmpr_ops
->reset
)(); /* unlock */
152 static void zft_init_driver(void)
154 TRACE_FUN(ft_t_flow
);
160 zft_write_protected
=
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
);
173 int zft_def_idle_state(void)
176 TRACE_FUN(ft_t_flow
);
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
183 (void)zft_close_volume(&zft_pos
);
185 if (ftape_abort_operation() < 0) {
186 TRACE(ft_t_warn
, "ftape_abort_operation() failed");
189 /* clear remaining read buffers */
190 zft_zap_read_buffers();
191 zft_io_state
= zft_idle
;
195 /*****************************************************************************
197 * functions for the MTIOCTOP commands *
199 *****************************************************************************/
201 static int mt_dummy(int *dummy
)
203 TRACE_FUN(ft_t_flow
);
208 static int mt_reset(int *dummy
)
210 TRACE_FUN(ft_t_flow
);
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.
219 TRACE_CATCH(_zft_open(-1 /* fake reopen */, 0 /* dummy */),);
223 static int mt_fsf(int *arg
)
226 TRACE_FUN(ft_t_flow
);
228 result
= zft_skip_volumes(*arg
, &zft_pos
);
229 zft_just_before_eof
= 0;
233 static int mt_bsf(int *arg
)
236 TRACE_FUN(ft_t_flow
);
239 result
= zft_skip_volumes(-*arg
+ 1, &zft_pos
);
244 static int seek_block(__s64 data_offset
,
245 __s64 block_increment
,
250 __s64 vol_block_count
;
251 const zft_volinfo
*volume
;
253 TRACE_FUN(ft_t_flow
);
255 volume
= zft_find_volume(pos
->seg_pos
);
256 if (volume
->start_seg
== 0 || volume
->end_seg
== 0) {
259 new_block_pos
= (zft_div_blksz(data_offset
, volume
->blk_sz
)
261 vol_block_count
= zft_div_blksz(volume
->size
, volume
->blk_sz
);
262 if (new_block_pos
< 0) {
264 "new_block_pos " LL_X
" < 0", LL(new_block_pos
));
265 zft_resid
= (int)new_block_pos
;
268 } else if (new_block_pos
> vol_block_count
) {
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
;
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
,
282 pos
->tape_pos
= zft_calc_tape_pos(pos
->seg_pos
);
283 pos
->tape_pos
+= pos
->seg_byte_pos
;
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
,
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.
297 TRACE(ft_t_noise
, "set zft_just_before_eof");
298 zft_position_before_eof(pos
, volume
);
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
,
310 zft_resid
= new_block_pos
- zft_div_blksz(pos
->volume_pos
,
314 zft_resid
= -zft_resid
;
316 TRACE_EXIT ((exceed
|| zft_resid
!= 0) && result
>= 0) ? -EINVAL
: result
;
319 static int mt_fsr(int *arg
)
322 TRACE_FUN(ft_t_flow
);
324 result
= seek_block(zft_pos
.volume_pos
, *arg
, &zft_pos
);
328 static int mt_bsr(int *arg
)
331 TRACE_FUN(ft_t_flow
);
333 result
= seek_block(zft_pos
.volume_pos
, -*arg
, &zft_pos
);
337 static int mt_weof(int *arg
)
340 TRACE_FUN(ft_t_flow
);
342 TRACE_CATCH(zft_flush_buffers(),);
343 result
= zft_weof(*arg
, &zft_pos
);
347 static int mt_rew(int *dummy
)
350 TRACE_FUN(ft_t_flow
);
352 if(zft_header_read
) {
353 (void)zft_def_idle_state();
355 result
= ftape_seek_to_bot();
356 zft_reset_position(&zft_pos
);
360 static int mt_offl(int *dummy
)
363 TRACE_FUN(ft_t_flow
);
366 result
= mt_rew(NULL
);
370 static int mt_nop(int *dummy
)
372 TRACE_FUN(ft_t_flow
);
373 /* should we set tape status?
375 if (!zft_offline
) { /* offline includes no_tape */
376 (void)zft_def_idle_state();
381 static int mt_reten(int *dummy
)
384 TRACE_FUN(ft_t_flow
);
386 if(zft_header_read
) {
387 (void)zft_def_idle_state();
389 result
= ftape_seek_to_eot();
391 result
= ftape_seek_to_bot();
396 static int fsfbsfm(int arg
, zft_position
*pos
)
398 const zft_volinfo
*vtbl
;
400 TRACE_FUN(ft_t_flow
);
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
412 zft_just_before_eof
= 0;
413 TRACE_CATCH(zft_skip_volumes(arg
< 0 ? arg
: arg
-1, pos
),
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;
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
));
428 zft_just_before_eof
= 1;
432 static int mt_bsfm(int *arg
)
435 TRACE_FUN(ft_t_flow
);
437 result
= fsfbsfm(-*arg
, &zft_pos
);
441 static int mt_fsfm(int *arg
)
444 TRACE_FUN(ft_t_flow
);
446 result
= fsfbsfm(*arg
, &zft_pos
);
450 static int mt_eom(int *dummy
)
452 TRACE_FUN(ft_t_flow
);
454 zft_skip_to_eom(&zft_pos
);
458 static int mt_erase(int *dummy
)
461 TRACE_FUN(ft_t_flow
);
463 result
= zft_erase();
467 static int mt_ras2(int *dummy
)
470 TRACE_FUN(ft_t_flow
);
476 /* Sets the new blocksize in BYTES
479 static int mt_setblk(int *new_size
)
481 TRACE_FUN(ft_t_flow
);
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
);
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
);
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");
501 zft_blk_sz
= *new_size
;
505 static int mt_setdensity(int *arg
)
507 TRACE_FUN(ft_t_flow
);
509 SET_TRACE_LEVEL(*arg
);
510 TRACE(TRACE_LEVEL
, "tracing set to %d", TRACE_LEVEL
);
511 if ((int)TRACE_LEVEL
!= *arg
) {
517 static int mt_seek(int *new_block_pos
)
522 result
= seek_block(0, (__s64
)*new_block_pos
, &zft_pos
);
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.
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.
535 static int mt_setdrvbuffer(int *cnt
)
537 TRACE_FUN(ft_t_flow
);
542 TRACE_CATCH(ftape_set_nr_buffers(*cnt
),);
545 /* return the block position from start of volume
547 static int mt_tell(int *arg
)
549 TRACE_FUN(ft_t_flow
);
551 *arg
= zft_div_blksz(zft_pos
.volume_pos
,
552 zft_find_volume(zft_pos
.seg_pos
)->blk_sz
);
556 static int mt_compression(int *arg
)
558 TRACE_FUN(ft_t_flow
);
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.
566 if ((unsigned int)*arg
> 1) {
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");
574 zft_mt_compression
= *arg
;
575 if ((zft_unit
& ZFT_ZIP_MODE
) == 0) {
576 zft_use_compression
= zft_mt_compression
;
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
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
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
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.<
607 int zft_check_write_access(zft_position
*pos
)
609 TRACE_FUN(ft_t_flow
);
611 if (zft_offline
) { /* offline includes no_tape */
613 ft_t_info
, "tape is offline or no cartridge");
616 TRACE_ABORT(-EACCES
, ft_t_info
, "tape is not formatted");
618 if (zft_write_protected
) {
619 TRACE_ABORT(-EACCES
, ft_t_info
, "cartridge write protected");
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
629 TRACE_ABORT(-EACCES
, ft_t_warn
,
630 "Cannot write to cartridges written by old ftape when not at BOT");
632 /* not at BOT, but allow writes at EOD, of course
634 if (!zft_tape_at_eod(pos
)) {
635 TRACE_ABORT(-EACCES
, ft_t_info
,
636 "tape not at BOT and not at EOD");
639 /* fine. Now the tape is either at BOT or at EOD. */
641 /* or in raw mode in which case we don't care about BOT and EOD */
645 /* OPEN routine called by kernel-interface code
647 * NOTE: this is also called by mt_reset() with dev_minor == -1
648 * to fake a reopen after a reset.
650 int _zft_open(unsigned int dev_minor
, unsigned int access_mode
)
652 static unsigned int tape_unit
;
653 static unsigned int file_access_mode
;
655 TRACE_FUN(ft_t_flow
);
657 if ((int)dev_minor
== -1) {
659 zft_unit
= tape_unit
;
660 access_mode
= file_access_mode
;
661 zft_init_driver(); /* reset all static data to defaults */
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
);
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,
676 zft_unit
= dev_minor
;
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");
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.
691 if (ft_no_tape
|| !ft_formatted
) {
695 zft_offline
= 1; /* so we need not test two variables */
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");
704 zft_write_protected
= (access_mode
== O_RDONLY
||
705 ft_write_protected
!= 0);
706 if (zft_write_protected
) {
708 "read only access mode: %d, "
709 "drive write protected: %d",
710 access_mode
== O_RDONLY
,
711 ft_write_protected
!= 0);
714 TRACE_CATCH(zft_vmalloc_once(&zft_deblock_buf
,FT_SEGMENT_SIZE
),
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
721 * might also be a problem if the user makes a backup with a
722 * *qft* device and rewinds it with a raw device.
726 zft_pos
.seg_pos
>= 0 &&
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
);
735 /* RELEASE routine called by kernel-interface code
740 TRACE_FUN(ft_t_flow
);
743 /* call the hardware release routine. Puts the drive offline */
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
);
753 if ((zft_tape_at_lbot(&zft_pos
) ||
754 !(zft_unit
& FTAPE_NO_REWIND
))) {
756 result
= zft_update_header_segments();
759 "Error: unable to update header segments");
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 */
769 zft_reset_position(&zft_pos
);
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.
775 if (zft_deblock_segment
== -1) {
776 zft_vfree(&zft_deblock_buf
, FT_SEGMENT_SIZE
);
778 /* high level driver status, forces creation of a new volume
779 * when calling ftape_write again and not zft_just_before_eof
781 zft_io_state
= zft_idle
;
787 } else if (zft_cmpr_lock(0 /* don't load */) == 0) {
788 (*zft_cmpr_ops
->reset
)(); /* unlock it again */
791 /* call the hardware release routine. Puts the drive offline */
797 * the wrapper function around the wrapper MTIOCTOP ioctl
799 static int mtioctop(struct mtop
*mtop
, int arg_size
)
802 fun_entry
*mt_fun_entry
;
803 TRACE_FUN(ft_t_flow
);
805 if (arg_size
!= sizeof(struct mtop
) || mtop
->mt_op
>= NR_MT_CMDS
) {
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
) {
814 TRACE_ABORT(-ENXIO
, ft_t_info
, "no tape present");
816 TRACE_ABORT(-ENXIO
, ft_t_info
, "drive is offline");
819 if (!mt_fun_entry
->not_formatted
&& !ft_formatted
) {
820 TRACE_ABORT(-EACCES
, ft_t_info
, "tape is not formatted");
822 if (!mt_fun_entry
->write_protected
) {
823 TRACE_CATCH(zft_check_write_access(&zft_pos
),);
825 if (mt_fun_entry
->need_idle_state
&& !(zft_offline
|| !ft_formatted
)) {
826 TRACE_CATCH(zft_def_idle_state(),);
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");
832 result
= (mt_fun_entry
->function
)(&mtop
->mt_count
);
833 if (zft_tape_at_lbot(&zft_pos
)) {
834 TRACE_CATCH(zft_update_header_segments(),);
843 * standard MTIOCGET ioctl
845 static int mtiocget(struct mtget
*mtget
, int arg_size
)
847 const zft_volinfo
*volume
;
849 TRACE_FUN(ft_t_flow
);
851 if (arg_size
!= sizeof(struct mtget
)) {
852 TRACE_ABORT(-EINVAL
, ft_t_info
, "bad argument size: %d",
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
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
867 if (ft_write_protected
) {
868 mtget
->mt_gstat
|= GMT_WR_PROT(~0UL);
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
;
877 if (zft_tape_at_eod(&zft_pos
)) {
878 mtget
->mt_gstat
|= GMT_EOD(~0UL);
880 if (zft_pos
.tape_pos
> max_tape_pos
) {
881 mtget
->mt_gstat
|= GMT_EOT(~0UL);
883 mtget
->mt_blkno
= zft_div_blksz(zft_pos
.volume_pos
,
885 if (zft_just_before_eof
) {
886 mtget
->mt_gstat
|= GMT_EOF(~0UL);
888 if (zft_tape_at_lbot(&zft_pos
)) {
889 mtget
->mt_gstat
|= GMT_BOT(~0UL);
892 mtget
->mt_fileno
= mtget
->mt_blkno
= -1;
893 if (mtget
->mt_dsreg
& QIC_STATUS_AT_BOT
) {
894 mtget
->mt_gstat
|= GMT_BOT(~0UL);
899 mtget
->mt_gstat
= GMT_DR_OPEN(~0UL);
901 mtget
->mt_gstat
= 0UL;
903 mtget
->mt_fileno
= mtget
->mt_blkno
= -1;
910 * Read a floppy tape segment. This is useful for manipulating the
911 * volume table, and read the old header segment before re-formatting
914 static int mtiocrdftseg(struct mtftseg
* mtftseg
, int arg_size
)
916 TRACE_FUN(ft_t_flow
);
918 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCRDFTSEG");
920 TRACE_ABORT(-EACCES
, ft_t_info
,
921 "driver needs to be in raw mode for this ioctl");
923 if (arg_size
!= sizeof(struct mtftseg
)) {
924 TRACE_ABORT(-EINVAL
, ft_t_info
, "bad argument size: %d",
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");
935 TRACE_EXIT
-EACCES
; /* -ENXIO ? */
938 if (!zft_header_read
) {
939 TRACE_CATCH(zft_def_idle_state(),);
941 if (mtftseg
->mt_segno
> ft_last_data_segment
) {
942 TRACE_ABORT(-EINVAL
, ft_t_info
, "segment number is too large");
944 mtftseg
->mt_result
= ftape_read_segment(mtftseg
->mt_segno
,
947 if (mtftseg
->mt_result
< 0) {
948 /* a negativ result is not an ioctl error. if
949 * the user wants to read damaged tapes,
954 if (copy_to_user(mtftseg
->mt_data
,
956 mtftseg
->mt_result
) != 0) {
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
970 static int mtiocwrftseg(struct mtftseg
* mtftseg
, int arg_size
)
973 TRACE_FUN(ft_t_flow
);
975 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCWRFTSEG");
976 if (zft_write_protected
|| zft_qic_mode
) {
979 if (arg_size
!= sizeof(struct mtftseg
)) {
980 TRACE_ABORT(-EINVAL
, ft_t_info
, "bad argument size: %d",
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");
993 * We don't check for ft_formatted, because this gives
994 * only the software status of the driver.
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.
1002 if (zft_hseg_buf
== NULL
) {
1005 if (mtftseg
->mt_mode
!= FT_WR_DELETE
) {
1006 if (copy_from_user(zft_deblock_buf
,
1008 FT_SEGMENT_SIZE
) != 0) {
1012 mtftseg
->mt_result
= ftape_write_segment(mtftseg
->mt_segno
,
1015 if (mtftseg
->mt_result
>= 0 && mtftseg
->mt_mode
== FT_WR_SINGLE
) {
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
1021 if ((result
= ftape_loop_until_writes_done()) < 0) {
1022 mtftseg
->mt_result
= result
;
1031 * get information about volume positioned at.
1033 static int mtiocvolinfo(struct mtvolinfo
*volinfo
, int arg_size
)
1035 const zft_volinfo
*volume
;
1036 TRACE_FUN(ft_t_flow
);
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
);
1046 if (!ft_formatted
) {
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
;
1062 static int mtioc_zftape_getblksz(struct mtblksz
*blksz
, int arg_size
)
1064 TRACE_FUN(ft_t_flow
);
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
);
1077 if (!ft_formatted
) {
1080 TRACE_CATCH(zft_def_idle_state(),);
1081 blksz
->mt_blksz
= zft_find_volume(zft_pos
.seg_pos
)->blk_sz
;
1088 * get the capacity of the tape cartridge.
1090 static int mtiocgetsize(struct mttapesize
*size
, int arg_size
)
1092 TRACE_FUN(ft_t_flow
);
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
);
1102 if (!ft_formatted
) {
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);
1112 static int mtiocpos(struct mtpos
*mtpos
, int arg_size
)
1115 TRACE_FUN(ft_t_flow
);
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
);
1122 result
= mt_tell((int *)&mtpos
->mt_blkno
);
1126 #ifdef MTIOCFTFORMAT
1128 * formatting of floppy tape cartridges. This is intended to be used
1129 * together with the MTIOCFTCMD ioctl and the new mmap feature
1133 * This function uses ftape_decode_header_segment() to inform the low
1134 * level ftape module about the new parameters.
1136 * It erases the hseg_buf. The calling process must specify all
1137 * parameters to assure proper operation.
1139 * return values: -EINVAL - wrong argument size
1140 * -EINVAL - if ftape_decode_header_segment() failed.
1142 static int set_format_parms(struct ftfmtparms
*p
, __u8
*hseg_buf
)
1144 ft_trace_t old_level
= TRACE_LEVEL
;
1145 TRACE_FUN(ft_t_flow
);
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
);
1151 /* fill in user specified parameters
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
;
1159 /* fill in sane defaults to make ftape happy.
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);
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);
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.
1178 TRACE_CATCH(ftape_calibrate_data_rate(p
->ft_qicstd
&QIC_TAPE_STD_MASK
),
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
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
);
1193 * Return the internal SOFTWARE status of the kernel driver. This does
1194 * NOT query the tape drive about its status.
1196 static int get_format_parms(struct ftfmtparms
*p
, __u8
*hseg_buffer
)
1198 TRACE_FUN(ft_t_flow
);
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
;
1210 static int mtiocftformat(struct mtftformat
*mtftformat
, int arg_size
)
1213 union fmt_arg
*arg
= &mtftformat
->fmt_arg
;
1214 TRACE_FUN(ft_t_flow
);
1216 TRACE(ft_t_noise
, "Mag tape ioctl command: MTIOCFTFORMAT");
1219 TRACE_ABORT(-ENXIO
, ft_t_info
, "no tape present");
1221 TRACE_ABORT(-ENXIO
, ft_t_info
, "drive is offline");
1225 TRACE_ABORT(-EACCES
, ft_t_info
,
1226 "driver needs to be in raw mode for this ioctl");
1228 if (zft_hseg_buf
== NULL
) {
1229 TRACE_CATCH(zft_vcalloc_once(&zft_hseg_buf
, FT_SEGMENT_SIZE
),);
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
),);
1236 case FTFMT_GET_PARMS
:
1237 TRACE_CATCH(get_format_parms(&arg
->fmt_parms
, zft_hseg_buf
),);
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");
1244 TRACE_CATCH(ftape_format_track(arg
->fmt_track
.ft_track
,
1245 arg
->fmt_track
.ft_gap3
),);
1248 TRACE_CATCH(ftape_format_status(&arg
->fmt_status
.ft_segment
),);
1251 TRACE_CATCH(ftape_verify_segment(arg
->fmt_verify
.ft_segment
,
1252 (SectorMap
*)&arg
->fmt_verify
.ft_bsm
),);
1255 TRACE_ABORT(-EINVAL
, ft_t_err
, "Invalid format operation");
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.
1267 static int mtiocftcmd(struct mtftcmd
*ftcmd
, int arg_size
)
1270 TRACE_FUN(ft_t_flow
);
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");
1278 TRACE_ABORT(-EACCES
, ft_t_info
,
1279 "driver needs to be in raw mode for this ioctl");
1281 if (arg_size
!= sizeof(struct mtftcmd
)) {
1282 TRACE_ABORT(-EINVAL
,
1283 ft_t_info
, "bad argument size: %d", arg_size
);
1285 if (ftcmd
->ft_wait_before
) {
1286 TRACE_CATCH(ftape_ready_wait(ftcmd
->ft_wait_before
,
1287 &ftcmd
->ft_status
),);
1289 if (ftcmd
->ft_status
& QIC_STATUS_ERROR
)
1291 if (ftcmd
->ft_result_bits
!= 0) {
1292 TRACE_CATCH(ftape_report_operation(&ftcmd
->ft_result
,
1294 ftcmd
->ft_result_bits
),);
1296 TRACE_CATCH(ftape_command(ftcmd
->ft_cmd
),);
1297 if (ftcmd
->ft_status
& QIC_STATUS_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
)
1305 if (ftcmd
->ft_wait_after
!= 0) {
1306 TRACE_CATCH(ftape_ready_wait(ftcmd
->ft_wait_after
,
1307 &ftcmd
->ft_status
),);
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),);
1315 TRACE_EXIT
0; /* this is not an i/o error */
1319 /* IOCTL routine called by kernel-interface code
1321 int _zft_ioctl(unsigned int command
, void __user
* arg
)
1324 union { struct mtop mtop
;
1328 struct mtftseg mtftseg
;
1331 struct mtvolinfo mtvolinfo
;
1334 struct mttapesize mttapesize
;
1336 #ifdef MTIOCFTFORMAT
1337 struct mtftformat mtftformat
;
1340 struct mtblksz mtblksz
;
1343 struct mtftcmd mtftcmd
;
1346 int arg_size
= _IOC_SIZE(command
);
1347 int dir
= _IOC_DIR(command
);
1348 TRACE_FUN(ft_t_flow
);
1350 /* This check will only catch arguments that are too large !
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
);
1356 if (dir
& _IOC_WRITE
) {
1357 if (copy_from_user(&krnl_arg
, arg
, arg_size
) != 0) {
1361 TRACE(ft_t_flow
, "called with ioctl command: 0x%08x", command
);
1364 result
= mtioctop(&krnl_arg
.mtop
, arg_size
);
1367 result
= mtiocget(&krnl_arg
.mtget
, arg_size
);
1370 result
= mtiocpos(&krnl_arg
.mtpos
, arg_size
);
1374 result
= mtiocvolinfo(&krnl_arg
.mtvolinfo
, arg_size
);
1378 case MTIOC_ZFTAPE_GETBLKSZ
:
1379 result
= mtioc_zftape_getblksz(&krnl_arg
.mtblksz
, arg_size
);
1383 case MTIOCRDFTSEG
: /* read a segment via ioctl */
1384 result
= mtiocrdftseg(&krnl_arg
.mtftseg
, arg_size
);
1388 case MTIOCWRFTSEG
: /* write a segment via ioctl */
1389 result
= mtiocwrftseg(&krnl_arg
.mtftseg
, arg_size
);
1394 result
= mtiocgetsize(&krnl_arg
.mttapesize
, arg_size
);
1397 #ifdef MTIOCFTFORMAT
1399 result
= mtiocftformat(&krnl_arg
.mtftformat
, arg_size
);
1404 result
= mtiocftcmd(&krnl_arg
.mtftcmd
, arg_size
);
1411 if ((result
>= 0) && (dir
& _IOC_READ
)) {
1412 if (copy_to_user(arg
, &krnl_arg
, arg_size
) != 0) {