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

📄 dmz.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	s = spl5();	oaddr->dmzcsr = (unit&07) | DMZIR_LCR | DMZ_IE;	/*  	 * Disconnect modem line if baudrate is zero.  POSIX checks the output	 * baud rate, while non-POSIX checks the input baud rate.	 */	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))) { 		tp->t_cflag |= HUPCL;		(void) dmzmctl(unit, DMZ_OFF, DMSET);		splx(s);		return;	}	lpar = (dmz_speeds[tp->t_cflag_ext&CBAUD]<<12) | 	/* ospeed */		(dmz_speeds[tp->t_cflag&CBAUD]<<8);		/* ispeed */	lcr = DMZLCR_ENA;	/*	 * Berkeley-only dinosaurs	 */	if (tp->t_line != TERMIODISC) {		if ((tp->t_cflag & CBAUD) == B134){			lpar |= BITS6|PENABLE; 			tp->t_cflag |= CS6|PARENB;		}		else if ((tp->t_cflag_ext & CBAUD) == B110){			lpar |= TWOSB;			tp->t_cflag |= CSTOPB;		}	} 	/* 	 * System V termio functionality.	 * Set device registers according to the specifications of the termio	 * structure. 	 */ 	if (tp->t_cflag & CREAD) 		lcr |= DMZ_RE;	else 		lcr &= ~DMZ_RE; 	if (tp->t_cflag & CSTOPB) 		lpar |= TWOSB; 	else 		lpar &= ~TWOSB; 	/* parity is enable */ 	if (tp->t_cflag & PARENB) { 		if ((tp->t_cflag & PARODD) == 0) 			/* set even */ 			lpar |= PENABLE|EPAR; 		else 			/* else set odd */ 			lpar = (lpar | PENABLE)&~EPAR; 	} 	/* 	 * character size. 	 * clear bits and check for 6,7,and 8, else its 5 bits. 	 */ 	lpar &= ~BITS8; 	switch(tp->t_cflag&CSIZE) { 		case CS6: 			lpar |= BITS6; 			break; 		case CS7: 			lpar |= BITS7; 			break; 		case CS8: 			lpar |= BITS8; 			break; 	}	/*	 * Outgoing Auto flow control.	 * No auto flow control allowed if startc != ^q and startc !=	 * ^s.  Most drivers do not allow this to be changed.	 */	if ((tp->t_cflag_ext & PAUTOFLOW) && (tp->t_cc[VSTOP] == CTRL('s')) && 		(tp->t_cc[VSTART] == CTRL('q')))		lcr |= DMZ_AUTOX;	lpar |= (unit&07);	oaddr->dmzlpr = lpar;	SETLCR(oaddr, lcr);#ifdef DMZDEBUG	if (dmzdebug)		mprintf("dmzparam: lpr=%x, lcr=%x, oaddr=%x\n",			oaddr->dmzlpr, oaddr->dmzun.dmzirw, oaddr);#endif	splx(s);}/* * DMZ32 transmitter interrupt. * Restart the idle line. */dmzxint(dmz, octetnum)	int dmz, octetnum;  /* dmz is the module that interrupted */			    /* octetnum is the octet within the module */{	struct tty *tp0;	register struct tty *tp;	register struct octet *addr;	register struct uba_device *ui;	register int t;	short cntr;        /*         * Index to propper tty structure by dmz number and octet.  Later move         * pointer up for the respective line number.         */        int unit0 = (dmz * NUMLINES) + (octetnum<<3);	ui = dmzinfo[dmz];	addr = &((struct dmzdevice *)ui->ui_addr)->octets[octetnum];	tp0 = &dmz_tty[unit0];	while ((t = addr->dmzcsr) & DMZ_TI) {		if (t & DMZ_NXM)			/* SHOULD RESTART OR SOMETHING... */			printf("dmz%d: NXM line %d\n", dmz, t >> 8 & 7);		t = t >> 8 & 7;		tp = tp0 + t;		tp->t_state &= ~TS_BUSY;		if (tp->t_state&TS_FLUSH)			tp->t_state &= ~TS_FLUSH;		else if (dmz_dma[unit0 + t]) {			/*			 * Do arithmetic in a short to make up			 * for lost 16&17 bits.			 */			addr->dmzcsr = DMZIR_TBA | DMZ_IE | t;			cntr = addr->dmztba -			    UBACVT(tp->t_outq.c_cf, ui->ui_ubanum);			ndflush(&tp->t_outq, (int)cntr);		}		if (tp->t_line)			(*linesw[tp->t_line].l_start)(tp);		else			dmzstart(tp);	}}/* * Start (restart) transmission on the given DMZ32 line. */dmzstart(tp)	register struct tty *tp;{	register struct octet *addr;	register int unit, nch, line;	int s;	register int dmz;	unit = minor(tp->t_dev);	dmz = unit / NUMLINES;	line = unit & 07;  /* specific line on octetnum */	addr = (struct octet *)tp->t_addr;	/*	 * Must hold interrupts in following code to prevent	 * state of the tp from changing.	 */	s = spl5();	/*	 * If it's currently active, or delaying, no need to do anything.	 * Also dont transmit if not CTS.	 */	if ((tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) ||		 ((tp->t_state & TS_CARR_ON) && (dmzmodem[unit]&MODEM_CTS)==0))		goto out;	/*	 * If there are still characters in the silo,	 * just reenable the transmitter.	 */	addr->dmzcsr = DMZ_IE | DMZIR_TBUF | line;	if (addr->dmztsc) {		addr->dmzcsr = DMZ_IE | DMZIR_LCR | line;                /*                 * If outgoing auto flow control is enabled, the hardware will                 * control the transmit enable bit.                 */                if ((tp->t_cflag_ext & PAUTOFLOW) == 0)			SETLCR(addr, addr->dmzlcr|DMZ_TE);		tp->t_state |= TS_BUSY;		goto out;	}	/*	 * If there are sleepers, and output has drained below low	 * water mark, wake up the sleepers.	 */	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;		}	}	/*	 * Now restart transmission unless the output queue is	 * empty.	 */	if (tp->t_outq.c_cc == 0)		goto out;	if ((tp->t_lflag_ext & PRAW) || (tp->t_oflag_ext & PLITOUT) || 	    ((tp->t_oflag & OPOST) == 0))		nch = ndqb(&tp->t_outq, 0);	else {		if ((nch = ndqb(&tp->t_outq, DELAY_FLAG)) == 0) {			/*			* If first thing on queue is a delay process it.			*/			nch = getc(&tp->t_outq);			timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);			tp->t_state |= TS_TIMEOUT;			goto out;		}	}	/*	 * If characters to transmit, restart transmission.	 */	if (nch >= dmz_mindma) {		register car;		dmz_dma[minor(tp->t_dev)] = 1;		addr->dmzcsr = DMZ_IE | DMZIR_LCR | line;                /*                 * If outgoing auto flow control is enabled, the hardware will                 * control the transmit enable bit.                 */		if ((tp->t_cflag_ext & PAUTOFLOW) == 0)			SETLCR(addr, addr->dmzlcr|DMZ_TE);		car = UBACVT(tp->t_outq.c_cf, dmzinfo[dmz]->ui_ubanum);		addr->dmzcsr = DMZ_IE | DMZIR_TBA | line;		/*		 * Give the device the starting address of a DMA transfer.  		 * Translate the system virtual address into a physical		 * address.		 */		addr->dmztba = svtophy(car);		addr->dmztcc = ((car >> 2) & 0xc000) | nch;		tp->t_state |= TS_BUSY;	} else if (nch) {		register char *cp = tp->t_outq.c_cf;		register int i;		dmz_dma[minor(tp->t_dev)] = 0;		nch = MIN(nch, DMZ_SILOCNT);		addr->dmzcsr = DMZ_IE | DMZIR_LCR | line;                /*                 * If outgoing auto flow control is enabled, the hardware will                 * control the transmit enable bit.                 */                if ((tp->t_cflag_ext & PAUTOFLOW) == 0)			SETLCR(addr, addr->dmzlcr|DMZ_TE);		addr->dmzcsr = DMZ_IE | DMZIR_TBUF | line;		for (i = 0; i < nch; i++)			addr->dmztbuf = *cp++;		ndflush(&tp->t_outq, nch);		tp->t_state |= TS_BUSY;	}out:	splx(s);}/* * Stop output on a line, e.g. for ^S/^Q or output flush. *//*ARGSUSED*/dmzstop(tp, flag)	register struct tty *tp;{	register struct octet *oaddr;	register int unit, s;	unit = minor(tp->t_dev);	unit &= 07;   /* line number on octet */	oaddr = (struct octet *)tp->t_addr;	/*	 * Block input/output interrupts while messing with state.	 */	s = spl5();	if (tp->t_state & TS_BUSY) {		/*		 * Device is transmitting; stop output		 * by selecting the line and disabling		 * the transmitter.  If this is a flush		 * request then flush the output silo,		 * otherwise we will pick up where we		 * left off by enabling the transmitter.		 */		oaddr->dmzcsr = DMZIR_LCR | unit | DMZ_IE;		/*		 * If this test isn't done, the hardware will need to see a		 * start character to get it going again if DMZ_AUTOX is set.		 */                if ((tp->t_cflag_ext & PAUTOFLOW) == 0)			SETLCR(oaddr, oaddr->dmzlcr &~ DMZ_TE);		if ((tp->t_state&TS_TTSTOP)==0) {			tp->t_state |= TS_FLUSH;			SETLCR(oaddr, oaddr->dmzlcr|DMZ_FLUSH);		} else			tp->t_state &= ~TS_BUSY;	}	splx(s);}/* * DMZ32 modem control */dmzmctl(dev, bits, how)	dev_t dev;	int bits, how;{	register struct octet *dmzaddr;	register int line, mbits, lcr;	int unit;	int s;	unit = minor(dev);	dmzaddr = (struct octet *)(dmz_tty[unit].t_addr);	line = unit & 07;  /* line number */	s = spl5();	dmzaddr->dmzcsr = DMZ_IE | DMZIR_TBUF | line;	mbits = dmzaddr->dmzrms << 8;	dmzaddr->dmzcsr = DMZ_IE | DMZIR_LCR | line;	mbits |= dmzaddr->dmztms;	lcr = dmzaddr->dmzlcr;	switch (how) {	case DMSET:		mbits = (mbits &0xff00) | bits;		break;	case DMBIS:		mbits |= bits;		break;	case DMBIC:		mbits &= ~bits;		break;	case DMGET:		(void) splx(s);		return(mbits);	}	if (mbits & DMZ_BRK)		lcr |= DMZ_RBRK;	else		lcr &= ~DMZ_RBRK;	lcr = ((mbits & 037) << 8) | (lcr & 0xff);	dmzaddr->dmzun.dmzirw = lcr;	(void) splx(s);#ifdef DMZDEBUG	if (dmzdebug)		mprintf("dmzmctl: unit=%d, l#=%d, lcr=%x, oaddr=%x\n",			unit, line, dmzaddr->dmzun.dmzirw, dmzaddr);#endif	return(mbits);}/* * Reset state of driver if UBA reset was necessary. * Reset the csr, lpr, and lcr registers on open lines, and * restart transmitters. */dmzreset(uban)	int uban;{	register int dmz, unit;	register struct tty *tp;	register struct uba_device *ui;	register struct octet *oaddr;	int i, o;	if (tty_ubinfo[uban] == 0)		return;	cbase[uban] = tty_ubinfo[uban]&0x3ffff;	for (dmz = 0; dmz < nNDMZ; dmz++) {  /* for each dmz module */		ui = dmzinfo[dmz];		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)			continue;		printf(" dmz%d", dmz);		unit = (dmz << 5);		for (o = 0; o < 3; o++) {  /* for each octet */			oaddr = &((struct dmzdevice *)ui->ui_addr)->octets[o];			oaddr->dmzcsr = DMZ_IE;			oaddr->dmzrsp = dmz_timeout;  /* receive timer should be higher */			for (i = 0; i < 8; i++) {  /* for each line */				tp = &dmz_tty[unit];				if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {					dmzparam(unit);					(void) dmzmctl(unit, DMZ_ON, DMSET);					tp->t_state &= ~TS_BUSY;					dmzstart(tp);				}				unit++;			}		}	}}/* octet interrupt handlers *//* In version 1.2 these are not used - dmzr/xint is called with the octet number */dmzrinta(dmz)	int dmz;{	dmzrint(dmz, 0);}dmzxinta(dmz)	int dmz;{	dmzxint(dmz, 0);}dmzrintb(dmz)	int dmz;{	dmzrint(dmz, 1);}dmzxintb(dmz)	int dmz;{	dmzxint(dmz, 1);}dmzrintc(dmz)	int dmz;{	dmzrint(dmz, 2);}dmzxintc(dmz)	int dmz;{	dmzxint(dmz, 2);}dmz_cd_drop(tp)register struct tty *tp;{	register struct octet *addr = (struct octet *)tp->t_addr;	register unit = minor(tp->t_dev);	addr->dmzcsr = DMZ_IE | DMZIR_TBUF | (unit&07);	if ((tp->t_state&TS_CARR_ON) &&		((addr->dmzrms&DMZ_CAR) == 0)) {#ifdef DMZDEBUG		if (dmzdebug)		    mprintf("dmz_cd:  no CD, tp=%x, unit=%x, addr=%x\n",			tp, unit, addr);#endif		dmz_tty_drop(tp);		return;	}	dmzmodem[unit] |= MODEM_CD;#ifdef DMZDEBUG	if (dmzdebug)	    mprintf("dmz_cd:  CD is up, tp=%x\n", tp);#endif}dmz_dsr_check(tp)register struct tty *tp;{	int unit = minor(tp->t_dev);	register struct octet *addr = (struct octet *)tp->t_addr;	if (dmzmodem[unit]&MODEM_DSR_START) {#ifdef DMZDEBUG		if (dmzdebug)		    mprintf("dmz_dsr_check0:  tp=%x\n", tp);#endif		dmzmodem[unit] &= ~MODEM_DSR_START;		addr->dmzcsr = DMZ_IE | DMZIR_TBUF | (unit&07);	   	/* 	    	 * If dmzdsr is set look for DSR|CTS|CD, otherwise look 	    	 * for CD|CTS only.	    	 */		if (dmzdsr) {			if ((addr->dmzrms&DMZ_XMIT)==DMZ_XMIT)				dmz_start_tty(tp);		}		else {			if ((addr->dmzrms&DMZ_NODSR)==DMZ_NODSR)				dmz_start_tty(tp);		}		return;	}	if ((tp->t_state&TS_CARR_ON)==0)  {		dmz_tty_drop(tp);#ifdef DMZDEBUG		if (dmzdebug)		    mprintf("dmz_dsr_check:  no carrier, tp=%x\n", tp);#endif	}#ifdef DMZDEBUG	else		if (dmzdebug)		    mprintf("dmz_dsr_check:  carrier is up, tp=%x\n", tp);#endif}/* *  cd_down return 1 if carrier has been down for at least 2 secs. */dmz_cd_down(tp)struct tty *tp;{	int msecs;	register int unit = minor(tp->t_dev);	msecs = 1000000 * (time.tv_sec - dmztimestamp[unit].tv_sec) +		(time.tv_usec - dmztimestamp[unit].tv_usec);	if (msecs > 2000000)		return(1);	else		return(0);}dmz_tty_drop(tp)struct tty *tp;{	register struct octet *addr = (struct octet *)tp->t_addr;	register int line; 	register int unit;#ifdef DMZDEBUG		if (dmzdebug)			mprintf("dmz_start_tty:  drop tty , tp=%x, flags=%x\n", tp, tp->t_flags);#endif	if (tp->t_flags&NOHANG)		return; 	unit = minor(tp->t_dev); 	line = unit & 07; 	dmzmodem[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);	addr->dmzcsr=DMZ_IE | DMZIR_LCR | line;	addr->dmztms = 0;}dmz_start_tty(tp)	register struct tty *tp;{	register int unit = minor(tp->t_dev);	if (tp->t_state&TS_CARR_ON) {#ifdef DMZDEBUG		if (dmzdebug)			mprintf("dmz_start_tty:  carr on, tp=%x\n", tp);#endif		return;	}	tp->t_state &= ~TS_ONDELAY;	tp->t_state |= TS_CARR_ON;	if (dmzmodem[unit]&MODEM_DSR)		untimeout(dmz_dsr_check, tp);	dmzmodem[unit] |= MODEM_CD|MODEM_CTS|MODEM_DSR;	dmztimestamp[unit] = dmzzerotime;	wakeup((caddr_t)&tp->t_rawq);}dmzbaudrate(speed)register int speed;{    if (dmz_valid_speeds & (1 << speed))	return (1);    else	return (0);}#endif

⌨️ 快捷键说明

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