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

📄 wt.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
case 0:cmds(0x28);break;case 1:cmds(0x29);break;case 2:cmds(0x27);break;case 3:cmds(0x24);	}	return(0);}/* * close routine * called on last device close * If not rewind-on-close, leave read or write command intact. */wtclose(dev){	int wtdsl2();#ifdef DEBUG	debug("WTclose:\n");#endif	if (Hogproc == myproc)		Hogproc = (struct proc *) 0;	if (!exflag && (wtflags & TPWANY) && !(wtflags & (TPSESS|TPDEAD))) {		if (!(wtflags & TPWO))			wstart();#ifdef DEBUG		debug("WT: Writing file mark\n");#endif		wmark();	/* write file mark */#ifdef DEBUG		debug("WT: Wrote file mark, going to wait\n");#endif		if (rdyexc(HZ/10) == ERROR) {			wtsense(0);			}		}	if (TP_REWCLOSE(dev) || (wtflags & (TPSESS|TPDEAD))) {	/* rewind tape to beginning of tape, deselect tape, and make a note */	/* don't wait until rewind, though */		/* Ending read or write causes rewind to happen, if no error,		 * and READY and EXCEPTION stay up until it finishes */		if (wtflags & (TPRO|TPWO))		{#ifdef DEBUG			debug("End read or write\n");#endif			rdyexc(HZ/10);			ioend();			wtflags &= ~(TPRO|TPWO);		}		else	wtwind();		wtflags |= TPSTART | TPREW;		timeout(wtdsl2, 0, HZ);	}	else if (!(wtflags & (TPVOL|TPWANY)))	{		/* space forward to after next file mark no writing done */		/* This allows skipping data without reading it.*/#ifdef DEBUG		debug("Reading past file mark\n");#endif		if (!(wtflags & TPRO))			rstart();		rmark();		if (rdyexc(HZ/10))		{			wtsense(TP_WRP);		}	}	wtflags &= TPREW|TPDEAD|TPSTART|TPRO|TPWO;	return(0);}/* return ERROR if user I/O request should receive an I/O error code */wtsense(ignor){	wtflags &= ~(TPRO|TPWO);#ifdef DEBUGx	debug("WTsense: start ");#endif	if (rdstatus(&wterror) == ERROR)	{#ifdef DEBUG		debug("WTsense: Can't read status\n");#endif		return(ERROR);	}#ifdef DEBUG	if (wterror.wt_err & (TP_ST0|TP_ST1))	{		debug("Tperror: status %x error %d underruns %d\n",			wterror.wt_err, wterror.wt_ercnt, wterror.wt_urcnt);	}	else		debug("done. no error\n");#endif	wterror.wt_err &= ~ignor;	/* ignore certain errors */	reperr(wterror.wt_err);	if (((wterror.wt_err & TP_ST0) && (wterror.wt_err & TP_ERR0)) ||		    ((wterror.wt_err & TP_ST1) && (wterror.wt_err & TP_ERR1)))			return	ERROR;	return SUCCESS;}/* lifted from tdriver.c from Wangtek */reperr(srb0)int srb0;{	int s0 = srb0 & (TP_ERR0|TP_ERR1);	/* find out which exception to report */ 	if (s0) {		if (s0 & TP_USL) 			sterr("Drive not online");		else if (s0 & TP_CNI) 			sterr("No cartridge");		else if ((s0 & TP_WRP) && !(wtflags & TPWP))		{			sterr("Tape is write protected");			wtflags |= TPWP;		}		/*		if (s0 & TP_FIL)			sterr("Filemark detected");		*/		else if (s0 & TP_BNL)			sterr("Block in error not located");		else if (s0 & TP_UDA)			sterr("Unrecoverable data error");		/*		else if (s0 & TP_EOM)			sterr("End of tape");		*/		else if (s0 & TP_NDT)			sterr("No data detected");		/*		if (s0 & TP_POR)			sterr("Reset occured");		*/		else if (s0 & TP_BOM)			sterr("Beginning of tape");		else if (s0 & TP_ILL)			sterr("Illegal command");	}}	sterr(errstr)char	*errstr;{	printf("Streamer: %s\n", errstr);}/* Wait until rewind finishes, and deselect drive */wtdsl2() {	int	stat;	stat = inb(wtport) & (READY|EXCEP);#ifdef DEBUG	debug("Timeout: Waiting for rewind to finish: stat %x\n", stat);#endif	switch (stat) {		/* They're active low, ya'know */		case READY|EXCEP:			timeout(wtdsl2, (caddr_t) 0, HZ);			return;		case EXCEP: 			wtflags &= ~TPREW;			return;		case READY:		case	0:			wtflags &= ~TPREW;			sterr("Rewind failed");			wtsense(TP_WRP);			return;			}	}wtwind() {#ifdef DEBUG	debug("WT: About to rewind\n");#endif	rwind();	/* actually start rewind */}wtintr(unit) {	if (wtflags & (TPWO|TPRO))	{		isrlock = 1;		if (wtio) isr();		isrlock = 0;	}}wtinit() {	if (wtchan < 1 || wtchan > 3)	{		sterr("Bad DMA channel, cannot init driver");		return;	}	wtlinit();	/* init assembly language variables */	pageset();}rdyexc(ticks){	int s;#ifdef DEBUG	int os = 0xffff;		/* force printout first time */#endif	for (;;) {			/* loop until ready or exception */		s=(inb(wtport) & 0xff);	/* read the status register */#ifdef DEBUG		if (os != s) {			debug("Status reg = %x\n", s); /* */			os = s;			}#endif		if (!(s & EXCEP))	/* check if exception have occured */			break;		if (!(s & READY))	/* check if controller is ready */			break;		s = splbio();		delay((ticks/HZ)*1000000); /* */		splx(s);	}#ifdef DEBUG	debug("Status reg = %x on return\n", s); /* */#endif	return((s & EXCEP)?SUCCESS:ERROR);  /* return exception if it occured */}pollrdy(){	int	 sps;#ifdef DEBUG	debug("Pollrdy\n");#endif	sps = splbio();	while (wtio) {		int error;		if (error = tsleep((caddr_t)&wci, WTPRI | PCATCH,			"wtpoll", 0)) {			splx(sps);			return(error);		}	}	splx(sps);#ifdef DEBUG	debug("Finish poll, wci %d exflag %d\n", wci, exflag);#endif	return (EIO);}wtdma()		/* start up i/o operation, called from dma() in wtlib1.s */{	wtio = 1;	if (!wtimeron)	{		wtimeron = 1;		timeout(wtimer, (caddr_t) 0, HZ/2);	}}wtwake()	/* end i/o operation, called from isr() in wtlib1.s */{	wtio = 0;	wakeup(&wci);}pageset(){	unsigned long pp;	pp = (unsigned long) pagebuf;	pageaddr = kvtop(pp);#ifdef DEBUG	debug("pageset: addr %lx\n", pageaddr);#endif}#define nearstatic nearsendcmd(){	/* desired command in global mbits */	outb(CTLPORT, mbits | REQUEST);		/* set request */	while (inb(STATPORT) & READY);		/* wait for ready */	outb(CTLPORT, mbits & ~REQUEST);	/* reset request */	while ((inb(STATPORT) & READY) == 0);	/* wait for not ready */}static near		/* execute command */cmds(cmd){	register s;	do s = inb(STATPORT);	while ((s & STAT) == STAT);	/* wait for ready */	if ((s & EXCEP) == 0)		/* if exception */		return ERROR;		/* error */		outb(CMDPORT, cmd);		/* output the command	*/	outb(CTLPORT, mbits=ONLINE);	/* set & send ONLINE	*/	sendcmd();	return SUCCESS;}qicmd(cmd){	return cmds(cmd);}rstart(){	return cmds(RDDATA);}rmark(){	return cmds(READFM);}wstart(){	return cmds(WRTDATA);}ioend(){	register s;	register rval = SUCCESS;	do s = inb(STATPORT);	while ((s & STAT) == STAT);	/* wait for ready */	if ((s & EXCEP) == 0)		/* if exception */		rval = ERROR;		/* error */		mbits &= ~ONLINE;	outb(CTLPORT, mbits);		/* reset ONLINE */	outb(MASKREG, wtchan+4);	/* turn off dma */	outb(CLEARFF, 0);		/* reset direction flag */	return rval;}wmark(){	register s;	if (cmds(WRITEFM) == ERROR)		return ERROR;	do s = inb(STATPORT);	while ((s & STAT) == STAT);	/* wait for ready */	if ((s & EXCEP) == 0)		/* if exception */		return ERROR;		/* error */	return SUCCESS;}rwind(){	register s;	mbits = CMDOFF;	do s = inb(STATPORT);	while ((s & STAT) == STAT);	/* wait for ready */	outb(CMDPORT, REWIND);	sendcmd();	return SUCCESS;}rdstatus(stp)char *stp;		/* pointer to 6 byte buffer */{	register s;	int n;	do s = inb(STATPORT);	while ((s & STAT) == STAT);	/* wait for ready or exception */	outb(CMDPORT, RDSTAT);	sendcmd();			/* send read status command */	for (n=0; n<6; n++)	{#ifdef DEBUGx		debug("rdstatus: waiting, byte %d\n", n);#endif		do s = inb(STATPORT);		while ((s & STAT) == STAT);	/* wait for ready */#ifdef DEBUGx		debug("rdstatus: done\n");#endif		if ((s & EXCEP) == 0)		/* if exception */			return ERROR;		/* error */		*stp++ = inb(DATAPORT);		/* read status byte */		outb(CTLPORT, mbits | REQUEST);	/* set request */#ifdef DEBUGx		debug("rdstatus: waiting after request, byte %d\n", n);#endif		while ((inb(STATPORT)&READY) == 0);	/* wait for not ready */		for (s=100; s>0; s--);		/* wait an additional time */		outb(CTLPORT, mbits & ~REQUEST);/* unset request */#ifdef DEBUGx		debug("rdstatus: done\n");#endif	}	return SUCCESS;}t_reset(){	register i;	mbits |= RESET;	outb(CTLPORT, mbits);		/* send reset */	delay(20);	mbits &= ~RESET;	outb(CTLPORT, mbits);		/* turn off reset */	if ((inb(STATPORT) & RESETMASK) == RESETVAL)		return SUCCESS;	return ERROR;}staticdma(){	int x=splbio();	wtdma();	outb(CLEARFF, 0);	outb(MODEREG, mode);	/* set dma mode */	outb(dmareg, bufptr & 0xFF);	outb(dmareg, (bufptr>>8) & 0xFF);	outb(pagereg, (bufptr>>16) & 0xFF);                         	outb(dmareg+1, (BLKSIZE-1) & 0xFF);	outb(dmareg+1, (BLKSIZE-1) >> 8);	outb(wtport, eqdma+ONLINE);	outb(MASKREG, wtchan);	/* enable command to 8237, start dma */	splx(x);}static nearwtstart(buf, cnt)long buf;int cnt;{	register s;	bufptr = buf;		/* init statics */	numbytes = cnt;	wci = 0;		/* init flags */	exflag = 0;	bytes = 0;		/* init counter */	do s = inb(STATPORT) & STAT;	while (s == STAT);	/* wait for ready or error */	if (s & EXCEP)		/* no error */	{		dma();		return SUCCESS;	}	return ERROR;		/* error */}rtape(buf, cnt)long buf;			/* physical address */int cnt;			/* number of bytes */{	mode = dma_read;	return wtstart(buf,cnt);}wtape(buf, cnt)long buf;			/* physical address */int cnt;			/* number of bytes */{	mode = dma_write;	return wtstart(buf,cnt);}isr(){	int stat = inb(wtport);	if (!(stat & EXCEP))	/* exception during I/O */	{		if (bytes + BLKSIZE >= numbytes) wci = 1;		exflag = 1;		goto isrwake;	}	if ((stat & READY) || !(inb(STATUSREG) & dma_done))		return;	exflag = 0;	outb(wtport, ONLINE);	bytes += BLKSIZE;	if (bytes >= numbytes)	/* normal completion of I/O */	{		wci = 1;isrwake:		outb(MASKREG, 4+wtchan);	/* turn off dma */		wtwake();			/* wake up user level */	}	else	{			/* continue I/O */		bufptr += BLKSIZE;		dma();	}}wtlinit(){	switch (wtchan) {	case 1:		return;	case 2:		pagereg = 0x81;		dma_done = 4;		break;	case 3:		eqdma = 0x10;		pagereg = 0x82;		dma_done = 8;		break;	}	dma_write = wtchan+0x48;	dma_read = wtchan+0x44;	dmareg = wtchan+wtchan;}/* * delay i microseconds */delay(i)register int i;{	while (i-- > 0)		DELAY(1000);}wtsize(){}wtdump(){}#include <i386/isa/isa_device.h>#include <i386/isa/icu.h>int	wtprobe(), wtattach();struct	isa_driver wtdriver = {	wtprobe, wtattach, "wt",};wtprobe(dvp)	struct isa_device *dvp;{	int val,i,s;#ifdef lint	wtintr(0);#endif	wtport = dvp->id_iobase;	if(t_reset() != SUCCESS) return(0);	return(1);}wtattach() { }#endif NWT

⌨️ 快捷键说明

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