ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / ftape / lowlevel / ftape-ctl.c
1 /*
2  *      Copyright (C) 1993-1996 Bas Laarhoven,
3  *                    1996-1997 Claus-Justus Heine.
4
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.
9
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.
14
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.
18
19  *
20  * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.c,v $
21  * $Revision: 1.4 $
22  * $Date: 1997/11/11 14:37:44 $
23  *
24  *      This file contains the non-read/write ftape functions for the
25  *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
26  */
27
28 #include <linux/config.h>
29 #include <linux/errno.h>
30 #include <linux/mm.h>
31 #include <linux/mman.h>
32
33 #include <linux/ftape.h>
34 #include <linux/qic117.h>
35 #include <asm/uaccess.h>
36 #include <asm/io.h>
37
38 /* ease porting between pre-2.4.x and later kernels */
39 #define vma_get_pgoff(v)      ((v)->vm_pgoff)
40
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"
48
49 /*      Global vars.
50  */
51 ftape_info ftape_status = {
52 /*  vendor information */
53         { 0, },     /* drive type */
54 /*  data rates */
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   */
61         0,          /* formatted */
62         1,          /* no tape */
63         1,          /* write protected */
64         1,          /* new tape */
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 */
80         -1,
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 */
86         1,          /* failure */
87 /*  history record */
88         { 0, }      /* history record */
89 };
90         
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()
94                                   * in ftape-io.c
95                                   */
96
97 /*      Local vars.
98  */
99 static const vendor_struct vendors[] = QIC117_VENDORS;
100 static const wakeup_method methods[] = WAKEUP_METHODS;
101
102 const ftape_info *ftape_get_status(void)
103 {
104 #if defined(STATUS_PARANOYA)
105         static ftape_info get_status;
106
107         get_status = ftape_status;
108         return &get_status;
109 #else
110         return &ftape_status; /*  maybe return only a copy of it to assure 
111                                *  read only access
112                                */
113 #endif
114 }
115
116 void ftape_set_status(const ftape_info *status)
117 {
118         ftape_status = *status;
119 }
120
121 static int ftape_not_operational(int status)
122 {
123         /* return true if status indicates tape can not be used.
124          */
125         return ((status ^ QIC_STATUS_CARTRIDGE_PRESENT) &
126                 (QIC_STATUS_ERROR |
127                  QIC_STATUS_CARTRIDGE_PRESENT |
128                  QIC_STATUS_NEW_CARTRIDGE));
129 }
130
131 int ftape_seek_to_eot(void)
132 {
133         int status;
134         TRACE_FUN(ft_t_any);
135
136         TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
137         while ((status & QIC_STATUS_AT_EOT) == 0) {
138                 if (ftape_not_operational(status)) {
139                         TRACE_EXIT -EIO;
140                 }
141                 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD,
142                                                ftape_timeout.rewind,&status),);
143         }
144         TRACE_EXIT 0;
145 }
146
147 int ftape_seek_to_bot(void)
148 {
149         int status;
150         TRACE_FUN(ft_t_any);
151
152         TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
153         while ((status & QIC_STATUS_AT_BOT) == 0) {
154                 if (ftape_not_operational(status)) {
155                         TRACE_EXIT -EIO;
156                 }
157                 TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE,
158                                                ftape_timeout.rewind,&status),);
159         }
160         TRACE_EXIT 0;
161 }
162
163 static int ftape_new_cartridge(void)
164 {
165         ft_location.track = -1; /* force seek on first access */
166         ftape_zap_read_buffers();
167         ftape_zap_write_buffers();
168         return 0;
169 }
170
171 int ftape_abort_operation(void)
172 {
173         int result = 0;
174         int status;
175         TRACE_FUN(ft_t_flow);
176
177         if (ft_runner_status == running) {
178                 TRACE(ft_t_noise, "aborting runner, waiting");
179                 
180                 ft_runner_status = do_abort;
181                 /* set timeout so that the tape will run to logical EOT
182                  * if we missed the last sector and there are no queue pulses.
183                  */
184                 result = ftape_dumb_stop();
185         }
186         if (ft_runner_status != idle) {
187                 if (ft_runner_status == do_abort) {
188                         TRACE(ft_t_noise, "forcing runner abort");
189                 }
190                 TRACE(ft_t_noise, "stopping tape");
191                 result = ftape_stop_tape(&status);
192                 ft_location.known = 0;
193                 ft_runner_status  = idle;
194         }
195         ftape_reset_buffer();
196         ftape_zap_read_buffers();
197         ftape_set_state(idle);
198         TRACE_EXIT result;
199 }
200
201 static int lookup_vendor_id(unsigned int vendor_id)
202 {
203         int i = 0;
204
205         while (vendors[i].vendor_id != vendor_id) {
206                 if (++i >= NR_ITEMS(vendors)) {
207                         return -1;
208                 }
209         }
210         return i;
211 }
212
213 void ftape_detach_drive(void)
214 {
215         TRACE_FUN(ft_t_any);
216
217         TRACE(ft_t_flow, "disabling tape drive and fdc");
218         ftape_put_drive_to_sleep(ft_drive_type.wake_up);
219         fdc_catch_stray_interrupts(1);  /* one always comes */
220         fdc_disable();
221         fdc_release_irq_and_dma();
222         fdc_release_regions();
223         TRACE_EXIT;
224 }
225
226 static void clear_history(void)
227 {
228         ft_history.used = 0;
229         ft_history.id_am_errors =
230                 ft_history.id_crc_errors =
231                 ft_history.data_am_errors =
232                 ft_history.data_crc_errors =
233                 ft_history.overrun_errors =
234                 ft_history.no_data_errors =
235                 ft_history.retries =
236                 ft_history.crc_errors =
237                 ft_history.crc_failures =
238                 ft_history.ecc_failures =
239                 ft_history.corrected =
240                 ft_history.defects =
241                 ft_history.rewinds = 0;
242 }
243
244 int ftape_activate_drive(vendor_struct * drive_type)
245 {
246         int result = 0;
247         TRACE_FUN(ft_t_flow);
248
249         /* If we already know the drive type, wake it up.
250          * Else try to find out what kind of drive is attached.
251          */
252         if (drive_type->wake_up != unknown_wake_up) {
253                 TRACE(ft_t_flow, "enabling tape drive and fdc");
254                 result = ftape_wakeup_drive(drive_type->wake_up);
255                 if (result < 0) {
256                         TRACE(ft_t_err, "known wakeup method failed");
257                 }
258         } else {
259                 wake_up_types method;
260                 const ft_trace_t old_tracing = TRACE_LEVEL;
261                 if (TRACE_LEVEL < ft_t_flow) {
262                         SET_TRACE_LEVEL(ft_t_bug);
263                 }
264
265                 /*  Try to awaken the drive using all known methods.
266                  *  Lower tracing for a while.
267                  */
268                 for (method=no_wake_up; method < NR_ITEMS(methods); ++method) {
269                         drive_type->wake_up = method;
270 #ifdef CONFIG_FT_TWO_DRIVES
271                         /*  Test setup for dual drive configuration.
272                          *  /dev/rft2 uses mountain wakeup
273                          *  /dev/rft3 uses colorado wakeup
274                          *  Other systems will use the normal scheme.
275                          */
276                         if ((ft_drive_sel < 2)                            ||
277                             (ft_drive_sel == 2 && method == FT_WAKE_UP_1) ||
278                             (ft_drive_sel == 3 && method == FT_WAKE_UP_2)) {
279                                 result=ftape_wakeup_drive(drive_type->wake_up);
280                         } else {
281                                 result = -EIO;
282                         }
283 #else
284                         result = ftape_wakeup_drive(drive_type->wake_up);
285 #endif
286                         if (result >= 0) {
287                                 TRACE(ft_t_warn, "drive wakeup method: %s",
288                                       methods[drive_type->wake_up].name);
289                                 break;
290                         }
291                 }
292                 SET_TRACE_LEVEL(old_tracing);
293
294                 if (method >= NR_ITEMS(methods)) {
295                         /* no response at all, cannot open this drive */
296                         drive_type->wake_up = unknown_wake_up;
297                         TRACE(ft_t_err, "no tape drive found !");
298                         result = -ENODEV;
299                 }
300         }
301         TRACE_EXIT result;
302 }
303
304 int ftape_get_drive_status(void)
305 {
306         int result;
307         int status;
308         TRACE_FUN(ft_t_flow);
309
310         ft_no_tape = ft_write_protected = 0;
311         /*    Tape drive is activated now.
312          *    First clear error status if present.
313          */
314         do {
315                 result = ftape_ready_wait(ftape_timeout.reset, &status);
316                 if (result < 0) {
317                         if (result == -ETIME) {
318                                 TRACE(ft_t_err, "ftape_ready_wait timeout");
319                         } else if (result == -EINTR) {
320                                 TRACE(ft_t_err, "ftape_ready_wait aborted");
321                         } else {
322                                 TRACE(ft_t_err, "ftape_ready_wait failed");
323                         }
324                         TRACE_EXIT -EIO;
325                 }
326                 /*  Clear error condition (drive is ready !)
327                  */
328                 if (status & QIC_STATUS_ERROR) {
329                         unsigned int error;
330                         qic117_cmd_t command;
331
332                         TRACE(ft_t_err, "error status set");
333                         result = ftape_report_error(&error, &command, 1);
334                         if (result < 0) {
335                                 TRACE(ft_t_err,
336                                       "report_error_code failed: %d", result);
337                                 /* hope it's working next time */
338                                 ftape_reset_drive();
339                                 TRACE_EXIT -EIO;
340                         } else if (error != 0) {
341                                 TRACE(ft_t_noise, "error code   : %d", error);
342                                 TRACE(ft_t_noise, "error command: %d", command);
343                         }
344                 }
345                 if (status & QIC_STATUS_NEW_CARTRIDGE) {
346                         unsigned int error;
347                         qic117_cmd_t command;
348                         const ft_trace_t old_tracing = TRACE_LEVEL;
349                         SET_TRACE_LEVEL(ft_t_bug);
350
351                         /*  Undocumented feature: Must clear (not present!)
352                          *  error here or we'll fail later.
353                          */
354                         ftape_report_error(&error, &command, 1);
355
356                         SET_TRACE_LEVEL(old_tracing);
357                         TRACE(ft_t_info, "status: new cartridge");
358                         ft_new_tape = 1;
359                 } else {
360                         ft_new_tape = 0;
361                 }
362                 FT_SIGNAL_EXIT(_DONT_BLOCK);
363         } while (status & QIC_STATUS_ERROR);
364         
365         ft_no_tape = !(status & QIC_STATUS_CARTRIDGE_PRESENT);
366         ft_write_protected = (status & QIC_STATUS_WRITE_PROTECT) != 0;
367         if (ft_no_tape) {
368                 TRACE(ft_t_warn, "no cartridge present");
369         } else {
370                 if (ft_write_protected) {
371                         TRACE(ft_t_noise, "Write protected cartridge");
372                 }
373         }
374         TRACE_EXIT 0;
375 }
376
377 void ftape_log_vendor_id(void)
378 {
379         int vendor_index;
380         TRACE_FUN(ft_t_flow);
381
382         ftape_report_vendor_id(&ft_drive_type.vendor_id);
383         vendor_index = lookup_vendor_id(ft_drive_type.vendor_id);
384         if (ft_drive_type.vendor_id == UNKNOWN_VENDOR &&
385             ft_drive_type.wake_up == wake_up_colorado) {
386                 vendor_index = 0;
387                 /* hack to get rid of all this mail */
388                 ft_drive_type.vendor_id = 0;
389         }
390         if (vendor_index < 0) {
391                 /* Unknown vendor id, first time opening device.  The
392                  * drive_type remains set to type found at wakeup
393                  * time, this will probably keep the driver operating
394                  * for this new vendor.  
395                  */
396                 TRACE(ft_t_warn, "\n"
397                       KERN_INFO "============ unknown vendor id ===========\n"
398                       KERN_INFO "A new, yet unsupported tape drive is found\n"
399                       KERN_INFO "Please report the following values:\n"
400                       KERN_INFO "   Vendor id     : 0x%04x\n"
401                       KERN_INFO "   Wakeup method : %s\n"
402                       KERN_INFO "And a description of your tape drive\n"
403                       KERN_INFO "to "THE_FTAPE_MAINTAINER"\n"
404                       KERN_INFO "==========================================",
405                       ft_drive_type.vendor_id,
406                       methods[ft_drive_type.wake_up].name);
407                 ft_drive_type.speed = 0;                /* unknown */
408         } else {
409                 ft_drive_type.name  = vendors[vendor_index].name;
410                 ft_drive_type.speed = vendors[vendor_index].speed;
411                 TRACE(ft_t_info, "tape drive type: %s", ft_drive_type.name);
412                 /* scan all methods for this vendor_id in table */
413                 while(ft_drive_type.wake_up != vendors[vendor_index].wake_up) {
414                         if (vendor_index < NR_ITEMS(vendors) - 1 &&
415                             vendors[vendor_index + 1].vendor_id 
416                             == 
417                             ft_drive_type.vendor_id) {
418                                 ++vendor_index;
419                         } else {
420                                 break;
421                         }
422                 }
423                 if (ft_drive_type.wake_up != vendors[vendor_index].wake_up) {
424                         TRACE(ft_t_warn, "\n"
425                      KERN_INFO "==========================================\n"
426                      KERN_INFO "wakeup type mismatch:\n"
427                      KERN_INFO "found: %s, expected: %s\n"
428                      KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n"
429                      KERN_INFO "==========================================",
430                               methods[ft_drive_type.wake_up].name,
431                               methods[vendors[vendor_index].wake_up].name);
432                 }
433         }
434         TRACE_EXIT;
435 }
436
437 void ftape_calc_timeouts(unsigned int qic_std,
438                          unsigned int data_rate,
439                          unsigned int tape_len)
440 {
441         int speed;              /* deci-ips ! */
442         int ff_speed;
443         int length;
444         TRACE_FUN(ft_t_any);
445
446         /*                           tape transport speed
447          *  data rate:        QIC-40   QIC-80   QIC-3010 QIC-3020
448          *
449          *    250 Kbps        25 ips     n/a      n/a      n/a
450          *    500 Kbps        50 ips   34 ips   22.6 ips   n/a
451          *      1 Mbps          n/a    68 ips   45.2 ips 22.6 ips
452          *      2 Mbps          n/a      n/a      n/a    45.2 ips
453          *
454          *  fast tape transport speed is at least 68 ips.
455          */
456         switch (qic_std) {
457         case QIC_TAPE_QIC40:
458                 speed = (data_rate == 250) ? 250 : 500;
459                 break;
460         case QIC_TAPE_QIC80:
461                 speed = (data_rate == 500) ? 340 : 680;
462                 break;
463         case QIC_TAPE_QIC3010:
464                 speed = (data_rate == 500) ? 226 : 452;
465                 break;
466         case QIC_TAPE_QIC3020:
467                 speed = (data_rate == 1000) ? 226 : 452;
468                 break;
469         default:
470                 TRACE(ft_t_bug, "Unknown qic_std (bug) ?");
471                 speed = 500;
472                 break;
473         }
474         if (ft_drive_type.speed == 0) {
475                 unsigned long t0;
476                 static int dt = 0;     /* keep gcc from complaining */
477                 static int first_time = 1;
478
479                 /*  Measure the time it takes to wind to EOT and back to BOT.
480                  *  If the tape length is known, calculate the rewind speed.
481                  *  Else keep the time value for calculation of the rewind
482                  *  speed later on, when the length _is_ known.
483                  *  Ask for a report only when length and speed are both known.
484                  */
485                 if (first_time) {
486                         ftape_seek_to_bot();
487                         t0 = jiffies;
488                         ftape_seek_to_eot();
489                         ftape_seek_to_bot();
490                         dt = (int) (((jiffies - t0) * FT_USPT) / 1000);
491                         if (dt < 1) {
492                                 dt = 1; /* prevent div by zero on failures */
493                         }
494                         first_time = 0;
495                         TRACE(ft_t_info,
496                               "trying to determine seek timeout, got %d msec",
497                               dt);
498                 }
499                 if (tape_len != 0) {
500                         ft_drive_type.speed = 
501                                 (2 * 12 * tape_len * 1000) / dt;
502                         TRACE(ft_t_warn, "\n"
503                      KERN_INFO "==========================================\n"
504                      KERN_INFO "drive type: %s\n"
505                      KERN_INFO "delta time = %d ms, length = %d ft\n"
506                      KERN_INFO "has a maximum tape speed of %d ips\n"
507                      KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n"
508                      KERN_INFO "==========================================",
509                               ft_drive_type.name, dt, tape_len, 
510                               ft_drive_type.speed);
511                 }
512         }
513         /*  Handle unknown length tapes as very long ones. We'll
514          *  determine the actual length from a header segment later.
515          *  This is normal for all modern (Wide,TR1/2/3) formats.
516          */
517         if (tape_len <= 0) {
518                 TRACE(ft_t_noise,
519                       "Unknown tape length, using maximal timeouts");
520                 length = QIC_TOP_TAPE_LEN;      /* use worst case values */
521         } else {
522                 length = tape_len;              /* use actual values */
523         }
524         if (ft_drive_type.speed == 0) {
525                 ff_speed = speed; 
526         } else {
527                 ff_speed = ft_drive_type.speed;
528         }
529         /*  time to go from bot to eot at normal speed (data rate):
530          *  time = (1+delta) * length (ft) * 12 (inch/ft) / speed (ips)
531          *  delta = 10 % for seek speed, 20 % for rewind speed.
532          */
533         ftape_timeout.seek = (length * 132 * FT_SECOND) / speed;
534         ftape_timeout.rewind = (length * 144 * FT_SECOND) / (10 * ff_speed);
535         ftape_timeout.reset = 20 * FT_SECOND + ftape_timeout.rewind;
536         TRACE(ft_t_noise, "timeouts for speed = %d, length = %d\n"
537               KERN_INFO "seek timeout  : %d sec\n"
538               KERN_INFO "rewind timeout: %d sec\n"
539               KERN_INFO "reset timeout : %d sec",
540               speed, length,
541               (ftape_timeout.seek + 500) / 1000,
542               (ftape_timeout.rewind + 500) / 1000,
543               (ftape_timeout.reset + 500) / 1000);
544         TRACE_EXIT;
545 }
546
547 /* This function calibrates the datarate (i.e. determines the maximal
548  * usable data rate) and sets the global variable ft_qic_std to qic_std
549  *
550  */
551 int ftape_calibrate_data_rate(unsigned int qic_std)
552 {
553         int rate = ft_fdc_rate_limit;
554         int result;
555         TRACE_FUN(ft_t_flow);
556
557         ft_qic_std = qic_std;
558
559         if (ft_qic_std == -1) {
560                 TRACE_ABORT(-EIO, ft_t_err,
561                 "Unable to determine data rate if QIC standard is unknown");
562         }
563
564         /*  Select highest rate supported by both fdc and drive.
565          *  Start with highest rate supported by the fdc.
566          */
567         while (fdc_set_data_rate(rate) < 0 && rate > 250) {
568                 rate /= 2;
569         }
570         TRACE(ft_t_info,
571               "Highest FDC supported data rate: %d Kbps", rate);
572         ft_fdc_max_rate = rate;
573         do {
574                 result = ftape_set_data_rate(rate, ft_qic_std);
575         } while (result == -EINVAL && (rate /= 2) > 250);
576         if (result < 0) {
577                 TRACE_ABORT(-EIO, ft_t_err, "set datarate failed");
578         }
579         ft_data_rate = rate;
580         TRACE_EXIT 0;
581 }
582
583 int ftape_init_drive(void)
584 {
585         int status;
586         qic_model model;
587         unsigned int qic_std;
588         unsigned int data_rate;
589         TRACE_FUN(ft_t_flow);
590
591         ftape_init_drive_needed = 0; /* don't retry if this fails ? */
592         TRACE_CATCH(ftape_report_raw_drive_status(&status),);
593         if (status & QIC_STATUS_CARTRIDGE_PRESENT) {
594                 if (!(status & QIC_STATUS_AT_BOT)) {
595                         /*  Antique drives will get here after a soft reset,
596                          *  modern ones only if the driver is loaded when the
597                          *  tape wasn't rewound properly.
598                          */
599                         /* Tape should be at bot if new cartridge ! */
600                         ftape_seek_to_bot();
601                 }
602                 if (!(status & QIC_STATUS_REFERENCED)) {
603                         TRACE(ft_t_flow, "starting seek_load_point");
604                         TRACE_CATCH(ftape_command_wait(QIC_SEEK_LOAD_POINT,
605                                                        ftape_timeout.reset,
606                                                        &status),);
607                 }
608         }
609         ft_formatted = (status & QIC_STATUS_REFERENCED) != 0;
610         if (!ft_formatted) {
611                 TRACE(ft_t_warn, "Warning: tape is not formatted !");
612         }
613
614         /*  report configuration aborts when ftape_tape_len == -1
615          *  unknown qic_std is okay if not formatted.
616          */
617         TRACE_CATCH(ftape_report_configuration(&model,
618                                                &data_rate,
619                                                &qic_std,
620                                                &ftape_tape_len),);
621
622         /*  Maybe add the following to the /proc entry
623          */
624         TRACE(ft_t_info, "%s drive @ %d Kbps",
625               (model == prehistoric) ? "prehistoric" :
626               ((model == pre_qic117c) ? "pre QIC-117C" :
627                ((model == post_qic117b) ? "post QIC-117B" :
628                 "post QIC-117D")), data_rate);
629
630         if (ft_formatted) {
631                 /*  initialize ft_used_data_rate to maximum value 
632                  *  and set ft_qic_std
633                  */
634                 TRACE_CATCH(ftape_calibrate_data_rate(qic_std),);
635                 if (ftape_tape_len == 0) {
636                         TRACE(ft_t_info, "unknown length QIC-%s tape",
637                               (ft_qic_std == QIC_TAPE_QIC40) ? "40" :
638                               ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
639                                ((ft_qic_std == QIC_TAPE_QIC3010) 
640                                 ? "3010" : "3020")));
641                 } else {
642                         TRACE(ft_t_info, "%d ft. QIC-%s tape", ftape_tape_len,
643                               (ft_qic_std == QIC_TAPE_QIC40) ? "40" :
644                               ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
645                                ((ft_qic_std == QIC_TAPE_QIC3010)
646                                 ? "3010" : "3020")));
647                 }
648                 ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
649                 /* soft write-protect QIC-40/QIC-80 cartridges used with a
650                  * Colorado T3000 drive. Buggy hardware!
651                  */
652                 if ((ft_drive_type.vendor_id == 0x011c6) &&
653                     ((ft_qic_std == QIC_TAPE_QIC40 ||
654                       ft_qic_std == QIC_TAPE_QIC80) &&
655                      !ft_write_protected)) {
656                         TRACE(ft_t_warn, "\n"
657         KERN_INFO "The famous Colorado T3000 bug:\n"
658         KERN_INFO "%s drives can't write QIC40 and QIC80\n"
659         KERN_INFO "cartridges but don't set the write-protect flag!",
660                               ft_drive_type.name);
661                         ft_write_protected = 1;
662                 }
663         } else {
664                 /*  Doesn't make too much sense to set the data rate
665                  *  because we don't know what to use for the write
666                  *  precompensation.
667                  *  Need to do this again when formatting the cartridge.
668                  */
669                 ft_data_rate = data_rate;
670                 ftape_calc_timeouts(QIC_TAPE_QIC40,
671                                     data_rate,
672                                     ftape_tape_len);
673         }
674         ftape_new_cartridge();
675         TRACE_EXIT 0;
676 }
677
678 static void ftape_munmap(void)
679 {
680         int i;
681         TRACE_FUN(ft_t_flow);
682         
683         for (i = 0; i < ft_nr_buffers; i++) {
684                 ft_buffer[i]->mmapped = 0;
685         }
686         TRACE_EXIT;
687 }
688
689 /*   Map the dma buffers into the virtual address range given by vma.
690  *   We only check the caller doesn't map non-existent buffers. We
691  *   don't check for multiple mappings.
692  */
693 int ftape_mmap(struct vm_area_struct *vma)
694 {
695         int num_buffers;
696         int i;
697         TRACE_FUN(ft_t_flow);
698         
699         if (ft_failure) {
700                 TRACE_EXIT -ENODEV;
701         }
702         if (!(vma->vm_flags & (VM_READ|VM_WRITE))) {
703                 TRACE_ABORT(-EINVAL, ft_t_err, "Undefined mmap() access");
704         }
705         if (vma_get_pgoff(vma) != 0) {
706                 TRACE_ABORT(-EINVAL, ft_t_err, "page offset must be 0");
707         }
708         if ((vma->vm_end - vma->vm_start) % FT_BUFF_SIZE != 0) {
709                 TRACE_ABORT(-EINVAL, ft_t_err,
710                             "size = %ld, should be a multiple of %d",
711                             vma->vm_end - vma->vm_start,
712                             FT_BUFF_SIZE);
713         }
714         num_buffers = (vma->vm_end - vma->vm_start) / FT_BUFF_SIZE;
715         if (num_buffers > ft_nr_buffers) {
716                 TRACE_ABORT(-EINVAL,
717                             ft_t_err, "size = %ld, should be less than %d",
718                             vma->vm_end - vma->vm_start,
719                             ft_nr_buffers * FT_BUFF_SIZE);
720         }
721         if (ft_driver_state != idle) {
722                 /* this also clears the buffer states 
723                  */
724                 ftape_abort_operation();
725         } else {
726                 ftape_reset_buffer();
727         }
728         for (i = 0; i < num_buffers; i++) {
729                 TRACE_CATCH(remap_page_range(vma, vma->vm_start +
730                                              i * FT_BUFF_SIZE,
731                                              virt_to_phys(ft_buffer[i]->address),
732                                              FT_BUFF_SIZE,
733                                              vma->vm_page_prot),
734                             _res = -EAGAIN);
735                 TRACE(ft_t_noise, "remapped dma buffer @ %p to location @ %p",
736                       ft_buffer[i]->address,
737                       (void *)(vma->vm_start + i * FT_BUFF_SIZE));
738         }
739         for (i = 0; i < num_buffers; i++) {
740                 memset(ft_buffer[i]->address, 0xAA, FT_BUFF_SIZE);
741                 ft_buffer[i]->mmapped++;
742         }       
743         TRACE_EXIT 0;
744 }
745
746 static void ftape_init_driver(void); /* forward declaration */
747
748 /*      OPEN routine called by kernel-interface code
749  */
750 int ftape_enable(int drive_selection)
751 {
752         TRACE_FUN(ft_t_any);
753
754         if (ft_drive_sel == -1 || ft_drive_sel != drive_selection) {
755                 /* Other selection than last time
756                  */
757                 ftape_init_driver();
758         }
759         ft_drive_sel = FTAPE_SEL(drive_selection);
760         ft_failure = 0;
761         TRACE_CATCH(fdc_init(),); /* init & detect fdc */
762         TRACE_CATCH(ftape_activate_drive(&ft_drive_type),
763                     fdc_disable();
764                     fdc_release_irq_and_dma();
765                     fdc_release_regions());
766         TRACE_CATCH(ftape_get_drive_status(), ftape_detach_drive());
767         if (ft_drive_type.vendor_id == UNKNOWN_VENDOR) {
768                 ftape_log_vendor_id();
769         }
770         if (ft_new_tape) {
771                 ftape_init_drive_needed = 1;
772         }
773         if (!ft_no_tape && ftape_init_drive_needed) {
774                 TRACE_CATCH(ftape_init_drive(), ftape_detach_drive());
775         }
776         ftape_munmap(); /* clear the mmap flag */
777         clear_history();
778         TRACE_EXIT 0;
779 }
780
781 /*   release routine called by the high level interface modules
782  *   zftape or sftape.
783  */
784 void ftape_disable(void)
785 {
786         int i;
787         TRACE_FUN(ft_t_any);
788
789         for (i = 0; i < ft_nr_buffers; i++) {
790                 if (ft_buffer[i]->mmapped) {
791                         TRACE(ft_t_noise, "first byte of buffer %d: 0x%02x",
792                               i, *ft_buffer[i]->address);
793                 }
794         }
795         if (sigtestsetmask(&current->pending.signal, _DONT_BLOCK) && 
796             !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)) &&
797             ftape_tape_running) {
798                 TRACE(ft_t_warn,
799                       "Interrupted by fatal signal and tape still running");
800                 ftape_dumb_stop();
801                 ftape_abort_operation(); /* it's annoying */
802         } else {
803                 ftape_set_state(idle);
804         }
805         ftape_detach_drive();
806         if (ft_history.used) {
807                 TRACE(ft_t_info, "== Non-fatal errors this run: ==");
808                 TRACE(ft_t_info, "fdc isr statistics:\n"
809                       KERN_INFO " id_am_errors     : %3d\n"
810                       KERN_INFO " id_crc_errors    : %3d\n"
811                       KERN_INFO " data_am_errors   : %3d\n"
812                       KERN_INFO " data_crc_errors  : %3d\n"
813                       KERN_INFO " overrun_errors   : %3d\n"
814                       KERN_INFO " no_data_errors   : %3d\n"
815                       KERN_INFO " retries          : %3d",
816                       ft_history.id_am_errors,   ft_history.id_crc_errors,
817                       ft_history.data_am_errors, ft_history.data_crc_errors,
818                       ft_history.overrun_errors, ft_history.no_data_errors,
819                       ft_history.retries);
820                 if (ft_history.used & 1) {
821                         TRACE(ft_t_info, "ecc statistics:\n"
822                               KERN_INFO " crc_errors       : %3d\n"
823                               KERN_INFO " crc_failures     : %3d\n"
824                               KERN_INFO " ecc_failures     : %3d\n"
825                               KERN_INFO " sectors corrected: %3d",
826                               ft_history.crc_errors,   ft_history.crc_failures,
827                               ft_history.ecc_failures, ft_history.corrected);
828                 }
829                 if (ft_history.defects > 0) {
830                         TRACE(ft_t_warn, "Warning: %d media defects!",
831                               ft_history.defects);
832                 }
833                 if (ft_history.rewinds > 0) {
834                         TRACE(ft_t_info, "tape motion statistics:\n"
835                               KERN_INFO "repositions       : %3d",
836                               ft_history.rewinds);
837                 }
838         }
839         ft_failure = 1;
840         TRACE_EXIT;
841 }
842
843 static void ftape_init_driver(void)
844 {
845         TRACE_FUN(ft_t_flow);
846
847         ft_drive_type.vendor_id = UNKNOWN_VENDOR;
848         ft_drive_type.speed     = 0;
849         ft_drive_type.wake_up   = unknown_wake_up;
850         ft_drive_type.name      = "Unknown";
851
852         ftape_timeout.seek      = 650 * FT_SECOND;
853         ftape_timeout.reset     = 670 * FT_SECOND;
854         ftape_timeout.rewind    = 650 * FT_SECOND;
855         ftape_timeout.head_seek =  15 * FT_SECOND;
856         ftape_timeout.stop      =   5 * FT_SECOND;
857         ftape_timeout.pause     =  16 * FT_SECOND;
858
859         ft_qic_std             = -1;
860         ftape_tape_len         = 0;  /* unknown */
861         ftape_current_command  = 0;
862         ftape_current_cylinder = -1;
863
864         ft_segments_per_track       = 102;
865         ftape_segments_per_head     = 1020;
866         ftape_segments_per_cylinder = 4;
867         ft_tracks_per_tape          = 20;
868
869         ft_failure = 1;
870
871         ft_formatted       = 0;
872         ft_no_tape         = 1;
873         ft_write_protected = 1;
874         ft_new_tape        = 1;
875
876         ft_driver_state = idle;
877
878         ft_data_rate = 
879                 ft_fdc_max_rate   = 500;
880         ft_drive_max_rate = 0; /* triggers set_rate_test() */
881
882         ftape_init_drive_needed = 1;
883
884         ft_header_segment_1    = -1;
885         ft_header_segment_2    = -1;
886         ft_used_header_segment = -1;
887         ft_first_data_segment  = -1;
888         ft_last_data_segment   = -1;
889
890         ft_location.track = -1;
891         ft_location.known = 0;
892
893         ftape_tape_running = 0;
894         ftape_might_be_off_track = 1;
895
896         ftape_new_cartridge();  /* init some tape related variables */
897         ftape_init_bsm();
898         TRACE_EXIT;
899 }