[TG3]: Set minimal hw interrupt mitigation.
[linux-2.6/verdex.git] / drivers / char / ftape / zftape / zftape-ctl.c
blob6c7874e5c199ec32f5ae8297fb0e41d0d9cc2804
1 /*
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)
7 any later version.
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>
29 #include <linux/mm.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"
45 /* Global vars.
47 int zft_write_protected; /* this is when cartridge rdonly or O_RDONLY */
48 int zft_header_read;
49 int zft_offline;
50 unsigned int zft_unit;
51 int zft_resid;
52 int zft_mt_compression;
54 /* Local vars.
56 static int going_offline;
58 typedef int (mt_fun)(int *argptr);
59 typedef int (*mt_funp)(int *argptr);
60 typedef struct
62 mt_funp function;
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 */
68 char *name;
69 } fun_entry;
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);
121 pos->seg_byte_pos =
122 pos->volume_pos = 0;
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);
135 } else {
136 pos->tape_pos = 0;
137 pos->seg_pos = -1;
139 zft_just_before_eof = 0;
140 zft_deblock_segment = -1;
141 zft_io_state = zft_idle;
142 zft_zap_read_buffers();
143 zft_prevent_flush();
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 */
150 TRACE_EXIT;
153 static void zft_init_driver(void)
155 TRACE_FUN(ft_t_flow);
157 zft_resid =
158 zft_header_read =
159 zft_old_ftape =
160 zft_offline =
161 zft_write_protected =
162 going_offline =
163 zft_mt_compression =
164 zft_header_changed =
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);
171 TRACE_EXIT;
174 int zft_def_idle_state(void)
176 int result = 0;
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");
188 result = -EIO;
190 /* clear remaining read buffers */
191 zft_zap_read_buffers();
192 zft_io_state = zft_idle;
193 TRACE_EXIT result;
196 /*****************************************************************************
198 * functions for the MTIOCTOP commands *
200 *****************************************************************************/
202 static int mt_dummy(int *dummy)
204 TRACE_FUN(ft_t_flow);
206 TRACE_EXIT -ENOSYS;
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 */),);
221 TRACE_EXIT 0;
224 static int mt_fsf(int *arg)
226 int result;
227 TRACE_FUN(ft_t_flow);
229 result = zft_skip_volumes(*arg, &zft_pos);
230 zft_just_before_eof = 0;
231 TRACE_EXIT result;
234 static int mt_bsf(int *arg)
236 int result = 0;
237 TRACE_FUN(ft_t_flow);
239 if (*arg != 0) {
240 result = zft_skip_volumes(-*arg + 1, &zft_pos);
242 TRACE_EXIT result;
245 static int seek_block(__s64 data_offset,
246 __s64 block_increment,
247 zft_position *pos)
249 int result = 0;
250 __s64 new_block_pos;
251 __s64 vol_block_count;
252 const zft_volinfo *volume;
253 int exceed;
254 TRACE_FUN(ft_t_flow);
256 volume = zft_find_volume(pos->seg_pos);
257 if (volume->start_seg == 0 || volume->end_seg == 0) {
258 TRACE_EXIT -EIO;
260 new_block_pos = (zft_div_blksz(data_offset, volume->blk_sz)
261 + block_increment);
262 vol_block_count = zft_div_blksz(volume->size, volume->blk_sz);
263 if (new_block_pos < 0) {
264 TRACE(ft_t_noise,
265 "new_block_pos " LL_X " < 0", LL(new_block_pos));
266 zft_resid = (int)new_block_pos;
267 new_block_pos = 0;
268 exceed = 1;
269 } else if (new_block_pos > vol_block_count) {
270 TRACE(ft_t_noise,
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;
275 exceed = 1;
276 } else {
277 exceed = 0;
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,
282 zft_deblock_buf);
283 pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
284 pos->tape_pos += pos->seg_byte_pos;
285 } else {
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,
290 pos->tape_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,
309 volume->blk_sz);
310 if (!exceed) {
311 zft_resid = new_block_pos - zft_div_blksz(pos->volume_pos,
312 volume->blk_sz);
314 if (zft_resid < 0) {
315 zft_resid = -zft_resid;
317 TRACE_EXIT ((exceed || zft_resid != 0) && result >= 0) ? -EINVAL : result;
320 static int mt_fsr(int *arg)
322 int result;
323 TRACE_FUN(ft_t_flow);
325 result = seek_block(zft_pos.volume_pos, *arg, &zft_pos);
326 TRACE_EXIT result;
329 static int mt_bsr(int *arg)
331 int result;
332 TRACE_FUN(ft_t_flow);
334 result = seek_block(zft_pos.volume_pos, -*arg, &zft_pos);
335 TRACE_EXIT result;
338 static int mt_weof(int *arg)
340 int result;
341 TRACE_FUN(ft_t_flow);
343 TRACE_CATCH(zft_flush_buffers(),);
344 result = zft_weof(*arg, &zft_pos);
345 TRACE_EXIT result;
348 static int mt_rew(int *dummy)
350 int result;
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);
358 TRACE_EXIT result;
361 static int mt_offl(int *dummy)
363 int result;
364 TRACE_FUN(ft_t_flow);
366 going_offline= 1;
367 result = mt_rew(NULL);
368 TRACE_EXIT result;
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();
379 TRACE_EXIT 0;
382 static int mt_reten(int *dummy)
384 int result;
385 TRACE_FUN(ft_t_flow);
387 if(zft_header_read) {
388 (void)zft_def_idle_state();
390 result = ftape_seek_to_eot();
391 if (result >= 0) {
392 result = ftape_seek_to_bot();
394 TRACE_EXIT(result);
397 static int fsfbsfm(int arg, zft_position *pos)
399 const zft_volinfo *vtbl;
400 __s64 block_pos;
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
410 if (arg == 0) {
411 TRACE_EXIT 0;
413 zft_just_before_eof = 0;
414 TRACE_CATCH(zft_skip_volumes(arg < 0 ? arg : arg-1, pos),
415 if (arg > 0) {
416 zft_resid ++;
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;
423 zft_resid = 1;
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;
430 TRACE_EXIT 0;
433 static int mt_bsfm(int *arg)
435 int result;
436 TRACE_FUN(ft_t_flow);
438 result = fsfbsfm(-*arg, &zft_pos);
439 TRACE_EXIT result;
442 static int mt_fsfm(int *arg)
444 int result;
445 TRACE_FUN(ft_t_flow);
447 result = fsfbsfm(*arg, &zft_pos);
448 TRACE_EXIT result;
451 static int mt_eom(int *dummy)
453 TRACE_FUN(ft_t_flow);
455 zft_skip_to_eom(&zft_pos);
456 TRACE_EXIT 0;
459 static int mt_erase(int *dummy)
461 int result;
462 TRACE_FUN(ft_t_flow);
464 result = zft_erase();
465 TRACE_EXIT result;
468 static int mt_ras2(int *dummy)
470 int result;
471 TRACE_FUN(ft_t_flow);
473 result = -ENOSYS;
474 TRACE_EXIT result;
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");
500 *new_size = 1;
502 zft_blk_sz = *new_size;
503 TRACE_EXIT 0;
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) {
513 TRACE_EXIT -EINVAL;
515 TRACE_EXIT 0;
518 static int mt_seek(int *new_block_pos)
520 int result= 0;
521 TRACE_FUN(ft_t_any);
523 result = seek_block(0, (__s64)*new_block_pos, &zft_pos);
524 TRACE_EXIT result;
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);
540 if (*cnt < 3) {
541 TRACE_EXIT -EINVAL;
543 TRACE_CATCH(ftape_set_nr_buffers(*cnt),);
544 TRACE_EXIT 0;
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);
554 TRACE_EXIT 0;
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) {
568 TRACE_EXIT -EINVAL;
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;
579 TRACE_EXIT 0;
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
590 * formatted
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
593 * deny writes when
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 */
613 TRACE_ABORT(-ENXIO,
614 ft_t_info, "tape is offline or no cartridge");
616 if (!ft_formatted) {
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");
622 if (zft_qic_mode) {
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
629 if (zft_old_ftape) {
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 */
643 TRACE_EXIT 0;
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;
655 int result;
656 TRACE_FUN(ft_t_flow);
658 if ((int)dev_minor == -1) {
659 /* fake reopen */
660 zft_unit = tape_unit;
661 access_mode = file_access_mode;
662 zft_init_driver(); /* reset all static data to defaults */
663 } else {
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,
675 zft_init_driver();
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) {
693 zft_uninit_mem();
695 if (ft_no_tape) {
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) {
708 TRACE(ft_t_noise,
709 "read only access mode: %d, "
710 "drive write protected: %d",
711 access_mode == O_RDONLY,
712 ft_write_protected != 0);
714 if (!zft_offline) {
715 TRACE_CATCH(zft_vmalloc_once(&zft_deblock_buf,FT_SEGMENT_SIZE),
716 ftape_disable());
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
720 * header segments
722 * might also be a problem if the user makes a backup with a
723 * *qft* device and rewinds it with a raw device.
725 if (zft_qic_mode &&
726 !zft_old_ftape &&
727 zft_pos.seg_pos >= 0 &&
728 zft_header_read &&
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);
733 TRACE_EXIT 0;
736 /* RELEASE routine called by kernel-interface code
738 int _zft_close(void)
740 int result = 0;
741 TRACE_FUN(ft_t_flow);
743 if (zft_offline) {
744 /* call the hardware release routine. Puts the drive offline */
745 ftape_disable();
746 TRACE_EXIT 0;
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))) {
756 if (result >= 0) {
757 result = zft_update_header_segments();
758 } else {
759 TRACE(ft_t_err,
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;
783 if (going_offline) {
784 zft_init_driver();
785 zft_uninit_mem();
786 going_offline = 0;
787 zft_offline = 1;
788 } else if (zft_cmpr_lock(0 /* don't load */) == 0) {
789 (*zft_cmpr_ops->reset)(); /* unlock it again */
791 zft_memory_stats();
792 /* call the hardware release routine. Puts the drive offline */
793 ftape_disable();
794 TRACE_EXIT result;
798 * the wrapper function around the wrapper MTIOCTOP ioctl
800 static int mtioctop(struct mtop *mtop, int arg_size)
802 int result = 0;
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) {
807 TRACE_EXIT -EINVAL;
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) {
814 if (ft_no_tape) {
815 TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
816 } else {
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(),);
837 if (result >= 0) {
838 zft_resid = 0;
840 TRACE_EXIT result;
844 * standard MTIOCGET ioctl
846 static int mtiocget(struct mtget *mtget, int arg_size)
848 const zft_volinfo *volume;
849 __s64 max_tape_pos;
850 TRACE_FUN(ft_t_flow);
852 if (arg_size != sizeof(struct mtget)) {
853 TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
854 arg_size);
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
860 * MTIOCTOP commands
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,
885 volume->blk_sz);
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);
892 } else {
893 mtget->mt_fileno = mtget->mt_blkno = -1;
894 if (mtget->mt_dsreg & QIC_STATUS_AT_BOT) {
895 mtget->mt_gstat |= GMT_BOT(~0UL);
898 } else {
899 if (ft_no_tape) {
900 mtget->mt_gstat = GMT_DR_OPEN(~0UL);
901 } else {
902 mtget->mt_gstat = 0UL;
904 mtget->mt_fileno = mtget->mt_blkno = -1;
906 TRACE_EXIT 0;
909 #ifdef MTIOCRDFTSEG
911 * Read a floppy tape segment. This is useful for manipulating the
912 * volume table, and read the old header segment before re-formatting
913 * the cartridge.
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");
920 if (zft_qic_mode) {
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",
926 arg_size);
928 if (zft_offline) {
929 TRACE_EXIT -ENXIO;
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");
935 if (!ft_formatted) {
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,
946 zft_deblock_buf,
947 mtftseg->mt_mode);
948 if (mtftseg->mt_result < 0) {
949 /* a negativ result is not an ioctl error. if
950 * the user wants to read damaged tapes,
951 * it's up to her/him
953 TRACE_EXIT 0;
955 if (copy_to_user(mtftseg->mt_data,
956 zft_deblock_buf,
957 mtftseg->mt_result) != 0) {
958 TRACE_EXIT -EFAULT;
960 TRACE_EXIT 0;
962 #endif
964 #ifdef MTIOCWRFTSEG
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
969 * formatting.
971 static int mtiocwrftseg(struct mtftseg * mtftseg, int arg_size)
973 int result;
974 TRACE_FUN(ft_t_flow);
976 TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCWRFTSEG");
977 if (zft_write_protected || zft_qic_mode) {
978 TRACE_EXIT -EACCES;
980 if (arg_size != sizeof(struct mtftseg)) {
981 TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
982 arg_size);
984 if (zft_offline) {
985 TRACE_EXIT -ENXIO;
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) {
1004 TRACE_EXIT -ENXIO;
1006 if (mtftseg->mt_mode != FT_WR_DELETE) {
1007 if (copy_from_user(zft_deblock_buf,
1008 mtftseg->mt_data,
1009 FT_SEGMENT_SIZE) != 0) {
1010 TRACE_EXIT -EFAULT;
1013 mtftseg->mt_result = ftape_write_segment(mtftseg->mt_segno,
1014 zft_deblock_buf,
1015 mtftseg->mt_mode);
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;
1026 TRACE_EXIT 0;
1028 #endif
1030 #ifdef MTIOCVOLINFO
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);
1044 if (zft_offline) {
1045 TRACE_EXIT -ENXIO;
1047 if (!ft_formatted) {
1048 TRACE_EXIT -EACCES;
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;
1058 TRACE_EXIT 0;
1060 #endif
1062 #ifdef ZFT_OBSOLETE
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);
1075 if (zft_offline) {
1076 TRACE_EXIT -ENXIO;
1078 if (!ft_formatted) {
1079 TRACE_EXIT -EACCES;
1081 TRACE_CATCH(zft_def_idle_state(),);
1082 blksz->mt_blksz = zft_find_volume(zft_pos.seg_pos)->blk_sz;
1083 TRACE_EXIT 0;
1085 #endif
1087 #ifdef MTIOCGETSIZE
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);
1100 if (zft_offline) {
1101 TRACE_EXIT -ENXIO;
1103 if (!ft_formatted) {
1104 TRACE_EXIT -EACCES;
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);
1109 TRACE_EXIT 0;
1111 #endif
1113 static int mtiocpos(struct mtpos *mtpos, int arg_size)
1115 int result;
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);
1124 TRACE_EXIT result;
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);
1168 } else {
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),
1180 _res = -EINVAL);
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);
1190 TRACE_EXIT 0;
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;
1208 TRACE_EXIT 0;
1211 static int mtiocftformat(struct mtftformat *mtftformat, int arg_size)
1213 int result;
1214 union fmt_arg *arg = &mtftformat->fmt_arg;
1215 TRACE_FUN(ft_t_flow);
1217 TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTFORMAT");
1218 if (zft_offline) {
1219 if (ft_no_tape) {
1220 TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
1221 } else {
1222 TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline");
1225 if (zft_qic_mode) {
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),);
1236 TRACE_EXIT 0;
1237 case FTFMT_GET_PARMS:
1238 TRACE_CATCH(get_format_parms(&arg->fmt_parms, zft_hseg_buf),);
1239 TRACE_EXIT 0;
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),);
1247 TRACE_EXIT 0;
1248 case FTFMT_STATUS:
1249 TRACE_CATCH(ftape_format_status(&arg->fmt_status.ft_segment),);
1250 TRACE_EXIT 0;
1251 case FTFMT_VERIFY:
1252 TRACE_CATCH(ftape_verify_segment(arg->fmt_verify.ft_segment,
1253 (SectorMap *)&arg->fmt_verify.ft_bsm),);
1254 TRACE_EXIT 0;
1255 default:
1256 TRACE_ABORT(-EINVAL, ft_t_err, "Invalid format operation");
1258 TRACE_EXIT result;
1260 #endif
1262 #ifdef MTIOCFTCMD
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)
1270 int i;
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");
1278 if (zft_qic_mode) {
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)
1291 goto ftmtcmd_error;
1292 if (ftcmd->ft_result_bits != 0) {
1293 TRACE_CATCH(ftape_report_operation(&ftcmd->ft_result,
1294 ftcmd->ft_cmd,
1295 ftcmd->ft_result_bits),);
1296 } else {
1297 TRACE_CATCH(ftape_command(ftcmd->ft_cmd),);
1298 if (ftcmd->ft_status & QIC_STATUS_ERROR)
1299 goto ftmtcmd_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)
1303 goto ftmtcmd_error;
1306 if (ftcmd->ft_wait_after != 0) {
1307 TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_after,
1308 &ftcmd->ft_status),);
1310 ftmtcmd_error:
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 */
1318 #endif
1320 /* IOCTL routine called by kernel-interface code
1322 int _zft_ioctl(unsigned int command, void __user * arg)
1324 int result;
1325 union { struct mtop mtop;
1326 struct mtget mtget;
1327 struct mtpos mtpos;
1328 #ifdef MTIOCRDFTSEG
1329 struct mtftseg mtftseg;
1330 #endif
1331 #ifdef MTIOCVOLINFO
1332 struct mtvolinfo mtvolinfo;
1333 #endif
1334 #ifdef MTIOCGETSIZE
1335 struct mttapesize mttapesize;
1336 #endif
1337 #ifdef MTIOCFTFORMAT
1338 struct mtftformat mtftformat;
1339 #endif
1340 #ifdef ZFT_OBSOLETE
1341 struct mtblksz mtblksz;
1342 #endif
1343 #ifdef MTIOCFTCMD
1344 struct mtftcmd mtftcmd;
1345 #endif
1346 } krnl_arg;
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) {
1359 TRACE_EXIT -EFAULT;
1362 TRACE(ft_t_flow, "called with ioctl command: 0x%08x", command);
1363 switch (command) {
1364 case MTIOCTOP:
1365 result = mtioctop(&krnl_arg.mtop, arg_size);
1366 break;
1367 case MTIOCGET:
1368 result = mtiocget(&krnl_arg.mtget, arg_size);
1369 break;
1370 case MTIOCPOS:
1371 result = mtiocpos(&krnl_arg.mtpos, arg_size);
1372 break;
1373 #ifdef MTIOCVOLINFO
1374 case MTIOCVOLINFO:
1375 result = mtiocvolinfo(&krnl_arg.mtvolinfo, arg_size);
1376 break;
1377 #endif
1378 #ifdef ZFT_OBSOLETE
1379 case MTIOC_ZFTAPE_GETBLKSZ:
1380 result = mtioc_zftape_getblksz(&krnl_arg.mtblksz, arg_size);
1381 break;
1382 #endif
1383 #ifdef MTIOCRDFTSEG
1384 case MTIOCRDFTSEG: /* read a segment via ioctl */
1385 result = mtiocrdftseg(&krnl_arg.mtftseg, arg_size);
1386 break;
1387 #endif
1388 #ifdef MTIOCWRFTSEG
1389 case MTIOCWRFTSEG: /* write a segment via ioctl */
1390 result = mtiocwrftseg(&krnl_arg.mtftseg, arg_size);
1391 break;
1392 #endif
1393 #ifdef MTIOCGETSIZE
1394 case MTIOCGETSIZE:
1395 result = mtiocgetsize(&krnl_arg.mttapesize, arg_size);
1396 break;
1397 #endif
1398 #ifdef MTIOCFTFORMAT
1399 case MTIOCFTFORMAT:
1400 result = mtiocftformat(&krnl_arg.mtftformat, arg_size);
1401 break;
1402 #endif
1403 #ifdef MTIOCFTCMD
1404 case MTIOCFTCMD:
1405 result = mtiocftcmd(&krnl_arg.mtftcmd, arg_size);
1406 break;
1407 #endif
1408 default:
1409 result = -EINVAL;
1410 break;
1412 if ((result >= 0) && (dir & _IOC_READ)) {
1413 if (copy_to_user(arg, &krnl_arg, arg_size) != 0) {
1414 TRACE_EXIT -EFAULT;
1417 TRACE_EXIT result;