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