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