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

📄 mdc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
	return ((*linesw[tp->t_line].l_open)(dev, tp));}mdcclose(dev, flag)	dev_t dev;{	register volatile struct mdz_reg *dcaddr;	register struct tty *tp;	register int unit;	register int linenum;	register int minor_num;	register int s;	extern int wakeup();	minor_num = minor(dev);	unit = minor_num >> LINEBITS;	dcaddr = mdz_regs[unit];	linenum = minor_num & LINEMASK;	if (minor_num >= mdc_cnt) {		return (ENXIO);	}#	ifdef DEBUG	if (mdcdebug)		cprintf("mdcclose: unit=%d, linenum=%d\n",unit, linenum);#	endif DEBUG	tp = &mdc_tty[minor_num];	/*	 * 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);	/*	 * dcbreak 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.  	 */	s = spltty();	if(mdc_brk[unit] & (1<< linenum)) {		dcaddr->dcbreak = (mdc_brk[unit] &= ~(1 << linenum));		wbflush();	}	splx(s);	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 */		/*		 * Drop appropriate signals to terminate the connection.		 */		mdcmodem_active &= ~(1 << minor_num);		/* 		 * De-assert modem control leads.  		 * No disabling of interrupts is done.	Characters read in on		 * a non-open line will be discarded.		 */		if (((tp->t_cflag & CLOCAL) == 0) && (unit != NOMODEM_UNIT) &&		    (linenum == MODEM_LINE)) {		    s = spltty();		    dcaddr->dctcr &= ~(DC_RDTR | DC_RRTS | DC_RSS);		    /*drop DTR for at least a sec. if modem line*/#				ifdef DEBUG		    if (mdcdebug)			cprintf("mdcclose: 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 (dcaddr->dcmsr &  DC_DSR) {			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);		    mdcmodem[unit] = 0;		}	}	/* reset line to default mode */	mdcsoftCAR[unit] &= ~(1<<(linenum));	mdcsoftCAR[unit] |= (1<<(linenum)) & mdcdefaultCAR[unit];	ttyclose(tp);	tty_def_close(tp);}mdcread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	register int minor_num;	minor_num = minor(dev);	tp = &mdc_tty[minor_num];	return ((*linesw[tp->t_line].l_read)(tp, uio));}mdcwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	register int minor_num;	minor_num = minor(dev);	tp = &mdc_tty[minor_num];	return ((*linesw[tp->t_line].l_write)(tp, uio));}/* * Device interrupt service routine.  Examine the csr to see what the  * interrupt is all about and dispatch the appropriate handler. */mdcintr(unit)	register int unit;{	register volatile struct mdz_reg *dcaddr;	register unsigned int csr;	if (unit > nMDC) {	/* sanity check */		cprintf("mdcintr: invalid unit %d.\n",unit);		return;	}	dcaddr = mdz_regs[unit];	csr = dcaddr->dccsr;	/*	 * OUTPUT:	 * The transmitter buffer is now empty for the specified line.  Call	 * the pdma routine to place a new character in the tbuf.	 */	if (csr & DC_TRDY) {		_mdcpdma(unit);	}	/*	 * INPUT:	 * A character has been received.  Pass this up to the user application.	 */	if (csr & DC_RDONE) {		mdcrint(unit);	}}/* * A character has been received.  Pass this character up to the user level * application after examining for errors such as parity errors or breaks. */mdcrint(unit)	register int unit;{	register volatile struct mdz_reg *dcaddr;	register struct tty *tp;	register u_short c;	/* rbuf register is 16 bits long */	struct tty *tp0;	register int flg;	register int linenum;	int overrun = 0;	u_short data;	int counter = 0;	tp0 = &mdc_tty[0];	dcaddr = mdz_regs[unit];	while (dcaddr->dccsr&DC_RDONE) {		/* character present */		c = dcaddr->dcrbuf;		linenum = (c>>8)&LINEMASK;		tp = tp0 + linenum + (NDCLINE * unit);		if (tp >= &mdc_tty[mdc_cnt])			continue;		if ((tp->t_state & TS_ISOPEN) == 0) {			wakeup((caddr_t)&tp->t_rawq);			continue;		}		flg = tp->t_iflag;		/* DC_FE is interpreted as a break */		if (c & DC_FE) {			/*			 * If configured for trusted path, initiate			 * trusted path handling.			 */#			ifdef DEBUG			if (mdcdebug)				mprintf("mdcrint: BREAK RECEIVED on unit = %d, linenum = %d\n", unit, linenum);#			endif DEBUG			if (do_tpath) {				tp->t_tpath |= TP_DOSAK;				(*linesw[tp->t_line].l_rint)(c, tp);				break;			}			if (flg & IGNBRK)				continue;			if (flg & BRKINT) {				if ((tp->t_lflag_ext & PRAW) && 					(tp->t_line != TERMIODISC))					c = 0;				else {				        ttyflush(tp, FREAD | FWRITE);					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 & DC_PE){			/*			 * If input parity checking is not enabled, clear out			 * parity error in this character.			 */#			ifdef DEBUG			if (mdcdebug > 1)				mprintf("mdcrint: Parity Error\n");#			endif DEBUG			if ((flg & INPCK) == 0) {				c &= ~DC_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;				}			}		}		/*		 * Data Overrun.  Only complain about this once per routine		 * entry.  Increment error count to record the number of		 * errors.		 */		if (c&DC_DO) {			if(overrun == 0) {				printf("mdc%d: input silo overflow\n", 0);				overrun = 1;			}		        mdc_softc[unit].sc_softcnt[linenum]++; /* overrun errs */		}		/*		 * Strip the character to be 7 bits in length.		 */		if (flg & ISTRIP){			c &= 0177;		}		/*		 * Strip the character to be 8 bits in length.		 */		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*/mdcioctl(dev, cmd, data, flag)	dev_t dev;	register int cmd;	caddr_t data;	int flag;{	register volatile struct mdz_reg *dcaddr;	register int unit;	register int linenum;	register struct tty *tp;	register int s;	struct uba_device *ui;	struct devget *devget;	int error;	int minor_num;	minor_num = minor(dev);	unit = minor_num >> LINEBITS;	dcaddr = mdz_regs[unit];	linenum = minor_num & LINEMASK;	if (minor_num >= mdc_cnt) {		return (ENXIO);	}	tp = &mdc_tty[minor_num];	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 */				mdcparam(minor_num);				break;		}		return (error);	}	switch (cmd) {	/*	 * Begin a break sequence.  The line will remain in a break state	 * until cleared.	 */	case TIOCSBRK:	    	timeout(mdcsetbreak, tp, mdc_speeds[tp->t_cflag & CBAUD].delay_set_break); 		TTY_SLEEP(tp, (caddr_t)&tp->t_dev, TTOPRI);		s = spltty();		if((mdc_brk[unit] & (1<< linenum)) == 0) {		  dcaddr->dcbreak = (mdc_brk[unit] |= (1 << linenum));		  wbflush();		}		splx(s);#ifdef DEBUG	if (mdcdebug)	   mprintf("TIOCSBRK: unit = %d, linenum = %d, mdc_brk = %d, dccsr = 0x%x\n", unit, linenum, mdc_brk[unit], dcaddr->dccsr);#endif DEBUG		break;	/*	 * End a break sequence.	 */	case TIOCCBRK:		s = spltty();		if(mdc_brk[unit] & (1<< linenum)) {		   dcaddr->dcbreak = (mdc_brk[unit] &= ~(1 << linenum));		   wbflush();		}		splx(s);#ifdef DEBUG	if (mdcdebug)	   mprintf("TIOCCBRK: unit = %d, linenum = %d, mdc_brk = %d, dccsr = 0x%x\n", unit, linenum, mdc_brk[unit], dcaddr->dccsr);#endif DEBUG		break;	/*	 * Sets DTR and RTS in the tcr register.	 */	case TIOCSDTR:		(void) mdcmctl(dev, SML_DTR | SML_RTS, DMBIS);		break;	/*	 * Clears DTR and RTS in the tcr register.	 */	case TIOCCDTR:		(void) mdcmctl(dev, SML_DTR | SML_RTS, DMBIC);		break;	/*	 * TIOCSMLB and TIOCCMLB are used to set and clear the maintenance	 * loopback mode.  This is useful to test the lines without the need	 * for loopback connectors.  Restrict access to root users.	 *	 * Note that setting this bit will loopback ALL the lines on this	 * particular DC chip,  not just the specific line refered to by tp!	 * Just to be on the safe side, do not allow this on the console unit.	 * Perhaps this ioctl is to dangerous to include.	 */	case TIOCSMLB:		if ((u.u_uid) || (unit == CONSOLE_UNIT)) {			return(EPERM);		}		s = spltty();		dcaddr->dccsr |= (DC_MAINT);		wbflush();		splx(s);		break;	case TIOCCMLB:		if ((u.u_uid) || (unit == CONSOLE_UNIT)) {			return(EPERM);		}		s = spltty();		dcaddr->dccsr &= ~(DC_MAINT);		wbflush();		splx(s);		break;	/*	 * Set the specified generic modem control attributes.	 * No way this works!  The only relevant settings are DTR and RTS,	 * all others are not even looked at.	 */	case TIOCMSET:		(void) mdcmctl(dev, dmtomdc(*(int *)data), DMSET);		break;	/*	 * Set the specified bits in the generic modem control attributes.	 * No way this works!  The only relevant settings are DTR and RTS,	 * all others are not even looked at.	 */	case TIOCMBIS:		(void) mdcmctl(dev, dmtomdc(*(int *)data), DMBIS);		break;	/*	 * Clear the specified bits from the generic modem control attributes.	 * No way this works!  The only relevant settings are DTR and RTS,	 * all others are not even looked at.	 */	case TIOCMBIC:		(void) mdcmctl(dev, dmtomdc(*(int *)data), DMBIC);		break;	/*	 * Return the current generic modem control attributes.  Generally	 * speaking this will return garbage.	 * No way this works!  The only relevant settings are DTR and RTS,	 * all others are not even looked at.	 */	case TIOCMGET:		*(int *)data = mdctodm(mdcmctl(dev, 0, DMGET));		break;	/*	 * Specify that this line is to be considered a direct connect	 * (no modem) line.	 */	case TIOCNMODEM:  /* ignore modem status */		/*		 * By setting the software representation of modem signals		 * to "on" we fake the system into thinking that this is an		 * established modem connection.		 */		s = spltty();		mdcsoftCAR[unit] |= (1<<(linenum));		if (*(int *)data) /* make mode permanent */			mdcdefaultCAR[unit] |= (1<<(linenum));		tp->t_state |= TS_CARR_ON;		tp->t_cflag |= CLOCAL;		/* Map to termio */		splx(s);		break;	/*	 * Specify that this line is to be considered a modem 	 * (not direct connect) line.  This means pay attention to the 	 * modem control leads.	 */	case TIOCMODEM:  /* look at modem status - sleep if no carrier */		s = spltty();		/*		 * The only lines that allow modem control are line 2 of 		 * DC0 and DC1.  Should the ioctl fail?		 */		if ((unit == NOMODEM_UNIT) || (linenum != MODEM_LINE)) {			tp->t_cflag |= CLOCAL;	/* paranoia */			splx(s);			break;		}		mdcsoftCAR[unit] &= ~(1<<(linenum));		if (*(int *)data) { /* make mode permanent */			mdcdefaultCAR[unit] &= ~(1<<(linenum));		}		/*		 * See if signals necessary for modem connection are present		 *		 * dc7085 chip on PMAX only provides DSR		 *		 */

⌨️ 快捷键说明

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