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

📄 ftape-io.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		TRACE(2, "warning: error status set!");		result = 1;	}	TRACE_EXIT;	return result;}int ftape_report_error(int *error, int *command, int report){	TRACE_FUN(8, "ftape_report_error");	int code;	int result;	result = ftape_report_operation(&code, QIC_REPORT_ERROR_CODE, 16);	if (result < 0) {		result = -EIO;	} else {		*error = code & 0xff;		*command = (code >> 8) & 0xff;		if (report) {			if (*error != 0) {				TRACEi(3, "errorcode:", *error);			} else {				TRACE(3, "No error");			}		}		if (report && *error != 0 && tracing > 3) {			if (*error >= 0 && *error < NR_ITEMS(ftape_errors)) {				TRACEx1(-1, "%sFatal ERROR:",					(ftape_errors[*error].fatal ? "" : "Non-"));				TRACEx1(-1, "%s ...", ftape_errors[*error].message);			} else {				TRACE(-1, "Unknown ERROR !");			}			if (*command >= 0 && *command < NR_ITEMS(qic117_cmds) &&			    qic117_cmds[*command].name != NULL) {				TRACEx1(-1, "... caused by command \'%s\'",					qic117_cmds[*command].name);			} else {				TRACEi(-1, "... caused by unknown command", *command);			}		}	}	TRACE_EXIT;	return result;}int ftape_in_error_state(int status){	TRACE_FUN(8, "ftape_in_error_state");	int result = 0;	if ((status & QIC_STATUS_READY) && (status & QIC_STATUS_ERROR)) {		TRACE(2, "warning: error status set!");		result = 1;	}	TRACE_EXIT;	return result;}static int ftape_report_configuration(qic_model * model, int *rate,				      int *qic_std, int *tape_len){	int result;	int config;	int status;	TRACE_FUN(8, "ftape_report_configuration");	result = ftape_report_operation(&config, QIC_REPORT_DRIVE_CONFIGURATION, 8);	if (result < 0) {		*model = prehistoric;		*rate = QIC_CONFIG_RATE_500;		*qic_std = QIC_TAPE_QIC40;		*tape_len = 205;		result = 0;	} else {		*rate = (config & QIC_CONFIG_RATE_MASK) >> QIC_CONFIG_RATE_SHIFT;		result = ftape_report_operation(&status, QIC_REPORT_TAPE_STATUS, 8);		if (result < 0) {			/* pre- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is valid.			 */			*qic_std = (config & QIC_CONFIG_80) ? QIC_TAPE_QIC80 : QIC_TAPE_QIC40;			*tape_len = (config & QIC_CONFIG_LONG) ? 307 : 205;			*model = pre_qic117c;			result = 0;		} else {			*model = post_qic117b;			TRACEx1(8, "report tape status result = %02x", status);			/* post- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is invalid.			 */			switch (status & QIC_TAPE_STD_MASK) {			case QIC_TAPE_QIC40:			case QIC_TAPE_QIC80:			case QIC_TAPE_QIC3020:			case QIC_TAPE_QIC3010:				*qic_std = status & QIC_TAPE_STD_MASK;				break;			default:				*qic_std = -1;				break;			}			switch (status & QIC_TAPE_LEN_MASK) {			case QIC_TAPE_205FT:				/* Unfortunately the new QIC-117 rev G standard shows				 * no way to discriminate between 205 and 425 ft tapes.				 * The obvious way seems not to be used: the QIC_CONFIG_LONG				 * bit isn't used for this (on all drives ?).				 */				if (config & QIC_CONFIG_LONG) {					*tape_len = 425;	/* will this ever execute ??? */				} else {					*tape_len = 0;	/* length unknown: 205 or 425 ft. */				}				break;			case QIC_TAPE_307FT:				*tape_len = 307;				break;			case QIC_TAPE_400FT:				/*				 * Trouble! Iomega Ditto 800 and Conner TST800R drives reports				 * 400ft for 750ft tapes. Yuck, yuck, yuck.  Since the value				 * is only used to compute a timeout value, the largest of the				 * two is used.				 */				*tape_len = 750;	/* either 400 or 750 ft. */				break;			case QIC_TAPE_1100FT:				*tape_len = 1100;				break;			case QIC_TAPE_FLEX:				*tape_len = 0;				break;			default:				*tape_len = -1;				break;			}			if (*qic_std == -1 || *tape_len == -1) {				TRACE(2, "post qic-117b spec drive with unknown tape");				result = -EIO;			} else {				result = 0;			}		}	}	TRACE_EXIT;	return (result < 0) ? -EIO : 0;}int ftape_report_rom_version(int *version){	int result;	result = ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8);	return (result < 0) ? -EIO : 0;}int ftape_report_signature(int *signature){	int result;	result = ftape_command(28);	result = ftape_report_operation(signature, 9, 8);	result = ftape_command(30);	return (result < 0) ? -EIO : 0;}void ftape_report_vendor_id(unsigned int *id){	TRACE_FUN(8, "ftape_report_vendor_id");	int result;	/*	 *    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 {				TRACEx1(4, "got old 8 bit id: %04x", *id);				*id |= 0x20000;			}		} else {			TRACEx1(4, "got 8 bit id: %04x", *id);			*id |= 0x10000;		}	} else {		TRACEx1(4, "got 16 bit id: %04x", *id);	}	if (*id == 0x0047) {		int version;		int sign;		result = ftape_report_rom_version(&version);		if (result < 0) {			TRACE(-1, "report rom version failed");			TRACE_EXIT;			return;		}		TRACEx1(4, "CMS rom version: %d", version);		ftape_command(QIC_ENTER_DIAGNOSTIC_1);		ftape_command(QIC_ENTER_DIAGNOSTIC_1);		result = ftape_report_operation(&sign, 9, 8);		if (result < 0) {			int error, command;			ftape_report_error(&error, &command, 1);			ftape_command(QIC_ENTER_PRIMARY_MODE);			TRACE_EXIT;			return;	/* faalt hier ! */		} else {			TRACEx1(4, "CMS signature: %02x", sign);		}		if (sign == 0xa5) {			result = ftape_report_operation(&sign, 37, 8);			if (result < 0) {				if (version >= 63) {					*id = 0x8880;					TRACE(4, "This is an Iomega drive !");				} else {					*id = 0x0047;					TRACE(4, "This is a real CMS drive !");				}			} else {				*id = 0x0047;				TRACEx1(4, "CMS status: %d", sign);			}		} else {			*id = UNKNOWN_VENDOR;		}		ftape_command(QIC_ENTER_PRIMARY_MODE);	}	TRACE_EXIT;}void ftape_set_rate_test(int *supported){	TRACE_FUN(8, "ftape_set_rate_test");	int error;	int command;	int i;	int result;	int status;	/*  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.	 */	*supported = 0;	for (i = 0; i < NR_ITEMS(rates); ++i) {		result = ftape_command(QIC_SELECT_RATE);		if (result >= 0) {			result = ftape_parameter_wait(rates[i].drive_code,						    1 * SECOND, &status);			if (result >= 0) {				if (status & QIC_STATUS_ERROR) {					result = ftape_report_error(&error, &command, 0);				} else {					*supported = 1;		/* did accept a request */				}			}		}	}	TRACEx1(4, "Select Rate command is%s supported",		*supported ? "" : " not");	TRACE_EXIT;}int ftape_set_data_rate(int new_rate){	TRACE_FUN(8, "ftape_set_data_rate");	int status;	int result;	int data_rate;	qic_model model;	int supported;	static int first_time = 1;	if (first_time) {		ftape_set_rate_test(&supported);		first_time = 0;	}	if (rates[new_rate].fdc_code == -1) {		TRACEx1(4, "%sb/s data rate not supported by the fdc",			rates[new_rate].text);		result = -EINVAL;	} else {		int error = 0;		int command;		result = ftape_command(QIC_SELECT_RATE);		if (result >= 0) {			result = ftape_parameter_wait(rates[new_rate].drive_code,						    1 * SECOND, &status);			result = ftape_report_raw_drive_status(&status);			if (result >= 0 && (status & QIC_STATUS_ERROR)) {				result = ftape_report_error(&error, &command, 0);				if (result >= 0 && supported &&				    error == 31 && command == QIC_SELECT_RATE) {					result = -EINVAL;				}			}		}		if (result >= 0) {			result = ftape_report_configuration(&model, &data_rate,						    &qic_std, &tape_len);			if (result >= 0 && data_rate != rates[new_rate].drive_code) {				result = -EINVAL;			}		}		if (result < 0) {			TRACEx1(4, "could not set %sb/s data rate", rates[new_rate].text);		} else {			TRACEx2(2, "%s drive @ %sb/s",				(model == prehistoric) ? "prehistoric" :				((model == pre_qic117c) ? "pre QIC-117C" :				 ((model == post_qic117b) ? "post QIC-117B" : "post QIC-117D")),				rates[new_rate].text);			if (tape_len == 0) {				TRACEx1(2, "unknown length QIC-%s tape",				     (qic_std == QIC_TAPE_QIC40) ? "40" :				    ((qic_std == QIC_TAPE_QIC80) ? "80" :				     ((qic_std == QIC_TAPE_QIC3010) ? "3010" : "3020")));			} else {				TRACEx2(2, "%d ft. QIC-%s tape",					tape_len,				     (qic_std == QIC_TAPE_QIC40) ? "40" :				    ((qic_std == QIC_TAPE_QIC80) ? "80" :				     ((qic_std == QIC_TAPE_QIC3010) ? "3010" : "3020")));			}			/*			 *  Set data rate and write precompensation as specified:			 *			 *            |  QIC-40/80  | QIC-3010/3020			 *   rate     |   precomp   |    precomp			 *  ----------+-------------+--------------			 *  250 Kbps. |   250 ns.   |     0 ns.			 *  500 Kbps. |   125 ns.   |     0 ns.			 *    1 Mbps. |    42 ns.   |     0 ns.			 *    2 Mbps  |      N/A    |     0 ns.			 */			if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) {				fdc_set_write_precomp(rates[new_rate].precomp);			} else {				fdc_set_write_precomp(0);			}			fdc_set_data_rate(rates[new_rate].fdc_code);			ftape_data_rate = new_rate;	/* store rate set */		}	}	if (result < 0 && result != -EINVAL) {		result = -EIO;	}	TRACE_EXIT;	return result;}/*      Seek the head to the specified track. */int ftape_seek_head_to_track(int track){	TRACE_FUN(8, "ftape_seek_head_to_track");	int status;	int result;	location.track = -1;	/* remains set in case of error */	if (track < 0 || track >= tracks_per_tape) {		TRACE(-1, "track out of bounds");		result = -EINVAL;	} else {		TRACEx1(5, "seeking track %d", track);		result = ftape_command(QIC_SEEK_HEAD_TO_TRACK);		if (result < 0) {			TRACE(1, "ftape_command failed");		} else {			result = ftape_parameter_wait(track, timeout.head_seek, &status);			if (result < 0) {				TRACE(1, "ftape_parameter_wait failed");			} else {				location.track = track;				might_be_off_track = 0;			}		}	}	TRACE_EXIT;	return result;}int ftape_wakeup_drive(wake_up_types method){	TRACE_FUN(8, "ftape_wakeup_drive");	int result;	int status;	int motor_on = 0;	switch (method) {	case wake_up_colorado:		result = ftape_command(QIC_PHANTOM_SELECT);		if (result == 0) {			result = ftape_parameter( /* unit */ 0);		}		break;	case wake_up_mountain:		result = ftape_command(QIC_SOFT_SELECT);		if (result == 0) {			ftape_sleep(MILLISECOND);	/* NEEDED */			result = ftape_parameter(18);		}		break;	case wake_up_insight:		ftape_sleep(100 * MILLISECOND);		motor_on = 1;		fdc_motor(motor_on);	/* enable is done by motor-on */	case no_wake_up:		result = 0;		break;	default:		result = -ENODEV;	/* unknown wakeup method */	}	/*  If wakeup succeeded we shouldn't get an error here..	 */	if (result == 0) {		result = ftape_report_raw_drive_status(&status);		if (result < 0 && motor_on) {			fdc_motor(0);	/* motor off if failed */		}	}	TRACE_EXIT;	return result;}int ftape_put_drive_to_sleep(vendor_struct drive_type){	TRACE_FUN(8, "ftape_put_drive_to_sleep");	int result;	switch (drive_type.wake_up) {	case wake_up_colorado:		result = ftape_command(QIC_PHANTOM_DESELECT);		break;	case wake_up_mountain:		result = ftape_command(QIC_SOFT_DESELECT);		break;	case wake_up_insight:		fdc_motor(0);	/* enable is done by motor-on */	case no_wake_up:	/* no wakeup / no sleep ! */		result = 0;		break;	default:		result = -ENODEV;	/* unknown wakeup method */	}	TRACE_EXIT;	return result;}int ftape_reset_drive(void){	TRACE_FUN(8, "ftape_reset_drive");	int result = 0;	int status;	int err_code;	int err_command;	int i;	/*    We want to re-establish contact with our drive.	 *    Fire a number of reset commands (single step pulses)	 *    and pray for success.	 */	for (i = 0; i < 2; ++i) {		TRACE(5, "Resetting fdc");		fdc_reset();		ftape_sleep(10 * MILLISECOND);		TRACE(5, "Reset command to drive");		result = ftape_command(QIC_RESET);		if (result == 0) {			ftape_sleep(1 * SECOND);	/* drive not accessible during 1 second */			TRACE(5, "Re-selecting drive");			/*  Strange, the QIC-117 specs don't mention this but the			 *  drive gets deselected after a soft reset !			 *  So we need to enable it again.			 */			result = ftape_wakeup_drive(drive_type.wake_up);			if (result < 0) {				TRACE(1, "Wakeup failed !");			}			TRACE(5, "Waiting until drive gets ready");			result = ftape_ready_wait(timeout.reset, &status);			if (result == 0 && status & QIC_STATUS_ERROR) {				result = ftape_report_error(&err_code, &err_command, 1);				if (result == 0 && err_code == 27) {					/* Okay, drive saw reset command and responded as it should					 */					break;				} else {					result = -EIO;				}			} else {				result = -EIO;			}		}		if (current->signal & _DONT_BLOCK) {			TRACE(1, "aborted by non-blockable signal");			result = -EINTR;			break;	/* exit on signal */		}	}	if (result != 0) {		TRACE(1, "General failure to reset tape drive");	} else {		/*  Restore correct settings		 */		ftape_set_data_rate(ftape_data_rate);	/* keep original rate */	}	TRACE_EXIT;	return result;}

⌨️ 快捷键说明

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