2 * Copyright (C) 1993-1996 Bas Laarhoven,
3 * 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-ctl.c,v $
22 * $Date: 1997/11/11 14:37:44 $
24 * This file contains the non-read/write ftape functions for the
25 * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
28 #include <linux/config.h>
29 #include <linux/errno.h>
31 #include <linux/mman.h>
33 #include <linux/ftape.h>
34 #include <linux/qic117.h>
35 #include <asm/uaccess.h>
38 /* ease porting between pre-2.4.x and later kernels */
39 #define vma_get_pgoff(v) ((v)->vm_pgoff)
41 #include "../lowlevel/ftape-tracing.h"
42 #include "../lowlevel/ftape-io.h"
43 #include "../lowlevel/ftape-ctl.h"
44 #include "../lowlevel/ftape-write.h"
45 #include "../lowlevel/ftape-read.h"
46 #include "../lowlevel/ftape-rw.h"
47 #include "../lowlevel/ftape-bsm.h"
51 ftape_info ftape_status
= {
52 /* vendor information */
53 { 0, }, /* drive type */
55 500, /* used data rate */
56 500, /* drive max rate */
57 500, /* fdc max rate */
58 /* drive selection, either FTAPE_SEL_A/B/C/D */
59 -1, /* drive selection */
60 /* flags set after decode the drive and tape status */
63 1, /* write protected */
65 /* values of last queried drive/tape status and error */
66 {{0,}}, /* last error code */
67 {{0,}}, /* drive status, configuration, tape status */
68 /* cartridge geometry */
69 20, /* tracks_per_tape */
70 102, /* segments_per_track */
71 /* location of header segments, etc. */
72 -1, /* used_header_segment */
73 -1, /* header_segment_1 */
74 -1, /* header_segment_2 */
75 -1, /* first_data_segment */
76 -1, /* last_data_segment */
77 /* the format code as stored in the header segment */
78 fmt_normal
, /* format code */
79 /* the default for the qic std: unknown */
81 /* is tape running? */
82 idle
, /* runner_state */
83 /* is tape reading/writing/verifying/formatting/deleting */
84 idle
, /* driver state */
85 /* flags fatal hardware error */
88 { 0, } /* history record */
91 int ftape_segments_per_head
= 1020;
92 int ftape_segments_per_cylinder
= 4;
93 int ftape_init_drive_needed
= 1; /* need to be global for ftape_reset_drive()
99 static const vendor_struct vendors
[] = QIC117_VENDORS
;
100 static const wakeup_method methods
[] = WAKEUP_METHODS
;
102 const ftape_info
*ftape_get_status(void)
104 #if defined(STATUS_PARANOYA)
105 static ftape_info get_status
;
107 get_status
= ftape_status
;
110 return &ftape_status
; /* maybe return only a copy of it to assure
116 static int ftape_not_operational(int status
)
118 /* return true if status indicates tape can not be used.
120 return ((status
^ QIC_STATUS_CARTRIDGE_PRESENT
) &
122 QIC_STATUS_CARTRIDGE_PRESENT
|
123 QIC_STATUS_NEW_CARTRIDGE
));
126 int ftape_seek_to_eot(void)
131 TRACE_CATCH(ftape_ready_wait(ftape_timeout
.pause
, &status
),);
132 while ((status
& QIC_STATUS_AT_EOT
) == 0) {
133 if (ftape_not_operational(status
)) {
136 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD
,
137 ftape_timeout
.rewind
,&status
),);
142 int ftape_seek_to_bot(void)
147 TRACE_CATCH(ftape_ready_wait(ftape_timeout
.pause
, &status
),);
148 while ((status
& QIC_STATUS_AT_BOT
) == 0) {
149 if (ftape_not_operational(status
)) {
152 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE
,
153 ftape_timeout
.rewind
,&status
),);
158 static int ftape_new_cartridge(void)
160 ft_location
.track
= -1; /* force seek on first access */
161 ftape_zap_read_buffers();
162 ftape_zap_write_buffers();
166 int ftape_abort_operation(void)
170 TRACE_FUN(ft_t_flow
);
172 if (ft_runner_status
== running
) {
173 TRACE(ft_t_noise
, "aborting runner, waiting");
175 ft_runner_status
= do_abort
;
176 /* set timeout so that the tape will run to logical EOT
177 * if we missed the last sector and there are no queue pulses.
179 result
= ftape_dumb_stop();
181 if (ft_runner_status
!= idle
) {
182 if (ft_runner_status
== do_abort
) {
183 TRACE(ft_t_noise
, "forcing runner abort");
185 TRACE(ft_t_noise
, "stopping tape");
186 result
= ftape_stop_tape(&status
);
187 ft_location
.known
= 0;
188 ft_runner_status
= idle
;
190 ftape_reset_buffer();
191 ftape_zap_read_buffers();
192 ftape_set_state(idle
);
196 static int lookup_vendor_id(unsigned int vendor_id
)
200 while (vendors
[i
].vendor_id
!= vendor_id
) {
201 if (++i
>= NR_ITEMS(vendors
)) {
208 static void ftape_detach_drive(void)
212 TRACE(ft_t_flow
, "disabling tape drive and fdc");
213 ftape_put_drive_to_sleep(ft_drive_type
.wake_up
);
214 fdc_catch_stray_interrupts(1); /* one always comes */
216 fdc_release_irq_and_dma();
217 fdc_release_regions();
221 static void clear_history(void)
224 ft_history
.id_am_errors
=
225 ft_history
.id_crc_errors
=
226 ft_history
.data_am_errors
=
227 ft_history
.data_crc_errors
=
228 ft_history
.overrun_errors
=
229 ft_history
.no_data_errors
=
231 ft_history
.crc_errors
=
232 ft_history
.crc_failures
=
233 ft_history
.ecc_failures
=
234 ft_history
.corrected
=
236 ft_history
.rewinds
= 0;
239 static int ftape_activate_drive(vendor_struct
* drive_type
)
242 TRACE_FUN(ft_t_flow
);
244 /* If we already know the drive type, wake it up.
245 * Else try to find out what kind of drive is attached.
247 if (drive_type
->wake_up
!= unknown_wake_up
) {
248 TRACE(ft_t_flow
, "enabling tape drive and fdc");
249 result
= ftape_wakeup_drive(drive_type
->wake_up
);
251 TRACE(ft_t_err
, "known wakeup method failed");
254 wake_up_types method
;
255 const ft_trace_t old_tracing
= TRACE_LEVEL
;
256 if (TRACE_LEVEL
< ft_t_flow
) {
257 SET_TRACE_LEVEL(ft_t_bug
);
260 /* Try to awaken the drive using all known methods.
261 * Lower tracing for a while.
263 for (method
=no_wake_up
; method
< NR_ITEMS(methods
); ++method
) {
264 drive_type
->wake_up
= method
;
265 #ifdef CONFIG_FT_TWO_DRIVES
266 /* Test setup for dual drive configuration.
267 * /dev/rft2 uses mountain wakeup
268 * /dev/rft3 uses colorado wakeup
269 * Other systems will use the normal scheme.
271 if ((ft_drive_sel
< 2) ||
272 (ft_drive_sel
== 2 && method
== FT_WAKE_UP_1
) ||
273 (ft_drive_sel
== 3 && method
== FT_WAKE_UP_2
)) {
274 result
=ftape_wakeup_drive(drive_type
->wake_up
);
279 result
= ftape_wakeup_drive(drive_type
->wake_up
);
282 TRACE(ft_t_warn
, "drive wakeup method: %s",
283 methods
[drive_type
->wake_up
].name
);
287 SET_TRACE_LEVEL(old_tracing
);
289 if (method
>= NR_ITEMS(methods
)) {
290 /* no response at all, cannot open this drive */
291 drive_type
->wake_up
= unknown_wake_up
;
292 TRACE(ft_t_err
, "no tape drive found !");
299 static int ftape_get_drive_status(void)
303 TRACE_FUN(ft_t_flow
);
305 ft_no_tape
= ft_write_protected
= 0;
306 /* Tape drive is activated now.
307 * First clear error status if present.
310 result
= ftape_ready_wait(ftape_timeout
.reset
, &status
);
312 if (result
== -ETIME
) {
313 TRACE(ft_t_err
, "ftape_ready_wait timeout");
314 } else if (result
== -EINTR
) {
315 TRACE(ft_t_err
, "ftape_ready_wait aborted");
317 TRACE(ft_t_err
, "ftape_ready_wait failed");
321 /* Clear error condition (drive is ready !)
323 if (status
& QIC_STATUS_ERROR
) {
325 qic117_cmd_t command
;
327 TRACE(ft_t_err
, "error status set");
328 result
= ftape_report_error(&error
, &command
, 1);
331 "report_error_code failed: %d", result
);
332 /* hope it's working next time */
335 } else if (error
!= 0) {
336 TRACE(ft_t_noise
, "error code : %d", error
);
337 TRACE(ft_t_noise
, "error command: %d", command
);
340 if (status
& QIC_STATUS_NEW_CARTRIDGE
) {
342 qic117_cmd_t command
;
343 const ft_trace_t old_tracing
= TRACE_LEVEL
;
344 SET_TRACE_LEVEL(ft_t_bug
);
346 /* Undocumented feature: Must clear (not present!)
347 * error here or we'll fail later.
349 ftape_report_error(&error
, &command
, 1);
351 SET_TRACE_LEVEL(old_tracing
);
352 TRACE(ft_t_info
, "status: new cartridge");
357 FT_SIGNAL_EXIT(_DONT_BLOCK
);
358 } while (status
& QIC_STATUS_ERROR
);
360 ft_no_tape
= !(status
& QIC_STATUS_CARTRIDGE_PRESENT
);
361 ft_write_protected
= (status
& QIC_STATUS_WRITE_PROTECT
) != 0;
363 TRACE(ft_t_warn
, "no cartridge present");
365 if (ft_write_protected
) {
366 TRACE(ft_t_noise
, "Write protected cartridge");
372 static void ftape_log_vendor_id(void)
375 TRACE_FUN(ft_t_flow
);
377 ftape_report_vendor_id(&ft_drive_type
.vendor_id
);
378 vendor_index
= lookup_vendor_id(ft_drive_type
.vendor_id
);
379 if (ft_drive_type
.vendor_id
== UNKNOWN_VENDOR
&&
380 ft_drive_type
.wake_up
== wake_up_colorado
) {
382 /* hack to get rid of all this mail */
383 ft_drive_type
.vendor_id
= 0;
385 if (vendor_index
< 0) {
386 /* Unknown vendor id, first time opening device. The
387 * drive_type remains set to type found at wakeup
388 * time, this will probably keep the driver operating
389 * for this new vendor.
391 TRACE(ft_t_warn
, "\n"
392 KERN_INFO
"============ unknown vendor id ===========\n"
393 KERN_INFO
"A new, yet unsupported tape drive is found\n"
394 KERN_INFO
"Please report the following values:\n"
395 KERN_INFO
" Vendor id : 0x%04x\n"
396 KERN_INFO
" Wakeup method : %s\n"
397 KERN_INFO
"And a description of your tape drive\n"
398 KERN_INFO
"to "THE_FTAPE_MAINTAINER
"\n"
399 KERN_INFO
"==========================================",
400 ft_drive_type
.vendor_id
,
401 methods
[ft_drive_type
.wake_up
].name
);
402 ft_drive_type
.speed
= 0; /* unknown */
404 ft_drive_type
.name
= vendors
[vendor_index
].name
;
405 ft_drive_type
.speed
= vendors
[vendor_index
].speed
;
406 TRACE(ft_t_info
, "tape drive type: %s", ft_drive_type
.name
);
407 /* scan all methods for this vendor_id in table */
408 while(ft_drive_type
.wake_up
!= vendors
[vendor_index
].wake_up
) {
409 if (vendor_index
< NR_ITEMS(vendors
) - 1 &&
410 vendors
[vendor_index
+ 1].vendor_id
412 ft_drive_type
.vendor_id
) {
418 if (ft_drive_type
.wake_up
!= vendors
[vendor_index
].wake_up
) {
419 TRACE(ft_t_warn
, "\n"
420 KERN_INFO
"==========================================\n"
421 KERN_INFO
"wakeup type mismatch:\n"
422 KERN_INFO
"found: %s, expected: %s\n"
423 KERN_INFO
"please report this to "THE_FTAPE_MAINTAINER
"\n"
424 KERN_INFO
"==========================================",
425 methods
[ft_drive_type
.wake_up
].name
,
426 methods
[vendors
[vendor_index
].wake_up
].name
);
432 void ftape_calc_timeouts(unsigned int qic_std
,
433 unsigned int data_rate
,
434 unsigned int tape_len
)
436 int speed
; /* deci-ips ! */
441 /* tape transport speed
442 * data rate: QIC-40 QIC-80 QIC-3010 QIC-3020
444 * 250 Kbps 25 ips n/a n/a n/a
445 * 500 Kbps 50 ips 34 ips 22.6 ips n/a
446 * 1 Mbps n/a 68 ips 45.2 ips 22.6 ips
447 * 2 Mbps n/a n/a n/a 45.2 ips
449 * fast tape transport speed is at least 68 ips.
453 speed
= (data_rate
== 250) ? 250 : 500;
456 speed
= (data_rate
== 500) ? 340 : 680;
458 case QIC_TAPE_QIC3010
:
459 speed
= (data_rate
== 500) ? 226 : 452;
461 case QIC_TAPE_QIC3020
:
462 speed
= (data_rate
== 1000) ? 226 : 452;
465 TRACE(ft_t_bug
, "Unknown qic_std (bug) ?");
469 if (ft_drive_type
.speed
== 0) {
471 static int dt
= 0; /* keep gcc from complaining */
472 static int first_time
= 1;
474 /* Measure the time it takes to wind to EOT and back to BOT.
475 * If the tape length is known, calculate the rewind speed.
476 * Else keep the time value for calculation of the rewind
477 * speed later on, when the length _is_ known.
478 * Ask for a report only when length and speed are both known.
485 dt
= (int) (((jiffies
- t0
) * FT_USPT
) / 1000);
487 dt
= 1; /* prevent div by zero on failures */
491 "trying to determine seek timeout, got %d msec",
495 ft_drive_type
.speed
=
496 (2 * 12 * tape_len
* 1000) / dt
;
497 TRACE(ft_t_warn
, "\n"
498 KERN_INFO
"==========================================\n"
499 KERN_INFO
"drive type: %s\n"
500 KERN_INFO
"delta time = %d ms, length = %d ft\n"
501 KERN_INFO
"has a maximum tape speed of %d ips\n"
502 KERN_INFO
"please report this to "THE_FTAPE_MAINTAINER
"\n"
503 KERN_INFO
"==========================================",
504 ft_drive_type
.name
, dt
, tape_len
,
505 ft_drive_type
.speed
);
508 /* Handle unknown length tapes as very long ones. We'll
509 * determine the actual length from a header segment later.
510 * This is normal for all modern (Wide,TR1/2/3) formats.
514 "Unknown tape length, using maximal timeouts");
515 length
= QIC_TOP_TAPE_LEN
; /* use worst case values */
517 length
= tape_len
; /* use actual values */
519 if (ft_drive_type
.speed
== 0) {
522 ff_speed
= ft_drive_type
.speed
;
524 /* time to go from bot to eot at normal speed (data rate):
525 * time = (1+delta) * length (ft) * 12 (inch/ft) / speed (ips)
526 * delta = 10 % for seek speed, 20 % for rewind speed.
528 ftape_timeout
.seek
= (length
* 132 * FT_SECOND
) / speed
;
529 ftape_timeout
.rewind
= (length
* 144 * FT_SECOND
) / (10 * ff_speed
);
530 ftape_timeout
.reset
= 20 * FT_SECOND
+ ftape_timeout
.rewind
;
531 TRACE(ft_t_noise
, "timeouts for speed = %d, length = %d\n"
532 KERN_INFO
"seek timeout : %d sec\n"
533 KERN_INFO
"rewind timeout: %d sec\n"
534 KERN_INFO
"reset timeout : %d sec",
536 (ftape_timeout
.seek
+ 500) / 1000,
537 (ftape_timeout
.rewind
+ 500) / 1000,
538 (ftape_timeout
.reset
+ 500) / 1000);
542 /* This function calibrates the datarate (i.e. determines the maximal
543 * usable data rate) and sets the global variable ft_qic_std to qic_std
546 int ftape_calibrate_data_rate(unsigned int qic_std
)
548 int rate
= ft_fdc_rate_limit
;
550 TRACE_FUN(ft_t_flow
);
552 ft_qic_std
= qic_std
;
554 if (ft_qic_std
== -1) {
555 TRACE_ABORT(-EIO
, ft_t_err
,
556 "Unable to determine data rate if QIC standard is unknown");
559 /* Select highest rate supported by both fdc and drive.
560 * Start with highest rate supported by the fdc.
562 while (fdc_set_data_rate(rate
) < 0 && rate
> 250) {
566 "Highest FDC supported data rate: %d Kbps", rate
);
567 ft_fdc_max_rate
= rate
;
569 result
= ftape_set_data_rate(rate
, ft_qic_std
);
570 } while (result
== -EINVAL
&& (rate
/= 2) > 250);
572 TRACE_ABORT(-EIO
, ft_t_err
, "set datarate failed");
578 static int ftape_init_drive(void)
582 unsigned int qic_std
;
583 unsigned int data_rate
;
584 TRACE_FUN(ft_t_flow
);
586 ftape_init_drive_needed
= 0; /* don't retry if this fails ? */
587 TRACE_CATCH(ftape_report_raw_drive_status(&status
),);
588 if (status
& QIC_STATUS_CARTRIDGE_PRESENT
) {
589 if (!(status
& QIC_STATUS_AT_BOT
)) {
590 /* Antique drives will get here after a soft reset,
591 * modern ones only if the driver is loaded when the
592 * tape wasn't rewound properly.
594 /* Tape should be at bot if new cartridge ! */
597 if (!(status
& QIC_STATUS_REFERENCED
)) {
598 TRACE(ft_t_flow
, "starting seek_load_point");
599 TRACE_CATCH(ftape_command_wait(QIC_SEEK_LOAD_POINT
,
604 ft_formatted
= (status
& QIC_STATUS_REFERENCED
) != 0;
606 TRACE(ft_t_warn
, "Warning: tape is not formatted !");
609 /* report configuration aborts when ftape_tape_len == -1
610 * unknown qic_std is okay if not formatted.
612 TRACE_CATCH(ftape_report_configuration(&model
,
617 /* Maybe add the following to the /proc entry
619 TRACE(ft_t_info
, "%s drive @ %d Kbps",
620 (model
== prehistoric
) ? "prehistoric" :
621 ((model
== pre_qic117c
) ? "pre QIC-117C" :
622 ((model
== post_qic117b
) ? "post QIC-117B" :
623 "post QIC-117D")), data_rate
);
626 /* initialize ft_used_data_rate to maximum value
629 TRACE_CATCH(ftape_calibrate_data_rate(qic_std
),);
630 if (ftape_tape_len
== 0) {
631 TRACE(ft_t_info
, "unknown length QIC-%s tape",
632 (ft_qic_std
== QIC_TAPE_QIC40
) ? "40" :
633 ((ft_qic_std
== QIC_TAPE_QIC80
) ? "80" :
634 ((ft_qic_std
== QIC_TAPE_QIC3010
)
635 ? "3010" : "3020")));
637 TRACE(ft_t_info
, "%d ft. QIC-%s tape", ftape_tape_len
,
638 (ft_qic_std
== QIC_TAPE_QIC40
) ? "40" :
639 ((ft_qic_std
== QIC_TAPE_QIC80
) ? "80" :
640 ((ft_qic_std
== QIC_TAPE_QIC3010
)
641 ? "3010" : "3020")));
643 ftape_calc_timeouts(ft_qic_std
, ft_data_rate
, ftape_tape_len
);
644 /* soft write-protect QIC-40/QIC-80 cartridges used with a
645 * Colorado T3000 drive. Buggy hardware!
647 if ((ft_drive_type
.vendor_id
== 0x011c6) &&
648 ((ft_qic_std
== QIC_TAPE_QIC40
||
649 ft_qic_std
== QIC_TAPE_QIC80
) &&
650 !ft_write_protected
)) {
651 TRACE(ft_t_warn
, "\n"
652 KERN_INFO
"The famous Colorado T3000 bug:\n"
653 KERN_INFO
"%s drives can't write QIC40 and QIC80\n"
654 KERN_INFO
"cartridges but don't set the write-protect flag!",
656 ft_write_protected
= 1;
659 /* Doesn't make too much sense to set the data rate
660 * because we don't know what to use for the write
662 * Need to do this again when formatting the cartridge.
664 ft_data_rate
= data_rate
;
665 ftape_calc_timeouts(QIC_TAPE_QIC40
,
669 ftape_new_cartridge();
673 static void ftape_munmap(void)
676 TRACE_FUN(ft_t_flow
);
678 for (i
= 0; i
< ft_nr_buffers
; i
++) {
679 ft_buffer
[i
]->mmapped
= 0;
684 /* Map the dma buffers into the virtual address range given by vma.
685 * We only check the caller doesn't map non-existent buffers. We
686 * don't check for multiple mappings.
688 int ftape_mmap(struct vm_area_struct
*vma
)
692 TRACE_FUN(ft_t_flow
);
697 if (!(vma
->vm_flags
& (VM_READ
|VM_WRITE
))) {
698 TRACE_ABORT(-EINVAL
, ft_t_err
, "Undefined mmap() access");
700 if (vma_get_pgoff(vma
) != 0) {
701 TRACE_ABORT(-EINVAL
, ft_t_err
, "page offset must be 0");
703 if ((vma
->vm_end
- vma
->vm_start
) % FT_BUFF_SIZE
!= 0) {
704 TRACE_ABORT(-EINVAL
, ft_t_err
,
705 "size = %ld, should be a multiple of %d",
706 vma
->vm_end
- vma
->vm_start
,
709 num_buffers
= (vma
->vm_end
- vma
->vm_start
) / FT_BUFF_SIZE
;
710 if (num_buffers
> ft_nr_buffers
) {
712 ft_t_err
, "size = %ld, should be less than %d",
713 vma
->vm_end
- vma
->vm_start
,
714 ft_nr_buffers
* FT_BUFF_SIZE
);
716 if (ft_driver_state
!= idle
) {
717 /* this also clears the buffer states
719 ftape_abort_operation();
721 ftape_reset_buffer();
723 for (i
= 0; i
< num_buffers
; i
++) {
726 pfn
= virt_to_phys(ft_buffer
[i
]->address
) >> PAGE_SHIFT
;
727 TRACE_CATCH(remap_pfn_range(vma
, vma
->vm_start
+
733 TRACE(ft_t_noise
, "remapped dma buffer @ %p to location @ %p",
734 ft_buffer
[i
]->address
,
735 (void *)(vma
->vm_start
+ i
* FT_BUFF_SIZE
));
737 for (i
= 0; i
< num_buffers
; i
++) {
738 memset(ft_buffer
[i
]->address
, 0xAA, FT_BUFF_SIZE
);
739 ft_buffer
[i
]->mmapped
++;
744 static void ftape_init_driver(void); /* forward declaration */
746 /* OPEN routine called by kernel-interface code
748 int ftape_enable(int drive_selection
)
752 if (ft_drive_sel
== -1 || ft_drive_sel
!= drive_selection
) {
753 /* Other selection than last time
757 ft_drive_sel
= FTAPE_SEL(drive_selection
);
759 TRACE_CATCH(fdc_init(),); /* init & detect fdc */
760 TRACE_CATCH(ftape_activate_drive(&ft_drive_type
),
762 fdc_release_irq_and_dma();
763 fdc_release_regions());
764 TRACE_CATCH(ftape_get_drive_status(), ftape_detach_drive());
765 if (ft_drive_type
.vendor_id
== UNKNOWN_VENDOR
) {
766 ftape_log_vendor_id();
769 ftape_init_drive_needed
= 1;
771 if (!ft_no_tape
&& ftape_init_drive_needed
) {
772 TRACE_CATCH(ftape_init_drive(), ftape_detach_drive());
774 ftape_munmap(); /* clear the mmap flag */
779 /* release routine called by the high level interface modules
782 void ftape_disable(void)
787 for (i
= 0; i
< ft_nr_buffers
; i
++) {
788 if (ft_buffer
[i
]->mmapped
) {
789 TRACE(ft_t_noise
, "first byte of buffer %d: 0x%02x",
790 i
, *ft_buffer
[i
]->address
);
793 if (sigtestsetmask(¤t
->pending
.signal
, _DONT_BLOCK
) &&
794 !(sigtestsetmask(¤t
->pending
.signal
, _NEVER_BLOCK
)) &&
795 ftape_tape_running
) {
797 "Interrupted by fatal signal and tape still running");
799 ftape_abort_operation(); /* it's annoying */
801 ftape_set_state(idle
);
803 ftape_detach_drive();
804 if (ft_history
.used
) {
805 TRACE(ft_t_info
, "== Non-fatal errors this run: ==");
806 TRACE(ft_t_info
, "fdc isr statistics:\n"
807 KERN_INFO
" id_am_errors : %3d\n"
808 KERN_INFO
" id_crc_errors : %3d\n"
809 KERN_INFO
" data_am_errors : %3d\n"
810 KERN_INFO
" data_crc_errors : %3d\n"
811 KERN_INFO
" overrun_errors : %3d\n"
812 KERN_INFO
" no_data_errors : %3d\n"
813 KERN_INFO
" retries : %3d",
814 ft_history
.id_am_errors
, ft_history
.id_crc_errors
,
815 ft_history
.data_am_errors
, ft_history
.data_crc_errors
,
816 ft_history
.overrun_errors
, ft_history
.no_data_errors
,
818 if (ft_history
.used
& 1) {
819 TRACE(ft_t_info
, "ecc statistics:\n"
820 KERN_INFO
" crc_errors : %3d\n"
821 KERN_INFO
" crc_failures : %3d\n"
822 KERN_INFO
" ecc_failures : %3d\n"
823 KERN_INFO
" sectors corrected: %3d",
824 ft_history
.crc_errors
, ft_history
.crc_failures
,
825 ft_history
.ecc_failures
, ft_history
.corrected
);
827 if (ft_history
.defects
> 0) {
828 TRACE(ft_t_warn
, "Warning: %d media defects!",
831 if (ft_history
.rewinds
> 0) {
832 TRACE(ft_t_info
, "tape motion statistics:\n"
833 KERN_INFO
"repositions : %3d",
841 static void ftape_init_driver(void)
843 TRACE_FUN(ft_t_flow
);
845 ft_drive_type
.vendor_id
= UNKNOWN_VENDOR
;
846 ft_drive_type
.speed
= 0;
847 ft_drive_type
.wake_up
= unknown_wake_up
;
848 ft_drive_type
.name
= "Unknown";
850 ftape_timeout
.seek
= 650 * FT_SECOND
;
851 ftape_timeout
.reset
= 670 * FT_SECOND
;
852 ftape_timeout
.rewind
= 650 * FT_SECOND
;
853 ftape_timeout
.head_seek
= 15 * FT_SECOND
;
854 ftape_timeout
.stop
= 5 * FT_SECOND
;
855 ftape_timeout
.pause
= 16 * FT_SECOND
;
858 ftape_tape_len
= 0; /* unknown */
859 ftape_current_command
= 0;
860 ftape_current_cylinder
= -1;
862 ft_segments_per_track
= 102;
863 ftape_segments_per_head
= 1020;
864 ftape_segments_per_cylinder
= 4;
865 ft_tracks_per_tape
= 20;
871 ft_write_protected
= 1;
874 ft_driver_state
= idle
;
877 ft_fdc_max_rate
= 500;
878 ft_drive_max_rate
= 0; /* triggers set_rate_test() */
880 ftape_init_drive_needed
= 1;
882 ft_header_segment_1
= -1;
883 ft_header_segment_2
= -1;
884 ft_used_header_segment
= -1;
885 ft_first_data_segment
= -1;
886 ft_last_data_segment
= -1;
888 ft_location
.track
= -1;
889 ft_location
.known
= 0;
891 ftape_tape_running
= 0;
892 ftape_might_be_off_track
= 1;
894 ftape_new_cartridge(); /* init some tape related variables */