ftape-read.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. * Copyright (C) 1993-1996 Bas Laarhoven,
  3. * (C) 1996-1997 Claus-Justus Heine.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; see the file COPYING. If not, write to
  14. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  15. *
  16. * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.c,v $
  17. * $Revision: 1.6 $
  18. * $Date: 1997/10/21 14:39:22 $
  19. *
  20. * This file contains the reading code
  21. * for the QIC-117 floppy-tape driver for Linux.
  22. *
  23. */
  24. #include <linux/string.h>
  25. #include <linux/errno.h>
  26. #include <linux/mm.h>
  27. #include <linux/ftape.h>
  28. #include <linux/qic117.h>
  29. #include "../lowlevel/ftape-tracing.h"
  30. #include "../lowlevel/ftape-read.h"
  31. #include "../lowlevel/ftape-io.h"
  32. #include "../lowlevel/ftape-ctl.h"
  33. #include "../lowlevel/ftape-rw.h"
  34. #include "../lowlevel/ftape-write.h"
  35. #include "../lowlevel/ftape-ecc.h"
  36. #include "../lowlevel/ftape-bsm.h"
  37. /* Global vars.
  38. */
  39. /* Local vars.
  40. */
  41. void ftape_zap_read_buffers(void)
  42. {
  43. int i;
  44. for (i = 0; i < ft_nr_buffers; ++i) {
  45. /* changed to "fit" with dynamic allocation of tape_buffer. --khp */
  46. ft_buffer[i]->status = waiting;
  47. ft_buffer[i]->bytes = 0;
  48. ft_buffer[i]->skip = 0;
  49. ft_buffer[i]->retry = 0;
  50. }
  51. /* ftape_reset_buffer(); */
  52. }
  53. static SectorMap convert_sector_map(buffer_struct * buff)
  54. {
  55. int i = 0;
  56. SectorMap bad_map = ftape_get_bad_sector_entry(buff->segment_id);
  57. SectorMap src_map = buff->soft_error_map | buff->hard_error_map;
  58. SectorMap dst_map = 0;
  59. TRACE_FUN(ft_t_any);
  60. if (bad_map || src_map) {
  61. TRACE(ft_t_flow, "bad_map = 0x%08lx", (long) bad_map);
  62. TRACE(ft_t_flow, "src_map = 0x%08lx", (long) src_map);
  63. }
  64. while (bad_map) {
  65. while ((bad_map & 1) == 0) {
  66. if (src_map & 1) {
  67. dst_map |= (1 << i);
  68. }
  69. src_map >>= 1;
  70. bad_map >>= 1;
  71. ++i;
  72. }
  73. /* (bad_map & 1) == 1 */
  74. src_map >>= 1;
  75. bad_map >>= 1;
  76. }
  77. if (src_map) {
  78. dst_map |= (src_map << i);
  79. }
  80. if (dst_map) {
  81. TRACE(ft_t_flow, "dst_map = 0x%08lx", (long) dst_map);
  82. }
  83. TRACE_EXIT dst_map;
  84. }
  85. static int correct_and_copy_fraction(buffer_struct *buff, __u8 * destination,
  86. int start, int size)
  87. {
  88. struct memory_segment mseg;
  89. int result;
  90. SectorMap read_bad;
  91. TRACE_FUN(ft_t_any);
  92. mseg.read_bad = convert_sector_map(buff);
  93. mseg.marked_bad = 0; /* not used... */
  94. mseg.blocks = buff->bytes / FT_SECTOR_SIZE;
  95. mseg.data = buff->address;
  96. /* If there are no data sectors we can skip this segment.
  97. */
  98. if (mseg.blocks <= 3) {
  99. TRACE_ABORT(0, ft_t_noise, "empty segment");
  100. }
  101. read_bad = mseg.read_bad;
  102. ft_history.crc_errors += count_ones(read_bad);
  103. result = ftape_ecc_correct_data(&mseg);
  104. if (read_bad != 0 || mseg.corrected != 0) {
  105. TRACE(ft_t_noise, "crc error map: 0x%08lx", (unsigned long)read_bad);
  106. TRACE(ft_t_noise, "corrected map: 0x%08lx", (unsigned long)mseg.corrected);
  107. ft_history.corrected += count_ones(mseg.corrected);
  108. }
  109. if (result == ECC_CORRECTED || result == ECC_OK) {
  110. if (result == ECC_CORRECTED) {
  111. TRACE(ft_t_info, "ecc corrected segment: %d", buff->segment_id);
  112. }
  113. if(start < 0) {
  114. start= 0;
  115. }
  116. if((start+size) > ((mseg.blocks - 3) * FT_SECTOR_SIZE)) {
  117. size = (mseg.blocks - 3) * FT_SECTOR_SIZE - start;
  118. }
  119. if (size < 0) {
  120. size= 0;
  121. }
  122. if(size > 0) {
  123. memcpy(destination + start, mseg.data + start, size);
  124. }
  125. if ((read_bad ^ mseg.corrected) & mseg.corrected) {
  126. /* sectors corrected without crc errors set */
  127. ft_history.crc_failures++;
  128. }
  129. TRACE_EXIT size; /* (mseg.blocks - 3) * FT_SECTOR_SIZE; */
  130. } else {
  131. ft_history.ecc_failures++;
  132. TRACE_ABORT(-EAGAIN,
  133. ft_t_err, "ecc failure on segment %d",
  134. buff->segment_id);
  135. }
  136. TRACE_EXIT 0;
  137. }
  138. /* Read given segment into buffer at address.
  139. */
  140. int ftape_read_segment_fraction(const int segment_id,
  141. void *address,
  142. const ft_read_mode_t read_mode,
  143. const int start,
  144. const int size)
  145. {
  146. int result = 0;
  147. int retry = 0;
  148. int bytes_read = 0;
  149. int read_done = 0;
  150. TRACE_FUN(ft_t_flow);
  151. ft_history.used |= 1;
  152. TRACE(ft_t_data_flow, "segment_id = %d", segment_id);
  153. if (ft_driver_state != reading) {
  154. TRACE(ft_t_noise, "calling ftape_abort_operation");
  155. TRACE_CATCH(ftape_abort_operation(),);
  156. ftape_set_state(reading);
  157. }
  158. for(;;) {
  159. buffer_struct *tail;
  160. /* Allow escape from this loop on signal !
  161. */
  162. FT_SIGNAL_EXIT(_DONT_BLOCK);
  163. /* Search all full buffers for the first matching the
  164. * wanted segment. Clear other buffers on the fly.
  165. */
  166. tail = ftape_get_buffer(ft_queue_tail);
  167. while (!read_done && tail->status == done) {
  168. /* Allow escape from this loop on signal !
  169. */
  170. FT_SIGNAL_EXIT(_DONT_BLOCK);
  171. if (tail->segment_id == segment_id) {
  172. /* If out buffer is already full,
  173. * return its contents.
  174. */
  175. TRACE(ft_t_flow, "found segment in cache: %d",
  176. segment_id);
  177. if (tail->deleted) {
  178. /* Return a value that
  179. * read_header_segment
  180. * understands. As this
  181. * should only occur when
  182. * searching for the header
  183. * segments it shouldn't be
  184. * misinterpreted elsewhere.
  185. */
  186. TRACE_EXIT 0;
  187. }
  188. result = correct_and_copy_fraction(
  189. tail,
  190. address,
  191. start,
  192. size);
  193. TRACE(ft_t_flow, "segment contains (bytes): %d",
  194. result);
  195. if (result < 0) {
  196. if (result != -EAGAIN) {
  197. TRACE_EXIT result;
  198. }
  199. /* keep read_done == 0, will
  200. * trigger
  201. * ftape_abort_operation
  202. * because reading wrong
  203. * segment.
  204. */
  205. TRACE(ft_t_err, "ecc failed, retry");
  206. ++retry;
  207. } else {
  208. read_done = 1;
  209. bytes_read = result;
  210. }
  211. } else {
  212. TRACE(ft_t_flow,"zapping segment in cache: %d",
  213. tail->segment_id);
  214. }
  215. tail->status = waiting;
  216. tail = ftape_next_buffer(ft_queue_tail);
  217. }
  218. if (!read_done && tail->status == reading) {
  219. if (tail->segment_id == segment_id) {
  220. switch(ftape_wait_segment(reading)) {
  221. case 0:
  222. break;
  223. case -EINTR:
  224. TRACE_ABORT(-EINTR, ft_t_warn,
  225. "interrupted by "
  226. "non-blockable signal");
  227. break;
  228. default:
  229. TRACE(ft_t_noise,
  230. "wait_segment failed");
  231. ftape_abort_operation();
  232. ftape_set_state(reading);
  233. break;
  234. }
  235. } else {
  236. /* We're reading the wrong segment,
  237. * stop runner.
  238. */
  239. TRACE(ft_t_noise, "reading wrong segment");
  240. ftape_abort_operation();
  241. ftape_set_state(reading);
  242. }
  243. }
  244. /* should runner stop ?
  245. */
  246. if (ft_runner_status == aborting) {
  247. buffer_struct *head = ftape_get_buffer(ft_queue_head);
  248. switch(head->status) {
  249. case error:
  250. ft_history.defects +=
  251. count_ones(head->hard_error_map);
  252. case reading:
  253. head->status = waiting;
  254. break;
  255. default:
  256. break;
  257. }
  258. TRACE_CATCH(ftape_dumb_stop(),);
  259. } else {
  260. /* If just passed last segment on tape: wait
  261. * for BOT or EOT mark. Sets ft_runner_status to
  262. * idle if at lEOT and successful
  263. */
  264. TRACE_CATCH(ftape_handle_logical_eot(),);
  265. }
  266. /* If we got a segment: quit, or else retry up to limit.
  267. *
  268. * If segment to read is empty, do not start runner for it,
  269. * but wait for next read call.
  270. */
  271. if (read_done ||
  272. ftape_get_bad_sector_entry(segment_id) == EMPTY_SEGMENT ) {
  273. /* bytes_read = 0; should still be zero */
  274. TRACE_EXIT bytes_read;
  275. }
  276. if (retry > FT_RETRIES_ON_ECC_ERROR) {
  277. ft_history.defects++;
  278. TRACE_ABORT(-ENODATA, ft_t_err,
  279. "too many retries on ecc failure");
  280. }
  281. /* Now at least one buffer is empty !
  282. * Restart runner & tape if needed.
  283. */
  284. TRACE(ft_t_any, "head: %d, tail: %d, ft_runner_status: %d",
  285. ftape_buffer_id(ft_queue_head),
  286. ftape_buffer_id(ft_queue_tail),
  287. ft_runner_status);
  288. TRACE(ft_t_any, "buffer[].status, [head]: %d, [tail]: %d",
  289. ftape_get_buffer(ft_queue_head)->status,
  290. ftape_get_buffer(ft_queue_tail)->status);
  291. tail = ftape_get_buffer(ft_queue_tail);
  292. if (tail->status == waiting) {
  293. buffer_struct *head = ftape_get_buffer(ft_queue_head);
  294. ftape_setup_new_segment(head, segment_id, -1);
  295. if (read_mode == FT_RD_SINGLE) {
  296. /* disable read-ahead */
  297. head->next_segment = 0;
  298. }
  299. ftape_calc_next_cluster(head);
  300. if (ft_runner_status == idle) {
  301. result = ftape_start_tape(segment_id,
  302. head->sector_offset);
  303. if (result < 0) {
  304. TRACE_ABORT(result, ft_t_err, "Error: "
  305. "segment %d unreachable",
  306. segment_id);
  307. }
  308. }
  309. head->status = reading;
  310. fdc_setup_read_write(head, FDC_READ);
  311. }
  312. }
  313. /* not reached */
  314. TRACE_EXIT -EIO;
  315. }
  316. int ftape_read_header_segment(__u8 *address)
  317. {
  318. int result;
  319. int header_segment;
  320. int first_failed = 0;
  321. int status;
  322. TRACE_FUN(ft_t_flow);
  323. ft_used_header_segment = -1;
  324. TRACE_CATCH(ftape_report_drive_status(&status),);
  325. TRACE(ft_t_flow, "reading...");
  326. /* We're looking for the first header segment.
  327. * A header segment cannot contain bad sectors, therefor at the
  328. * tape start, segments with bad sectors are (according to QIC-40/80)
  329. * written with deleted data marks and must be skipped.
  330. */
  331. memset(address, '\0', (FT_SECTORS_PER_SEGMENT - 3) * FT_SECTOR_SIZE);
  332. result = 0;
  333. #define HEADER_SEGMENT_BOUNDARY 68 /* why not 42? */
  334. for (header_segment = 0;
  335. header_segment < HEADER_SEGMENT_BOUNDARY && result == 0;
  336. ++header_segment) {
  337. /* Set no read-ahead, the isr will force read-ahead whenever
  338. * it encounters deleted data !
  339. */
  340. result = ftape_read_segment(header_segment,
  341. address,
  342. FT_RD_SINGLE);
  343. if (result < 0 && !first_failed) {
  344. TRACE(ft_t_err, "header segment damaged, trying backup");
  345. first_failed = 1;
  346. result = 0; /* force read of next (backup) segment */
  347. }
  348. }
  349. if (result < 0 || header_segment >= HEADER_SEGMENT_BOUNDARY) {
  350. TRACE_ABORT(-EIO, ft_t_err,
  351. "no readable header segment found");
  352. }
  353. TRACE_CATCH(ftape_abort_operation(),);
  354. ft_used_header_segment = header_segment;
  355. result = ftape_decode_header_segment(address);
  356. TRACE_EXIT result;
  357. }
  358. int ftape_decode_header_segment(__u8 *address)
  359. {
  360. unsigned int max_floppy_side;
  361. unsigned int max_floppy_track;
  362. unsigned int max_floppy_sector;
  363. unsigned int new_tape_len;
  364. TRACE_FUN(ft_t_flow);
  365. if (GET4(address, FT_SIGNATURE) == FT_D2G_MAGIC) {
  366. /* Ditto 2GB header segment. They encrypt the bad sector map.
  367. * We decrypt it and store them in normal format.
  368. * I hope this is correct.
  369. */
  370. int i;
  371. TRACE(ft_t_warn,
  372. "Found Ditto 2GB tape, "
  373. "trying to decrypt bad sector map");
  374. for (i=256; i < 29 * FT_SECTOR_SIZE; i++) {
  375. address[i] = ~(address[i] - (i&0xff));
  376. }
  377. PUT4(address, 0,FT_HSEG_MAGIC);
  378. } else if (GET4(address, FT_SIGNATURE) != FT_HSEG_MAGIC) {
  379. TRACE_ABORT(-EIO, ft_t_err,
  380. "wrong signature in header segment");
  381. }
  382. ft_format_code = (ft_format_type) address[FT_FMT_CODE];
  383. if (ft_format_code != fmt_big) {
  384. ft_header_segment_1 = GET2(address, FT_HSEG_1);
  385. ft_header_segment_2 = GET2(address, FT_HSEG_2);
  386. ft_first_data_segment = GET2(address, FT_FRST_SEG);
  387. ft_last_data_segment = GET2(address, FT_LAST_SEG);
  388. } else {
  389. ft_header_segment_1 = GET4(address, FT_6_HSEG_1);
  390. ft_header_segment_2 = GET4(address, FT_6_HSEG_2);
  391. ft_first_data_segment = GET4(address, FT_6_FRST_SEG);
  392. ft_last_data_segment = GET4(address, FT_6_LAST_SEG);
  393. }
  394. TRACE(ft_t_noise, "first data segment: %d", ft_first_data_segment);
  395. TRACE(ft_t_noise, "last data segment: %d", ft_last_data_segment);
  396. TRACE(ft_t_noise, "header segments are %d and %d",
  397. ft_header_segment_1, ft_header_segment_2);
  398. /* Verify tape parameters...
  399. * QIC-40/80 spec: tape_parameters:
  400. *
  401. * segments-per-track segments_per_track
  402. * tracks-per-cartridge tracks_per_tape
  403. * max-floppy-side (segments_per_track *
  404. * tracks_per_tape - 1) /
  405. * ftape_segments_per_head
  406. * max-floppy-track ftape_segments_per_head /
  407. * ftape_segments_per_cylinder - 1
  408. * max-floppy-sector ftape_segments_per_cylinder *
  409. * FT_SECTORS_PER_SEGMENT
  410. */
  411. ft_segments_per_track = GET2(address, FT_SPT);
  412. ft_tracks_per_tape = address[FT_TPC];
  413. max_floppy_side = address[FT_FHM];
  414. max_floppy_track = address[FT_FTM];
  415. max_floppy_sector = address[FT_FSM];
  416. TRACE(ft_t_noise, "(fmt/spt/tpc/fhm/ftm/fsm) = %d/%d/%d/%d/%d/%d",
  417. ft_format_code, ft_segments_per_track, ft_tracks_per_tape,
  418. max_floppy_side, max_floppy_track, max_floppy_sector);
  419. new_tape_len = ftape_tape_len;
  420. switch (ft_format_code) {
  421. case fmt_425ft:
  422. new_tape_len = 425;
  423. break;
  424. case fmt_normal:
  425. if (ftape_tape_len == 0) { /* otherwise 307 ft */
  426. new_tape_len = 205;
  427. }
  428. break;
  429. case fmt_1100ft:
  430. new_tape_len = 1100;
  431. break;
  432. case fmt_var:{
  433. int segments_per_1000_inch = 1; /* non-zero default for switch */
  434. switch (ft_qic_std) {
  435. case QIC_TAPE_QIC40:
  436. segments_per_1000_inch = 332;
  437. break;
  438. case QIC_TAPE_QIC80:
  439. segments_per_1000_inch = 488;
  440. break;
  441. case QIC_TAPE_QIC3010:
  442. segments_per_1000_inch = 730;
  443. break;
  444. case QIC_TAPE_QIC3020:
  445. segments_per_1000_inch = 1430;
  446. break;
  447. }
  448. new_tape_len = (1000 * ft_segments_per_track +
  449. (segments_per_1000_inch - 1)) / segments_per_1000_inch;
  450. break;
  451. }
  452. case fmt_big:{
  453. int segments_per_1000_inch = 1; /* non-zero default for switch */
  454. switch (ft_qic_std) {
  455. case QIC_TAPE_QIC40:
  456. segments_per_1000_inch = 332;
  457. break;
  458. case QIC_TAPE_QIC80:
  459. segments_per_1000_inch = 488;
  460. break;
  461. case QIC_TAPE_QIC3010:
  462. segments_per_1000_inch = 730;
  463. break;
  464. case QIC_TAPE_QIC3020:
  465. segments_per_1000_inch = 1430;
  466. break;
  467. default:
  468. TRACE_ABORT(-EIO, ft_t_bug,
  469. "%x QIC-standard with fmt-code %d, please report",
  470. ft_qic_std, ft_format_code);
  471. }
  472. new_tape_len = ((1000 * ft_segments_per_track +
  473. (segments_per_1000_inch - 1)) /
  474. segments_per_1000_inch);
  475. break;
  476. }
  477. default:
  478. TRACE_ABORT(-EIO, ft_t_err,
  479. "unknown tape format, please report !");
  480. }
  481. if (new_tape_len != ftape_tape_len) {
  482. ftape_tape_len = new_tape_len;
  483. TRACE(ft_t_info, "calculated tape length is %d ft",
  484. ftape_tape_len);
  485. ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
  486. }
  487. if (ft_segments_per_track == 0 && ft_tracks_per_tape == 0 &&
  488. max_floppy_side == 0 && max_floppy_track == 0 &&
  489. max_floppy_sector == 0) {
  490. /* QIC-40 Rev E and earlier has no values in the header.
  491. */
  492. ft_segments_per_track = 68;
  493. ft_tracks_per_tape = 20;
  494. max_floppy_side = 1;
  495. max_floppy_track = 169;
  496. max_floppy_sector = 128;
  497. }
  498. /* This test will compensate for the wrong parameter on tapes
  499. * formatted by Conner software.
  500. */
  501. if (ft_segments_per_track == 150 &&
  502. ft_tracks_per_tape == 28 &&
  503. max_floppy_side == 7 &&
  504. max_floppy_track == 149 &&
  505. max_floppy_sector == 128) {
  506. TRACE(ft_t_info, "the famous CONNER bug: max_floppy_side off by one !");
  507. max_floppy_side = 6;
  508. }
  509. /* These tests will compensate for the wrong parameter on tapes
  510. * formatted by ComByte Windows software.
  511. *
  512. * First, for 205 foot tapes
  513. */
  514. if (ft_segments_per_track == 100 &&
  515. ft_tracks_per_tape == 28 &&
  516. max_floppy_side == 9 &&
  517. max_floppy_track == 149 &&
  518. max_floppy_sector == 128) {
  519. TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");
  520. max_floppy_side = 4;
  521. }
  522. /* Next, for 307 foot tapes. */
  523. if (ft_segments_per_track == 150 &&
  524. ft_tracks_per_tape == 28 &&
  525. max_floppy_side == 9 &&
  526. max_floppy_track == 149 &&
  527. max_floppy_sector == 128) {
  528. TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");
  529. max_floppy_side = 6;
  530. }
  531. /* This test will compensate for the wrong parameter on tapes
  532. * formatted by Colorado Windows software.
  533. */
  534. if (ft_segments_per_track == 150 &&
  535. ft_tracks_per_tape == 28 &&
  536. max_floppy_side == 6 &&
  537. max_floppy_track == 150 &&
  538. max_floppy_sector == 128) {
  539. TRACE(ft_t_info, "the famous Colorado bug: max_floppy_track off by one !");
  540. max_floppy_track = 149;
  541. }
  542. ftape_segments_per_head = ((max_floppy_sector/FT_SECTORS_PER_SEGMENT) *
  543. (max_floppy_track + 1));
  544. /* This test will compensate for some bug reported by Dima
  545. * Brodsky. Seems to be a Colorado bug, either. (freebee
  546. * Imation tape shipped together with Colorado T3000
  547. */
  548. if ((ft_format_code == fmt_var || ft_format_code == fmt_big) &&
  549. ft_tracks_per_tape == 50 &&
  550. max_floppy_side == 54 &&
  551. max_floppy_track == 255 &&
  552. max_floppy_sector == 128) {
  553. TRACE(ft_t_info, "the famous ??? bug: max_floppy_track off by one !");
  554. max_floppy_track = 254;
  555. }
  556. /*
  557. * Verify drive_configuration with tape parameters
  558. */
  559. if (ftape_segments_per_head == 0 || ftape_segments_per_cylinder == 0 ||
  560. ((ft_segments_per_track * ft_tracks_per_tape - 1) / ftape_segments_per_head
  561. != max_floppy_side) ||
  562. (ftape_segments_per_head / ftape_segments_per_cylinder - 1 != max_floppy_track) ||
  563. (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT != max_floppy_sector)
  564. #ifdef TESTING
  565. || ((ft_format_code == fmt_var || ft_format_code == fmt_big) &&
  566. (max_floppy_track != 254 || max_floppy_sector != 128))
  567. #endif
  568. ) {
  569. char segperheadz = ftape_segments_per_head ? ' ' : '?';
  570. char segpercylz = ftape_segments_per_cylinder ? ' ' : '?';
  571. TRACE(ft_t_err,"Tape parameters inconsistency, please report");
  572. TRACE(ft_t_err, "reported = %d/%d/%d/%d/%d/%d",
  573. ft_format_code,
  574. ft_segments_per_track,
  575. ft_tracks_per_tape,
  576. max_floppy_side,
  577. max_floppy_track,
  578. max_floppy_sector);
  579. TRACE(ft_t_err, "required = %d/%d/%d/%d%c/%d%c/%d",
  580. ft_format_code,
  581. ft_segments_per_track,
  582. ft_tracks_per_tape,
  583. ftape_segments_per_head ?
  584. ((ft_segments_per_track * ft_tracks_per_tape -1) /
  585. ftape_segments_per_head ) :
  586. (ft_segments_per_track * ft_tracks_per_tape -1),
  587. segperheadz,
  588. ftape_segments_per_cylinder ?
  589. (ftape_segments_per_head /
  590. ftape_segments_per_cylinder - 1 ) :
  591. ftape_segments_per_head - 1,
  592. segpercylz,
  593. (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT));
  594. TRACE_EXIT -EIO;
  595. }
  596. ftape_extract_bad_sector_map(address);
  597. TRACE_EXIT 0;
  598. }