/*
 * Copyright (C) 1993-1996 Bas Laarhoven,
 *           (C) 1996-1997 Claus-Justus Heine.

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

 *
 * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.c,v $
 * $Revision: 1.7.4.2 $
 * $Date: 1997/11/16 14:48:17 $
 *
 *      This file contains the low-level floppy disk interface code
 *      for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
 *      Linux.
 */

#include <linux/config.h> /* for CONFIG_FT_* */
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/irq.h>

#include <linux/ftape.h>
#include <linux/qic117.h>
#include "../lowlevel/ftape-tracing.h"
#include "../lowlevel/fdc-io.h"
#include "../lowlevel/fdc-isr.h"
#include "../lowlevel/ftape-io.h"
#include "../lowlevel/ftape-rw.h"
#include "../lowlevel/ftape-ctl.h"
#include "../lowlevel/ftape-calibr.h"
#include "../lowlevel/fc-10.h"

/*      Global vars.
 */
static int ftape_motor;
volatile int ftape_current_cylinder = -1;
volatile fdc_mode_enum fdc_mode = fdc_idle;
fdc_config_info fdc;
DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr);

unsigned int ft_fdc_base       = CONFIG_FT_FDC_BASE;
unsigned int ft_fdc_irq        = CONFIG_FT_FDC_IRQ;
unsigned int ft_fdc_dma        = CONFIG_FT_FDC_DMA;
unsigned int ft_fdc_threshold  = CONFIG_FT_FDC_THR;  /* bytes */
unsigned int ft_fdc_rate_limit = CONFIG_FT_FDC_MAX_RATE; /* bits/sec */
int ft_probe_fc10        = CONFIG_FT_PROBE_FC10;
int ft_mach2             = CONFIG_FT_MACH2;

/*      Local vars.
 */
static spinlock_t fdc_io_lock; 
static unsigned int fdc_calibr_count;
static unsigned int fdc_calibr_time;
static int fdc_status;
volatile __u8 fdc_head;		/* FDC head from sector id */
volatile __u8 fdc_cyl;		/* FDC track from sector id */
volatile __u8 fdc_sect;		/* FDC sector from sector id */
static int fdc_data_rate = 500;	/* data rate (Kbps) */
static int fdc_rate_code;	/* data rate code (0 == 500 Kbps) */
static int fdc_seek_rate = 2;	/* step rate (msec) */
static void (*do_ftape) (void);
static int fdc_fifo_state;	/* original fifo setting - fifo enabled */
static int fdc_fifo_thr;	/* original fifo setting - threshold */
static int fdc_lock_state;	/* original lock setting - locked */
static int fdc_fifo_locked;	/* has fifo && lock set ? */
static __u8 fdc_precomp;	/* default precomp. value (nsec) */
static __u8 fdc_prec_code;	/* fdc precomp. select code */

static char ftape_id[] = "ftape";  /* used by request irq and free irq */

static int fdc_set_seek_rate(int seek_rate);

void fdc_catch_stray_interrupts(int count)
{
	unsigned long flags;

	spin_lock_irqsave(&fdc_io_lock, flags);
	if (count == 0) {
		ft_expected_stray_interrupts = 0;
	} else {
		ft_expected_stray_interrupts += count;
	}
	spin_unlock_irqrestore(&fdc_io_lock, flags);
}

/*  Wait during a timeout period for a given FDC status.
 *  If usecs == 0 then just test status, else wait at least for usecs.
 *  Returns -ETIME on timeout. Function must be calibrated first !
 */
static int fdc_wait(unsigned int usecs, __u8 mask, __u8 state)
{
	int count_1 = (fdc_calibr_count * usecs +
                       fdc_calibr_count - 1) / fdc_calibr_time;

	do {
		fdc_status = inb_p(fdc.msr);
		if ((fdc_status & mask) == state) {
			return 0;
		}
	} while (count_1-- >= 0);
	return -ETIME;
}

int fdc_ready_wait(unsigned int usecs)
{
	return fdc_wait(usecs, FDC_DATA_READY | FDC_BUSY, FDC_DATA_READY);
}

/* Why can't we just use udelay()?
 */
static void fdc_usec_wait(unsigned int usecs)
{
	fdc_wait(usecs, 0, 1);	/* will always timeout ! */
}

static int fdc_ready_out_wait(unsigned int usecs)
{
	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
	return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_OUT_READY);
}

void fdc_wait_calibrate(void)
{
	ftape_calibrate("fdc_wait",
			fdc_usec_wait, &fdc_calibr_count, &fdc_calibr_time); 
}

/*  Wait for a (short) while for the FDC to become ready
 *  and transfer the next command byte.
 *  Return -ETIME on timeout on getting ready (depends on hardware!).
 */
static int fdc_write(const __u8 data)
{
	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
	if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_IN_READY) < 0) {
		return -ETIME;
	} else {
		outb(data, fdc.fifo);
		return 0;
	}
}

/*  Wait for a (short) while for the FDC to become ready
 *  and transfer the next result byte.
 *  Return -ETIME if timeout on getting ready (depends on hardware!).
 */
static int fdc_read(__u8 * data)
{
	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
	if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_OUT_READY) < 0) {
		return -ETIME;
	} else {
		*data = inb(fdc.fifo);
		return 0;
	}
}

/*  Output a cmd_len long command string to the FDC.
 *  The FDC should be ready to receive a new command or
 *  an error (EBUSY or ETIME) will occur.
 */
