Example #1
0
int ftape_wakeup_drive(wake_up_types method)
{
	int status;
	int motor_on = 0;
	TRACE_FUN(ft_t_any);

	switch (method) {
	case wake_up_colorado:
		TRACE_CATCH(ftape_command(QIC_PHANTOM_SELECT),);
		TRACE_CATCH(ftape_parameter(0 /* ft_drive_sel ?? */),);
		break;
	case wake_up_mountain:
		TRACE_CATCH(ftape_command(QIC_SOFT_SELECT),);
		ftape_sleep(FT_MILLISECOND);	/* NEEDED */
		TRACE_CATCH(ftape_parameter(18),);
		break;
	case wake_up_insight:
		ftape_sleep(100 * FT_MILLISECOND);
		motor_on = 1;
		fdc_motor(motor_on);	/* enable is done by motor-on */
	case no_wake_up:
		break;
	default:
		TRACE_EXIT -ENODEV;	/* unknown wakeup method */
		break;
	}
	/*  If wakeup succeeded we shouldn't get an error here..
	 */
	TRACE_CATCH(ftape_report_raw_drive_status(&status),
		    if (motor_on) {
			    fdc_motor(0);
		    });
Example #2
0
/*      Wait for the drive to get ready.
 *      timeout time in milli-seconds
 *      Returned status is valid if result != -EIO
 *
 *      Should we allow to be killed by SIGINT?  (^C)
 *      Would be nice at least for large timeouts.
 */
int ftape_ready_wait(unsigned int timeout, int *status)
{
	unsigned long t0;
	unsigned int poll_delay;
	int signal_retries;
	TRACE_FUN(ft_t_any);

	/*  the following ** REALLY ** reduces the system load when
	 *  e.g. one simply rewinds or retensions. The tape is slow 
	 *  anyway. It is really not necessary to detect error 
	 *  conditions with 1/10 seconds granularity
	 *
	 *  On my AMD 133MHZ 486: 100 ms: 23% system load
	 *                        1  sec:  5%
	 *                        5  sec:  0.6%, yeah
	 */
	if (timeout <= FT_SECOND) {
		poll_delay = 100 * FT_MILLISECOND;
		signal_retries = 20; /* two seconds */
	} else if (timeout < 20 * FT_SECOND) {
		TRACE(ft_t_flow, "setting poll delay to 1 second");
		poll_delay = FT_SECOND;
		signal_retries = 2; /* two seconds */
	} else {
		TRACE(ft_t_flow, "setting poll delay to 5 seconds");
		poll_delay = 5 * FT_SECOND;
		signal_retries = 1; /* five seconds */
	}
	for (;;) {
		t0 = jiffies;
		TRACE_CATCH(ftape_report_raw_drive_status(status),);
		if (*status & QIC_STATUS_READY) {
			TRACE_EXIT 0;
		}
		if (!signal_retries--) {
			FT_SIGNAL_EXIT(_NEVER_BLOCK);
		}
		if ((int)timeout >= 0) {
			/* this will fail when jiffies wraps around about
			 * once every year :-)
			 */
			timeout -= ((jiffies - t0) * FT_SECOND) / HZ;
			if (timeout <= 0) {
				TRACE_ABORT(-ETIME, ft_t_err, "timeout");
			}
			ftape_sleep(poll_delay);
			timeout -= poll_delay;
		} else {
			ftape_sleep(poll_delay);
		}
	}
	TRACE_EXIT -ETIME;
}
Example #3
0
/*  Called by modules package when installing the driver
 *  or by kernel during the initialization phase
 */
static int __init ftape_init(void)
{
	TRACE_FUN(ft_t_flow);

#ifdef MODULE
#ifndef CONFIG_FT_NO_TRACE_AT_ALL
	if (ft_tracing != -1) {
		ftape_tracing = ft_tracing;
	}
#endif
	printk(KERN_INFO FTAPE_VERSION "\n");
        if (TRACE_LEVEL >= ft_t_info) {
		printk(
KERN_INFO "(c) 1993-1996 Bas Laarhoven ([email protected])\n"
KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen ([email protected])\n"
KERN_INFO "(c) 1996-1997 Claus-Justus Heine ([email protected])\n"
KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n"
KERN_INFO "Compiled for Linux version %s\n", UTS_RELEASE);
        }
#else /* !MODULE */
	/* print a short no-nonsense boot message */
	printk(KERN_INFO FTAPE_VERSION " for Linux " UTS_RELEASE "\n");
#endif /* MODULE */
	TRACE(ft_t_info, "installing QIC-117 floppy tape hardware drive ... ");
	TRACE(ft_t_info, "ftape_init @ 0x%p", ftape_init);
	/*  Allocate the DMA buffers. They are deallocated at cleanup() time.
	 */
#if TESTING
#ifdef MODULE
	while (ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS) < 0) {
		ftape_sleep(FT_SECOND/20);
		if (signal_pending(current)) {
			(void)ftape_set_nr_buffers(0);
			TRACE(ft_t_bug,
			      "Killed by signal while allocating buffers.");
			TRACE_ABORT(-EINTR, 
				    ft_t_bug, "Free up memory and retry");
		}
	}
#else
	TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS),
		    (void)ftape_set_nr_buffers(0));
