示例#1
0
int ftape_init_drive(int *formatted)
{
	TRACE_FUN(5, "ftape_init_drive");
	int result = 0;
	int status;

	result = ftape_report_raw_drive_status(&status);
	if (result >= 0 && (status & QIC_STATUS_CARTRIDGE_PRESENT)) {
		if (!(status & QIC_STATUS_AT_BOT)) {
			/*  Antique drives will get here after a soft reset,
			 *  modern ones only if the driver is loaded when the
			 *  tape wasn't rewound properly.
			 */
			ftape_seek_to_bot();
		}
		if (!(status & QIC_STATUS_REFERENCED)) {
			TRACE(5, "starting seek_load_point");
			result = ftape_command_wait(QIC_SEEK_LOAD_POINT,
						 timeout.reset, &status);
			if (result < 0) {
				TRACE(1, "seek_load_point failed (command)");
			}
		}
	}
	if (result >= 0) {
		int rate;

		*formatted = (status & QIC_STATUS_REFERENCED);
		if (!*formatted) {
			TRACE(1, "Warning: tape is not formatted !");
		}
		/*  Select highest rate supported by both fdc and drive.
		 *  Start with highest rate supported by the fdc.
		 */
		if (fdc.type >= i82078_1)
			rate = 0;
		else if (fdc.type >= i82077)
			rate = 1;
		else
			rate = 2;
		do {
			result = ftape_set_data_rate(rate);
			if (result >= 0) {
				ftape_calc_timeouts();
				break;
			}
			++rate;
		} while (rate < 4);
		if (result < 0) {
			result = -EIO;
		}
	}
	if (result >= 0) {
		/* Tape should be at bot if new cartridge ! */
		ftape_new_cartridge();
	}
	init_drive_needed = 0;
	TRACE_EXIT;
	return result;
}
示例#2
0
static int ft_check_cmd_restrictions(qic117_cmd_t command)
{
	int status = -1;
	TRACE_FUN(ft_t_any);
	
	TRACE(ft_t_flow, "%s", qic117_cmds[command].name);
	/* A new motion command during an uninterruptible (motion)
	 *  command requires a ready status before the new command can
	 *  be issued. Otherwise a new motion command needs to be
	 *  checked against required status.
	 */
	if (qic117_cmds[command].cmd_type == motion &&
	    qic117_cmds[ftape_current_command].non_intr) {
		ftape_report_raw_drive_status(&status);
		if ((status & QIC_STATUS_READY) == 0) {
			TRACE(ft_t_noise,
			      "motion cmd (%d) during non-intr cmd (%d)",
			      command, ftape_current_command);
			TRACE(ft_t_noise, "waiting until drive gets ready");
			ftape_ready_wait(ftape_timeout.seek,
					 &status);
		}
	}
	if (qic117_cmds[command].mask != 0) {
		__u8 difference;
		/*  Some commands do require a certain status:
		 */
		if (status == -1) {	/* not yet set */
			ftape_report_raw_drive_status(&status);
		}
		difference = ((status ^ qic117_cmds[command].state) &
			      qic117_cmds[command].mask);
		/*  Wait until the drive gets
		 *  ready. This may last forever if
		 *  the drive never gets ready... 
		 */
		while ((difference & QIC_STATUS_READY) != 0) {
			TRACE(ft_t_noise, "command %d issued while not ready",
			      command);
			TRACE(ft_t_noise, "waiting until drive gets ready");
			if (ftape_ready_wait(ftape_timeout.seek,
					     &status) == -EINTR) {
				/*  Bail out on signal !
				 */
				TRACE_ABORT(-EINTR, ft_t_warn,
				      "interrupted by non-blockable signal");
			}
			difference = ((status ^ qic117_cmds[command].state) &
				      qic117_cmds[command].mask);
		}
		while ((difference & QIC_STATUS_ERROR) != 0) {
			int err;
			qic117_cmd_t cmd;

			TRACE(ft_t_noise,
			      "command %d issued while error pending",
			      command);
			TRACE(ft_t_noise, "clearing error status");
			ftape_report_error(&err, &cmd, 1);
			ftape_report_raw_drive_status(&status);
			difference = ((status ^ qic117_cmds[command].state) &
				      qic117_cmds[command].mask);
			if ((difference & QIC_STATUS_ERROR) != 0) {
				/*  Bail out on fatal signal !
				 */
				FT_SIGNAL_EXIT(_NEVER_BLOCK);
			}
		}
		if (difference) {
			/*  Any remaining difference can't be solved
			 *  here.  
			 */
			if (difference & (QIC_STATUS_CARTRIDGE_PRESENT |
					  QIC_STATUS_NEW_CARTRIDGE |
					  QIC_STATUS_REFERENCED)) {
				TRACE(ft_t_warn,
				      "Fatal: tape removed or reinserted !");
				ft_failure = 1;
			} else {
				TRACE(ft_t_err, "wrong state: 0x%02x should be: 0x%02x",
				      status & qic117_cmds[command].mask,
				      qic117_cmds[command].state);
			}
			TRACE_EXIT -EIO;
		}
		if (~status & QIC_STATUS_READY & qic117_cmds[command].mask) {
			TRACE_ABORT(-EBUSY, ft_t_err, "Bad: still busy!");
		}
	}
	TRACE_EXIT 0;
}