2 * Copyright (C) 1993-1996 Bas Laarhoven,
3 * (C) 1996-1997 Claus-Justus Heine.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.c,v $
22 * $Date: 1997/10/21 14:39:22 $
24 * This file contains the reading code
25 * for the QIC-117 floppy-tape driver for Linux.
29 #include <linux/string.h>
30 #include <linux/errno.h>
33 #include <linux/ftape.h>
34 #include <linux/qic117.h>
35 #include "../lowlevel/ftape-tracing.h"
36 #include "../lowlevel/ftape-read.h"
37 #include "../lowlevel/ftape-io.h"
38 #include "../lowlevel/ftape-ctl.h"
39 #include "../lowlevel/ftape-rw.h"
40 #include "../lowlevel/ftape-write.h"
41 #include "../lowlevel/ftape-ecc.h"
42 #include "../lowlevel/ftape-bsm.h"
50 void ftape_zap_read_buffers(void)
54 for (i
= 0; i
< ft_nr_buffers
; ++i
) {
55 /* changed to "fit" with dynamic allocation of tape_buffer. --khp */
56 ft_buffer
[i
]->status
= waiting
;
57 ft_buffer
[i
]->bytes
= 0;
58 ft_buffer
[i
]->skip
= 0;
59 ft_buffer
[i
]->retry
= 0;
61 /* ftape_reset_buffer(); */
64 static SectorMap
convert_sector_map(buffer_struct
* buff
)
67 SectorMap bad_map
= ftape_get_bad_sector_entry(buff
->segment_id
);
68 SectorMap src_map
= buff
->soft_error_map
| buff
->hard_error_map
;
69 SectorMap dst_map
= 0;
72 if (bad_map
|| src_map
) {
73 TRACE(ft_t_flow
, "bad_map = 0x%08lx", (long) bad_map
);
74 TRACE(ft_t_flow
, "src_map = 0x%08lx", (long) src_map
);
77 while ((bad_map
& 1) == 0) {
85 /* (bad_map & 1) == 1 */
90 dst_map
|= (src_map
<< i
);
93 TRACE(ft_t_flow
, "dst_map = 0x%08lx", (long) dst_map
);
98 static int correct_and_copy_fraction(buffer_struct
*buff
, __u8
* destination
,
101 struct memory_segment mseg
;
106 mseg
.read_bad
= convert_sector_map(buff
);
107 mseg
.marked_bad
= 0; /* not used... */
108 mseg
.blocks
= buff
->bytes
/ FT_SECTOR_SIZE
;
109 mseg
.data
= buff
->address
;
110 /* If there are no data sectors we can skip this segment.
112 if (mseg
.blocks
<= 3) {
113 TRACE_ABORT(0, ft_t_noise
, "empty segment");
115 read_bad
= mseg
.read_bad
;
116 ft_history
.crc_errors
+= count_ones(read_bad
);
117 result
= ftape_ecc_correct_data(&mseg
);
118 if (read_bad
!= 0 || mseg
.corrected
!= 0) {
119 TRACE(ft_t_noise
, "crc error map: 0x%08lx", (unsigned long)read_bad
);
120 TRACE(ft_t_noise
, "corrected map: 0x%08lx", (unsigned long)mseg
.corrected
);
121 ft_history
.corrected
+= count_ones(mseg
.corrected
);
123 if (result
== ECC_CORRECTED
|| result
== ECC_OK
) {
124 if (result
== ECC_CORRECTED
) {
125 TRACE(ft_t_info
, "ecc corrected segment: %d", buff
->segment_id
);
130 if((start
+size
) > ((mseg
.blocks
- 3) * FT_SECTOR_SIZE
)) {
131 size
= (mseg
.blocks
- 3) * FT_SECTOR_SIZE
- start
;
137 memcpy(destination
+ start
, mseg
.data
+ start
, size
);
139 if ((read_bad
^ mseg
.corrected
) & mseg
.corrected
) {
140 /* sectors corrected without crc errors set */
141 ft_history
.crc_failures
++;
143 TRACE_EXIT size
; /* (mseg.blocks - 3) * FT_SECTOR_SIZE; */
145 ft_history
.ecc_failures
++;
147 ft_t_err
, "ecc failure on segment %d",
153 /* Read given segment into buffer at address.
155 int ftape_read_segment_fraction(const int segment_id
,
157 const ft_read_mode_t read_mode
,
165 TRACE_FUN(ft_t_flow
);
167 ft_history
.used
|= 1;
168 TRACE(ft_t_data_flow
, "segment_id = %d", segment_id
);
169 if (ft_driver_state
!= reading
) {
170 TRACE(ft_t_noise
, "calling ftape_abort_operation");
171 TRACE_CATCH(ftape_abort_operation(),);
172 ftape_set_state(reading
);
176 /* Allow escape from this loop on signal !
178 FT_SIGNAL_EXIT(_DONT_BLOCK
);
179 /* Search all full buffers for the first matching the
180 * wanted segment. Clear other buffers on the fly.
182 tail
= ftape_get_buffer(ft_queue_tail
);
183 while (!read_done
&& tail
->status
== done
) {
184 /* Allow escape from this loop on signal !
186 FT_SIGNAL_EXIT(_DONT_BLOCK
);
187 if (tail
->segment_id
== segment_id
) {
188 /* If out buffer is already full,
189 * return its contents.
191 TRACE(ft_t_flow
, "found segment in cache: %d",
194 /* Return a value that
195 * read_header_segment
196 * understands. As this
197 * should only occur when
198 * searching for the header
199 * segments it shouldn't be
200 * misinterpreted elsewhere.
204 result
= correct_and_copy_fraction(
209 TRACE(ft_t_flow
, "segment contains (bytes): %d",
212 if (result
!= -EAGAIN
) {
215 /* keep read_done == 0, will
217 * ftape_abort_operation
218 * because reading wrong
221 TRACE(ft_t_err
, "ecc failed, retry");
228 TRACE(ft_t_flow
,"zapping segment in cache: %d",
231 tail
->status
= waiting
;
232 tail
= ftape_next_buffer(ft_queue_tail
);
234 if (!read_done
&& tail
->status
== reading
) {
235 if (tail
->segment_id
== segment_id
) {
236 switch(ftape_wait_segment(reading
)) {
240 TRACE_ABORT(-EINTR
, ft_t_warn
,
242 "non-blockable signal");
246 "wait_segment failed");
247 ftape_abort_operation();
248 ftape_set_state(reading
);
252 /* We're reading the wrong segment,
255 TRACE(ft_t_noise
, "reading wrong segment");
256 ftape_abort_operation();
257 ftape_set_state(reading
);
260 /* should runner stop ?
262 if (ft_runner_status
== aborting
) {
263 buffer_struct
*head
= ftape_get_buffer(ft_queue_head
);
264 switch(head
->status
) {
266 ft_history
.defects
+=
267 count_ones(head
->hard_error_map
);
269 head
->status
= waiting
;
274 TRACE_CATCH(ftape_dumb_stop(),);
276 /* If just passed last segment on tape: wait
277 * for BOT or EOT mark. Sets ft_runner_status to
278 * idle if at lEOT and successful
280 TRACE_CATCH(ftape_handle_logical_eot(),);
282 /* If we got a segment: quit, or else retry up to limit.
284 * If segment to read is empty, do not start runner for it,
285 * but wait for next read call.
288 ftape_get_bad_sector_entry(segment_id
) == EMPTY_SEGMENT
) {
289 /* bytes_read = 0; should still be zero */
290 TRACE_EXIT bytes_read
;
293 if (retry
> FT_RETRIES_ON_ECC_ERROR
) {
294 ft_history
.defects
++;
295 TRACE_ABORT(-ENODATA
, ft_t_err
,
296 "too many retries on ecc failure");
298 /* Now at least one buffer is empty !
299 * Restart runner & tape if needed.
301 TRACE(ft_t_any
, "head: %d, tail: %d, ft_runner_status: %d",
302 ftape_buffer_id(ft_queue_head
),
303 ftape_buffer_id(ft_queue_tail
),
305 TRACE(ft_t_any
, "buffer[].status, [head]: %d, [tail]: %d",
306 ftape_get_buffer(ft_queue_head
)->status
,
307 ftape_get_buffer(ft_queue_tail
)->status
);
308 tail
= ftape_get_buffer(ft_queue_tail
);
309 if (tail
->status
== waiting
) {
310 buffer_struct
*head
= ftape_get_buffer(ft_queue_head
);
312 ftape_setup_new_segment(head
, segment_id
, -1);
313 if (read_mode
== FT_RD_SINGLE
) {
314 /* disable read-ahead */
315 head
->next_segment
= 0;
317 ftape_calc_next_cluster(head
);
318 if (ft_runner_status
== idle
) {
319 result
= ftape_start_tape(segment_id
,
320 head
->sector_offset
);
322 TRACE_ABORT(result
, ft_t_err
, "Error: "
323 "segment %d unreachable",
327 head
->status
= reading
;
328 fdc_setup_read_write(head
, FDC_READ
);
335 int ftape_read_header_segment(__u8
*address
)
339 int first_failed
= 0;
341 TRACE_FUN(ft_t_flow
);
343 ft_used_header_segment
= -1;
344 TRACE_CATCH(ftape_report_drive_status(&status
),);
345 TRACE(ft_t_flow
, "reading...");
346 /* We're looking for the first header segment.
347 * A header segment cannot contain bad sectors, therefor at the
348 * tape start, segments with bad sectors are (according to QIC-40/80)
349 * written with deleted data marks and must be skipped.
351 memset(address
, '\0', (FT_SECTORS_PER_SEGMENT
- 3) * FT_SECTOR_SIZE
);
353 #define HEADER_SEGMENT_BOUNDARY 68 /* why not 42? */
354 for (header_segment
= 0;
355 header_segment
< HEADER_SEGMENT_BOUNDARY
&& result
== 0;
357 /* Set no read-ahead, the isr will force read-ahead whenever
358 * it encounters deleted data !
360 result
= ftape_read_segment(header_segment
,
363 if (result
< 0 && !first_failed
) {
364 TRACE(ft_t_err
, "header segment damaged, trying backup");
366 result
= 0; /* force read of next (backup) segment */
369 if (result
< 0 || header_segment
>= HEADER_SEGMENT_BOUNDARY
) {
370 TRACE_ABORT(-EIO
, ft_t_err
,
371 "no readable header segment found");
373 TRACE_CATCH(ftape_abort_operation(),);
374 ft_used_header_segment
= header_segment
;
375 result
= ftape_decode_header_segment(address
);
379 int ftape_decode_header_segment(__u8
*address
)
381 unsigned int max_floppy_side
;
382 unsigned int max_floppy_track
;
383 unsigned int max_floppy_sector
;
384 unsigned int new_tape_len
;
385 TRACE_FUN(ft_t_flow
);
387 if (GET4(address
, FT_SIGNATURE
) == FT_D2G_MAGIC
) {
388 /* Ditto 2GB header segment. They encrypt the bad sector map.
389 * We decrypt it and store them in normal format.
390 * I hope this is correct.
394 "Found Ditto 2GB tape, "
395 "trying to decrypt bad sector map");
396 for (i
=256; i
< 29 * FT_SECTOR_SIZE
; i
++) {
397 address
[i
] = ~(address
[i
] - (i
&0xff));
399 PUT4(address
, 0,FT_HSEG_MAGIC
);
400 } else if (GET4(address
, FT_SIGNATURE
) != FT_HSEG_MAGIC
) {
401 TRACE_ABORT(-EIO
, ft_t_err
,
402 "wrong signature in header segment");
404 ft_format_code
= (ft_format_type
) address
[FT_FMT_CODE
];
405 if (ft_format_code
!= fmt_big
) {
406 ft_header_segment_1
= GET2(address
, FT_HSEG_1
);
407 ft_header_segment_2
= GET2(address
, FT_HSEG_2
);
408 ft_first_data_segment
= GET2(address
, FT_FRST_SEG
);
409 ft_last_data_segment
= GET2(address
, FT_LAST_SEG
);
411 ft_header_segment_1
= GET4(address
, FT_6_HSEG_1
);
412 ft_header_segment_2
= GET4(address
, FT_6_HSEG_2
);
413 ft_first_data_segment
= GET4(address
, FT_6_FRST_SEG
);
414 ft_last_data_segment
= GET4(address
, FT_6_LAST_SEG
);
416 TRACE(ft_t_noise
, "first data segment: %d", ft_first_data_segment
);
417 TRACE(ft_t_noise
, "last data segment: %d", ft_last_data_segment
);
418 TRACE(ft_t_noise
, "header segments are %d and %d",
419 ft_header_segment_1
, ft_header_segment_2
);
421 /* Verify tape parameters...
422 * QIC-40/80 spec: tape_parameters:
424 * segments-per-track segments_per_track
425 * tracks-per-cartridge tracks_per_tape
426 * max-floppy-side (segments_per_track *
427 * tracks_per_tape - 1) /
428 * ftape_segments_per_head
429 * max-floppy-track ftape_segments_per_head /
430 * ftape_segments_per_cylinder - 1
431 * max-floppy-sector ftape_segments_per_cylinder *
432 * FT_SECTORS_PER_SEGMENT
434 ft_segments_per_track
= GET2(address
, FT_SPT
);
435 ft_tracks_per_tape
= address
[FT_TPC
];
436 max_floppy_side
= address
[FT_FHM
];
437 max_floppy_track
= address
[FT_FTM
];
438 max_floppy_sector
= address
[FT_FSM
];
439 TRACE(ft_t_noise
, "(fmt/spt/tpc/fhm/ftm/fsm) = %d/%d/%d/%d/%d/%d",
440 ft_format_code
, ft_segments_per_track
, ft_tracks_per_tape
,
441 max_floppy_side
, max_floppy_track
, max_floppy_sector
);
442 new_tape_len
= ftape_tape_len
;
443 switch (ft_format_code
) {
448 if (ftape_tape_len
== 0) { /* otherwise 307 ft */
456 int segments_per_1000_inch
= 1; /* non-zero default for switch */
457 switch (ft_qic_std
) {
459 segments_per_1000_inch
= 332;
462 segments_per_1000_inch
= 488;
464 case QIC_TAPE_QIC3010
:
465 segments_per_1000_inch
= 730;
467 case QIC_TAPE_QIC3020
:
468 segments_per_1000_inch
= 1430;
471 new_tape_len
= (1000 * ft_segments_per_track
+
472 (segments_per_1000_inch
- 1)) / segments_per_1000_inch
;
476 int segments_per_1000_inch
= 1; /* non-zero default for switch */
477 switch (ft_qic_std
) {
479 segments_per_1000_inch
= 332;
482 segments_per_1000_inch
= 488;
484 case QIC_TAPE_QIC3010
:
485 segments_per_1000_inch
= 730;
487 case QIC_TAPE_QIC3020
:
488 segments_per_1000_inch
= 1430;
491 TRACE_ABORT(-EIO
, ft_t_bug
,
492 "%x QIC-standard with fmt-code %d, please report",
493 ft_qic_std
, ft_format_code
);
495 new_tape_len
= ((1000 * ft_segments_per_track
+
496 (segments_per_1000_inch
- 1)) /
497 segments_per_1000_inch
);
501 TRACE_ABORT(-EIO
, ft_t_err
,
502 "unknown tape format, please report !");
504 if (new_tape_len
!= ftape_tape_len
) {
505 ftape_tape_len
= new_tape_len
;
506 TRACE(ft_t_info
, "calculated tape length is %d ft",
508 ftape_calc_timeouts(ft_qic_std
, ft_data_rate
, ftape_tape_len
);
510 if (ft_segments_per_track
== 0 && ft_tracks_per_tape
== 0 &&
511 max_floppy_side
== 0 && max_floppy_track
== 0 &&
512 max_floppy_sector
== 0) {
513 /* QIC-40 Rev E and earlier has no values in the header.
515 ft_segments_per_track
= 68;
516 ft_tracks_per_tape
= 20;
518 max_floppy_track
= 169;
519 max_floppy_sector
= 128;
521 /* This test will compensate for the wrong parameter on tapes
522 * formatted by Conner software.
524 if (ft_segments_per_track
== 150 &&
525 ft_tracks_per_tape
== 28 &&
526 max_floppy_side
== 7 &&
527 max_floppy_track
== 149 &&
528 max_floppy_sector
== 128) {
529 TRACE(ft_t_info
, "the famous CONNER bug: max_floppy_side off by one !");
532 /* These tests will compensate for the wrong parameter on tapes
533 * formatted by ComByte Windows software.
535 * First, for 205 foot tapes
537 if (ft_segments_per_track
== 100 &&
538 ft_tracks_per_tape
== 28 &&
539 max_floppy_side
== 9 &&
540 max_floppy_track
== 149 &&
541 max_floppy_sector
== 128) {
542 TRACE(ft_t_info
, "the ComByte bug: max_floppy_side incorrect!");
545 /* Next, for 307 foot tapes. */
546 if (ft_segments_per_track
== 150 &&
547 ft_tracks_per_tape
== 28 &&
548 max_floppy_side
== 9 &&
549 max_floppy_track
== 149 &&
550 max_floppy_sector
== 128) {
551 TRACE(ft_t_info
, "the ComByte bug: max_floppy_side incorrect!");
554 /* This test will compensate for the wrong parameter on tapes
555 * formatted by Colorado Windows software.
557 if (ft_segments_per_track
== 150 &&
558 ft_tracks_per_tape
== 28 &&
559 max_floppy_side
== 6 &&
560 max_floppy_track
== 150 &&
561 max_floppy_sector
== 128) {
562 TRACE(ft_t_info
, "the famous Colorado bug: max_floppy_track off by one !");
563 max_floppy_track
= 149;
565 ftape_segments_per_head
= ((max_floppy_sector
/FT_SECTORS_PER_SEGMENT
) *
566 (max_floppy_track
+ 1));
567 /* This test will compensate for some bug reported by Dima
568 * Brodsky. Seems to be a Colorado bug, either. (freebee
569 * Imation tape shipped together with Colorado T3000
571 if ((ft_format_code
== fmt_var
|| ft_format_code
== fmt_big
) &&
572 ft_tracks_per_tape
== 50 &&
573 max_floppy_side
== 54 &&
574 max_floppy_track
== 255 &&
575 max_floppy_sector
== 128) {
576 TRACE(ft_t_info
, "the famous ??? bug: max_floppy_track off by one !");
577 max_floppy_track
= 254;
580 * Verify drive_configuration with tape parameters
582 if (ftape_segments_per_head
== 0 || ftape_segments_per_cylinder
== 0 ||
583 ((ft_segments_per_track
* ft_tracks_per_tape
- 1) / ftape_segments_per_head
584 != max_floppy_side
) ||
585 (ftape_segments_per_head
/ ftape_segments_per_cylinder
- 1 != max_floppy_track
) ||
586 (ftape_segments_per_cylinder
* FT_SECTORS_PER_SEGMENT
!= max_floppy_sector
)
588 || ((ft_format_code
== fmt_var
|| ft_format_code
== fmt_big
) &&
589 (max_floppy_track
!= 254 || max_floppy_sector
!= 128))
592 char segperheadz
= ftape_segments_per_head
? ' ' : '?';
593 char segpercylz
= ftape_segments_per_cylinder
? ' ' : '?';
594 TRACE(ft_t_err
,"Tape parameters inconsistency, please report");
595 TRACE(ft_t_err
, "reported = %d/%d/%d/%d/%d/%d",
597 ft_segments_per_track
,
602 TRACE(ft_t_err
, "required = %d/%d/%d/%d%c/%d%c/%d",
604 ft_segments_per_track
,
606 ftape_segments_per_head
?
607 ((ft_segments_per_track
* ft_tracks_per_tape
-1) /
608 ftape_segments_per_head
) :
609 (ft_segments_per_track
* ft_tracks_per_tape
-1),
611 ftape_segments_per_cylinder
?
612 (ftape_segments_per_head
/
613 ftape_segments_per_cylinder
- 1 ) :
614 ftape_segments_per_head
- 1,
616 (ftape_segments_per_cylinder
* FT_SECTORS_PER_SEGMENT
));
619 ftape_extract_bad_sector_map(address
);