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

📄 dmf.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
		timeout(dmfsetbreak, tp, dmf_delay[tp->t_cflag & CBAUD]);		TTY_SLEEP(tp, (caddr_t)&tp->t_dev, TTOPRI);		(void) dmfmctl(dev, DMF_BRK, DMBIS);		break;	case TIOCCBRK:		(void) dmfmctl(dev, DMF_BRK, DMBIC);		break;	case TIOCSDTR:		(void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS);		break;	case TIOCCDTR:		(void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC);		break;	case TIOCMSET:		(void) dmfmctl(dev, dmtodmf(*(int *)data), DMSET);		break;	case TIOCMBIS:		(void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIS);		break;	case TIOCMBIC:		(void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIC);		break;	case TIOCMGET:		*(int *)data = dmftodm(dmfmctl(dev, 0, DMGET));		break;#ifdef 0	/*	 * Doesn't work yet !	 */	/* Set local loopback mode */	case TIOCSMLB:		if (u.u_uid)			return(EPERM);		s=spl5();		dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr);		dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | (unit & LINEMASK);		SETLCR(dmfaddr, dmfaddr->dmflcr|DMF_MAINT);		splx(s);		break;	/* Clear local loopback mode */	case TIOCCMLB:		if (u.u_uid)			return(EPERM);		s=spl5();		dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr);		dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | (unit & LINEMASK);		SETLCR(dmfaddr, dmfaddr->dmflcr&~DMF_MAINT);		splx(s);		break;#endif 0	case TIOCNMODEM:  /* ignore modem status */		s = spl5();		dmfsoftCAR[dmf] |= (1<<(unit&LINEMASK));		if (*(int *)data) /* make mode permanent */			dmfdefaultCAR[dmf] |= (1<<(unit&LINEMASK));		dmfmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR;		tp->t_state |= TS_CARR_ON;		tp->t_cflag |= CLOCAL;		/* Map to termio */		splx(s);		break;	case TIOCMODEM:  /* look at modem status - sleep if no carrier */		s = spl5();		dmfsoftCAR[dmf] &= ~(1<<(unit&LINEMASK));		if (*(int *)data) /* make mode permanent */			dmfdefaultCAR[dmf] &= ~(1<<(unit&LINEMASK));		dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr);		dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | (unit&LINEMASK);	   	/* 	    	 * If dmfdsr is set look for DSR|CTS|CD, otherwise look 	    	 * for CD|CTS only.	    	 */		if ((dmfdsr && ((dmfaddr->dmfrms & DMF_XMIT)==DMF_XMIT)) ||		    ((dmfdsr == 0) && ((dmfaddr->dmfrms & DMF_NODSR)==DMF_NODSR))){			tp->t_state |= TS_CARR_ON;			tp->t_state &= ~TS_ONDELAY;			dmfmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR;		}		else {			tp->t_state &= ~(TS_CARR_ON);			dmfmodem[unit] &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR);		}		tp->t_cflag &= ~CLOCAL;		/* Map to termio */		splx(s);		break;	case TIOCWONLINE:		s = spl5();#ifdef DMFDEBUG		if (dmfdebug)			mprintf("dmfioctl: WONLINE, tp=%x, state=%x\n",				tp, tp->t_state);#endif		dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr);		dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | (unit&LINEMASK);	   	/* 	    	 * If dmfdsr is set look for DSR|CTS|CD, otherwise look 	    	 * for CD|CTS only.	    	 */		if ((dmfdsr && ((dmfaddr->dmfrms & DMF_XMIT)==DMF_XMIT)) ||		    ((dmfdsr == 0) && ((dmfaddr->dmfrms & DMF_NODSR)==DMF_NODSR))){			tp->t_state |= TS_CARR_ON;			tp->t_state &= ~TS_ONDELAY;			dmfmodem[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));		if (tp->t_cflag & CLOCAL) {			sc->sc_category_flags[unit&LINEMASK] |= DEV_MODEM;			sc->sc_category_flags[unit&LINEMASK] &= ~DEV_MODEM_ON;		}		else			sc->sc_category_flags[unit&LINEMASK] |= (DEV_MODEM|DEV_MODEM_ON);		devget->category = DEV_TERMINAL;		devget->bus = DEV_UB;		bcopy(DEV_DMF32,devget->interface,		      strlen(DEV_DMF32));		bcopy(DEV_UNKNOWN,devget->device,		      strlen(DEV_UNKNOWN));		/* terminal	*/		devget->adpt_num = ui->ui_adpt; 	/* which adapter*/		devget->nexus_num = ui->ui_nexus;	/* which nexus	*/		devget->bus_num = ui->ui_ubanum;	/* which UBA	*/		devget->ctlr_num = dmf; 		/* which interf.*/		devget->slave_num = unit&LINEMASK;	/* which line	*/		bcopy(ui->ui_driver->ud_dname,		      devget->dev_name,		      strlen(ui->ui_driver->ud_dname)); /* Ultrix "dmf" */		devget->unit_num = unit&LINEMASK;	/* which dmf line ? */		devget->soft_count =		      sc->sc_softcnt[unit&LINEMASK];	/* soft er. cnt.*/		devget->hard_count =		      sc->sc_hardcnt[unit&LINEMASK];	/* hard er cnt. */		devget->stat = sc->sc_flags[unit&LINEMASK]; /* status	*/		devget->category_stat =		      sc->sc_category_flags[unit&LINEMASK]; /* cat. stat.  */		break;	/*	 * Used to specify that this device has outgoing auto flow control.	 * Set appropriate bit in lpar.	 */	case TIOAUTO:		/*	 	* Outgoing Auto flow control.	 	* No auto flow control allowed if startc != ^q and startc !=	 	* ^s.  Most drivers do not allow these chars to be changed.	 	*/                if ((tp->t_cflag_ext&PAUTOFLOW) && (tp->t_cc[VSTOP] != CTRL('s'))                        || (tp->t_cc[VSTART] != CTRL('q')))                        tp->t_cflag_ext &= ~PAUTOFLOW;		dmfparam(unit);		break;	default:		if (u.u_procp->p_progenv == A_POSIX) 			return (EINVAL);		return (ENOTTY);	}	return (0);}dmtodmf(bits)	register int bits;{	register int b;	b = bits & 012;	if (bits & DML_ST) b |= DMF_RATE;	if (bits & DML_RTS) b |= DMF_RTS;	if (bits & DML_USR) b |= DMF_USRW;	return(b);}dmftodm(bits)	register int bits;{	register int b;	b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE;	if (bits & DMF_USRR) b |= DML_USR;	if (bits & DMF_RTS) b |= DML_RTS;	return(b);}/* * Set parameters from open or stty into the DMF hardware * registers. */dmfparam(unit)	register int unit;{	register struct tty *tp;	register struct dmfdevice *addr;	register int lpar, lcr;	int s;	tp = &dmf_tty[unit];	addr = (struct dmfdevice *)tp->t_addr;	/*	 * Block interrupts so parameters will be set	 * before the line interrupts.	 */	s = spl5();	addr->dmfcsr = (unit&LINEMASK) | DMFIR_LCR | DMF_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) dmfmctl(unit, DMF_OFF, DMSET);		splx(s);		return;	}	lpar = (dmf_speeds[tp->t_cflag_ext&CBAUD]<<12) | 	/* ospeed */		(dmf_speeds[tp->t_cflag&CBAUD]<<8);	/* ispeed */	lcr = DMFLCR_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;		}	} 	/*	 * Set device registers according to the specifications of the termio	 * structure. 	 */ 	if (tp->t_cflag & CREAD) 		lcr |= DMF_RE;	else 		lcr &= ~DMF_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 |= DMF_AUTOX;	lpar |= (unit&LINEMASK);	addr->dmflpr = lpar;	SETLCR(addr, lcr);#ifdef DMFDEBUG	if (dmfdebug)		mprintf("dmfparam: tp=%x, lpr=%x, lcr=%o\n",			tp, addr->dmflpr, addr->dmfun.dmfirw);#endif	splx(s);}/* * DMF32 transmitter interrupt. * Restart the idle line. */dmfxint(dmf)	int dmf;{	int u = dmf * 8;	struct tty *tp0 = &dmf_tty[u];	register struct tty *tp;	register struct dmfdevice *addr;	register struct uba_device *ui;	register int t;	short cntr;	ui = dmfinfo[dmf];	addr = (struct dmfdevice *)ui->ui_addr;	while ((t = addr->dmfcsr) & DMF_TI) {		if (t & DMF_NXM)			/* SHOULD RESTART OR SOMETHING... */			printf("dmf%d: NXM line %d\n", dmf, 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 (dmf_dma[u + t]) {			/*			 * Do arithmetic in a short to make up			 * for lost 16&17 bits.			 */			addr->dmfcsr = DMFIR_TBA | DMF_IE | t;			cntr = addr->dmftba -			    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			dmfstart(tp);	}}/* * Start (restart) transmission on the given DMF32 line. */dmfstart(tp)	register struct tty *tp;{	register struct dmfdevice *addr;	register int unit, nch, line;	int s;	register int dmf;	unit = minor(tp->t_dev);	dmf = unit >> 3;	line = unit & LINEMASK;	addr = (struct dmfdevice *)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 do not transmit if not CTS.	 */	if ((tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) ||		 ((tp->t_state & TS_CARR_ON) && (dmfmodem[unit]&MODEM_CTS)==0))		goto out;	/*	 * If there are still characters in the silo,	 * just reenable the transmitter.	 */	addr->dmfcsr = DMF_IE | DMFIR_TBUF | line;	if (addr->dmftsc) {		addr->dmfcsr = DMF_IE | DMFIR_LCR | line;		SETLCR(addr, addr->dmflcr|DMF_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 >= dmf_mindma) {		register car;		dmf_dma[unit] = 1;		addr->dmfcsr = DMF_IE | DMFIR_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->dmflcr|DMF_TE);		car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum);		addr->dmfcsr = DMF_IE | DMFIR_TBA | line;		/*		 * Give the device the starting address of a DMA transfer.  		 * Translate the system virtual address into a physical		 * address.		 */		addr->dmftba = svtophy(car);		addr->dmftcc = ((car >> 2) & 0xc000) | nch;		tp->t_state |= TS_BUSY;	} else if (nch) {		register char *cp = tp->t_outq.c_cf;		register int i;		dmf_dma[unit] = 0;		nch = MIN(nch, DMF_SILOCNT);		addr->dmfcsr = DMF_IE | DMFIR_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->dmflcr|DMF_TE);		addr->dmfcsr = DMF_IE | DMFIR_TBUF | line;		for (i = 0; i < nch; i++)

⌨️ 快捷键说明

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