This source file includes following definitions.
- udelay
- udelay_calibrate
- ftape_sleep
- ftape_command
- ftape_parameter
- ftape_ready_wait
- ftape_command_wait
- ftape_parameter_wait
- ftape_report_operation
- ftape_report_raw_drive_status
- ftape_report_drive_status
- ftape_report_error
- ftape_in_error_state
- ftape_report_configuration
- ftape_report_rom_version
- ftape_report_signature
- ftape_report_vendor_id
- ftape_set_rate_test
- ftape_set_data_rate
- ftape_seek_head_to_track
- ftape_wakeup_drive
- ftape_put_drive_to_sleep
- ftape_reset_drive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <linux/module.h>
30 #include <linux/errno.h>
31 #include <linux/sched.h>
32 #include <linux/mm.h>
33 #include <linux/ftape.h>
34 #include <asm/segment.h>
35 #include <asm/system.h>
36 #include <linux/ioctl.h>
37 #include <linux/mtio.h>
38
39 #include "tracing.h"
40 #include "fdc-io.h"
41 #include "qic117.h"
42 #include "ftape-io.h"
43 #include "ftape-ctl.h"
44 #include "ftape-rw.h"
45 #include "ftape-write.h"
46 #include "ftape-read.h"
47 #include "ftape-eof.h"
48 #include "kernel-interface.h"
49 #include "calibr.h"
50
51
52
53
54 timeout_table timeout;
55 vendor_struct drive_type;
56 int qic_std;
57 int tape_len;
58 volatile int current_command;
59 const struct qic117_command_table qic117_cmds[] = QIC117_COMMANDS;
60 int might_be_off_track;
61
62
63
64 static int command_parameter = 0;
65
66
67
68
69 static const ftape_error ftape_errors[] = QIC117_ERRORS;
70 static int ftape_udelay_count;
71 static int ftape_udelay_time;
72 static const struct {
73 char *text;
74 int fdc_code;
75 byte drive_code;
76 int precomp;
77 } rates[4] = {
78
79 #if defined(FDC_82078SL)
80 {
81 "2 M", -1 , QIC_CONFIG_RATE_2000, 0
82 },
83 #else
84 {
85 "2 M", fdc_data_rate_2000, QIC_CONFIG_RATE_2000, 0
86 },
87 #endif
88 {
89 "1 M", fdc_data_rate_1000, QIC_CONFIG_RATE_1000, 42
90 },
91 {
92 "500 K", fdc_data_rate_500, QIC_CONFIG_RATE_500, 125
93 },
94 {
95 "250 K", fdc_data_rate_250, QIC_CONFIG_RATE_250, 250
96 },
97 };
98 typedef enum {
99 prehistoric, pre_qic117c, post_qic117b, post_qic117d
100 } qic_model;
101
102
103 void udelay(int usecs)
104 {
105 volatile int count = (1 + (usecs * ftape_udelay_count - 1) /
106 ftape_udelay_time);
107 volatile int i;
108
109 while (count-- > 0) {
110 for (i = 0; i < 20; ++i);
111 }
112 }
113
114 int udelay_calibrate(void)
115 {
116 return calibrate("udelay", udelay, &ftape_udelay_count, &ftape_udelay_time);
117 }
118
119
120
121 void ftape_sleep(unsigned int time)
122 {
123 TRACE_FUN(8, "ftape_sleep");
124 unsigned long flags;
125 int ticks = 1 + (time + MSPT - 1) / MSPT;
126
127
128
129 if (time < MSPT) {
130
131 udelay(1000 * time);
132 } else {
133 TRACEx2(8, "%d msec, %d ticks", time, ticks);
134 current->timeout = jiffies + ticks;
135 current->state = TASK_INTERRUPTIBLE;
136 save_flags(flags);
137 sti();
138 do {
139 while (current->state != TASK_RUNNING) {
140 schedule();
141 }
142 if (current->signal & ~current->blocked) {
143 TRACE(1, "awoken by non-blocked signal :-(");
144 break;
145 }
146 } while (current->timeout > 0);
147 restore_flags(flags);
148 }
149 TRACE_EXIT;
150 }
151
152 int ftape_report_raw_drive_status(int *status);
153
154
155
156
157 int ftape_command(int command)
158 {
159 TRACE_FUN(8, "ftape_command");
160 int result = 0;
161 int track;
162 int old_tracing = tracing;
163 static int level = 0;
164 int status = -1;
165
166 if (++level > 5) {
167
168
169 TRACEx1(1, "bug - recursion for command: %d", command);
170 result = -EIO;
171 } else if (command_parameter) {
172
173
174 TRACEx1(5, "called with parameter = %d", command - 2);
175 } else if (command <= 0 || command > NR_ITEMS(qic117_cmds)) {
176
177
178 TRACEx1(-1, "bug - bad command: %d", command);
179 result = -EIO;
180 } else {
181
182
183
184 if (command == QIC_REPORT_DRIVE_STATUS) {
185 TRACE(8, "report drive status called");
186 tracing = 0;
187 } else if (command == QIC_REPORT_NEXT_BIT) {
188 tracing = 0;
189 } else {
190 TRACEx1(5, "%s", qic117_cmds[command].name);
191
192
193
194
195
196 if (qic117_cmds[command].cmd_type == motion &&
197 qic117_cmds[current_command].non_intr) {
198 ftape_report_raw_drive_status(&status);
199 if ((status & QIC_STATUS_READY) == 0) {
200 TRACEx2(4, "motion cmd (%d) during non-intr cmd (%d)",
201 command, current_command);
202 TRACE(4, "waiting until drive gets ready");
203 ftape_ready_wait(timeout.seek, &status);
204 }
205 }
206 if (qic117_cmds[command].mask != 0) {
207 byte difference;
208
209
210
211 if (status == -1) {
212 ftape_report_raw_drive_status(&status);
213 }
214 difference = ((status ^ qic117_cmds[command].state) &
215 qic117_cmds[command].mask);
216
217
218
219 while ((difference & QIC_STATUS_READY) != 0) {
220 TRACEx1(4, "command %d issued while not ready", command);
221 TRACE(4, "waiting until drive gets ready");
222 ftape_ready_wait(timeout.seek, &status);
223 difference = ((status ^ qic117_cmds[command].state) &
224 qic117_cmds[command].mask);
225
226
227 if (current->signal & _DONT_BLOCK) {
228 result = -EINTR;
229 break;
230 }
231 }
232 while (result == 0 && (difference & QIC_STATUS_ERROR) != 0) {
233 int err;
234 int cmd;
235
236 TRACEx1(4, "command %d issued while error pending", command);
237 TRACE(4, "clearing error status");
238 ftape_report_error(&err, &cmd, 1);
239 ftape_report_raw_drive_status(&status);
240 difference = ((status ^ qic117_cmds[command].state) &
241 qic117_cmds[command].mask);
242
243
244 if (current->signal & _DONT_BLOCK) {
245 result = -EINTR;
246 break;
247 }
248 }
249 if (result == 0 && difference) {
250
251
252 if (difference & (QIC_STATUS_CARTRIDGE_PRESENT |
253 QIC_STATUS_NEW_CARTRIDGE |
254 QIC_STATUS_REFERENCED)) {
255 TRACE(1, "Fatal: tape removed or reinserted !");
256 ftape_failure = 1;
257 } else {
258 TRACEx2(1, "wrong state: 0x%02x should be: 0x%02x",
259 status & qic117_cmds[command].mask,
260 qic117_cmds[command].state);
261 }
262 result = -EIO;
263 }
264 if (~status & QIC_STATUS_READY & qic117_cmds[command].mask) {
265 TRACE(1, "Bad: still busy!");
266 result = -EBUSY;
267 }
268 }
269 }
270 }
271 tracing = old_tracing;
272
273
274 if (result >= 0) {
275
276
277
278 ftape_sleep(3 * MILLISECOND);
279
280
281 if (current_cylinder >= command) {
282 track = current_cylinder - command;
283 } else {
284 track = current_cylinder + command;
285 }
286 result = fdc_seek(track);
287
288
289
290 if (qic117_cmds[command].cmd_type == motion &&
291 command != QIC_LOGICAL_FORWARD && command != QIC_STOP_TAPE) {
292 location.known = 0;
293 }
294 command_parameter = 0;
295 current_command = command;
296 }
297 --level;
298 TRACE_EXIT;
299 return result;
300 }
301
302
303
304
305
306 int ftape_parameter(int command)
307 {
308 command_parameter = 1;
309 return ftape_command(command + 2);
310 }
311
312
313
314
315
316 int ftape_ready_wait(int timeout, int *status)
317 {
318 TRACE_FUN(8, "ftape_ready_wait");
319 int result;
320 unsigned long t0;
321 const int poll_delay = 100 * MILLISECOND;
322
323 for (;;) {
324 t0 = jiffies;
325 result = ftape_report_raw_drive_status(status);
326 if (result < 0) {
327 TRACE(1, "ftape_report_raw_drive_status failed");
328 result = -EIO;
329 break;
330 }
331 if (*status & QIC_STATUS_READY) {
332 result = 0;
333 break;
334 }
335 if (timeout >= 0) {
336
337
338
339 timeout -= ((jiffies - t0) * SECOND) / HZ;
340 if (timeout <= 0) {
341 TRACE(1, "timeout");
342 result = -ETIME;
343 break;
344 }
345 ftape_sleep(poll_delay);
346 timeout -= poll_delay;
347 } else {
348 ftape_sleep(poll_delay);
349 }
350 if (current->signal & _NEVER_BLOCK) {
351 TRACE(1, "interrupted by fatal signal");
352 result = -EINTR;
353 break;
354 }
355 }
356 TRACE_EXIT;
357 return result;
358 }
359
360
361
362 int ftape_command_wait(int command, int timeout, int *status)
363 {
364 TRACE_FUN(8, "ftape_command_wait");
365 int result;
366
367
368
369 result = ftape_command(command);
370 if (result >= 0) {
371 result = ftape_ready_wait(timeout, status);
372 }
373 TRACE_EXIT;
374 return result;
375 }
376
377 int ftape_parameter_wait(int command, int timeout, int *status)
378 {
379 TRACE_FUN(8, "ftape_parameter_wait");
380 int result;
381
382
383
384 result = ftape_parameter(command);
385 if (result >= 0) {
386 result = ftape_ready_wait(timeout, status);
387 }
388 TRACE_EXIT;
389 return result;
390 }
391
392
393
394
395
396
397
398
399
400 static int ftape_report_operation(int *status, int command, int result_length)
401 {
402 TRACE_FUN(8, "ftape_report_operation");
403 int i, st3;
404 int result;
405 unsigned int t0, t1, dt;
406
407 result = ftape_command(command);
408 if (result < 0) {
409 TRACE(1, "ftape_command failed");
410 TRACE_EXIT;
411 return result;
412 }
413 t0 = timestamp();
414 dt = 0;
415 i = 0;
416 do {
417 ++i;
418 ftape_sleep(3 * MILLISECOND);
419 result = fdc_sense_drive_status(&st3);
420 if (result < 0) {
421 TRACE(1, "fdc_sense_drive_status failed");
422 TRACE_EXIT;
423 return result;
424 }
425
426
427
428
429 t1 = timestamp();
430 dt += timediff(t0, t1);
431 t0 = t1;
432
433
434
435
436 } while (!(st3 & ST3_TRACK_0) && dt < 300000);
437 if (st3 & ST3_TRACK_0) {
438
439
440
441 if (i > 1 && dt > 6000) {
442 TRACEx2(1, "Acknowledge after %u msec. (%i iter)", dt / 1000, i);
443 }
444 } else {
445 TRACEx2(1, "No acknowledge after %u msec. (%i iter)", dt / 1000, i);
446 TRACE(1, "timeout on Acknowledge");
447 TRACE_EXIT;
448 return -EIO;
449 }
450 *status = 0;
451 for (i = 0; i < result_length + 1; i++) {
452 result = ftape_command(QIC_REPORT_NEXT_BIT);
453 if (result < 0) {
454 TRACE(1, "report next bit failed");
455 TRACE_EXIT;
456 return result;
457 }
458 #if 1
459
460
461
462
463 #else
464 fdc_interrupt_wait(25 * MILLISECOND);
465 #endif
466 result = fdc_sense_drive_status(&st3);
467 if (result < 0) {
468 TRACE(1, "fdc_sense_drive_status (2) failed");
469 TRACE_EXIT;
470 return result;
471 }
472 if (i < result_length) {
473 *status |= ((st3 & ST3_TRACK_0) ? 1 : 0) << i;
474 } else {
475 if ((st3 & ST3_TRACK_0) == 0) {
476 TRACE(1, "missing status stop bit");
477 TRACE_EXIT;
478 return -EIO;
479 }
480 }
481 }
482
483 result = ftape_command(QIC_REPORT_NEXT_BIT);
484 TRACE_EXIT;
485 return 0;
486 }
487
488
489
490 int ftape_report_raw_drive_status(int *status)
491 {
492 TRACE_FUN(8, "ftape_report_raw_drive_status");
493 int result;
494 int count = 0;
495
496 do {
497 result = ftape_report_operation(status, QIC_REPORT_DRIVE_STATUS, 8);
498 } while (result < 0 && ++count <= 3);
499 if (result < 0) {
500 TRACE(1, "report_operation failed");
501 result = -EIO;
502 } else if (*status & QIC_STATUS_READY) {
503 current_command = 0;
504 }
505 TRACE_EXIT;
506 return result;
507 }
508
509 int ftape_report_drive_status(int *status)
510 {
511 TRACE_FUN(8, "ftape_report_drive_status");
512 int result;
513
514 result = ftape_report_raw_drive_status(status);
515 if (result < 0) {
516 TRACE(1, "ftape_report_raw_drive_status failed");
517 TRACE_EXIT;
518 return result;
519 }
520 if (*status & QIC_STATUS_NEW_CARTRIDGE ||
521 !(*status & QIC_STATUS_CARTRIDGE_PRESENT)) {
522 ftape_failure = 1;
523 TRACE_EXIT;
524 return -EIO;
525 }
526 if (*status & QIC_STATUS_READY && *status & QIC_STATUS_ERROR) {
527
528 TRACE(2, "warning: error status set!");
529 result = 1;
530 }
531 TRACE_EXIT;
532 return result;
533 }
534
535 int ftape_report_error(int *error, int *command, int report)
536 {
537 TRACE_FUN(8, "ftape_report_error");
538 int code;
539 int result;
540
541 result = ftape_report_operation(&code, QIC_REPORT_ERROR_CODE, 16);
542 if (result < 0) {
543 result = -EIO;
544 } else {
545 *error = code & 0xff;
546 *command = (code >> 8) & 0xff;
547 if (report) {
548 if (*error != 0) {
549 TRACEi(3, "errorcode:", *error);
550 } else {
551 TRACE(3, "No error");
552 }
553 }
554 if (report && *error != 0 && tracing > 3) {
555 if (*error >= 0 && *error < NR_ITEMS(ftape_errors)) {
556 TRACEx1(-1, "%sFatal ERROR:",
557 (ftape_errors[*error].fatal ? "" : "Non-"));
558 TRACEx1(-1, "%s ...", ftape_errors[*error].message);
559 } else {
560 TRACE(-1, "Unknown ERROR !");
561 }
562 if (*command >= 0 && *command < NR_ITEMS(qic117_cmds) &&
563 qic117_cmds[*command].name != NULL) {
564 TRACEx1(-1, "... caused by command \'%s\'",
565 qic117_cmds[*command].name);
566 } else {
567 TRACEi(-1, "... caused by unknown command", *command);
568 }
569 }
570 }
571 TRACE_EXIT;
572 return result;
573 }
574
575 int ftape_in_error_state(int status)
576 {
577 TRACE_FUN(8, "ftape_in_error_state");
578 int result = 0;
579
580 if ((status & QIC_STATUS_READY) && (status & QIC_STATUS_ERROR)) {
581 TRACE(2, "warning: error status set!");
582 result = 1;
583 }
584 TRACE_EXIT;
585 return result;
586 }
587
588 static int ftape_report_configuration(qic_model * model, int *rate,
589 int *qic_std, int *tape_len)
590 {
591 int result;
592 int config;
593 int status;
594
595 TRACE_FUN(8, "ftape_report_configuration");
596 result = ftape_report_operation(&config, QIC_REPORT_DRIVE_CONFIGURATION, 8);
597 if (result < 0) {
598 *model = prehistoric;
599 *rate = QIC_CONFIG_RATE_500;
600 *qic_std = QIC_TAPE_QIC40;
601 *tape_len = 205;
602 result = 0;
603 } else {
604 *rate = (config & QIC_CONFIG_RATE_MASK) >> QIC_CONFIG_RATE_SHIFT;
605 result = ftape_report_operation(&status, QIC_REPORT_TAPE_STATUS, 8);
606 if (result < 0) {
607
608
609 *qic_std = (config & QIC_CONFIG_80) ? QIC_TAPE_QIC80 : QIC_TAPE_QIC40;
610 *tape_len = (config & QIC_CONFIG_LONG) ? 307 : 205;
611 *model = pre_qic117c;
612 result = 0;
613 } else {
614 *model = post_qic117b;
615 TRACEx1(8, "report tape status result = %02x", status);
616
617
618 switch (status & QIC_TAPE_STD_MASK) {
619 case QIC_TAPE_QIC40:
620 case QIC_TAPE_QIC80:
621 case QIC_TAPE_QIC3020:
622 case QIC_TAPE_QIC3010:
623 *qic_std = status & QIC_TAPE_STD_MASK;
624 break;
625 default:
626 *qic_std = -1;
627 break;
628 }
629 switch (status & QIC_TAPE_LEN_MASK) {
630 case QIC_TAPE_205FT:
631
632
633
634
635
636 if (config & QIC_CONFIG_LONG) {
637 *tape_len = 425;
638 } else {
639 *tape_len = 0;
640 }
641 break;
642 case QIC_TAPE_307FT:
643 *tape_len = 307;
644 break;
645 case QIC_TAPE_400FT:
646
647
648
649
650
651
652 *tape_len = 750;
653 break;
654 case QIC_TAPE_1100FT:
655 *tape_len = 1100;
656 break;
657 case QIC_TAPE_FLEX:
658 *tape_len = 0;
659 break;
660 default:
661 *tape_len = -1;
662 break;
663 }
664 if (*qic_std == -1 || *tape_len == -1) {
665 TRACE(2, "post qic-117b spec drive with unknown tape");
666 result = -EIO;
667 } else {
668 result = 0;
669 }
670 }
671 }
672 TRACE_EXIT;
673 return (result < 0) ? -EIO : 0;
674 }
675
676 int ftape_report_rom_version(int *version)
677 {
678 int result;
679
680 result = ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8);
681 return (result < 0) ? -EIO : 0;
682 }
683
684 int ftape_report_signature(int *signature)
685 {
686 int result;
687
688 result = ftape_command(28);
689 result = ftape_report_operation(signature, 9, 8);
690 result = ftape_command(30);
691 return (result < 0) ? -EIO : 0;
692 }
693
694 void ftape_report_vendor_id(unsigned int *id)
695 {
696 TRACE_FUN(8, "ftape_report_vendor_id");
697 int result;
698
699
700
701
702
703
704
705 result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 16);
706 if (result < 0) {
707 result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 8);
708 if (result < 0) {
709
710
711 result = ftape_report_operation((int *) id, 24, 8);
712 if (result < 0) {
713 *id = UNKNOWN_VENDOR;
714 } else {
715 TRACEx1(4, "got old 8 bit id: %04x", *id);
716 *id |= 0x20000;
717 }
718 } else {
719 TRACEx1(4, "got 8 bit id: %04x", *id);
720 *id |= 0x10000;
721 }
722 } else {
723 TRACEx1(4, "got 16 bit id: %04x", *id);
724 }
725 if (*id == 0x0047) {
726 int version;
727 int sign;
728
729 result = ftape_report_rom_version(&version);
730 if (result < 0) {
731 TRACE(-1, "report rom version failed");
732 TRACE_EXIT;
733 return;
734 }
735 TRACEx1(4, "CMS rom version: %d", version);
736 ftape_command(QIC_ENTER_DIAGNOSTIC_1);
737 ftape_command(QIC_ENTER_DIAGNOSTIC_1);
738 result = ftape_report_operation(&sign, 9, 8);
739 if (result < 0) {
740 int error, command;
741
742 ftape_report_error(&error, &command, 1);
743 ftape_command(QIC_ENTER_PRIMARY_MODE);
744 TRACE_EXIT;
745 return;
746 } else {
747 TRACEx1(4, "CMS signature: %02x", sign);
748 }
749 if (sign == 0xa5) {
750 result = ftape_report_operation(&sign, 37, 8);
751 if (result < 0) {
752 if (version >= 63) {
753 *id = 0x8880;
754 TRACE(4, "This is an Iomega drive !");
755 } else {
756 *id = 0x0047;
757 TRACE(4, "This is a real CMS drive !");
758 }
759 } else {
760 *id = 0x0047;
761 TRACEx1(4, "CMS status: %d", sign);
762 }
763 } else {
764 *id = UNKNOWN_VENDOR;
765 }
766 ftape_command(QIC_ENTER_PRIMARY_MODE);
767 }
768 TRACE_EXIT;
769 }
770
771 void ftape_set_rate_test(int *supported)
772 {
773 TRACE_FUN(8, "ftape_set_rate_test");
774 int error;
775 int command;
776 int i;
777 int result;
778 int status;
779
780
781
782
783
784 *supported = 0;
785 for (i = 0; i < NR_ITEMS(rates); ++i) {
786 result = ftape_command(QIC_SELECT_RATE);
787 if (result >= 0) {
788 result = ftape_parameter_wait(rates[i].drive_code,
789 1 * SECOND, &status);
790 if (result >= 0) {
791 if (status & QIC_STATUS_ERROR) {
792 result = ftape_report_error(&error, &command, 0);
793 } else {
794 *supported = 1;
795 }
796 }
797 }
798 }
799 TRACEx1(4, "Select Rate command is%s supported",
800 *supported ? "" : " not");
801 TRACE_EXIT;
802 }
803
804 int ftape_set_data_rate(int new_rate)
805 {
806 TRACE_FUN(8, "ftape_set_data_rate");
807 int status;
808 int result;
809 int data_rate;
810 qic_model model;
811 int supported;
812 static int first_time = 1;
813
814 if (first_time) {
815 ftape_set_rate_test(&supported);
816 first_time = 0;
817 }
818 if (rates[new_rate].fdc_code == -1) {
819 TRACEx1(4, "%sb/s data rate not supported by the fdc",
820 rates[new_rate].text);
821 result = -EINVAL;
822 } else {
823 int error = 0;
824 int command;
825
826 result = ftape_command(QIC_SELECT_RATE);
827 if (result >= 0) {
828 result = ftape_parameter_wait(rates[new_rate].drive_code,
829 1 * SECOND, &status);
830 result = ftape_report_raw_drive_status(&status);
831 if (result >= 0 && (status & QIC_STATUS_ERROR)) {
832 result = ftape_report_error(&error, &command, 0);
833 if (result >= 0 && supported &&
834 error == 31 && command == QIC_SELECT_RATE) {
835 result = -EINVAL;
836 }
837 }
838 }
839 if (result >= 0) {
840 result = ftape_report_configuration(&model, &data_rate,
841 &qic_std, &tape_len);
842 if (result >= 0 && data_rate != rates[new_rate].drive_code) {
843 result = -EINVAL;
844 }
845 }
846 if (result < 0) {
847 TRACEx1(4, "could not set %sb/s data rate", rates[new_rate].text);
848 } else {
849 TRACEx2(2, "%s drive @ %sb/s",
850 (model == prehistoric) ? "prehistoric" :
851 ((model == pre_qic117c) ? "pre QIC-117C" :
852 ((model == post_qic117b) ? "post QIC-117B" : "post QIC-117D")),
853 rates[new_rate].text);
854 if (tape_len == 0) {
855 TRACEx1(2, "unknown length QIC-%s tape",
856 (qic_std == QIC_TAPE_QIC40) ? "40" :
857 ((qic_std == QIC_TAPE_QIC80) ? "80" :
858 ((qic_std == QIC_TAPE_QIC3010) ? "3010" : "3020")));
859 } else {
860 TRACEx2(2, "%d ft. QIC-%s tape",
861 tape_len,
862 (qic_std == QIC_TAPE_QIC40) ? "40" :
863 ((qic_std == QIC_TAPE_QIC80) ? "80" :
864 ((qic_std == QIC_TAPE_QIC3010) ? "3010" : "3020")));
865 }
866
867
868
869
870
871
872
873
874
875
876
877 if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) {
878 fdc_set_write_precomp(rates[new_rate].precomp);
879 } else {
880 fdc_set_write_precomp(0);
881 }
882 fdc_set_data_rate(rates[new_rate].fdc_code);
883 ftape_data_rate = new_rate;
884 }
885 }
886 if (result < 0 && result != -EINVAL) {
887 result = -EIO;
888 }
889 TRACE_EXIT;
890 return result;
891 }
892
893
894
895 int ftape_seek_head_to_track(int track)
896 {
897 TRACE_FUN(8, "ftape_seek_head_to_track");
898 int status;
899 int result;
900
901 location.track = -1;
902 if (track < 0 || track >= tracks_per_tape) {
903 TRACE(-1, "track out of bounds");
904 result = -EINVAL;
905 } else {
906 TRACEx1(5, "seeking track %d", track);
907 result = ftape_command(QIC_SEEK_HEAD_TO_TRACK);
908 if (result < 0) {
909 TRACE(1, "ftape_command failed");
910 } else {
911 result = ftape_parameter_wait(track, timeout.head_seek, &status);
912 if (result < 0) {
913 TRACE(1, "ftape_parameter_wait failed");
914 } else {
915 location.track = track;
916 might_be_off_track = 0;
917 }
918 }
919 }
920 TRACE_EXIT;
921 return result;
922 }
923
924 int ftape_wakeup_drive(wake_up_types method)
925 {
926 TRACE_FUN(8, "ftape_wakeup_drive");
927 int result;
928 int status;
929 int motor_on = 0;
930
931 switch (method) {
932 case wake_up_colorado:
933 result = ftape_command(QIC_PHANTOM_SELECT);
934 if (result == 0) {
935 result = ftape_parameter( 0);
936 }
937 break;
938 case wake_up_mountain:
939 result = ftape_command(QIC_SOFT_SELECT);
940 if (result == 0) {
941 ftape_sleep(MILLISECOND);
942 result = ftape_parameter(18);
943 }
944 break;
945 case wake_up_insight:
946 ftape_sleep(100 * MILLISECOND);
947 motor_on = 1;
948 fdc_motor(motor_on);
949 case no_wake_up:
950 result = 0;
951 break;
952 default:
953 result = -ENODEV;
954 }
955
956
957 if (result == 0) {
958 result = ftape_report_raw_drive_status(&status);
959 if (result < 0 && motor_on) {
960 fdc_motor(0);
961 }
962 }
963 TRACE_EXIT;
964 return result;
965 }
966
967 int ftape_put_drive_to_sleep(vendor_struct drive_type)
968 {
969 TRACE_FUN(8, "ftape_put_drive_to_sleep");
970 int result;
971
972 switch (drive_type.wake_up) {
973 case wake_up_colorado:
974 result = ftape_command(QIC_PHANTOM_DESELECT);
975 break;
976 case wake_up_mountain:
977 result = ftape_command(QIC_SOFT_DESELECT);
978 break;
979 case wake_up_insight:
980 fdc_motor(0);
981 case no_wake_up:
982 result = 0;
983 break;
984 default:
985 result = -ENODEV;
986 }
987 TRACE_EXIT;
988 return result;
989 }
990
991 int ftape_reset_drive(void)
992 {
993 TRACE_FUN(8, "ftape_reset_drive");
994 int result = 0;
995 int status;
996 int err_code;
997 int err_command;
998 int i;
999
1000
1001
1002
1003
1004 for (i = 0; i < 2; ++i) {
1005 TRACE(5, "Resetting fdc");
1006 fdc_reset();
1007 ftape_sleep(10 * MILLISECOND);
1008 TRACE(5, "Reset command to drive");
1009 result = ftape_command(QIC_RESET);
1010 if (result == 0) {
1011 ftape_sleep(1 * SECOND);
1012 TRACE(5, "Re-selecting drive");
1013
1014
1015
1016
1017 result = ftape_wakeup_drive(drive_type.wake_up);
1018 if (result < 0) {
1019 TRACE(1, "Wakeup failed !");
1020 }
1021 TRACE(5, "Waiting until drive gets ready");
1022 result = ftape_ready_wait(timeout.reset, &status);
1023 if (result == 0 && status & QIC_STATUS_ERROR) {
1024 result = ftape_report_error(&err_code, &err_command, 1);
1025 if (result == 0 && err_code == 27) {
1026
1027
1028 break;
1029 } else {
1030 result = -EIO;
1031 }
1032 } else {
1033 result = -EIO;
1034 }
1035 }
1036 if (current->signal & _DONT_BLOCK) {
1037 TRACE(1, "aborted by non-blockable signal");
1038 result = -EINTR;
1039 break;
1040 }
1041 }
1042 if (result != 0) {
1043 TRACE(1, "General failure to reset tape drive");
1044 } else {
1045
1046
1047 ftape_set_data_rate(ftape_data_rate);
1048 }
1049 TRACE_EXIT;
1050 return result;
1051 }