int fdc_command(const __u8 * cmd_data, int cmd_len)
{
	int result = 0;
	unsigned long flags;
	int count = cmd_len;
	int retry = 0;
#ifdef TESTING
	static unsigned int last_time;
	unsigned int time;
#endif
	TRACE_FUN(ft_t_any);

	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
	spin_lock_irqsave(&fdc_io_lock, flags);
	if (!in_interrupt())
		/* Yes, I know, too much comments inside this function
		 * ...
		 * 
		 * Yet another bug in the original driver. All that
		 * havoc is caused by the fact that the isr() sends
		 * itself a command to the floppy tape driver (pause,
		 * micro step pause).  Now, the problem is that
		 * commands are transmitted via the fdc_seek
		 * command. But: the fdc performs seeks in the
		 * background i.e. it doesn't signal busy while
		 * sending the step pulses to the drive. Therefore the
		 * non-interrupt level driver has no chance to tell
		 * whether the isr() just has issued a seek. Therefore
		 * we HAVE TO have a look at the ft_hide_interrupt
		 * flag: it signals the non-interrupt level part of
		 * the driver that it has to wait for the fdc until it
		 * has completet seeking.
		 *
		 * THIS WAS PRESUMABLY THE REASON FOR ALL THAT
		 * "fdc_read timeout" errors, I HOPE :-)
		 */
		if (ft_hide_interrupt) {
			restore_flags(flags);
			TRACE(ft_t_info,
			      "Waiting for the isr() completing fdc_seek()");
			if (fdc_interrupt_wait(2 * FT_SECOND) < 0) {
				TRACE(ft_t_warn,
		      "Warning: timeout waiting for isr() seek to complete");
			}
			if (ft_hide_interrupt || !ft_seek_completed) {
				/* There cannot be another
				 * interrupt. The isr() only stops
				 * the tape and the next interrupt
				 * won't come until we have send our
				 * command to the drive.
				 */
				TRACE_ABORT(-EIO, ft_t_bug,
					    "BUG? isr() is still seeking?\n"
					    KERN_INFO "hide: %d\n"
					    KERN_INFO "seek: %d",
					    ft_hide_interrupt,
					    ft_seek_completed);

			}
			fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
			spin_lock_irqsave(&fdc_io_lock, flags);
		}
	fdc_status = inb(fdc.msr);
	if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) {
		spin_unlock_irqrestore(&fdc_io_lock, flags);
		TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready");
	} 
	fdc_mode = *cmd_data;	/* used by isr */
#ifdef TESTING
	if (fdc_mode == FDC_SEEK) {
		time = ftape_timediff(last_time, ftape_timestamp());
		if (time < 6000) {
	TRACE(ft_t_bug,"Warning: short timeout between seek commands: %d",
	      time);
		}
	}
#endif
	if (!in_interrupt()) {
		/* shouldn't be cleared if called from isr
		 */
		ft_interrupt_seen = 0;
	}
	while (count) {
		result = fdc_write(*cmd_data);
		if (result < 0) {
			TRACE(ft_t_fdc_dma,
			      "fdc_mode = %02x, status = %02x at index %d",
			      (int) fdc_mode, (int) fdc_status,
			      cmd_len - count);
			if (++retry <= 3) {
				TRACE(ft_t_warn, "fdc_write timeout, retry");
			} else {
				TRACE(ft_t_err, "fdc_write timeout, fatal");
				/* recover ??? */
				break;
			}
		} else {
			--count;
			++cmd_data;
		}
        }
#ifdef TESTING
	if (fdc_mode == FDC_SEEK) {
		last_time = ftape_timestamp();
	}
#endif
	spin_unlock_irqrestore(&fdc_io_lock, flags);
	TRACE_EXIT result;
}

/*  Input a res_len long result string from the FDC.
 *  The FDC should be ready to send the result or an error
 *  (EBUSY or ETIME) will occur.
 */
int fdc_result(__u8 * res_data, int res_len)
{
	int result = 0;
	unsigned long flags;
	int count = res_len;
	int retry = 0;
	TRACE_FUN(ft_t_any);

	spin_lock_irqsave(&fdc_io_lock, flags);
	fdc_status = inb(fdc.msr);
	if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) {
		TRACE(ft_t_err, "fdc not ready");
		result = -EBUSY;
	} else while (count) {
		if (!(fdc_status & FDC_BUSY)) {
			spin_unlock_irqrestore(&fdc_io_lock, flags);
			TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase");
		}
		result = fdc_read(res_data);
		if (result < 0) {
			TRACE(ft_t_fdc_dma,
			      "fdc_mode = %02x, status = %02x at index %d",
			      (int) fdc_mode,
			      (int) fdc_status,
			      res_len - count);
			if (++retry <= 3) {
				TRACE(ft_t_warn, "fdc_read timeout, retry");
			} else {
				TRACE(ft_t_err, "fdc_read timeout, fatal");
				/* recover ??? */
				break;
				++retry;
			}
		} else {
			--count;
			++res_data;
		}
	}
	spin_unlock_irqrestore(&fdc_io_lock, flags);
	fdc_usec_wait(FT_RQM_DELAY);	/* allow FDC to negate BSY */
	TRACE_EXIT result;
}

/*      Handle command and result phases for
 *      commands without data phase.
 */
static int fdc_issue_command(const __u8 * out_data, int out_count,
		      __u8 * in_data, int in_count)
{
	TRACE_FUN(ft_t_any);

	if (out_count > 0) {
		TRACE_CATCH(fdc_command(out_data, out_count),);
	}
	/* will take 24 - 30 usec for fdc_sense_drive_status and
	 * fdc_sense_interrupt_status commands.
	 *    35 fails sometimes (5/9/93 SJL)
	 * On a loaded system it incidentally takes longer than
	 * this for the fdc to get ready ! ?????? WHY ??????
	 * So until we know what's going on use a very long timeout.
	 */
	TRACE_CATCH(fdc_ready_out_wait(500 /* usec */),);
	if (in_count > 0) {
		TRACE_CATCH(fdc_result(in_data, in_count),
			    TRACE(ft_t_err, "result phase aborted"));
	}
	TRACE_EXIT 0;
}

/*      Wait for FDC interrupt with timeout (in milliseconds).
 *      Signals are blocked so the wait will not be aborted.
 *      Note: interrupts must be enabled ! (23/05/93 SJL)
 */
