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

📄 dmz.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)dmz.c	4.1	(ULTRIX)	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1985-88 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.	* *									* ************************************************************************//* * dmz.c  6.1	7/29/83 * * Modification history * * DMZ32 terminal driver * *  5-May-85 - Larry Cohen * *	Derived from 4.2BSD labeled: dmz.c	6.1	83/07/29. *	Add dma support, switch between dma and silo - derived from UCB. * * 16-Jan-86 - Larry Cohen * *	Add full DEC standard 52 support. * * 18-Mar-86 - jaw * *	br/cvec changed to NOT use registers. * * 14-Apr-86 - jaw * *	remove MAXNUBA references.....use NUBA only! * * 26-Apr-86 - ricky palmer * *	Added new DEVIOCGET ioctl request code. V2.0 * * 11-Jul-86 - ricky palmer * *	Added adpt and nexus fields to DEVIOCGET code. * * 05-Aug-86 - Tim Burke * *	In dmzrint, record present time in timestamp in the event of *	a carrier drop. * * 12-Aug-86 - Tim Burke * *	Set dmz_mindma to a value of 200 to prevent dma transfers from occuring. *	This is to aviod hardware problems with NXM errors, and should be *	changed back when the device is fixed. * * 25-Aug-86 - Tim Burke * *	Insure that line is dropped and will restart on a false call to modem. *	Also change state to ~TS_CARR_ON to kill associated processes. * * 26-Aug-86 - rsp (Ricky Palmer) * *	Cleaned up devioctl code to (1) zero out devget structure *	upon entry and (2) use strlen instead of fixed storage *	for bcopy's. Fixed code to handle 24 lines instead of 32. * *  4-Dec-86 - Tim Burke * *	Bug fix to modem control.  In dmz_tty_drop routine, clear the stopped *	state to prevent modem lines from hanging on close.   * * 15-Dec-86 - Tim Burke * *	When a break occurs, (interpreted as a framing error) set the variable *	c to be the interrupt character.  There was a problem here due to the *	fact that sign extension is done which causes unwanted side affects. To *	solve this bug, the character is stripped to 8 bits. * *	Modified probe routine to wait for self test to complete. * *	Fix DEVIOGET to return propper modem status information. * *   9-Jan-86 - Tim Burke * *	Bug fix to TIOCMODEM to clear modem flags if signals are not up. * * 28-Jan-87 - Tim Burke * *	Added the capability to ignore the "DSR" modem signal.  This is being *	done to allow modems that do not follow DEC Standard 52 to still  *	function as they would have prior to the addition of DECSTD52 code *	into the drivers.  If the driver is setup to ignore "DSR" then it will *	not be following DECSTD52.  To follow DECSTD52 set dmzdsr to "1", to *	ignore "DSR" set dmzdsr to be "0"; * *  3-Mar-87 - Tim Burke * *	Added full TERMIO functionality to terminal subsystem. *	Fixup master reset code in probe routine to work on a per-octet basis. * * *  27-Jul-87 - Dan Stuart & Tim Burke * *    Changed to properly link logical and physical lines, and index *    properly into dmz_tty.  Finishes 32 -> 24 lines changes by rsp above. * *  8-Sep-87 - rsp (Ricky Palmer) * *      Defined and used LINEMASK where appropriate to correctly set *      line number. * *  9-Sept-87 - Tim Burke * *	Added support for hardware auto flow control on the outgoing side.  This *	will provide quick response to start/stop characters which will reduce *	buffer overflow on the receiving device. * * *  1-Dec-87 - Tim Burke * *	Added support for both System V termio(7) and POSIX termios(7).  These *	changes also include support for 8-bit canonical processing.  Changes *	involve: * *	- Default settings on first open depend on mode of open.  For termio *	  opens the defaults are "RAW" style, while non-termio opens default *	  to the traditional "cooked" style. *	- The driver now represents its terminal attributes and special  *	  characters in the POSIX termios data structure.  This contrasts the *	  original approach of storing attributes and special chars in the *	  t_flags, ltchars and tchars. *	- New termio ioctls: TCSANOW, TCSADRAIN, TCSADFLUSH, TCSETA, TESETAW, *	  TCSETAF.	 *	- Addition of LPASS8 to local mode word for 8-bit canonical support. * * 29-Jan-88 - Tim Burke *	Changed most softCAR[unit&LINEMASK] references to use the CLOCAL *	bit of the control flags to determine if the line is set to be a *	modem line or a direct connect.  The setting of softCAR[] remains *	to allow one to set default settings for device open. * * 16-May-88 - Tim Burke * * 	Call param routine for setting of local mode word because it can  * 	affect bit size and parity. * * 14-Jul-88 - Tim Burke * * 	The probe routine has been modified to accept only one parameter. *	The controller number is not passed to this routine. * * 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. * * 18-Aug-88 - Tim Burke * *	If PARMRK is set and a BREAK occurs, return '\0377','\0','\0'. * * 25-Jan-89 - Randall Brown * *	Changed cd_drop to look at LNOHANG.  Changed close routine to look *	at HUPCL. * * 12-Jun-89 - dws * *	Added trusted path support. * * 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. * * 15-Aug-89 - Randall Brown * *	Changed all references of TCSADFLUSH to TCSAFLUSH  * * 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. */#include "dmz.h"#if NDMZ > 0  || defined(BINARY)#include "../data/dmz_data.c"int dmzdebug = 0;/* * Definition of the driver for the auto-configuration program. * There are three sets of interrupt vectors for the dmz32 - one set * for each octet of lines. */int	dmzprobe(), dmzattach(), dmzrinta(), dmzxinta(), dmzbaudrate(),		dmzrintb(), dmzxintb(), dmzrintc(), dmzxintc();int	dmz_cd_drop(), dmz_dsr_check(), dmz_cd_down(), dmz_tty_drop();struct	timeval dmzzerotime = {0,0};int	dmzcdtime = 2;u_short dmzstd[] = { 0 };struct	uba_driver dmzdriver =	{ dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo };int	dmz_timeout = 10;		/* silo timeout, in ms */	/*	 * dmz_mindma should be set to a value of 4, such that dma is performed	 * on blocks of four or greater characters to transfer.  Presently	 * there is a hardware problem in the dmz device causing large	 * numbers of NXM errors to occur.  These errors could potentially	 * cause system panics.  As a temporary fix, the value of dmz_mindma	 * is set to be greater that 60 (which is the largest possible clist	 * size, which prevents dma from being done.  This fix could	 * potentially degrade performance to produce stable operation.	 */int	dmz_mindma = 200;		/* don't dma below this point *//* * Local variables for the driver */char	dmz_speeds[] =	{ 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 };short	dmz_valid_speeds = 0x7fbf; /* 0,1,1,1, 1,1,1,1, 1,0,1,1, 1,1,1,1 */int	dmzstart(), ttrstrt();#define NUMLINES 24		     	/* 24 lines on a DMZ */#ifndef MODEM_CD#define MODEM_CD   0x01#define MODEM_DSR  0x02#define MODEM_CTS  0x04#define MODEM_DSR_START  0x08#endif/* * The clist space is mapped by the driver onto each UNIBUS. * The UBACVT macro converts a clist space address for unibus uban * into an i/o space address for the DMA routine. */#define UBACVT(x, uban) 	(cbase[uban] + ((x)-(char *)cfree))/* * Routine for configuration to set dmz interrupt. *//*ARGSUSED*/dmzprobe(reg)	caddr_t reg;{	register struct dmzdevice *dmzaddr = (struct dmzdevice *)reg;	register struct octet *oaddr;	register int totaldelay;#ifdef lint	dmzxinta(0); dmzrinta(0);	dmzxintb(0); dmzrintb(0);	dmzxintc(0); dmzrintc(0);#endif	if(dmzdebug)		printf("dmzprobe\n");	/*	 * If a self test is not being done, start one up.  Wait for the	 * self-test to complete before interrupting. Done on a per-octet basis.	 */	for ( oaddr=dmzaddr->octets; oaddr<=dmzaddr->octets+2; ++oaddr ) {	    if ( (oaddr->dmzcsr&DMZ_CLR) == 0 )	        oaddr->dmzcsr |= DMZ_CLR;	    totaldelay = 0;	    while ( (oaddr->dmzcsr&DMZ_CLR) && (totaldelay<=70) ) {	        totaldelay++;	        DELAY(50000);	    }	    if ( oaddr->dmzcsr & DMZ_CLR )	        printf("Warning: DMZ Master Clear failure, octet %d\n",	            oaddr-dmzaddr->octets);	}	if ((dmzaddr->dmzccsr0 & DMZ_IDENT) != DMZ_IDENT) {		printf("dmzprobe: not a dmz\n");		return;	}	br = 0x15;	/* load base of interrupt vectors */	dmzaddr->dmzccsr0 = ((uba_hd[numuba].uh_lastiv -= 4*6) >> 2);	/* try to generate an interrupt on the first octet */	oaddr = dmzaddr->octets;  /* first octet */	oaddr->dmzcsr = DMZ_IE | DMZIR_LCR;	oaddr->dmzlcr = DMZ_TE | DMZ_FLUSH;	DELAY(100000);		/* wait 1/10'th of a sec for interrupt */	{ int temp = oaddr->dmzcsr; /* clear interrupt flag */ }	if (cvec && cvec != 0x200) /* check to see if interrupt occurred */		cvec -= 4;	   /* point to first interrupt vector (recv)*/	else		uba_hd[numuba].uh_lastiv += 4*6; /* no interrupt						  * restore floating vector.						  */	/* NEED TO SAVE IT SOMEWHERE FOR OTHER DEVICES */	return (sizeof (struct dmzdevice));}/* * Routine called to attach a dmz. */dmzattach(ui)	struct uba_device *ui;{	dmzsoftCAR[ui->ui_unit] = ui->ui_flags;	dmzdefaultCAR[ui->ui_unit] = ui->ui_flags;	if (dmzdebug)		printf("dmzattach: unit=%d, flags=%x\n",			ui->ui_unit, ui->ui_flags);}/* * Open a DMZ32 line, mapping the clist onto the uba if this * is the first dmz on this uba.  Turn on this dmz if this is * the first use of it. *//*ARGSUSED*/dmzopen(dev, flag)	dev_t dev;{	register struct tty *tp;	register int unit, dmz, octetnum;	register struct octet *oaddr;	/* pointer to octet set */	register struct uba_device *ui;        register int maxdmzlines;	int s;	int inuse;  /*hold state of inuse bit while blocked waiting for carr*/	unit = minor(dev);	dmz = unit / NUMLINES;  /* module number */        maxdmzlines = ndmz;     /* NDMZ * 24 = maximun number of line */        if (unit >= maxdmzlines || (ui = dmzinfo[dmz])== 0 || ui->ui_alive == 0)              return (ENXIO);	tp = &dmz_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);        octetnum = ( unit % NUMLINES ) / 8;           /* get octet #, line # later */	oaddr = &((struct dmzdevice *)ui->ui_addr)->octets[octetnum];	tp->t_addr = (caddr_t)oaddr;	tp->t_oproc = dmzstart;	tp->t_baudrate = dmzbaudrate;	tp->t_state |= TS_WOPEN;#ifdef DMZDEBUG	if (dmzdebug)		mprintf("dmzopen: unit=%d, oaddr=%x, tp=%x\n", unit, oaddr, tp);#endif	/*	 * While setting up state for this uba and this dmz,	 * block uba resets which can clear the state.	 */	s = spl5();	while (tty_ubinfo[ui->ui_ubanum] == -1)		/* need this lock because uballoc can sleep */		sleep(&tty_ubinfo[ui->ui_ubanum], TTIPRI);	if (tty_ubinfo[ui->ui_ubanum] == 0) {		tty_ubinfo[ui->ui_ubanum] = -1;		tty_ubinfo[ui->ui_ubanum] =		    uballoc(ui->ui_ubanum, (caddr_t)cfree,			nclist*sizeof(struct cblock), 0);		wakeup(&tty_ubinfo[ui->ui_ubanum]);	}	cbase[ui->ui_ubanum] = tty_ubinfo[ui->ui_ubanum]&0x3ffff;	oaddr->dmzcsr |= DMZ_IE;	splx(s);	if ((tp->t_state&TS_ISOPEN) == 0) {		dmzmodem[unit] = MODEM_DSR_START;		oaddr->dmzrsp = dmz_timeout;	}	tty_def_open(tp, dev, flag, (dmzsoftCAR[dmz]&(1<<(unit%NUMLINES))));	dmzparam(unit);	/*	 * Wait for carrier, then process line discipline specific open.	 */	s = spl5();	dmzmctl(dev, DMZ_ON, DMSET);	/* assert DTR */	if (tp->t_cflag & CLOCAL) {#ifdef DMZDEBUG		if (dmzdebug)			mprintf("dmzopen: local, unit=%d\n", unit);#endif		tp->t_state |= TS_CARR_ON;		dmzmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR;	} else		if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) {		    oaddr->dmzcsr = DMZ_IE | DMZIR_TBUF | (unit&07);		    /*		     * DSR should not come up until DTR is asserted		     * normally.  However if TS_HUPCL is not set it is		     * possible to get here with all modem signals		     * already asserted.  Or we could be dealing with		     * an enormously slow modem and it has not deasserted		     * DSR yet.		     */		   if (oaddr->dmzrms&DMZ_DSR) {#ifdef notdef			timeout(wakeup, (caddr_t) &tp->t_dev, 2*hz);			sleep((caddr_t)&tp->t_dev, PZERO-10);#endif#ifdef DMZDEBUG			if ((dmzdebug) && (oaddr->dmzrms&DMZ_DSR))					mprintf("dmz%d: DSR up before DTR\n", unit);#endif DMZDEBUG		    }		     /*		      * lets assume we have a valid DSR signal now		      */		    oaddr->dmzcsr = DMZ_IE | DMZIR_TBUF | (unit&07);#ifdef DMZDEBUG			if (dmzdebug)				mprintf("dmzopen: is dsr up?, unit=%d\n", unit);#endif			/*			 * 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 (dmzdsr) {			    if (oaddr->dmzrms&DMZ_DSR) {#ifdef DMZDEBUG				if (dmzdebug)					mprintf("dmzopen: dsr up, unit=%d\n", unit);#endif				dmzmodem[unit] |= (MODEM_DSR_START|MODEM_DSR);				tp->t_dev = dev; /* need it for timeouts */				timeout(dmz_dsr_check, tp, hz*30);				timeout(dmz_dsr_check, tp, hz/2);			    }			}			else {				dmzmodem[unit] |= (MODEM_DSR_START|MODEM_DSR);				dmz_dsr_check(tp);			}		}	if (flag & (O_NDELAY|O_NONBLOCK)) {#ifdef DMZDEBUG		if (dmzdebug)			mprintf("dmzopen: O_NDELAY, unit=%d\n", unit);#endif		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 wakeup is due to a false call. 		 */ 		if (dmzmodem[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 DMZ32 line. *//*ARGSUSED*/dmzclose(dev, flag)	dev_t dev;	int flag;{	register struct tty *tp;	register unit;	register dmz, s;	register struct octet *addr;	unit = minor(dev);	dmz = unit / NUMLINES;	tp = &dmz_tty[unit];#ifdef DMZDEBUG	if (dmzdebug)		mprintf("dmzclose: unit=%d, oaddr=%x\n", unit, tp->t_addr);#endif	s = spl5();	if (tp->t_line)		(*linesw[tp->t_line].l_close)(tp);	(void) dmzmctl(unit, DMZ_BRK, DMBIC);	if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_ISOPEN)==0) {		(void) dmzmctl(unit, DMZ_OFF, DMSET);		tp->t_state &= ~TS_CARR_ON; /* prevents recv intr. timeouts */		if ((tp->t_cflag & CLOCAL) == 0) {#ifdef DMZDEBUG			if (dmzdebug)				mprintf("dmzclose: drop dtr, unit=%d, oaddr=%x\n", unit, tp->t_addr);#endif			tp->t_state |= TS_CLOSING;			/* wait for DSR to drop */			addr = (struct octet *)tp->t_addr;			addr->dmzcsr = DMZ_IE | DMZIR_TBUF | (unit&07);			/*			 * If the DSR signal is being followed, give the modem			 * 5 seconds to deasset it.			 */			if (dmzdsr && (addr->dmzrms&DMZ_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);#ifdef DMZDEBUG			if (dmzdebug && (addr->dmzrms&DMZ_DSR) )				mprintf("dmzclose: dsr still on, unit=%d, oaddr=%x\n", unit, tp->t_addr);#endif			tp->t_state &= ~(TS_CLOSING);			wakeup((caddr_t)&tp->t_rawq);		}	}	/* reset line to default mode */	dmzsoftCAR[dmz] &= ~(1<<(unit%NUMLINES));	dmzsoftCAR[dmz] |= (1<<(unit%NUMLINES)) & dmzdefaultCAR[dmz];	ttyclose(tp);	dmzmodem[unit] = 0;	tty_def_close(tp);	splx(s);}dmzread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	tp = &dmz_tty[minor(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio));}dmzwrite(dev, uio)	dev_t dev;	struct uio *uio;{

⌨️ 快捷键说明

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