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

📄 dca.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	tp = &dca_tty[unit];	c = dca->dca_data;	if ((tp->t_state & TS_ISOPEN) == 0) {#ifdef KGDB		/* we don't care about parity errors */		if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) &&		    kgdb_dev == makedev(dcamajor, unit) && c == FRAME_END)			kgdb_connect(0); /* trap into kgdb */#endif		return;	}	if (stat & (LSR_BI | LSR_FE))		c |= TTY_FE;	else if (stat & LSR_PE)		c |= TTY_PE;	else if (stat & LSR_OE)		dcaoflows[unit]++;	(*linesw[tp->t_line].l_rint)(c, tp);}dcamint(unit, dca)	register int unit;	register struct dcadevice *dca;{	register struct tty *tp;	register u_char stat;	tp = &dca_tty[unit];	stat = dca->dca_msr;#ifdef DEBUG	dcamintcount[stat & 0xf]++;#endif	if ((stat & MSR_DDCD) &&	    (dcasoftCAR & (1 << unit)) == 0) {		if (stat & MSR_DCD)			(void)(*linesw[tp->t_line].l_modem)(tp, 1);		else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)			dca->dca_mcr &= ~(MCR_DTR | MCR_RTS);	}	/*	 * CTS change.	 * If doing HW output flow control start/stop output as appropriate.	 */	if ((stat & MSR_DCTS) &&	    (tp->t_state & TS_ISOPEN) && (tp->t_cflag & CCTS_OFLOW)) {		if (stat & MSR_CTS) {			tp->t_state &=~ TS_TTSTOP;			dcastart(tp);		} else {			tp->t_state |= TS_TTSTOP;		}	}}dcaioctl(dev, cmd, data, flag, p)	dev_t dev;	int cmd;	caddr_t data;	int flag;	struct proc *p;{	register struct tty *tp;	register int unit = UNIT(dev);	register struct dcadevice *dca;	register int error; 	tp = &dca_tty[unit];	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);	if (error >= 0)		return (error);	error = ttioctl(tp, cmd, data, flag);	if (error >= 0)		return (error);	dca = dca_addr[unit];	switch (cmd) {	case TIOCSBRK:		dca->dca_cfcr |= CFCR_SBREAK;		break;	case TIOCCBRK:		dca->dca_cfcr &= ~CFCR_SBREAK;		break;	case TIOCSDTR:		(void) dcamctl(dev, MCR_DTR | MCR_RTS, DMBIS);		break;	case TIOCCDTR:		(void) dcamctl(dev, MCR_DTR | MCR_RTS, DMBIC);		break;	case TIOCMSET:		(void) dcamctl(dev, *(int *)data, DMSET);		break;	case TIOCMBIS:		(void) dcamctl(dev, *(int *)data, DMBIS);		break;	case TIOCMBIC:		(void) dcamctl(dev, *(int *)data, DMBIC);		break;	case TIOCMGET:		*(int *)data = dcamctl(dev, 0, DMGET);		break;	default:		return (ENOTTY);	}	return (0);}dcaparam(tp, t)	register struct tty *tp;	register struct termios *t;{	register struct dcadevice *dca;	register int cfcr, cflag = t->c_cflag;	int unit = UNIT(tp->t_dev);	int ospeed = ttspeedtab(t->c_ospeed, dcaspeedtab); 	/* check requested parameters */        if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))                return (EINVAL);        /* and copy to tty */        tp->t_ispeed = t->c_ispeed;        tp->t_ospeed = t->c_ospeed;        tp->t_cflag = cflag;	dca = dca_addr[unit];	dca->dca_ier = IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC;#ifdef hp700	dca->dca_mcr |= MCR_IEN;#endif	if (ospeed == 0) {		(void) dcamctl(unit, 0, DMSET);	/* hang up line */		return (0);	}	dca->dca_cfcr |= CFCR_DLAB;	dca->dca_data = ospeed & 0xFF;	dca->dca_ier = ospeed >> 8;	switch (cflag&CSIZE) {	case CS5:		cfcr = CFCR_5BITS; break;	case CS6:		cfcr = CFCR_6BITS; break;	case CS7:		cfcr = CFCR_7BITS; break;	case CS8:		cfcr = CFCR_8BITS; break;	}	if (cflag&PARENB) {		cfcr |= CFCR_PENAB;		if ((cflag&PARODD) == 0)			cfcr |= CFCR_PEVEN;	}	if (cflag&CSTOPB)		cfcr |= CFCR_STOPB;	dca->dca_cfcr = cfcr;	if (dca_hasfifo & (1 << unit))		dca->dca_fifo = FIFO_ENABLE | FIFO_TRIGGER_14;	return (0);} voiddcastart(tp)	register struct tty *tp;{	register struct dcadevice *dca;	int s, unit, c; 	unit = UNIT(tp->t_dev);	dca = dca_addr[unit];	s = spltty();	if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))		goto out;	if (tp->t_outq.c_cc <= tp->t_lowat) {		if (tp->t_state&TS_ASLEEP) {			tp->t_state &= ~TS_ASLEEP;			wakeup((caddr_t)&tp->t_outq);		}		selwakeup(&tp->t_wsel);	}	if (tp->t_outq.c_cc == 0)		goto out;	if (dca->dca_lsr & LSR_TXRDY) {		c = getc(&tp->t_outq);		tp->t_state |= TS_BUSY;		dca->dca_data = c;		if (dca_hasfifo & (1 << unit)) {			for (c = 1; c < 16 && tp->t_outq.c_cc; ++c)				dca->dca_data = getc(&tp->t_outq);#ifdef DEBUG			if (c > 16)				fifoout[0]++;			else				fifoout[c]++;#endif		}	}out:	splx(s);} /* * Stop output on a line. *//*ARGSUSED*/dcastop(tp, flag)	register struct tty *tp;	int flag;{	register int s;	s = spltty();	if (tp->t_state & TS_BUSY) {		if ((tp->t_state&TS_TTSTOP)==0)			tp->t_state |= TS_FLUSH;	}	splx(s);} dcamctl(dev, bits, how)	dev_t dev;	int bits, how;{	register struct dcadevice *dca;	register int unit;	int s;	unit = UNIT(dev);	dca = dca_addr[unit];#ifdef hp700	/*	 * Always make sure MCR_IEN is set (unless setting to 0)	 */#ifdef KGDB	if (how == DMSET && kgdb_dev == makedev(dcamajor, unit))		bits |= MCR_IEN;	else#endif	if (how == DMBIS || (how == DMSET && bits))		bits |= MCR_IEN;	else if (how == DMBIC)		bits &= ~MCR_IEN;#endif	s = spltty();	switch (how) {	case DMSET:		dca->dca_mcr = bits;		break;	case DMBIS:		dca->dca_mcr |= bits;		break;	case DMBIC:		dca->dca_mcr &= ~bits;		break;	case DMGET:		bits = dca->dca_msr;		break;	}	(void) splx(s);	return (bits);}/* * Following are all routines needed for DCA to act as console */#include <hp/dev/cons.h>dcacnprobe(cp)	struct consdev *cp;{	int unit;	/* locate the major number */	for (dcamajor = 0; dcamajor < nchrdev; dcamajor++)		if (cdevsw[dcamajor].d_open == dcaopen)			break;	/* XXX: ick */	unit = CONUNIT;#ifdef hp300	dca_addr[CONUNIT] = (struct dcadevice *) sctova(CONSCODE);	/* make sure hardware exists */	if (badaddr((short *)dca_addr[unit])) {		cp->cn_pri = CN_DEAD;		return;	}#endif#ifdef hp700	dca_addr[CONUNIT] = CONPORT;#endif	/* initialize required fields */	cp->cn_dev = makedev(dcamajor, unit);	cp->cn_tp = &dca_tty[unit];#ifdef hp300	switch (dca_addr[unit]->dca_id) {	case DCAID0:	case DCAID1:		cp->cn_pri = CN_NORMAL;		break;	case DCAREMID0:	case DCAREMID1:		cp->cn_pri = CN_REMOTE;		break;	default:		cp->cn_pri = CN_DEAD;		break;	}#endif#ifdef hp700	cp->cn_pri = CN_NORMAL;#endif	/*	 * If dcaconsole is initialized, raise our priority.	 */	if (dcaconsole == unit)		cp->cn_pri = CN_REMOTE;#ifdef KGDB	if (major(kgdb_dev) == 1)			/* XXX */		kgdb_dev = makedev(dcamajor, minor(kgdb_dev));#endif}dcacninit(cp)	struct consdev *cp;{	int unit = UNIT(cp->cn_dev);	dcainit(unit, dcadefaultrate);	dcaconsole = unit;	dcaconsinit = 1;}dcainit(unit, rate)	int unit, rate;{	register struct dcadevice *dca;	int s;	short stat;#ifdef lint	stat = unit; if (stat) return;#endif	dca = dca_addr[unit];	s = splhigh();#ifdef hp300	dca->dca_reset = 0xFF;	DELAY(100);	dca->dca_ic = IC_IE;#endif	dca->dca_cfcr = CFCR_DLAB;	rate = ttspeedtab(rate, dcaspeedtab);	dca->dca_data = rate & 0xFF;	dca->dca_ier = rate >> 8;	dca->dca_cfcr = CFCR_8BITS;	dca->dca_ier = IER_ERXRDY | IER_ETXRDY;#ifdef hp700	dca->dca_mcr |= MCR_IEN;#endif	dca->dca_fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14;	DELAY(100);	stat = dca->dca_iir;	splx(s);}dcacngetc(dev)	dev_t dev;{	register struct dcadevice *dca = dca_addr[UNIT(dev)];	register u_char stat;	int c, s;#ifdef lint	stat = dev; if (stat) return (0);#endif	s = splhigh();	while (((stat = dca->dca_lsr) & LSR_RXRDY) == 0)		;	c = dca->dca_data;	stat = dca->dca_iir;	splx(s);	return (c);}/* * Console kernel output character routine. */dcacnputc(dev, c)	dev_t dev;	register int c;{	register struct dcadevice *dca = dca_addr[UNIT(dev)];	register int timo;	register u_char stat;	int s = splhigh();#ifdef lint	stat = dev; if (stat) return;#endif	if (dcaconsinit == 0) {		(void) dcainit(UNIT(dev), dcadefaultrate);		dcaconsinit = 1;	}	/* wait for any pending transmission to finish */	timo = 50000;	while (((stat = dca->dca_lsr) & LSR_TXRDY) == 0 && --timo)		;	dca->dca_data = c;	/* wait for this transmission to complete */	timo = 1500000;	while (((stat = dca->dca_lsr) & LSR_TXRDY) == 0 && --timo)		;	/*	 * If the "normal" interface was busy transfering a character	 * we must let our interrupt through to keep things moving.	 * Otherwise, we clear the interrupt that we have caused.	 */	if ((dca_tty[UNIT(dev)].t_state & TS_BUSY) == 0)		stat = dca->dca_iir;	splx(s);}#endif

⌨️ 快捷键说明

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