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

📄 fc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic char *sccsid = "@(#)fc.c	4.1	(ULTRIX)	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1985, 1986, 1987 by		* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************/#include "fc.h"#if NFC > 0 || defined(BINARY)/* *  Firefox serial line unit driver * *  Modification History: * * 31-Oct-89 - Randall Brown * *	Added the support to allow the device to determine if baudrate is  *	supported before it is set in the tty data structures. * * 15-Aug-89 - Randall Brown * *	Changed all references of TCSADFLUSH to TCSAFLUSH  * * 21-Jul-89 - Randall Brown * *	Moved default open and default close code to tty.c and call it *	using tty_def_open() and tty_def_close().  In the close routine, *	don't clear the baudrate so that subsequent opens will keep the *	present attributes.  This only applies to a Berkeley environment. * * 12-Jun-89 - dws *	Added trusted path support. * * 15-Feb-89 - darrell *	Removed the global variable ka60_expect_memerr. * * 12-Jan-89 - jaw *	merge Xe changes for FFox drivers * * 25-Jan-89 - Randall Brown * *	Changed cd_drop to look at LNOHANG.  Changed close routine to look *	at HUPCL. * * 20-Jan-89 - darrell *	Cleanup, and added a module counter to keep track of the number *	of memory modules in the system. * * 18-Nov-88 - darrell (for tim) *	Fixed a bug where the system would hang during boot if a character *	was typed on the keyboard or if the mouse was moved. * * 28-Sep-88 - darrell *	Changed all writes to fbicsr to be read-modif-write accesses *	so as to not change the value of the LEDS on any hardware modules. * * 28-Sep-88 - Randall Brown *	Fixed a bug in fcxint so that the transmitter interrupt will be *	acknowledged when the terminal is in the stop state. * * 27-Sep-88 - darrell *	Added mapping code for FGCTSIXSmap. * * 13-Sep-88 - Ali Rafieymehr * *	Fixed a bug which was causing the "select" not to work for *	alternate console. * * 02-Sep-88 - Tim Burke * *	Return EINVAL instead of ENOTTY for POSIX programs on invalid ioctls. * * 18-Aug-88 - Tim Burke * *	If PARMRK is set and a BREAK occurs, return '\0377','\0','\0'. * * 5-Aug-88 - Tim Burke * *	Return the 2 character sequence 0377, 0377 upon receipt of a valid *	0377 character only when PARMRK is set under the termio line disc. * * 12-15-87	darrell *	Copied this file from ss.c. */#include "../data/fc_data.c"int fcdebug = 0;int fcbail1 = 0;	/* Bit spin count failures */int fcbail2 = 0;int fcbail3 = 0;int ff_diagcons = 0;	/* 0 = LEGSS, 1 = VT220 *//** Driver information for auto-configuration stuff.*/int	fcprobe(), fcattach(), fcrint();int	fc_cd_drop(), fc_dsr_check(), fc_cd_down(), fc_tty_drop(); /* Modem */u_short	fcstd[] = { 0 };struct	uba_driver fcdriver ={ fcprobe, 0, fcattach, 0, fcstd, "fc", fcinfo };int	fcstart(), fcxint(), fcdma(), fcbaudrate();int	ttrstrt();int	fcact;/* * Graphics device driver entry points. * Used to call graphics device driver as needed. */extern	(*vs_gdopen)();extern	(*vs_gdclose)();extern	(*vs_gdread)();extern	(*vs_gdwrite)();extern	(*vs_gdselect)();extern	(*vs_gdkint)();extern	(*vs_gdioctl)();extern	(*vs_gdstop)();#define	FASTTIMER	(hz/30)		/* rate to drain silos, when in use */#define MODEM_UNIT	2		/* Modem control only on unit 2     */#define LINEMASK        0x03            /* line unit mask */int	fcsilos;			/* mask of SLU's with silo in use */int	fctimerintvl;			/* time interval for fctimer */int	fchighrate = 100;		/* silo on if fcchars > fchighrate */int	fclowrate = 75;			/* silo off if fcrate < fclowrate *//** The SLU doesn't interrupt on carrier transitions, so* we have to use a timer to watch it.*/char	fc_timer;		/* timer started? */char	fc_speeds[] ={ 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 };short	fc_valid_speeds = 0x7fbf; /* 0,1,1,1, 1,1,1,1, 1,0,1,1, 1,1,1,1 */u_char fccan_previous;		/* Used to detect modem transitions */extern long cpu_fbic_addr;extern struct mb_node mbus_nodes[];extern struct cpusw *cpup;	/* pointer to cpusw entry */long cpu_fbic_addr;struct	tty		sm_tty;fcprobe(reg)	caddr_t reg;{	register struct fc_regs *fcaddr = (struct fc_regs *)reg;	int	 i;	int	 tries;	/*	 * ONLY on a Firefox	 */	if(cpu != VAX_60)		return(0);	/*	 * Hit master clear to reset chip to known state.	 * Give time for self test to pass.	 */	tries = 0;	fcaddr->fccsr = FC_CLR;	while ((fcaddr->fccsr & FC_CLR) & (tries++ < 10)) {		DELAY(100000);	}#ifdef notdef	/*	 * Cause the DZ to interrupt	 */	fcaddr->fccsr = FC_TIE | FC_MSE;	fcaddr->fctcr = 0x8;            /*  enable line 3 */	/* The DZ should interrupt during this delay */	DELAY(100000);	fcaddr->fccsr = FC_MSE;	fcaddr->fctcr = 0;#endif notdef	return (1);	/* 1 not sizeof anything, just says probe succeeded */}fcattach(ui)	register struct uba_device *ui;{	register struct pdma *pdp = &fcpdma[ui->ui_unit*4];	register struct tty *tp = &fc_tty[ui->ui_unit*4];	register int cntr;	register struct fc_regs *fcaddr = (struct fc_regs *)ffcons;	extern fcscan();	for (cntr = 0; cntr < 4; cntr++) {		/* dzdevice looks wrong, but see vaxuba/pdma.h for reason */		pdp->p_addr = (struct dzdevice *)&fcaddr->fccsr;		pdp->p_arg = (int)tp;		pdp->p_fcn = fcxint;		pdp++, tp++;	}	fcsoftCAR[ui->ui_unit] = ui->ui_flags;	fcdefaultCAR[ui->ui_unit] = ui->ui_flags;	fcmodem = 0; 	if (fc_timer == 0) {		fc_timer++;		timeout(fcscan, (caddr_t)0, hz);		fctimerintvl = FASTTIMER;	}}/*ARGSUSED*/fcopen(dev, flag)	dev_t dev;{	register struct fc_regs *fcaddr = (struct fc_regs *)ffcons;	register struct tty *tp;	register int unit;	register int maj;	int inuse;  /*hold state of inuse bit while blocked waiting for carr*/#	ifdef DEBUG	if (fcdebug > 1)		cprintf("fcopen\n");#	endif DEBUG	maj = major(dev);	/*	 * If a diagnostic console is attached to SLU line 3,	 * don't allow open of the printer port (also line 3).	 * This could cause lpr to write to the console.	 */	if ((ff_diagcons) && (maj == FCMAJOR)) {		if((minor(dev)&LINEMASK) == 3) {		cprintf("out ENXIO 1");			return (ENXIO);		}	}	unit = minor(dev);#	ifdef DEBUG	if (fcdebug > 1)		cprintf("fcopen: unit = %d\n",unit);#	endif DEBUG	if((ff_diagcons) && (maj == CONSOLEMAJOR) && ((unit&LINEMASK) == 0))		unit |= 3;	if (unit >= fc_cnt || fcpdma[unit].p_addr == 0) {#		ifdef DEBUG		if (fcdebug)			cprintf("fcopen:fc_cnt=%d, p_addr=%x\n",fc_cnt, fcpdma[unit].p_addr);#		endif DEBUG		return (ENXIO);	}	/*	 * Never allow open of device 54/0 (/dev/tty00)	 * because it conflicts with 0/0 (/dev/console).	 */	if ((unit == 0) && (maj == FCMAJOR)) {#		ifdef DEBUG		cprintf("out ENXIO 3");#		endif DEBUG		return (ENXIO);	}	/*	 * If the console is a graphics device (VAXstation 2000),	 * don't allow open of device 54/1 (/dev/tty01)	 * because it conflicts with 0/1 (graphics pointer device).	if (vs_gdopen && (unit == 1) && (maj == FCMAJOR)) {#		ifdef DEBUG		if (fcdebug)			cprintf("fcopen: out ENXIO 3.5\n");#		endif DEBUG		return (ENXIO);	}	/*	 * Call the graphics device open routine	 * if there is one and the open if for the fancy tube.	 */	if ((vs_gdopen && (unit <= 1)) || (vs_gdopen && (unit == 2) &&	    (maj == CONSOLEMAJOR)))		return((*vs_gdopen)(dev, flag));	tp = &fc_tty[unit];	if (tp->t_state&TS_XCLUDE && u.u_uid != 0){		return (EBUSY);	}	while (tp->t_state&TS_CLOSING) { /* let DTR stay down for awhile */		sleep((caddr_t)&tp->t_rawq, TTIPRI);	}	tp->t_addr = (caddr_t)&fcpdma[unit];	tp->t_oproc = fcstart;	tp->t_baudrate = fcbaudrate;	tty_def_open(tp, dev, flag, (fcsoftCAR[unit>>2]&(1<<(unit&LINEMASK))));	if ((tp->t_state & TS_ISOPEN) == 0) {		if (unit == MODEM_UNIT)			fcmodem = MODEM_DSR_START;		if((maj == CONSOLEMAJOR) && ((minor(dev)&3) == 0)) {		    tp->t_cflag &= ~CBAUD;		    tp->t_cflag = B9600;		    tp->t_cflag_ext &= ~CBAUD;		    tp->t_cflag_ext = B9600;		    tp->t_flags = ANYP|ECHO|CRMOD;		    tp->t_iflag |= ICRNL; /* Map CRMOD */		    tp->t_oflag |= ONLCR; /* Map CRMOD */		}	} 	fcparam(unit);		/* enables interrupts */	(void) spl6();	/*	 * No modem control provided for lines with softCAR set.	 * Modem control provided only for line 2.	 */        if ((unit != MODEM_UNIT) || (tp->t_cflag & CLOCAL)) {		/*		 * This is a local connection - ignore carrier 		 * receive enable interrupts enabled above via fcparam() 		 */		tp->t_state |= TS_CARR_ON;		/* fcscan sets */		if (unit == MODEM_UNIT)			fcaddr->fcdtr |= (FC_RDTR|FC_RRTS);		/*	 	 * 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;		(void) spl0();		return ((*linesw[tp->t_line].l_open)(dev, tp));	}	/* 	 *  this is a modem line 	 */	/* receive enable interrupts enabled above via fcparam() */	fcaddr->fcdtr |= (FC_RDTR|FC_RRTS);	/*	 * After DSR first comes up we must wait for the other signals	 * before commencing transmission.         */        if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) {		/*		 * Delay before examining other signals if DSR is being followed		 * otherwise proceed directly to fc_dsr_check to look for 		 * carrier detect and clear to send.		 */		if (fcdsr) {			 if ((fcaddr->fcmsr)&FC_RDSR) {				fcmodem |= (MODEM_DSR_START|MODEM_DSR);				tp->t_dev = dev; /* need it for timeouts */				/* 		 		* Give Carrier and CTS 30 sec. to come up.  		 		* Prevent any transmission in the first 500ms.		 		*/				timeout(fc_dsr_check, tp, hz*30);  				timeout(fc_dsr_check, tp, hz/2);			}		}		/* 	 	 * Ignoring DSR so immediately check for CD & CTS.		 */		else {				fcmodem |= (MODEM_DSR_START|MODEM_DSR);				fc_dsr_check(tp);		}	}#	ifdef DEBUG	if (fcdebug)		cprintf("fcopen:  line=%d, state=%x, tp=%x\n", unit,			tp->t_state, tp);#	endif DEBUG        if (flag & (O_NDELAY|O_NONBLOCK))		tp->t_state |= TS_ONDELAY;	else		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 we were awoken by a false call to the modem			 * line by a non-modem. 			 */			if (fcmodem&MODEM_BADCALL){				(void) spl0();				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)) {					(void) spl0();					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;	(void) spl0();	return ((*linesw[tp->t_line].l_open)(dev, tp));}/*ARGSUSED*/fcclose(dev, flag)	dev_t dev;{	register struct tty *tp;	register int unit;	register int s;	register struct fc_regs *fcaddr = (struct fc_regs *)ffcons;	int fc;	extern int wakeup();	unit = minor(dev);	if((ff_diagcons) && (major(dev) == CONSOLEMAJOR) && ((unit&LINEMASK) == 0))		unit |= 3;	/*	 * Call the craphics device close routine	 * if ther is one and the close is for it.	 */	if ((vs_gdclose && (unit <= 1)) || (vs_gdclose && (unit == 2) &&	    (major(dev) == CONSOLEMAJOR))){		(*vs_gdclose)(dev, flag);		return;	}	fc = unit >> 2;#	ifdef DEBUG	if (fcdebug)		cprintf("fcclose: unit=%x, fc=%x\n",unit,fc);#	endif DEBUG	tp = &fc_tty[unit];	/*	 * Do line discipline specific close functions then return here	 * in the old line disc for final closing.	 */	if (tp->t_line)		(*linesw[tp->t_line].l_close)(tp);	/*	 * fcbrk is write-only and sends a BREAK (SPACE condition) until         * the break control bit is cleared. Here we are clearing any 	 * breaks for this line on close.	 */	fcaddr->fcbrk = (fc_brk[fc] &= ~(1 << (unit&LINEMASK)));	if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_WOPEN) || (tp->t_state&TS_ISOPEN)==0) {		tp->t_state &= ~TS_CARR_ON;   /* prevents recv intr. timeouts */		if (unit == MODEM_UNIT) {			/*		 	 * Drop appropriate signals to terminate the connection.		 	 */			fcaddr->fcdtr &= ~(FC_RDTR|FC_RRTS);                        if ((tp->t_cflag & CLOCAL) == 0) {				s = spl6();				/*drop DTR for at least a sec. if modem line*/#				ifdef DEBUG				if (fcdebug)					cprintf("fcclose: DTR drop, state =%x\n"						,tp->t_state);#				endif DEBUG				tp->t_state |= TS_CLOSING;				/*			 	 * Wait at most 5 sec for DSR to go off.  			 	 * Also hold DTR down for a period.			 	 */				if (fcdsr && (fcaddr->fcmsr & FC_RDSR)) {					timeout(wakeup,(caddr_t)&tp->t_dev,5*hz);					sleep((caddr_t)&tp->t_dev, PZERO-10);				}				/*			 	 * Hold DTR down for 200+ ms.			 	 */				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);			}		}		/*		 * No disabling of interrupts is done.  Characters read in on		 * a non-open line will be discarded.		 */	}	/* reset line to default mode */	fcsoftCAR[fc] &= ~(1<<(unit&LINEMASK));	fcsoftCAR[fc] |= (1<<(unit&LINEMASK)) & fcdefaultCAR[fc];	if (unit == MODEM_UNIT)		fcmodem = 0;	ttyclose(tp);	tty_def_close(tp);}/* * fcread() shared with graphics device drivers (sm & sg). */fcread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	register int unit;	unit = minor(dev);	if((ff_diagcons) && (major(dev) == CONSOLEMAJOR) && ((unit&LINEMASK) == 0))		unit |= 3;	if((unit == 1) && vs_gdread)	    return((*vs_gdread)(dev, uio));	if (vs_gdopen && (unit == 2) && (major(dev) == CONSOLEMAJOR))	    tp = &sm_tty;	else	    tp = &fc_tty[unit];	return ((*linesw[tp->t_line].l_read)(tp, uio));}/* * fcwrite() shared with graphics device drivers (sm & sg). */fcwrite(dev, uio)	dev_t dev;	struct uio *uio;

⌨️ 快捷键说明

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