ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / ftape / lowlevel / fdc-io.c
1 /*
2  * Copyright (C) 1993-1996 Bas Laarhoven,
3  *           (C) 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/fdc-io.c,v $
21  * $Revision: 1.7.4.2 $
22  * $Date: 1997/11/16 14:48:17 $
23  *
24  *      This file contains the low-level floppy disk interface code
25  *      for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
26  *      Linux.
27  */
28
29 #include <linux/config.h> /* for CONFIG_FT_* */
30 #include <linux/errno.h>
31 #include <linux/sched.h>
32 #include <linux/ioport.h>
33 #include <linux/interrupt.h>
34 #include <asm/system.h>
35 #include <asm/io.h>
36 #include <asm/dma.h>
37 #include <asm/irq.h>
38
39 #include <linux/ftape.h>
40 #include <linux/qic117.h>
41 #include "../lowlevel/ftape-tracing.h"
42 #include "../lowlevel/fdc-io.h"
43 #include "../lowlevel/fdc-isr.h"
44 #include "../lowlevel/ftape-io.h"
45 #include "../lowlevel/ftape-rw.h"
46 #include "../lowlevel/ftape-ctl.h"
47 #include "../lowlevel/ftape-calibr.h"
48 #include "../lowlevel/fc-10.h"
49
50 /*      Global vars.
51  */
52 int ftape_motor;
53 volatile int ftape_current_cylinder = -1;
54 volatile fdc_mode_enum fdc_mode = fdc_idle;
55 fdc_config_info fdc;
56 DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr);
57
58 unsigned int ft_fdc_base       = CONFIG_FT_FDC_BASE;
59 unsigned int ft_fdc_irq        = CONFIG_FT_FDC_IRQ;
60 unsigned int ft_fdc_dma        = CONFIG_FT_FDC_DMA;
61 unsigned int ft_fdc_threshold  = CONFIG_FT_FDC_THR;  /* bytes */
62 unsigned int ft_fdc_rate_limit = CONFIG_FT_FDC_MAX_RATE; /* bits/sec */
63 int ft_probe_fc10        = CONFIG_FT_PROBE_FC10;
64 int ft_mach2             = CONFIG_FT_MACH2;
65
66 /*      Local vars.
67  */
68 static spinlock_t fdc_io_lock; 
69 static unsigned int fdc_calibr_count;
70 static unsigned int fdc_calibr_time;
71 static int fdc_status;
72 volatile __u8 fdc_head;         /* FDC head from sector id */
73 volatile __u8 fdc_cyl;          /* FDC track from sector id */
74 volatile __u8 fdc_sect;         /* FDC sector from sector id */
75 static int fdc_data_rate = 500; /* data rate (Kbps) */
76 static int fdc_rate_code;       /* data rate code (0 == 500 Kbps) */
77 static int fdc_seek_rate = 2;   /* step rate (msec) */
78 static void (*do_ftape) (void);
79 static int fdc_fifo_state;      /* original fifo setting - fifo enabled */
80 static int fdc_fifo_thr;        /* original fifo setting - threshold */
81 static int fdc_lock_state;      /* original lock setting - locked */
82 static int fdc_fifo_locked;     /* has fifo && lock set ? */
83 static __u8 fdc_precomp;        /* default precomp. value (nsec) */
84 static __u8 fdc_prec_code;      /* fdc precomp. select code */
85
86 static char ftape_id[] = "ftape";  /* used by request irq and free irq */
87
88 void fdc_catch_stray_interrupts(int count)
89 {
90         unsigned long flags;
91
92         spin_lock_irqsave(&fdc_io_lock, flags);
93         if (count == 0) {
94                 ft_expected_stray_interrupts = 0;
95         } else {
96                 ft_expected_stray_interrupts += count;
97         }
98         spin_unlock_irqrestore(&fdc_io_lock, flags);
99 }
100
101 /*  Wait during a timeout period for a given FDC status.
102  *  If usecs == 0 then just test status, else wait at least for usecs.
103  *  Returns -ETIME on timeout. Function must be calibrated first !
104  */
105 int fdc_wait(unsigned int usecs, __u8 mask, __u8 state)
106 {
107         int count_1 = (fdc_calibr_count * usecs +
108                        fdc_calibr_count - 1) / fdc_calibr_time;
109
110         do {
111                 fdc_status = inb_p(fdc.msr);
112                 if ((fdc_status & mask) == state) {
113                         return 0;
114                 }
115         } while (count_1-- >= 0);
116         return -ETIME;
117 }
118
119 int fdc_ready_wait(unsigned int usecs)
120 {
121         return fdc_wait(usecs, FDC_DATA_READY | FDC_BUSY, FDC_DATA_READY);
122 }
123
124 /* Why can't we just use udelay()?
125  */
126 static void fdc_usec_wait(unsigned int usecs)
127 {
128         fdc_wait(usecs, 0, 1);  /* will always timeout ! */
129 }
130
131 int fdc_ready_out_wait(unsigned int usecs)
132 {
133         fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
134         return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_OUT_READY);
135 }
136
137 int fdc_ready_in_wait(unsigned int usecs)
138 {
139         fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
140         return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_IN_READY);
141 }
142
143 void fdc_wait_calibrate(void)
144 {
145         ftape_calibrate("fdc_wait",
146                         fdc_usec_wait, &fdc_calibr_count, &fdc_calibr_time); 
147 }
148
149 /*  Wait for a (short) while for the FDC to become ready
150  *  and transfer the next command byte.
151  *  Return -ETIME on timeout on getting ready (depends on hardware!).
152  */
153 static int fdc_write(const __u8 data)
154 {
155         fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
156         if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_IN_READY) < 0) {
157                 return -ETIME;
158         } else {
159                 outb(data, fdc.fifo);
160                 return 0;
161         }
162 }
163
164 /*  Wait for a (short) while for the FDC to become ready
165  *  and transfer the next result byte.
166  *  Return -ETIME if timeout on getting ready (depends on hardware!).
167  */
168 static int fdc_read(__u8 * data)
169 {
170         fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
171         if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_OUT_READY) < 0) {
172                 return -ETIME;
173         } else {
174                 *data = inb(fdc.fifo);
175                 return 0;
176         }
177 }
178
179 /*  Output a cmd_len long command string to the FDC.
180  *  The FDC should be ready to receive a new command or
181  *  an error (EBUSY or ETIME) will occur.
182  */
183 int fdc_command(const __u8 * cmd_data, int cmd_len)
184 {
185         int result = 0;
186         unsigned long flags;
187         int count = cmd_len;
188         int retry = 0;
189 #ifdef TESTING
190         static unsigned int last_time;
191         unsigned int time;
192 #endif
193         TRACE_FUN(ft_t_any);
194
195         fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
196         spin_lock_irqsave(&fdc_io_lock, flags);
197         if (!in_interrupt())
198                 /* Yes, I know, too much comments inside this function
199                  * ...
200                  * 
201                  * Yet another bug in the original driver. All that
202                  * havoc is caused by the fact that the isr() sends
203                  * itself a command to the floppy tape driver (pause,
204                  * micro step pause).  Now, the problem is that
205                  * commands are transmitted via the fdc_seek
206                  * command. But: the fdc performs seeks in the
207                  * background i.e. it doesn't signal busy while
208                  * sending the step pulses to the drive. Therefore the
209                  * non-interrupt level driver has no chance to tell
210                  * whether the isr() just has issued a seek. Therefore
211                  * we HAVE TO have a look at the ft_hide_interrupt
212                  * flag: it signals the non-interrupt level part of
213                  * the driver that it has to wait for the fdc until it
214                  * has completet seeking.
215                  *
216                  * THIS WAS PRESUMABLY THE REASON FOR ALL THAT
217                  * "fdc_read timeout" errors, I HOPE :-)
218                  */
219                 if (ft_hide_interrupt) {
220                         restore_flags(flags);
221                         TRACE(ft_t_info,
222                               "Waiting for the isr() completing fdc_seek()");
223                         if (fdc_interrupt_wait(2 * FT_SECOND) < 0) {
224                                 TRACE(ft_t_warn,
225                       "Warning: timeout waiting for isr() seek to complete");
226                         }
227                         if (ft_hide_interrupt || !ft_seek_completed) {
228                                 /* There cannot be another
229                                  * interrupt. The isr() only stops
230                                  * the tape and the next interrupt
231                                  * won't come until we have send our
232                                  * command to the drive.
233                                  */
234                                 TRACE_ABORT(-EIO, ft_t_bug,
235                                             "BUG? isr() is still seeking?\n"
236                                             KERN_INFO "hide: %d\n"
237                                             KERN_INFO "seek: %d",
238                                             ft_hide_interrupt,
239                                             ft_seek_completed);
240
241                         }
242                         fdc_usec_wait(FT_RQM_DELAY);    /* wait for valid RQM status */
243                         spin_lock_irqsave(&fdc_io_lock, flags);
244                 }
245         fdc_status = inb(fdc.msr);
246         if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) {
247                 spin_unlock_irqrestore(&fdc_io_lock, flags);
248                 TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready");
249         } 
250         fdc_mode = *cmd_data;   /* used by isr */
251 #ifdef TESTING
252         if (fdc_mode == FDC_SEEK) {
253                 time = ftape_timediff(last_time, ftape_timestamp());
254                 if (time < 6000) {
255         TRACE(ft_t_bug,"Warning: short timeout between seek commands: %d",
256               time);
257                 }
258         }
259 #endif
260         if (!in_interrupt()) {
261                 /* shouldn't be cleared if called from isr
262                  */
263                 ft_interrupt_seen = 0;
264         }
265         while (count) {
266                 result = fdc_write(*cmd_data);
267                 if (result < 0) {
268                         TRACE(ft_t_fdc_dma,
269                               "fdc_mode = %02x, status = %02x at index %d",
270                               (int) fdc_mode, (int) fdc_status,
271                               cmd_len - count);
272                         if (++retry <= 3) {
273                                 TRACE(ft_t_warn, "fdc_write timeout, retry");
274                         } else {
275                                 TRACE(ft_t_err, "fdc_write timeout, fatal");
276                                 /* recover ??? */
277                                 break;
278                         }
279                 } else {
280                         --count;
281                         ++cmd_data;
282                 }
283         }
284 #ifdef TESTING
285         if (fdc_mode == FDC_SEEK) {
286                 last_time = ftape_timestamp();
287         }
288 #endif
289         spin_unlock_irqrestore(&fdc_io_lock, flags);
290         TRACE_EXIT result;
291 }
292
293 /*  Input a res_len long result string from the FDC.
294  *  The FDC should be ready to send the result or an error
295  *  (EBUSY or ETIME) will occur.
296  */
297 int fdc_result(__u8 * res_data, int res_len)
298 {
299         int result = 0;
300         unsigned long flags;
301         int count = res_len;
302         int retry = 0;
303         TRACE_FUN(ft_t_any);
304
305         spin_lock_irqsave(&fdc_io_lock, flags);
306         fdc_status = inb(fdc.msr);
307         if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) {
308                 TRACE(ft_t_err, "fdc not ready");
309                 result = -EBUSY;
310         } else while (count) {
311                 if (!(fdc_status & FDC_BUSY)) {
312                         spin_unlock_irqrestore(&fdc_io_lock, flags);
313                         TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase");
314                 }
315                 result = fdc_read(res_data);
316                 if (result < 0) {
317                         TRACE(ft_t_fdc_dma,
318                               "fdc_mode = %02x, status = %02x at index %d",
319                               (int) fdc_mode,
320                               (int) fdc_status,
321                               res_len - count);
322                         if (++retry <= 3) {
323                                 TRACE(ft_t_warn, "fdc_read timeout, retry");
324                         } else {
325                                 TRACE(ft_t_err, "fdc_read timeout, fatal");
326                                 /* recover ??? */
327                                 break;
328                                 ++retry;
329                         }
330                 } else {
331                         --count;
332                         ++res_data;
333                 }
334         }
335         spin_unlock_irqrestore(&fdc_io_lock, flags);
336         fdc_usec_wait(FT_RQM_DELAY);    /* allow FDC to negate BSY */
337         TRACE_EXIT result;
338 }
339
340 /*      Handle command and result phases for
341  *      commands without data phase.
342  */
343 int fdc_issue_command(const __u8 * out_data, int out_count,
344                       __u8 * in_data, int in_count)
345 {
346         TRACE_FUN(ft_t_any);
347
348         if (out_count > 0) {
349                 TRACE_CATCH(fdc_command(out_data, out_count),);
350         }
351         /* will take 24 - 30 usec for fdc_sense_drive_status and
352          * fdc_sense_interrupt_status commands.
353          *    35 fails sometimes (5/9/93 SJL)
354          * On a loaded system it incidentally takes longer than
355          * this for the fdc to get ready ! ?????? WHY ??????
356          * So until we know what's going on use a very long timeout.
357          */
358         TRACE_CATCH(fdc_ready_out_wait(500 /* usec */),);
359         if (in_count > 0) {
360                 TRACE_CATCH(fdc_result(in_data, in_count),
361                             TRACE(ft_t_err, "result phase aborted"));
362         }
363         TRACE_EXIT 0;
364 }
365
366 /*      Wait for FDC interrupt with timeout (in milliseconds).
367  *      Signals are blocked so the wait will not be aborted.
368  *      Note: interrupts must be enabled ! (23/05/93 SJL)
369  */
370 int fdc_interrupt_wait(unsigned int time)
371 {
372         DECLARE_WAITQUEUE(wait,current);
373         sigset_t old_sigmask;   
374         static int resetting;
375         long timeout;
376
377         TRACE_FUN(ft_t_fdc_dma);
378
379         if (waitqueue_active(&ftape_wait_intr)) {
380                 TRACE_ABORT(-EIO, ft_t_err, "error: nested call");
381         }
382         /* timeout time will be up to USPT microseconds too long ! */
383         timeout = (1000 * time + FT_USPT - 1) / FT_USPT;
384
385         spin_lock_irq(&current->sighand->siglock);
386         old_sigmask = current->blocked;
387         sigfillset(&current->blocked);
388         recalc_sigpending();
389         spin_unlock_irq(&current->sighand->siglock);
390
391         current->state = TASK_INTERRUPTIBLE;
392         add_wait_queue(&ftape_wait_intr, &wait);
393         while (!ft_interrupt_seen && (current->state == TASK_INTERRUPTIBLE)) {
394                 timeout = schedule_timeout(timeout);
395         }
396
397         spin_lock_irq(&current->sighand->siglock);
398         current->blocked = old_sigmask;
399         recalc_sigpending();
400         spin_unlock_irq(&current->sighand->siglock);
401         
402         remove_wait_queue(&ftape_wait_intr, &wait);
403         /*  the following IS necessary. True: as well
404          *  wake_up_interruptible() as the schedule() set TASK_RUNNING
405          *  when they wakeup a task, BUT: it may very well be that
406          *  ft_interrupt_seen is already set to 1 when we enter here
407          *  in which case schedule() gets never called, and
408          *  TASK_RUNNING never set. This has the funny effect that we
409          *  execute all the code until we leave kernel space, but then
410          *  the task is stopped (a task CANNOT be preempted while in
411          *  kernel mode. Sending a pair of SIGSTOP/SIGCONT to the
412          *  tasks wakes it up again. Funny! :-)
413          */
414         current->state = TASK_RUNNING; 
415         if (ft_interrupt_seen) { /* woken up by interrupt */
416                 ft_interrupt_seen = 0;
417                 TRACE_EXIT 0;
418         }
419         /*  Original comment:
420          *  In first instance, next statement seems unnecessary since
421          *  it will be cleared in fdc_command. However, a small part of
422          *  the software seems to rely on this being cleared here
423          *  (ftape_close might fail) so stick to it until things get fixed !
424          */
425         /*  My deeply sought of knowledge:
426          *  Behold NO! It is obvious. fdc_reset() doesn't call fdc_command()
427          *  but nevertheless uses fdc_interrupt_wait(). OF COURSE this needs to
428          *  be reset here.
429          */
430         ft_interrupt_seen = 0;  /* clear for next call */
431         if (!resetting) {
432                 resetting = 1;  /* break infinite recursion if reset fails */
433                 TRACE(ft_t_any, "cleanup reset");
434                 fdc_reset();
435                 resetting = 0;
436         }
437         TRACE_EXIT (signal_pending(current)) ? -EINTR : -ETIME;
438 }
439
440 /*      Start/stop drive motor. Enable DMA mode.
441  */
442 void fdc_motor(int motor)
443 {
444         int unit = ft_drive_sel;
445         int data = unit | FDC_RESET_NOT | FDC_DMA_MODE;
446         TRACE_FUN(ft_t_any);
447
448         ftape_motor = motor;
449         if (ftape_motor) {
450                 data |= FDC_MOTOR_0 << unit;
451                 TRACE(ft_t_noise, "turning motor %d on", unit);
452         } else {
453                 TRACE(ft_t_noise, "turning motor %d off", unit);
454         }
455         if (ft_mach2) {
456                 outb_p(data, fdc.dor2);
457         } else {
458                 outb_p(data, fdc.dor);
459         }
460         ftape_sleep(10 * FT_MILLISECOND);
461         TRACE_EXIT;
462 }
463
464 static void fdc_update_dsr(void)
465 {
466         TRACE_FUN(ft_t_any);
467
468         TRACE(ft_t_flow, "rate = %d Kbps, precomp = %d ns",
469               fdc_data_rate, fdc_precomp);
470         if (fdc.type >= i82077) {
471                 outb_p((fdc_rate_code & 0x03) | fdc_prec_code, fdc.dsr);
472         } else {
473                 outb_p(fdc_rate_code & 0x03, fdc.ccr);
474         }
475         TRACE_EXIT;
476 }
477
478 void fdc_set_write_precomp(int precomp)
479 {
480         TRACE_FUN(ft_t_any);
481
482         TRACE(ft_t_noise, "New precomp: %d nsec", precomp);
483         fdc_precomp = precomp;
484         /*  write precompensation can be set in multiples of 41.67 nsec.
485          *  round the parameter to the nearest multiple and convert it
486          *  into a fdc setting. Note that 0 means default to the fdc,
487          *  7 is used instead of that.
488          */
489         fdc_prec_code = ((fdc_precomp + 21) / 42) << 2;
490         if (fdc_prec_code == 0 || fdc_prec_code > (6 << 2)) {
491                 fdc_prec_code = 7 << 2;
492         }
493         fdc_update_dsr();
494         TRACE_EXIT;
495 }
496
497 /*  Reprogram the 82078 registers to use Data Rate Table 1 on all drives.
498  */
499 void fdc_set_drive_specs(void)
500 {
501         __u8 cmd[] = { FDC_DRIVE_SPEC, 0x00, 0x00, 0x00, 0x00, 0xc0};
502         int result;
503         TRACE_FUN(ft_t_any);
504
505         TRACE(ft_t_flow, "Setting of drive specs called");
506         if (fdc.type >= i82078_1) {
507                 cmd[1] = (0 << 5) | (2 << 2);
508                 cmd[2] = (1 << 5) | (2 << 2);
509                 cmd[3] = (2 << 5) | (2 << 2);
510                 cmd[4] = (3 << 5) | (2 << 2);
511                 result = fdc_command(cmd, NR_ITEMS(cmd));
512                 if (result < 0) {
513                         TRACE(ft_t_err, "Setting of drive specs failed");
514                 }
515         }
516         TRACE_EXIT;
517 }
518
519 /* Select clock for fdc, must correspond with tape drive setting !
520  * This also influences the fdc timing so we must adjust some values.
521  */
522 int fdc_set_data_rate(int rate)
523 {
524         int bad_rate = 0;
525         TRACE_FUN(ft_t_any);
526
527         /* Select clock for fdc, must correspond with tape drive setting !
528          * This also influences the fdc timing so we must adjust some values.
529          */
530         TRACE(ft_t_fdc_dma, "new rate = %d", rate);
531         switch (rate) {
532         case 250:
533                 fdc_rate_code = fdc_data_rate_250;
534                 break;
535         case 500:
536                 fdc_rate_code = fdc_data_rate_500;
537                 break;
538         case 1000:
539                 if (fdc.type < i82077) {
540                         bad_rate = 1;
541                 } else {
542                         fdc_rate_code = fdc_data_rate_1000;
543                 }
544                 break;
545         case 2000:
546                 if (fdc.type < i82078_1) {
547                         bad_rate = 1;
548                 } else {
549                         fdc_rate_code = fdc_data_rate_2000;
550                 }
551                 break;
552         default:
553                 bad_rate = 1;
554         }
555         if (bad_rate) {
556                 TRACE_ABORT(-EIO,
557                             ft_t_fdc_dma, "%d is not a valid data rate", rate);
558         }
559         fdc_data_rate = rate;
560         fdc_update_dsr();
561         fdc_set_seek_rate(fdc_seek_rate);  /* clock changed! */
562         ftape_udelay(1000);
563         TRACE_EXIT 0;
564 }
565
566 /*  keep the unit select if keep_select is != 0,
567  */
568 static void fdc_dor_reset(int keep_select)
569 {
570         __u8 fdc_ctl = ft_drive_sel;
571
572         if (keep_select != 0) {
573                 fdc_ctl |= FDC_DMA_MODE;
574                 if (ftape_motor) {
575                         fdc_ctl |= FDC_MOTOR_0 << ft_drive_sel;
576                 }
577         }
578         ftape_udelay(10); /* ??? but seems to be necessary */
579         if (ft_mach2) {
580                 outb_p(fdc_ctl & 0x0f, fdc.dor);
581                 outb_p(fdc_ctl, fdc.dor2);
582         } else {
583                 outb_p(fdc_ctl, fdc.dor);
584         }
585         fdc_usec_wait(10); /* delay >= 14 fdc clocks */
586         if (keep_select == 0) {
587                 fdc_ctl = 0;
588         }
589         fdc_ctl |= FDC_RESET_NOT;
590         if (ft_mach2) {
591                 outb_p(fdc_ctl & 0x0f, fdc.dor);
592                 outb_p(fdc_ctl, fdc.dor2);
593         } else {
594                 outb_p(fdc_ctl, fdc.dor);
595         }
596 }
597
598 /*      Reset the floppy disk controller. Leave the ftape_unit selected.
599  */
600 void fdc_reset(void)
601 {
602         int st0;
603         int i;
604         int dummy;
605         unsigned long flags;
606         TRACE_FUN(ft_t_any);
607
608         spin_lock_irqsave(&fdc_io_lock, flags);
609
610         fdc_dor_reset(1); /* keep unit selected */
611
612         fdc_mode = fdc_idle;
613
614         /*  maybe the cli()/sti() pair is not necessary, BUT:
615          *  the following line MUST be here. Otherwise fdc_interrupt_wait()
616          *  won't wait. Note that fdc_reset() is called from 
617          *  ftape_dumb_stop() when the fdc is busy transferring data. In this
618          *  case fdc_isr() MOST PROBABLY sets ft_interrupt_seen, and tries
619          *  to get the result bytes from the fdc etc. CLASH.
620          */
621         ft_interrupt_seen = 0;
622         
623         /*  Program data rate
624          */
625         fdc_update_dsr();               /* restore data rate and precomp */
626
627         spin_unlock_irqrestore(&fdc_io_lock, flags);
628
629         /*
630          *      Wait for first polling cycle to complete
631          */
632         if (fdc_interrupt_wait(1 * FT_SECOND) < 0) {
633                 TRACE(ft_t_err, "no drive polling interrupt!");
634         } else {        /* clear all disk-changed statuses */
635                 for (i = 0; i < 4; ++i) {
636                         if(fdc_sense_interrupt_status(&st0, &dummy) != 0) {
637                                 TRACE(ft_t_err, "sense failed for %d", i);
638                         }
639                         if (i == ft_drive_sel) {
640                                 ftape_current_cylinder = dummy;
641                         }
642                 }
643                 TRACE(ft_t_noise, "drive polling completed");
644         }
645         /*
646          *      SPECIFY COMMAND
647          */
648         fdc_set_seek_rate(fdc_seek_rate);
649         /*
650          *      DRIVE SPECIFICATION COMMAND (if fdc type known)
651          */
652         if (fdc.type >= i82078_1) {
653                 fdc_set_drive_specs();
654         }
655         TRACE_EXIT;
656 }
657
658 #if !defined(CLK_48MHZ)
659 # define CLK_48MHZ 1
660 #endif
661
662 /*  When we're done, put the fdc into reset mode so that the regular
663  *  floppy disk driver will figure out that something is wrong and
664  *  initialize the controller the way it wants.
665  */
666 void fdc_disable(void)
667 {
668         __u8 cmd1[] = {FDC_CONFIGURE, 0x00, 0x00, 0x00};
669         __u8 cmd2[] = {FDC_LOCK};
670         __u8 cmd3[] = {FDC_UNLOCK};
671         __u8 stat[1];
672         TRACE_FUN(ft_t_flow);
673
674         if (!fdc_fifo_locked) {
675                 fdc_reset();
676                 TRACE_EXIT;
677         }
678         if (fdc_issue_command(cmd3, 1, stat, 1) < 0 || stat[0] != 0x00) {
679                 fdc_dor_reset(0);
680                 TRACE_ABORT(/**/, ft_t_bug, 
681                 "couldn't unlock fifo, configuration remains changed");
682         }
683         fdc_fifo_locked = 0;
684         if (CLK_48MHZ && fdc.type >= i82078) {
685                 cmd1[0] |= FDC_CLK48_BIT;
686         }
687         cmd1[2] = ((fdc_fifo_state) ? 0 : 0x20) + (fdc_fifo_thr - 1);
688         if (fdc_command(cmd1, NR_ITEMS(cmd1)) < 0) {
689                 fdc_dor_reset(0);
690                 TRACE_ABORT(/**/, ft_t_bug,
691                 "couldn't reconfigure fifo to old state");
692         }
693         if (fdc_lock_state &&
694             fdc_issue_command(cmd2, 1, stat, 1) < 0) {
695                 fdc_dor_reset(0);
696                 TRACE_ABORT(/**/, ft_t_bug, "couldn't lock old state again");
697         }
698         TRACE(ft_t_noise, "fifo restored: %sabled, thr. %d, %slocked",
699               fdc_fifo_state ? "en" : "dis",
700               fdc_fifo_thr, (fdc_lock_state) ? "" : "not ");
701         fdc_dor_reset(0);
702         TRACE_EXIT;
703 }
704
705 /*      Specify FDC seek-rate (milliseconds)
706  */
707 int fdc_set_seek_rate(int seek_rate)
708 {
709         /* set step rate, dma mode, and minimal head load and unload times
710          */
711         __u8 in[3] = { FDC_SPECIFY, 1, (1 << 1)};
712  
713         fdc_seek_rate = seek_rate;
714         in[1] |= (16 - (fdc_data_rate * fdc_seek_rate) / 500) << 4;
715
716         return fdc_command(in, 3);
717 }
718
719 /*      Sense drive status: get unit's drive status (ST3)
720  */
721 int fdc_sense_drive_status(int *st3)
722 {
723         __u8 out[2];
724         __u8 in[1];
725         TRACE_FUN(ft_t_any);
726
727         out[0] = FDC_SENSED;
728         out[1] = ft_drive_sel;
729         TRACE_CATCH(fdc_issue_command(out, 2, in, 1),);
730         *st3 = in[0];
731         TRACE_EXIT 0;
732 }
733
734 /*      Sense Interrupt Status command:
735  *      should be issued at the end of each seek.
736  *      get ST0 and current cylinder.
737  */
738 int fdc_sense_interrupt_status(int *st0, int *current_cylinder)
739 {
740         __u8 out[1];
741         __u8 in[2];
742         TRACE_FUN(ft_t_any);
743
744         out[0] = FDC_SENSEI;
745         TRACE_CATCH(fdc_issue_command(out, 1, in, 2),);
746         *st0 = in[0];
747         *current_cylinder = in[1];
748         TRACE_EXIT 0;
749 }
750
751 /*      step to track
752  */
753 int fdc_seek(int track)
754 {
755         __u8 out[3];
756         int st0, pcn;
757 #ifdef TESTING
758         unsigned int time;
759 #endif
760         TRACE_FUN(ft_t_any);
761
762         out[0] = FDC_SEEK;
763         out[1] = ft_drive_sel;
764         out[2] = track;
765 #ifdef TESTING
766         time = ftape_timestamp();
767 #endif
768         /*  We really need this command to work !
769          */
770         ft_seek_completed = 0;
771         TRACE_CATCH(fdc_command(out, 3),
772                     fdc_reset();
773                     TRACE(ft_t_noise, "destination was: %d, resetting FDC...",
774                           track));
775         /*    Handle interrupts until ft_seek_completed or timeout.
776          */
777         for (;;) {
778                 TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
779                 if (ft_seek_completed) {
780                         TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
781                         if ((st0 & ST0_SEEK_END) == 0) {
782                                 TRACE_ABORT(-EIO, ft_t_err,
783                                       "no seek-end after seek completion !??");
784                         }
785                         break;
786                 }
787         }
788 #ifdef TESTING
789         time = ftape_timediff(time, ftape_timestamp()) / ABS(track - ftape_current_cylinder);
790         if ((time < 900 || time > 3100) && ABS(track - ftape_current_cylinder) > 5) {
791                 TRACE(ft_t_warn, "Wrong FDC STEP interval: %d usecs (%d)",
792                          time, track - ftape_current_cylinder);
793         }
794 #endif
795         /*    Verify whether we issued the right tape command.
796          */
797         /* Verify that we seek to the proper track. */
798         if (pcn != track) {
799                 TRACE_ABORT(-EIO, ft_t_err, "bad seek..");
800         }
801         ftape_current_cylinder = track;
802         TRACE_EXIT 0;
803 }
804
805 /*      Recalibrate and wait until home.
806  */
807 int fdc_recalibrate(void)
808 {
809         __u8 out[2];
810         int st0;
811         int pcn;
812         int retry;
813         int old_seek_rate = fdc_seek_rate;
814         TRACE_FUN(ft_t_any);
815
816         TRACE_CATCH(fdc_set_seek_rate(6),);
817         out[0] = FDC_RECAL;
818         out[1] = ft_drive_sel;
819         ft_seek_completed = 0;
820         TRACE_CATCH(fdc_command(out, 2),);
821         /*    Handle interrupts until ft_seek_completed or timeout.
822          */
823         for (retry = 0;; ++retry) {
824                 TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
825                 if (ft_seek_completed) {
826                         TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
827                         if ((st0 & ST0_SEEK_END) == 0) {
828                                 if (retry < 1) {
829                                         continue; /* some drives/fdc's
830                                                    * give an extra interrupt
831                                                    */
832                                 } else {
833                                         TRACE_ABORT(-EIO, ft_t_err,
834                                     "no seek-end after seek completion !??");
835                                 }
836                         }
837                         break;
838                 }
839         }
840         ftape_current_cylinder = pcn;
841         if (pcn != 0) {
842                 TRACE(ft_t_err, "failed: resulting track = %d", pcn);
843         }
844         TRACE_CATCH(fdc_set_seek_rate(old_seek_rate),);
845         TRACE_EXIT 0;
846 }
847
848 static int perpend_mode; /* set if fdc is in perpendicular mode */
849
850 static int perpend_off(void)
851 {
852         __u8 perpend[] = {FDC_PERPEND, 0x00};
853         TRACE_FUN(ft_t_any);
854         
855         if (perpend_mode) {
856                 /* Turn off perpendicular mode */
857                 perpend[1] = 0x80;
858                 TRACE_CATCH(fdc_command(perpend, 2),
859                             TRACE(ft_t_err,"Perpendicular mode exit failed!"));
860                 perpend_mode = 0;
861         }
862         TRACE_EXIT 0;
863 }
864
865 static int handle_perpend(int segment_id)
866 {
867         __u8 perpend[] = {FDC_PERPEND, 0x00};
868         TRACE_FUN(ft_t_any);
869
870         /* When writing QIC-3020 tapes, turn on perpendicular mode
871          * if tape is moving in forward direction (even tracks).
872          */
873         if (ft_qic_std == QIC_TAPE_QIC3020 &&
874             ((segment_id / ft_segments_per_track) & 1) == 0) {
875 /*  FIXME: some i82077 seem to support perpendicular mode as
876  *  well. 
877  */
878 #if 0
879                 if (fdc.type < i82077AA) {}
880 #else
881                 if (fdc.type < i82077 && ft_data_rate < 1000) {
882 #endif
883                         /*  fdc does not support perpendicular mode: complain 
884                          */
885                         TRACE_ABORT(-EIO, ft_t_err,
886                                     "Your FDC does not support QIC-3020.");
887                 }
888                 perpend[1] = 0x03 /* 0x83 + (0x4 << ft_drive_sel) */ ;
889                 TRACE_CATCH(fdc_command(perpend, 2),
890                            TRACE(ft_t_err,"Perpendicular mode entry failed!"));
891                 TRACE(ft_t_flow, "Perpendicular mode set");
892                 perpend_mode = 1;
893                 TRACE_EXIT 0;
894         }
895         TRACE_EXIT perpend_off();
896 }
897
898 static inline void fdc_setup_dma(char mode,
899                                  volatile void *addr, unsigned int count)
900 {
901         /* Program the DMA controller.
902          */
903         disable_dma(fdc.dma);
904         clear_dma_ff(fdc.dma);
905         set_dma_mode(fdc.dma, mode);
906         set_dma_addr(fdc.dma, virt_to_bus((void*)addr));
907         set_dma_count(fdc.dma, count);
908         enable_dma(fdc.dma);
909 }
910
911 /*  Setup fdc and dma for formatting the next segment
912  */
913 int fdc_setup_formatting(buffer_struct * buff)
914 {
915         unsigned long flags;
916         __u8 out[6] = {
917                 FDC_FORMAT, 0x00, 3, 4 * FT_SECTORS_PER_SEGMENT, 0x00, 0x6b
918         };
919         TRACE_FUN(ft_t_any);
920         
921         TRACE_CATCH(handle_perpend(buff->segment_id),);
922         /* Program the DMA controller.
923          */
924         TRACE(ft_t_fdc_dma,
925               "phys. addr. = %lx", virt_to_bus((void*) buff->ptr));
926         spin_lock_irqsave(&fdc_io_lock, flags);
927         fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4);
928         /* Issue FDC command to start reading/writing.
929          */
930         out[1] = ft_drive_sel;
931         out[4] = buff->gap3;
932         TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)),
933                     restore_flags(flags); fdc_mode = fdc_idle);
934         spin_unlock_irqrestore(&fdc_io_lock, flags);
935         TRACE_EXIT 0;
936 }
937
938
939 /*      Setup Floppy Disk Controller and DMA to read or write the next cluster
940  *      of good sectors from or to the current segment.
941  */
942 int fdc_setup_read_write(buffer_struct * buff, __u8 operation)
943 {
944         unsigned long flags;
945         __u8 out[9];
946         int dma_mode;
947         TRACE_FUN(ft_t_any);
948
949         switch(operation) {
950         case FDC_VERIFY:
951                 if (fdc.type < i82077) {
952                         operation = FDC_READ;
953                 }
954         case FDC_READ:
955         case FDC_READ_DELETED:
956                 dma_mode = DMA_MODE_READ;
957                 TRACE(ft_t_fdc_dma, "xfer %d sectors to 0x%p",
958                       buff->sector_count, buff->ptr);
959                 TRACE_CATCH(perpend_off(),);
960                 break;
961         case FDC_WRITE_DELETED:
962                 TRACE(ft_t_noise, "deleting segment %d", buff->segment_id);
963         case FDC_WRITE:
964                 dma_mode = DMA_MODE_WRITE;
965                 /* When writing QIC-3020 tapes, turn on perpendicular mode
966                  * if tape is moving in forward direction (even tracks).
967                  */
968                 TRACE_CATCH(handle_perpend(buff->segment_id),);
969                 TRACE(ft_t_fdc_dma, "xfer %d sectors from 0x%p",
970                       buff->sector_count, buff->ptr);
971                 break;
972         default:
973                 TRACE_ABORT(-EIO,
974                             ft_t_bug, "bug: invalid operation parameter");
975         }
976         TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr));
977         spin_lock_irqsave(&fdc_io_lock, flags);
978         if (operation != FDC_VERIFY) {
979                 fdc_setup_dma(dma_mode, buff->ptr,
980                               FT_SECTOR_SIZE * buff->sector_count);
981         }
982         /* Issue FDC command to start reading/writing.
983          */
984         out[0] = operation;
985         out[1] = ft_drive_sel;
986         out[2] = buff->cyl;
987         out[3] = buff->head;
988         out[4] = buff->sect + buff->sector_offset;
989         out[5] = 3;             /* Sector size of 1K. */
990         out[6] = out[4] + buff->sector_count - 1;       /* last sector */
991         out[7] = 109;           /* Gap length. */
992         out[8] = 0xff;          /* No limit to transfer size. */
993         TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x",
994                 out[2], out[3], out[4], out[6] - out[4] + 1);
995         spin_unlock_irqrestore(&fdc_io_lock, flags);
996         TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle);
997         TRACE_EXIT 0;
998 }
999
1000 int fdc_fifo_threshold(__u8 threshold,
1001                        int *fifo_state, int *lock_state, int *fifo_thr)
1002 {
1003         const __u8 cmd0[] = {FDC_DUMPREGS};
1004         __u8 cmd1[] = {FDC_CONFIGURE, 0, (0x0f & (threshold - 1)), 0};
1005         const __u8 cmd2[] = {FDC_LOCK};
1006         const __u8 cmd3[] = {FDC_UNLOCK};
1007         __u8 reg[10];
1008         __u8 stat;
1009         int i;
1010         int result;
1011         TRACE_FUN(ft_t_any);
1012
1013         if (CLK_48MHZ && fdc.type >= i82078) {
1014                 cmd1[0] |= FDC_CLK48_BIT;
1015         }
1016         /*  Dump fdc internal registers for examination
1017          */
1018         TRACE_CATCH(fdc_command(cmd0, NR_ITEMS(cmd0)),
1019                     TRACE(ft_t_warn, "dumpreg cmd failed, fifo unchanged"));
1020         /*  Now read fdc internal registers from fifo
1021          */
1022         for (i = 0; i < (int)NR_ITEMS(reg); ++i) {
1023                 fdc_read(&reg[i]);
1024                 TRACE(ft_t_fdc_dma, "Register %d = 0x%02x", i, reg[i]);
1025         }
1026         if (fifo_state && lock_state && fifo_thr) {
1027                 *fifo_state = (reg[8] & 0x20) == 0;
1028                 *lock_state = reg[7] & 0x80;
1029                 *fifo_thr = 1 + (reg[8] & 0x0f);
1030         }
1031         TRACE(ft_t_noise,
1032               "original fifo state: %sabled, threshold %d, %slocked",
1033               ((reg[8] & 0x20) == 0) ? "en" : "dis",
1034               1 + (reg[8] & 0x0f), (reg[7] & 0x80) ? "" : "not ");
1035         /*  If fdc is already locked, unlock it first ! */
1036         if (reg[7] & 0x80) {
1037                 fdc_ready_wait(100);
1038                 TRACE_CATCH(fdc_issue_command(cmd3, NR_ITEMS(cmd3), &stat, 1),
1039                             TRACE(ft_t_bug, "FDC unlock command failed, "
1040                                   "configuration unchanged"));
1041         }
1042         fdc_fifo_locked = 0;
1043         /*  Enable fifo and set threshold at xx bytes to allow a
1044          *  reasonably large latency and reduce number of dma bursts.
1045          */
1046         fdc_ready_wait(100);
1047         if ((result = fdc_command(cmd1, NR_ITEMS(cmd1))) < 0) {
1048                 TRACE(ft_t_bug, "configure cmd failed, fifo unchanged");
1049         }
1050         /*  Now lock configuration so reset will not change it
1051          */
1052         if(fdc_issue_command(cmd2, NR_ITEMS(cmd2), &stat, 1) < 0 ||
1053            stat != 0x10) {
1054                 TRACE_ABORT(-EIO, ft_t_bug,
1055                             "FDC lock command failed, stat = 0x%02x", stat);
1056         }
1057         fdc_fifo_locked = 1;
1058         TRACE_EXIT result;
1059 }
1060
1061 static int fdc_fifo_enable(void)
1062 {
1063         TRACE_FUN(ft_t_any);
1064
1065         if (fdc_fifo_locked) {
1066                 TRACE_ABORT(0, ft_t_warn, "Fifo not enabled because locked");
1067         }
1068         TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
1069                                        &fdc_fifo_state,
1070                                        &fdc_lock_state,
1071                                        &fdc_fifo_thr),);
1072         TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
1073                                        NULL, NULL, NULL),);
1074         TRACE_EXIT 0;
1075 }
1076
1077 /*   Determine fd controller type 
1078  */
1079 static __u8 fdc_save_state[2];
1080
1081 int fdc_probe(void)
1082 {
1083         __u8 cmd[1];
1084         __u8 stat[16]; /* must be able to hold dumpregs & save results */
1085         int i;
1086         TRACE_FUN(ft_t_any);
1087
1088         /*  Try to find out what kind of fd controller we have to deal with
1089          *  Scheme borrowed from floppy driver:
1090          *  first try if FDC_DUMPREGS command works
1091          *  (this indicates that we have a 82072 or better)
1092          *  then try the FDC_VERSION command (82072 doesn't support this)
1093          *  then try the FDC_UNLOCK command (some older 82077's don't support this)
1094          *  then try the FDC_PARTID command (82078's support this)
1095          */
1096         cmd[0] = FDC_DUMPREGS;
1097         if (fdc_issue_command(cmd, 1, stat, 1) != 0) {
1098                 TRACE_ABORT(no_fdc, ft_t_bug, "No FDC found");
1099         }
1100         if (stat[0] == 0x80) {
1101                 /* invalid command: must be pre 82072 */
1102                 TRACE_ABORT(i8272,
1103                             ft_t_warn, "Type 8272A/765A compatible FDC found");
1104         }
1105         fdc_result(&stat[1], 9);
1106         fdc_save_state[0] = stat[7];
1107         fdc_save_state[1] = stat[8];
1108         cmd[0] = FDC_VERSION;
1109         if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
1110                 TRACE_ABORT(i8272, ft_t_warn, "Type 82072 FDC found");
1111         }
1112         if (*stat != 0x90) {
1113                 TRACE_ABORT(i8272, ft_t_warn, "Unknown FDC found");
1114         }
1115         cmd[0] = FDC_UNLOCK;
1116         if(fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] != 0x00) {
1117                 TRACE_ABORT(i8272, ft_t_warn,
1118                             "Type pre-1991 82077 FDC found, "
1119                             "treating it like a 82072");
1120         }
1121         if (fdc_save_state[0] & 0x80) { /* was locked */
1122                 cmd[0] = FDC_LOCK; /* restore lock */
1123                 (void)fdc_issue_command(cmd, 1, stat, 1);
1124                 TRACE(ft_t_warn, "FDC is already locked");
1125         }
1126         /* Test for a i82078 FDC */
1127         cmd[0] = FDC_PARTID;
1128         if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
1129                 /* invalid command: not a i82078xx type FDC */
1130                 for (i = 0; i < 4; ++i) {
1131                         outb_p(i, fdc.tdr);
1132                         if ((inb_p(fdc.tdr) & 0x03) != i) {
1133                                 TRACE_ABORT(i82077,
1134                                             ft_t_warn, "Type 82077 FDC found");
1135                         }
1136                 }
1137                 TRACE_ABORT(i82077AA, ft_t_warn, "Type 82077AA FDC found");
1138         }
1139         /* FDC_PARTID cmd succeeded */
1140         switch (stat[0] >> 5) {
1141         case 0x0:
1142                 /* i82078SL or i82078-1.  The SL part cannot run at
1143                  * 2Mbps (the SL and -1 dies are identical; they are
1144                  * speed graded after production, according to Intel).
1145                  * Some SL's can be detected by doing a SAVE cmd and
1146                  * look at bit 7 of the first byte (the SEL3V# bit).
1147                  * If it is 0, the part runs off 3Volts, and hence it
1148                  * is a SL.
1149                  */
1150                 cmd[0] = FDC_SAVE;
1151                 if(fdc_issue_command(cmd, 1, stat, 16) < 0) {
1152                         TRACE(ft_t_err, "FDC_SAVE failed. Dunno why");
1153                         /* guess we better claim the fdc to be a i82078 */
1154                         TRACE_ABORT(i82078,
1155                                     ft_t_warn,
1156                                     "Type i82078 FDC (i suppose) found");
1157                 }
1158                 if ((stat[0] & FDC_SEL3V_BIT)) {
1159                         /* fdc running off 5Volts; Pray that it's a i82078-1
1160                          */
1161                         TRACE_ABORT(i82078_1, ft_t_warn,
1162                                   "Type i82078-1 or 5Volt i82078SL FDC found");
1163                 }
1164                 TRACE_ABORT(i82078, ft_t_warn,
1165                             "Type 3Volt i82078SL FDC (1Mbps) found");
1166         case 0x1:
1167         case 0x2: /* S82078B  */
1168                 /* The '78B  isn't '78 compatible.  Detect it as a '77AA */
1169                 TRACE_ABORT(i82077AA, ft_t_warn, "Type i82077AA FDC found");
1170         case 0x3: /* NSC PC8744 core; used in several super-IO chips */
1171                 TRACE_ABORT(i82077AA,
1172                             ft_t_warn, "Type 82077AA compatible FDC found");
1173         default:
1174                 TRACE(ft_t_warn, "A previously undetected FDC found");
1175                 TRACE_ABORT(i82077AA, ft_t_warn,
1176                           "Treating it as a 82077AA. Please report partid= %d",
1177                             stat[0]);
1178         } /* switch(stat[ 0] >> 5) */
1179         TRACE_EXIT no_fdc;
1180 }
1181
1182 static int fdc_request_regions(void)
1183 {
1184         TRACE_FUN(ft_t_flow);
1185
1186         if (ft_mach2 || ft_probe_fc10) {
1187                 if (!request_region(fdc.sra, 8, "fdc (ft)")) {
1188 #ifndef BROKEN_FLOPPY_DRIVER
1189                         TRACE_EXIT -EBUSY;
1190 #else
1191                         TRACE(ft_t_warn,
1192 "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
1193 #endif
1194                 }
1195         } else {
1196                 if (!request_region(fdc.sra, 6, "fdc (ft)")) {
1197 #ifndef BROKEN_FLOPPY_DRIVER
1198                         TRACE_EXIT -EBUSY;
1199 #else
1200                         TRACE(ft_t_warn,
1201 "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
1202 #endif
1203                 }
1204                 if (!request_region(fdc.sra + 7, 1, "fdc (ft)")) {
1205 #ifndef BROKEN_FLOPPY_DRIVER
1206                         release_region(fdc.sra, 6);
1207                         TRACE_EXIT -EBUSY;
1208 #else
1209                         TRACE(ft_t_warn,
1210 "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra + 7);
1211 #endif
1212                 }
1213         }
1214         TRACE_EXIT 0;
1215 }
1216
1217 void fdc_release_regions(void)
1218 {
1219         TRACE_FUN(ft_t_flow);
1220
1221         if (fdc.sra != 0) {
1222                 if (fdc.dor2 != 0) {
1223                         release_region(fdc.sra, 8);
1224                 } else {
1225                         release_region(fdc.sra, 6);
1226                         release_region(fdc.dir, 1);
1227                 }
1228         }
1229         TRACE_EXIT;
1230 }
1231
1232 static int fdc_config_regs(unsigned int fdc_base, 
1233                            unsigned int fdc_irq, 
1234                            unsigned int fdc_dma)
1235 {
1236         TRACE_FUN(ft_t_flow);
1237
1238         fdc.irq = fdc_irq;
1239         fdc.dma = fdc_dma;
1240         fdc.sra = fdc_base;
1241         fdc.srb = fdc_base + 1;
1242         fdc.dor = fdc_base + 2;
1243         fdc.tdr = fdc_base + 3;
1244         fdc.msr = fdc.dsr = fdc_base + 4;
1245         fdc.fifo = fdc_base + 5;
1246         fdc.dir = fdc.ccr = fdc_base + 7;
1247         fdc.dor2 = (ft_mach2 || ft_probe_fc10) ? fdc_base + 6 : 0;
1248         TRACE_CATCH(fdc_request_regions(), fdc.sra = 0);
1249         TRACE_EXIT 0;
1250 }
1251
1252 static int fdc_config(void)
1253 {
1254         static int already_done;
1255         TRACE_FUN(ft_t_any);
1256
1257         if (already_done) {
1258                 TRACE_CATCH(fdc_request_regions(),);
1259                 *(fdc.hook) = fdc_isr;  /* hook our handler in */
1260                 TRACE_EXIT 0;
1261         }
1262         if (ft_probe_fc10) {
1263                 int fc_type;
1264                 
1265                 TRACE_CATCH(fdc_config_regs(ft_fdc_base,
1266                                             ft_fdc_irq, ft_fdc_dma),);
1267                 fc_type = fc10_enable();
1268                 if (fc_type != 0) {
1269                         TRACE(ft_t_warn, "FC-%c0 controller found", '0' + fc_type);
1270                         fdc.type = fc10;
1271                         fdc.hook = &do_ftape;
1272                         *(fdc.hook) = fdc_isr;  /* hook our handler in */
1273                         already_done = 1;
1274                         TRACE_EXIT 0;
1275                 } else {
1276                         TRACE(ft_t_warn, "FC-10/20 controller not found");
1277                         fdc_release_regions();
1278                         fdc.type = no_fdc;
1279                         ft_probe_fc10 = 0;
1280                         ft_fdc_base   = 0x3f0;
1281                         ft_fdc_irq    = 6;
1282                         ft_fdc_dma    = 2;
1283                 }
1284         }
1285         TRACE(ft_t_warn, "fdc base: 0x%x, irq: %d, dma: %d", 
1286               ft_fdc_base, ft_fdc_irq, ft_fdc_dma);
1287         TRACE_CATCH(fdc_config_regs(ft_fdc_base, ft_fdc_irq, ft_fdc_dma),);
1288         fdc.hook = &do_ftape;
1289         *(fdc.hook) = fdc_isr;  /* hook our handler in */
1290         already_done = 1;
1291         TRACE_EXIT 0;
1292 }
1293
1294 static irqreturn_t ftape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1295 {
1296         void (*handler) (void) = *fdc.hook;
1297         int handled = 0;
1298         TRACE_FUN(ft_t_any);
1299
1300         *fdc.hook = NULL;
1301         if (handler) {
1302                 handled = 1;
1303                 handler();
1304         } else {
1305                 TRACE(ft_t_bug, "Unexpected ftape interrupt");
1306         }
1307         TRACE_EXIT IRQ_RETVAL(handled);
1308 }
1309
1310 int fdc_grab_irq_and_dma(void)
1311 {
1312         TRACE_FUN(ft_t_any);
1313
1314         if (fdc.hook == &do_ftape) {
1315                 /*  Get fast interrupt handler.
1316                  */
1317                 if (request_irq(fdc.irq, ftape_interrupt,
1318                                 SA_INTERRUPT, "ft", ftape_id)) {
1319                         TRACE_ABORT(-EIO, ft_t_bug,
1320                                     "Unable to grab IRQ%d for ftape driver",
1321                                     fdc.irq);
1322                 }
1323                 if (request_dma(fdc.dma, ftape_id)) {
1324                         free_irq(fdc.irq, ftape_id);
1325                         TRACE_ABORT(-EIO, ft_t_bug,
1326                               "Unable to grab DMA%d for ftape driver",
1327                               fdc.dma);
1328                 }
1329         }
1330         if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
1331                 /* Using same dma channel or irq as standard fdc, need
1332                  * to disable the dma-gate on the std fdc. This
1333                  * couldn't be done in the floppy driver as some
1334                  * laptops are using the dma-gate to enter a low power
1335                  * or even suspended state :-(
1336                  */
1337                 outb_p(FDC_RESET_NOT, 0x3f2);
1338                 TRACE(ft_t_noise, "DMA-gate on standard fdc disabled");
1339         }
1340         TRACE_EXIT 0;
1341 }
1342
1343 int fdc_release_irq_and_dma(void)
1344 {
1345         TRACE_FUN(ft_t_any);
1346
1347         if (fdc.hook == &do_ftape) {
1348                 disable_dma(fdc.dma);   /* just in case... */
1349                 free_dma(fdc.dma);
1350                 free_irq(fdc.irq, ftape_id);
1351         }
1352         if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
1353                 /* Using same dma channel as standard fdc, need to
1354                  * disable the dma-gate on the std fdc. This couldn't
1355                  * be done in the floppy driver as some laptops are
1356                  * using the dma-gate to enter a low power or even
1357                  * suspended state :-(
1358                  */
1359                 outb_p(FDC_RESET_NOT | FDC_DMA_MODE, 0x3f2);
1360                 TRACE(ft_t_noise, "DMA-gate on standard fdc enabled again");
1361         }
1362         TRACE_EXIT 0;
1363 }
1364
1365 int fdc_init(void)
1366 {
1367         TRACE_FUN(ft_t_any);
1368
1369         /* find a FDC to use */
1370         TRACE_CATCH(fdc_config(),);
1371         TRACE_CATCH(fdc_grab_irq_and_dma(), fdc_release_regions());
1372         ftape_motor = 0;
1373         fdc_catch_stray_interrupts(0);  /* clear number of awainted
1374                                          * stray interrupte 
1375                                          */
1376         fdc_catch_stray_interrupts(1);  /* one always comes (?) */
1377         TRACE(ft_t_flow, "resetting fdc");
1378         fdc_set_seek_rate(2);           /* use nominal QIC step rate */
1379         fdc_reset();                    /* init fdc & clear track counters */
1380         if (fdc.type == no_fdc) {       /* no FC-10 or FC-20 found */
1381                 fdc.type = fdc_probe();
1382                 fdc_reset();            /* update with new knowledge */
1383         }
1384         if (fdc.type == no_fdc) {
1385                 fdc_release_irq_and_dma();
1386                 fdc_release_regions();
1387                 TRACE_EXIT -ENXIO;
1388         }
1389         if (fdc.type >= i82077) {
1390                 if (fdc_fifo_enable() < 0) {
1391                         TRACE(ft_t_warn, "couldn't enable fdc fifo !");
1392                 } else {
1393                         TRACE(ft_t_flow, "fdc fifo enabled and locked");
1394                 }
1395         }
1396         TRACE_EXIT 0;
1397 }