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

📄 dh.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
		s = spl5();		dhsoftCAR[dh] &= ~(1<<(unit&0xf));  		if (*(int *)data) /* make mode permanent */			dhdefaultCAR[dh] &= ~(1<<(unit&0xf));  		splx(s);		break;	case TIOCWONLINE:		dmopen(dev, 0);		break;	default:		return (ENOTTY);	}	return (0);}/* * Set parameters from open or stty into the DH hardware * registers. */dhparam(unit)	register int unit;{	register struct tty *tp;	register struct dhdevice *addr;	register int lpar;	int s;	tp = &dh11[unit];	addr = (struct dhdevice *)tp->t_addr;	/*	 * Block interrupts so parameters will be set	 * before the line interrupts.	 */	s = spl5();	addr->un.dhcsrl = (unit&0xf) | DH_IE;	/*  	 * Disconnect modem line if baudrate is zero.	 */	if ((tp->t_cflag & CBAUD) == B0) {		tp->t_cflag |= HUPCL;		dmctl(unit, DML_OFF, DMSET);		splx(s);		return;	}	lpar = (((tp->t_cflag_ext&CBAUD)<<6) | ((tp->t_cflag&CBAUD)<<10));	if (tp->t_flags & (RAW|LITOUT))		lpar |= BITS8;	else		lpar |= BITS7|PENABLE;	if ((tp->t_flags&EVENP) == 0)		lpar |= OPAR;	addr->dhlpr = lpar;	splx(s);}/* * DH11 transmitter interrupt. * Restart each line which used to be active but has * terminated transmission since the last interrupt. */dhxint(dh)	int dh;{	register struct tty *tp;	register struct dhdevice *addr;	short ttybit, bar, *sbar;	register struct uba_device *ui;	register int unit;	u_short cntr;	ui = dhinfo[dh];	addr = (struct dhdevice *)ui->ui_addr;	if (addr->un.dhcsr & DH_NXM) {		addr->un.dhcsr |= DH_CNI;		printf("dh%d: NXM\n", dh);	}	sbar = &dhsar[dh];	bar = *sbar & ~addr->dhbar;	unit = dh * 16; ttybit = 1;	addr->un.dhcsr &= (short)~DH_TI;	for (; bar; unit++, ttybit <<= 1) {		if (bar & ttybit) {			*sbar &= ~ttybit;			bar &= ~ttybit;			tp = &dh11[unit];			tp->t_state &= ~TS_BUSY;			if (tp->t_state&TS_FLUSH)				tp->t_state &= ~TS_FLUSH;			else {				addr->un.dhcsrl = (unit&017)|DH_IE;				/*				 * Do arithmetic in a short to make up				 * for lost 16&17 bits.				 */				cntr = addr->dhcar -				    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				dhstart(tp);		}	}}/* * Start (restart) transmission on the given DH11 line. */dhstart(tp)	register struct tty *tp;{	register struct dhdevice *addr;	register int car, dh, unit, nch;	int s;	unit = minor(tp->t_dev);	dh = unit >> 4;	unit &= 0xf;	addr = (struct dhdevice *)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.	 */	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))		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_flags & (RAW|LITOUT))		nch = ndqb(&tp->t_outq, 0);	else {		nch = ndqb(&tp->t_outq, 0200);		/*		 * If first thing on queue is a delay process it.		 */		if (nch == 0) {			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) {		car = UBACVT(tp->t_outq.c_cf, dhinfo[dh]->ui_ubanum);		addr->un.dhcsrl = unit|((car>>12)&0x30)|DH_IE;		/*		 * The following nonsense with short word		 * is to make sure the dhbar |= word below		 * is done with an interlocking bisw2 instruction.		 */		{ short word = 1 << unit;		dhsar[dh] |= word;		addr->dhcar = car;		addr->dhbcr = -nch;		addr->dhbar |= word;		}		tp->t_state |= TS_BUSY;	}out:	splx(s);}/* * Stop output on a line, e.g. for ^S/^Q or output flush. *//*ARGSUSED*/dhstop(tp, flag)	register struct tty *tp;{	register struct dhdevice *addr;	register int unit, s;	addr = (struct dhdevice *)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 setting the byte		 * count to -1.  We will clean up later		 * by examining the address where the dh stopped.		 */		unit = minor(tp->t_dev);		addr->un.dhcsrl = (unit&017) | DH_IE;		if ((tp->t_state&TS_TTSTOP)==0)			tp->t_state |= TS_FLUSH;		addr->dhbcr = -1;	}	splx(s);}/* * Reset state of driver if UBA reset was necessary. * Reset the csrl and lpr registers on open lines, and * restart transmitters. */dhreset(uban)	int uban;{	register int dh, unit;	register struct tty *tp;	register struct uba_device *ui;	int i;	if (tty_ubinfo[uban] == 0)		return;	cbase[uban] = tty_ubinfo[uban]&0x3ffff;	dh = 0;	for (dh = 0; dh < nNDH; dh++) {		ui = dhinfo[dh];		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)			continue;		printf(" dh%d", dh);		((struct dhdevice *)ui->ui_addr)->un.dhcsr |= DH_IE;		((struct dhdevice *)ui->ui_addr)->dhsilo = 0;		unit = dh * 16;		for (i = 0; i < 16; i++) {			tp = &dh11[unit];			if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {				dhparam(unit);				dmctl(unit, DML_ON, DMSET);				tp->t_state &= ~TS_BUSY;				dhstart(tp);			}			unit++;		}	}	dhsilos = 0;}int dhtransitions, dhslowtimers, dhfasttimers;		/*DEBUG*//* * At software clock interrupt time, check status. * Empty all the dh silos that are in use, and decide whether * to turn any silos off or on. */dhtimer(){	register int dh, s;	static int timercalls;	if (dhsilos) {		dhfasttimers++;		/*DEBUG*/		timercalls++;		s = spl5();		for (dh = 0; dh < nNDH; dh++)			if (dhsilos & (1 << dh))				dhrint(dh);		splx(s);	}	if ((dhsilos == 0) || ((timercalls += FASTTIMER) >= hz)) {		dhslowtimers++;		/*DEBUG*/		timercalls = 0;		for (dh = 0; dh < nNDH; dh++) {		    ave(dhrate[dh], dhchars[dh], 8);		    if ((dhchars[dh] > dhhighrate) &&		      ((dhsilos & (1 << dh)) == 0)) {			((struct dhdevice *)(dhinfo[dh]->ui_addr))->dhsilo =			    (dhchars[dh] > 500? 32 : 16);			dhsilos |= (1 << dh);			dhtransitions++;		/*DEBUG*/		    } else if ((dhsilos & (1 << dh)) &&		      (dhrate[dh] < dhlowrate)) {			((struct dhdevice *)(dhinfo[dh]->ui_addr))->dhsilo = 0;			dhsilos &= ~(1 << dh);		    }		    dhchars[dh] = 0;		}	}	timeout(dhtimer, (caddr_t) 0, dhsilos? FASTTIMER: hz);}/* * Turn on the line associated with dh dev. */dmopen(dev, flag)	dev_t dev;{	register struct tty *tp;	register struct dmdevice *addr;	register struct uba_device *ui;	register int unit;	register int dm;	int s;	int inuse;  /*hold state of inuse bit while blocked waiting for carr*/	unit = minor(dev);	dm = unit >> 4;	tp = &dh11[unit];	unit &= 0xf;	if (dm >= nNDH || (ui = dminfo[dm]) == 0 || ui->ui_alive == 0) 		return(ENXIO);	addr = (struct dmdevice *)ui->ui_addr;	s = spl5();	addr->dmcsr &= ~DM_SE;	while (addr->dmcsr & DM_BUSY)		;	addr->dmcsr = unit;	addr->dmlstat = DML_ON;	if ((addr->dmlstat&DML_CAR) || (dhsoftCAR[dm]&(1<<unit)))		tp->t_state |= TS_CARR_ON;	addr->dmcsr = DM_IE|DM_SE;	if (flag & O_NDELAY) 		tp->t_state |= TS_ONDELAY;	else		while ((tp->t_state&TS_CARR_ON)==0) {			inuse = tp->t_state&TS_INUSE;			sleep((caddr_t)&tp->t_rawq, TTIPRI);			/* if we opened "block if in use"  and			 *  the terminal was not inuse at that time			 *  but is became "in use" while we were			 *  waiting for carrier then return			 */			if ((flag & O_BLKINUSE) && (inuse==0) &&				(tp->t_state&TS_INUSE)) {					splx(s);					return(EALREADY);			}		}	splx(s);}/* * Dump control bits into the DM registers. */dmctl(dev, bits, how)	dev_t dev;	int bits, how;{	register struct uba_device *ui;	register struct dmdevice *addr;	register int unit, s;	int dm;	unit = minor(dev);	dm = unit >> 4;	if ((ui = dminfo[dm]) == 0 || ui->ui_alive == 0)		return;	addr = (struct dmdevice *)ui->ui_addr;	s = spl5();	addr->dmcsr &= ~DM_SE;	while (addr->dmcsr & DM_BUSY)		;	addr->dmcsr = unit & 0xf;	switch(how) {	case DMSET:		addr->dmlstat = bits;		break;	case DMBIS:		addr->dmlstat |= bits;		break;	case DMBIC:		addr->dmlstat &= ~bits;		break;	}	addr->dmcsr = DM_IE|DM_SE;	splx(s);}/* * DM11 interrupt; deal with carrier transitions. */dmintr(dm)	register int dm;{	register struct uba_device *ui;	register struct tty *tp;	register struct dmdevice *addr;	ui = dminfo[dm];	if (ui == 0)		return;	addr = (struct dmdevice *)ui->ui_addr;	if (addr->dmcsr&DM_DONE) {		if (addr->dmcsr&DM_CF) {			tp = &dh11[(dm<<4)+(addr->dmcsr&0xf)];			wakeup((caddr_t)&tp->t_rawq);			if ((tp->t_state&TS_WOPEN) == 0 &&			    (tp->t_flags & MDMBUF)) {				if (addr->dmlstat & DML_CAR) {					tp->t_state &= ~TS_TTSTOP;					ttstart(tp);				} else if ((tp->t_state&TS_TTSTOP) == 0) {					tp->t_state |= TS_TTSTOP;					dhstop(tp, 0);				}			} else if ((addr->dmlstat&DML_CAR)==0) {				if ((tp->t_state&TS_WOPEN)==0 &&				    (tp->t_flags & NOHANG) == 0) {					gsignal(tp->t_pgrp, SIGHUP);					gsignal(tp->t_pgrp, SIGCONT);					addr->dmlstat = 0;					ttyflush(tp, FREAD|FWRITE);				}				tp->t_state &= ~TS_CARR_ON;			} else {				tp->t_state |= TS_CARR_ON;				tp->t_state &= ~TS_ONDELAY;			}		}		addr->dmcsr = DM_IE|DM_SE;	}}#endif

⌨️ 快捷键说明

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