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

📄 com.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	c = inb(com+com_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(commajor, 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)		log(LOG_WARNING, "com%d: silo overflow\n", unit);	(*linesw[tp->t_line].l_rint)(c, tp);}commint(unit, com)	register int unit;	register com;{	register struct tty *tp;	register int stat;	tp = &com_tty[unit];	stat = inb(com+com_msr);	if ((stat & MSR_DDCD) && (comsoftCAR & (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)			outb(com+com_mcr,				inb(com+com_mcr) & ~(MCR_DTR | MCR_RTS) | MCR_IENABLE);	} else if ((stat & MSR_DCTS) && (tp->t_state & TS_ISOPEN) &&		   (tp->t_flags & CRTSCTS)) {		/* the line is up and we want to do rts/cts flow control */		if (stat & MSR_CTS) {			tp->t_state &=~ TS_TTSTOP;			ttstart(tp);		} else			tp->t_state |= TS_TTSTOP;	}}comioctl(dev, cmd, data, flag, p)	dev_t dev;	int cmd, flag;	caddr_t data;	struct proc *p;{	register struct tty *tp;	register int unit = UNIT(dev);	register com;	register int error; 	tp = &com_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);	com = com_addr[unit];	switch (cmd) {	case TIOCSBRK:		outb(com+com_cfcr, inb(com+com_cfcr) | CFCR_SBREAK);		break;	case TIOCCBRK:		outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK);		break;	case TIOCSDTR:		(void) commctl(dev, MCR_DTR | MCR_RTS, DMBIS);		break;	case TIOCCDTR:		(void) commctl(dev, MCR_DTR | MCR_RTS, DMBIC);		break;	case TIOCMSET:		(void) commctl(dev, *(int *)data, DMSET);		break;	case TIOCMBIS:		(void) commctl(dev, *(int *)data, DMBIS);		break;	case TIOCMBIC:		(void) commctl(dev, *(int *)data, DMBIC);		break;	case TIOCMGET:		*(int *)data = commctl(dev, 0, DMGET);		break;	default:		return (ENOTTY);	}	return (0);}comparam(tp, t)	register struct tty *tp;	register struct termios *t;{	register com;	register int cfcr, cflag = t->c_cflag;	int unit = UNIT(tp->t_dev);	int ospeed = ttspeedtab(t->c_ospeed, comspeedtab); 	/* 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;	com = com_addr[unit];	outb(com+com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS /*| IER_EMSC*/);	if (ospeed == 0) {		(void) commctl(unit, 0, DMSET);	/* hang up line */		return(0);	}	outb(com+com_cfcr, inb(com+com_cfcr) | CFCR_DLAB);	outb(com+com_data, ospeed & 0xFF);	outb(com+com_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;	outb(com+com_cfcr, cfcr);	if (com_hasfifo & (1 << unit))		outb(com+com_fifo, FIFO_ENABLE | FIFO_TRIGGER_14);	return(0);} voidcomstart(tp)	register struct tty *tp;{	register com;	int s, unit, c; 	unit = UNIT(tp->t_dev);	com = com_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 (inb(com+com_lsr) & LSR_TXRDY) {		c = getc(&tp->t_outq);		tp->t_state |= TS_BUSY;		outb(com+com_data, c);		if (com_hasfifo & (1 << unit))			for (c = 1; c < 16 && tp->t_outq.c_cc; ++c)				outb(com+com_data, getc(&tp->t_outq));	}out:	splx(s);} /* * Stop output on a line. *//*ARGSUSED*/comstop(tp, flag)	register struct tty *tp;{	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);} commctl(dev, bits, how)	dev_t dev;	int bits, how;{	register com;	register int unit;	int s;	unit = UNIT(dev);	com = com_addr[unit];	s = spltty();	switch (how) {	case DMSET:		outb(com+com_mcr, bits | MCR_IENABLE);		break;	case DMBIS:		outb(com+com_mcr, inb(com+com_mcr) | bits | MCR_IENABLE);		break;	case DMBIC:		outb(com+com_mcr, inb(com+com_mcr) & ~bits | MCR_IENABLE);		break;	case DMGET:		bits = inb(com+com_msr);		break;	}	(void) splx(s);	return(bits);}/* * Following are all routines needed for COM to act as console */#include <i386/i386/cons.h>comcnprobe(cp)	struct consdev *cp;{	int unit;	/* locate the major number */	for (commajor = 0; commajor < nchrdev; commajor++)		if (cdevsw[commajor].d_open == comopen)			break;	/* XXX: ick */	unit = CONUNIT;	com_addr[CONUNIT] = CONADDR;	/* make sure hardware exists?  XXX */	/* initialize required fields */	cp->cn_dev = makedev(commajor, unit);	cp->cn_tp = &com_tty[unit];#ifdef	COMCONSOLE	cp->cn_pri = CN_REMOTE;		/* Force a serial port console */#else	cp->cn_pri = CN_NORMAL;#endif}comcninit(cp)	struct consdev *cp;{	int unit = UNIT(cp->cn_dev);	cominit(unit, comdefaultrate);	comconsole = unit;	comconsinit = 1;}cominit(unit, rate)	int unit, rate;{	register int com;	int s;	short stat;#ifdef lint	stat = unit; if (stat) return;#endif	com = com_addr[unit];	s = splhigh();	outb(com+com_cfcr, CFCR_DLAB);	rate = ttspeedtab(comdefaultrate, comspeedtab);	outb(com+com_data, rate & 0xFF);	outb(com+com_ier, rate >> 8);	outb(com+com_cfcr, CFCR_8BITS);	outb(com+com_ier, IER_ERXRDY | IER_ETXRDY);	outb(com+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14);	stat = inb(com+com_iir);	splx(s);}comcngetc(dev){	register com = com_addr[UNIT(dev)];	short stat;	int c, s;#ifdef lint	stat = dev; if (stat) return(0);#endif	s = splhigh();	while (((stat = inb(com+com_lsr)) & LSR_RXRDY) == 0)		;	c = inb(com+com_data);	stat = inb(com+com_iir);	splx(s);	return(c);}/* * Console kernel output character routine. */comcnputc(dev, c)	dev_t dev;	register int c;{	register com = com_addr[UNIT(dev)];	register int timo;	short stat;	int s = splhigh();#ifdef lint	stat = dev; if (stat) return;#endif#ifdef KGDB	if (dev != kgdb_dev)#endif	if (comconsinit == 0) {		(void) cominit(UNIT(dev), comdefaultrate);		comconsinit = 1;	}	/* wait for any pending transmission to finish */	timo = 50000;	while (((stat = inb(com+com_lsr)) & LSR_TXRDY) == 0 && --timo)		;	outb(com+com_data, c);	/* wait for this transmission to complete */	timo = 1500000;	while (((stat = inb(com+com_lsr)) & LSR_TXRDY) == 0 && --timo)		;	/* clear any interrupts generated by this transmission */	stat = inb(com+com_iir);	splx(s);}#endif

⌨️ 快捷键说明

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