zftape-ctl.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:42k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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