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

📄 dh.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)dh.c	4.1	ULTRIX	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1988 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.	* *									* ************************************************************************//*	dh.c	6.1	83/07/29	*/#include "dh.h"#if NDH > 0  || defined(BINARY)/* * DH-11/DM-11 driver * 14-Apr-86 -- jaw *	remove MAXNUBA referances.....use NUBA only! * * 18-mar-86  -- jaw     br/cvec changed to NOT use registers. * * 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. * * 15-Dec-87 - Tim Burke * *	changed t_intrc to tp->t_cc[VINTR] so that this code will compile *	without errors in the wake of termio changes.  Note that this driver *	has not been updated to full termio compatibility with the other *	device drivers and will probably not work any more. * * 28-Jan-88 - Tim Burke * *	Changed references to t_ispeed and t_ospeed to use the POSIX cflag. *	This is needed because t_ispeed and t_ospeed have been removed from *	the tty structure. *	These changes have been made to allow this driver to COMPILE in light *	of the termio tty changes.  To date these changes are not complete for *	termio; nor have I been able to test them due to hardware unavailablity. */#include "../data/dh_data.c" /* * Definition of the driver for the auto-configuration program. * There is one definition for the dh and one for the dm. */int	dhprobe(), dhattach(), dhrint(), dhxint(), dhtimer();u_short	dhstd[] = { 0 };struct	uba_driver dhdriver =	{ dhprobe, 0, dhattach, 0, dhstd, "dh", dhinfo };int	dmprobe(), dmattach(), dmintr();u_short	dmstd[] = { 0 };struct	uba_driver dmdriver =	{ dmprobe, 0, dmattach, 0, dmstd, "dm", dminfo };#ifndef PORTSELECTOR#define ISPEED	B300#define IFLAGS	(EVENP|ODDP|ECHO)#define LFLAG (ISIG|ICANON|ECHO)#else#define ISPEED	B4800#define IFLAGS	(EVENP|ODDP)#define LFLAG (ISIG|ICANON)#endif/* termio flags will be set to these default values in non-termio mode to * provide a backward compatible ULTRIX environment. */#define IFLAG (BRKINT|IGNPAR|ISTRIP|IXON|IXANY)#define OFLAG (OPOST)#define CFLAG (PARENB|CREAD|CS7|ISPEED)#define	FASTTIMER	(hz/30)		/* scan rate with silos on */int	dhact;				/* mask of active dh's */int	dhsilos;			/* mask of dh's with silo in use */int	dhhighrate = 100;		/* silo on if dhchars > dhhighrate */int	dhlowrate = 75;			/* silo off if dhrate < dhlowrate */static	short timerstarted;int	dhstart(), ttrstrt();/* * 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 force a dh to interrupt. * Set to transmit at 9600 baud, and cause a transmitter interrupt. *//*ARGSUSED*/dhprobe(reg)	caddr_t reg;{	register struct dhdevice *dhaddr = (struct dhdevice *)reg;#ifdef lint	if (ndh11 == 0) ndh11 = 1;	dhrint(0); dhxint(0);#endif#ifndef notdef	dhaddr->un.dhcsr = DH_RIE|DH_MM|DH_RI;	DELAY(1000);	dhaddr->un.dhcsr &= ~DH_RI;	dhaddr->un.dhcsr = 0;#else	dhaddr->un.dhcsr = DH_TIE;	DELAY(5);	dhaddr->dhlpr = (B9600 << 10) | (B9600 << 6) | BITS7|PENABLE;	dhaddr->dhbcr = -1;	dhaddr->dhcar = 0;	dhaddr->dhbar = 1;	DELAY(100000);		/* wait 1/10'th of a sec for interrupt */	dhaddr->un.dhcsr = 0;	if (cvec && cvec != 0x200)		cvec -= 4;		/* transmit -> receive */#endif	return (sizeof (struct dhdevice));}/* * Routine called to attach a dh. */dhattach(ui)	struct uba_device *ui;{	dhsoftCAR[ui->ui_unit] = ui->ui_flags;	dhdefaultCAR[ui->ui_unit] = ui->ui_flags;}/* * Configuration routine to cause a dm to interrupt. */dmprobe(reg)	caddr_t reg;{	register int br, vec;			/* value-result */	register struct dmdevice *dmaddr = (struct dmdevice *)reg;#ifdef lint	br = 0; vec = br; br = vec;	dmintr(0);#endif	dmaddr->dmcsr = DM_DONE|DM_IE;	DELAY(20);	dmaddr->dmcsr = 0;	return (1);}/*ARGSUSED*/dmattach(ui)	struct uba_device *ui;{	/* no local state to set up */}/* * Open a DH11 line, mapping the clist onto the uba if this * is the first dh on this uba.  Turn on this dh if this is * the first use of it.  Also do a dmopen to wait for carrier. *//*ARGSUSED*/dhopen(dev, flag)	dev_t dev;{	register struct tty *tp;	register int unit, dh;	register struct dhdevice *addr;	register struct uba_device *ui;	int s;	unit = minor(dev);	dh = unit >> 4;	if (unit >= nNDH*16 || (ui = dhinfo[dh])== 0 || ui->ui_alive == 0)		return (ENXIO);	tp = &dh11[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);	addr = (struct dhdevice *)ui->ui_addr;	tp->t_addr = (caddr_t)addr;	tp->t_oproc = dhstart;	tp->t_state |= TS_WOPEN;	/*	 * While setting up state for this uba and this dh,	 * 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) {		/* 512+ is a kludge to try to get around a hardware problem */		tty_ubinfo[ui->ui_ubanum] = -1;  		tty_ubinfo[ui->ui_ubanum] =		    uballoc(ui->ui_ubanum, (caddr_t)cfree,			512+nclist*sizeof(struct cblock), 0);		wakeup(&tty_ubinfo[ui->ui_ubanum]);	}	cbase[ui->ui_ubanum] = tty_ubinfo[ui->ui_ubanum]&0x3ffff;	if (timerstarted == 0) {		timerstarted++;		timeout(dhtimer, (caddr_t) 0, hz);	}	if ((dhact&(1<<dh)) == 0) {		addr->un.dhcsr |= DH_IE;		dhact |= (1<<dh);		addr->dhsilo = 0;	}	splx(s);	/*	 * If this is first open, initialze tty state to default.	 */	if ((tp->t_state&TS_ISOPEN) == 0) {		ttychars(tp);#ifndef PORTSELECTOR		if ((tp->t_cflag & CBAUD) == 0) {#endif			tp->t_flags = IFLAGS;                        tp->t_iflag = IFLAG;                        tp->t_oflag = OFLAG;                        tp->t_lflag = LFLAG;                        tp->t_cflag = CFLAG;                        tp->t_cflag_ext = ISPEED;#ifndef PORTSELECTOR		}#endif		dhparam(unit);	}	/*	 * Wait for carrier, then process line discipline specific open.	 */	dmopen(dev, flag);	return ((*linesw[tp->t_line].l_open)(dev, tp));}/* * Close a DH11 line, turning off the DM11. *//*ARGSUSED*/dhclose(dev, flag)	dev_t dev;	int flag;{	register struct tty *tp;	register unit;	register dh;	unit = minor(dev);	dh = unit >> 4;	tp = &dh11[unit];	(*linesw[tp->t_line].l_close)(tp);	((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));	if (tp->t_cflag&HUPCL || (tp->t_state&TS_ISOPEN)==0) {		dmctl(unit, DML_OFF, DMSET);		if ((dhsoftCAR[dh] & (1<<(unit&0xf)))==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);		}	}	dhsoftCAR[dh] &= ~(1<<(unit&0xf));	dhsoftCAR[dh] |= (1<<(unit&0xf)) & dhdefaultCAR[dh];	ttyclose(tp);}dhread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp = &dh11[minor(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio));}dhwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp = &dh11[minor(dev)];	return ((*linesw[tp->t_line].l_write)(tp, uio));}/* * DH11 receiver interrupt. */dhrint(dh)	int dh;{	register struct tty *tp;	register c;	register struct dhdevice *addr;	register struct tty *tp0;	register struct uba_device *ui;	int overrun = 0;	ui = dhinfo[dh];	if (ui == 0 || ui->ui_alive == 0)		return;	addr = (struct dhdevice *)ui->ui_addr;	tp0 = &dh11[dh<<4];	/*	 * Loop fetching characters from the silo for this	 * dh until there are no more in the silo.	 */	while ((c = addr->dhrcr) < 0) {		tp = tp0 + ((c>>8)&0xf);		dhchars[dh]++;#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;		}		if (c & DH_PE)			if ((tp->t_flags&(EVENP|ODDP))==EVENP			 || (tp->t_flags&(EVENP|ODDP))==ODDP )				continue;		if ((c & DH_DO) && overrun == 0) {			printf("dh%d: silo overflow\n", dh);			overrun = 1;		}		if (c & DH_FE)			/*			 * At framing error (break) generate			 * a null (in raw mode, for getty), or a			 * interrupt (in cooked/cbreak mode).			 */			if (tp->t_flags&RAW)				c = 0;			else {				c = tp->t_cc[VINTR];				/*				 * Strip extraneous sign extension bits.				 */				c &= 0377;			}#if NHC > 0		if (tp->t_line == HCLDISC) {			HCINPUT(c, tp);		} else#endif			(*linesw[tp->t_line].l_rint)(c, tp);	}}/* * Ioctl for DH11. *//*ARGSUSED*/dhioctl(dev, cmd, data, flag)	caddr_t data;{	register struct tty *tp;	register int unit = minor(dev);	register int dh;	register int s;	int error;	dh = unit >> 4;	tp = &dh11[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 (cmd == TIOCSETP || cmd == TIOCSETN)			dhparam(unit);		return (error);	}	switch (cmd) {	case TIOCSBRK:		((struct dhdevice *)(tp->t_addr))->dhbreak |= 1<<(unit&017);		break;	case TIOCCBRK:		((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));		break;	case TIOCSDTR:		dmctl(unit, DML_DTR|DML_RTS, DMBIS);		break;	case TIOCCDTR:		dmctl(unit, DML_DTR|DML_RTS, DMBIC);		break;	case TIOCNMODEM:  /* ignore modem status */		s = spl5();		dhsoftCAR[dh] |= (1<<(unit&0xf));  		if (*(int *)data) /* make mode permanent */			dhdefaultCAR[dh] |= (1<<(unit&0xf));  		tp->t_state |= TS_CARR_ON;		splx(s);		break;	case TIOCMODEM:  /* look at modem status - sleep if no carrier */

⌨️ 快捷键说明

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