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

📄 dmf.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
	  while ((tp->t_state & TS_CARR_ON) == 0) {		tp->t_state |= TS_WOPEN;		inuse = tp->t_state&TS_INUSE;		sleep((caddr_t)&tp->t_rawq, TTIPRI);		/*		 * See if wakeup was due to a false call.		 */		if (dmfmodem[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);		}	  }	/*	 * 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;	splx(s);	return ((*linesw[tp->t_line].l_open)(dev, tp));}/* * Close a DMF32 line. *//*ARGSUSED*/dmfclose(dev, flag)	dev_t dev;	int flag;{	register struct tty *tp;	register unit;	register dmf, s;	register struct dmfdevice *addr;	unit = minor(dev);	if(unit & 0200)		return(dmflclose(dev,flag));	dmf = unit >> 3;	tp = &dmf_tty[unit];	if (tp->t_line)		(*linesw[tp->t_line].l_close)(tp);	(void) dmfmctl(unit, DMF_BRK, DMBIC);	if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_ISOPEN)==0) {		(void) dmfmctl(unit, DMF_OFF, DMSET);		tp->t_state &= ~TS_CARR_ON; /* prevents recv intr. timeouts */		if ((tp->t_cflag & CLOCAL) == 0) {			/*			 * Raise spl to insure that no timeouts expire before			 * the sleep is posted (in the event of interrupt).			 */			s = spl5();			/*drop DTR for at least a half sec. if modem line*/			tp->t_state |= TS_CLOSING;			/* wait for DSR to drop */			addr = (struct dmfdevice *)tp->t_addr;			addr->dmfcsr = DMF_IE | DMFIR_TBUF | (unit&LINEMASK);			/*			 * If the DSR signal is being followed, give the modem			 * at most 5 seconds to drop.			 */			if (dmfdsr && (addr->dmfrms&DMF_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);			tp->t_state &= ~(TS_CLOSING);			wakeup((caddr_t)&tp->t_rawq);			splx(s);		}	}	dmfsoftCAR[dmf] &= ~(1<<(unit&LINEMASK));	dmfsoftCAR[dmf] |= (1<<(unit&LINEMASK)) & dmfdefaultCAR[dmf];	ttyclose(tp);	dmfmodem[unit] = 0;	tty_def_close(tp);}dmfread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	if(minor(dev)&0200) return(ENXIO);	tp = &dmf_tty[minor(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio));}dmfwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	if(minor(dev)&0200)		return(dmflwrite(dev,uio));	tp = &dmf_tty[minor(dev)];	return ((*linesw[tp->t_line].l_write)(tp, uio));}/* * DMF32 receiver interrupt. */dmfrint(dmf)	int dmf;{	register struct tty *tp;	register c, flg;	register struct dmfdevice *addr;	register struct tty *tp0;	struct uba_device *ui;	register int line;	int overrun = 0;	register u_char *modem0, *modem;	int modem_cont;	ui = dmfinfo[dmf];	if (ui == 0 || ui->ui_alive == 0)		return;	addr = (struct dmfdevice *)ui->ui_addr;	tp0 = &dmf_tty[dmf<<3];	modem0 = &dmfmodem[dmf<<3];	/*	 * Loop fetching characters from the silo for this	 * dmf until there are no more in the silo.	 */	while ((c = addr->dmfrbuf) < 0) {		line = (c>>8)&LINEMASK;		tp = tp0 + line;		flg = tp->t_iflag;		modem = modem0 + line;#ifdef	DMFDEBUG		if (dmfdebug>1)			mprintf("dmfrint: tp=%x, c=%x\n", tp, c);#endif		/* check for modem transitions */		if (c & DMF_DSC) {#ifdef	DMFDEBUG			if (dmfdebug)				mprintf("dmfrint: DSC, tp=%x, rms=%x\n",					tp, addr->dmfrms);#endif			if (tp->t_cflag & CLOCAL)				continue;			addr->dmfcsr = DMF_IE | DMFIR_TBUF | line;			modem_cont = 0;			/*			 * Drop DTR immediately if DSR gone away.			 * If really an active close then do not			 *    send signals.			 */			if ((addr->dmfrms&DMF_DSR)==0)	{				 if (tp->t_state&TS_CLOSING) {					untimeout(wakeup, (caddr_t) &tp->t_dev);					wakeup((caddr_t) &tp->t_dev);#ifdef DMFDEBUG					if (dmfdebug)					   mprintf("dmfrint: dsr closing down, tp=%x\n", tp);#endif					continue;				 }				 if (tp->t_state&TS_CARR_ON) {					/* 					 * Only drop line if DSR is being followed. 					 */					if (dmfdsr) {						dmf_tty_drop(tp);						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->dmfrms&DMF_CAR)==0) {				if (*modem & MODEM_CD) {				    /* only start timer once */				    if (dmfdebug)					mprintf("dmfrint, cd_drop, tp=%x\n", tp);				    *modem &= ~MODEM_CD;				    dmftimestamp[minor(tp->t_dev)] = time;				    timeout(dmf_cd_drop, tp, hz*dmfcdtime);				    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(dmf_cd_drop, tp);					if (dmf_cd_down(tp))						/* drop connection */						dmf_tty_drop(tp);					*modem |= MODEM_CD;				        modem_cont = 1;			       }			/* CTS flow control check */			if (tp->t_state&TS_CARR_ON)				if ((addr->dmfrms&DMF_CTS)==0) {					tp->t_state |= TS_TTSTOP;					*modem &= ~MODEM_CTS;					if (dmfdebug)					   mprintf("dmfrint: CTS stop, tp=%x\n", tp);					dmfstop(tp, 0);					continue;				} else if ((*modem&MODEM_CTS)==0) {					    tp->t_state &= ~TS_TTSTOP;					    *modem |= MODEM_CTS;					    if (dmfdebug)					       mprintf("dmfrint: CTS start, tp=%x\n", tp);					    dmfstart(tp);					    continue;					}			/*			 * Avoid calling dmfstart due to a carrier transition.			 */			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 the DSR signal is being followed, wait at most			 * 30 seconds for CD, and don't transmit in the first 			 * 500ms.  Otherwise immediately look for CD|CTS.			 */			if (dmfdsr) {				if ((addr->dmfrms&DMF_XMIT)==DMF_XMIT				    && (*modem&MODEM_DSR_START)==0)					dmf_start_tty(tp);				else				    if ((addr->dmfrms&DMF_DSR) &&					(*modem&MODEM_DSR)==0) {					*modem |= (MODEM_DSR_START|MODEM_DSR);					/*					 * we should not look for CTS|CD for					 * about 500 ms.					 */					timeout(dmf_dsr_check, tp, hz*30);					timeout(dmf_dsr_check, tp, hz/2);				    }			}			/*			 * Ignore DSR 			 */			else				if ((addr->dmfrms & DMF_NODSR) == DMF_NODSR)					dmf_start_tty(tp);			continue;			} /* end of modem transition tests */		if ((tp->t_state&TS_ISOPEN)==0) {			wakeup((caddr_t)&tp->t_rawq);			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 		 */		/* DMF_FE is interpreted as a break */		if (c & DMF_FE) {			/* 			 * 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 DMFDEBUG				if (dmfdebug)					mprintf("dmfrint: BREAK RECEIVED\n");#endif DMFDEBUG				if ((tp->t_lflag_ext & PRAW) && 					(tp->t_line != TERMIODISC))					c = 0;				else {				    ttyflush(tp, FREAD|FWRITE);#ifdef DMFDEBUG				    if (dmfdebug)					mprintf("sending signal to tp->t_pgrp = %d\n", tp->t_pgrp);#endif DMFDEBUG				    gsignal(tp->t_pgrp, SIGINT);				    continue;				}			}			/*			 * TERMIO: If neither IGNBRK or BRKINT is set, a			 * break condition is read as a single '\0',			 * or if PARMRK is set as '\377','\0,'\0'.			 */			else {				if (flg & PARMRK){					(*linesw[tp->t_line].l_rint)(0377,tp);					(*linesw[tp->t_line].l_rint)(0,tp);				}				c = 0;			}				}		/* Parity Error */		else if (c & DMF_PE){			/* 			 * If input parity checking is not enabled, clear out			 * parity error in this character.			 */#ifdef DMFDEBUG			if (dmfdebug > 1)				mprintf("dmfrint: Parity Error\n");#endif DMFDEBUG			if ((flg & INPCK) == 0)				c &= ~DMF_PE;			else {				if (flg & IGNPAR)					continue;				/* If PARMRK is set, return a character with				 * framing or parity errors as a 3 character				 * sequence (0377,0,c).				 */				if (flg & PARMRK){					(*linesw[tp->t_line].l_rint)(0377,tp);					(*linesw[tp->t_line].l_rint)(0,tp);				}				/*				 * TERMIO: If neither PARMRK or IGNPAR is set, a				 * parity error is read as a single '\0'.				 */				else 					c = 0;			}		}		/* SVID does not say what to do with overrun errors */		if ((c & DMF_DO) && overrun == 0) {			printf("dmf%d: recv. fifo overflow\n", dmf);			overrun = 1;		}		if (flg & ISTRIP){			c &= 0177;			}		else {			c &= 0377;				/* If ISTRIP is not set a valid character of 377			 * is read as 0377,0377 to avoid ambiguity with			 * the PARMARK sequence.			 */ 			if ((c == 0377) && (tp->t_line == TERMIODISC) &&			    (flg & PARMRK))				(*linesw[tp->t_line].l_rint)(0377,tp);		}#if NHC > 0		if (tp->t_line == HCLDISC) {			HCINPUT(c, tp);		} else#endif			(*linesw[tp->t_line].l_rint)(c, tp);	}}/* * Ioctl for DMF32. *//*ARGSUSED*/dmfioctl(dev, cmd, data, flag)	dev_t dev;	register int cmd;	caddr_t data;	int flag;{	register int unit = minor(dev);	register struct dmfdevice *dmfaddr;	register struct tty *tp;	register int dmf;	register int s;	struct uba_device *ui;	struct dmf_softc *sc;	struct devget *devget;	int error;	if(unit & 0200)		return (ENOTTY);	tp = &dmf_tty[unit];	dmf = unit >> 3;	ui = dmfinfo[dmf];	sc = &dmf_softc[ui->ui_unit];	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);	if (error >= 0)		return (error);	error = ttioctl(tp, cmd, data, flag);	if (error >= 0) {		/*		 * If the call is to set terminal attributes which are		 * represented in the device's line parameter register then		 * call the param routine to update the device registers.		 */ 		switch(cmd) {			case TCSANOW:			/* POSIX termios */			case TCSADRAIN:			/* POSIX termios */			case TCSAFLUSH:			/* POSIX termios */ 			case TCSETA:			/* SVID termio */ 			case TCSETAW:			/* SVID termio */ 			case TCSETAF:			/* SVID termio */ 			case TIOCSETP:			/* Berkeley sgttyb */ 			case TIOCSETN:			/* Berkeley sgttyb */			case TIOCLBIS:			/* Berkeley lmode */			case TIOCLBIC:			/* Berkeley lmode */			case TIOCLSET:			/* Berkeley lmode */			case TIOCLGET:			/* Berkeley lmode */ 				dmfparam(unit); 				break; 		}		return (error);	}	switch (cmd) {	case TIOCSBRK:

⌨️ 快捷键说明

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