Exemplo n.º 1
0
/* This function calibrates the datarate (i.e. determines the maximal
 * usable data rate) and sets the global variable ft_qic_std to qic_std
 *
 */
int ftape_calibrate_data_rate(unsigned int qic_std)
{
	int rate = ft_fdc_rate_limit;
	int result;
	TRACE_FUN(ft_t_flow);

	ft_qic_std = qic_std;

	if (ft_qic_std == -1) {
		TRACE_ABORT(-EIO, ft_t_err,
		"Unable to determine data rate if QIC standard is unknown");
	}

	/*  Select highest rate supported by both fdc and drive.
	 *  Start with highest rate supported by the fdc.
	 */
	while (fdc_set_data_rate(rate) < 0 && rate > 250) {
		rate /= 2;
	}
	TRACE(ft_t_info,
	      "Highest FDC supported data rate: %d Kbps", rate);
	ft_fdc_max_rate = rate;
	do {
		result = ftape_set_data_rate(rate, ft_qic_std);
	} while (result == -EINVAL && (rate /= 2) > 250);
	if (result < 0) {
		TRACE_ABORT(-EIO, ft_t_err, "set datarate failed");
	}
	ft_data_rate = rate;
	TRACE_EXIT 0;
}
Exemplo n.º 2
0
int ftape_set_data_rate(unsigned int new_rate /* Kbps */, unsigned int qic_std)
{
	int status;
	int result = 0;
	unsigned int data_rate = new_rate;
	static int supported;
	int rate_changed = 0;
	qic_model dummy_model;
	unsigned int dummy_qic_std, dummy_tape_len;
	TRACE_FUN(ft_t_any);

	if (ft_drive_max_rate == 0) { /* first time */
		supported = ftape_set_rate_test(&ft_drive_max_rate);
	}
	if (supported) {
		ftape_command(QIC_SELECT_RATE);
		result = ftape_parameter_wait(qic_rate_code(new_rate),
					      1 * FT_SECOND, &status);
		if (result >= 0 && !(status & QIC_STATUS_ERROR)) {
			rate_changed = 1;
		}
	}
	TRACE_CATCH(result = ftape_report_configuration(&dummy_model,
							&data_rate, 
							&dummy_qic_std,
							&dummy_tape_len),);
	if (data_rate != new_rate) {
		if (!supported) {
			TRACE(ft_t_warn, "Rate change not supported!");
		} else if (rate_changed) {
			TRACE(ft_t_warn, "Requested: %d, got %d",
			      new_rate, data_rate);
		} else {
			TRACE(ft_t_warn, "Rate change failed!");
		}
		result = -EINVAL;
	}
	/*
	 *  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 && data_rate > 500) || 
	    (qic_std == QIC_TAPE_QIC80 && data_rate > 1000)) {
		TRACE_ABORT(-EINVAL,
			    ft_t_warn, "Datarate too high for QIC-mode");
	}
	TRACE_CATCH(fdc_set_data_rate(data_rate),_res = -EINVAL);
	ft_data_rate = data_rate;
	if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) {
		switch (data_rate) {
		case 250:
			fdc_set_write_precomp(250);
			break;
		default:
		case 500:
			fdc_set_write_precomp(125);
			break;
		case 1000:
			fdc_set_write_precomp(42);
			break;
		}
	} else {
		fdc_set_write_precomp(0);
	}
	TRACE_EXIT result;
}