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