Ejemplo n.º 1
0
static int ftape_set_rate_test(unsigned int *max_rate)
{
	unsigned int error;
	qic117_cmd_t command;
	int status;
	int supported = 0;
	TRACE_FUN(ft_t_any);

	/*  Check if the drive does support the select rate command
	 *  by testing all different settings. If any one is accepted
	 *  we assume the command is supported, else not.
	 */
	for (*max_rate = 2000; *max_rate >= 250; *max_rate /= 2) {
		if (ftape_command(QIC_SELECT_RATE) < 0) {
			continue;
		}		
		if (ftape_parameter_wait(qic_rate_code(*max_rate),
					 1 * FT_SECOND, &status) < 0) {
			continue;
		}
		if (status & QIC_STATUS_ERROR) {
			ftape_report_error(&error, &command, 0);
			continue;
		}
		supported = 1; /* did accept a request */
		break;
	}
	TRACE(ft_t_noise, "Select Rate command is%s supported", 
	      supported ? "" : " not");
	TRACE_EXIT supported;
}
Ejemplo n.º 2
0
int ftape_get_drive_status(void)
{
	int result;
	int status;
	TRACE_FUN(ft_t_flow);

	ft_no_tape = ft_write_protected = 0;
	/*    Tape drive is activated now.
	 *    First clear error status if present.
	 */
	do {
		result = ftape_ready_wait(ftape_timeout.reset, &status);
		if (result < 0) {
			if (result == -ETIME) {
				TRACE(ft_t_err, "ftape_ready_wait timeout");
			} else if (result == -EINTR) {
				TRACE(ft_t_err, "ftape_ready_wait aborted");
			} else {
				TRACE(ft_t_err, "ftape_ready_wait failed");
			}
			TRACE_EXIT -EIO;
		}
		/*  Clear error condition (drive is ready !)
		 */
		if (status & QIC_STATUS_ERROR) {
			unsigned int error;
			qic117_cmd_t command;

			TRACE(ft_t_err, "error status set");
			result = ftape_report_error(&error, &command, 1);
			if (result < 0) {
				TRACE(ft_t_err,
				      "report_error_code failed: %d", result);
				/* hope it's working next time */
				ftape_reset_drive();
				TRACE_EXIT -EIO;
			} else if (error != 0) {
				TRACE(ft_t_noise, "error code   : %d", error);
				TRACE(ft_t_noise, "error command: %d", command);
			}
		}
		if (status & QIC_STATUS_NEW_CARTRIDGE) {
			unsigned int error;
			qic117_cmd_t command;
			const ft_trace_t old_tracing = TRACE_LEVEL;
			SET_TRACE_LEVEL(ft_t_bug);

			/*  Undocumented feature: Must clear (not present!)
			 *  error here or we'll fail later.
			 */
			ftape_report_error(&error, &command, 1);

			SET_TRACE_LEVEL(old_tracing);
			TRACE(ft_t_info, "status: new cartridge");
			ft_new_tape = 1;
		} else {
			ft_new_tape = 0;
		}
		FT_SIGNAL_EXIT(_DONT_BLOCK);
	} while (status & QIC_STATUS_ERROR);
	
	ft_no_tape = !(status & QIC_STATUS_CARTRIDGE_PRESENT);
	ft_write_protected = (status & QIC_STATUS_WRITE_PROTECT) != 0;
	if (ft_no_tape) {
		TRACE(ft_t_warn, "no cartridge present");
	} else {
		if (ft_write_protected) {
			TRACE(ft_t_noise, "Write protected cartridge");
		}
	}
	TRACE_EXIT 0;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
void ftape_report_vendor_id(unsigned int *id)
{
	int result;
	TRACE_FUN(ft_t_any);

	/* We'll try to get a vendor id from the drive.  First
	 * according to the QIC-117 spec, a 16-bit id is requested.
	 * If that fails we'll try an 8-bit version, otherwise we'll
	 * try an undocumented query.
	 */
	result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 16);
	if (result < 0) {
		result = ftape_report_operation((int *) id,
						QIC_REPORT_VENDOR_ID, 8);
		if (result < 0) {
			/* The following is an undocumented call found
			 * in the CMS code.
			 */
			result = ftape_report_operation((int *) id, 24, 8);
			if (result < 0) {
				*id = UNKNOWN_VENDOR;
			} else {
				TRACE(ft_t_noise, "got old 8 bit id: %04x",
				      *id);
				*id |= 0x20000;
			}
		} else {
			TRACE(ft_t_noise, "got 8 bit id: %04x", *id);
			*id |= 0x10000;
		}
	} else {
		TRACE(ft_t_noise, "got 16 bit id: %04x", *id);
	}
	if (*id == 0x0047) {
		int version;
		int sign;

		if (ftape_report_rom_version(&version) < 0) {
			TRACE(ft_t_bug, "report rom version failed");
			TRACE_EXIT;
		}
		TRACE(ft_t_noise, "CMS rom version: %d", version);
		ftape_command(QIC_ENTER_DIAGNOSTIC_1);
		ftape_command(QIC_ENTER_DIAGNOSTIC_1);
		diagnostic_mode = 1;
		if (ftape_report_operation(&sign, 9, 8) < 0) {
			unsigned int error;
			qic117_cmd_t command;

			ftape_report_error(&error, &command, 1);
			ftape_command(QIC_ENTER_PRIMARY_MODE);
			diagnostic_mode = 0;
			TRACE_EXIT;	/* failure ! */
		} else {
			TRACE(ft_t_noise, "CMS signature: %02x", sign);
		}
		if (sign == 0xa5) {
			result = ftape_report_operation(&sign, 37, 8);
			if (result < 0) {
				if (version >= 63) {
					*id = 0x8880;
					TRACE(ft_t_noise,
					      "This is an Iomega drive !");
				} else {
					*id = 0x0047;
					TRACE(ft_t_noise,
					      "This is a real CMS drive !");
				}
			} else {
				*id = 0x0047;
				TRACE(ft_t_noise, "CMS status: %d", sign);
			}
		} else {
			*id = UNKNOWN_VENDOR;
		}
		ftape_command(QIC_ENTER_PRIMARY_MODE);
		diagnostic_mode = 0;
	}
	TRACE_EXIT;
}
Ejemplo n.º 5
0
int ftape_get_drive_status(int *new_tape, int *no_tape, int *wp_tape)
{
	TRACE_FUN(5, "ftape_get_drive_status");
	int result;
	int status;

	*no_tape =
	    *wp_tape = 0;
	/*    Tape drive is activated now.
	 *    First clear error status if present.
	 */
	do {
		result = ftape_ready_wait(timeout.reset, &status);
		if (result < 0) {
			if (result == -ETIME) {
				TRACE(1, "ftape_ready_wait timeout");
			} else if (result == -EINTR) {
				TRACE(1, "ftape_ready_wait aborted");
			} else {
				TRACE(1, "ftape_ready_wait failed");
			}
			result = -EIO;
			break;
		}
		/*  Clear error condition (drive is ready !)
		 */
		if (status & QIC_STATUS_ERROR) {
			int error;
			int command;

			TRACE(1, "error status set");
			result = ftape_report_error(&error, &command, 1);
			if (result < 0) {
				TRACEi(1, "report_error_code failed:", result);
				ftape_reset_drive();	/* hope it's working next time */
				init_drive_needed = 1;
				result = -EIO;
				break;
			} else if (error != 0) {
				TRACEi(4, "error code   :", error);
				TRACEi(4, "error command:", command);
			}
		}
		if (status & QIC_STATUS_NEW_CARTRIDGE) {
			int error;
			int command;
			int old_tracing = tracing;

			/*  Undocumented feature: Must clear (not present!) error 
			 *  here or we'll fail later.
			 */
			tracing = 0;
			ftape_report_error(&error, &command, 1);
			tracing = old_tracing;
			TRACE(3, "status: new cartridge");
			*new_tape = 1;
		}
	} while (status & QIC_STATUS_ERROR);

	*no_tape = !(status & QIC_STATUS_CARTRIDGE_PRESENT);
	*wp_tape = (status & QIC_STATUS_WRITE_PROTECT);
	if (*no_tape) {
		TRACE(1, "no cartridge present");
	} else {
		if (*wp_tape) {
			TRACE(2, "Write protected cartridge");
		}
	}
	TRACE_EXIT;
	return result;
}