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

📄 dz.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)dz.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.	* *									* ************************************************************************//* * dz.c  6.1   7/29/83 * * Modification history * * DZ11/DZ32/DZV11/DZQ11 terminal driver * * 18-Mar-86 - jaw * *	Derived from 4.2BSD labeled: dz.c      6.1     83/07/29. *	br/cvec changed to NOT use registers. * * 26-Apr-86 - ricky palmer * *	Added new DEVIOCGET ioctl request code. V2.0 * * 13-Jun-86 - jaw * *	Fix to uba reset and drivers. * * 30-Jun-86 - Tim Burke * *	Bug fix to TIOCMODEM looks first to see if device type is DZ32 *	before examining carrier detect. * * 11-Jul-86 - ricky palmer * *	Added adpt and nexus fields to DEVIOCGET code. * * 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. * * 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. * *  6-Feb-87 - Tim Burke * *	Removed printf of master reset failure in probe routine, as it may be *	incorrectly appearing. (Particularly in the DMF & DMZ drivers) * *  3-Mar-87 - Tim Burke * *	Added full TERMIO functionality to terminal subsystem. * *  8-Sep-87 - Ricky Palmer (rsp) * *	Defined LINEMASK for this driver and replaced all hardcoded *	references to "07" to be LINEMASK. Also fixed DEVIOCGET code to *	use LINEMASK. * *  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. * * 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'. * * 02-Sep-88 - Tim Burke * *	Return EINVAL instead of ENOTTY for POSIX programs on invalid ioctls. * * 23-Sep-88 - Randall Brown * *	Fixed a bug in dzxint so that the transmitter interrupt will be *	acknowledged when the terminal is in the stop state. * * 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 "dz.h"#if NDZ > 0 || defined(BINARY)#include "../data/dz_data.c"#ifdef DZDEBUGint dzdebug = 0;#endif DZDEBUG/** Driver information for auto-configuration stuff.*/int	dzprobe(), dzattach(), dzrint(), dzbaudrate();u_short dzstd[] = { 0 };struct	uba_driver dzdriver ={ dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };int	dzstart(), dzxint(), dzdma();int	ttrstrt();int	dzact;#define dzwait(x)	while (((x)->dzlcs & DZ_ACK) == 0)#define FASTTIMER	(hz/30) 	/* rate to drain silos, when in use */#define LINEMASK        0x07            /* line number mask */int	dzsilos;			/* mask of dz's with silo in use */int	dztimerintvl;			/* time interval for dztimer */int	dzhighrate = 100;		/* silo on if dzchars > dzhighrate */int	dzlowrate = 75; 		/* silo off if dzrate < dzlowrate *//** The dz11 doesn't interrupt on carrier transitions, so* we have to use a timer to watch it.*/char	dz_timer;		/* timer started? */char	dz_speeds[] ={ 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 };short	dz_valid_speeds = 0x3fbf; /* 0,0,1,1, 1,1,1,1, 1,0,1,1, 1,1,1,1 */dzprobe(reg)	caddr_t reg;{	register struct dzdevice *dzaddr = (struct dzdevice *)reg;	register int totaldelay;#ifdef lint	dzrint(0); dzxint((struct tty *)0);#endif	dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32;	if (dzaddr->dzcsr & DZ_32)		dzaddr->dzlnen = 1;	else		dzaddr->dztcr = 1;		/* enable any line */	DELAY(100000);	dzaddr->dzcsr = DZ_CLR|DZ_32;		/* reset everything */	/*	 * If a self test is not being done, start one up.  Wait for the	 * self-test (to a max of 4 sec.) to complete before interrupting.	 */	if ((dzaddr->dzcsr & DZ_CLR) == 0)	    dzaddr->dzcsr |= DZ_CLR;	totaldelay = 0;	while ( (dzaddr->dzcsr & DZ_CLR) && ( totaldelay <= 70) ){	    totaldelay++;	    DELAY(50000);	}	/*	 * This message may be incorrectly printed - particularly in the	 * DMF & DMZ drivers.	if (dzaddr->dzcsr & DZ_CLR)	    printf("Warning: DZ device failed to exit self-test\n");	 */	if (cvec && cvec != 0x200)		cvec -= 4;	return (sizeof (struct dzdevice));}dzattach(ui)	register struct uba_device *ui;{	register struct pdma *pdp = &dzpdma[ui->ui_unit*8];	register struct tty *tp = &dz_tty[ui->ui_unit*8];	register int cntr;	extern dzscan();	for (cntr = 0; cntr < 8; cntr++) {		pdp->p_addr = (struct dzdevice *)ui->ui_addr;		pdp->p_arg = (int)tp;		pdp->p_fcn = dzxint;		pdp++, tp++;	}	dzsoftCAR[ui->ui_unit] = ui->ui_flags;	dzdefaultCAR[ui->ui_unit] = ui->ui_flags;	if (dz_timer == 0) {		dz_timer++;		timeout(dzscan, (caddr_t)0, hz);		dztimerintvl = FASTTIMER;	}}/*ARGSUSED*/dzopen(dev, flag)	dev_t dev;{	register struct tty *tp;	register int unit;	int inuse;  /*hold state of inuse bit while blocked waiting for carr*/	unit = minor(dev);	if (unit >= dz_cnt || dzpdma[unit].p_addr == 0)		return (ENXIO);	tp = &dz_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)&dzpdma[unit];	tp->t_oproc = dzstart;	tp->t_baudrate = dzbaudrate;	tty_def_open(tp, dev, flag, (dzsoftCAR[unit>>3]&(1<<(unit&LINEMASK))));	dzparam(unit);	(void) dzmctl(dev, DZ_ON, DMSET);	(void) spl5();	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);			/* 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*/dzclose(dev, flag)	dev_t dev;{	register struct tty *tp;	register int unit;	register struct dzdevice *dzaddr;	int dz;	unit = minor(dev);	dz = unit >> 3;	tp = &dz_tty[unit];	(*linesw[tp->t_line].l_close)(tp);	dzaddr = dzpdma[unit].p_addr;	if (dzaddr->dzcsr&DZ_32)		(void) dzmctl(dev, DZ_BRK, DMBIC);	else		dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&LINEMASK)));	if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_WOPEN) || (tp->t_state&TS_ISOPEN)==0) {		(void) dzmctl(dev, DZ_OFF, DMSET);		if (dzsoftCAR[dz] & ((tp->t_cflag & CLOCAL)==0))  {			/*drop DTR for at least a sec. if modem line*/			tp->t_state |= TS_CLOSING;			sleep((caddr_t)&lbolt, PZERO-10);			sleep((caddr_t)&lbolt, PZERO-10);			tp->t_state &= ~(TS_CLOSING);			wakeup((caddr_t)&tp->t_rawq);		}	}	/* reset line to default mode */	dzsoftCAR[dz] &= ~(1<<(unit&LINEMASK));	dzsoftCAR[dz] |= (1<<(unit&LINEMASK)) & dzdefaultCAR[dz];	ttyclose(tp);	tty_def_close(tp);}dzread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	tp = &dz_tty[minor(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio));}dzwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	tp = &dz_tty[minor(dev)];	return ((*linesw[tp->t_line].l_write)(tp, uio));}/*ARGSUSED*/dzrint(dz)	int dz;{	register struct tty *tp;	register int c, flg;	register struct dzdevice *dzaddr;	register struct tty *tp0;	register int unit;	int overrun = 0;	if ((dzact & (1<<dz)) == 0)		return;	unit = dz * 8;	dzaddr = dzpdma[unit].p_addr;	tp0 = &dz_tty[unit];	dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE);	/* the manual says this song */	dzaddr->dzcsr |= DZ_RIE|DZ_MIE; 	/*   and dance is necessary */	while (dzaddr->dzcsr & DZ_MSC) {	/* DZ32 modem change interrupt */		c = dzaddr->dzmtsr;		tp = tp0 + (c&7);		if (tp >= &dz_tty[dz_cnt])			break;		dzaddr->dzlcs = c&7;	/* get status of modem lines */		dzwait(dzaddr); 	/* wait for them */		if (c & DZ_CD)		/* carrier status change? */		if (dzaddr->dzlcs & DZ_CD) {	/* carrier up? */			if ((tp->t_state&TS_CARR_ON) == 0) {				wakeup((caddr_t)&tp->t_rawq);				tp->t_state |= TS_CARR_ON;				tp->t_state &= ~TS_ONDELAY;			}		} else {	/* no carrier */			if (tp->t_state&TS_CARR_ON) {				gsignal(tp->t_pgrp, SIGHUP);				gsignal(tp->t_pgrp, SIGCONT);				dzaddr->dzlcs = DZ_ACK|(c&7);				ttyflush(tp, FREAD|FWRITE);			}			tp->t_state &= ~TS_CARR_ON;		}	}	while ((c = dzaddr->dzrbuf) < 0) {	/* char present */		dzchars[dz]++;		tp = tp0 + ((c>>8)&LINEMASK);		if (tp >= &dz_tty[dz_cnt])			continue;		flg = tp->t_iflag;		if ((tp->t_state & TS_ISOPEN) == 0) {			wakeup((caddr_t)&tp->t_rawq);#ifdef PORTSELECTOR			if ((tp->t_state&TS_WOPEN) == 0)#endif			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 		 */		/* DZ_FE is interpreted as a break */		if (c & DZ_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 DZDEBUG				if (dzdebug)					mprintf("dzrint: BREAK RECEIVED\n");#endif DZDEBUG				if ((tp->t_lflag_ext & PRAW) && 					(tp->t_line != TERMIODISC))					c = 0;				else {				    ttyflush(tp, FREAD|FWRITE);#ifdef DZDEBUG				    if (dzdebug)					mprintf("sending signal to tp->t_pgrp = %d\n", tp->t_pgrp);#endif DZDEBUG				    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 & DZ_PE){			/* 			 * If input parity checking is not enabled, clear out			 * parity error in this character.			 */#ifdef DZDEBUG			if (dzdebug > 1)				mprintf("dzrint: Parity Error\n");#endif DZDEBUG			if ((flg & INPCK) == 0)				c &= ~DZ_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 & DZ_DO) && overrun == 0) {			printf("dz%d: recv. fifo overflow\n", dz);			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);	}}/*ARGSUSED*/dzioctl(dev, cmd, data, flag)	dev_t dev;	register int cmd;	caddr_t data;	int flag;{	register int unit = minor(dev);	register struct tty *tp = &dz_tty[unit];	register int dz = unit >> 3;	register struct dzdevice *dzaddr;	register int s;	struct uba_device *ui = dzinfo[dz];	struct dz_softc *sc = &dz_softc[ui->ui_unit];	struct devget *devget;	int error;	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 */

⌨️ 快捷键说明

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