This source file includes following definitions.
- ftape_zap_read_buffers
- convert_sector_map
- correct_and_copy
- read_segment
- read_header_segment
- _ftape_read
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <linux/module.h>
30 #include <linux/string.h>
31 #include <linux/errno.h>
32 #include <linux/mm.h>
33 #include <linux/ftape.h>
34 #include <asm/segment.h>
35
36 #include "tracing.h"
37 #include "ftape-read.h"
38 #include "qic117.h"
39 #include "ftape-io.h"
40 #include "ftape-ctl.h"
41 #include "ftape-rw.h"
42 #include "ftape-write.h"
43 #include "ftape-eof.h"
44 #include "ecc.h"
45 #include "ftape-bsm.h"
46
47
48
49
50
51
52 int buf_pos_rd = 0;
53 int buf_len_rd = 0;
54
55 void ftape_zap_read_buffers(void)
56 {
57 int i;
58
59 for (i = 0; i < NR_BUFFERS; ++i) {
60
61
62
63 buffer[i].address = tape_buffer[i];
64 buffer[i].status = waiting;
65 buffer[i].bytes = 0;
66 buffer[i].skip = 0;
67 buffer[i].retry = 0;
68 }
69 buf_len_rd = 0;
70 buf_pos_rd = 0;
71 eof_mark = 0;
72 ftape_state = idle;
73 }
74
75 static unsigned long convert_sector_map(buffer_struct * buff)
76 {
77 TRACE_FUN(8, "convert_sector_map");
78 int i = 0;
79 unsigned long bad_map = get_bad_sector_entry(buff->segment_id);
80 unsigned long src_map = buff->soft_error_map | buff->hard_error_map;
81 unsigned long dst_map = 0;
82
83 if (bad_map || src_map) {
84 TRACEx1(5, "bad_map = 0x%08lx", bad_map);
85 TRACEx1(5, "src_map = 0x%08lx", src_map);
86 }
87 while (bad_map) {
88 while ((bad_map & 1) == 0) {
89 if (src_map & 1) {
90 dst_map |= (1 << i);
91 }
92 src_map >>= 1;
93 bad_map >>= 1;
94 ++i;
95 }
96
97 src_map >>= 1;
98 bad_map >>= 1;
99 }
100 if (src_map) {
101 dst_map |= (src_map << i);
102 }
103 if (dst_map) {
104 TRACEx1(5, "dst_map = 0x%08lx", dst_map);
105 }
106 TRACE_EXIT;
107 return dst_map;
108 }
109
110 int correct_and_copy(unsigned int tail, byte * destination)
111 {
112 TRACE_FUN(8, "correct_and_copy");
113 struct memory_segment mseg;
114 int result;
115 BAD_SECTOR read_bad;
116
117 mseg.read_bad = convert_sector_map(&buffer[tail]);
118 mseg.marked_bad = 0;
119 mseg.blocks = buffer[tail].bytes / SECTOR_SIZE;
120 mseg.data = buffer[tail].address;
121
122
123 if (mseg.blocks <= 3) {
124 TRACE(4, "empty segment");
125 TRACE_EXIT;
126 return 0;
127 }
128 read_bad = mseg.read_bad;
129 history.crc_errors += count_ones(read_bad);
130 result = ecc_correct_data(&mseg);
131 if (read_bad != 0 || mseg.corrected != 0) {
132 TRACElx(4, "crc error map:", read_bad);
133 TRACElx(4, "corrected map:", mseg.corrected);
134 history.corrected += count_ones(mseg.corrected);
135 }
136 if (result == ECC_CORRECTED || result == ECC_OK) {
137 if (result == ECC_CORRECTED) {
138 TRACEi(3, "ecc corrected segment:", buffer[tail].segment_id);
139 }
140 memcpy(destination, mseg.data, (mseg.blocks - 3) * SECTOR_SIZE);
141 if ((read_bad ^ mseg.corrected) & mseg.corrected) {
142
143 history.crc_failures++;
144 }
145 TRACE_EXIT;
146 return (mseg.blocks - 3) * SECTOR_SIZE;
147 } else {
148 TRACEi(1, "ecc failure on segment", buffer[tail].segment_id);
149 history.ecc_failures++;
150 TRACE_EXIT;
151 return -EAGAIN;
152 }
153 TRACE_EXIT;
154 return 0;
155 }
156
157
158
159 int read_segment(unsigned segment_id, byte * address, int *eof_mark,
160 int read_ahead)
161 {
162 TRACE_FUN(5, "read_segment");
163 int read_done = 0;
164 int result = 0;
165 int bytes_read = 0;
166 int retry = 0;
167
168 TRACEi(5, "segment_id =", segment_id);
169 if (ftape_state != reading) {
170 if (ftape_state == writing) {
171 ftape_flush_buffers();
172 TRACE(5, "calling ftape_abort_operation");
173 result = ftape_abort_operation();
174 if (result < 0) {
175 TRACE(1, "ftape_abort_operation failed");
176 TRACE_EXIT;
177 return -EIO;
178 }
179 } else {
180
181 ftape_zap_read_buffers();
182 }
183 ftape_state = reading;
184 }
185 if (segment_id >= segments_per_track * tracks_per_tape) {
186 TRACE(5, "reading past end of tape");
187 TRACE_EXIT;
188 return -ENOSPC;
189 }
190 for (;;) {
191
192
193
194 while (!read_done && buffer[tail].status == done) {
195 if (buffer[tail].segment_id == segment_id) {
196 unsigned eof_sector;
197 unsigned sector_count = 0;
198 unsigned long bsm = get_bad_sector_entry(segment_id);
199 int i;
200
201
202
203 if (buffer[tail].deleted) {
204 TRACEi(5, "found segment in cache :", segment_id);
205 TRACE_EXIT;
206
207
208
209
210 return 0;
211 }
212 TRACEi(5, "found segment in cache :", segment_id);
213 eof_sector = check_for_eof(segment_id);
214 if (eof_sector > 0) {
215 TRACEi(5, "end of file mark in sector:", eof_sector);
216 for (i = 1; i < eof_sector; ++i) {
217 if ((bsm & 1) == 0) {
218 ++sector_count;
219 }
220 bsm >>= 1;
221 }
222 *eof_mark = 1;
223 }
224 if (eof_sector != 1) {
225 result = correct_and_copy(tail, address);
226 TRACEi(5, "segment contains (bytes) :", result);
227 if (result < 0) {
228 if (result != -EAGAIN) {
229 TRACE_EXIT;
230 return result;
231 }
232
233
234
235 TRACE(1, "ecc failed, retry");
236 ++retry;
237 } else {
238 read_done = 1;
239 }
240 } else {
241 read_done = 1;
242 }
243 if (eof_sector > 0) {
244 bytes_read = sector_count * SECTOR_SIZE;
245 TRACEi(5, "partial read count:", bytes_read);
246 } else {
247 bytes_read = result;
248 }
249 } else {
250 TRACEi(5, "zapping segment in cache :", buffer[tail].segment_id);
251 }
252 buffer[tail].status = waiting;
253 next_buffer(&tail);
254 }
255 if (!read_done && buffer[tail].status == reading) {
256 if (buffer[tail].segment_id == segment_id) {
257 int result = wait_segment(reading);
258 if (result < 0) {
259 if (result == -EINTR) {
260 TRACE_EXIT;
261 return result;
262 }
263 TRACE(1, "wait_segment failed while reading");
264 ftape_abort_operation();
265 }
266 } else {
267
268
269 ftape_abort_operation();
270 }
271 }
272
273
274 if (runner_status == logical_eot) {
275 int status;
276 result = ftape_ready_wait(timeout.seek, &status);
277 if (result < 0) {
278 TRACE(1, "ftape_ready_wait waiting for eot/bot failed");
279 }
280 if ((status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) == 0) {
281 TRACE(1, "eot/bot not reached");
282 }
283 runner_status = end_of_tape;
284 }
285
286
287 if (runner_status == aborting || runner_status == buffer_overrun ||
288 runner_status == end_of_tape) {
289 if (runner_status != end_of_tape &&
290 !(runner_status == aborting && !tape_running)) {
291 ftape_dumb_stop();
292 }
293 if (runner_status == aborting) {
294 if (buffer[head].status == reading || buffer[head].status == error) {
295 if (buffer[head].status == error) {
296 history.defects += count_ones(buffer[head].hard_error_map);
297 }
298 buffer[head].status = waiting;
299 }
300 }
301 runner_status = idle;
302 }
303
304
305
306 if (get_bad_sector_entry(segment_id) == EMPTY_SEGMENT) {
307 bytes_read = 0;
308 read_done = 1;
309 }
310
311
312 if (current->signal & _DONT_BLOCK) {
313 TRACE(2, "interrupted by non-blockable signal");
314 TRACE_EXIT;
315 return -EINTR;
316 }
317
318
319 if (read_done) {
320 break;
321 }
322 if (retry > RETRIES_ON_ECC_ERROR) {
323 history.defects++;
324 TRACE(1, "too many retries on ecc failure");
325 TRACE_EXIT;
326 return -ENODATA;
327 }
328
329
330
331 TRACEx3(8, "head: %d, tail: %d, runner_status: %d",
332 head, tail, runner_status);
333 TRACEx2(8, "buffer[].status, [head]: %d, [tail]: %d",
334 buffer[head].status, buffer[tail].status);
335 if (buffer[tail].status == waiting) {
336 setup_new_segment(&buffer[head], segment_id, -1);
337 if (!read_ahead) {
338 buffer[head].next_segment = 0;
339 }
340 calc_next_cluster(&buffer[head]);
341 if (runner_status == idle) {
342 result = ftape_start_tape(segment_id,
343 buffer[head].sector_offset);
344 if (result < 0) {
345 TRACEx1(1, "Error: segment %d unreachable", segment_id);
346 TRACE_EXIT;
347 return result;
348 }
349 runner_status = running;
350 }
351 buffer[head].status = reading;
352 setup_fdc_and_dma(&buffer[head], FDC_READ);
353 }
354 }
355 if (read_done) {
356 TRACE_EXIT;
357 return bytes_read;
358 } else {
359 TRACE(1, "too many retries");
360 TRACE_EXIT;
361 return -EIO;
362 }
363 }
364
365 int read_header_segment(byte * address)
366 {
367 TRACE_FUN(5, "read_header_segment");
368 int i;
369 int result;
370 int header_segment = -1;
371 unsigned int max_floppy_side;
372 unsigned int max_floppy_track;
373 unsigned int max_floppy_sector;
374 int first_failed = 0;
375 int status;
376 int new_tape_len;
377
378 result = ftape_report_drive_status(&status);
379 if (result < 0) {
380 TRACE(1, "error: error_status or report failure");
381 TRACE_EXIT;
382 return -EIO;
383 }
384 TRACE(5, "reading...");
385 ftape_last_segment.id = 68;
386
387
388
389
390
391 used_header_segment = -1;
392 result = 0;
393 for (header_segment = 0;
394 header_segment < ftape_last_segment.id && result == 0;
395 ++header_segment) {
396
397
398
399 result = read_segment(header_segment, address, &status, 0);
400 if (result < 0 && !first_failed) {
401 TRACE(1, "header segment damaged, trying backup");
402 first_failed = 1;
403 result = 0;
404 }
405 }
406 if (result < 0 || header_segment >= ftape_last_segment.id) {
407 TRACE(1, "no readable header segment found");
408 TRACE_EXIT;
409 return -EIO;
410 }
411 result = ftape_abort_operation();
412 if (result < 0) {
413 TRACE(1, "ftape_abort_operation failed");
414 TRACE_EXIT;
415 return -EIO;
416 }
417 if (GET4(address, 0) != 0xaa55aa55) {
418 TRACE(1, "wrong signature in header segment");
419 TRACE_EXIT;
420 return -EIO;
421 }
422 header_segment_1 = GET2(address, 6);
423 header_segment_2 = GET2(address, 8);
424 TRACEx2(2, "header segments are %d and %d",
425 header_segment_1, header_segment_2);
426 used_header_segment = (first_failed) ? header_segment_2 : header_segment_1;
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 format_code = (format_type) * (address + 4);
442 segments_per_track = GET2(address, 24);
443 tracks_per_tape = *(address + 26);
444 max_floppy_side = *(address + 27);
445 max_floppy_track = *(address + 28);
446 max_floppy_sector = *(address + 29);
447 TRACEx6(4, "(fmt/spt/tpc/fhm/ftm/fsm) = %d/%d/%d/%d/%d/%d",
448 format_code, segments_per_track, tracks_per_tape,
449 max_floppy_side, max_floppy_track, max_floppy_sector);
450 new_tape_len = tape_len;
451 switch (format_code) {
452 case fmt_425ft:
453 new_tape_len = 425;
454 break;
455 case fmt_normal:
456 if (tape_len == 0) {
457 new_tape_len = 205;
458 }
459 break;
460 case fmt_1100ft:
461 new_tape_len = 1100;
462 break;
463 case fmt_wide:{
464 int segments_per_1000_inch = 1;
465 switch (qic_std) {
466 case QIC_TAPE_QIC40:
467 segments_per_1000_inch = 332;
468 break;
469 case QIC_TAPE_QIC80:
470 segments_per_1000_inch = 488;
471 break;
472 case QIC_TAPE_QIC3010:
473 segments_per_1000_inch = 730;
474 break;
475 case QIC_TAPE_QIC3020:
476 segments_per_1000_inch = 1430;
477 break;
478 }
479 new_tape_len = (1000 * segments_per_track +
480 (segments_per_1000_inch - 1)) / segments_per_1000_inch;
481 break;
482 }
483 default:
484 TRACE(1, "unknown tape format, please report !");
485 TRACE_EXIT;
486 return -EIO;
487 }
488 if (new_tape_len != tape_len) {
489 tape_len = new_tape_len;
490 TRACEx1(1, "calculated tape length is %d ft", tape_len);
491 ftape_calc_timeouts();
492 }
493 if (segments_per_track == 0 && tracks_per_tape == 0 &&
494 max_floppy_side == 0 && max_floppy_track == 0 &&
495 max_floppy_sector == 0) {
496
497
498 segments_per_track = 68;
499 tracks_per_tape = 20;
500 max_floppy_side = 1;
501 max_floppy_track = 169;
502 max_floppy_sector = 128;
503 }
504
505
506
507 if (segments_per_track == 150 &&
508 tracks_per_tape == 28 &&
509 max_floppy_side == 7 &&
510 max_floppy_track == 149 &&
511 max_floppy_sector == 128) {
512 TRACE(-1, "the famous CONNER bug: max_floppy_side off by one !");
513 max_floppy_side = 6;
514 }
515
516
517
518 if (segments_per_track == 150 &&
519 tracks_per_tape == 28 &&
520 max_floppy_side == 6 &&
521 max_floppy_track == 150 &&
522 max_floppy_sector == 128) {
523 TRACE(-1, "the famous Colorado bug: max_floppy_track off by one !");
524 max_floppy_track = 149;
525 }
526 segments_per_head = ((max_floppy_sector / SECTORS_PER_SEGMENT) *
527 (max_floppy_track + 1));
528
529
530
531 if (segments_per_head == 0 || segments_per_cylinder == 0 ||
532 ((segments_per_track * tracks_per_tape - 1) / segments_per_head
533 != max_floppy_side) ||
534 (segments_per_head / segments_per_cylinder - 1 != max_floppy_track) ||
535 (segments_per_cylinder * SECTORS_PER_SEGMENT != max_floppy_sector)
536 #ifdef TESTING
537 || (format_code == 4 && (max_floppy_track != 254 || max_floppy_sector != 128))
538 #endif
539 ) {
540 TRACE(1, "Tape parameters inconsistency, please report");
541 TRACE_EXIT;
542 return -EIO;
543 }
544 first_data_segment = GET2(address, 10);
545 TRACEi(4, "first data segment:", first_data_segment);
546 extract_bad_sector_map(address);
547
548
549
550 ftape_last_segment.size = 0;
551 for (i = segments_per_track * tracks_per_tape - 1; i >= 0; --i) {
552 int space = SECTORS_PER_SEGMENT - 3 - count_ones(get_bad_sector_entry(i));
553 if (space > 0) {
554 ftape_last_segment.size += space;
555 ftape_last_segment.free = (ftape_last_segment.size -
556 sizeof(deblock_buffer) / SECTOR_SIZE);
557 if (ftape_last_segment.free >= 0) {
558 ftape_last_segment.id = i;
559 TRACEx2(4, "`last' segment is %d, %d Kb",
560 ftape_last_segment.id, ftape_last_segment.size);
561 break;
562 }
563 }
564 }
565
566
567 if (!ftape_validate_label(&deblock_buffer[30])) {
568 TRACE(-1, "This tape has no `Linux raw format' label,\n"
569 "***** Use `mt' to erase this tape if you want to use file marks !");
570 } else {
571 extract_file_marks(address);
572 }
573 ftape_reset_position();
574 TRACE_EXIT;
575 return 0;
576 }
577
578 int _ftape_read(char *buff, int req_len)
579 {
580 TRACE_FUN(5, "_ftape_read");
581 int result = 0;
582 int cnt;
583 int to_do = req_len;
584 static int remaining;
585 int bytes_read = 0;
586
587 if (ftape_offline || !formatted || no_tape) {
588 TRACEx3(-1, "offline = %d, formatted = %d, no_tape = %d",
589 ftape_offline, formatted, no_tape);
590 result = -EIO;
591 } else {
592 history.used |= 1;
593 if (first_data_segment == -1) {
594 result = read_header_segment(deblock_buffer);
595 }
596 }
597 if (result < 0) {
598 TRACE_EXIT;
599 return result;
600 }
601
602
603
604
605 while (to_do > 0) {
606
607
608
609
610
611
612
613 if (!eof_mark && ftape_seg_pos - 1 >= ftape_last_segment.id) {
614 TRACEi(5, "remaining of last segment:", remaining);
615 if (to_do > remaining) {
616 to_do = remaining;
617 TRACE(5, "clipped request to remaining");
618 }
619 }
620 while (!eof_mark && buf_len_rd == 0) {
621
622
623 if (ftape_seg_pos == ftape_last_segment.id) {
624 remaining = sizeof(deblock_buffer);
625 TRACEi(5, "remaining set to:", remaining);
626 }
627 result = read_segment(ftape_seg_pos, deblock_buffer, &eof_mark, 1);
628 if (result < 0) {
629 if (result == -ENODATA) {
630
631
632 ++ftape_seg_pos;
633 }
634 TRACEx1(4, "read_segment result: %d", result);
635 TRACE_EXIT;
636 return result;
637 }
638
639
640 if (current->signal & _DONT_BLOCK) {
641 TRACE(2, "interrupted by non-blockable signal");
642 TRACE_EXIT;
643 return -EINTR;
644 }
645 buf_pos_rd = 0;
646 buf_len_rd = result;
647 ++ftape_seg_pos;
648 }
649
650
651 cnt = (buf_len_rd < to_do) ? buf_len_rd : to_do;
652 TRACEi(7, "nr bytes just read:", cnt);
653 if (cnt > 0) {
654 result = verify_area(VERIFY_WRITE, buff, cnt);
655 if (result) {
656 TRACEx1(1, "verify_area failed, exitcode = %d", result);
657 TRACE_EXIT;
658 return -EIO;
659 }
660 memcpy_tofs(buff, deblock_buffer + buf_pos_rd, cnt);
661 buff += cnt;
662 to_do -= cnt;
663 remaining -= cnt;
664 bytes_read += cnt;
665 buf_pos_rd += cnt;
666 buf_len_rd -= cnt;
667 }
668 if (eof_mark && buf_len_rd == 0) {
669 TRACE(5, "partial count because of eof mark");
670 if (bytes_read == 0) {
671 eof_mark = 0;
672 }
673 break;
674 }
675 }
676 TRACE_EXIT;
677 return bytes_read;
678 }