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

📄 ct.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		case MTBSF:			goto gotaddr;		case MTOFFL:			sc->sc_blkno = 0;			sc->sc_ul.unit = C_SUNIT(sc->sc_punit);			sc->sc_ul.cmd = C_UNLOAD;			hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,				C_CMD, &sc->sc_ul, sizeof(sc->sc_ul));			break;		case MTWEOF:			sc->sc_blkno++;			sc->sc_flags |= CTF_WRT;			sc->sc_wfm.unit = C_SUNIT(sc->sc_punit);			sc->sc_wfm.cmd = C_WFM;			hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,				C_CMD, &sc->sc_wfm, sizeof(sc->sc_wfm));			ctaddeof(unit);			break;		case MTBSR:			sc->sc_blkno--;			goto gotaddr;		case MTFSR:			sc->sc_blkno++;			goto gotaddr;		case MTREW:			sc->sc_blkno = 0;#ifdef DEBUG			if(ctdebug & CT_BSF)				printf("ct%d: clearing eofs\n", unit);#endif			for (i=0; i<EOFS; i++)				sc->sc_eofs[i] = 0;			sc->sc_eofp = 0;gotaddr:			sc->sc_ioc.saddr = C_SADDR;			sc->sc_ioc.addr0 = 0;			sc->sc_ioc.addr = sc->sc_blkno;			sc->sc_ioc.unit = C_SUNIT(sc->sc_punit);			sc->sc_ioc.nop2 = C_NOP;			sc->sc_ioc.slen = C_SLEN;			sc->sc_ioc.len = 0;			sc->sc_ioc.nop3 = C_NOP;			sc->sc_ioc.cmd = C_READ;			hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,				C_CMD, &sc->sc_ioc, sizeof(sc->sc_ioc));			break;		}	}	else {mustio:		if ((bp->b_flags & B_READ) &&		    sc->sc_flags & (CTF_BEOF|CTF_EOT)) {#ifdef DEBUG			if (ctdebug & CDB_FILES)				printf("ctstart: before flags %x\n", sc->sc_flags);#endif			if (sc->sc_flags & CTF_BEOF) {				sc->sc_flags &= ~CTF_BEOF;				sc->sc_flags |= CTF_AEOF;#ifdef DEBUG				if (ctdebug & CDB_FILES)					printf("ctstart: after flags %x\n", sc->sc_flags);#endif			}			bp->b_resid = bp->b_bcount;			iodone(bp);			hpibfree(&sc->sc_dq);			if (dp = bp->b_actf)				dp->b_actb = bp->b_actb;			else				cttab[unit].b_actb = bp->b_actb;			*bp->b_actb = dp;			if ((bp = dp) == NULL) {				cttab[unit].b_active = 0;				return;			}			sc->sc_addr = bp->b_un.b_addr;			sc->sc_resid = bp->b_bcount;			if (hpibreq(&sc->sc_dq))				goto again;			return;		}					sc->sc_flags |= CTF_IO;		sc->sc_ioc.unit = C_SUNIT(sc->sc_punit);		sc->sc_ioc.saddr = C_SADDR;		sc->sc_ioc.addr0 = 0;		sc->sc_ioc.addr = sc->sc_blkno;		sc->sc_ioc.nop2 = C_NOP;		sc->sc_ioc.slen = C_SLEN;		sc->sc_ioc.len = sc->sc_resid;		sc->sc_ioc.nop3 = C_NOP;		if (bp->b_flags & B_READ)			sc->sc_ioc.cmd = C_READ;		else {			sc->sc_ioc.cmd = C_WRITE;			sc->sc_flags |= (CTF_WRT | CTF_WRTTN);		}		hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD,			&sc->sc_ioc, sizeof(sc->sc_ioc));	}	hpibawait(sc->sc_hd->hp_ctlr);}ctgo(unit)	register int unit;{	register struct ct_softc *sc = &ct_softc[unit];	register struct buf *bp;	bp = cttab[unit].b_actf;	hpibgo(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC,		sc->sc_addr, sc->sc_resid, bp->b_flags & B_READ);}/* * Hideous grue to handle EOF/EOT (mostly for reads) */cteof(sc, bp)	register struct ct_softc *sc;	register struct buf *bp;{	long blks;	/*	 * EOT on a write is an error.	 */	if ((bp->b_flags & B_READ) == 0) {		bp->b_resid = bp->b_bcount;		bp->b_flags |= B_ERROR;		bp->b_error = ENOSPC;		sc->sc_flags |= CTF_EOT;		return;	}	/*	 * Use returned block position to determine how many blocks	 * we really read and update b_resid.	 */	blks = sc->sc_stat.c_blk - sc->sc_blkno - 1;#ifdef DEBUG	if (ctdebug & CDB_FILES)		printf("cteof: bc %d oblk %d nblk %d read %d, resid %d\n",		       bp->b_bcount, sc->sc_blkno, sc->sc_stat.c_blk,		       blks, bp->b_bcount - CTKTOB(blks));#endif	if (blks == -1) { /* 9145 on EOF does not change sc_stat.c_blk */		blks = 0;		sc->sc_blkno++;	}	else {		sc->sc_blkno = sc->sc_stat.c_blk;	}	bp->b_resid = bp->b_bcount - CTKTOB(blks);	/*	 * If we are at physical EOV or were after an EOF,	 * we are now at logical EOT.	 */	if ((sc->sc_stat.c_aef & AEF_EOV) ||	    (sc->sc_flags & CTF_AEOF)) {		sc->sc_flags |= CTF_EOT;		sc->sc_flags &= ~(CTF_AEOF|CTF_BEOF);	}	/*	 * If we were before an EOF or we have just completed a FSF,	 * we are now after EOF.	 */	else if ((sc->sc_flags & CTF_BEOF) ||		 (sc->sc_flags & CTF_CMD) && sc->sc_cmd == MTFSF) {		sc->sc_flags |= CTF_AEOF;		sc->sc_flags &= ~CTF_BEOF;	}	/*	 * Otherwise if we read something we are now before EOF	 * (and no longer after EOF).	 */	else if (blks) {		sc->sc_flags |= CTF_BEOF;		sc->sc_flags &= ~CTF_AEOF;	}	/*	 * Finally, if we didn't read anything we just passed an EOF	 */	else		sc->sc_flags |= CTF_AEOF;#ifdef DEBUG	if (ctdebug & CDB_FILES)		printf("cteof: leaving flags %x\n", sc->sc_flags);#endif}ctintr(unit)	register int unit;{	register struct ct_softc *sc = &ct_softc[unit];	register struct buf *bp, *dp;	u_char stat;	bp = cttab[unit].b_actf;	if (bp == NULL) {		printf("ct%d: bp == NULL\n", unit);		return;	}	if (sc->sc_flags & CTF_IO) {		sc->sc_flags &= ~CTF_IO;		if (hpibustart(sc->sc_hd->hp_ctlr))			ctgo(unit);		return;	}	if ((sc->sc_flags & CTF_STATWAIT) == 0) {		if (hpibpptest(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave) == 0) {			sc->sc_flags |= CTF_STATWAIT;			hpibawait(sc->sc_hd->hp_ctlr);			return;		}	} else		sc->sc_flags &= ~CTF_STATWAIT;	hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, &stat, 1);#ifdef DEBUG	if (ctdebug & CDB_FILES)		printf("ctintr: before flags %x\n", sc->sc_flags);#endif	if (stat) {		sc->sc_rsc.unit = C_SUNIT(sc->sc_punit);		sc->sc_rsc.cmd = C_STATUS;		hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD,			&sc->sc_rsc, sizeof(sc->sc_rsc));		hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC,			&sc->sc_stat, sizeof(sc->sc_stat));		hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT,			&stat, 1);#ifdef DEBUG		if (ctdebug & CDB_FILES)			printf("ctintr: return stat 0x%x, A%x F%x blk %d\n",			       stat, sc->sc_stat.c_aef,			       sc->sc_stat.c_fef, sc->sc_stat.c_blk);#endif		if (stat == 0) {			if (sc->sc_stat.c_aef & (AEF_EOF | AEF_EOV)) {				cteof(sc, bp);				ctaddeof(unit);				goto done;			}			if (sc->sc_stat.c_fef & FEF_PF) {				ctreset(sc, sc->sc_hd);				ctstart(unit);				return;			}			if (sc->sc_stat.c_fef & FEF_REXMT) {				ctstart(unit);				return;			}			if (sc->sc_stat.c_aef & 0x5800) {				if (sc->sc_stat.c_aef & 0x4000)					tprintf(sc->sc_tpr,						"ct%d: uninitialized media\n",						unit);				if (sc->sc_stat.c_aef & 0x1000)					tprintf(sc->sc_tpr,						"ct%d: not ready\n", unit);				if (sc->sc_stat.c_aef & 0x0800)					tprintf(sc->sc_tpr,						"ct%d: write protect\n", unit);			} else {				printf("ct%d err: v%d u%d ru%d bn%d, ",				       unit,				       (sc->sc_stat.c_vu>>4)&0xF,				       sc->sc_stat.c_vu&0xF,				       sc->sc_stat.c_pend,				       sc->sc_stat.c_blk);				printf("R0x%x F0x%x A0x%x I0x%x\n",				       sc->sc_stat.c_ref,				       sc->sc_stat.c_fef,				       sc->sc_stat.c_aef,				       sc->sc_stat.c_ief);			}		} else			printf("ct%d: request status failed\n", unit);		bp->b_flags |= B_ERROR;		bp->b_error = EIO;		goto done;	} else		bp->b_resid = 0;	if (sc->sc_flags & CTF_CMD) {		switch (sc->sc_cmd) {		case MTFSF:			sc->sc_flags &= ~(CTF_BEOF|CTF_AEOF);			sc->sc_blkno += CTBTOK(sc->sc_resid);			ctstart(unit);			return;		case MTBSF:			sc->sc_flags &= ~(CTF_AEOF|CTF_BEOF|CTF_EOT);			break;		case MTBSR:			sc->sc_flags &= ~CTF_BEOF;			if (sc->sc_flags & CTF_EOT) {				sc->sc_flags |= CTF_AEOF;				sc->sc_flags &= ~CTF_EOT;			} else if (sc->sc_flags & CTF_AEOF) {				sc->sc_flags |= CTF_BEOF;				sc->sc_flags &= ~CTF_AEOF;			}			break;		case MTWEOF:			sc->sc_flags &= ~CTF_BEOF;			if (sc->sc_flags & (CTF_AEOF|CTF_EOT)) {				sc->sc_flags |= CTF_EOT;				sc->sc_flags &= ~CTF_AEOF;			} else				sc->sc_flags |= CTF_AEOF;			break;		case MTREW:		case MTOFFL:			sc->sc_flags &= ~(CTF_BEOF|CTF_AEOF|CTF_EOT);			break;		}	} else {		sc->sc_flags &= ~CTF_AEOF;		sc->sc_blkno += CTBTOK(sc->sc_resid);	}done:#ifdef DEBUG	if (ctdebug & CDB_FILES)		printf("ctintr: after flags %x\n", sc->sc_flags);#endif	if (dp = bp->b_actf)		dp->b_actb = bp->b_actb;	else		cttab[unit].b_actb = bp->b_actb;	*bp->b_actb = dp;	iodone(bp);	hpibfree(&sc->sc_dq);	if (cttab[unit].b_actf == NULL) {		cttab[unit].b_active = 0;		return;	}	ctustart(unit);}ctread(dev, uio)	dev_t dev;	struct uio *uio;{	register int unit = UNIT(dev);	return(physio(ctstrategy, &ctbuf[unit], dev, B_READ, minphys, uio));}ctwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register int unit = UNIT(dev);	return(physio(ctstrategy, &ctbuf[unit], dev, B_WRITE, minphys, uio));}/*ARGSUSED*/ctioctl(dev, cmd, data, flag)	dev_t dev;	int cmd, flag;	caddr_t data;{	register struct mtop *op;	register int cnt;	switch (cmd) {	case MTIOCTOP:		op = (struct mtop *)data;		switch(op->mt_op) {		case MTWEOF:		case MTFSF:		case MTBSR:		case MTBSF:		case MTFSR:			cnt = op->mt_count;			break;		case MTREW:		case MTOFFL:			cnt = 1;			break;		default:			return(EINVAL);		}		ctcommand(dev, op->mt_op, cnt);		break;	case MTIOCGET:		break;	default:		return(EINVAL);	}	return(0);}/*ARGSUSED*/ctdump(dev)	dev_t dev;{	return(ENXIO);}ctaddeof(unit)	int unit;{	register struct ct_softc *sc = &ct_softc[unit];		if (sc->sc_eofp == EOFS - 1)		sc->sc_eofs[EOFS - 1]++;	else {		sc->sc_eofp++;		if (sc->sc_eofp == EOFS - 1)			sc->sc_eofs[EOFS - 1] = EOFS;		else			/* save blkno */			sc->sc_eofs[sc->sc_eofp] = sc->sc_blkno - 1;	}#ifdef DEBUG	if (ctdebug & CT_BSF)		printf("ct%d: add eof pos %d blk %d\n",		       unit, sc->sc_eofp,		       sc->sc_eofs[sc->sc_eofp]);#endif}#endif

⌨️ 快捷键说明

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