ht.c

来自「著名的AT&T UNIX v6 源码」· C语言 代码 · 共 350 行

C
350
字号
/* * TJU16 tape driver */#include "../h/param.h"#include "../h/systm.h"#include "../h/buf.h"#include "../h/conf.h"#include "../h/dir.h"#include "../h/file.h"#include "../h/user.h"#include "../h/uba.h"#include "../h/map.h"#include "../h/mba.h"struct	device{	int	htcs1;	int	htds;	int	hter;	int	htmr;	int	htas;	int	htfc;	int	htdt;	int	htck;	int	htsn;	int	httc;};struct	buf	httab;struct	buf	rhtbuf;struct	buf	chtbuf;#define	NUNIT	1#define	BUNIT	2#define	INF	1000000char	h_openf[NUNIT];daddr_t	h_blkno[NUNIT];char	h_flags[NUNIT];daddr_t	h_nxrec[NUNIT];#define	HTADDR	((struct device *)(MBA1 + MBA_ERB))#define	GO	01#define	WCOM	060#define	RCOM	070#define	NOP	0#define	WEOF	026#define	SFORW	030#define	SREV	032#define	ERASE	024#define	REW	06#define	DCLR	010#define P800	01700		/* 800 + pdp11 mode */#define	P1600	02300		/* 1600 + pdp11 mode */#define	IENABLE	0100#define	RDY	0200#define	TM	04#define	DRY	0200#define EOT	02000#define CS	02000#define COR	0100000#define PES	040#define WRL	04000#define MOL	010000#define ERR	040000#define FCE	01000#define	TRE	040000#define HARD	064023	/* UNS|OPI|NEF|FMT|RMR|ILR|ILF */#define	SIO	1#define	SSFOR	2#define	SSREV	3#define SRETRY	4#define SCOM	5#define SOK	6#define H_WRITTEN 1htopen(dev, flag){	register unit, ds;	httab.b_flags |= B_TAPE;	unit = minor(dev) & 03;	if (unit >= NUNIT || h_openf[unit]) {		u.u_error = ENXIO;		return;	}	h_blkno[unit] = 0;	h_nxrec[unit] = INF;	h_flags[unit] = 0;	ds = hcommand(dev, NOP);	if ((ds&MOL)==0 || (flag && (ds&WRL)))		u.u_error = ENXIO;	if (u.u_error==0)		h_openf[unit]++;}htclose(dev, flag){	register int unit;	unit = minor(dev) & 03;	if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) {		hcommand(dev, WEOF);		hcommand(dev, WEOF);		hcommand(dev, SREV);	}/*	hcommand(dev, REW);	*//* for 'mtm' file positioning */	if((minor(dev)&4) == 0) /* no 4 -> rewind */		hcommand(dev,REW) ;	h_openf[unit] = 0;}hcommand(dev, com){	register struct buf *bp;	bp = &chtbuf;	spl5();	while(bp->b_flags&B_BUSY) {		bp->b_flags |= B_WANTED;		sleep(bp, PRIBIO);	}	spl0();	bp->b_dev = dev;	bp->b_resid = com;	bp->b_blkno = 0;	bp->b_flags = B_BUSY|B_READ;	htstrategy(bp);	iowait(bp);	if(bp->b_flags&B_WANTED)		wakeup(bp);	bp->b_flags = 0;	return(bp->b_resid);}htstrategy(bp)register struct buf *bp;{	register daddr_t *p;	if(bp != &chtbuf) {		p = &h_nxrec[minor(bp->b_dev)&03];		if(bp->b_blkno > *p) {			bp->b_flags |= B_ERROR;			bp->b_error = ENXIO;			iodone(bp);			return;		}		if(bp->b_blkno == *p && bp->b_flags&B_READ) {			bp->b_resid = bp->b_bcount;			clrbuf(bp);			iodone(bp);			return;		}		if ((bp->b_flags&B_READ)==0) {			*p = bp->b_blkno + 1;			h_flags[minor(bp->b_dev)&03] |=  H_WRITTEN;		}	}	bp->av_forw = NULL;	spl5();	if (httab.b_actf == NULL)		httab.b_actf = bp;	else		httab.b_actl->av_forw = bp;	httab.b_actl = bp;	if (httab.b_active==0)		htstart();	spl0();}htstart(){	register struct buf *bp;	register unit, den;	daddr_t blkno;    loop:	if ((bp = httab.b_actf) == NULL)		return;	unit = minor(bp->b_dev);	den = P800 | (unit&03);	if(unit >= 8)		den = P1600 | (unit&03);	if((HTADDR->httc&03777) != den)		HTADDR->httc = den;	unit &= 03;	blkno = h_blkno[unit];	if (bp == &chtbuf) {		if (bp->b_resid==NOP) {			bp->b_resid = HTADDR->htds & 0xffff;			goto next;		}		httab.b_active = SCOM;		HTADDR->htfc = 0;		HTADDR->htcs1 = bp->b_resid|GO;		return;	}	if (h_openf[unit] < 0 || bp->b_blkno > h_nxrec[unit])		goto abort;	if (blkno == bp->b_blkno) {		httab.b_active = SIO;		HTADDR->htfc = -bp->b_bcount;		mbastart(bp, HTADDR);	} else {		if (blkno < bp->b_blkno) {			httab.b_active = SSFOR;			HTADDR->htfc = blkno - bp->b_blkno;			HTADDR->htcs1 = SFORW|GO;		} else {			httab.b_active = SSREV;			HTADDR->htfc = bp->b_blkno - blkno;			HTADDR->htcs1 = SREV|GO;		}	}	return;    abort:	bp->b_flags |= B_ERROR;    next:	httab.b_actf = bp->av_forw;	iodone(bp);	goto loop;}htintr(mbastat, as){	register struct buf *bp;	register int unit, state;	int	err;	if ((bp = httab.b_actf)==NULL)		return;	unit = minor(bp->b_dev) & 03;	state = httab.b_active;	httab.b_active = 0;	if (HTADDR->htds&(ERR|EOT|TM) || mbastat & MBAEBITS) {		err = HTADDR->hter & 0xffff;		if ((mbastat & MBAEBITS) || (err&HARD))			state = 0;		if (bp == &rhtbuf)			err &= ~FCE;		if ((bp->b_flags&B_READ) && (HTADDR->htds&PES))			err &= ~(CS|COR);		if(HTADDR->htds&EOT || (HTADDR->htds&MOL)==0) {			if(h_openf[unit])				h_openf[unit] = -1;		}		else if(HTADDR->htds&TM) {			HTADDR->htfc = 0;			h_nxrec[unit] = bp->b_blkno;			state = SOK;		}		else if(state && err == 0)			state = SOK;		if(httab.b_errcnt > 4)			deverror(bp, HTADDR->hter, mbastat);		((struct mba_regs *)MBA1)->mba_cr &= ~MBAIE;		HTADDR->htcs1 = DCLR|GO;		((struct mba_regs *)MBA1)->mba_cr |= MBAIE;		if (state==SIO && ++httab.b_errcnt < 10) {			httab.b_active = SRETRY;			h_blkno[unit]++;			HTADDR->htfc = -1;			HTADDR->htcs1 = SREV|GO;			return;		}		if (state!=SOK) {			bp->b_flags |= B_ERROR;			state = SIO;		}	} else if (HTADDR->htcs1 < 0) {	/* SC */		if(HTADDR->htds & ERR) {			((struct mba_regs *)MBA1)->mba_cr &= ~MBAIE;			HTADDR->htcs1 = DCLR|GO;			((struct mba_regs *)MBA1)->mba_cr |= MBAIE;		}	}	switch(state) {	case SIO:	case SOK:		h_blkno[unit]++;	case SCOM:		httab.b_errcnt = 0;		httab.b_actf = bp->av_forw;		bp->b_resid = - (HTADDR->htfc & 0xffff);		if (bp->b_flags & B_READ)			bp->b_resid += bp->b_bcount;		iodone(bp);		break;	case SRETRY:		if((bp->b_flags&B_READ)==0) {			httab.b_active = SSFOR;			HTADDR->htcs1 = ERASE|GO;			return;		}	case SSFOR:	case SSREV:		if(HTADDR->htds & TM) {			if(state == SSREV) {				h_nxrec[unit] = bp->b_blkno - (HTADDR->htfc&0xffff);				h_blkno[unit] = h_nxrec[unit];			} else {				h_nxrec[unit] = bp->b_blkno + (HTADDR->htfc & 0xffff) - 1;				h_blkno[unit] = bp->b_blkno + (HTADDR->htfc & 0xffff);			}		} else			h_blkno[unit] = bp->b_blkno;		break;	default:		return;	}	htstart();}htread(dev){	htphys(dev);	physio(htstrategy, &rhtbuf, dev, B_READ);}htwrite(dev){	htphys(dev);	physio(htstrategy, &rhtbuf, dev, B_WRITE);}htphys(dev){	register unit;	daddr_t a;	unit = minor(dev) & 03;	if(unit < NUNIT) {		a = u.u_offset >> 9;		h_blkno[unit] = a;		h_nxrec[unit] = a+1;	}}

⌨️ 快捷键说明

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