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