Exemple #1
0
static int mt_reset(int *dummy)
{        
	TRACE_FUN(ft_t_flow);
	
	(void)ftape_seek_to_bot();
	TRACE_CATCH(ftape_reset_drive(),
		    zft_init_driver(); zft_uninit_mem(); zft_offline = 1);
	/*  fake a re-open of the device. This will set all flage and 
	 *  allocate buffers as appropriate. The new tape condition will
	 *  force the open routine to do anything we need.
	 */
	TRACE_CATCH(_zft_open(-1 /* fake reopen */, 0 /* dummy */),);
	TRACE_EXIT 0;
}
Exemple #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;
}
Exemple #3
0
/*      IOCTL routine called by kernel-interface code
 */
int _ftape_ioctl(unsigned int command, void *arg)
{
	TRACE_FUN(8, "ftape_ioctl");
	int result = EINVAL;
	union {
		struct mtop mtop;
		struct mtget mtget;
	} krnl_arg;
	int arg_size = (command & IOCSIZE_MASK) >> IOCSIZE_SHIFT;

	/* This check will only catch arguments that are too large !
	 */
	if ((command & IOC_INOUT) && arg_size > sizeof(krnl_arg)) {
		TRACEi(1, "bad argument size:", arg_size);
		TRACE_EXIT;
		return -EINVAL;
	}
	if (command & IOC_IN) {
		int error = verify_area(VERIFY_READ, arg, arg_size);
		if (error) {
			TRACE_EXIT;
			return error;
		}
		memcpy_fromfs(&krnl_arg.mtop, arg, arg_size);
	}
	TRACEx1(5, "called with ioctl command: 0x%08x", command);
	switch (command) {
		/* cpio compatibility
		 * mtrasx and mtreset are mt extension by Hennus Bergman
		 * mtseek and mttell are mt extension by eddy olk
		 */
	case MTIOCTOP:
		TRACEx1(5, "calling MTIOCTOP command: 0x%08x", krnl_arg.mtop.mt_op);
		switch (krnl_arg.mtop.mt_op) {
		case MTNOP:
			/* gnu mt calls MTNOP before MTIOCGET to set status */
			result = 0;
			break;
		case MTRESET:
			result = ftape_reset_drive();
			init_drive_needed = 1;
			if (result < 0 || ftape_offline) {
				break;
			}
			result = ftape_seek_to_bot();
			ftape_reset_position();
			break;
		case MTREW:
		case MTOFFL:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			ftape_flush_buffers();
			ftape_update_header_segments(NULL, 1);
			result = ftape_seek_to_bot();
			ftape_reset_position();
			if (krnl_arg.mtop.mt_op == MTOFFL) {
				going_offline = 1;
				TRACE(4, "Putting tape drive offline");
			}
			result = 0;
			break;
		case MTRETEN:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			result = ftape_seek_to_eot();
			if (result >= 0) {
				result = ftape_seek_to_bot();
			}
			ftape_reset_position();
			break;
		case MTERASE:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			result = ftape_erase();
			break;
		case MTEOM:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			result = ftape_seek_eom();
			break;
		case MTFSFM:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			eof_mark = 1;	/* position ready to extend */
		case MTFSF:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			result = ftape_seek_eof(krnl_arg.mtop.mt_count);
			break;
		case MTBSFM:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			eof_mark = 1;	/* position ready to extend */
		case MTBSF:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			result = ftape_seek_eof(-krnl_arg.mtop.mt_count);
			break;
		case MTFSR:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			tracing = krnl_arg.mtop.mt_count;
			TRACEx1(2, "tracing set to %d", tracing);
			result = 0;
			break;
		case MTBSR:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
#if 0
			result = ftape_fix();
#else
			result = 0;
#endif
			break;
		case MTWEOF:
			if (ftape_offline) {
				result = -EIO;
				break;
			}
			result = ftape_weof(krnl_arg.mtop.mt_count, ftape_seg_pos, 1);
			if (result >= 0) {
				ftape_seg_pos += krnl_arg.mtop.mt_count - 1;
			}
			break;
			/* MTRASx and MTRESET are mt extension by Hennus Bergman
			 */
		case MTRAS1:
		case MTRAS2:
		case MTRAS3:
		case MTSEEK:
		case MTTELL:
		default:
			TRACEi(1, "MTIOCTOP sub-command not implemented:", krnl_arg.mtop.mt_op);
			result = -EIO;
			break;
		}
		break;
	case MTIOCGET:
		krnl_arg.mtget.mt_type = drive_type.vendor_id + 0x800000;
		krnl_arg.mtget.mt_resid = 0;	/* not implemented */
		krnl_arg.mtget.mt_dsreg = 0;	/* status register */
		krnl_arg.mtget.mt_gstat =	/* device independent status */
		    ((ftape_offline) ? 0 : GMT_ONLINE(-1L)) |
		    ((write_protected) ? GMT_WR_PROT(-1L) : 0) |
		    ((no_tape) ? GMT_DR_OPEN(-1L) : 0);
		krnl_arg.mtget.mt_erreg = ftape_last_error;	/* error register */
		result = ftape_file_no(&krnl_arg.mtget.mt_fileno,
				       &krnl_arg.mtget.mt_blkno);
		break;
	case MTIOCPOS:
		TRACE(5, "Mag tape ioctl command: MTIOCPOS");
		TRACE(1, "MTIOCPOS command not implemented");
		break;
	default:
		result = -EINVAL;
		break;
	}
	if (command & IOC_OUT) {
		int error = verify_area(VERIFY_WRITE, arg, arg_size);
		if (error) {
			TRACE_EXIT;
			return error;
		}
		memcpy_tofs(arg, &krnl_arg, arg_size);
	}
	TRACE_EXIT;
	return result;
}
Exemple #4
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;
}