zftape-ctl.c 39 KB

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