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

📄 tm.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * the transfer and continue processing this slave.	 */	if (um->um_ubinfo)		ubadone(um);	um->um_tab.b_errcnt = 0;	dp->b_actf = bp->av_forw;	iodone(bp);	goto loop;}/* * The bus resources we needed have been * allocated to us; start the device. */tmdgo(um)	register struct uba_ctlr *um;{	register struct tmdevice *addr = (struct tmdevice *)um->um_addr;	addr->tmba = um->um_ubinfo;	addr->tmcs = um->um_cmd | ((um->um_ubinfo >> 12) & 0x30);}/* * TM interrupt routine. */tmintr(tm11)	int tm11;{	register struct buf *bp;	register struct uba_ctlr *um = tmminfo[tm11];	register struct tmdevice *addr;	register struct te_softc *sc;	register int state;	register struct buf *dp;	int tmunit, unit;	if ((dp = um->um_tab.b_actf) == NULL)		return;	bp = dp->b_actf;	tmunit = TMUNIT(bp->b_dev);	unit = UNIT(bp->b_dev);	addr = (struct tmdevice *)tedinfo[unit]->ui_addr;	sc = &te_softc[unit];	/*	 * If last command was a rewind, and tape is still	 * rewinding, wait for the rewind complete interrupt.	 */	if (um->um_tab.b_active == SREW) {		um->um_tab.b_active = SCOM;		if (addr->tmer&TMER_RWS) {			sc->sc_timo = 5*60;		/* 5 minutes */			return;		}	}	/*	 * An operation completed... record status	 */	sc->sc_timo = INF;	sc->sc_dsreg = addr->tmcs;	sc->sc_erreg = addr->tmer;	sc->sc_resid = addr->tmbc;	if ((bp->b_flags & B_READ) == 0)		sc->sc_flags |= DEV_WRITTEN;	state = um->um_tab.b_active;	um->um_tab.b_active = 0;	/*	 * Check for errors.	 */	if (addr->tmcs & TM_ERR) {		while (addr->tmer & TMER_SDWN)			;			/* await settle down */		/*		 * If we hit end-of-tape (EOT),		 * just return.		 */		if (addr->tmer & TMER_EOT) {			sc->sc_flags |= DEV_EOM;			goto opdone;		}		/*		 * If we hit the end of the tape file, update position.		 */		if (addr->tmer & TMER_EOF) {			sc->sc_category_flags |= DEV_TPMARK;			if (bp == &ctmbuf[tmunit]) {				if (sc->sc_blkno >				    bdbtofsb(bp->b_blkno)) {					/* reversing */					sc->sc_nxrec =					       bdbtofsb(bp->b_blkno) -					       addr->tmbc;					sc->sc_blkno = sc->sc_nxrec;				} else {					/* spacing forward */					sc->sc_blkno =						bdbtofsb(bp->b_blkno) +						addr->tmbc;					sc->sc_nxrec = sc->sc_blkno - 1;				}				goto seteof;			}			/* eof on read */			sc->sc_nxrec = bdbtofsb(bp->b_blkno);seteof:			state = SCOM;		/* force completion */			/*			 * Stuff bc so it will be unstuffed correctly			 * later to get resid.			 */			addr->tmbc = -bp->b_bcount;			goto opdone;		}		/*		 * If we were reading raw tape and the only error was		 * that the record was too long, then we don't consider		 * this an error.		 */		if (bp != &ctmbuf[tmunit] && (bp->b_flags&B_READ) &&		    (addr->tmer&(TMER_HARD|TMER_SOFT)) == TMER_RLE)			goto ignoreerr;		/*		 * If error is not hard, and this was an i/o operation		 * retry up to 8 times.		 */		if ((addr->tmer&TMER_HARD)==0 && state==SIO) {			if (++um->um_tab.b_errcnt < 7) {				sc->sc_blkno++;				ubadone(um);				goto opcont;			}		} else			/*			 * Hard or non-i/o errors on non-raw tape			 * cause it to close.			 */			if (sc->sc_openf>0 && bp == &ctmbuf[tmunit])				sc->sc_openf = -1;		/*		 * Couldn't recover error		 */		sc->sc_flags |= DEV_HARDERR;		mprintf("%s: unit# %d: hard error block# %d\n",			sc->sc_device, unit, bp->b_blkno);		mprintf("tmer=%b\n", sc->sc_erreg, TMER_BITS);		bp->b_flags |= B_ERROR;		goto opdone;	}	/*	 * Advance tape control FSM.	 */ignoreerr:	if (addr->tmer & TMER_EOT) {		sc->sc_flags |= DEV_EOM;	}	switch (state) {	case SIO:		/*		 * Read/write increments tape block number		 */		sc->sc_blkno++;		goto opdone;	case SCOM:		/*		 * For forward/backward space record update current		 * position.		 */		if (bp == &ctmbuf[tmunit])		switch (bp->b_command) {		case TM_SFORW:			sc->sc_blkno -= bp->b_repcnt;			break;		case TM_SREV:			sc->sc_blkno += bp->b_repcnt;			break;		}		goto opdone;	case SSEEK:		sc->sc_blkno = bdbtofsb(bp->b_blkno);		goto opcont;	default:		panic("tmintr");	}opdone:	/*	 * Reset error count and remove	 * from device queue.	 */	sc->sc_flags |= DEV_DONE;	um->um_tab.b_errcnt = 0;	dp->b_actf = bp->av_forw;	/*	 * Check resid; watch out for resid >32767 (tmbc not negative).	 */	bp->b_resid = ((int) -addr->tmbc) & 0xffff;	ubadone(um);	iodone(bp);	/*	 * Circulate slave to end of controller	 * queue to give other slaves a chance.	 */	um->um_tab.b_actf = dp->b_forw;	if (dp->b_actf) {		dp->b_forw = NULL;		if (um->um_tab.b_actf == NULL)			um->um_tab.b_actf = dp;		else			um->um_tab.b_actl->b_forw = dp;		um->um_tab.b_actl = dp;	}	if (um->um_tab.b_actf == 0)		return;opcont:	tmstart(um);}tmtimer(dev)	register int dev;{	register struct te_softc *sc = &te_softc[UNIT(dev)];	register int tmunit = TMUNIT(dev);	register int unit = UNIT(dev);	register short x;	if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) {		mprintf("%s: unit# %d: lost interrupt\n",			sc->sc_device, unit);		sc->sc_timo = INF;		x = spl5();		tmintr(tmunit);		(void) splx(x);	}	timeout(tmtimer, (caddr_t)dev, 5*hz);}tmread(dev, uio)	register dev_t dev;	register struct uio *uio;{	register int tmunit = TMUNIT(dev);	return (physio(tmstrategy, &rtmbuf[tmunit], dev, B_READ,		minphys, uio));}tmwrite(dev, uio)	register dev_t dev;	register struct uio *uio;{	register int tmunit = TMUNIT(dev);	return (physio(tmstrategy, &rtmbuf[tmunit], dev, B_WRITE,		minphys, uio));}tmioctl(dev, cmd, data, flag)	dev_t dev;	register int cmd;	caddr_t data;	int flag;{	register struct uba_device *ui = tedinfo[TMUNIT(dev)];	register struct te_softc *sc = &te_softc[UNIT(dev)];	register struct buf *bp = &ctmbuf[TMUNIT(dev)];	register callcount;	register int fcount;	struct mtop *mtop;	struct mtget *mtget;	struct devget *devget;	int unit = UNIT(dev);	/* we depend of the values and order of the MT codes here */	static tmops[] = { TM_WEOF,TM_SFORW,TM_SREV,TM_SFORW,			   TM_SREV,TM_REW,TM_OFFL,TM_SENSE };	switch (cmd) {	case MTIOCTOP:				/* tape operation */		mtop = (struct mtop *)data;		switch (mtop->mt_op) {		case MTWEOF:			callcount = mtop->mt_count;			fcount = 1;			break;		case MTFSF: case MTBSF:			callcount = mtop->mt_count;			fcount = INF;			break;		case MTFSR: case MTBSR:			callcount = 1;			fcount = mtop->mt_count;			break;		case MTREW: case MTOFFL:			sc->sc_flags &= ~DEV_EOM;			callcount = 1;			fcount = 1;			break;		case MTNOP: case MTCACHE: case MTNOCACHE:		case MTCLX: case MTCLS:   			return(0);		case MTCSE:			sc->sc_flags |= DEV_CSE;			sc->sc_category_flags &= ~DEV_TPMARK;			return(0);		case MTENAEOT:			dis_eot_te[unit] = 0;			return(0);		case MTDISEOT:			dis_eot_te[unit] = DISEOT;			sc->sc_flags &= ~DEV_EOM;			return(0);			case MTFLUSH:			/*			 * Flush controller's write back cache.  Since this			 * driver can not support this functionality, return			 * ENXIO to indicate the lack of support.			 */			return (ENXIO);		default:			return (ENXIO);		}		if (callcount <= 0 || fcount <= 0)			return (EINVAL);		while (--callcount >= 0) {			tmcommand(dev, tmops[mtop->mt_op], fcount);			if ((mtop->mt_op == MTFSR || mtop->mt_op ==			    MTBSR) && bp->b_resid)				return (EIO);			if ((bp->b_flags & B_ERROR) ||			    sc->sc_erreg & TMER_BOT)				break;		}		return (geterror(bp));	case MTIOCGET:				/* tape status */		mtget = (struct mtget *)data;		mtget->mt_dsreg = sc->sc_dsreg;		mtget->mt_erreg = sc->sc_erreg;		mtget->mt_resid = sc->sc_resid;		mtget->mt_type = MT_ISTM;		break;	case DEVIOCGET: 			/* device status */		devget = (struct devget *)data;		bzero(devget,sizeof(struct devget));		devget->category = DEV_TAPE;		devget->bus = DEV_UB;		bcopy(DEV_UNKNOWN,devget->interface,		      strlen(DEV_UNKNOWN));		bcopy(sc->sc_device,devget->device,		      strlen(sc->sc_device));		devget->adpt_num = ui->ui_adpt; 	/* which adapter*/		devget->nexus_num = ui->ui_nexus;	/* which nexus	*/		devget->bus_num = ui->ui_ubanum;	/* which UBA	*/		devget->ctlr_num = ui->ui_ctlr; 	/* which interf.*/		devget->slave_num = ui->ui_slave;	/* which plug	*/		bcopy(ui->ui_driver->ud_dname,		      devget->dev_name,		      strlen(ui->ui_driver->ud_dname)); /* Ultrix "te"	*/		devget->unit_num = unit;		/* which te??	*/		devget->soft_count = sc->sc_softcnt;	/* soft er. cnt.*/		devget->hard_count = sc->sc_hardcnt;	/* hard er. cnt.*/		devget->stat = sc->sc_flags;		/* status	*/		devget->category_stat = sc->sc_category_flags;	/* c.st.*/		break;	default:		return (ENXIO);	}	return (0);}tmreset(uban)	register int uban;{	register struct uba_ctlr *um;	register struct uba_device *ui;	register struct buf *dp;	register int tm11;	register int unit;	struct te_softc *sc;	for (tm11 = 0; tm11 < nNTM; tm11++) {		if ((um = tmminfo[tm11]) == 0 || um->um_alive == 0 ||		   um->um_ubanum != uban)			continue;		um->um_tab.b_active = 0;		um->um_tab.b_actf = um->um_tab.b_actl = 0;		if (um->um_ubinfo) {			mprintf("tm reset");			mprintf("<%d>", (um->um_ubinfo>>28)&0xf);			um->um_ubinfo = 0;		}		((struct tmdevice *)(um->um_addr))->tmcs = TM_DCLR;		for (unit = 0; unit < nNTE; unit++) {			if ((ui = tedinfo[unit]) == 0 || ui->ui_mi !=			    um || ui->ui_alive == 0)				continue;			sc = &te_softc[unit];			dp = &teutab[unit];			dp->b_active = 0;			dp->b_forw = 0;			if (um->um_tab.b_actf == NULL)				um->um_tab.b_actf = dp;			else				um->um_tab.b_actl->b_forw = dp;			um->um_tab.b_actl = dp;			if (sc->sc_openf > 0)				sc->sc_openf = -1;		}		tmstart(um);	}}tmdump(){	register struct uba_device *ui;	register struct uba_regs *up;	register struct tmdevice *addr;	register int blk;	register int num = maxfree;	register int start = 0;	if (tedinfo[0] == 0)		return (ENXIO);	ui = PHYS(tedinfo[0], struct uba_device *);	up = PHYS(ui->ui_hd, struct uba_hd *)->uh_physuba;	ubainit(up);	DELAY(500000);	addr = (struct tmdevice *)ui->ui_physaddr;	tmwait(addr);	addr->tmcs = TM_DCLR | TM_GO;	while (num > 0) {		blk = num > DBSIZE ? DBSIZE : num;		tmdwrite(start, blk, addr, up);		start += blk;		num -= blk;	}	tmeof(addr);	tmeof(addr);	tmwait(addr);	if (addr->tmcs&TM_ERR)		return (EIO);	addr->tmcs = TM_REW | TM_GO;	tmwait(addr);	return (0);}tmdwrite(dbuf, num, addr, up)	register int dbuf;	register int num;	register struct tmdevice *addr;	register struct uba_regs *up;{	register struct pte *io;	register int npf;	tmwait(addr);	io = up->uba_map;	npf = num+1;	while (--npf != 0)		 *(int *)io++ = (dbuf++ | (1<<UBAMR_DPSHIFT) |				 UBAMR_MRV);	*(int *)io = 0;	addr->tmbc = -(num*NBPG);	addr->tmba = 0;	addr->tmcs = TM_WCOM | TM_GO;}tmwait(addr)	register struct tmdevice *addr;{	register int s;	do		s = addr->tmcs;	while ((s & TM_CUR) == 0);}tmeof(addr)	register struct tmdevice *addr;{	tmwait(addr);	addr->tmcs = TM_WEOF | TM_GO;}#endif

⌨️ 快捷键说明

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