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

📄 scsi_tape.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
 *			physio() and tzstrategy() called. *			minphys() limits maximum transfer size. * */tzwrite(dev, uio)	register dev_t dev;	register struct uio *uio;{	int unit = UNIT(dev);	return (physio(tzstrategy, &rszbuf[unit], dev, B_WRITE, minphys, uio));}/* TODO: debug (too handy to remove) */int	tz_sk_print = 0;/* * * Name:		tzioctl		-Tape ioctl routine * * Abstract:		This routine is called via the ioctl system call *			to perform various non data transfer functions, *			such as MTIOCTOP (magtape operation). * * Inputs: * * dev			ULTRIX major/minor device number. * cmd			The ioctl to execute. * data			Pointer to data bassed with ioctl. * flag			Flag passed with ioctl. * * Outputs: *			Some ioctls pass data back to the caller. *			Possible device off-line error message. * * Return Values: * * EINVAL		Invalid argument to ioctl. * ENXIO		Non supported ioctl. * 0			Success. * * Side Effects: *			Several other routines called. * */tzioctl(dev, cmd, data, flag)	dev_t dev;	register int cmd;	caddr_t data;	int flag;{	register struct uba_device *ui;	int unit = UNIT(dev);	int cntlr;	int targid;	register struct sz_softc *sc;	register int callcount;	register int fcount;	struct mtop *mtop;	struct mtget *mtget;	struct devget *devget;	struct sz_modsns_dt *msdp;	 struct scsi_devtab *sdp;        struct tape_opt_tab *todp;        /* we depend of the values and order of the MT codes here         * static tzops[] = { SZ_WFM,SZ_P_FSPACEF,SZ_P_BSPACEF,SZ_P_FSPACER,         *                 SZ_P_BSPACER,SZ_REWIND,SZ_P_UNLOAD,SZ_P_CACHE,         *                 SZ_P_NOCACHE,SZ_RQSNS };        */#define SZ_SZNOP SZ_INQ        /* we depend on the values and order of the MT codes here */        static tzops[] = { SZ_WFM,SZ_P_FSPACEF,SZ_P_BSPACEF,SZ_P_FSPACER,                        /* MTWEOF    MTFSF       MTBSF       MTFSR      */                           SZ_P_BSPACER,SZ_REWIND,SZ_P_UNLOAD,SZ_SZNOP,                        /* MTBSR          MTREW     MTOFFL     MTNOP    */                           SZ_P_CACHE,SZ_P_NOCACHE,SZ_RQSNS,SZ_RQSNS,                        /* MTCACHE    MTNOCACHE    MTCSE    MTCLX       */                           SZ_RQSNS,SZ_SZNOP,SZ_SZNOP,SZ_SZNOP,SZ_SZNOP,SZ_SZNOP,                        /* MTCLS  MTENAEOT MTDISEOT MTFLUSH MTGTON MTGTOFF */                           SZ_P_RETENSION};                        /* MTRETEN */	ui = szdinfo[unit];	cntlr = ui->ui_ctlr;	targid = ui->ui_slave;	sc = &sz_softc[cntlr];	sdp = (struct scsi_devtab *)sc->sc_devtab[targid];		/* 	 * get our tape option struct if available	*/	if( sdp->opt_tab != NULL){	    todp = (struct tape_opt_tab *)sdp->opt_tab;	}	switch (cmd) {	case MTIOCTOP:				/* tape operation */		/* 		 * If SZ_NODEVICE is set, the device was opened		 * with FNDELAY, but the device didn't respond.		 * We'll try again to see if the device is here,		 * if it is not, return an error		 */		if (sc->sc_szflags[targid] & SZ_NODEVICE) {		    DEV_UGH(sc->sc_device[targid],unit,"offline");		    return(ENXIO);		}		mtop = (struct mtop *)data;		switch (mtop->mt_op) {		case MTWEOF:			callcount = 1;			if( sc->sc_category_flags[targid] & TPMARK_PENDING){			    fcount = mtop->mt_count - 1;			    sc->sc_category_flags[targid] &= ~TPMARK_PENDING;			}			else {			    fcount = mtop->mt_count;			}			break;		case MTFSF: 			callcount = 1;			if( sc->sc_category_flags[targid] & TPMARK_PENDING){			    fcount = mtop->mt_count - 1;			    if (fcount < 0 ){				fcount = 0;			    }			    if( fcount == 0){				sc->sc_category_flags[targid] &= ~TPMARK_PENDING;				sc->sc_category_flags[targid] |= DEV_TPMARK;			    }			    else {				sc->sc_category_flags[targid] &= ~TPMARK_PENDING;			    }			}			else {			    fcount = mtop->mt_count;			}			break;		case MTBSF:			callcount = 1;			if( sc->sc_category_flags[targid] & TPMARK_PENDING){			    fcount = mtop->mt_count + 1;			    sc->sc_category_flags[targid] &= ~TPMARK_PENDING;			}			else {			    fcount = mtop->mt_count;			}			break;		case MTFSR:			callcount = 1;			if( sc->sc_category_flags[targid] & TPMARK_PENDING){			    fcount = mtop->mt_count - 1;			    if (fcount < 0 ){				fcount = 0;			    }			    if( fcount == 0){				sc->sc_category_flags[targid] &= ~TPMARK_PENDING;				sc->sc_category_flags[targid] |= DEV_TPMARK;			    }			    else {				sc->sc_category_flags[targid] &= ~TPMARK_PENDING;			    }			}			else {			    fcount = mtop->mt_count;			}			break;		case MTBSR:			callcount = 1;			if( sc->sc_category_flags[targid] & TPMARK_PENDING){			    fcount = mtop->mt_count + 1;			    sc->sc_category_flags[targid] &= ~TPMARK_PENDING;			}			else {			    fcount = mtop->mt_count;			}			break;		case MTOFFL:			sc->sc_flags[targid] |= DEV_OFFLINE;			sc->sc_category_flags[targid] &= ~TPMARK_PENDING;		case MTREW:			sc->sc_flags[targid] &= ~DEV_EOM;			sc->sc_category_flags[targid] &= ~TPMARK_PENDING;			callcount = 1;			fcount = 1;			break;		case MTNOP:			return(0);		case MTCACHE:		case MTNOCACHE:			return(ENXIO);		case MTFLUSH:			return(ENXIO);		case MTCSE:			/*			 * Clear Serious Exception, used by tape utilities			 * to clean up after Nbuf I/O and end of media.			 */			sc->sc_category_flags[targid] &= ~DEV_TPMARK;			sc->sc_flags[targid] |= DEV_CSE;			return(0);		case MTCLX: case MTCLS:			return(0);		case MTENAEOT:			dis_eot_sz[unit] = 0;			return(0);		case MTDISEOT:			dis_eot_sz[unit] = DISEOT;			sc->sc_flags[targid] &= ~DEV_EOM;			return(0);		case MTRETEN:	/* RETENSION command... */			sc->sc_flags[targid] &= ~DEV_EOM;			sc->sc_category_flags[targid] &= ~TPMARK_PENDING;			callcount = 1;			fcount = 1;			break;		default:			return (ENXIO);		}		if (callcount <= 0 || fcount <= 0)			return (EINVAL);		while (--callcount >= 0) {			tzcommand(dev, tzops[mtop->mt_op], fcount, 0);			if (sc->sc_c_status[targid] != SZ_GOOD) {			    /* TODO: debug (too handy to remove) */			    if (tz_sk_print) {				printf("tzioctl: Sense Key = 0x%x\n",				    sc->sc_c_snskey[targid]);			    }			    if ((sc->sc_c_snskey[targid] != SZ_NOSENSE) &&				(sc->sc_c_snskey[targid] != SZ_RECOVERR))				    return(EIO);			    if (sc->sc_category_flags[targid] & DEV_TPMARK)				    return(EIO);			}		}		return(0);	case MTIOCGET:				/* tape status */		mtget = (struct mtget *)data;		/* MTX depends on DEV_EOM in sc_flags for EOT handling */		mtget->mt_dsreg = (unsigned short)sc->sc_flags[targid];		/* sorry no useful error information available */		mtget->mt_erreg = 0;		/* best guess */		mtget->mt_resid = sc->sc_resid[targid];		/* this is a SCSI tape */		mtget->mt_type = MT_ISSCSI;		break;	case DEVIOCGET: 			/* device status */		devget = (struct devget *)data;		bzero(devget,sizeof(struct devget));		devget->category = DEV_TAPE;		devget->bus = DEV_NB;		bcopy(DEV_VS_SCSI, devget->interface, strlen(DEV_VS_SCSI));		bcopy(sc->sc_device[targid], devget->device, DEV_SIZE);		devget->adpt_num = 0;		devget->nexus_num = 0;		devget->bus_num = 0;		devget->ctlr_num = cntlr;		devget->rctlr_num = 0;		devget->slave_num = targid;		bcopy("tz", devget->dev_name, 3);		devget->unit_num = unit;		devget->soft_count = sc->sc_softcnt[targid];		devget->hard_count = sc->sc_hardcnt[targid];		devget->stat = sc->sc_flags[targid];		/* 		 * we only want the lower 4 bits at this time 		 * the rest is density which gwts filled in later 		*/		devget->category_stat = (sc->sc_category_flags[targid] & 0X0F);		/*		 * Do a mode sense to check for write locked drive.		 * First one can fail due to unit attention.		 */		tzcommand(dev, SZ_MODSNS, -1, 0);		if (sc->sc_c_status[targid] != SZ_GOOD)		    tzcommand(dev, SZ_MODSNS, -1, 0);		if (sc->sc_c_status[targid] == SZ_GOOD) {		    msdp = (struct sz_modsns_dt *)&sc->sz_dat[targid];		    if (msdp->wp) {		/* Tape is write locked. */			devget->stat |= DEV_WRTLCK;		    }		    /*		     * Setup the tape density.		     */		    if (msdp->density <= density_entrys) {			devget->category_stat |= density_table[msdp->density];		    }		    /*		     * Setup default density codes.		     */		    if (msdp->density == SCSI_DENS_DEFAULT) {			switch (sdp->devtype) {			    case TZK10:				devget->category_stat |= DEV_16000_BPI;				break;			    case TLZ04:				devget->category_stat |= DEV_61000_BPI;				break;			    case TZK08:				devget->category_stat |= DEV_54000_BPI;				break;			    case TZ30:			    case TZK50:				devget->category_stat |= DEV_6666BPI;				break;			    default:				if (sdp->opt_tab) {		        	    if (todp->opt_flags & SCSI_QIC) {					devget->category_stat |= DEV_10000_BPI;		        	    } else if (todp->opt_flags & SCSI_9TRK) {					devget->category_stat |= DEV_6250BPI;				    }				}				break;			} /* End 'switch (sdp->devtype)' */		    } /* End 'if (msdp->density == SCSI_DENS_DEFAULT)' */		} /* End 'if (sc->sc_c_status[targid] == SZ_GOOD)' */		break;	default:		return (ENXIO);	}	return (0);}/* * * Name:		tzcomplete	-Tape completion routine * * Abstract:		This routine is called from the scsi state machine *			to perform the completion work for the current data *			transfer. * * Inputs: * * bp			Buffer pointer of command to be completed. * * Outputs: *			Only printing debug messages. * * Return Values: 	Nothing formal, b_resid is updated. * * Side Effects: *			biodone() is called to free up the current bp. *			The buffer queue is changed to free up the front entry. * */int tzcomplete( bp )    struct buf *bp;{    register struct uba_ctlr *um;    register struct buf *dp;    register int s;    int unit = UNIT(bp->b_dev);    int targid;    int cntlr;    register struct sz_softc *sc;    struct uba_device *ui;    ui = szdinfo[unit];    dp = &szutab[unit];    targid = ui->ui_slave;    cntlr = ui->ui_ctlr;    sc = &sz_softc[cntlr];    PRINTD( targid, 0x01, ("tzcomplete called unit %d\n", UNIT(bp->b_dev)) );    /*     * Remove the completed request from the queue     * and release the buffer.     */    /* TODO: are we absolutely sure dp is valid? */    dp->b_actf = bp->av_forw;    bp->b_resid = sc->sc_resid[targid];    PRINTD(targid, 0x04, ("resid = %d\n", bp->b_resid));    sc->sc_flags[targid] |= DEV_DONE;    biodone(bp);    sc->sc_xevent[targid] = SZ_BEGIN;    sz_retries[sc->sc_unit[targid]] = 0;    /*     * The comand has ended     */    dp->b_active = 0;}tzdump(){}#endif

⌨️ 快捷键说明

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