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

📄 tm.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
#/* * TM tape driver */#include "../h/param.h"#include "../h/buf.h"#include "../h/dir.h"#include "../h/conf.h"#include "../h/file.h"#include "../h/user.h"struct device {	int	tmer;	int	tmcs;	int	tmbc;	char	*tmba;	int	tmdb;	int	tmrd;};struct	buf	tmtab;struct	buf	ctmbuf;struct	buf	rtmbuf;char	t_flags[8];char	t_openf[8];daddr_t	t_blkno[8];daddr_t	t_nxrec[8];#define	TMADDR ((struct device *)0172520)#define	GO	01#define	RCOM	02#define	WCOM	04#define	WEOF	06#define	NOP	0100#define	SFORW	010#define	SREV	012#define	WIRG	014#define	REW	016#define	DENS	060000		/* 9-channel */#define	IENABLE	0100#define	CRDY	0200#define GAPSD	010000#define	TUR	1#define	HARD	0102200	/* ILC, EOT, NXM */#define RLE	0100#define	EOF	0040000#define	WL	04#define	SSEEK	1#define	SIO	2#define	SCOM	3#define T_WRITTEN 1tmopen(dev, flag){	register unit, ds;	unit = minor(dev) & 0177;	if (t_openf[unit]) {		u.u_error = ENXIO;		return;	}	t_blkno[unit] = 0;	t_nxrec[unit] = 65535;	t_flags[unit] = 0;	tmtab.b_flags |= B_TAPE;	ds = tcommand(dev, NOP);	if ((ds&TUR)==0) {		printf("mt%d off line\n",unit);		u.u_error = ENXIO;	}	if (flag && ds&WL) {		printf("mt%d needs write ring\n",unit);		u.u_error = ENXIO;	}	if (u.u_error==0)		t_openf[unit]++;}tmclose(dev, flag)dev_t dev;int flag;{	if ( flag == FWRITE ||	((flag&FWRITE) && (t_flags[minor(dev)&0177]&T_WRITTEN))) {		tcommand(dev, WEOF);		tcommand(dev, WEOF);		tcommand(dev, SREV);	}	if ((minor(dev)&0200) == 0)		tcommand(dev, REW);	t_openf[minor(dev)&077] = 0;}tcommand(dev, com){	register struct buf *bp;	bp = &ctmbuf;	spl5();	while (bp->b_flags&B_BUSY) {		bp->b_flags |= B_WANTED;		sleep((caddr_t)bp, PRIBIO);	}	bp->b_flags = B_BUSY|B_READ;	spl0();	bp->b_dev = dev;	bp->b_resid = com;	bp->b_blkno = 0;	tmstrategy(bp);	iowait(bp);	if (bp->b_flags&B_WANTED)		wakeup((caddr_t)bp);	bp->b_flags = 0;	return(bp->b_resid);}tmstrategy(bp)register struct buf *bp;{	register daddr_t *p;	if(bp->b_flags&B_PHYS)		mapalloc(bp);	if (bp != &ctmbuf) {		p = &t_nxrec[minor(bp->b_dev)&0177];		if (*p <= bp->b_blkno) {			if (*p < bp->b_blkno) {				bp->b_flags |= B_ERROR;				iodone(bp);				return;			}			if (bp->b_flags&B_READ) {				clrbuf(bp);				bp->b_resid = 0;				iodone(bp);				return;			}		}		if ((bp->b_flags&B_READ) == 0) {			t_flags[minor(bp->b_dev)&0177] |= T_WRITTEN;			*p = bp->b_blkno+1;		}	}	bp->av_forw = 0;	spl5();	if (tmtab.b_actf == NULL)		tmtab.b_actf = bp;	else		tmtab.b_actl->av_forw = bp;	tmtab.b_actl = bp;	if (tmtab.b_active == NULL)		tmstart();	spl0();}tmstart(){	register struct buf *bp;	register int com;	int unit;	register daddr_t *blkno;    loop:	if ((bp = tmtab.b_actf) == 0)		return;	unit = minor(bp->b_dev)&0177;	blkno = &t_blkno[unit];	if (t_openf[unit] < 0 || (TMADDR->tmcs & CRDY) == NULL) {		bp->b_flags |= B_ERROR;		goto next;	}	if (bp == &ctmbuf) {		if (bp->b_resid == NOP) {			bp->b_resid = TMADDR->tmer;			goto next;		}		tmtab.b_active = SCOM;		TMADDR->tmcs = DENS|bp->b_resid|GO| (unit<<8) | IENABLE;		return;	}	com = (unit<<8) | ((bp->b_xmem & 03) << 4) | IENABLE|DENS;	if (*blkno != bp->b_blkno) {		tmtab.b_active = SSEEK;		if (*blkno < bp->b_blkno) {			com |= SFORW|GO;			TMADDR->tmbc = *blkno - bp->b_blkno;		} else {			if (bp->b_blkno == 0)				com |= REW|GO;			else {				com |= SREV|GO;				TMADDR->tmbc = bp->b_blkno - *blkno;			}		}		TMADDR->tmcs = com;		return;	}	tmtab.b_active = SIO;	TMADDR->tmbc = -bp->b_bcount;	TMADDR->tmba = bp->b_un.b_addr;	TMADDR->tmcs = com | ((bp->b_flags&B_READ)? RCOM|GO:	    ((tmtab.b_errcnt)? WIRG|GO: WCOM|GO));	return;next:	tmtab.b_actf = bp->av_forw;	iodone(bp);	goto loop;}tmintr(){	register struct buf *bp;	register int unit;	int	state;	if ((bp = tmtab.b_actf) == NULL)		return;	unit = minor(bp->b_dev)&0177;	state = tmtab.b_active;	tmtab.b_active = 0;	if (TMADDR->tmcs < 0) {		/* error bit */		while(TMADDR->tmrd & GAPSD) ; /* wait for gap shutdown */		if (TMADDR->tmer&EOF) {			t_nxrec[unit] = bp->b_blkno;			state = SCOM;			TMADDR->tmbc = -bp->b_bcount;			goto out;		}		if ((TMADDR->tmer&HARD) == 0 && TMADDR->tmer&RLE) {			state = SIO;			goto out;		}		if ((TMADDR->tmer&(HARD|EOF)) == NULL && state==SIO) {			if (++tmtab.b_errcnt < 2) {				t_blkno[unit]++;				tmtab.b_active = 0;				tmstart();				return;			}		} else			if (t_openf[unit]>0 && bp!=&rtmbuf &&				(TMADDR->tmer&EOF)==0 ) {				t_openf[unit] = -1;				deverror(bp, TMADDR->tmer, 0);			}		bp->b_flags |= B_ERROR;		state = SIO;	}out:	switch ( state ) {	case SIO:		t_blkno[unit] += (bp->b_bcount>>BSHIFT);	case SCOM:		tmtab.b_errcnt = 0;		tmtab.b_actf = bp->av_forw;		bp->b_resid = -TMADDR->tmbc;		iodone(bp);		break;	case SSEEK:		t_blkno[unit] = bp->b_blkno;		break;	default:		return;	}	tmstart();}tmread(dev){	tmphys(dev);	physio(tmstrategy, &rtmbuf, dev, B_READ);}tmwrite(dev){	tmphys(dev);	physio(tmstrategy, &rtmbuf, dev, B_WRITE);}tmphys(dev){	register unit;	daddr_t a;	unit = minor(dev) & 0177;	if(unit < 8) {		a = u.u_offset >> 9;		t_blkno[unit] = a;		t_nxrec[unit] = a+1;	}}

⌨️ 快捷键说明

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