⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftape-ctl.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		length = tape_len;	}	if (drive_type.speed == 0) {		unsigned long t0;		int dt;		ftape_seek_to_bot();		t0 = jiffies;		ftape_seek_to_eot();		ftape_seek_to_bot();		dt = (int) ((jiffies - t0) * MSPT);		drive_type.speed = (2 * 12 * length * 1000) / dt;		TRACE(-1, "==========================================");		TRACEx1(-1, "drive : %s", drive_type.name);		TRACEx2(-1, "delta time = %d, length = %d", dt, length);		TRACEx1(-1, "has max tape speed of %d ips", drive_type.speed);		TRACE(-1, "please report this to <claus@momo.math.rwth-aachen.de>");		TRACE(-1, "==========================================");	}	/*  time to go from bot to eot at normal speed (data rate):	 *  time = (1+delta) * length (ft) * 12 (inch/ft) / speed (ips)	 *  delta = 10 % for seek speed, 20 % for rewind speed.	 */	timeout.seek = (length * 132 * SECOND) / speed;	timeout.rewind = (length * 144 * SECOND) / (10 * drive_type.speed);	timeout.reset = 20 * SECOND + timeout.rewind;	TRACEx2(4, "speed = %d, length = %d", speed, length);	TRACEx1(4, "seek timeout: %d sec", (timeout.seek + 500) / 1000);	TRACEx1(4, "rewind timeout: %d sec", (timeout.rewind + 500) / 1000);	TRACE_EXIT;}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;}/*      OPEN routine called by kernel-interface code */int _ftape_open(void){	TRACE_FUN(8, "_ftape_open");	int result;	static int new_tape = 1;	result = fdc_init();	if (result >= 0) {		result = ftape_activate_drive(&drive_type);		if (result < 0) {			fdc_disable();			fdc_release_irq_and_dma();		} else {			result = ftape_get_drive_status(&new_tape, &no_tape, &write_protected);			if (result < 0) {				ftape_detach_drive();			} else {				if (drive_type.vendor_id == UNKNOWN_VENDOR) {					ftape_log_vendor_id();				}				if (no_tape) {					ftape_offline = 1;				} else if (new_tape) {					ftape_offline = 0;					init_drive_needed = 1;					read_only = 0;	/* enable writes again */				}				if (!ftape_offline && init_drive_needed) {					result = ftape_init_drive(&formatted);					if (result >= 0) {						new_tape = 0;					} else {						ftape_detach_drive();					}				}				if (result >= 0) {					clear_history();				}			}		}	}	TRACE_EXIT;	return result;}/*      RELEASE routine called by kernel-interface code */int _ftape_close(void){	TRACE_FUN(8, "_ftape_close");	int result = 0;	int last_segment = 0;	if (!ftape_offline) {		result = ftape_flush_buffers();		last_segment = ftape_seg_pos - 1;		if (!(ftape_unit & FTAPE_NO_REWIND)) {			if (result >= 0) {				result = ftape_update_header_segments(NULL, 1);				if (result < 0) {					TRACE(1, "error: update of header segments failed");				}			} else {				TRACE(1, "error: unable to update header segments");			}		}		ftape_abort_operation();		if (!(ftape_unit & FTAPE_NO_REWIND)) {			if (!no_tape) {				TRACE(5, "rewinding tape");				result = ftape_seek_to_bot();			}			ftape_reset_position();			ftape_zap_read_buffers();			ftape_zap_write_buffers();		}	}	ftape_detach_drive();	fdc_uninit();	if (history.used) {		TRACE(3, "== Non-fatal errors this run: ==");		TRACE(3, "fdc isr statistics:");		TRACEi(3, " id_am_errors     :", history.id_am_errors);		TRACEi(3, " id_crc_errors    :", history.id_crc_errors);		TRACEi(3, " data_am_errors   :", history.data_am_errors);		TRACEi(3, " data_crc_errors  :", history.data_crc_errors);		TRACEi(3, " overrun_errors   :", history.overrun_errors);		TRACEi(3, " no_data_errors   :", history.no_data_errors);		TRACEi(3, " retries          :", history.retries);		if (history.used & 1) {			TRACE(3, "ecc statistics:");			TRACEi(3, " crc_errors       :", history.crc_errors);			TRACEi(3, " crc_failures     :", history.crc_failures);			TRACEi(3, " ecc_failures     :", history.ecc_failures);			TRACEi(3, " sectors corrected:", history.corrected);		}		TRACEx2(3, "media defects     : %d%s", history.defects,			history.defects ? " !!!" : "");		TRACEi(3, "repositions       :", history.rewinds);		TRACEi(3, "last segment      :", last_segment);	}	if (going_offline) {		going_offline = 0;		ftape_offline = 1;	}	TRACE_EXIT;	return result;}/*      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;}void ftape_init_driver(void){	drive_type.vendor_id = UNKNOWN_VENDOR;	drive_type.speed = 0;	drive_type.wake_up = unknown_wake_up;	drive_type.name = "Unknown";	timeout.seek = 650 * SECOND;	timeout.reset = 670 * SECOND;	timeout.rewind = 650 * SECOND;	timeout.head_seek = 15 * SECOND;	timeout.stop = 5 * SECOND;	timeout.pause = 16 * SECOND;	qic_std = -1;	tape_len = -1;	current_command = 0;	current_cylinder = -1;	segments_per_track = 102;	segments_per_head = 1020;	segments_per_cylinder = 4;	tracks_per_tape = 20;	ftape_failure = 1;	ftape_seg_pos = 0;	first_data_segment = -1;	ftape_state = idle;	no_tape = 1;	formatted = 0;	ftape_data_rate = 0;	going_offline = 0;	read_only = 0;	init_drive_needed = 1;	header_segment_1 = -1;	header_segment_2 = -1;	used_header_segment = -1;	location.track = -1;	location.known = 0;	tape_running = 0;	might_be_off_track = 1;	ftape_new_cartridge();	/* init some tape related variables */	ftape_init_bsm();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -