Import 2.1.81
[davej-history.git] / drivers / char / ftape / lowlevel / ftape-ctl.c
blob05f1f61466934b94b929b717db98a787e3498a37
1 /*
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)
8 any later version.
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 $
21 * $Revision: 1.4 $
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>
30 #include <linux/mm.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>
38 #else
39 #include <asm/segment.h>
40 #endif
41 #include <asm/io.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"
51 /* Global vars.
53 ftape_info ftape_status = {
54 /* vendor information */
55 { 0, }, /* drive type */
56 /* data rates */
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 */
63 0, /* formatted */
64 1, /* no tape */
65 1, /* write protected */
66 1, /* new tape */
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 */
82 -1,
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 */
88 1, /* failure */
89 /* history record */
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()
96 * in ftape-io.c
99 /* Local vars.
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;
110 return &get_status;
111 #else
112 return &ftape_status; /* maybe return only a copy of it to assure
113 * read only access
115 #endif
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) &
128 (QIC_STATUS_ERROR |
129 QIC_STATUS_CARTRIDGE_PRESENT |
130 QIC_STATUS_NEW_CARTRIDGE));
133 int ftape_seek_to_eot(void)
135 int status;
136 TRACE_FUN(ft_t_any);
138 TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
139 while ((status & QIC_STATUS_AT_EOT) == 0) {
140 if (ftape_not_operational(status)) {
141 TRACE_EXIT -EIO;
143 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD,
144 ftape_timeout.rewind,&status),);
146 TRACE_EXIT 0;
149 int ftape_seek_to_bot(void)
151 int status;
152 TRACE_FUN(ft_t_any);
154 TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
155 while ((status & QIC_STATUS_AT_BOT) == 0) {
156 if (ftape_not_operational(status)) {
157 TRACE_EXIT -EIO;
159 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE,
160 ftape_timeout.rewind,&status),);
162 TRACE_EXIT 0;
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();
170 return 0;
173 int ftape_abort_operation(void)
175 int result = 0;
176 int status;
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);
200 TRACE_EXIT result;
203 static int lookup_vendor_id(unsigned int vendor_id)
205 int i = 0;
207 while (vendors[i].vendor_id != vendor_id) {
208 if (++i >= NR_ITEMS(vendors)) {
209 return -1;
212 return i;
215 void ftape_detach_drive(void)
217 TRACE_FUN(ft_t_any);
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 */
222 fdc_disable();
223 fdc_release_irq_and_dma();
224 fdc_release_regions();
225 TRACE_EXIT;
228 static void clear_history(void)
230 ft_history.used = 0;
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 =
237 ft_history.retries =
238 ft_history.crc_errors =
239 ft_history.crc_failures =
240 ft_history.ecc_failures =
241 ft_history.corrected =
242 ft_history.defects =
243 ft_history.rewinds = 0;
246 int ftape_activate_drive(vendor_struct * drive_type)
248 int result = 0;
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);
257 if (result < 0) {
258 TRACE(ft_t_err, "known wakeup method failed");
260 } else {
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);
282 } else {
283 result = -EIO;
285 #else
286 result = ftape_wakeup_drive(drive_type->wake_up);
287 #endif
288 if (result >= 0) {
289 TRACE(ft_t_warn, "drive wakeup method: %s",
290 methods[drive_type->wake_up].name);
291 break;
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 !");
300 result = -ENODEV;
303 TRACE_EXIT result;
306 int ftape_get_drive_status(void)
308 int result;
309 int status;
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.
316 do {
317 result = ftape_ready_wait(ftape_timeout.reset, &status);
318 if (result < 0) {
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");
323 } else {
324 TRACE(ft_t_err, "ftape_ready_wait failed");
326 TRACE_EXIT -EIO;
328 /* Clear error condition (drive is ready !)
330 if (status & QIC_STATUS_ERROR) {
331 unsigned int error;
332 qic117_cmd_t command;
334 TRACE(ft_t_err, "error status set");
335 result = ftape_report_error(&error, &command, 1);
336 if (result < 0) {
337 TRACE(ft_t_err,
338 "report_error_code failed: %d", result);
339 /* hope it's working next time */
340 ftape_reset_drive();
341 TRACE_EXIT -EIO;
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) {
348 unsigned int error;
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");
360 ft_new_tape = 1;
361 } else {
362 ft_new_tape = 0;
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;
369 if (ft_no_tape) {
370 TRACE(ft_t_warn, "no cartridge present");
371 } else {
372 if (ft_write_protected) {
373 TRACE(ft_t_noise, "Write protected cartridge");
376 TRACE_EXIT 0;
379 void ftape_log_vendor_id(void)
381 int vendor_index;
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) {
388 vendor_index = 0;
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 */
410 } else {
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) {
420 ++vendor_index;
421 } else {
422 break;
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);
436 TRACE_EXIT;
439 void ftape_calc_timeouts(unsigned int qic_std,
440 unsigned int data_rate,
441 unsigned int tape_len)
443 int speed; /* deci-ips ! */
444 int ff_speed;
445 int length;
446 TRACE_FUN(ft_t_any);
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.
458 switch (qic_std) {
459 case QIC_TAPE_QIC40:
460 speed = (data_rate == 250) ? 250 : 500;
461 break;
462 case QIC_TAPE_QIC80:
463 speed = (data_rate == 500) ? 340 : 680;
464 break;
465 case QIC_TAPE_QIC3010:
466 speed = (data_rate == 500) ? 226 : 452;
467 break;
468 case QIC_TAPE_QIC3020:
469 speed = (data_rate == 1000) ? 226 : 452;
470 break;
471 default:
472 TRACE(ft_t_bug, "Unknown qic_std (bug) ?");
473 speed = 500;
474 break;
476 if (ft_drive_type.speed == 0) {
477 unsigned long t0;
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.
487 if (first_time) {
488 ftape_seek_to_bot();
489 t0 = jiffies;
490 ftape_seek_to_eot();
491 ftape_seek_to_bot();
492 dt = (int) (((jiffies - t0) * FT_USPT) / 1000);
493 if (dt < 1) {
494 dt = 1; /* prevent div by zero on failures */
496 first_time = 0;
497 TRACE(ft_t_info,
498 "trying to determine seek timeout, got %d msec",
499 dt);
501 if (tape_len != 0) {
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.
519 if (tape_len <= 0) {
520 TRACE(ft_t_noise,
521 "Unknown tape length, using maximal timeouts");
522 length = QIC_TOP_TAPE_LEN; /* use worst case values */
523 } else {
524 length = tape_len; /* use actual values */
526 if (ft_drive_type.speed == 0) {
527 ff_speed = speed;
528 } else {
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",
542 speed, length,
543 (ftape_timeout.seek + 500) / 1000,
544 (ftape_timeout.rewind + 500) / 1000,
545 (ftape_timeout.reset + 500) / 1000);
546 TRACE_EXIT;
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;
556 int result;
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) {
570 rate /= 2;
572 TRACE(ft_t_info,
573 "Highest FDC supported data rate: %d Kbps", rate);
574 ft_fdc_max_rate = rate;
575 do {
576 result = ftape_set_data_rate(rate, ft_qic_std);
577 } while (result == -EINVAL && (rate /= 2) > 250);
578 if (result < 0) {
579 TRACE_ABORT(-EIO, ft_t_err, "set datarate failed");
581 ft_data_rate = rate;
582 TRACE_EXIT 0;
585 int ftape_init_drive(void)
587 int status;
588 qic_model model;
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 ! */
602 ftape_seek_to_bot();
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,
607 ftape_timeout.reset,
608 &status),);
611 ft_formatted = (status & QIC_STATUS_REFERENCED) != 0;
612 if (!ft_formatted) {
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,
620 &data_rate,
621 &qic_std,
622 &ftape_tape_len),);
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);
632 if (ft_formatted) {
633 /* initialize ft_used_data_rate to maximum value
634 * and set ft_qic_std
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")));
643 } else {
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!",
662 ft_drive_type.name);
663 ft_write_protected = 1;
665 } else {
666 /* Doesn't make too much sense to set the data rate
667 * because we don't know what to use for the write
668 * precompensation.
669 * Need to do this again when formatting the cartridge.
671 ft_data_rate = data_rate;
672 ftape_calc_timeouts(QIC_TAPE_QIC40,
673 data_rate,
674 ftape_tape_len);
676 ftape_new_cartridge();
677 TRACE_EXIT 0;
680 static void ftape_munmap(void)
682 int i;
683 TRACE_FUN(ft_t_flow);
685 for (i = 0; i < ft_nr_buffers; i++) {
686 ft_buffer[i]->mmapped = 0;
688 TRACE_EXIT;
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)
697 int num_buffers;
698 int i;
699 TRACE_FUN(ft_t_flow);
701 if (ft_failure) {
702 TRACE_EXIT -ENODEV;
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),
714 FT_BUFF_SIZE);
716 num_buffers = (vma_get_end (vma) - vma_get_start (vma)) / FT_BUFF_SIZE;
717 if (num_buffers > ft_nr_buffers) {
718 TRACE_ABORT(-EINVAL,
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();
727 } else {
728 ftape_reset_buffer();
730 for (i = 0; i < num_buffers; i++) {
731 TRACE_CATCH(remap_page_range(vma_get_start (vma) +
732 i * FT_BUFF_SIZE,
733 virt_to_phys(ft_buffer[i]->address),
734 FT_BUFF_SIZE,
735 vma_get_page_prot (vma)),
736 _res = -EAGAIN);
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++;
745 TRACE_EXIT 0;
748 static void ftape_init_driver(void); /* forward declaration */
750 /* OPEN routine called by kernel-interface code
752 int ftape_enable(int drive_selection)
754 TRACE_FUN(ft_t_any);
756 if (ft_drive_sel == -1 || ft_drive_sel != drive_selection) {
757 /* Other selection than last time
759 ftape_init_driver();
761 ft_drive_sel = FTAPE_SEL(drive_selection);
762 ft_failure = 0;
763 TRACE_CATCH(fdc_init(),); /* init & detect fdc */
764 TRACE_CATCH(ftape_activate_drive(&ft_drive_type),
765 fdc_disable();
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();
772 if (ft_new_tape) {
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 */
779 clear_history();
780 TRACE_EXIT 0;
783 /* release routine called by the high level interface modules
784 * zftape or sftape.
786 void ftape_disable(void)
788 int i;
789 TRACE_FUN(ft_t_any);
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(&current->signal, _DONT_BLOCK) &&
798 !(sigtestsetmask(&current->signal, _NEVER_BLOCK)) &&
799 ftape_tape_running) {
800 TRACE(ft_t_warn,
801 "Interrupted by fatal signal and tape still running");
802 ftape_dumb_stop();
803 ftape_abort_operation(); /* it's annoying */
804 } else {
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,
821 ft_history.retries);
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!",
833 ft_history.defects);
835 if (ft_history.rewinds > 0) {
836 TRACE(ft_t_info, "tape motion statistics:\n"
837 KERN_INFO "repositions : %3d",
838 ft_history.rewinds);
841 ft_failure = 1;
842 TRACE_EXIT;
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;
861 ft_qic_std = -1;
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;
871 ft_failure = 1;
873 ft_formatted = 0;
874 ft_no_tape = 1;
875 ft_write_protected = 1;
876 ft_new_tape = 1;
878 ft_driver_state = idle;
880 ft_data_rate =
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 */
899 ftape_init_bsm();
900 TRACE_EXIT;