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

📄 ftape-ctl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *      Copyright (C) 1993-1996 Bas Laarhoven, *                    1996-1997 Claus-Justus Heine. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING.  If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.c,v $ * $Revision: 1.4 $ * $Date: 1997/11/11 14:37:44 $ * *      This file contains the non-read/write ftape functions for the *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. */#include <linux/config.h>#include <linux/errno.h>#include <linux/mm.h>#include <linux/mman.h>#include <linux/ftape.h>#include <linux/qic117.h>#include <asm/uaccess.h>#include <asm/io.h>/* ease porting between pre-2.4.x and later kernels */#define vma_get_pgoff(v)      ((v)->vm_pgoff)#include "../lowlevel/ftape-tracing.h"#include "../lowlevel/ftape-io.h"#include "../lowlevel/ftape-ctl.h"#include "../lowlevel/ftape-write.h"#include "../lowlevel/ftape-read.h"#include "../lowlevel/ftape-rw.h"#include "../lowlevel/ftape-bsm.h"/*      Global vars. */ftape_info ftape_status = {/*  vendor information */	{ 0, },     /* drive type *//*  data rates */	500,        /* used data rate */	500,        /* drive max rate */	500,        /* fdc max rate   *//*  drive selection, either FTAPE_SEL_A/B/C/D */	-1,     /* drive selection *//*  flags set after decode the drive and tape status   */	0,          /* formatted */	1,          /* no tape */	1,          /* write protected */	1,          /* new tape *//*  values of last queried drive/tape status and error */	{{0,}},     /* last error code */	{{0,}},     /* drive status, configuration, tape status *//*  cartridge geometry */        20,         /* tracks_per_tape */        102,        /* segments_per_track *//*  location of header segments, etc. */	-1,     /* used_header_segment */	-1,     /* header_segment_1 */	-1,     /* header_segment_2 */	-1,     /* first_data_segment */        -1,     /* last_data_segment *//*  the format code as stored in the header segment  */	fmt_normal, /* format code *//*  the default for the qic std: unknown */	-1,/*  is tape running? */	idle,       /* runner_state *//*  is tape reading/writing/verifying/formatting/deleting */	idle,       /* driver state *//*  flags fatal hardware error */	1,          /* failure *//*  history record */	{ 0, }      /* history record */};	int ftape_segments_per_head     = 1020;int ftape_segments_per_cylinder = 4;int ftape_init_drive_needed = 1; /* need to be global for ftape_reset_drive()				  * in ftape-io.c				  *//*      Local vars. */static const vendor_struct vendors[] = QIC117_VENDORS;static const wakeup_method methods[] = WAKEUP_METHODS;const ftape_info *ftape_get_status(void){#if defined(STATUS_PARANOYA)	static ftape_info get_status;	get_status = ftape_status;	return &get_status;#else	return &ftape_status; /*  maybe return only a copy of it to assure 			       *  read only access			       */#endif}static int ftape_not_operational(int status){	/* return true if status indicates tape can not be used.	 */	return ((status ^ QIC_STATUS_CARTRIDGE_PRESENT) &		(QIC_STATUS_ERROR |		 QIC_STATUS_CARTRIDGE_PRESENT |		 QIC_STATUS_NEW_CARTRIDGE));}int ftape_seek_to_eot(void){	int status;	TRACE_FUN(ft_t_any);	TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);	while ((status & QIC_STATUS_AT_EOT) == 0) {		if (ftape_not_operational(status)) {			TRACE_EXIT -EIO;		}		TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD,					       ftape_timeout.rewind,&status),);	}	TRACE_EXIT 0;}int ftape_seek_to_bot(void){	int status;	TRACE_FUN(ft_t_any);	TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);	while ((status & QIC_STATUS_AT_BOT) == 0) {		if (ftape_not_operational(status)) {			TRACE_EXIT -EIO;		}		TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE,					       ftape_timeout.rewind,&status),);	}	TRACE_EXIT 0;}static int ftape_new_cartridge(void){	ft_location.track = -1; /* force seek on first access */	ftape_zap_read_buffers();	ftape_zap_write_buffers();	return 0;}int ftape_abort_operation(void){	int result = 0;	int status;	TRACE_FUN(ft_t_flow);	if (ft_runner_status == running) {		TRACE(ft_t_noise, "aborting runner, waiting");				ft_runner_status = do_abort;		/* set timeout so that the tape will run to logical EOT		 * if we missed the last sector and there are no queue pulses.		 */		result = ftape_dumb_stop();	}	if (ft_runner_status != idle) {		if (ft_runner_status == do_abort) {			TRACE(ft_t_noise, "forcing runner abort");		}		TRACE(ft_t_noise, "stopping tape");		result = ftape_stop_tape(&status);		ft_location.known = 0;		ft_runner_status  = idle;	}	ftape_reset_buffer();	ftape_zap_read_buffers();	ftape_set_state(idle);	TRACE_EXIT result;}static int lookup_vendor_id(unsigned int vendor_id){	int i = 0;	while (vendors[i].vendor_id != vendor_id) {		if (++i >= NR_ITEMS(vendors)) {			return -1;		}	}	return i;}static void ftape_detach_drive(void){	TRACE_FUN(ft_t_any);	TRACE(ft_t_flow, "disabling tape drive and fdc");	ftape_put_drive_to_sleep(ft_drive_type.wake_up);	fdc_catch_stray_interrupts(1);	/* one always comes */	fdc_disable();	fdc_release_irq_and_dma();	fdc_release_regions();	TRACE_EXIT;}static void clear_history(void){	ft_history.used = 0;	ft_history.id_am_errors =		ft_history.id_crc_errors =		ft_history.data_am_errors =		ft_history.data_crc_errors =		ft_history.overrun_errors =		ft_history.no_data_errors =		ft_history.retries =		ft_history.crc_errors =		ft_history.crc_failures =		ft_history.ecc_failures =		ft_history.corrected =		ft_history.defects =		ft_history.rewinds = 0;}static int ftape_activate_drive(vendor_struct * drive_type){	int result = 0;	TRACE_FUN(ft_t_flow);	/* If we already know the drive type, wake it up.	 * Else try to find out what kind of drive is attached.	 */	if (drive_type->wake_up != unknown_wake_up) {		TRACE(ft_t_flow, "enabling tape drive and fdc");		result = ftape_wakeup_drive(drive_type->wake_up);		if (result < 0) {			TRACE(ft_t_err, "known wakeup method failed");		}	} else {		wake_up_types method;		const ft_trace_t old_tracing = TRACE_LEVEL;		if (TRACE_LEVEL < ft_t_flow) {			SET_TRACE_LEVEL(ft_t_bug);		}		/*  Try to awaken the drive using all known methods.		 *  Lower tracing for a while.		 */		for (method=no_wake_up; method < NR_ITEMS(methods); ++method) {			drive_type->wake_up = method;#ifdef CONFIG_FT_TWO_DRIVES			/*  Test setup for dual drive configuration.			 *  /dev/rft2 uses mountain wakeup			 *  /dev/rft3 uses colorado wakeup			 *  Other systems will use the normal scheme.			 */			if ((ft_drive_sel < 2)                            ||			    (ft_drive_sel == 2 && method == FT_WAKE_UP_1) ||			    (ft_drive_sel == 3 && method == FT_WAKE_UP_2)) {				result=ftape_wakeup_drive(drive_type->wake_up);			} else {				result = -EIO;			}#else			result = ftape_wakeup_drive(drive_type->wake_up);#endif			if (result >= 0) {				TRACE(ft_t_warn, "drive wakeup method: %s",				      methods[drive_type->wake_up].name);				break;			}		}		SET_TRACE_LEVEL(old_tracing);		if (method >= NR_ITEMS(methods)) {			/* no response at all, cannot open this drive */			drive_type->wake_up = unknown_wake_up;			TRACE(ft_t_err, "no tape drive found !");			result = -ENODEV;		}	}	TRACE_EXIT result;}static 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;}static void ftape_log_vendor_id(void){	int vendor_index;	TRACE_FUN(ft_t_flow);	ftape_report_vendor_id(&ft_drive_type.vendor_id);	vendor_index = lookup_vendor_id(ft_drive_type.vendor_id);	if (ft_drive_type.vendor_id == UNKNOWN_VENDOR &&	    ft_drive_type.wake_up == wake_up_colorado) {		vendor_index = 0;		/* hack to get rid of all this mail */		ft_drive_type.vendor_id = 0;	}	if (vendor_index < 0) {		/* Unknown vendor id, first time opening device.  The		 * drive_type remains set to type found at wakeup		 * time, this will probably keep the driver operating		 * for this new vendor.  		 */		TRACE(ft_t_warn, "\n"		      KERN_INFO "============ unknown vendor id ===========\n"		      KERN_INFO "A new, yet unsupported tape drive is found\n"		      KERN_INFO "Please report the following values:\n"		      KERN_INFO "   Vendor id     : 0x%04x\n"		      KERN_INFO "   Wakeup method : %s\n"		      KERN_INFO "And a description of your tape drive\n"		      KERN_INFO "to "THE_FTAPE_MAINTAINER"\n"		      KERN_INFO "==========================================",		      ft_drive_type.vendor_id,		      methods[ft_drive_type.wake_up].name);		ft_drive_type.speed = 0;		/* unknown */	} else {		ft_drive_type.name  = vendors[vendor_index].name;		ft_drive_type.speed = vendors[vendor_index].speed;		TRACE(ft_t_info, "tape drive type: %s", ft_drive_type.name);		/* scan all methods for this vendor_id in table */		while(ft_drive_type.wake_up != vendors[vendor_index].wake_up) {			if (vendor_index < NR_ITEMS(vendors) - 1 &&			    vendors[vendor_index + 1].vendor_id 			    == 			    ft_drive_type.vendor_id) {				++vendor_index;			} else {				break;			}		}		if (ft_drive_type.wake_up != vendors[vendor_index].wake_up) {			TRACE(ft_t_warn, "\n"		     KERN_INFO "==========================================\n"		     KERN_INFO "wakeup type mismatch:\n"		     KERN_INFO "found: %s, expected: %s\n"		     KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n"		     KERN_INFO "==========================================",			      methods[ft_drive_type.wake_up].name,			      methods[vendors[vendor_index].wake_up].name);		}	}	TRACE_EXIT;}void ftape_calc_timeouts(unsigned int qic_std,			 unsigned int data_rate,			 unsigned int tape_len){	int speed;		/* deci-ips ! */	int ff_speed;	int length;	TRACE_FUN(ft_t_any);	/*                           tape transport speed	 *  data rate:        QIC-40   QIC-80   QIC-3010 QIC-3020	 *	 *    250 Kbps        25 ips     n/a      n/a      n/a	 *    500 Kbps        50 ips   34 ips   22.6 ips   n/a	 *      1 Mbps          n/a    68 ips   45.2 ips 22.6 ips	 *      2 Mbps          n/a      n/a      n/a    45.2 ips	 *	 *  fast tape transport speed is at least 68 ips.

⌨️ 快捷键说明

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