int fdc_interrupt_wait(unsigned int time)
{
	DECLARE_WAITQUEUE(wait,current);
	sigset_t old_sigmask;	
	static int resetting;
	long timeout;

	TRACE_FUN(ft_t_fdc_dma);

 	if (waitqueue_active(&ftape_wait_intr)) {
		TRACE_ABORT(-EIO, ft_t_err, "error: nested call");
	}
	/* timeout time will be up to USPT microseconds too long ! */
	timeout = (1000 * time + FT_USPT - 1) / FT_USPT;

	spin_lock_irq(&current->sighand->siglock);
	old_sigmask = current->blocked;
	sigfillset(&current->blocked);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	set_current_state(TASK_INTERRUPTIBLE);
	add_wait_queue(&ftape_wait_intr, &wait);
	while (!ft_interrupt_seen && (current->state == TASK_INTERRUPTIBLE)) {
		timeout = schedule_timeout(timeout);
        }

	spin_lock_irq(&current->sighand->siglock);
	current->blocked = old_sigmask;
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
	
	remove_wait_queue(&ftape_wait_intr, &wait);
	/*  the following IS necessary. True: as well
	 *  wake_up_interruptible() as the schedule() set TASK_RUNNING
	 *  when they wakeup a task, BUT: it may very well be that
	 *  ft_interrupt_seen is already set to 1 when we enter here
	 *  in which case schedule() gets never called, and
	 *  TASK_RUNNING never set. This has the funny effect that we
	 *  execute all the code until we leave kernel space, but then
	 *  the task is stopped (a task CANNOT be preempted while in
	 *  kernel mode. Sending a pair of SIGSTOP/SIGCONT to the
	 *  tasks wakes it up again. Funny! :-)
	 */
	current->state = TASK_RUNNING; 
	if (ft_interrupt_seen) { /* woken up by interrupt */
		ft_interrupt_seen = 0;
		TRACE_EXIT 0;
	}
	/*  Original comment:
	 *  In first instance, next statement seems unnecessary since
	 *  it will be cleared in fdc_command. However, a small part of
	 *  the software seems to rely on this being cleared here
	 *  (ftape_close might fail) so stick to it until things get fixed !
	 */
	/*  My deeply sought of knowledge:
	 *  Behold NO! It is obvious. fdc_reset() doesn't call fdc_command()
	 *  but nevertheless uses fdc_interrupt_wait(). OF COURSE this needs to
	 *  be reset here.
	 */
	ft_interrupt_seen = 0;	/* clear for next call */
	if (!resetting) {
		resetting = 1;	/* break infinite recursion if reset fails */
		TRACE(ft_t_any, "cleanup reset");
		fdc_reset();
		resetting = 0;
	}
	TRACE_EXIT (signal_pending(current)) ? -EINTR : -ETIME;
}

/*      Start/stop drive motor. Enable DMA mode.
 */
void fdc_motor(int motor)
{
	int unit = ft_drive_sel;
	int data = unit | FDC_RESET_NOT | FDC_DMA_MODE;
	TRACE_FUN(ft_t_any);

	ftape_motor = motor;
	if (ftape_motor) {
		data |= FDC_MOTOR_0 << unit;
		TRACE(ft_t_noise, "turning motor %d on", unit);
	} else {
		TRACE(ft_t_noise, "turning motor %d off", unit);
	}
	if (ft_mach2) {
		outb_p(data, fdc.dor2);
	} else {
		outb_p(data, fdc.dor);
	}
	ftape_sleep(10 * FT_MILLISECOND);
	TRACE_EXIT;
}

static void fdc_update_dsr(void)
{
	TRACE_FUN(ft_t_any);

	TRACE(ft_t_flow, "rate = %d Kbps, precomp = %d ns",
	      fdc_data_rate, fdc_precomp);
	if (fdc.type >= i82077) {
		outb_p((fdc_rate_code & 0x03) | fdc_prec_code, fdc.dsr);
	} else {
		outb_p(fdc_rate_code & 0x03, fdc.ccr);
	}
	TRACE_EXIT;
}

void fdc_set_write_precomp(int precomp)
{
	TRACE_FUN(ft_t_any);

	TRACE(ft_t_noise, "New precomp: %d nsec", precomp);
	fdc_precomp = precomp;
	/*  write precompensation can be set in multiples of 41.67 nsec.
	 *  round the parameter to the nearest multiple and convert it
	 *  into a fdc setting. Note that 0 means default to the fdc,
	 *  7 is used instead of that.
	 */
	fdc_prec_code = ((fdc_precomp + 21) / 42) << 2;
	if (fdc_prec_code == 0 || fdc_prec_code > (6 << 2)) {
		fdc_prec_code = 7 << 2;
	}
	fdc_update_dsr();
	TRACE_EXIT;
}

/*  Reprogram the 82078 registers to use Data Rate Table 1 on all drives.
 */
static void fdc_set_drive_specs(void)
{
	__u8 cmd[] = { FDC_DRIVE_SPEC, 0x00, 0x00, 0x00, 0x00, 0xc0};
	int result;
	TRACE_FUN(ft_t_any);

	TRACE(ft_t_flow, "Setting of drive specs called");
	if (fdc.type >= i82078_1) {
		cmd[1] = (0 << 5) | (2 << 2);
		cmd[2] = (1 << 5) | (2 << 2);
		cmd[3] = (2 << 5) | (2 << 2);
		cmd[4] = (3 << 5) | (2 << 2);
		result = fdc_command(cmd, NR_ITEMS(cmd));
		if (result < 0) {
			TRACE(ft_t_err, "Setting of drive specs failed");
		}
	}
	TRACE_EXIT;
}

/* Select clock for fdc, must correspond with tape drive setting !
 * This also influences the fdc timing so we must adjust some values.
 */
