ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / ftape / lowlevel / ftape-io.c
1 /*
2  *      Copyright (C) 1993-1996 Bas Laarhoven,
3  *                (C) 1996      Kai Harrekilde-Petersen,
4  *                (C) 1997      Claus-Justus Heine.
5
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)
9  any later version.
10
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with this program; see the file COPYING.  If not, write to
18  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20  *
21  * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.c,v $
22  * $Revision: 1.4 $
23  * $Date: 1997/11/11 14:02:36 $
24  *
25  *      This file contains the general control functions for the
26  *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
27  */
28
29 #include <linux/errno.h>
30 #include <linux/sched.h>
31 #include <linux/mm.h>
32 #include <asm/system.h>
33 #include <linux/ioctl.h>
34 #include <linux/mtio.h>
35
36 #include <linux/ftape.h>
37 #include <linux/qic117.h>
38 #include "../lowlevel/ftape-tracing.h"
39 #include "../lowlevel/fdc-io.h"
40 #include "../lowlevel/ftape-io.h"
41 #include "../lowlevel/ftape-ctl.h"
42 #include "../lowlevel/ftape-rw.h"
43 #include "../lowlevel/ftape-write.h"
44 #include "../lowlevel/ftape-read.h"
45 #include "../lowlevel/ftape-init.h"
46 #include "../lowlevel/ftape-calibr.h"
47
48 /*      Global vars.
49  */
50 /* NOTE: sectors start numbering at 1, all others at 0 ! */
51 ft_timeout_table ftape_timeout;
52 unsigned int ftape_tape_len;
53 volatile qic117_cmd_t ftape_current_command;
54 const struct qic117_command_table qic117_cmds[] = QIC117_COMMANDS;
55 int ftape_might_be_off_track;
56
57 /*      Local vars.
58  */
59 static int diagnostic_mode;
60 static unsigned int ftape_udelay_count;
61 static unsigned int ftape_udelay_time;
62
63 void ftape_udelay(unsigned int usecs)
64 {
65         volatile int count = (ftape_udelay_count * usecs +
66                               ftape_udelay_count - 1) / ftape_udelay_time;
67         volatile int i;
68
69         while (count-- > 0) {
70                 for (i = 0; i < 20; ++i);
71         }
72 }
73
74 void ftape_udelay_calibrate(void)
75 {
76         ftape_calibrate("ftape_udelay",
77                         ftape_udelay, &ftape_udelay_count, &ftape_udelay_time);
78 }
79
80 /*      Delay (msec) routine.
81  */
82 void ftape_sleep(unsigned int time)
83 {
84         TRACE_FUN(ft_t_any);
85
86         time *= 1000;   /* msecs -> usecs */
87         if (time < FT_USPT) {
88                 /*  Time too small for scheduler, do a busy wait ! */
89                 ftape_udelay(time);
90         } else {
91                 long timeout;
92                 unsigned long flags;
93                 unsigned int ticks = (time + FT_USPT - 1) / FT_USPT;
94
95                 TRACE(ft_t_any, "%d msec, %d ticks", time/1000, ticks);
96                 timeout = ticks;
97                 save_flags(flags);
98                 sti();
99                 set_current_state(TASK_INTERRUPTIBLE);
100                 do {
101                         /*  Mmm. Isn't current->blocked == 0xffffffff ?
102                          */
103                         if (signal_pending(current)) {
104                                 TRACE(ft_t_err,
105                                       "awoken by non-blocked signal :-(");
106                                 break;  /* exit on signal */
107                         }
108                         while (current->state != TASK_RUNNING) {
109                                 timeout = schedule_timeout(timeout);
110                         }
111                 } while (timeout);
112                 restore_flags(flags);
113         }
114         TRACE_EXIT;
115 }
116
117 /*  send a command or parameter to the drive
118  *  Generates # of step pulses.
119  */
120 static inline int ft_send_to_drive(int arg)
121 {
122         /*  Always wait for a command_timeout period to separate
123          *  individuals commands and/or parameters.
124          */
125         ftape_sleep(3 * FT_MILLISECOND);
126         /*  Keep cylinder nr within range, step towards home if possible.
127          */
128         if (ftape_current_cylinder >= arg) {
129                 return fdc_seek(ftape_current_cylinder - arg);
130         } else {
131                 return fdc_seek(ftape_current_cylinder + arg);
132         }
133 }
134
135 /* forward */ int ftape_report_raw_drive_status(int *status);
136
137 static int ft_check_cmd_restrictions(qic117_cmd_t command)
138 {
139         int status = -1;
140         TRACE_FUN(ft_t_any);
141         
142         TRACE(ft_t_flow, "%s", qic117_cmds[command].name);
143         /* A new motion command during an uninterruptible (motion)
144          *  command requires a ready status before the new command can
145          *  be issued. Otherwise a new motion command needs to be
146          *  checked against required status.
147          */
148         if (qic117_cmds[command].cmd_type == motion &&
149             qic117_cmds[ftape_current_command].non_intr) {
150                 ftape_report_raw_drive_status(&status);
151                 if ((status & QIC_STATUS_READY) == 0) {
152                         TRACE(ft_t_noise,
153                               "motion cmd (%d) during non-intr cmd (%d)",
154                               command, ftape_current_command);
155                         TRACE(ft_t_noise, "waiting until drive gets ready");
156                         ftape_ready_wait(ftape_timeout.seek,
157                                          &status);
158                 }
159         }
160         if (qic117_cmds[command].mask != 0) {
161                 __u8 difference;
162                 /*  Some commands do require a certain status:
163                  */
164                 if (status == -1) {     /* not yet set */
165                         ftape_report_raw_drive_status(&status);
166                 }
167                 difference = ((status ^ qic117_cmds[command].state) &
168                               qic117_cmds[command].mask);
169                 /*  Wait until the drive gets
170                  *  ready. This may last forever if
171                  *  the drive never gets ready... 
172                  */
173                 while ((difference & QIC_STATUS_READY) != 0) {
174                         TRACE(ft_t_noise, "command %d issued while not ready",
175                               command);
176                         TRACE(ft_t_noise, "waiting until drive gets ready");
177                         if (ftape_ready_wait(ftape_timeout.seek,
178                                              &status) == -EINTR) {
179                                 /*  Bail out on signal !
180                                  */
181                                 TRACE_ABORT(-EINTR, ft_t_warn,
182                                       "interrupted by non-blockable signal");
183                         }
184                         difference = ((status ^ qic117_cmds[command].state) &
185                                       qic117_cmds[command].mask);
186                 }
187                 while ((difference & QIC_STATUS_ERROR) != 0) {
188                         int err;
189                         qic117_cmd_t cmd;
190
191                         TRACE(ft_t_noise,
192                               "command %d issued while error pending",
193                               command);
194                         TRACE(ft_t_noise, "clearing error status");
195                         ftape_report_error(&err, &cmd, 1);
196                         ftape_report_raw_drive_status(&status);
197                         difference = ((status ^ qic117_cmds[command].state) &
198                                       qic117_cmds[command].mask);
199                         if ((difference & QIC_STATUS_ERROR) != 0) {
200                                 /*  Bail out on fatal signal !
201                                  */
202                                 FT_SIGNAL_EXIT(_NEVER_BLOCK);
203                         }
204                 }
205                 if (difference) {
206                         /*  Any remaining difference can't be solved
207                          *  here.  
208                          */
209                         if (difference & (QIC_STATUS_CARTRIDGE_PRESENT |
210                                           QIC_STATUS_NEW_CARTRIDGE |
211                                           QIC_STATUS_REFERENCED)) {
212                                 TRACE(ft_t_warn,
213                                       "Fatal: tape removed or reinserted !");
214                                 ft_failure = 1;
215                         } else {
216                                 TRACE(ft_t_err, "wrong state: 0x%02x should be: 0x%02x",
217                                       status & qic117_cmds[command].mask,
218                                       qic117_cmds[command].state);
219                         }
220                         TRACE_EXIT -EIO;
221                 }
222                 if (~status & QIC_STATUS_READY & qic117_cmds[command].mask) {
223                         TRACE_ABORT(-EBUSY, ft_t_err, "Bad: still busy!");
224                 }
225         }
226         TRACE_EXIT 0;
227 }
228
229 /*      Issue a tape command:
230  */
231 int ftape_command(qic117_cmd_t command)
232 {
233         int result = 0;
234         static int level;
235         TRACE_FUN(ft_t_any);
236
237         if ((unsigned int)command > NR_ITEMS(qic117_cmds)) {
238                 /*  This is a bug we'll want to know about too.
239                  */
240                 TRACE_ABORT(-EIO, ft_t_bug, "bug - bad command: %d", command);
241         }
242         if (++level > 5) { /*  This is a bug we'll want to know about. */
243                 --level;
244                 TRACE_ABORT(-EIO, ft_t_bug, "bug - recursion for command: %d",
245                             command);
246         }
247         /*  disable logging and restriction check for some commands,
248          *  check all other commands that have a prescribed starting
249          *  status.
250          */
251         if (diagnostic_mode) {
252                 TRACE(ft_t_flow, "diagnostic command %d", command);
253         } else if (command == QIC_REPORT_DRIVE_STATUS ||
254                    command == QIC_REPORT_NEXT_BIT) {
255                 TRACE(ft_t_any, "%s", qic117_cmds[command].name);
256         } else {
257                 TRACE_CATCH(ft_check_cmd_restrictions(command), --level);
258         }
259         /*  Now all conditions are met or result was < 0.
260          */
261         result = ft_send_to_drive((unsigned int)command);
262         if (qic117_cmds[command].cmd_type == motion &&
263             command != QIC_LOGICAL_FORWARD && command != QIC_STOP_TAPE) {
264                 ft_location.known = 0;
265         }
266         ftape_current_command = command;
267         --level;
268         TRACE_EXIT result;
269 }
270
271 /*      Send a tape command parameter:
272  *      Generates command # of step pulses.
273  *      Skips tape-status call !
274  */
275 int ftape_parameter(unsigned int parameter)
276 {
277         TRACE_FUN(ft_t_any);
278
279         TRACE(ft_t_flow, "called with parameter = %d", parameter);
280         TRACE_EXIT ft_send_to_drive(parameter + 2);
281 }
282
283 /*      Wait for the drive to get ready.
284  *      timeout time in milli-seconds
285  *      Returned status is valid if result != -EIO
286  *
287  *      Should we allow to be killed by SIGINT?  (^C)
288  *      Would be nice at least for large timeouts.
289  */
290 int ftape_ready_wait(unsigned int timeout, int *status)
291 {
292         unsigned long t0;
293         unsigned int poll_delay;
294         int signal_retries;
295         TRACE_FUN(ft_t_any);
296
297         /*  the following ** REALLY ** reduces the system load when
298          *  e.g. one simply rewinds or retensions. The tape is slow 
299          *  anyway. It is really not necessary to detect error 
300          *  conditions with 1/10 seconds granularity
301          *
302          *  On my AMD 133MHZ 486: 100 ms: 23% system load
303          *                        1  sec:  5%
304          *                        5  sec:  0.6%, yeah
305          */
306         if (timeout <= FT_SECOND) {
307                 poll_delay = 100 * FT_MILLISECOND;
308                 signal_retries = 20; /* two seconds */
309         } else if (timeout < 20 * FT_SECOND) {
310                 TRACE(ft_t_flow, "setting poll delay to 1 second");
311                 poll_delay = FT_SECOND;
312                 signal_retries = 2; /* two seconds */
313         } else {
314                 TRACE(ft_t_flow, "setting poll delay to 5 seconds");
315                 poll_delay = 5 * FT_SECOND;
316                 signal_retries = 1; /* five seconds */
317         }
318         for (;;) {
319                 t0 = jiffies;
320                 TRACE_CATCH(ftape_report_raw_drive_status(status),);
321                 if (*status & QIC_STATUS_READY) {
322                         TRACE_EXIT 0;
323                 }
324                 if (!signal_retries--) {
325                         FT_SIGNAL_EXIT(_NEVER_BLOCK);
326                 }
327                 if ((int)timeout >= 0) {
328                         /* this will fail when jiffies wraps around about
329                          * once every year :-)
330                          */
331                         timeout -= ((jiffies - t0) * FT_SECOND) / HZ;
332                         if (timeout <= 0) {
333                                 TRACE_ABORT(-ETIME, ft_t_err, "timeout");
334                         }
335                         ftape_sleep(poll_delay);
336                         timeout -= poll_delay;
337                 } else {
338                         ftape_sleep(poll_delay);
339                 }
340         }
341         TRACE_EXIT -ETIME;
342 }
343
344 /*      Issue command and wait up to timeout milli seconds for drive ready
345  */
346 int ftape_command_wait(qic117_cmd_t command, unsigned int timeout, int *status)
347 {
348         int result;
349
350         /* Drive should be ready, issue command
351          */
352         result = ftape_command(command);
353         if (result >= 0) {
354                 result = ftape_ready_wait(timeout, status);
355         }
356         return result;
357 }
358
359 int ftape_parameter_wait(unsigned int parm, unsigned int timeout, int *status)
360 {
361         int result;
362
363         /* Drive should be ready, issue command
364          */
365         result = ftape_parameter(parm);
366         if (result >= 0) {
367                 result = ftape_ready_wait(timeout, status);
368         }
369         return result;
370 }
371
372 /*--------------------------------------------------------------------------
373  *      Report operations
374  */
375
376 /* Query the drive about its status.  The command is sent and
377    result_length bits of status are returned (2 extra bits are read
378    for start and stop). */
379
380 int ftape_report_operation(int *status,
381                            qic117_cmd_t command,
382                            int result_length)
383 {
384         int i, st3;
385         unsigned int t0;
386         unsigned int dt;
387         TRACE_FUN(ft_t_any);
388
389         TRACE_CATCH(ftape_command(command),);
390         t0 = ftape_timestamp();
391         i = 0;
392         do {
393                 ++i;
394                 ftape_sleep(3 * FT_MILLISECOND);        /* see remark below */
395                 TRACE_CATCH(fdc_sense_drive_status(&st3),);
396                 dt = ftape_timediff(t0, ftape_timestamp());
397                 /*  Ack should be asserted within Ttimout + Tack = 6 msec.
398                  *  Looks like some drives fail to do this so extend this
399                  *  period to 300 msec.
400                  */
401         } while (!(st3 & ST3_TRACK_0) && dt < 300000);
402         if (!(st3 & ST3_TRACK_0)) {
403                 TRACE(ft_t_err,
404                       "No acknowledge after %u msec. (%i iter)", dt / 1000, i);
405                 TRACE_ABORT(-EIO, ft_t_err, "timeout on Acknowledge");
406         }
407         /*  dt may be larger than expected because of other tasks
408          *  scheduled while we were sleeping.
409          */
410         if (i > 1 && dt > 6000) {
411                 TRACE(ft_t_err, "Acknowledge after %u msec. (%i iter)",
412                       dt / 1000, i);
413         }
414         *status = 0;
415         for (i = 0; i < result_length + 1; i++) {
416                 TRACE_CATCH(ftape_command(QIC_REPORT_NEXT_BIT),);
417                 TRACE_CATCH(fdc_sense_drive_status(&st3),);
418                 if (i < result_length) {
419                         *status |= ((st3 & ST3_TRACK_0) ? 1 : 0) << i;
420                 } else if ((st3 & ST3_TRACK_0) == 0) {
421                         TRACE_ABORT(-EIO, ft_t_err, "missing status stop bit");
422                 }
423         }
424         /* this command will put track zero and index back into normal state */
425         (void)ftape_command(QIC_REPORT_NEXT_BIT);
426         TRACE_EXIT 0;
427 }
428
429 /* Report the current drive status. */
430
431 int ftape_report_raw_drive_status(int *status)
432 {
433         int result;
434         int count = 0;
435         TRACE_FUN(ft_t_any);
436
437         do {
438                 result = ftape_report_operation(status,
439                                                 QIC_REPORT_DRIVE_STATUS, 8);
440         } while (result < 0 && ++count <= 3);
441         if (result < 0) {
442                 TRACE_ABORT(-EIO, ft_t_err,
443                             "report_operation failed after %d trials", count);
444         }
445         if ((*status & 0xff) == 0xff) {
446                 TRACE_ABORT(-EIO, ft_t_err,
447                             "impossible drive status 0xff");
448         }
449         if (*status & QIC_STATUS_READY) {
450                 ftape_current_command = QIC_NO_COMMAND; /* completed */
451         }
452         ft_last_status.status.drive_status = (__u8)(*status & 0xff);
453         TRACE_EXIT 0;
454 }
455
456 int ftape_report_drive_status(int *status)
457 {
458         TRACE_FUN(ft_t_any);
459
460         TRACE_CATCH(ftape_report_raw_drive_status(status),);
461         if (*status & QIC_STATUS_NEW_CARTRIDGE ||
462             !(*status & QIC_STATUS_CARTRIDGE_PRESENT)) {
463                 ft_failure = 1; /* will inhibit further operations */
464                 TRACE_EXIT -EIO;
465         }
466         if (*status & QIC_STATUS_READY && *status & QIC_STATUS_ERROR) {
467                 /*  Let caller handle all errors */
468                 TRACE_ABORT(1, ft_t_warn, "warning: error status set!");
469         }
470         TRACE_EXIT 0;
471 }
472
473 int ftape_report_error(unsigned int *error,
474                        qic117_cmd_t *command, int report)
475 {
476         static const ftape_error ftape_errors[] = QIC117_ERRORS;
477         int code;
478         TRACE_FUN(ft_t_any);
479
480         TRACE_CATCH(ftape_report_operation(&code, QIC_REPORT_ERROR_CODE, 16),);
481         *error   = (unsigned int)(code & 0xff);
482         *command = (qic117_cmd_t)((code>>8)&0xff);
483         /*  remember hardware status, maybe useful for status ioctls
484          */
485         ft_last_error.error.command = (__u8)*command;
486         ft_last_error.error.error   = (__u8)*error;
487         if (!report) {
488                 TRACE_EXIT 0;
489         }
490         if (*error == 0) {
491                 TRACE_ABORT(0, ft_t_info, "No error");
492         }
493         TRACE(ft_t_info, "errorcode: %d", *error);
494         if (*error < NR_ITEMS(ftape_errors)) {
495                 TRACE(ft_t_noise, "%sFatal ERROR:",
496                       (ftape_errors[*error].fatal ? "" : "Non-"));
497                 TRACE(ft_t_noise, "%s ...", ftape_errors[*error].message);
498         } else {
499                 TRACE(ft_t_noise, "Unknown ERROR !");
500         }
501         if ((unsigned int)*command < NR_ITEMS(qic117_cmds) &&
502             qic117_cmds[*command].name != NULL) {
503                 TRACE(ft_t_noise, "... caused by command \'%s\'",
504                       qic117_cmds[*command].name);
505         } else {
506                 TRACE(ft_t_noise, "... caused by unknown command %d",
507                       *command);
508         }
509         TRACE_EXIT 0;
510 }
511
512 int ftape_in_error_state(int status)
513 {
514         TRACE_FUN(ft_t_any);
515
516         if ((status & QIC_STATUS_READY) && (status & QIC_STATUS_ERROR)) {
517                 TRACE_ABORT(1, ft_t_warn, "warning: error status set!");
518         }
519         TRACE_EXIT 0;
520 }
521
522 int ftape_report_configuration(qic_model *model,
523                                unsigned int *rate,
524                                int *qic_std,
525                                int *tape_len)
526 {
527         int result;
528         int config;
529         int status;
530         static const unsigned int qic_rates[ 4] = { 250, 2000, 500, 1000 };
531         TRACE_FUN(ft_t_any);
532
533         result = ftape_report_operation(&config,
534                                         QIC_REPORT_DRIVE_CONFIGURATION, 8);
535         if (result < 0) {
536                 ft_last_status.status.drive_config = (__u8)0x00;
537                 *model = prehistoric;
538                 *rate = 500;
539                 *qic_std = QIC_TAPE_QIC40;
540                 *tape_len = 205;
541                 TRACE_EXIT 0;
542         } else {
543                 ft_last_status.status.drive_config = (__u8)(config & 0xff);
544         }
545         *rate = qic_rates[(config & QIC_CONFIG_RATE_MASK) >> QIC_CONFIG_RATE_SHIFT];
546         result = ftape_report_operation(&status, QIC_REPORT_TAPE_STATUS, 8);
547         if (result < 0) {
548                 ft_last_status.status.tape_status = (__u8)0x00;
549                 /* pre- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is valid.
550                  */
551                 *qic_std = (config & QIC_CONFIG_80) ?
552                         QIC_TAPE_QIC80 : QIC_TAPE_QIC40;
553                 /* ?? how's about 425ft tapes? */
554                 *tape_len = (config & QIC_CONFIG_LONG) ? 307 : 0;
555                 *model = pre_qic117c;
556                 result = 0;
557         } else {
558                 ft_last_status.status.tape_status = (__u8)(status & 0xff);
559                 *model = post_qic117b;
560                 TRACE(ft_t_any, "report tape status result = %02x", status);
561                 /* post- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is
562                  * invalid. 
563                  */
564                 switch (status & QIC_TAPE_STD_MASK) {
565                 case QIC_TAPE_QIC40:
566                 case QIC_TAPE_QIC80:
567                 case QIC_TAPE_QIC3020:
568                 case QIC_TAPE_QIC3010:
569                         *qic_std = status & QIC_TAPE_STD_MASK;
570                         break;
571                 default:
572                         *qic_std = -1;
573                         break;
574                 }
575                 switch (status & QIC_TAPE_LEN_MASK) {
576                 case QIC_TAPE_205FT:
577                         /* 205 or 425+ ft 550 Oe tape */
578                         *tape_len = 0;
579                         break;
580                 case QIC_TAPE_307FT:
581                         /* 307.5 ft 550 Oe Extended Length (XL) tape */
582                         *tape_len = 307;
583                         break;
584                 case QIC_TAPE_VARIABLE:
585                         /* Variable length 550 Oe tape */
586                         *tape_len = 0;
587                         break;
588                 case QIC_TAPE_1100FT:
589                         /* 1100 ft 550 Oe tape */
590                         *tape_len = 1100;
591                         break;
592                 case QIC_TAPE_FLEX:
593                         /* Variable length 900 Oe tape */
594                         *tape_len = 0;
595                         break;
596                 default:
597                         *tape_len = -1;
598                         break;
599                 }
600                 if (*qic_std == -1 || *tape_len == -1) {
601                         TRACE(ft_t_any,
602                               "post qic-117b spec drive with unknown tape");
603                 }
604                 result = *tape_len == -1 ? -EIO : 0;
605                 if (status & QIC_TAPE_WIDE) {
606                         switch (*qic_std) {
607                         case QIC_TAPE_QIC80:
608                                 TRACE(ft_t_info, "TR-1 tape detected");
609                                 break;
610                         case QIC_TAPE_QIC3010:
611                                 TRACE(ft_t_info, "TR-2 tape detected");
612                                 break;
613                         case QIC_TAPE_QIC3020:
614                                 TRACE(ft_t_info, "TR-3 tape detected");
615                                 break;
616                         default:
617                                 TRACE(ft_t_warn,
618                                       "Unknown Travan tape type detected");
619                                 break;
620                         }
621                 }
622         }
623         TRACE_EXIT (result < 0) ? -EIO : 0;
624 }
625
626 int ftape_report_rom_version(int *version)
627 {
628
629         if (ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8) < 0) {
630                 return -EIO;
631         } else {
632                 return 0;
633         }
634 }
635
636 int ftape_report_signature(int *signature)
637 {
638         int result;
639
640         result = ftape_command(28);
641         result = ftape_report_operation(signature, 9, 8);
642         result = ftape_command(30);
643         return (result < 0) ? -EIO : 0;
644 }
645
646 void ftape_report_vendor_id(unsigned int *id)
647 {
648         int result;
649         TRACE_FUN(ft_t_any);
650
651         /* We'll try to get a vendor id from the drive.  First
652          * according to the QIC-117 spec, a 16-bit id is requested.
653          * If that fails we'll try an 8-bit version, otherwise we'll
654          * try an undocumented query.
655          */
656         result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 16);
657         if (result < 0) {
658                 result = ftape_report_operation((int *) id,
659                                                 QIC_REPORT_VENDOR_ID, 8);
660                 if (result < 0) {
661                         /* The following is an undocumented call found
662                          * in the CMS code.
663                          */
664                         result = ftape_report_operation((int *) id, 24, 8);
665                         if (result < 0) {
666                                 *id = UNKNOWN_VENDOR;
667                         } else {
668                                 TRACE(ft_t_noise, "got old 8 bit id: %04x",
669                                       *id);
670                                 *id |= 0x20000;
671                         }
672                 } else {
673                         TRACE(ft_t_noise, "got 8 bit id: %04x", *id);
674                         *id |= 0x10000;
675                 }
676         } else {
677                 TRACE(ft_t_noise, "got 16 bit id: %04x", *id);
678         }
679         if (*id == 0x0047) {
680                 int version;
681                 int sign;
682
683                 if (ftape_report_rom_version(&version) < 0) {
684                         TRACE(ft_t_bug, "report rom version failed");
685                         TRACE_EXIT;
686                 }
687                 TRACE(ft_t_noise, "CMS rom version: %d", version);
688                 ftape_command(QIC_ENTER_DIAGNOSTIC_1);
689                 ftape_command(QIC_ENTER_DIAGNOSTIC_1);
690                 diagnostic_mode = 1;
691                 if (ftape_report_operation(&sign, 9, 8) < 0) {
692                         unsigned int error;
693                         qic117_cmd_t command;
694
695                         ftape_report_error(&error, &command, 1);
696                         ftape_command(QIC_ENTER_PRIMARY_MODE);
697                         diagnostic_mode = 0;
698                         TRACE_EXIT;     /* failure ! */
699                 } else {
700                         TRACE(ft_t_noise, "CMS signature: %02x", sign);
701                 }
702                 if (sign == 0xa5) {
703                         result = ftape_report_operation(&sign, 37, 8);
704                         if (result < 0) {
705                                 if (version >= 63) {
706                                         *id = 0x8880;
707                                         TRACE(ft_t_noise,
708                                               "This is an Iomega drive !");
709                                 } else {
710                                         *id = 0x0047;
711                                         TRACE(ft_t_noise,
712                                               "This is a real CMS drive !");
713                                 }
714                         } else {
715                                 *id = 0x0047;
716                                 TRACE(ft_t_noise, "CMS status: %d", sign);
717                         }
718                 } else {
719                         *id = UNKNOWN_VENDOR;
720                 }
721                 ftape_command(QIC_ENTER_PRIMARY_MODE);
722                 diagnostic_mode = 0;
723         }
724         TRACE_EXIT;
725 }
726
727 static int qic_rate_code(unsigned int rate)
728 {
729         switch (rate) {
730         case 250:
731                 return QIC_CONFIG_RATE_250;
732         case 500:
733                 return QIC_CONFIG_RATE_500;
734         case 1000:
735                 return QIC_CONFIG_RATE_1000;
736         case 2000:
737                 return QIC_CONFIG_RATE_2000;
738         default:
739                 return QIC_CONFIG_RATE_500;
740         }
741 }
742
743 static int ftape_set_rate_test(unsigned int *max_rate)
744 {
745         unsigned int error;
746         qic117_cmd_t command;
747         int status;
748         int supported = 0;
749         TRACE_FUN(ft_t_any);
750
751         /*  Check if the drive does support the select rate command
752          *  by testing all different settings. If any one is accepted
753          *  we assume the command is supported, else not.
754          */
755         for (*max_rate = 2000; *max_rate >= 250; *max_rate /= 2) {
756                 if (ftape_command(QIC_SELECT_RATE) < 0) {
757                         continue;
758                 }               
759                 if (ftape_parameter_wait(qic_rate_code(*max_rate),
760                                          1 * FT_SECOND, &status) < 0) {
761                         continue;
762                 }
763                 if (status & QIC_STATUS_ERROR) {
764                         ftape_report_error(&error, &command, 0);
765                         continue;
766                 }
767                 supported = 1; /* did accept a request */
768                 break;
769         }
770         TRACE(ft_t_noise, "Select Rate command is%s supported", 
771               supported ? "" : " not");
772         TRACE_EXIT supported;
773 }
774
775 int ftape_set_data_rate(unsigned int new_rate /* Kbps */, unsigned int qic_std)
776 {
777         int status;
778         int result = 0;
779         unsigned int data_rate = new_rate;
780         static int supported;
781         int rate_changed = 0;
782         qic_model dummy_model;
783         unsigned int dummy_qic_std, dummy_tape_len;
784         TRACE_FUN(ft_t_any);
785
786         if (ft_drive_max_rate == 0) { /* first time */
787                 supported = ftape_set_rate_test(&ft_drive_max_rate);
788         }
789         if (supported) {
790                 ftape_command(QIC_SELECT_RATE);
791                 result = ftape_parameter_wait(qic_rate_code(new_rate),
792                                               1 * FT_SECOND, &status);
793                 if (result >= 0 && !(status & QIC_STATUS_ERROR)) {
794                         rate_changed = 1;
795                 }
796         }
797         TRACE_CATCH(result = ftape_report_configuration(&dummy_model,
798                                                         &data_rate, 
799                                                         &dummy_qic_std,
800                                                         &dummy_tape_len),);
801         if (data_rate != new_rate) {
802                 if (!supported) {
803                         TRACE(ft_t_warn, "Rate change not supported!");
804                 } else if (rate_changed) {
805                         TRACE(ft_t_warn, "Requested: %d, got %d",
806                               new_rate, data_rate);
807                 } else {
808                         TRACE(ft_t_warn, "Rate change failed!");
809                 }
810                 result = -EINVAL;
811         }
812         /*
813          *  Set data rate and write precompensation as specified:
814          *
815          *            |  QIC-40/80  | QIC-3010/3020
816          *   rate     |   precomp   |    precomp
817          *  ----------+-------------+--------------
818          *  250 Kbps. |   250 ns.   |     0 ns.
819          *  500 Kbps. |   125 ns.   |     0 ns.
820          *    1 Mbps. |    42 ns.   |     0 ns.
821          *    2 Mbps  |      N/A    |     0 ns.
822          */
823         if ((qic_std == QIC_TAPE_QIC40 && data_rate > 500) || 
824             (qic_std == QIC_TAPE_QIC80 && data_rate > 1000)) {
825                 TRACE_ABORT(-EINVAL,
826                             ft_t_warn, "Datarate too high for QIC-mode");
827         }
828         TRACE_CATCH(fdc_set_data_rate(data_rate),_res = -EINVAL);
829         ft_data_rate = data_rate;
830         if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) {
831                 switch (data_rate) {
832                 case 250:
833                         fdc_set_write_precomp(250);
834                         break;
835                 default:
836                 case 500:
837                         fdc_set_write_precomp(125);
838                         break;
839                 case 1000:
840                         fdc_set_write_precomp(42);
841                         break;
842                 }
843         } else {
844                 fdc_set_write_precomp(0);
845         }
846         TRACE_EXIT result;
847 }
848
849 /*  The next two functions are used to cope with excessive overrun errors
850  */
851 int ftape_increase_threshold(void)
852 {
853         TRACE_FUN(ft_t_flow);
854
855         if (fdc.type < i82077 || ft_fdc_threshold >= 12) {
856                 TRACE_ABORT(-EIO, ft_t_err, "cannot increase fifo threshold");
857         }
858         if (fdc_fifo_threshold(++ft_fdc_threshold, NULL, NULL, NULL) < 0) {
859                 TRACE(ft_t_err, "cannot increase fifo threshold");
860                 ft_fdc_threshold --;
861                 fdc_reset();
862         }
863         TRACE(ft_t_info, "New FIFO threshold: %d", ft_fdc_threshold);
864         TRACE_EXIT 0;
865 }
866
867 int ftape_half_data_rate(void)
868 {
869         if (ft_data_rate < 500) {
870                 return -1;
871         }
872         if (ftape_set_data_rate(ft_data_rate / 2, ft_qic_std) < 0) {
873                 return -EIO;
874         }
875         ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
876         return 0;
877 }
878
879 /*      Seek the head to the specified track.
880  */
881 int ftape_seek_head_to_track(unsigned int track)
882 {
883         int status;
884         TRACE_FUN(ft_t_any);
885
886         ft_location.track = -1; /* remains set in case of error */
887         if (track >= ft_tracks_per_tape) {
888                 TRACE_ABORT(-EINVAL, ft_t_bug, "track out of bounds");
889         }
890         TRACE(ft_t_flow, "seeking track %d", track);
891         TRACE_CATCH(ftape_command(QIC_SEEK_HEAD_TO_TRACK),);
892         TRACE_CATCH(ftape_parameter_wait(track, ftape_timeout.head_seek,
893                                          &status),);
894         ft_location.track = track;
895         ftape_might_be_off_track = 0;
896         TRACE_EXIT 0;
897 }
898
899 int ftape_wakeup_drive(wake_up_types method)
900 {
901         int status;
902         int motor_on = 0;
903         TRACE_FUN(ft_t_any);
904
905         switch (method) {
906         case wake_up_colorado:
907                 TRACE_CATCH(ftape_command(QIC_PHANTOM_SELECT),);
908                 TRACE_CATCH(ftape_parameter(0 /* ft_drive_sel ?? */),);
909                 break;
910         case wake_up_mountain:
911                 TRACE_CATCH(ftape_command(QIC_SOFT_SELECT),);
912                 ftape_sleep(FT_MILLISECOND);    /* NEEDED */
913                 TRACE_CATCH(ftape_parameter(18),);
914                 break;
915         case wake_up_insight:
916                 ftape_sleep(100 * FT_MILLISECOND);
917                 motor_on = 1;
918                 fdc_motor(motor_on);    /* enable is done by motor-on */
919         case no_wake_up:
920                 break;
921         default:
922                 TRACE_EXIT -ENODEV;     /* unknown wakeup method */
923                 break;
924         }
925         /*  If wakeup succeeded we shouldn't get an error here..
926          */
927         TRACE_CATCH(ftape_report_raw_drive_status(&status),
928                     if (motor_on) {
929                             fdc_motor(0);
930                     });
931         TRACE_EXIT 0;
932 }
933
934 int ftape_put_drive_to_sleep(wake_up_types method)
935 {
936         TRACE_FUN(ft_t_any);
937
938         switch (method) {
939         case wake_up_colorado:
940                 TRACE_CATCH(ftape_command(QIC_PHANTOM_DESELECT),);
941                 break;
942         case wake_up_mountain:
943                 TRACE_CATCH(ftape_command(QIC_SOFT_DESELECT),);
944                 break;
945         case wake_up_insight:
946                 fdc_motor(0);   /* enable is done by motor-on */
947         case no_wake_up:        /* no wakeup / no sleep ! */
948                 break;
949         default:
950                 TRACE_EXIT -ENODEV;     /* unknown wakeup method */
951         }
952         TRACE_EXIT 0;
953 }
954
955 int ftape_reset_drive(void)
956 {
957         int result = 0;
958         int status;
959         unsigned int err_code;
960         qic117_cmd_t err_command;
961         int i;
962         TRACE_FUN(ft_t_any);
963
964         /*  We want to re-establish contact with our drive.  Fire a
965          *  number of reset commands (single step pulses) and pray for
966          *  success.
967          */
968         for (i = 0; i < 2; ++i) {
969                 TRACE(ft_t_flow, "Resetting fdc");
970                 fdc_reset();
971                 ftape_sleep(10 * FT_MILLISECOND);
972                 TRACE(ft_t_flow, "Reset command to drive");
973                 result = ftape_command(QIC_RESET);
974                 if (result == 0) {
975                         ftape_sleep(1 * FT_SECOND); /*  drive not
976                                                      *  accessible
977                                                      *  during 1 second
978                                                      */
979                         TRACE(ft_t_flow, "Re-selecting drive");
980
981                         /* Strange, the QIC-117 specs don't mention
982                          * this but the drive gets deselected after a
983                          * soft reset !  So we need to enable it
984                          * again.
985                          */
986                         if (ftape_wakeup_drive(ft_drive_type.wake_up) < 0) {
987                                 TRACE(ft_t_err, "Wakeup failed !");
988                         }
989                         TRACE(ft_t_flow, "Waiting until drive gets ready");
990                         result= ftape_ready_wait(ftape_timeout.reset, &status);
991                         if (result == 0 && (status & QIC_STATUS_ERROR)) {
992                                 result = ftape_report_error(&err_code,
993                                                             &err_command, 1);
994                                 if (result == 0 && err_code == 27) {
995                                         /*  Okay, drive saw reset
996                                          *  command and responded as it
997                                          *  should
998                                          */
999                                         break;
1000                                 } else {
1001                                         result = -EIO;
1002                                 }
1003                         } else {
1004                                 result = -EIO;
1005                         }
1006                 }
1007                 FT_SIGNAL_EXIT(_DONT_BLOCK);
1008         }
1009         if (result != 0) {
1010                 TRACE(ft_t_err, "General failure to reset tape drive");
1011         } else {
1012                 /*  Restore correct settings: keep original rate 
1013                  */
1014                 ftape_set_data_rate(ft_data_rate, ft_qic_std);
1015         }
1016         ftape_init_drive_needed = 1;
1017         TRACE_EXIT result;
1018 }