zftape-ctl.c 39 KB

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