int fdc_set_data_rate(int rate)
{
	int bad_rate = 0;
	TRACE_FUN(ft_t_any);

	/* Select clock for fdc, must correspond with tape drive setting !
	 * This also influences the fdc timing so we must adjust some values.
	 */
	TRACE(ft_t_fdc_dma, "new rate = %d", rate);
	switch (rate) {
	case 250:
		fdc_rate_code = fdc_data_rate_250;
		break;
	case 500:
		fdc_rate_code = fdc_data_rate_500;
		break;
	case 1000:
		if (fdc.type < i82077) {
			bad_rate = 1;
                } else {
			fdc_rate_code = fdc_data_rate_1000;
		}
		break;
	case 2000:
		if (fdc.type < i82078_1) {
			bad_rate = 1;
                } else {
			fdc_rate_code = fdc_data_rate_2000;
		}
		break;
	default:
		bad_rate = 1;
        }
	if (bad_rate) {
		TRACE_ABORT(-EIO,
			    ft_t_fdc_dma, "%d is not a valid data rate", rate);
	}
	fdc_data_rate = rate;
	fdc_update_dsr();
	fdc_set_seek_rate(fdc_seek_rate);  /* clock changed! */
	ftape_udelay(1000);
	TRACE_EXIT 0;
}

/*  keep the unit select if keep_select is != 0,
 */
static void fdc_dor_reset(int keep_select)
{
	__u8 fdc_ctl = ft_drive_sel;

	if (keep_select != 0) {
		fdc_ctl |= FDC_DMA_MODE;
		if (ftape_motor) {
			fdc_ctl |= FDC_MOTOR_0 << ft_drive_sel;
		}
	}
	ftape_udelay(10); /* ??? but seems to be necessary */
	if (ft_mach2) {
		outb_p(fdc_ctl & 0x0f, fdc.dor);
		outb_p(fdc_ctl, fdc.dor2);
	} else {
		outb_p(fdc_ctl, fdc.dor);
	}
	fdc_usec_wait(10); /* delay >= 14 fdc clocks */
	if (keep_select == 0) {
		fdc_ctl = 0;
	}
	fdc_ctl |= FDC_RESET_NOT;
	if (ft_mach2) {
		outb_p(fdc_ctl & 0x0f, fdc.dor);
		outb_p(fdc_ctl, fdc.dor2);
	} else {
		outb_p(fdc_ctl, fdc.dor);
	}
}

/*      Reset the floppy disk controller. Leave the ftape_unit selected.
 */
void fdc_reset(void)
{
	int st0;
	int i;
	int dummy;
	unsigned long flags;
	TRACE_FUN(ft_t_any);

	spin_lock_irqsave(&fdc_io_lock, flags);

	fdc_dor_reset(1); /* keep unit selected */

	fdc_mode = fdc_idle;

	/*  maybe the cli()/sti() pair is not necessary, BUT:
	 *  the following line MUST be here. Otherwise fdc_interrupt_wait()
	 *  won't wait. Note that fdc_reset() is called from 
	 *  ftape_dumb_stop() when the fdc is busy transferring data. In this
	 *  case fdc_isr() MOST PROBABLY sets ft_interrupt_seen, and tries
	 *  to get the result bytes from the fdc etc. CLASH.
	 */
	ft_interrupt_seen = 0;
	
	/*  Program data rate
	 */
	fdc_update_dsr();               /* restore data rate and precomp */

	spin_unlock_irqrestore(&fdc_io_lock, flags);

        /*
         *	Wait for first polling cycle to complete
	 */
	if (fdc_interrupt_wait(1 * FT_SECOND) < 0) {
		TRACE(ft_t_err, "no drive polling interrupt!");
	} else {	/* clear all disk-changed statuses */
		for (i = 0; i < 4; ++i) {
			if(fdc_sense_interrupt_status(&st0, &dummy) != 0) {
				TRACE(ft_t_err, "sense failed for %d", i);
			}
			if (i == ft_drive_sel) {
				ftape_current_cylinder = dummy;
			}
		}
		TRACE(ft_t_noise, "drive polling completed");
	}
	/*
         *	SPECIFY COMMAND
	 */
	fdc_set_seek_rate(fdc_seek_rate);
	/*
	 *	DRIVE SPECIFICATION COMMAND (if fdc type known)
	 */
	if (fdc.type >= i82078_1) {
		fdc_set_drive_specs();
	}
	TRACE_EXIT;
}

#if !defined(CLK_48MHZ)
# define CLK_48MHZ 1
#endif

/*  When we're done, put the fdc into reset mode so that the regular
 *  floppy disk driver will figure out that something is wrong and
 *  initialize the controller the way it wants.
 */
void fdc_disable(void)
{
	__u8 cmd1[] = {FDC_CONFIGURE, 0x00, 0x00, 0x00};
	__u8 cmd2[] = {FDC_LOCK};
	__u8 cmd3[] = {FDC_UNLOCK};
	__u8 stat[1];
	TRACE_FUN(ft_t_flow);

	if (!fdc_fifo_locked) {
		fdc_reset();
		TRACE_EXIT;
	}
	if (fdc_issue_command(cmd3, 1, stat, 1) < 0 || stat[0] != 0x00) {
		fdc_dor_reset(0);
		TRACE_ABORT(/**/, ft_t_bug, 
		"couldn't unlock fifo, configuration remains changed");
	}
	fdc_fifo_locked = 0;
	if (CLK_48MHZ && fdc.type >= i82078) {
		cmd1[0] |= FDC_CLK48_BIT;
	}
	cmd1[2] = ((fdc_fifo_state) ? 0 : 0x20) + (fdc_fifo_thr - 1);
	if (fdc_command(cmd1, NR_ITEMS(cmd1)) < 0) {
		fdc_dor_reset(0);
		TRACE_ABORT(/**/, ft_t_bug,
		"couldn't reconfigure fifo to old state");
	}
	if (fdc_lock_state &&
	    fdc_issue_command(cmd2, 1, stat, 1) < 0) {
		fdc_dor_reset(0);
		TRACE_ABORT(/**/, ft_t_bug, "couldn't lock old state again");
	}
	TRACE(ft_t_noise, "fifo restored: %sabled, thr. %d, %slocked",
	      fdc_fifo_state ? "en" : "dis",
	      fdc_fifo_thr, (fdc_lock_state) ? "" : "not ");
	fdc_dor_reset(0);
	TRACE_EXIT;
}

/*      Specify FDC seek-rate (milliseconds)
 */
