📄 rs.c
字号:
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 + -