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

📄 scsi_tape.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)scsi_tape.c	4.6  (ULTRIX)        1/22/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1984,86,87,88,89 by		* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any	other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived	from  software	received  from	the	* *   University    of	California,   Berkeley,   and	from   Bell	* *   Laboratories.  Use, duplication, or disclosure is	subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or	reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ * * scsi_tape.c	23_Jun-89 * * VAX SCSI device driver (tape routines) * * Modification history: * *  08-Jan-91	Robin Miller *	Modified DEVIOCGET ioctl() code to properly return tape density *	codes.  To resolve this problem, the density_table[] was defined *	to decode the mode sense density code, and additional code was *	added to return default density codes. * *  15-Nov-90	Robin Miller *	Removed clearing of the DEV_TPMARK flag in tzstrategy() for nbuf *	I/O requests (B_RAWASYNC).  This caused a race condition with code *	in the SCSI state machine with outstanding read requests.  This *	problem caused the queued reads to read past the tape file mark. * *  21-Sept-90	Bill Dallas *	Fixed 2 problems with the devget ioctl. *	Problem one caused a panic if someone made a minor *	number by hand (aka mknod) which was out side the *	controllers range. The second problem was minor, *	we never gave back to the user the lower 4 bits *	of the devget.category_stat field. * *  30-Jul-90	Bill Dallas    *	Added fixed block tape units tape mark handling. *	This included a new falg in sc_category_flags called *	TPMARK_PENDING * *  13-Nov-89   Janet Schank *      Changed the refrence of nNSCSI to nNSCSIBUS. * *  08-Oct-89	Fred Canter *	Bump TZ30 minium revision level to 11. It should be 12, but *	we never received rev 12 drives to test. *	Remove #ifdef OLDWAY. * *  01-Oct-89	Fred Canter *	Bug fix. Tapes were not reporting write locked status via the *	devioget ioctl. * *  24-Jul-89	Fred Canter *	Bug fix for dump (MT CACHE ioctls not supported by SCSI). * *  16-Jul-89	Fred Canter *	Changed meaning of count field for MODSNS tzcommand/rzcommand. * *  23-Jun-89	John A. Gallant *	Added the tape command completion routine. * *  19-Jun-89	Fred Canter *	Convert to scsi_devtab. * * 13-Jun-89	Fred Canter *	Added MTFLUSH to tzioctl (always returns ENXIO). * * 06-Apr-89	Fred Canter *	Added TZxx (EXABYTE) support. Cannot count on TZxx drives *	supporting the receive diagnostic results command. * *	Added b_comand to replace b_command for local command buffers. *	Use b_gid instead of b_resid to store command. * *	Added debug code to allow mode sense before tape open. * * 12-Feb-89	Fred Canter *	Added function header comments to each routine. * *  5-Feb-89	Fred Canter *	Added tz_tz30_minrev and tz_tzk50_minrev so minimum firmware *	revision levels for tapes can be changed with adb. * * 14-Jan-89	Fred Canter *	Clear sc_category_flags in tzopen() so left over DEV_TPMARK *	does not casue drive to fail all commands after encountering *	a tape mark. *	Fixed a bug which caused a space command (via ioctl) to *	space over a tape mark without failing (as it should). *	In tzioctl(), fail the ioctl if DEV_TPMARK set. *	Update minimum firmware revision for the TZK50 to 45. * * 28-Dec-88	Fred Canter *	Changed stops to tzops in tzioctl, for consistency. * * 18-Dec-88	Fred Canter *	Fixed (as best I could) info returned for MTIOCGET ioctl *	(mt status). So MTX can handle EOT on SCSI tapes. * * 17-Dec-88	Fred Canter *	Added pseudo commands to resolve the conflict between *	SZ_UNLOAD and SZ_SSUNIT both being opcode 0x1b. * * 16-Oct-88	Fred Canter *	Clean up comments. * * 28-Sep-88	Fred Canter *	Clean up comments. * * 21-Aug-88	Fred Canter *	Fixed a bug which caused the magtape exerciser MTIOCTOP ioctl *	to fail. Check status and sense key after ioctl. * * 17-Aug-88	Fred Canter *	Created this file by moving the SCSI tape specific files *	from the old combined driver (scsi.c) to scsi_tape.c. * ***********************************************************************/#include "scsi.h"#include "sii.h"#if NSCSI > 0 || NSII > 0 || defined(BINARY)#include "../data/scsi_data.c"#include "scsi_debug.h"/* * Define the tape density table. */static int density_table[] = {	0,				/* 0x00 - Default density.	*/	DEV_800BPI,			/* 0x01 - 800 BPI   (NRZI, R)	*/	DEV_1600BPI,			/* 0x02 - 1600 BPI  (PE, R)	*/	DEV_6250BPI,			/* 0x03 - 6250 BPI  (GCR, R)	*/	DEV_8000_BPI,			/* 0x04 - 8000 BPI  (GCR, C)	*/	DEV_8000_BPI,			/* 0x05 - 8000 BPI  (GCR, C)	*/	0,				/* 0x06 - 3200 BPI  (PE, R)	*/	0,				/* 0x07 - 6400 BPI  (IMFM, C)	*/	DEV_8000_BPI,			/* 0x08 - 8000 BPI  (GCR, CS)	*/	DEV_38000BPI,			/* 0x09 - 37871 BPI (GCR, C)	*/	DEV_6666BPI,			/* 0x0A - 6667 BPI  (MFM, C)	*/	DEV_1600BPI,			/* 0x0B - 1600 BPI  (PE, C)	*/	0,				/* 0x0C - 12690 BPI (GCR, C)	*/	DEV_10000_BPI,			/* 0x0D - QIC-120 with ECC.	*/	DEV_10000_BPI,			/* 0x0E - QIC-150 with ECC.	*/	DEV_10000_BPI,			/* 0x0F - QIC-120   (GCR, C)	*/	DEV_10000_BPI,			/* 0x10 - QIC-150   (GCR, C)	*/	DEV_16000_BPI,			/* 0x11 - QIC-320   (GCR, C)	*/	0,				/* 0x12 - QIC-1350  (RLL, C)	*/	DEV_61000_BPI,			/* 0x13 - 4mm Tape  (DDS, CS)	*/	DEV_54000_BPI			/* 0x14 - 8mm Tape  (???, CS)	*/};static int density_entrys = sizeof(density_table) / sizeof(int);/* * TODO: *	Temporary(?) debug variable. *	If nonzero, SZ_NODEVICE is returned from tz_rcvdiag() *	if the tape fails self test or its firmware revision *	level is too far out of date. *	If zero, tz_rcvdiag() results are ignored. */int sz_open_fst = 1;int	wakeup();extern int hz;extern int sz_unit_rcvdiag[];	/* If zero, need unit's selftest status *//* * Unit on line flag. Set to one if the * device is on-line. Set to zero on any unit * attention condition. */extern int sz_unit_online[];/* * * Name:		tzopen		-Tape open routine * * Abstract:		This routine is called each time a tape device *			is opened. This routine: makes sure the device *			exists, checks for device on-line via test unit *			ready, and does a mode select (sets buffered mode). *			On the first call, a receive diagnostic results *			command is done to make sure the tape drive is ok. * * Inputs: * * dev			ULTRIX major/minor device number. * flag			How to open flag (read, write, NDELAY). * * Outputs: *			Possible error messages (eg, device off-line). *			sz_unit_online flag set. *			Exclusive use flag (sc_openf) flag set. * * Return Values: * * ENXIO		No such device or address (non extistent device). * EIO			I/O error (device off-line, etc). * 0			Open succeeded. * * Side Effects: *			tzcommand() called. *			sleep() called. * */tzopen(dev, flag)	register dev_t dev;	register int flag;{	register struct uba_device *ui;	register struct sz_softc *sc;	int unit = UNIT(dev);	int cntlr;	int targid;	int retry = 0;	int retval;	int dev_ready;	struct sz_modsns_dt *sdp;	/*	 * Order of following checks is important.	 */	if (unit >= nNSZ)	    return(ENXIO);	ui = szdinfo[unit];	if ((ui == 0) || (ui->ui_alive == 0))	    return(ENXIO);	cntlr = ui->ui_ctlr;	if (cntlr >= nNSCSIBUS)	    return(ENXIO);	targid = ui->ui_slave;	sc = &sz_softc[cntlr];	if (sc->sc_alive[targid] == 0 || sc->sc_openf[targid])	    return (ENXIO);	if ((sc->sc_devtyp[targid] & SZ_TAPE) == 0)	    return(ENXIO);	/*	 * This is a strange use of the FNDELAY flag.  It	 * is here to allow the installation finder program	 * to open the device when the tape cartridge is not	 * inserted.  The installation finder program needs	 * to do an ioctl, so open must succeed whether or	 * not a cartridge is present.	 */	/*	 * Clear sc_flags, device will lockup after any	 * hard error (DEV_HARDERR set) if we don't.	 * TODO: other drivers look at dis_eot_??[]!	 */	sc->sc_flags[targid] = 0;	sc->sc_category_flags[targid] = 0;	sc->sc_szflags[targid] &= ~SZ_NODEVICE;	/*	 * Get selftest result, if we haven't already.	 * The tz_rcvdiag() routine will return	 * SZ_NODEVICE if anything is wrong.	 *	 * Fix for the nodiag flag in devtab..Some units	 * must have a senddiag cmd before a recvdiag cmd  	 * or data is garbage for the recv diag cmd. We 	 * will just look at the NO_DIAG flag in the devtab	 * struct for this type unit.	 */	if ((sz_unit_rcvdiag[unit] == 0) && 		((sc->sc_devtab[targid]->flags & SCSI_NODIAG) == 0))	    {	    sc->sc_szflags[targid] |= tz_rcvdiag(dev);	}	/*	 * Try to bring the drive on line.	 * The TZK50 takes about 25 seconds come ready after	 * a cartridge change. The TZ30 takes about 30 seconds.	 * So, we try for 40 seconds to bring the drive on-line.	 * This allows the user some think time to realize the	 * tape is off-line and load the cartridge.	 */	dev_ready = 0;	for (retry = 0; retry < 20; retry++) {	    if (sc->sc_szflags[targid] & SZ_NODEVICE) {		if (flag & FNDELAY)		    break;		else		    return(ENXIO);	    }	    tzcommand(dev, SZ_TUR, 1, 0);	    if (sc->sc_c_status[targid] == SZ_GOOD) {		dev_ready = 1;		break;	    }	    else if (sc->sc_c_status[targid] == SZ_BAD) {		continue;	    }	    else if (sc->sc_c_status[targid] == SZ_CHKCND) {		retval = SZ_RETRY;		switch(sc->sc_c_snskey[targid]) {		case SZ_NOSENSE:		case SZ_RECOVERR:		    retval = SZ_SUCCESS;		    dev_ready = 1;		    break;		case SZ_NOTREADY:		    timeout(wakeup, (caddr_t)&sc->sc_alive[targid], (hz*2));		    sleep((caddr_t)&sc->sc_alive[targid], PZERO + 1);		    if (!(sc->sc_flags[targid] & DEV_EOM)) {			sc->sc_flags[targid] = 0;		    }		    break;		case SZ_UNITATTEN:		    sz_unit_online[unit] = 0;		    /* just retry */		    break;		default:		    /* TODO: may want to retry? */		    if (!(sc->sc_flags[targid] & DEV_EOM)) {			sc->sc_flags[targid] = 0;		    }		    if(flag & FNDELAY) {			sc->sc_szflags[targid] |= SZ_NODEVICE;			retval = SZ_SUCCESS;		    }		    else {			return(ENXIO);		    }		    break;		}	/* end of switch */		if (retval == SZ_SUCCESS)		    break;		/* from for loop */		else		    continue;		/* with for loop */	    }	    else {		/* TODO: debug */		printf("tzopen: impossible sc_c_status (val=%d)\n",		    sc->sc_c_status[targid]);		continue;	/* retry */	    }	}	/* end for loop */	if (retry >= 20) {	    if (!(flag & FNDELAY)) {	    	DEV_UGH(sc->sc_device[targid], unit, "offline");	    	return(EIO);	    }	}	/*	 * If SZ_NODEVICE is not set, the device exists,	 * and we want to do a SZ_MODSEL command	 */	if (!(sc->sc_szflags[targid] & SZ_NODEVICE)) {	    if (tz_exabyte_modsns) {		tzcommand(dev, SZ_MODSNS, -1, 0);		if (sc->sc_c_status[targid] != SZ_GOOD)		    printf("tzopen: %s unit %d: mode sense failed\n",			sc->sc_device[targid], unit);		sdp = (struct sz_modsns_dt *)&sc->sz_dat[targid];		printf("vu = 0x%x, mt = 0x%x, rt = 0x%x\n", sdp->vulen,			sdp->pad[0], sdp->pad[1]);	    }	    for (retry = 0; retry < 5; retry++) {		tzcommand(dev, SZ_MODSEL, 1, 0);		if (sc->sc_c_status[targid] == SZ_GOOD)		    break;	    }	    if ((retry >= 5) && ((flag & FNDELAY) == 0)) {		printf("tzopen: %s unit %d: mode select failed\n",		    sc->sc_device[targid], unit);		return(EIO);	    }	}	/* So open nodelay doesn't falsely set on-line! */	if (dev_ready)	    sz_unit_online[unit] = 1;	sc->sc_openf[targid] = 1;	return (0);}int	tz_tz30_minrev = 11;	/* Minimum TZ30 firmware revision */int	tz_tzk50_minrev = 45;	/* Minimum TZK50 firmware revision *//* * * Name:		tz_rcvdiag	-Receive diagnostic results * * Abstract:		This routine executes a receive diagnostic results *			command for the specified tape drive, and uses *			the results to determine if the tape exists, *			is up to minimum firmware revision, and passed *			self test. * * Inputs: * * dev			ULTRIX major/minor device number. * * Outputs: *			sz_unit_rcvdiag flag set. *			Possible firmware revision level warning message. *			Possible error message (receive diagnostics failed). * * Return Values: * * SZ_NODEVICE		Tape drive does not exist or failed self test. * SZ_SUCCESS		Tape exists and is operational. *

⌨️ 快捷键说明

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