static int fdc_set_seek_rate(int seek_rate)
{
	/* set step rate, dma mode, and minimal head load and unload times
	 */
	__u8 in[3] = { FDC_SPECIFY, 1, (1 << 1)};
 
	fdc_seek_rate = seek_rate;
	in[1] |= (16 - (fdc_data_rate * fdc_seek_rate) / 500) << 4;

	return fdc_command(in, 3);
}

/*      Sense drive status: get unit's drive status (ST3)
 */
int fdc_sense_drive_status(int *st3)
{
	__u8 out[2];
	__u8 in[1];
	TRACE_FUN(ft_t_any);

	out[0] = FDC_SENSED;
	out[1] = ft_drive_sel;
	TRACE_CATCH(fdc_issue_command(out, 2, in, 1),);
	*st3 = in[0];
	TRACE_EXIT 0;
}

/*      Sense Interrupt Status command:
 *      should be issued at the end of each seek.
 *      get ST0 and current cylinder.
 */
int fdc_sense_interrupt_status(int *st0, int *current_cylinder)
{
	__u8 out[1];
	__u8 in[2];
	TRACE_FUN(ft_t_any);

	out[0] = FDC_SENSEI;
	TRACE_CATCH(fdc_issue_command(out, 1, in, 2),);
	*st0 = in[0];
	*current_cylinder = in[1];
	TRACE_EXIT 0;
}

/*      step to track
 */
int fdc_seek(int track)
{
	__u8 out[3];
	int st0, pcn;
#ifdef TESTING
	unsigned int time;
#endif
	TRACE_FUN(ft_t_any);

	out[0] = FDC_SEEK;
	out[1] = ft_drive_sel;
	out[2] = track;
#ifdef TESTING
	time = ftape_timestamp();
#endif
	/*  We really need this command to work !
	 */
	ft_seek_completed = 0;
	TRACE_CATCH(fdc_command(out, 3),
		    fdc_reset();
		    TRACE(ft_t_noise, "destination was: %d, resetting FDC...",
			  track));
	/*    Handle interrupts until ft_seek_completed or timeout.
	 */
	for (;;) {
		TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
		if (ft_seek_completed) {
			TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
			if ((st0 & ST0_SEEK_END) == 0) {
				TRACE_ABORT(-EIO, ft_t_err,
				      "no seek-end after seek completion !??");
			}
			break;
		}
	}
#ifdef TESTING
	time = ftape_timediff(time, ftape_timestamp()) / abs(track - ftape_current_cylinder);
	if ((time < 900 || time > 3100) && abs(track - ftape_current_cylinder) > 5) {
		TRACE(ft_t_warn, "Wrong FDC STEP interval: %d usecs (%d)",
                         time, track - ftape_current_cylinder);
	}
#endif
	/*    Verify whether we issued the right tape command.
	 */
	/* Verify that we seek to the proper track. */
	if (pcn != track) {
		TRACE_ABORT(-EIO, ft_t_err, "bad seek..");
	}
	ftape_current_cylinder = track;
	TRACE_EXIT 0;
}

static int perpend_mode; /* set if fdc is in perpendicular mode */

static int perpend_off(void)
{
 	__u8 perpend[] = {FDC_PERPEND, 0x00};
	TRACE_FUN(ft_t_any);
	
	if (perpend_mode) {
		/* Turn off perpendicular mode */
		perpend[1] = 0x80;
		TRACE_CATCH(fdc_command(perpend, 2),
			    TRACE(ft_t_err,"Perpendicular mode exit failed!"));
		perpend_mode = 0;
	}
	TRACE_EXIT 0;
}

static int handle_perpend(int segment_id)
{
 	__u8 perpend[] = {FDC_PERPEND, 0x00};
	TRACE_FUN(ft_t_any);

	/* When writing QIC-3020 tapes, turn on perpendicular mode
	 * if tape is moving in forward direction (even tracks).
	 */
	if (ft_qic_std == QIC_TAPE_QIC3020 &&
	    ((segment_id / ft_segments_per_track) & 1) == 0) {
/*  FIXME: some i82077 seem to support perpendicular mode as
 *  well. 
 */
#if 0
		if (fdc.type < i82077AA) {}
#else
		if (fdc.type < i82077 && ft_data_rate < 1000) {
#endif
			/*  fdc does not support perpendicular mode: complain 
			 */
			TRACE_ABORT(-EIO, ft_t_err,
				    "Your FDC does not support QIC-3020.");
		}
		perpend[1] = 0x03 /* 0x83 + (0x4 << ft_drive_sel) */ ;
		TRACE_CATCH(fdc_command(perpend, 2),
			   TRACE(ft_t_err,"Perpendicular mode entry failed!"));
		TRACE(ft_t_flow, "Perpendicular mode set");
		perpend_mode = 1;
		TRACE_EXIT 0;
	}
	TRACE_EXIT perpend_off();
}

static inline void fdc_setup_dma(char mode,
				 volatile void *addr, unsigned int count)
{
	/* Program the DMA controller.
	 */
	disable_dma(fdc.dma);
	clear_dma_ff(fdc.dma);
	set_dma_mode(fdc.dma, mode);
	set_dma_addr(fdc.dma, virt_to_bus((void*)addr));
	set_dma_count(fdc.dma, count);
	enable_dma(fdc.dma);
}

/*  Setup fdc and dma for formatting the next segment
 */
int fdc_setup_formatting(buffer_struct * buff)
{
	unsigned long flags;
	__u8 out[6] = {
		FDC_FORMAT, 0x00, 3, 4 * FT_SECTORS_PER_SEGMENT, 0x00, 0x6b
	};
	TRACE_FUN(ft_t_any);
	
	TRACE_CATCH(handle_perpend(buff->segment_id),);
	/* Program the DMA controller.
	 */
        TRACE(ft_t_fdc_dma,
	      "phys. addr. = %lx", virt_to_bus((void*) buff->ptr));
	spin_lock_irqsave(&fdc_io_lock, flags);
	fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4);
	/* Issue FDC command to start reading/writing.
	 */
	out[1] = ft_drive_sel;
	out[4] = buff->gap3;
	TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)),
		    restore_flags(flags); fdc_mode = fdc_idle);
	spin_unlock_irqrestore(&fdc_io_lock, flags);
	TRACE_EXIT 0;
}


