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

📄 rs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	else		ndflush(&tp->t_outq, count);	(void) splx(s);	if (tp->t_line)		(*linesw[tp->t_line].l_start)(tp);	else		rsstart(tp);}/* * Start (restart) transmission on the given RS line. */voidrsstart(tp)	register struct tty *tp;{	register int unit, nch;	int s;	unit = minor(tp->t_dev);	/*	 * Must hold interrupts in following code to prevent	 * state of the tp from changing.	 */	s = spltty();	/*	 * 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 ther are still characters in the IOP,	 * just reenable transmit.	 */	if (rs_stopped[unit]) {		rs_start(unit);		rs_stopped[unit] = 0;		goto out;	}	/*	 * If there are sleepers, and output has drained below low	 * water mark, wake up the sleepers.	 */	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);	}	/*	 * 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) {		tp->t_state |= TS_BUSY;		rs_output(unit, nch);	}out:	(void) splx(s);}/* * Stop output on a line, e.g. for ^S/^Q or output flush. *//*ARGSUSED*/rsstop(tp, flag)	register struct tty *tp;{	register int unit, s;	unit = minor(tp->t_dev);	s = spltty();	if (tp->t_state & TS_BUSY) {		rs_stop(unit, 0);		rs_stopped[unit] = 1;		if ((tp->t_state & TS_TTSTOP) == 0) {			tp->t_state |= TS_FLUSH;			rs_stop(unit, 1);		}	}	(void) splx(s);}/* * RS modem control */rsmctl(dev, bits, how)	dev_t dev;	int bits, how;{	register int unit, mbits;	int s;#ifdef AUTO_ENABLE	bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK|RS_AUTO_ENABLE);#else	bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK);#endif	unit = minor(dev);	s = spltty();		/* spl5 -> spltty, 90/02/28 sak */	mbits = rs_get_param(unit);	switch (how) {	case DMSET:		mbits = mbits & ~(RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK) | bits;		break;	case DMBIS:		mbits |= bits;		break;	case DMBIC:		mbits &= ~bits;		break;	case DMGET:		(void) splx(s);		return(mbits);	}	rs_param[unit] = mbits;	rs_set_param(unit, rs_param[unit]);	(void) splx(s);	return(mbits);}/* * Reset state of driver if IOP reset was necessary. * Reset the parameter and status, and * restart transmitters. */rsreset(){	register int unit;	register struct tty *tp;	register struct iop_device *ii;	for (unit = 0; unit < NRS * 4; unit++) {		ii = rsinfo[unit >> 2];		if (ii == 0 || ii->ii_alive == 0)			continue;		printf(" rs%d", unit);		tp = &rs_tty[unit];		if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {			rs_reset(unit);			rsparam(tp, &tp->t_termios);			(void) rsmctl(unit, RS_ON, DMSET);			tp->t_state &= ~TS_BUSY;			rsstart(tp);		}	}}/* * RS status interrupt */_rssint(unit, stat)	int unit;	int stat;{	register struct tty *tp;#ifdef notyet /* KU:XXX */	intrcnt[INTR_RS0 + unit]++;#endif	tp = &rs_tty[unit];	if (stat & RS_DCD) {		rs_param[unit] |= RS_DCD;		(void)(*linesw[tp->t_line].l_modem)(tp, 1);	} else if (RS_CARR(unit) == 0 &&	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {		rs_param[unit] &= ~(RS_DCD | RS_DTR);		rs_set_param(unit, rs_param[unit]);	}	if (stat & OVERRUN_ERROR) {		printf("rs%d: fifo overflow\n", unit);		rs_param[unit] &= ~OVERRUN_ERROR;		rs_set_param(unit, rs_param[unit]);	}	if (stat & RBREAK) {		rs_param[unit] &= ~RBREAK;		if (tp->t_state & TS_ISOPEN)			(*linesw[tp->t_line].l_rint)			    (tp->t_flags & RAW ? '\0' : tp->t_cc[VINTR], tp);	}}/* * RS control interrupt */rscint(rs)	int rs;{	printf("rscint: %d\n", rs);}/* * RS H/W control */voidrsctrl(tp, cmd, arg)	struct tty *tp;	int cmd;	int arg;{#ifdef notyet /* KU:XXX */	int unit = minor(tp->t_dev);	switch (cmd) {	case TC_HBLOCK:		if (RS_FLAG(unit, RF_FLOWCTL))			rsflowctl(unit, arg);		break;	default:		break;	}	return (0);#endif}rsflowctl(unit, block)	int unit;	int block;{	int s;	s = spltty();	if (block)		rs_param[unit] &= ~RS_RTS;	else		rs_param[unit] |= RS_RTS;	rs_set_param(unit, rs_param[unit]);	(void) splx(s);}/* * Machine dependent functions * *	rs_probe() *	rs_init() *	rsrint() *	rsxint() *	rssint() *	rs_enable() *	rs_output() *	rs_start() *	rs_stop() *	rs_reset() *	rs_get_param() *	rs_set_param() */#ifdef CPU_SINGLE#include <news3400/hbdev/hbvar.h>#include <news3400/hbdev/rsreg.h>#include <news3400/sio/scc.h>int	rslastcount[NRS*4];int	scc_unit[] = { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 };int	rs_unit[] = { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11 };rs_probe(hi)	struct hb_device *hi;{	register int i, cmax;	for (i = (hi->hi_unit << 2), cmax = 4; cmax > 0; cmax--, i++) {		if (i == 2 || i == 3)			continue;		if (scc_probe(scc_unit[i]))			continue;		return (0);	}	return (1);}rs_init(unit)	int unit;{	if (scc_open(scc_unit[unit])) {		printf("rs_init: chan %d open failed.\n", scc_unit[unit]);		return (-1);	}	return (0);}rs_enable(unit)	int unit;{	scc_enable(scc_unit[unit]);}rsrint(scc, buf, cnt)	int scc;	char *buf;	int cnt;{	_rsrint(rs_unit[scc], buf, cnt);}rsxint(scc)	int scc;{	int unit = rs_unit[scc];	_rsxint(unit, rslastcount[unit]);}rssint(scc, stat)	int scc;	int stat;{	_rssint(rs_unit[scc], stat);}rs_start(unit)	int unit;{	scc_start(scc_unit[unit]);}rs_output(unit, n)	int unit;	int n;{	rslastcount[unit] =	    scc_write(scc_unit[unit], rs_tty[unit].t_outq.c_cf, n);}rs_stop(unit, flush)	int unit;	int flush;{	if (flush)		scc_flush(scc_unit[unit]);}rs_reset(unit)	int unit;{	scc_reset(scc_unit[unit]);}rs_get_param(unit)	int unit;{	return (scc_get_param(scc_unit[unit]));}rs_set_param(unit, param)	int unit;	int param;{	scc_set_param(scc_unit[unit], param);}#endif /* CPU_SINGLE */#ifdef IPC_MRX#include "../ipc/newsipc.h"#include "../mrx/h/scc.h"#include "../mrx/h/cio.h"int	port_rsrecv[NRS*4];int	port_rsxmit[NRS*4];int	port_rsstat[NRS*4];int	port_rsctrl[NRS*4];int	port_recv_iop[NRS*4];int	port_xmit_iop[NRS*4];int	port_ctrl_iop[NRS*4];int	port_stat_iop[NRS*4];/* *	minor No: 0 - 12 ----> SCC unit No : 0 - 9 */int	scc_unit[] = { 1, 0, -1, -1, 3, 2, 5, 4, 7, 6, 9, 8 };rs_probe(ii)	struct iop_device *ii;{	register int base = ii->ii_unit << 2;	register int i, j;	char buf[16];#define	PT_CREATE(buf, name, unit, func, arg)	\	port_create(make_name(buf, name, unit), func, arg)#define	OB_QUERY(buf, name, unit) \	object_query(make_name(buf, name, unit))	for (i = base; i < base+4; i++) {		if ((j = scc_unit[i]) < 0)			continue;		port_recv_iop[i] = OB_QUERY(buf, "scc_inputX", j);		if (port_recv_iop[i] <= 0)			return (0);		port_xmit_iop[i] = OB_QUERY(buf, "scc_outputX", j);		port_ctrl_iop[i] = OB_QUERY(buf, "scc_ctrlX", j);		port_stat_iop[i] = OB_QUERY(buf, "scc_statX", j);		port_rsrecv[i] = PT_CREATE(buf, "@rsrecvX", j, rsrint, i);		port_rsxmit[i] = PT_CREATE(buf, "@rsxmitX", j, rsxint, i);		port_rsctrl[i] = PT_CREATE(buf, "@rsctrlX", j, NULL, 0);		port_rsstat[i] = PT_CREATE(buf, "@rsstatX", j, rssint, i);	}	return (1);}rs_init(unit)	int unit;{	int len;	msg_send(port_stat_iop[unit], port_rsstat[unit], NULL, 0, 0);	return (0);}rs_enable(unit)	int unit;{	int len;	len = MAX_CIO;	msg_send(port_recv_iop[unit], port_rsrecv[unit], &len, sizeof(len), 0);}rsrint(unit)	register int	unit;{	char *addr;	int from, len;	msg_recv(port_rsrecv[unit], &from, &addr, &len, 0);#ifdef mips	clean_dcache(addr, len + 8);#endif	_rsrint(unit, addr, len);}rsxint(unit)	register int unit;{	int from, *len;	msg_recv(port_rsxmit[unit], &from, &len, NULL, 0);	_rsxint(unit, *len);}rssint(unit)	register int unit;{	int from, *reply;	msg_recv(port_rsstat[unit], &from, &reply, NULL, 0);	_rssint(unit, *reply);	msg_send(from, port_rsstat[unit], NULL, 0, 0);}rs_start(unit)	int unit;{	int func;	func = CIO_START;	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);}rs_output(unit, n)	int unit;	int n;{	msg_send(port_xmit_iop[unit], port_rsxmit[unit],	    rs_tty[unit].t_outq.c_cf, min(n, MAX_CIO), 0);}rs_stop(unit, flush)	int unit;	int flush;{	int func;	func = flush ? CIO_FLUSH : CIO_STOP;	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);}rs_reset(unit)	int unit;{	int func;	func = CIO_RESET;	msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);}rs_get_param(unit)	register int unit;{	register int port;	struct scc_ctrl_req req;	int param, *reply;	port = port_rsctrl[unit];	req.scc_func = CIO_GETPARAMS;	/* message length 8 means 2 * sizeof(int) : func and status */	msg_send(port_ctrl_iop[unit], port, &req, 8, 0);	msg_recv(port, NULL, &reply, NULL, 0);	param = *reply;	msg_free(port);	return (param);}rs_set_param(unit, param)	register int unit;	int param;{	struct scc_ctrl_req req;	req.scc_func = CIO_SETPARAMS;	req.scc_arg = param;	/* message length 8 means 2 * sizeof(int) : func and param */	msg_send(port_ctrl_iop[unit], 0, &req, 8, 0);}#endif /* IPC_MRX */#endif /* NRS > 0 */

⌨️ 快捷键说明

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