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

📄 tu.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* not reached */			break;		    }		tu.tu_rcnt = tudata.pk_mcount;		tu.tu_state = TUS_GETD;		break;	/*	 * Got the data, now fetch the checksum.	 */	case TUS_GETD:		tu.tu_rbptr = (u_char *)&tudata.pk_chksum;		tu.tu_rcnt = sizeof (tudata.pk_chksum);		tu.tu_state = TUS_GETC;		break;	case TUS_CHKERR:		/* from tudma only */		tu.tu_cerrs++;		goto tus_get;	case TUS_GET:		if (!MRSP)			/* 		 	 * The checksum has already been calculated and		 	 * verified in the pseudo DMA routine		 	 */			goto tus_get;	case TUS_GETC:		/* got entire packet */		if (tudata.pk_chksum !=		    tuchk(*((short *)&tudata), (u_short *)		     (tudata.pk_flag == TUF_DATA ? 		     (u_short *) tu.tu_addr : (u_short *)&tudata.pk_op),		     (int)tudata.pk_mcount))			tu.tu_cerrs++;tus_get:		if (tudata.pk_flag == TUF_DATA) {			/* data packet, advance to next */			tu.tu_addr += tudata.pk_mcount;			tu.tu_count -= tudata.pk_mcount;			tu.tu_state = TUS_GETH;			tu.tu_rbptr = (u_char *)&tudata; /* next packet */			tu.tu_rcnt = 2;			tu.tu_flag = 1;		} else if (tudata.pk_flag==TUF_CMD && tudata.pk_op==TUOP_END) {			/* end packet, idle and reenable transmitter */			tu.tu_state = TUS_IDLE;			tu.tu_flag = 0;			mtpr(CSTS, IE);#ifdef TUDEBUG			printd("ON ");#endif			if ((bp = tutab.b_actf) == NULL) {				printf("tu%d: no bp, active %d\n",					tudata.pk_unit, tutab.b_active);				tustart();				return;			}			if (tudata.pk_mod > 1) {        /* hard error */				bp->b_flags |= B_ERROR;				tu.tu_herrs++;				switch (tudata.pk_mod & 0377) {				case 0377:				    sp = errstrgs[0];				    break;				case 0376:				    sp = errstrgs[1];				    break;				case 0370:				    sp = errstrgs[2];				    break;				case 0367:				    sp = errstrgs[3];				    break;				case 0365:				    sp = errstrgs[4];				    break;				case 0357:				    sp = errstrgs[5];				    break;				case 0340:				    sp = errstrgs[6];				    break;				case 0337:				    sp = errstrgs[7];				    break;				case 0320:				    sp = errstrgs[8];				    break;				case 0311:				    sp = errstrgs[9];				    break;				default:				    sp = errstrgs[10];				    break;				}				printf("tu%d: hard error bn%d, pk_status %o %s\n", minor(bp->b_dev)&DNUM, bp->b_blkno, tudata.pk_mod&0377, sp);			} else if (tudata.pk_mod != 0)	/* soft error */				tu.tu_serrs++;			tutab.b_active = NULL;			tutab.b_actf = bp->av_forw;			bp->b_resid = tu.tu_count;			if ((bp->b_flags&B_READ) == 0)				tu_vee(&tu_pcnt[minor(bp->b_dev)&DNUM]);			timeout(iodone,bp,1);			tu.tu_toerrs = tu.tu_poerrs = 0;			tustart();		} else {			/*			 * Neither data nor end: data was lost			 * somehow, restart the transfer			 */			mtpr(CSRS, 0);		/* flush the rest */			tu_restart();			tu.tu_serrs++;		}		break;	case TUS_IDLE:	case TUS_INIT1:		break;	default:bad:		if (c == TUF_INITF) {			mprintf("tu%d: protocol error, state=%s op=%x cnt=%d \				block=%d\n", (int)tucmd.pk_unit,				tustates[tu.tu_state], tucmd.pk_op,				tucmd.pk_count, tucmd.pk_block);			/* resync protocol and retry ---- pmk */			if (++tu.tu_poerrs > MAXERRS) {			    tu.tu_poerrs = 0;			    if ((bp = tutab.b_actf) != NULL) {				bp->b_flags |= B_ERROR;				tutab.b_active = NULL;				tutab.b_actf = bp->av_forw;				if ((bp->b_flags&B_READ) == 0)					tu_vee(&tu_pcnt[minor(bp->b_dev)&DNUM]);				timeout(iodone,bp,1);			    }			}			tureset();		} else {			mprintf("tu%d: receive state error, state=%s byte=%x\n",			    (int)tucmd.pk_unit,tustates[tu.tu_state],c&0xff);			if (tutab.b_actf)				tu_restart();			else				wakeup((caddr_t)&tu);		}	}}/* * TU58 transmitter interrupt */tuxintr(){top:	if (tu.tu_wcnt) {		/* still stuff to send, send one byte */		while ((mfpr(CSTS) & READY) == 0)			;		mtpr(CSTD, *tu.tu_wbptr++);		tu.tu_wcnt--;		return;	}	/*	 * Last message byte was sent out.	 * Switch on state of transfer.	 */#ifdef TUDEBG	if (tudebug) {		printf("tuxintr: state=");		printstate(tu.tu_state);	}#endif	switch(tu.tu_state) {	/*	 * Two nulls have been sent, remove break, and send inits	 */	case TUS_INIT1:			mtpr(CSTS, IE);#ifdef TUDEBUG		printd("ON2 ");#endif		tu.tu_state = TUS_INIT2;		tu.tu_wbptr = tuinit;		tu.tu_wcnt = sizeof (tuinit);		goto top;	/*	 * Inits have been sent, wait for a continue msg.	 */	case TUS_INIT2:			mtpr(CSTS, 0);	/* disable transmitter interrupts */		(void) mfpr(CSRD);		mtpr(CSRS, IE);		tu.tu_flag = 1;		break;	/*	 * Read cmd packet sent, get ready for data	 */	case TUS_SENDR:		tu.tu_state = TUS_GETH;		tu.tu_rbptr = (u_char *)&tudata;		tu.tu_rcnt = 2;		tu.tu_flag = 1;		mtpr(CSTS, 0);	/* disable transmitter interrupts */#ifdef TUDEBUG		printd("OFF ");#endif		break;	/*	 * Write cmd packet sent, wait for continue	 */	case TUS_SENDW:			tu.tu_state = TUS_WAIT;		tu.tu_flag = 1;		if ((mfpr(CSRS)&IE) == 0) {			printf("NO IE\n");			mtpr(CSRS, IE);		}		break;	/*	 * Header sent, send data.	 */	case TUS_SENDH:		tu.tu_state = TUS_SENDD;		tu.tu_wbptr = (u_char *)tu.tu_addr;		tu.tu_wcnt = tudata.pk_mcount;		goto top;	/*	 * Data sent, follow with checksum.	 */	case TUS_SENDD:			tu.tu_state = TUS_SENDC;		tu.tu_wbptr = (u_char *)&tudata.pk_chksum;		tu.tu_wcnt = sizeof tudata.pk_chksum;		goto top;	/* 	 * Checksum sent, wait for continue.	 */	case TUS_SENDC:		/*		 * Updata buffer address and count.		 */		tu.tu_addr += tudata.pk_mcount;		tu.tu_count -= tudata.pk_mcount;		if (tu.tu_count) {			tu.tu_state = TUS_WAIT;			tu.tu_flag = 1;			break;		}		/*		 * End of transmission, get ready for end packet.		 */		tu.tu_state = TUS_GET;		tu.tu_rbptr = (u_char *)&tudata;		tu.tu_rcnt = sizeof (tudata);		tu.tu_flag = 1;		mtpr(CSTS, 0);#ifdef TUDEBUG		printd("OFF2 ");#endif		break;	/*	 * Random interrupt, probably from MRSP ACK	 */	case TUS_IDLE:	default:		break;	}#ifdef TUDEBUG	if (tudebug) {		printd("  new tu_state=");		printstate(tu.tu_state);	}#endif}/* * Compute checksum TU58 fashion */#ifdef linttuchk(word, cp, n)	register word;	register unsigned short *cp;	int n;{	register int c = n >> 1;	register long temp;	do {		temp = *cp++;	/* temp, only because vax cc won't *r++ */		word += temp;	} while (--c > 0);	if (n & 1)		word += *(unsigned char *)cp;	while (word & 0xffff0000)		word = (word & 0xffff) + ((word >> 16) & 0xffff);	return (word);}#elsetuchk(word0, wp, n)	register int word0;	/* r11 */	register char *wp;	/* r10 */	register int n;		/* r9 */{	asm("loop:");	asm("	addw2	(r10)+,r11");	/* add a word to sum */	asm("	adwc	$0,r11");	/* add in carry, end-around */	asm("	acbl	$2,$-2,r9,loop");	/* done yet? */	asm("	blbc	r9,ok");	/* odd byte count? */	asm("	movzbw	(r10),r10");	/* yes, get last byte */	asm("	addw2	r10,r11");	/* add it in */	asm("	adwc	$0,r11");	/* and the carry */	asm("ok:");	asm("	movl	r11,r0");	/* return sum */}#endiftuwatch(){	register int s;	register struct buf *bp;	if (tutimer == -1) { 		/* set in tuclose */		tutimer = 0;		return;	}	if (tu.tu_flag == 0) {		/* if no read in progress - skip */		timeout(tuwatch, (caddr_t)0, hz);		return;	}	if (tu.tu_flag++ <= 40) {		timeout(tuwatch, (caddr_t)0, hz);		return;	}	printf("tu%d: timeout, %s\n", tucmd.pk_unit,		tu.tu_toerrs < MAXERRS ? "command restarted" : "give up!");#ifdef TUDEBUG	printf(" %X %X %X %X %X %X %X %X\n", tu.tu_rbptr, tu.tu_rcnt,		tu.tu_wbptr, tu.tu_wcnt, tu.tu_state, tu.tu_flag,		tu.tu_addr, tu.tu_count);#endif	s = splx(TUIPL);	tu.tu_flag = 0;	(void) mfpr(CSRD);	mtpr(CSRS, IE);		/* in case we were flushing */	mtpr(CSTS, IE);	tu.tu_state = TUS_IDLE;	if (!tutab.b_active) {		wakeup((caddr_t)&tu);		goto retry;	}	if (tu.tu_toerrs++ < MAXERRS) {		tustart();		goto retry;	}	if ((bp = tutab.b_actf) != NULL) {		bp->b_flags |= B_ERROR;		tutab.b_active = NULL;		tutab.b_actf = bp->av_forw;		if ((bp->b_flags&B_READ) == 0)			tu_vee(&tu_pcnt[minor(bp->b_dev)&DNUM]);		timeout(iodone,bp,1);		tu.tu_toerrs = 0;		tustart();	}retry:	splx(s);	timeout(tuwatch, (caddr_t)0, hz);}tu_pee(cp)	char *cp;{	register int s;	s = splx(TUIPL);	if (++(*cp) > NTUQ)		sleep(cp, PRIBIO);	splx(s);}tu_vee(cp)	char *cp;{	register int s;	s = splx(TUIPL);	if (--(*cp) <= NTUQ)		wakeup(cp);	splx(s);}tu_restart(){	register int s;		s = splx(TUIPL);	tu.tu_flag = 0;	(void) mfpr(CSRD);	mtpr(CSRS, IE);		/* in case we were flushing */	mtpr(CSTS, IE);	tu.tu_state = TUS_IDLE;	timeout(tustart, (caddr_t)0, hz * 4);	splx(s);}#endif

⌨️ 快捷键说明

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