/*      Setup Floppy Disk Controller and DMA to read or write the next cluster
 *      of good sectors from or to the current segment.
 */
int fdc_setup_read_write(buffer_struct * buff, __u8 operation)
{
	unsigned long flags;
	__u8 out[9];
	int dma_mode;
	TRACE_FUN(ft_t_any);

	switch(operation) {
	case FDC_VERIFY:
		if (fdc.type < i82077) {
			operation = FDC_READ;
		}
	case FDC_READ:
	case FDC_READ_DELETED:
		dma_mode = DMA_MODE_READ;
		TRACE(ft_t_fdc_dma, "xfer %d sectors to 0x%p",
		      buff->sector_count, buff->ptr);
		TRACE_CATCH(perpend_off(),);
		break;
	case FDC_WRITE_DELETED:
		TRACE(ft_t_noise, "deleting segment %d", buff->segment_id);
	case FDC_WRITE:
		dma_mode = DMA_MODE_WRITE;
		/* When writing QIC-3020 tapes, turn on perpendicular mode
		 * if tape is moving in forward direction (even tracks).
		 */
		TRACE_CATCH(handle_perpend(buff->segment_id),);
		TRACE(ft_t_fdc_dma, "xfer %d sectors from 0x%p",
		      buff->sector_count, buff->ptr);
		break;
	default:
		TRACE_ABORT(-EIO,
			    ft_t_bug, "bug: invalid operation parameter");
	}
	TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr));
	spin_lock_irqsave(&fdc_io_lock, flags);
	if (operation != FDC_VERIFY) {
		fdc_setup_dma(dma_mode, buff->ptr,
			      FT_SECTOR_SIZE * buff->sector_count);
	}
	/* Issue FDC command to start reading/writing.
	 */
	out[0] = operation;
	out[1] = ft_drive_sel;
	out[2] = buff->cyl;
	out[3] = buff->head;
	out[4] = buff->sect + buff->sector_offset;
	out[5] = 3;		/* Sector size of 1K. */
	out[6] = out[4] + buff->sector_count - 1;	/* last sector */
	out[7] = 109;		/* Gap length. */
	out[8] = 0xff;		/* No limit to transfer size. */
	TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x",
		out[2], out[3], out[4], out[6] - out[4] + 1);
	spin_unlock_irqrestore(&fdc_io_lock, flags);
	TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle);
	TRACE_EXIT 0;
}

int fdc_fifo_threshold(__u8 threshold,
		       int *fifo_state, int *lock_state, int *fifo_thr)
{
	const __u8 cmd0[] = {FDC_DUMPREGS};
	__u8 cmd1[] = {FDC_CONFIGURE, 0, (0x0f & (threshold - 1)), 0};
	const __u8 cmd2[] = {FDC_LOCK};
	const __u8 cmd3[] = {FDC_UNLOCK};
	__u8 reg[10];
	__u8 stat;
	int i;
	int result;
	TRACE_FUN(ft_t_any);

	if (CLK_48MHZ && fdc.type >= i82078) {
		cmd1[0] |= FDC_CLK48_BIT;
	}
	/*  Dump fdc internal registers for examination
	 */
	TRACE_CATCH(fdc_command(cmd0, NR_ITEMS(cmd0)),
		    TRACE(ft_t_warn, "dumpreg cmd failed, fifo unchanged"));
	/*  Now read fdc internal registers from fifo
	 */
	for (i = 0; i < (int)NR_ITEMS(reg); ++i) {
		fdc_read(&reg[i]);
		TRACE(ft_t_fdc_dma, "Register %d = 0x%02x", i, reg[i]);
	}
	if (fifo_state && lock_state && fifo_thr) {
		*fifo_state = (reg[8] & 0x20) == 0;
		*lock_state = reg[7] & 0x80;
		*fifo_thr = 1 + (reg[8] & 0x0f);
	}
	TRACE(ft_t_noise,
	      "original fifo state: %sabled, threshold %d, %slocked",
	      ((reg[8] & 0x20) == 0) ? "en" : "dis",
	      1 + (reg[8] & 0x0f), (reg[7] & 0x80) ? "" : "not ");
	/*  If fdc is already locked, unlock it first ! */
	if (reg[7] & 0x80) {
		fdc_ready_wait(100);
		TRACE_CATCH(fdc_issue_command(cmd3, NR_ITEMS(cmd3), &stat, 1),
			    TRACE(ft_t_bug, "FDC unlock command failed, "
				  "configuration unchanged"));
	}
	fdc_fifo_locked = 0;
	/*  Enable fifo and set threshold at xx bytes to allow a
	 *  reasonably large latency and reduce number of dma bursts.
	 */
	fdc_ready_wait(100);
	if ((result = fdc_command(cmd1, NR_ITEMS(cmd1))) < 0) {
		TRACE(ft_t_bug, "configure cmd failed, fifo unchanged");
	}
	/*  Now lock configuration so reset will not change it
	 */
        if(fdc_issue_command(cmd2, NR_ITEMS(cmd2), &stat, 1) < 0 ||
	   stat != 0x10) {
		TRACE_ABORT(-EIO, ft_t_bug,
			    "FDC lock command failed, stat = 0x%02x", stat);
	}
	fdc_fifo_locked = 1;
	TRACE_EXIT result;
}

static int fdc_fifo_enable(void)
{
	TRACE_FUN(ft_t_any);

	if (fdc_fifo_locked) {
		TRACE_ABORT(0, ft_t_warn, "Fifo not enabled because locked");
	}
	TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
				       &fdc_fifo_state,
				       &fdc_lock_state,
				       &fdc_fifo_thr),);
	TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
				       NULL, NULL, NULL),);
	TRACE_EXIT 0;
}

/*   Determine fd controller type 
 */
static __u8 fdc_save_state[2];

