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

📄 mdc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
		     * look for modem transitions in an already		     * established connection.		     *		     */		    if (tp->t_state & TS_CARR_ON) {			    if (dcscan_modem & DC_CD) {			        /*			         * CD has come up again.			         * Stop timeout from occurring if set.			         * If interval is more than 2 secs then			         * drop DTR.			         */			        if ((mdcmodem[unit] & MODEM_CD) == 0) {				    untimeout(mdc_cd_drop, tp);				    if (mdc_cd_down(tp)) {				        /* drop connection */				        mdc_tty_drop(tp);				    }				    mdcmodem[unit] |= MODEM_CD;			        }			    } else {			        /*			         * Carrier must be down for greater than			         * 2 secs before closing down the line.			         */			        if (mdcmodem[unit] & MODEM_CD) {				    /* only start timer once */				    mdcmodem[unit] &= ~MODEM_CD;				    /*				     * Record present time so that if carrier				     * comes up after 2 secs, the line will drop				     */				    mdctimestamp[unit] = time;				    timeout(mdc_cd_drop, tp, hz * 2);			        }			    }		    				    /* CTS flow control check */		    				    if (!(dcscan_modem & DC_CTS)) {			        /*			         * Only allow transmission when CTS is set.			         */			        tp->t_state |= TS_TTSTOP;			        mdcmodem[unit] &= ~MODEM_CTS;#ifdef DEBUG			        if (mdcdebug)				    cprintf("mdcscan: CTS stop, tp=%x,unit=%d\n",tp,unit);#endif DEBUG			        mdcstop(tp, 0);			    } else if (!(mdcmodem[unit] & MODEM_CTS)) {			        /*			         * Restart transmission upon return of CTS.			         */			        tp->t_state &= ~TS_TTSTOP;			        mdcmodem[unit] |= MODEM_CTS;#ifdef DEBUG			        if (mdcdebug)				    cprintf("mdcscan: CTS start, tp=%x,unit=%d\n",tp,unit);#endif DEBUG			        mdcstart(tp);			    }		        }    			        /*		         * See if a modem transition has occured.  If we are 		         * waiting for this signal, cause action to be take via		         * mdc_start_tty.		         */		        if (((dcscan_modem & DC_XMIT) == DC_XMIT) &&			    (!(mdcmodem[unit] & MODEM_DSR_START)) &&			    (!(tp->t_state & TS_CARR_ON))) {#ifdef DEBUG				    if (mdcdebug)				        cprintf("mdcscan: MODEM transition: dcscan_modem = %x, mdcscan_previous = %x\n", dcscan_modem, mdcscan_previous[unit]);#endif DEBUG				    mdc_start_tty(tp);		        }	        }		/*		 * Save a copy of the modem status for comparison during the		 * next iteration.		 */	        mdcscan_previous[unit] = dcscan_modem; 	    }      }    }    /*     * Schedule the next scanner iteration.  Scan at a much higher frequency     * when a modem line is active.     */    if (mdcmodem_active) {        timeout(mdcscan, (caddr_t)0, hz/40);    }    else {        timeout(mdcscan, (caddr_t)0, hz);    }}/* * Write a character to the console. */mdcputc(c)	register int c;{    mdc_putc(c);    if ( c == '\n')	mdc_putc('\r');}/* * This routine outputs one character to the console. * * Called for system startup messages.  Also used for kernel printf's. * Not called from user level; ie a console getty does not use this. * * Characters must be printed without disturbing * output in progress on other lines! * This routines works with the SLU in interrupt or * non-interrupt mode of operation. BULL! * Characters are output as follows: *	spl5, remember if console line active. *	set console line tcr bit. *	wait for TRDY on console line (save status if wrong line). *	start output of character. *	wait for output complete. *	if any lines were active, set their tcr bits, *	otherwise clear the xmit ready interrupt. * */mdc_putc(c)	int c;{	register volatile struct mdz_reg *dcaddr;	register int	s; 	register u_short oldtcr;	register int	ln, linenum, timo;	dcaddr = mdz_regs[CONSOLE_UNIT];	linenum = CONSOLE_LINE;	c &= CHAR_MASK;			/* Strip character to 8-bits */	s = splhigh();	/*	 * Get a copy of the present transmit enable and DTR, RTS.	 * Next set transmit enable for this line.	 */	oldtcr = (dcaddr->dctcr & (1<<linenum));	dcaddr->dctcr |= (1<<linenum);	while (1) {		/*		 * Wait for the chip to be ready.  Impose a timer so that the		 * system does not hang if this bit fails to clear due to a		 * hardware error.  If the bit fails to clear then don't even		 * try to send out this character.		 */		timo = 1000000;		while ((dcaddr->dccsr&DC_TRDY) == 0) {				if(--timo == 0)				break;		}		if(timo == 0)			break;		/*		 * The DC chip has stoppped on a line that is ready to be		 * loaded with another transmit character.  If the line ready		 * for transmission is not the console line then clear		 * transmitter enable for the non-console line so that we		 * won't be bothered by that line again until the completion of		 * this putc operation.		 */		ln = (dcaddr->dccsr>>8) & LINEMASK;		if (ln != linenum) {			oldtcr |= (1 << ln);			dcaddr->dctcr &= ~(1 << ln);			continue;		}		/*		 * Output the character by writing into the transmitter buffer.		 * Provide a delay to allow time for the char to go out.  The 		 * registers should not be read for 1.4 microseconds.		 * Should this routine check to see if the console line is		 * presently asserting a break?		 */		dcaddr->dctbuf = c;		DELAY(5); 		/*		 * Wait for the character to be transmitted.		 */		while (1) {			timo = 1000000;			while ((dcaddr->dccsr&DC_TRDY) == 0) {					if(--timo == 0)					break;			}			if(timo == 0)				break;			ln = (dcaddr->dccsr>>8) & LINEMASK;			if (ln != linenum) {				oldtcr |= (1 << ln);				dcaddr->dctcr &= ~(1 << ln);				continue;			}			break;		}		break;	}	/*	 * Clear transmit enable for this line.  If this bit was set when this	 * routine was originaly entered it will then be restored.	 */	dcaddr->dctcr &= ~(1<<linenum);	if (oldtcr != 0)		dcaddr->dctcr |= oldtcr;	wbflush();	splx(s);}/* * This routine operates on the following assumptions: * 1. putc must have happened first, so SLU already inited. * 2. getc will happed before slu reveive interrupt enabled so *    don't need to worry about int_req or int_msk registers. */mdcgetc(){	register volatile struct mdz_reg *dcaddr;	register u_short c;	register int linenum;	dcaddr = mdz_regs[CONSOLE_UNIT];	linenum = CONSOLE_LINE;	while (1) {		/*		 * This will hang the system if RDONE never gets set!		 */		while ((dcaddr->dccsr&DC_RDONE) == 0) ;		c = dcaddr->dcrbuf;		if(((c >> 8) & LINEMASK) != linenum)	/* wrong line mumber */			continue;		/*		 * Toss the character away if there is an error.  I wonder if		 * throwing away parity errors is a bit harsh.		 */		if(c & (DC_DO|DC_FE|DC_PE))				continue;		break;	}	return(c & CHAR_MASK);}/* * Modem Control Routines *//* * * Function: * *	mdc_cd_drop * * Functional description: * * 	Determine if carrier has dropped.  If so call mdc_tty_drop to terminate * 	the connection. * * Arguements: * *	register struct tty *tp  -  terminal pointer ( for terminal attributes ) * * Return value: * *	none * */mdc_cd_drop(tp)register struct tty *tp;{	register volatile struct mdz_reg *dcaddr;	register int unit;	unit = minor(tp->t_dev) >> LINEBITS;	dcaddr = mdz_regs[unit];	if ((tp->t_state & TS_CARR_ON) && (!(dcaddr->dcmsr & DC_CD))) {#ifdef DEBUG	    if (mdcdebug)		cprintf("mdc_cd_drop: no CD, tp = %x, unit = %d\n", tp, unit);#endif DEBUG	    mdc_tty_drop(tp);	    return;	}	mdcmodem[unit] |= MODEM_CD;#ifdef DEBUG	if (mdcdebug)	    cprintf("mdc_cd_drop:  CD is up, tp = %x, unit = %d\n", tp, unit);#endif DEBUG} /* * * Function: * *	mdc_dsr_check * * Functional description: * *	DSR must be asserted for a connection to be established.  Here we  *	either start or terminate a connection on the basis of DSR. * * Arguements: * *	register struct tty *tp  -  terminal pointer (for terminal attributes) * * Return value: * *	none * */mdc_dsr_check(tp)register struct tty *tp;{	register volatile struct mdz_reg *dcaddr;	register int unit;	unit = minor(tp->t_dev) >> LINEBITS;	dcaddr = mdz_regs[unit];#	ifdef DEBUG       	if (mdcdebug) {       	    cprintf("mdc_dsr_check0:  tp=%x\n", tp);	    PRINT_SIGNALS(dcaddr);	}#	endif DEBUG	if (mdcmodem[unit] & MODEM_DSR_START) {	    mdcmodem[unit] &= ~MODEM_DSR_START;	    if ((dcaddr->dcmsr & DC_XMIT) == DC_XMIT) {		mdc_start_tty(tp);	    }	    return;	}	if ((tp->t_state&TS_CARR_ON)==0)		mdc_tty_drop(tp);}/* * * Function: * *	mdc_cd_down * * Functional description: * *	Determine whether or not carrier has been down for > 2 sec. * * Arguements: * *	register struct tty *tp  -  terminal pointer ( for terminal attributes ) * * Return value: * *	1 - if carrier was down for > 2 sec. *	0 - if carrier down <= 2 sec. * */mdc_cd_down(tp)register struct tty *tp;{        register int msecs, unit;	unit = minor(tp->t_dev) >> LINEBITS;	msecs = 1000000 * (time.tv_sec - mdctimestamp[unit].tv_sec) + 		(time.tv_usec - mdctimestamp[unit].tv_usec);	if (msecs > 2000000){#		ifdef DEBUG		if (mdcdebug)			cprintf("mdc_cd_down: msecs > 20000000\n");#		endif DEBUG		return(1);	}	else{#		ifdef DEBUG		if (mdcdebug)			cprintf("mdc_cd_down: msecs < 20000000\n");#		endif DEBUG		return(0);	}}/* * * Function: * *	mdc_tty_drop * * Functional description: * *	Terminate a connection. * * Arguements: * *	register struct tty *tp  -  terminal pointer ( for terminal attributes ) * * Return value: * *	none * */mdc_tty_drop(tp)struct tty *tp;{	register volatile struct mdz_reg *dcaddr;	register int unit;	register int minor_num;	minor_num = minor(tp->t_dev);	unit = minor_num >> LINEBITS;	dcaddr = mdz_regs[unit];	mdcmodem_active &= ~(1 << minor_num);	if (tp->t_flags & NOHANG)		return;#	ifdef DEBUG	if (mdcdebug)		cprintf("mdc_tty_drop: minor=%d\n",minor_num);#	endif DEBUG	/* 	 * Notify any processes waiting to open this line.  Useful in the	 * case of a false start.	 */	mdcmodem[unit] = MODEM_BADCALL; 	tp->t_state &= ~(TS_CARR_ON|TS_TTSTOP|TS_BUSY|TS_ISUSP);	wakeup((caddr_t)&tp->t_rawq);	gsignal(tp->t_pgrp, SIGHUP);	gsignal(tp->t_pgrp, SIGCONT);	dcaddr->dctcr &= ~(DC_RDTR | DC_RRTS | DC_RSS);}/* * * Function: * *	mdc_start_tty * * Functional description: * *	Establish a connection. * * Arguements: * *	register struct tty *tp  -  terminal pointer ( for terminal attributes ) * * Return value: * *	none * */mdc_start_tty(tp)	register struct tty *tp;{        register int unit;        register int linenum;	register int minor_num;	minor_num = minor(tp->t_dev);	unit = minor_num >> LINEBITS;	linenum = minor_num & LINEMASK;	/*	 * Setting this variable will cause the scanner to be called with	 * increased frequency.  As a sanity check, only set the bit if this	 * is a modem line to prevent the possible case where the scanner could	 * be increased for a no modem line.	 */	if ((unit != NOMODEM_UNIT) && (linenum == MODEM_LINE)) {		mdcmodem_active |= (1 << minor_num);		}	tp->t_state &= ~(TS_ONDELAY);	tp->t_state |= TS_CARR_ON;#	ifdef DEBUG        if (mdcdebug)	       cprintf("mdc_start_tty:  tp=%x\n", tp);#	endif DEBUG	if (mdcmodem[unit] & MODEM_DSR)		untimeout(mdc_dsr_check, tp);	mdcmodem[unit] |= MODEM_CD|MODEM_CTS|MODEM_DSR;	mdctimestamp[unit].tv_sec = mdctimestamp[unit].tv_usec = 0;	wakeup((caddr_t)&tp->t_rawq);}/* * Return 1 if the baud rate is supported, 0 if not supported. * * This scheme could be improved for the case of the console line which * really can't be set to any arbirtrary baud rate. */mdcbaudrate(speed)int speed;{	return(mdc_speeds[speed & CBAUD].baud_support);}/*  * Time up for process to set a break on a transmission line. */void mdcsetbreak(tp)register struct tty *tp;{	wakeup((caddr_t)&tp->t_dev);}

⌨️ 快捷键说明

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