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

📄 mdc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
		if ((dcaddr->dcmsr & DC_XMIT) == DC_XMIT) {			tp->t_state &= ~(TS_ONDELAY);			tp->t_state |= TS_CARR_ON;			mdcmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR;		} else {			tp->t_state &= ~(TS_CARR_ON);			mdcmodem[unit] &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR);		}		tp->t_cflag &= ~CLOCAL;		/* Map to termio */		splx(s);		break;	case TIOCWONLINE:		s = spltty();		/*		 * See if signals necessary for modem connection are present		 *		 * dc7085 chip on PMAX only provides DSR		 * 		 */		if ((dcaddr->dcmsr & DC_XMIT) == DC_XMIT) {			tp->t_state |= TS_CARR_ON;			tp->t_state &= ~(TS_ONDELAY);			mdcmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR;		} else {		    while ((tp->t_state & TS_CARR_ON) == 0)			sleep((caddr_t)&tp->t_rawq, TTIPRI);		}		splx(s);		break;	case DEVIOCGET:				/* device status */		devget = (struct devget *)data;		bzero(devget,sizeof(struct devget));		devget->category = DEV_TERMINAL;	/* terminal cat.*/		devget->bus = DEV_NB;			/* NO bus	*/		bcopy(DEV_MF_SLU,devget->interface,		      strlen(DEV_MF_SLU));		/* interface	*/		bcopy(DEV_UNKNOWN,devget->device,		      strlen(DEV_UNKNOWN));		/* terminal	*/		devget->adpt_num = 0;			/* NO adapter	*/		devget->nexus_num = 0;			/* fake nexus 0 */		devget->bus_num = 0;			/* NO bus	*/		devget->ctlr_num = unit;		/* cntlr number */		devget->slave_num = linenum;		/* line number	*/		bcopy("mdc", devget->dev_name, 4);	/* Ultrix "mdc"	*/		devget->unit_num = linenum;		/* dc line?	*/		devget->soft_count =		      mdc_softc[unit].sc_softcnt[linenum]; /* overrun errs */		devget->hard_count = 0;			/* hard err cnt */		devget->stat = 0;		devget->category_stat = (DEV_MODEM|DEV_MODEM_ON);		if ((unit == NOMODEM_UNIT) || (linenum != MODEM_LINE)) {			devget->category_stat &= DEV_MODEM;		}		if (tp->t_cflag & CLOCAL) {		    devget->category_stat &= ~DEV_MODEM_ON;		} 		break;	default:		if (u.u_procp->p_progenv == A_POSIX) 			return (EINVAL);		return (ENOTTY);	}	return (0);}/* * Part of a worthless generic modem lead handling mechanism.  The only 2 bits * here that are of any use are DC_RRTS and DC_RDTR. */dmtomdc(bits)	register int bits;{	register int b;	b = (bits >>1) & 0370;	if (bits & SML_RTS) b |= DC_RRTS;	if (bits & SML_DTR) b |= DC_RDTR;	return(b);}/* * Part of a worthless generic modem lead handling mechanism.  The only 2 bits * here that are of any use are DC_RRTS and DC_RDTR. */mdctodm(bits)	register int bits;{	register int b;	b = (bits << 1) & 0360;	if (bits & DC_DSR) b |= SML_DSR;	if (bits & DC_RDTR) b |= SML_DTR;	if (bits & DC_RRTS) b |= SML_RTS;	return(b);}/* * Set device line parameters. */mdcparam(minor_num)	register int minor_num;{	register volatile struct mdz_reg *dcaddr;	register struct tty *tp;	register u_short lpr;	register int unit;	register int linenum;	unit = minor_num >> LINEBITS;	linenum = minor_num & LINEMASK;	dcaddr = mdz_regs[unit];	tp = &mdc_tty[minor_num];	/*	 * Set master scan enable for this line.  This also clears out the	 * receive and transmit interrupt enables which will be conditionally	 * applied later.  Preserve maintenance loopback mode if specified.	 */	if (dcaddr->dccsr & DC_MAINT) {		dcaddr->dccsr = (DC_MSE | DC_MAINT); 	}	else {		dcaddr->dccsr = DC_MSE; 	}	/*	 * Setting a baud rate of 0 closes down a line (environment dependent).	 * Deassert DTR and RTS to drop the modem connection.	 */	if ((((tp->t_cflag&CBAUD)==B0) && (u.u_procp->p_progenv != A_POSIX)) ||	    (((tp->t_cflag_ext & CBAUD)==B0) &&	     (u.u_procp->p_progenv == A_POSIX))) {	    mdcmodem_active &= ~(1 << minor_num);		    /*	     * We only have control for DTR and RTS on the modem line.	     */	    if ((unit != NOMODEM_UNIT) && (linenum == MODEM_LINE)) {		dcaddr->dctcr &= ~(DC_RDTR | DC_RRTS | DC_RSS);	    }	    return;	}	/* 	 * The console line must be set to 8 bits no parity.  The baud	 * rate may be changed from its default value of 1200 by an	 * environment variable.  May want to make sure the tty struct	 * gets modified to specify these attributes as well.	 */	if ((unit == CONSOLE_UNIT) && (linenum == CONSOLE_LINE)) {		tp->t_cflag &= ~(CBAUD);		tp->t_cflag_ext &= ~(CBAUD);		tp->t_cflag |= (console_baud & CBAUD);		tp->t_cflag_ext |= (console_baud & CBAUD);		dcaddr->dclpr = (linenum | mdc_speeds[console_baud].baud_param |				BITS8 | DC_RE);	} 	/*	 * Set parameters in accordance with user specification.	 */	else {		lpr = (mdc_speeds[tp->t_cflag&CBAUD].baud_param) | (linenum);		/*		 * Berkeley-only dinosaur		 */		if (tp->t_line != TERMIODISC) {			if ((tp->t_cflag_ext&CBAUD) == B110) {				lpr |= TWOSB;				tp->t_cflag |= CSTOPB;			}		}		/*		 * Set device registers according to the specifications of the		 * termio structure.		 */		if (tp->t_cflag & CREAD) {			lpr |= DC_RE;			}		else  {			lpr &= ~DC_RE;			}		if (tp->t_cflag & CSTOPB) {			lpr |= TWOSB;		}		else {			lpr &= ~TWOSB;		}		if (tp->t_cflag & PARENB) {			if ((tp->t_cflag & PARODD) == 0)				/* set even */				lpr = (lpr | PENABLE)&~OPAR;			else				/* else set odd */				lpr |= PENABLE|OPAR;		}		/*		 * character size.		 * clear bits and check for 6,7,and 8, else its 5 bits.		 */		lpr &= ~BITS8;		switch(tp->t_cflag&CSIZE) {			case CS6:				lpr |= BITS6;				break;			case CS7:				lpr |= BITS7;				break;			case CS8:				lpr |= BITS8;				break;		}		dcaddr->dclpr = lpr;	}	dcaddr->dccsr |= (DC_TIE | DC_RIE);	wbflush();}/* * A transmitter ready interrupt has been generated on this unit.  This means * that the transmitter buffer for a line is empty and now ready to transmit * a new character.  If there are already characters stacked up in the pdma * structure then just stuff the tbuf with the character.  Otherwise the * present list of characters is empty so call the xint routine to setup a * new pdma chain if there are any new characters to be transmitted. */_mdcpdma(unit)	register int unit;{        register volatile struct mdz_reg *dcaddr;	register struct dcpdma *dp;	register int linenum;        dcaddr = mdz_regs[unit];	linenum = (dcaddr->dccsr >> 8) & LINEMASK;		dp = &mdc_pdma[unit][linenum];	if (dp->p_mem == dp->p_end) {	    	mdcxint(unit, linenum);	} else {	    	dcaddr->dctbuf = (unsigned char)(*dp->p_mem++);		wbflush();	}}/* * A transmitter interrupt has been generated for a line that does not have * a pdma chain setup.  Setup the pdma chain and call the start routine to * initiate output. */mdcxint(unit, linenum)	register int unit;	register int linenum;{	register volatile struct mdz_reg *dcaddr;	register struct dcpdma *dp;	register struct tty *tp;	dcaddr = mdz_regs[unit];	tp = &mdc_tty[linenum + (unit * NDCLINE)];#ifdef DEBUG	if (mdcdebug > 4)		mprintf("mdcxint: linenum = %d, tp = %x, c_cc = %d\n", linenum, tp, tp->t_outq.c_cc);#endif DEBUG	tp->t_state &= ~TS_BUSY;	dp = &mdc_pdma[unit][linenum];	if (tp->t_state & TS_FLUSH) {		tp->t_state &= ~TS_FLUSH;	} else {		/*		 * Remove characters that have already been transmitted from		 * the tty output queue.  Set the p_end and p_mem pointers to		 * be the same to signify an empty pdma chain.		 */	    	ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);		dp->p_end = dp->p_mem = tp->t_outq.c_cf;	}	if (tp->t_line) {		(*linesw[tp->t_line].l_start)(tp);	}	else {		mdcstart(tp);	}	/*	 * The BUSY flag will not be set in two cases:			 *   1. if there are no more chars in the outq OR	 *   2. there are chars in the outq but tty is in	 *      stopped state.					 *	 * Turn off line enable.	 */	if ((tp->t_state&TS_BUSY) == 0) {	    	dcaddr->dctcr &= ~(1<<linenum);	}}/* * Begin transmission on a line.  Obtain a count of the number of characters * to be sent.  If there are characters to send, update the pdma struct to * point to the beginning of these characters followed by a count.  Then set * the transmitter interrupt enable for this line.  This will cause an * interrupt when the line is ready to accept a character.  The interrupt will * call the mdcxint routine to stuff the character in the transmitter buffer. */mdcstart(tp)	register struct tty *tp;{	register volatile struct mdz_reg *dcaddr;	register struct dcpdma *dp;	register int cc;	register int unit, linenum;	int s;	s = spltty();	linenum = minor(tp->t_dev) & LINEMASK;	unit = minor(tp->t_dev) >> LINEBITS;	dcaddr = mdz_regs[unit];	/*	 * Do not do anything if currently delaying, or active.  Also only	 * transmit when CTS is up.	 */	if ((tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) ||		(((tp->t_cflag & CLOCAL) == 0)		&& ((tp->t_state&TS_CARR_ON) && (mdcmodem[unit]&MODEM_CTS)==0)))		goto out;	if (tp->t_outq.c_cc <= TTLOWAT(tp)) {		if (tp->t_state&TS_ASLEEP) {			tp->t_state &= ~TS_ASLEEP;			wakeup((caddr_t)&tp->t_outq);		}		if (tp->t_wsel) {			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);			tp->t_wsel = 0;			tp->t_state &= ~TS_WCOLL;		}	}	if (tp->t_outq.c_cc == 0)		goto out;#ifdef DEBUG	if (mdcdebug > 7) {		mprintf("mdcstart: linenum = %d, tp = %x, c_cc = %d\n", linenum, tp, tp->t_outq.c_cc);	}#endif DEBUG	if ((tp->t_lflag_ext & PRAW) || (tp->t_oflag_ext & PLITOUT) ||	    ((tp->t_oflag & OPOST) == 0))		cc = ndqb(&tp->t_outq, 0);	else {		cc = ndqb(&tp->t_outq, DELAY_FLAG);		if (cc == 0) {			cc = getc(&tp->t_outq);			timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);			tp->t_state |= TS_TIMEOUT;			goto out;		}	}	tp->t_state |= TS_BUSY;	dp = &mdc_pdma[unit][linenum];	dp->p_end = dp->p_mem = tp->t_outq.c_cf;	dp->p_end += cc;	dcaddr->dccsr |= DC_TIE;	dcaddr->dctcr |= (1<<linenum);	wbflush();out:	splx(s);}mdcstop(tp, flag)	register struct tty *tp;{	register struct dcpdma *dp;	register int s;	register int unit, linenum;	unit = minor(tp->t_dev) >> LINEBITS;        linenum = minor(tp->t_dev) & LINEMASK;	dp = &mdc_pdma[unit][linenum];	s = spltty();	if (tp->t_state & TS_BUSY) {	    	dp->p_end = dp->p_mem;		if ((tp->t_state&TS_TTSTOP)==0)			tp->t_state |= TS_FLUSH;	}	splx(s);}/* * This routine is part of a scheme to provide a generic modem control * interface.  Strictly speaking it is not supported and is more bother than * it is worth.  This routine reads the status of the present modem control * leads and represents them generically in the mbits return value. */mdcmctl(dev, bits, how)	dev_t dev;	int bits, how;{	register volatile struct mdz_reg *dcaddr;	register int unit, linenum, mbits;	register int b, s;	unit = minor(dev) >> LINEBITS;	dcaddr = mdz_regs[unit];	linenum = minor(dev) & LINEMASK;	if ((unit == NOMODEM_UNIT) || (linenum != MODEM_LINE))		return(0);		s = spltty();	mbits = (dcaddr->dctcr & DC_RDTR) ? SML_DTR : 0;	mbits |= (dcaddr->dctcr & DC_RRTS) ? SML_RTS : 0;	mbits |= (dcaddr->dcmsr & DC_CD) ? SML_CAR : 0;	mbits |= (dcaddr->dcmsr &  DC_DSR) ? SML_DSR : 0;	mbits |= (dcaddr->dcmsr & DC_CTS) ? SML_CTS : 0;	switch (how) {	case DMSET:		mbits = bits;		break;	case DMBIS:		mbits |= bits;		break;	case DMBIC:		mbits &= ~bits;		break;	case DMGET:		(void) splx(s);		return(mbits);	}	if (mbits & SML_DTR) {		dcaddr->dctcr |= (DC_RDTR | DC_RRTS);	}	else {		dcaddr->dctcr &= ~(DC_RDTR | DC_RRTS | DC_RSS);	}	wbflush();	(void) splx(s);	return(mbits);}#ifdef DEBUGint mdcscan_ctr = 1;#endif DEBUG/* * The DC chip does not interrupt on modem transitions.  For this reason a * scanner routine is needed to be called frequently to check the status of * the modem control leads and to react to changes of these leads. */mdcscan(){	register volatile struct mdz_reg *dcaddr;	register struct tty *tp;	register int unit;	register int linenum;	register u_short dcscan_modem;    for (unit = 0; unit < nMDC; unit++) {        if (unit != NOMODEM_UNIT) {	    /*	     * Obtain a copy of the modem status register.  If the value has not	     * changed since the last iteration then there is no work to be done	     * here.  	     */	    dcaddr = mdz_regs[unit];#ifdef DEBUG	    if (mdcdebug > 5) {		if (mdcscan_ctr++ == 45) {			cprintf("dcscan: ");			PRINT_SIGNALS(dcaddr);			mdcscan_ctr = 1;		}	    }#endif DEBUG	    dcscan_modem = dcaddr->dcmsr;		    if (dcscan_modem != mdcscan_previous[unit]) {	        tp = &mdc_tty[MODEM_LINE + (unit * NDCLINE)];	        if ((tp->t_cflag & CLOCAL) == 0) {		    /*		     * Drop DTR immediately if DSR has gone away.		     * If really an active close then do not		     *    send signals.		     */		    if (!(dcscan_modem &  DC_DSR)) {		        if (tp->t_state&TS_CLOSING) {			    untimeout(wakeup, (caddr_t) &tp->t_dev);			    wakeup((caddr_t) &tp->t_dev);		        }		        if (tp->t_state&TS_CARR_ON) {			    mdc_tty_drop(tp);		        }		    } else {		/* DSR has come up */		        /*		         * If DSR comes up for the first time we allow		         * 30 seconds for a live connection.		         */		        if ((mdcmodem[unit] & MODEM_DSR)==0) {			    mdcmodem[unit] |= (MODEM_DSR_START|MODEM_DSR);			        /*			         * we should not look for CTS|CD for about			         * 500 ms.			         */			        timeout(mdc_dsr_check, tp, hz*30);			        mdc_dsr_check(tp);		        }		    }		    /*

⌨️ 快捷键说明

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