static int fdc_probe(void)
{
	__u8 cmd[1];
	__u8 stat[16]; /* must be able to hold dumpregs & save results */
	int i;
	TRACE_FUN(ft_t_any);

	/*  Try to find out what kind of fd controller we have to deal with
	 *  Scheme borrowed from floppy driver:
	 *  first try if FDC_DUMPREGS command works
	 *  (this indicates that we have a 82072 or better)
	 *  then try the FDC_VERSION command (82072 doesn't support this)
	 *  then try the FDC_UNLOCK command (some older 82077's don't support this)
	 *  then try the FDC_PARTID command (82078's support this)
	 */
	cmd[0] = FDC_DUMPREGS;
	if (fdc_issue_command(cmd, 1, stat, 1) != 0) {
		TRACE_ABORT(no_fdc, ft_t_bug, "No FDC found");
	}
	if (stat[0] == 0x80) {
		/* invalid command: must be pre 82072 */
		TRACE_ABORT(i8272,
			    ft_t_warn, "Type 8272A/765A compatible FDC found");
	}
	fdc_result(&stat[1], 9);
	fdc_save_state[0] = stat[7];
	fdc_save_state[1] = stat[8];
	cmd[0] = FDC_VERSION;
	if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
		TRACE_ABORT(i8272, ft_t_warn, "Type 82072 FDC found");
	}
	if (*stat != 0x90) {
		TRACE_ABORT(i8272, ft_t_warn, "Unknown FDC found");
	}
	cmd[0] = FDC_UNLOCK;
	if(fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] != 0x00) {
		TRACE_ABORT(i8272, ft_t_warn,
			    "Type pre-1991 82077 FDC found, "
			    "treating it like a 82072");
	}
	if (fdc_save_state[0] & 0x80) { /* was locked */
		cmd[0] = FDC_LOCK; /* restore lock */
		(void)fdc_issue_command(cmd, 1, stat, 1);
		TRACE(ft_t_warn, "FDC is already locked");
	}
	/* Test for a i82078 FDC */
	cmd[0] = FDC_PARTID;
	if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
		/* invalid command: not a i82078xx type FDC */
		for (i = 0; i < 4; ++i) {
			outb_p(i, fdc.tdr);
			if ((inb_p(fdc.tdr) & 0x03) != i) {
				TRACE_ABORT(i82077,
					    ft_t_warn, "Type 82077 FDC found");
			}
		}
		TRACE_ABORT(i82077AA, ft_t_warn, "Type 82077AA FDC found");
	}
	/* FDC_PARTID cmd succeeded */
	switch (stat[0] >> 5) {
	case 0x0:
		/* i82078SL or i82078-1.  The SL part cannot run at
		 * 2Mbps (the SL and -1 dies are identical; they are
		 * speed graded after production, according to Intel).
		 * Some SL's can be detected by doing a SAVE cmd and
		 * look at bit 7 of the first byte (the SEL3V# bit).
		 * If it is 0, the part runs off 3Volts, and hence it
		 * is a SL.
		 */
		cmd[0] = FDC_SAVE;
		if(fdc_issue_command(cmd, 1, stat, 16) < 0) {
			TRACE(ft_t_err, "FDC_SAVE failed. Dunno why");
			/* guess we better claim the fdc to be a i82078 */
			TRACE_ABORT(i82078,
				    ft_t_warn,
				    "Type i82078 FDC (i suppose) found");
		}
		if ((stat[0] & FDC_SEL3V_BIT)) {
			/* fdc running off 5Volts; Pray that it's a i82078-1
			 */
			TRACE_ABORT(i82078_1, ft_t_warn,
				  "Type i82078-1 or 5Volt i82078SL FDC found");
		}
		TRACE_ABORT(i82078, ft_t_warn,
			    "Type 3Volt i82078SL FDC (1Mbps) found");
	case 0x1:
	case 0x2: /* S82078B  */
		/* The '78B  isn't '78 compatible.  Detect it as a '77AA */
		TRACE_ABORT(i82077AA, ft_t_warn, "Type i82077AA FDC found");
	case 0x3: /* NSC PC8744 core; used in several super-IO chips */
		TRACE_ABORT(i82077AA,
			    ft_t_warn, "Type 82077AA compatible FDC found");
	default:
		TRACE(ft_t_warn, "A previously undetected FDC found");
		TRACE_ABORT(i82077AA, ft_t_warn,
			  "Treating it as a 82077AA. Please report partid= %d",
			    stat[0]);
	} /* switch(stat[ 0] >> 5) */
	TRACE_EXIT no_fdc;
}

