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>
32 #include <linux/wrapper.h>
34 #include <linux/ftape.h>
35 #include <linux/qic117.h>
36 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,6)
37 #include <asm/uaccess.h>
39 #include <asm/segment.h>
43 #include "../lowlevel/ftape-tracing.h"
44 #include "../lowlevel/ftape-io.h"
45 #include "../lowlevel/ftape-ctl.h"
46 #include "../lowlevel/ftape-write.h"
47 #include "../lowlevel/ftape-read.h"
48 #include "../lowlevel/ftape-rw.h"
49 #include "../lowlevel/ftape-bsm.h"
53 ftape_info ftape_status
= {
54 /* vendor information */
55 { 0, }, /* drive type */
57 500, /* used data rate */
58 500, /* drive max rate */
59 500, /* fdc max rate */
60 /* drive selection, either FTAPE_SEL_A/B/C/D */
61 -1, /* drive selection */
62 /* flags set after decode the drive and tape status */
65 1, /* write protected */
67 /* values of last queried drive/tape status and error */
68 {{0,}}, /* last error code */
69 {{0,}}, /* drive status, configuration, tape status */
70 /* cartridge geometry */
71 20, /* tracks_per_tape */
72 102, /* segments_per_track */
73 /* location of header segments, etc. */
74 -1, /* used_header_segment */
75 -1, /* header_segment_1 */
76 -1, /* header_segment_2 */
77 -1, /* first_data_segment */
78 -1, /* last_data_segment */
79 /* the format code as stored in the header segment */
80 fmt_normal
, /* format code */
81 /* the default for the qic std: unknown */
83 /* is tape running? */
84 idle
, /* runner_state */
85 /* is tape reading/writing/verifying/formatting/deleting */
86 idle
, /* driver state */
87 /* flags fatal hardware error */
90 { 0, } /* history record */
93 int ftape_segments_per_head
= 1020;
94 int ftape_segments_per_cylinder
= 4;
95 int ftape_init_drive_needed
= 1; /* need to be global for ftape_reset_drive()
101 static const vendor_struct vendors
[] = QIC117_VENDORS
;
102 static const wakeup_method methods
[] = WAKEUP_METHODS
;
104 const ftape_info
*ftape_get_status(void)
106 #if defined(STATUS_PARANOYA)
107 static ftape_info get_status
;
109 get_status
= ftape_status
;
112 return &ftape_status
; /* maybe return only a copy of it to assure
118 void ftape_set_status(const ftape_info
*status
)
120 ftape_status
= *status
;
123 static int ftape_not_operational(int status
)
125 /* return true if status indicates tape can not be used.
127 return ((status
^ QIC_STATUS_CARTRIDGE_PRESENT
) &
129 QIC_STATUS_CARTRIDGE_PRESENT
|
130 QIC_STATUS_NEW_CARTRIDGE
));
133 int ftape_seek_to_eot(void)
138 TRACE_CATCH(ftape_ready_wait(ftape_timeout
.pause
, &status
),);
139 while ((status
& QIC_STATUS_AT_EOT
) == 0) {
140 if (ftape_not_operational(status
)) {
143 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD
,
144 ftape_timeout
.rewind
,&status
),);
149 int ftape_seek_to_bot(void)
154 TRACE_CATCH(ftape_ready_wait(ftape_timeout
.pause
, &status
),);
155 while ((status
& QIC_STATUS_AT_BOT
) == 0) {
156 if (ftape_not_operational(status
)) {
159 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE
,
160 ftape_timeout
.rewind
,&status
),);
165 static int ftape_new_cartridge(void)
167 ft_location
.track
= -1; /* force seek on first access */
168 ftape_zap_read_buffers();
169 ftape_zap_write_buffers();
173 int ftape_abort_operation(void)
177 TRACE_FUN(ft_t_flow
);
179 if (ft_runner_status
== running
) {
180 TRACE(ft_t_noise
, "aborting runner, waiting");
182 ft_runner_status
= do_abort
;
183 /* set timeout so that the tape will run to logical EOT
184 * if we missed the last sector and there are no queue pulses.
186 result
= ftape_dumb_stop();
188 if (ft_runner_status
!= idle
) {
189 if (ft_runner_status
== do_abort
) {
190 TRACE(ft_t_noise
, "forcing runner abort");
192 TRACE(ft_t_noise
, "stopping tape");
193 result
= ftape_stop_tape(&status
);
194 ft_location
.known
= 0;
195 ft_runner_status
= idle
;
197 ftape_reset_buffer();
198 ftape_zap_read_buffers();
199 ftape_set_state(idle
);
203 static int lookup_vendor_id(unsigned int vendor_id
)
207 while (vendors
[i
].vendor_id
!= vendor_id
) {
208 if (++i
>= NR_ITEMS(vendors
)) {
215 void ftape_detach_drive(void)
219 TRACE(ft_t_flow
, "disabling tape drive and fdc");
220 ftape_put_drive_to_sleep(ft_drive_type
.wake_up
);
221 fdc_catch_stray_interrupts(1); /* one always comes */
223 fdc_release_irq_and_dma();
224 fdc_release_regions();
228 static void clear_history(void)
231 ft_history
.id_am_errors
=
232 ft_history
.id_crc_errors
=
233 ft_history
.data_am_errors
=
234 ft_history
.data_crc_errors
=
235 ft_history
.overrun_errors
=
236 ft_history
.no_data_errors
=
238 ft_history
.crc_errors
=
239 ft_history
.crc_failures
=
240 ft_history
.ecc_failures
=
241 ft_history
.corrected
=
243 ft_history
.rewinds
= 0;
246 int ftape_activate_drive(vendor_struct
* drive_type
)
249 TRACE_FUN(ft_t_flow
);
251 /* If we already know the drive type, wake it up.
252 * Else try to find out what kind of drive is attached.
254 if (drive_type
->wake_up
!= unknown_wake_up
) {
255 TRACE(ft_t_flow
, "enabling tape drive and fdc");
256 result
= ftape_wakeup_drive(drive_type
->wake_up
);
258 TRACE(ft_t_err
, "known wakeup method failed");
261 wake_up_types method
;
262 const ft_trace_t old_tracing
= TRACE_LEVEL
;
263 if (TRACE_LEVEL
< ft_t_flow
) {
264 SET_TRACE_LEVEL(ft_t_bug
);
267 /* Try to awaken the drive using all known methods.
268 * Lower tracing for a while.
270 for (method
=no_wake_up
; method
< NR_ITEMS(methods
); ++method
) {
271 drive_type
->wake_up
= method
;
272 #ifdef CONFIG_FT_TWO_DRIVES
273 /* Test setup for dual drive configuration.
274 * /dev/rft2 uses mountain wakeup
275 * /dev/rft3 uses colorado wakeup
276 * Other systems will use the normal scheme.
278 if ((ft_drive_sel
< 2) ||
279 (ft_drive_sel
== 2 && method
== FT_WAKE_UP_1
) ||
280 (ft_drive_sel
== 3 && method
== FT_WAKE_UP_2
)) {
281 result
=ftape_wakeup_drive(drive_type
->wake_up
);
286 result
= ftape_wakeup_drive(drive_type
->wake_up
);
289 TRACE(ft_t_warn
, "drive wakeup method: %s",
290 methods
[drive_type
->wake_up
].name
);
294 SET_TRACE_LEVEL(old_tracing
);
296 if (method
>= NR_ITEMS(methods
)) {
297 /* no response at all, cannot open this drive */
298 drive_type
->wake_up
= unknown_wake_up
;
299 TRACE(ft_t_err
, "no tape drive found !");
306 int ftape_get_drive_status(void)
310 TRACE_FUN(ft_t_flow
);
312 ft_no_tape
= ft_write_protected
= 0;
313 /* Tape drive is activated now.
314 * First clear error status if present.
317 result
= ftape_ready_wait(ftape_timeout
.reset
, &status
);
319 if (result
== -ETIME
) {
320 TRACE(ft_t_err
, "ftape_ready_wait timeout");
321 } else if (result
== -EINTR
) {
322 TRACE(ft_t_err
, "ftape_ready_wait aborted");
324 TRACE(ft_t_err
, "ftape_ready_wait failed");
328 /* Clear error condition (drive is ready !)
330 if (status
& QIC_STATUS_ERROR
) {
332 qic117_cmd_t command
;
334 TRACE(ft_t_err
, "error status set");
335 result
= ftape_report_error(&error
, &command
, 1);
338 "report_error_code failed: %d", result
);
339 /* hope it's working next time */
342 } else if (error
!= 0) {
343 TRACE(ft_t_noise
, "error code : %d", error
);
344 TRACE(ft_t_noise
, "error command: %d", command
);
347 if (status
& QIC_STATUS_NEW_CARTRIDGE
) {
349 qic117_cmd_t command
;
350 const ft_trace_t old_tracing
= TRACE_LEVEL
;
351 SET_TRACE_LEVEL(ft_t_bug
);
353 /* Undocumented feature: Must clear (not present!)
354 * error here or we'll fail later.
356 ftape_report_error(&error
, &command
, 1);
358 SET_TRACE_LEVEL(old_tracing
);
359 TRACE(ft_t_info
, "status: new cartridge");
364 FT_SIGNAL_EXIT(_DONT_BLOCK
);
365 } while (status
& QIC_STATUS_ERROR
);
367 ft_no_tape
= !(status
& QIC_STATUS_CARTRIDGE_PRESENT
);
368 ft_write_protected
= (status
& QIC_STATUS_WRITE_PROTECT
) != 0;
370 TRACE(ft_t_warn
, "no cartridge present");
372 if (ft_write_protected
) {
373 TRACE(ft_t_noise
, "Write protected cartridge");
379 void ftape_log_vendor_id(void)
382 TRACE_FUN(ft_t_flow
);
384 ftape_report_vendor_id(&ft_drive_type
.vendor_id
);
385 vendor_index
= lookup_vendor_id(ft_drive_type
.vendor_id
);
386 if (ft_drive_type
.vendor_id
== UNKNOWN_VENDOR
&&
387 ft_drive_type
.wake_up
== wake_up_colorado
) {
389 /* hack to get rid of all this mail */
390 ft_drive_type
.vendor_id
= 0;
392 if (vendor_index
< 0) {
393 /* Unknown vendor id, first time opening device. The
394 * drive_type remains set to type found at wakeup
395 * time, this will probably keep the driver operating
396 * for this new vendor.
398 TRACE(ft_t_warn
, "\n"
399 KERN_INFO
"============ unknown vendor id ===========\n"
400 KERN_INFO
"A new, yet unsupported tape drive is found\n"
401 KERN_INFO
"Please report the following values:\n"
402 KERN_INFO
" Vendor id : 0x%04x\n"
403 KERN_INFO
" Wakeup method : %s\n"
404 KERN_INFO
"And a description of your tape drive\n"
405 KERN_INFO
"to "THE_FTAPE_MAINTAINER
"\n"
406 KERN_INFO
"==========================================",
407 ft_drive_type
.vendor_id
,
408 methods
[ft_drive_type
.wake_up
].name
);
409 ft_drive_type
.speed
= 0; /* unknown */
411 ft_drive_type
.name
= vendors
[vendor_index
].name
;
412 ft_drive_type
.speed
= vendors
[vendor_index
].speed
;
413 TRACE(ft_t_info
, "tape drive type: %s", ft_drive_type
.name
);
414 /* scan all methods for this vendor_id in table */
415 while(ft_drive_type
.wake_up
!= vendors
[vendor_index
].wake_up
) {
416 if (vendor_index
< NR_ITEMS(vendors
) - 1 &&
417 vendors
[vendor_index
+ 1].vendor_id
419 ft_drive_type
.vendor_id
) {
425 if (ft_drive_type
.wake_up
!= vendors
[vendor_index
].wake_up
) {
426 TRACE(ft_t_warn
, "\n"
427 KERN_INFO
"==========================================\n"
428 KERN_INFO
"wakeup type mismatch:\n"
429 KERN_INFO
"found: %s, expected: %s\n"
430 KERN_INFO
"please report this to "THE_FTAPE_MAINTAINER
"\n"
431 KERN_INFO
"==========================================",
432 methods
[ft_drive_type
.wake_up
].name
,
433 methods
[vendors
[vendor_index
].wake_up
].name
);
439 void ftape_calc_timeouts(unsigned int qic_std
,
440 unsigned int data_rate
,
441 unsigned int tape_len
)
443 int speed
; /* deci-ips ! */
448 /* tape transport speed
449 * data rate: QIC-40 QIC-80 QIC-3010 QIC-3020
451 * 250 Kbps 25 ips n/a n/a n/a
452 * 500 Kbps 50 ips 34 ips 22.6 ips n/a
453 * 1 Mbps n/a 68 ips 45.2 ips 22.6 ips
454 * 2 Mbps n/a n/a n/a 45.2 ips
456 * fast tape transport speed is at least 68 ips.
460 speed
= (data_rate
== 250) ? 250 : 500;
463 speed
= (data_rate
== 500) ? 340 : 680;
465 case QIC_TAPE_QIC3010
:
466 speed
= (data_rate
== 500) ? 226 : 452;
468 case QIC_TAPE_QIC3020
:
469 speed
= (data_rate
== 1000) ? 226 : 452;
472 TRACE(ft_t_bug
, "Unknown qic_std (bug) ?");
476 if (ft_drive_type
.speed
== 0) {
478 static int dt
= 0; /* keep gcc from complaining */
479 static int first_time
= 1;
481 /* Measure the time it takes to wind to EOT and back to BOT.
482 * If the tape length is known, calculate the rewind speed.
483 * Else keep the time value for calculation of the rewind
484 * speed later on, when the length _is_ known.
485 * Ask for a report only when length and speed are both known.
492 dt
= (int) (((jiffies
- t0
) * FT_USPT
) / 1000);
494 dt
= 1; /* prevent div by zero on failures */
498 "trying to determine seek timeout, got %d msec",
502 ft_drive_type
.speed
=
503 (2 * 12 * tape_len
* 1000) / dt
;
504 TRACE(ft_t_warn
, "\n"
505 KERN_INFO
"==========================================\n"
506 KERN_INFO
"drive type: %s\n"
507 KERN_INFO
"delta time = %d ms, length = %d ft\n"
508 KERN_INFO
"has a maximum tape speed of %d ips\n"
509 KERN_INFO
"please report this to "THE_FTAPE_MAINTAINER
"\n"
510 KERN_INFO
"==========================================",
511 ft_drive_type
.name
, dt
, tape_len
,
512 ft_drive_type
.speed
);
515 /* Handle unknown length tapes as very long ones. We'll
516 * determine the actual length from a header segment later.
517 * This is normal for all modern (Wide,TR1/2/3) formats.
521 "Unknown tape length, using maximal timeouts");
522 length
= QIC_TOP_TAPE_LEN
; /* use worst case values */
524 length
= tape_len
; /* use actual values */
526 if (ft_drive_type
.speed
== 0) {
529 ff_speed
= ft_drive_type
.speed
;
531 /* time to go from bot to eot at normal speed (data rate):
532 * time = (1+delta) * length (ft) * 12 (inch/ft) / speed (ips)
533 * delta = 10 % for seek speed, 20 % for rewind speed.
535 ftape_timeout
.seek
= (length
* 132 * FT_SECOND
) / speed
;
536 ftape_timeout
.rewind
= (length
* 144 * FT_SECOND
) / (10 * ff_speed
);
537 ftape_timeout
.reset
= 20 * FT_SECOND
+ ftape_timeout
.rewind
;
538 TRACE(ft_t_noise
, "timeouts for speed = %d, length = %d\n"
539 KERN_INFO
"seek timeout : %d sec\n"
540 KERN_INFO
"rewind timeout: %d sec\n"
541 KERN_INFO
"reset timeout : %d sec",
543 (ftape_timeout
.seek
+ 500) / 1000,
544 (ftape_timeout
.rewind
+ 500) / 1000,
545 (ftape_timeout
.reset
+ 500) / 1000);
549 /* This function calibrates the datarate (i.e. determines the maximal
550 * usable data rate) and sets the global variable ft_qic_std to qic_std
553 int ftape_calibrate_data_rate(unsigned int qic_std
)
555 int rate
= ft_fdc_rate_limit
;
557 TRACE_FUN(ft_t_flow
);
559 ft_qic_std
= qic_std
;
561 if (ft_qic_std
== -1) {
562 TRACE_ABORT(-EIO
, ft_t_err
,
563 "Unable to determine data rate if QIC standard is unknown");
566 /* Select highest rate supported by both fdc and drive.
567 * Start with highest rate supported by the fdc.
569 while (fdc_set_data_rate(rate
) < 0 && rate
> 250) {
573 "Highest FDC supported data rate: %d Kbps", rate
);
574 ft_fdc_max_rate
= rate
;
576 result
= ftape_set_data_rate(rate
, ft_qic_std
);
577 } while (result
== -EINVAL
&& (rate
/= 2) > 250);
579 TRACE_ABORT(-EIO
, ft_t_err
, "set datarate failed");
585 int ftape_init_drive(void)
589 unsigned int qic_std
;
590 unsigned int data_rate
;
591 TRACE_FUN(ft_t_flow
);
593 ftape_init_drive_needed
= 0; /* don't retry if this fails ? */
594 TRACE_CATCH(ftape_report_raw_drive_status(&status
),);
595 if (status
& QIC_STATUS_CARTRIDGE_PRESENT
) {
596 if (!(status
& QIC_STATUS_AT_BOT
)) {
597 /* Antique drives will get here after a soft reset,
598 * modern ones only if the driver is loaded when the
599 * tape wasn't rewound properly.
601 /* Tape should be at bot if new cartridge ! */
604 if (!(status
& QIC_STATUS_REFERENCED
)) {
605 TRACE(ft_t_flow
, "starting seek_load_point");
606 TRACE_CATCH(ftape_command_wait(QIC_SEEK_LOAD_POINT
,
611 ft_formatted
= (status
& QIC_STATUS_REFERENCED
) != 0;
613 TRACE(ft_t_warn
, "Warning: tape is not formatted !");
616 /* report configuration aborts when ftape_tape_len == -1
617 * unknown qic_std is okay if not formatted.
619 TRACE_CATCH(ftape_report_configuration(&model
,
624 /* Maybe add the following to the /proc entry
626 TRACE(ft_t_info
, "%s drive @ %d Kbps",
627 (model
== prehistoric
) ? "prehistoric" :
628 ((model
== pre_qic117c
) ? "pre QIC-117C" :
629 ((model
== post_qic117b
) ? "post QIC-117B" :
630 "post QIC-117D")), data_rate
);
633 /* initialize ft_used_data_rate to maximum value
636 TRACE_CATCH(ftape_calibrate_data_rate(qic_std
),);
637 if (ftape_tape_len
== 0) {
638 TRACE(ft_t_info
, "unknown length QIC-%s tape",
639 (ft_qic_std
== QIC_TAPE_QIC40
) ? "40" :
640 ((ft_qic_std
== QIC_TAPE_QIC80
) ? "80" :
641 ((ft_qic_std
== QIC_TAPE_QIC3010
)
642 ? "3010" : "3020")));
644 TRACE(ft_t_info
, "%d ft. QIC-%s tape", ftape_tape_len
,
645 (ft_qic_std
== QIC_TAPE_QIC40
) ? "40" :
646 ((ft_qic_std
== QIC_TAPE_QIC80
) ? "80" :
647 ((ft_qic_std
== QIC_TAPE_QIC3010
)
648 ? "3010" : "3020")));
650 ftape_calc_timeouts(ft_qic_std
, ft_data_rate
, ftape_tape_len
);
651 /* soft write-protect QIC-40/QIC-80 cartridges used with a
652 * Colorado T3000 drive. Buggy hardware!
654 if ((ft_drive_type
.vendor_id
== 0x011c6) &&
655 ((ft_qic_std
== QIC_TAPE_QIC40
||
656 ft_qic_std
== QIC_TAPE_QIC80
) &&
657 !ft_write_protected
)) {
658 TRACE(ft_t_warn
, "\n"
659 KERN_INFO
"The famous Colorado T3000 bug:\n"
660 KERN_INFO
"%s drives can't write QIC40 and QIC80\n"
661 KERN_INFO
"cartridges but don't set the write-protect flag!",
663 ft_write_protected
= 1;
666 /* Doesn't make too much sense to set the data rate
667 * because we don't know what to use for the write
669 * Need to do this again when formatting the cartridge.
671 ft_data_rate
= data_rate
;
672 ftape_calc_timeouts(QIC_TAPE_QIC40
,
676 ftape_new_cartridge();
680 static void ftape_munmap(void)
683 TRACE_FUN(ft_t_flow
);
685 for (i
= 0; i
< ft_nr_buffers
; i
++) {
686 ft_buffer
[i
]->mmapped
= 0;
691 /* Map the dma buffers into the virtual address range given by vma.
692 * We only check the caller doesn't map non-existent buffers. We
693 * don't check for multiple mappings.
695 int ftape_mmap(struct vm_area_struct
*vma
)
699 TRACE_FUN(ft_t_flow
);
704 if ((vma_get_flags(vma
) & (VM_READ
|VM_WRITE
)) == 0) {
705 TRACE_ABORT(-EINVAL
, ft_t_err
, "Undefined mmap() access");
707 if (vma_get_offset (vma
) != 0) {
708 TRACE_ABORT(-EINVAL
, ft_t_err
, "offset must be 0");
710 if ((vma_get_end (vma
) - vma_get_start (vma
)) % FT_BUFF_SIZE
!= 0) {
711 TRACE_ABORT(-EINVAL
, ft_t_err
,
712 "size = %ld, should be a multiple of %d",
713 vma_get_end (vma
) - vma_get_start (vma
),
716 num_buffers
= (vma_get_end (vma
) - vma_get_start (vma
)) / FT_BUFF_SIZE
;
717 if (num_buffers
> ft_nr_buffers
) {
719 ft_t_err
, "size = %ld, should be less than %d",
720 vma_get_end (vma
) - vma_get_start (vma
),
721 ft_nr_buffers
* FT_BUFF_SIZE
);
723 if (ft_driver_state
!= idle
) {
724 /* this also clears the buffer states
726 ftape_abort_operation();
728 ftape_reset_buffer();
730 for (i
= 0; i
< num_buffers
; i
++) {
731 TRACE_CATCH(remap_page_range(vma_get_start (vma
) +
733 virt_to_phys(ft_buffer
[i
]->address
),
735 vma_get_page_prot (vma
)),
737 TRACE(ft_t_noise
, "remapped dma buffer @ %p to location @ %p",
738 ft_buffer
[i
]->address
,
739 (void *)(vma_get_start(vma
) + i
* FT_BUFF_SIZE
));
741 for (i
= 0; i
< num_buffers
; i
++) {
742 memset(ft_buffer
[i
]->address
, 0xAA, FT_BUFF_SIZE
);
743 ft_buffer
[i
]->mmapped
++;
748 static void ftape_init_driver(void); /* forward declaration */
750 /* OPEN routine called by kernel-interface code
752 int ftape_enable(int drive_selection
)
756 if (ft_drive_sel
== -1 || ft_drive_sel
!= drive_selection
) {
757 /* Other selection than last time
761 ft_drive_sel
= FTAPE_SEL(drive_selection
);
763 TRACE_CATCH(fdc_init(),); /* init & detect fdc */
764 TRACE_CATCH(ftape_activate_drive(&ft_drive_type
),
766 fdc_release_irq_and_dma();
767 fdc_release_regions());
768 TRACE_CATCH(ftape_get_drive_status(), ftape_detach_drive());
769 if (ft_drive_type
.vendor_id
== UNKNOWN_VENDOR
) {
770 ftape_log_vendor_id();
773 ftape_init_drive_needed
= 1;
775 if (!ft_no_tape
&& ftape_init_drive_needed
) {
776 TRACE_CATCH(ftape_init_drive(), ftape_detach_drive());
778 ftape_munmap(); /* clear the mmap flag */
783 /* release routine called by the high level interface modules
786 void ftape_disable(void)
791 for (i
= 0; i
< ft_nr_buffers
; i
++) {
792 if (ft_buffer
[i
]->mmapped
) {
793 TRACE(ft_t_noise
, "first byte of buffer %d: 0x%02x",
794 i
, *ft_buffer
[i
]->address
);
797 if (sigtestsetmask(¤t
->signal
, _DONT_BLOCK
) &&
798 !(sigtestsetmask(¤t
->signal
, _NEVER_BLOCK
)) &&
799 ftape_tape_running
) {
801 "Interrupted by fatal signal and tape still running");
803 ftape_abort_operation(); /* it's annoying */
805 ftape_set_state(idle
);
807 ftape_detach_drive();
808 if (ft_history
.used
) {
809 TRACE(ft_t_info
, "== Non-fatal errors this run: ==");
810 TRACE(ft_t_info
, "fdc isr statistics:\n"
811 KERN_INFO
" id_am_errors : %3d\n"
812 KERN_INFO
" id_crc_errors : %3d\n"
813 KERN_INFO
" data_am_errors : %3d\n"
814 KERN_INFO
" data_crc_errors : %3d\n"
815 KERN_INFO
" overrun_errors : %3d\n"
816 KERN_INFO
" no_data_errors : %3d\n"
817 KERN_INFO
" retries : %3d",
818 ft_history
.id_am_errors
, ft_history
.id_crc_errors
,
819 ft_history
.data_am_errors
, ft_history
.data_crc_errors
,
820 ft_history
.overrun_errors
, ft_history
.no_data_errors
,
822 if (ft_history
.used
& 1) {
823 TRACE(ft_t_info
, "ecc statistics:\n"
824 KERN_INFO
" crc_errors : %3d\n"
825 KERN_INFO
" crc_failures : %3d\n"
826 KERN_INFO
" ecc_failures : %3d\n"
827 KERN_INFO
" sectors corrected: %3d",
828 ft_history
.crc_errors
, ft_history
.crc_failures
,
829 ft_history
.ecc_failures
, ft_history
.corrected
);
831 if (ft_history
.defects
> 0) {
832 TRACE(ft_t_warn
, "Warning: %d media defects!",
835 if (ft_history
.rewinds
> 0) {
836 TRACE(ft_t_info
, "tape motion statistics:\n"
837 KERN_INFO
"repositions : %3d",
845 static void ftape_init_driver(void)
847 TRACE_FUN(ft_t_flow
);
849 ft_drive_type
.vendor_id
= UNKNOWN_VENDOR
;
850 ft_drive_type
.speed
= 0;
851 ft_drive_type
.wake_up
= unknown_wake_up
;
852 ft_drive_type
.name
= "Unknown";
854 ftape_timeout
.seek
= 650 * FT_SECOND
;
855 ftape_timeout
.reset
= 670 * FT_SECOND
;
856 ftape_timeout
.rewind
= 650 * FT_SECOND
;
857 ftape_timeout
.head_seek
= 15 * FT_SECOND
;
858 ftape_timeout
.stop
= 5 * FT_SECOND
;
859 ftape_timeout
.pause
= 16 * FT_SECOND
;
862 ftape_tape_len
= 0; /* unknown */
863 ftape_current_command
= 0;
864 ftape_current_cylinder
= -1;
866 ft_segments_per_track
= 102;
867 ftape_segments_per_head
= 1020;
868 ftape_segments_per_cylinder
= 4;
869 ft_tracks_per_tape
= 20;
875 ft_write_protected
= 1;
878 ft_driver_state
= idle
;
881 ft_fdc_max_rate
= 500;
882 ft_drive_max_rate
= 0; /* triggers set_rate_test() */
884 ftape_init_drive_needed
= 1;
886 ft_header_segment_1
= -1;
887 ft_header_segment_2
= -1;
888 ft_used_header_segment
= -1;
889 ft_first_data_segment
= -1;
890 ft_last_data_segment
= -1;
892 ft_location
.track
= -1;
893 ft_location
.known
= 0;
895 ftape_tape_running
= 0;
896 ftape_might_be_off_track
= 1;
898 ftape_new_cartridge(); /* init some tape related variables */