2 * I use these routines just to decide when I have to fake a
3 * volume-table to preserve compatibility to original ftape.
6 * Copyright (C) 1994-1995 Bas Laarhoven.
8 * Modified for zftape 1996, 1997 Claus Heine.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-eof.c,v $
26 * $Date: 1997/10/05 19:19:02 $
28 * This file contains the eof mark handling code
29 * for the QIC-40/80 floppy-tape driver for Linux.
32 #include <linux/string.h>
33 #include <linux/errno.h>
35 #include <linux/zftape.h>
37 #include "../zftape/zftape-init.h"
38 #include "../zftape/zftape-rw.h"
39 #include "../zftape/zftape-eof.h"
44 /* a copy of the failed sector log from the header segment.
46 eof_mark_union
*zft_eof_map
;
48 /* number of eof marks (entries in bad sector log) on tape.
50 int zft_nr_eof_marks
= -1;
56 static char linux_tape_label
[] = "Linux raw format V";
58 min_fmt_version
= 1, max_fmt_version
= 2
60 static unsigned ftape_fmt_version
= 0;
63 /* Ftape (mis)uses the bad sector log to record end-of-file marks.
64 * Initially (when the tape is erased) all entries in the bad sector
65 * log are added to the tape's bad sector map. The bad sector log then
68 * The bad sector log normally contains entries of the form:
69 * even 16-bit word: segment number of bad sector
70 * odd 16-bit word: encoded date
71 * There can be a total of 448 entries (1792 bytes).
73 * My guess is that no program is using this bad sector log (the *
74 * format seems useless as there is no indication of the bad sector
75 * itself, only the segment) However, if any program does use the bad
76 * sector log, the format used by ftape will let the program think
77 * there are some bad sectors and no harm is done.
79 * The eof mark entries that ftape stores in the bad sector log: even
80 * 16-bit word: segment number of eof mark odd 16-bit word: sector
81 * number of eof mark [1..32]
83 * The zft_eof_map as maintained is a sorted list of eof mark entries.
86 * The tape name field in the header segments is used to store a linux
87 * tape identification string and a version number. This way the tape
88 * can be recognized as a Linux raw format tape when using tools under
91 * 'Wide' QIC tapes (format code 4) don't have a failed sector list
92 * anymore. That space is used for the (longer) bad sector map that
93 * now is a variable length list too. We now store our end-of-file
94 * marker list after the bad-sector-map on tape. The list is delimited
95 * by a (__u32) 0 entry.
98 int zft_ftape_validate_label(char *label
)
100 static char tmp_label
[45];
104 memcpy(tmp_label
, label
, FT_LABEL_SZ
);
105 tmp_label
[FT_LABEL_SZ
] = '\0';
106 TRACE(ft_t_noise
, "tape label = `%s'", tmp_label
);
107 ftape_fmt_version
= 0;
108 if (memcmp(label
, linux_tape_label
, strlen(linux_tape_label
)) == 0) {
109 int pos
= strlen(linux_tape_label
);
110 while (label
[pos
] >= '0' && label
[pos
] <= '9') {
111 ftape_fmt_version
*= 10;
112 ftape_fmt_version
= label
[ pos
++] - '0';
114 result
= (ftape_fmt_version
>= min_fmt_version
&&
115 ftape_fmt_version
<= max_fmt_version
);
117 TRACE(ft_t_noise
, "format version = %d", ftape_fmt_version
);
121 static __u8
* find_end_of_eof_list(__u8
* ptr
, __u8
* limit
)
123 while (ptr
+ 3 < limit
) {
125 if (get_unaligned((__u32
*)ptr
)) {
126 ptr
+= sizeof(__u32
);
134 void zft_ftape_extract_file_marks(__u8
* address
)
140 if (ft_format_code
== fmt_var
|| ft_format_code
== fmt_big
) {
142 __u8
* start
= ftape_find_end_of_bsm_list(address
);
144 zft_nr_eof_marks
= 0;
146 start
+= 3; /* skip end of list mark */
147 end
= find_end_of_eof_list(start
,
148 address
+ FT_SEGMENT_SIZE
);
149 if (end
&& end
- start
<= FT_FSL_SIZE
) {
150 zft_nr_eof_marks
= ((end
- start
) /
151 sizeof(eof_mark_union
));
152 zft_eof_map
= (eof_mark_union
*)start
;
155 "EOF Mark List is too long or damaged!");
159 "Bad Sector List is too long or damaged !");
162 zft_eof_map
= (eof_mark_union
*)&address
[FT_FSL
];
163 zft_nr_eof_marks
= GET2(address
, FT_FSL_CNT
);
165 TRACE(ft_t_noise
, "number of file marks: %d", zft_nr_eof_marks
);
166 if (ftape_fmt_version
== 1) {
167 TRACE(ft_t_info
, "swapping version 1 fields");
168 /* version 1 format uses swapped sector and segment
169 * fields, correct that !
171 for (i
= 0; i
< zft_nr_eof_marks
; ++i
) {
172 __u16 tmp
= GET2(&zft_eof_map
[i
].mark
.segment
,0);
173 PUT2(&zft_eof_map
[i
].mark
.segment
, 0,
174 GET2(&zft_eof_map
[i
].mark
.date
,0));
175 PUT2(&zft_eof_map
[i
].mark
.date
, 0, tmp
);
178 for (i
= 0; i
< zft_nr_eof_marks
; ++i
) {
179 TRACE(ft_t_noise
, "eof mark: %5d/%2d",
180 GET2(&zft_eof_map
[i
].mark
.segment
, 0),
181 GET2(&zft_eof_map
[i
].mark
.date
,0));
186 void zft_clear_ftape_file_marks(void)
188 TRACE_FUN(ft_t_flow
);
189 /* Clear failed sector log: remove all tape marks. We
190 * don't use old ftape-style EOF-marks.
192 TRACE(ft_t_info
, "Clearing old ftape's eof map");
193 memset(zft_eof_map
, 0, zft_nr_eof_marks
* sizeof(__u32
));
194 zft_nr_eof_marks
= 0;
195 PUT2(zft_hseg_buf
, FT_FSL_CNT
, 0); /* nr of eof-marks */
196 zft_header_changed
= 1;
197 zft_update_label(zft_hseg_buf
);