static int fdc_request_regions(void)
{
	TRACE_FUN(ft_t_flow);

	if (ft_mach2 || ft_probe_fc10) {
		if (!request_region(fdc.sra, 8, "fdc (ft)")) {
#ifndef BROKEN_FLOPPY_DRIVER
			TRACE_EXIT -EBUSY;
#else
			TRACE(ft_t_warn,
"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
#endif
		}
	} else {
		if (!request_region(fdc.sra, 6, "fdc (ft)")) {
#ifndef BROKEN_FLOPPY_DRIVER
			TRACE_EXIT -EBUSY;
#else
			TRACE(ft_t_warn,
"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
#endif
		}
		if (!request_region(fdc.sra + 7, 1, "fdc (ft)")) {
#ifndef BROKEN_FLOPPY_DRIVER
			release_region(fdc.sra, 6);
			TRACE_EXIT -EBUSY;
#else
			TRACE(ft_t_warn,
"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra + 7);
#endif
		}
	}
	TRACE_EXIT 0;
}

void fdc_release_regions(void)
{
	TRACE_FUN(ft_t_flow);

	if (fdc.sra != 0) {
		if (fdc.dor2 != 0) {
			release_region(fdc.sra, 8);
		} else {
			release_region(fdc.sra, 6);
			release_region(fdc.dir, 1);
		}
	}
	TRACE_EXIT;
}

static int fdc_config_regs(unsigned int fdc_base, 
			   unsigned int fdc_irq, 
			   unsigned int fdc_dma)
{
	TRACE_FUN(ft_t_flow);

	fdc.irq = fdc_irq;
	fdc.dma = fdc_dma;
	fdc.sra = fdc_base;
	fdc.srb = fdc_base + 1;
	fdc.dor = fdc_base + 2;
	fdc.tdr = fdc_base + 3;
	fdc.msr = fdc.dsr = fdc_base + 4;
	fdc.fifo = fdc_base + 5;
	fdc.dir = fdc.ccr = fdc_base + 7;
	fdc.dor2 = (ft_mach2 || ft_probe_fc10) ? fdc_base + 6 : 0;
	TRACE_CATCH(fdc_request_regions(), fdc.sra = 0);
	TRACE_EXIT 0;
}

static int fdc_config(void)
{
	static int already_done;
	TRACE_FUN(ft_t_any);

	if (already_done) {
		TRACE_CATCH(fdc_request_regions(),);
		*(fdc.hook) = fdc_isr;	/* hook our handler in */
		TRACE_EXIT 0;
	}
	if (ft_probe_fc10) {
		int fc_type;
		
		TRACE_CATCH(fdc_config_regs(ft_fdc_base,
					    ft_fdc_irq, ft_fdc_dma),);
		fc_type = fc10_enable();
		if (fc_type != 0) {
			TRACE(ft_t_warn, "FC-%c0 controller found", '0' + fc_type);
			fdc.type = fc10;
			fdc.hook = &do_ftape;
			*(fdc.hook) = fdc_isr;	/* hook our handler in */
			already_done = 1;
			TRACE_EXIT 0;
		} else {
			TRACE(ft_t_warn, "FC-10/20 controller not found");
			fdc_release_regions();
			fdc.type = no_fdc;
			ft_probe_fc10 = 0;
			ft_fdc_base   = 0x3f0;
			ft_fdc_irq    = 6;
			ft_fdc_dma    = 2;
		}
	}
	TRACE(ft_t_warn, "fdc base: 0x%x, irq: %d, dma: %d", 
	      ft_fdc_base, ft_fdc_irq, ft_fdc_dma);
	TRACE_CATCH(fdc_config_regs(ft_fdc_base, ft_fdc_irq, ft_fdc_dma),);
	fdc.hook = &do_ftape;
	*(fdc.hook) = fdc_isr;	/* hook our handler in */
	already_done = 1;
	TRACE_EXIT 0;
}

static irqreturn_t ftape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	void (*handler) (void) = *fdc.hook;
	int handled = 0;
	TRACE_FUN(ft_t_any);

	*fdc.hook = NULL;
	if (handler) {
		handled = 1;
		handler();
	} else {
		TRACE(ft_t_bug, "Unexpected ftape interrupt");
	}
	TRACE_EXIT IRQ_RETVAL(handled);
}

static int fdc_grab_irq_and_dma(void)
{
	TRACE_FUN(ft_t_any);

	if (fdc.hook == &do_ftape) {
		/*  Get fast interrupt handler.
		 */
		if (request_irq(fdc.irq, ftape_interrupt,
				SA_INTERRUPT, "ft", ftape_id)) {
			TRACE_ABORT(-EIO, ft_t_bug,
				    "Unable to grab IRQ%d for ftape driver",
				    fdc.irq);
		}
		if (request_dma(fdc.dma, ftape_id)) {
			free_irq(fdc.irq, ftape_id);
			TRACE_ABORT(-EIO, ft_t_bug,
			      "Unable to grab DMA%d for ftape driver",
			      fdc.dma);
		}
	}
	if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
		/* Using same dma channel or irq as standard fdc, need
		 * to disable the dma-gate on the std fdc. This
		 * couldn't be done in the floppy driver as some
		 * laptops are using the dma-gate to enter a low power
		 * or even suspended state :-(
		 */
		outb_p(FDC_RESET_NOT, 0x3f2);
		TRACE(ft_t_noise, "DMA-gate on standard fdc disabled");
	}
	TRACE_EXIT 0;
}

int fdc_release_irq_and_dma(void)
{
	TRACE_FUN(ft_t_any);

	if (fdc.hook == &do_ftape) {
		disable_dma(fdc.dma);	/* just in case... */
		free_dma(fdc.dma);
		free_irq(fdc.irq, ftape_id);
	}
	if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
		/* Using same dma channel as standard fdc, need to
		 * disable the dma-gate on the std fdc. This couldn't
		 * be done in the floppy driver as some laptops are
		 * using the dma-gate to enter a low power or even
		 * suspended state :-(
		 */
		outb_p(FDC_RESET_NOT | FDC_DMA_MODE, 0x3f2);
		TRACE(ft_t_noise, "DMA-gate on standard fdc enabled again");
	}
	TRACE_EXIT 0;
}

int fdc_init(void)
{
	TRACE_FUN(ft_t_any);

	/* find a FDC to use */
	TRACE_CATCH(fdc_config(),);
	TRACE_CATCH(fdc_grab_irq_and_dma(), fdc_release_regions());
	ftape_motor = 0;
	fdc_catch_stray_interrupts(0);	/* clear number of awainted
					 * stray interrupte 
					 */
	fdc_catch_stray_interrupts(1);	/* one always comes (?) */
	TRACE(ft_t_flow, "resetting fdc");
	fdc_set_seek_rate(2);		/* use nominal QIC step rate */
	fdc_reset();			/* init fdc & clear track counters */
	if (fdc.type == no_fdc) {	/* no FC-10 or FC-20 found */
		fdc.type = fdc_probe();
		fdc_reset();		/* update with new knowledge */
	}
	if (fdc.type == no_fdc) {
		fdc_release_irq_and_dma();
		fdc_release_regions();
		TRACE_EXIT -ENXIO;
	}
	if (fdc.type >= i82077) {
		if (fdc_fifo_enable() < 0) {
			TRACE(ft_t_warn, "couldn't enable fdc fifo !");
		} else {
			TRACE(ft_t_flow, "fdc fifo enabled and locked");
		}
	}
	TRACE_EXIT 0;
}
