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

📄 dhu.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
	/*	 * Wait for carrier, then process line discipline specific open.	 */	s=spltty();	if (addr->fun.fs.stat & DHU11) {		/*		 * only the dhu11 has a timer. manual says we have to		 * point to line 0 before we set the timer		 * This timer causes a delay before interrupting on the first		 * character in hopes that more than one character can be		 * processed by a single interrupt.		 */		addr->csr.low = DHU_RIE|(0 & LINEMASK); /* set to line 0 */		WBFLUSH();		addr->run.rxtimer = 10;		WBFLUSH();	}	if (tp->t_cflag & CLOCAL) {		/* this is a local connection - ignore carrier */		tp->t_state |= TS_CARR_ON;		dhumodem[unit] |= MODEM_CTS|MODEM_CD|MODEM_DSR;		addr->csr.low = DHU_RIE|(unit & LINEMASK); /* set to line #*/							  /* enable interrupts*/		WBFLUSH();		addr->lnctrl &= ~(DHU_MODEM);		addr->lnctrl |= (DHU_DTR|DHU_RTS|DHU_REN);		WBFLUSH();		splx(s);		/*	 	 * Set state bit to tell tty.c not to assign this line as the 	 	 * controlling terminal for the process which opens this line.	 	 */		if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX))			tp->t_state |= TS_ONOCTTY;		return ((*linesw[tp->t_line].l_open)(dev, tp));	}	addr->csr.low = DHU_RIE|(unit & LINEMASK);	WBFLUSH();	addr->lnctrl |= (DHU_DTR|DHU_RTS|DHU_MODEM|DHU_REN);	WBFLUSH();	/* 	 * If the DSR signal is followed, give carrier 30 secs to come up,	 * and do not transmit/receive data for the first 500ms.  Otherwise	 * immediately to to dhu_dsr_check tolook for CD and CTS. 	 */	if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) {		if (dhudsr) {			if ((addr->fun.fs.stat)&DHU_DSR) {				dhumodem[unit] |= (MODEM_DSR_START|MODEM_DSR);				tp->t_dev = dev; /* need it for timeouts */				timeout(dhu_dsr_check, tp, hz*30);				timeout(dhu_dsr_check, tp, hz/2);			}		}		else {			dhumodem[unit] |= (MODEM_DSR_START|MODEM_DSR);			dhu_dsr_check(tp);		}	}#ifdef DHUDEBUG	if (dhudebug)		mprintf("dhuopen:  line=%d, state=%x, pid=%d\n", unit,			tp->t_state, u.u_procp->p_pid);#endif	if (flag & (O_NDELAY|O_NONBLOCK))		tp->t_state |= TS_ONDELAY;	else {		while ((tp->t_state&TS_CARR_ON)==0) {			inuse = tp->t_state&TS_INUSE;			/*			 * Sleep until all the necessary modem signals			 * come up.			 */			sleep((caddr_t)&tp->t_rawq, TTIPRI); 			/* 			 * See if wakeup is due to a false call. 			 */ 			if (dhumodem[unit]&MODEM_BADCALL){				splx(s); 				return(EWOULDBLOCK);			}			/* if we opened "block if in use"  and			 *  the terminal was not inuse at that time			 *  but is became "in use" while we were			 *  waiting for carrier then return			 */			if ((flag & O_BLKINUSE) && (inuse==0) &&				(tp->t_state&TS_INUSE)) {					splx(s);					return(EALREADY);			}		}	}	splx(s);	/*	 * Set state bit to tell tty.c not to assign this line as the 	 * controlling terminal for the process which opens this line.	 */	if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX))		tp->t_state |= TS_ONOCTTY;	return ((*linesw[tp->t_line].l_open)(dev, tp));}/* * Close a DHU11 line. *//*ARGSUSED*/dhuclose(dev, flag)	dev_t dev;	int flag;{	register struct tty *tp;	register int unit, s;	register struct dhudevice *addr;	register int dhu;	extern int wakeup();	int turnoff = 0;	unit = minor(dev);	dhu = unit >> 4;	tp = &dhu11[unit];	addr = (struct dhudevice *)tp->t_addr;	tp->t_state |= TS_CLOSING;	if (tp->t_line)		(*linesw[tp->t_line].l_close)(tp);	if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_ISOPEN)==0) {		s = spltty();		turnoff++;		addr->csr.low = DHU_RIE|(unit & LINEMASK);		WBFLUSH();		addr->lnctrl &= ~(DHU_DTR|DHU_RTS);  /* turn off DTR */		WBFLUSH();		tp->t_state &= ~TS_CARR_ON; /* prevents recv intr. timeouts */		if ((tp->t_cflag & CLOCAL) == 0) {#ifdef DHUDEBUG			if (dhudebug)				mprintf("dhuclose: DTR drop line=%d, state=%x, pid=%d\n",			unit, tp->t_state, u.u_procp->p_pid);#endif			/*			 * Wait an additional 5 seconds for DSR to drop if			 * the DSR signal is being watched.			 */			if (dhudsr && (addr->fun.fs.stat&DHU_DSR)) {				timeout(wakeup, (caddr_t) &tp->t_dev, 5*hz);				sleep((caddr_t)&tp->t_dev, PZERO-10);			}			timeout(wakeup, (caddr_t) &tp->t_dev, hz/5);			sleep((caddr_t)&tp->t_dev, PZERO-10);		}		splx(s);	}#ifdef DHUDEBUG	if (dhudebug)		mprintf("dhuclose: line=%d, state=%x, pid=%d\n", unit,			tp->t_state, u.u_procp->p_pid);#endif	dhusoftCAR[dhu] &= ~(1<<(unit&LINEMASK));	dhusoftCAR[dhu] |= (1<<(unit&LINEMASK)) & dhudefaultCAR[dhu]; 	ttyclose(tp);  /* remember this will clear out t_state */  	if (turnoff) { 		/* we have to do this after the ttyclose so that output 		 * can still drain 		 */		s = spltty();		addr->csr.low = DHU_RIE|(unit & LINEMASK);		WBFLUSH(); 		addr->lnctrl = NULL; /* turn off interrupts also */		WBFLUSH();		splx(s);	}	dhumodem[unit] = 0;	tty_def_close(tp); 	wakeup((caddr_t)&tp->t_rawq); /* wake up anyone in dhuopen */ }dhuread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp = &dhu11[minor(dev)];		return ((*linesw[tp->t_line].l_read)(tp, uio));}dhuwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp = &dhu11[minor(dev)];	return ((*linesw[tp->t_line].l_write)(tp, uio));}/* * DHU11 receiver interrupt. */dhurint(dhu)	int dhu; /* module number */{	register struct tty *tp;	register int c, flg;	register struct dhudevice *addr;	struct tty *tp0;	register struct uba_device *ui;	int overrun = 0;	register u_char *modem0, *modem;	int unit; 	int modem_cont;	ui = dhuinfo[dhu];	if (ui == 0 || ui->ui_alive == 0)		return;	addr = (struct dhudevice *)ui->ui_addr;	tp0 = &dhu11[dhu<<4];  /* first tty structure that corresponds				* to this dhu11 module				*/	modem0 = &dhumodem[dhu<<4];	/*	 * Loop fetching characters from receive fifo for this	 * dhu until there are no more in the receive fifo.	 */	while ((c = addr->run.rbuf) < 0) {		/* if c < 0 then data valid is set */		unit = (c>>8)&LINEMASK;		tp = tp0 + unit; /* tty struct for this line */		flg = tp->t_iflag;				modem = modem0 + unit;#ifdef DHUDEBUG		if (dhudebug > 7)			mprintf("dhurint0: c=%x, tp=%x\n", c, tp);#endif		/* check for modem transitions */		if ((c & DHU_STAT)==DHU_STAT) {			if (c & DHU_DIAG) /* ignore diagnostic info */				continue;#ifdef DHUDEBUG			if (dhudebug > 4)				mprintf("dhurint: c=%x, tp=%x\n", c, tp);#endif			/*			 * Don't respond to modem status changes on a 			 * direct connect line.  Actually there should not			 * be any modem status interrupts on a direct connect			 * line because the link type is set to non-modem.			 */			if (tp->t_cflag & CLOCAL) 				continue;			/* set to line #*/			addr->csr.low = DHU_RIE|(unit & LINEMASK);			WBFLUSH();			modem_cont = 0;			/* examine modem status */			/*			 * Drop DTR immediately if DSR has gone away.			 * If really an active close then do not			 *    send signals.			 */			if ((addr->fun.fs.stat&DHU_DSR)==0) {				if (tp->t_state&TS_CLOSING) {					untimeout(wakeup, (caddr_t) &tp->t_dev);					wakeup((caddr_t) &tp->t_dev);					continue;				}				if (tp->t_state&TS_CARR_ON) {#ifdef DHUDEBUG					if (dhudebug)						mprintf("dhurint: DSR dropped,line=%d\n",unit);#endif DHUDEBUG					/* 					 * Only drop if DSR is being followed. 					 */					if (dhudsr) {						dhu_tty_drop(tp);						/*						 * Moved the continue here, so						 * that if both DSR & CD change						 * in same interval, we'll see						 * both.						 */						continue;					}				}			}			/*			 * Check for transient CD drops.			 * Only drop DTR if CD is down for more than 2 secs.			 */			if (tp->t_state&TS_CARR_ON)			    if ((addr->fun.fs.stat&DHU_CD)==0){				if ( *modem & MODEM_CD) {				    /* only start timer once */#ifdef DHUDEBUG				    if (dhudebug)					mprintf("dhurint, cd_drop, tp=%x\n", tp);#endif DHUDEBUG				    *modem &= ~MODEM_CD;				    dhutimestamp[minor(tp->t_dev)] = time;				    timeout(dhu_cd_drop, tp, hz*dhucdtime);				    modem_cont = 1;				}			    } else				/*				 * CD has come up again.				 * Stop timeout from occurring if set.				 * If interval is more than 2 secs then				 *  drop DTR.				 */				if ((*modem&MODEM_CD)==0) {					untimeout(dhu_cd_drop, tp);					if (dhu_cd_down(tp)) {						/* drop connection */						dhu_tty_drop(tp);					}					*modem |= MODEM_CD;				        modem_cont = 1;				}			/* CTS flow control check */			if (tp->t_state&TS_CARR_ON)				if ((addr->fun.fs.stat&DHU_CTS)==0) {					tp->t_state |= TS_TTSTOP;					*modem &= ~MODEM_CTS;#ifdef DHUDEBUG					if (dhudebug)					   mprintf("dhurint: CTS stop, line=%d\n", unit);#endif DHUDEBUG					dhustop(tp, 0);					continue;				} else if ((*modem&MODEM_CTS)==0) {					    tp->t_state &= ~TS_TTSTOP;					    *modem |= MODEM_CTS;#ifdef DHUDEBUG					    if (dhudebug)					       mprintf("dhurint: CTS start, line=%d\n", unit);#endif DHUDEBUG					    dhustart(tp);					    continue;					}			/*			 * Avoid calling dhu_start_tty for a CD transition if			 * the connection has already been established.			 */			if (modem_cont)				continue;			/*			 * If 500 ms timer has not expired then dont			 * check anything yet.			 * Check to see if DSR|CTS|CD are asserted.			 * If so we have a live connection.			 * If DSR is set for the first time we allow			 * 30 seconds for a live connection.			 *		    	 * 		    	 * If dhudsr is set look for DSR|CTS|CD, otherwise look 		    	 * for CD|CTS only.		    	 */			if (dhudsr) {				if ((addr->fun.fs.stat&DHU_XMIT)==DHU_XMIT			    	&& (*modem&MODEM_DSR_START)==0)					dhu_start_tty(tp);				else			    	if ((addr->fun.fs.stat&DHU_DSR) &&					(*modem&MODEM_DSR)==0) {					*modem |= (MODEM_DSR_START|MODEM_DSR);					/*				 	* we should not look for CTS|CD for				 	* about 500 ms.				 	*/					timeout(dhu_dsr_check, tp, hz*30);					timeout(dhu_dsr_check, tp, hz/2);			    	}			}			/* 			 * Ignore DSR.			 */			else {				if ((addr->fun.fs.stat&(DHU_CD|DHU_CTS))==(DHU_CD|DHU_CTS))					dhu_start_tty(tp);			}			/*			 * Examination of modem status character is complete.			 * Go back for the next character to avoid passing this			 * status info in the receiver buffer back to the user			 * as a valid character.			 */			continue;		}#ifndef PORTSELECTOR		if ((tp->t_state&TS_ISOPEN)==0) {#else		if ((tp->t_state&(TS_ISOPEN|TS_WOPEN))==0) {#endif			wakeup((caddr_t)tp);			continue;		}/*		This code handles the following termio input flags.  Also *		listed is what the default should be for propper Ultrix *		backward compatibility. * *		IGNBRK		FALSE *		BRKINT		TRUE *		IGNPAR		TRUE *		PARMRK		FALSE *		INPCK		TRUE *		ISTRIP		TRUE 		 */		/* DHU_FERR is interpreted as a break */		if (c & DHU_FERR) {			/*			 * If configured for trusted path, initiate			 * trusted path handling.			 */			if (do_tpath) {				tp->t_tpath |= TP_DOSAK;				(*linesw[tp->t_line].l_rint)(c, tp);				break;			}			if (flg & IGNBRK)				continue;			if (flg & BRKINT) {#ifdef DHUDEBUG			        if (dhudebug)				    mprintf("dhurint: BREAK RECEIVED, tp =%x\n", tp);#endif DHUDEBUG				if ((tp->t_lflag_ext & PRAW) && 					(tp->t_line != TERMIODISC))					c = 0;				else {				    ttyflush(tp, FREAD|FWRITE);#ifdef DHUDEBUG				    if (dhudebug)					mprintf("sending signal to tp->t_pgrp = %d\n", tp->t_pgrp);#endif DHUDEBUG				    gsignal(tp->t_pgrp, SIGINT);				    continue;				}			}			/*			 * TERMIO: If neither IGNBRK or BRKINT is set, a			 * break condition is read as a single '\0',

⌨️ 快捷键说明

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