#endif
#else
	TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS),
		    (void)ftape_set_nr_buffers(0));
#endif
	ft_drive_sel = -1;
	ft_failure   = 1;         /* inhibit any operation but open */
	ftape_udelay_calibrate(); /* must be before fdc_wait_calibrate ! */
	fdc_wait_calibrate();
#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
	(void)ftape_proc_init();
#endif
#ifdef CONFIG_ZFTAPE
	(void)zft_init();
#endif
	TRACE_EXIT 0;
}
Example #4
0
/*  send a command or parameter to the drive
 *  Generates # of step pulses.
 */
static inline int ft_send_to_drive(int arg)
{
	/*  Always wait for a command_timeout period to separate
	 *  individuals commands and/or parameters.
	 */
	ftape_sleep(3 * FT_MILLISECOND);
	/*  Keep cylinder nr within range, step towards home if possible.
	 */
	if (ftape_current_cylinder >= arg) {
		return fdc_seek(ftape_current_cylinder - arg);
	} else {
		return fdc_seek(ftape_current_cylinder + arg);
	}
}
Example #5
0
int ftape_report_operation(int *status,
			   qic117_cmd_t command,
			   int result_length)
{
	int i, st3;
	unsigned int t0;
	unsigned int dt;
	TRACE_FUN(ft_t_any);

	TRACE_CATCH(ftape_command(command),);
	t0 = ftape_timestamp();
	i = 0;
	do {
		++i;
		ftape_sleep(3 * FT_MILLISECOND);	/* see remark below */
		TRACE_CATCH(fdc_sense_drive_status(&st3),);
		dt = ftape_timediff(t0, ftape_timestamp());
		/*  Ack should be asserted within Ttimout + Tack = 6 msec.
		 *  Looks like some drives fail to do this so extend this
		 *  period to 300 msec.
		 */
	} while (!(st3 & ST3_TRACK_0) && dt < 300000);
	if (!(st3 & ST3_TRACK_0)) {
		TRACE(ft_t_err,
		      "No acknowledge after %u msec. (%i iter)", dt / 1000, i);
		TRACE_ABORT(-EIO, ft_t_err, "timeout on Acknowledge");
	}
	/*  dt may be larger than expected because of other tasks
	 *  scheduled while we were sleeping.
	 */
	if (i > 1 && dt > 6000) {
		TRACE(ft_t_err, "Acknowledge after %u msec. (%i iter)",
		      dt / 1000, i);
	}
	*status = 0;
	for (i = 0; i < result_length + 1; i++) {
		TRACE_CATCH(ftape_command(QIC_REPORT_NEXT_BIT),);
		TRACE_CATCH(fdc_sense_drive_status(&st3),);
		if (i < result_length) {
			*status |= ((st3 & ST3_TRACK_0) ? 1 : 0) << i;
		} else if ((st3 & ST3_TRACK_0) == 0) {
			TRACE_ABORT(-EIO, ft_t_err, "missing status stop bit");
		}
	}
	/* this command will put track zero and index back into normal state */
	(void)ftape_command(QIC_REPORT_NEXT_BIT);
	TRACE_EXIT 0;
}