📄 sio.c
字号:
default: return (ENOTTY); } return (0);}/* * */voidsiostart(tp) register struct tty *tp;{ register struct siodevice *sio; register int rr; int s, unit, c; unit = siounit(tp->t_dev); sio = sio_softc[unit].sc_pc->pc_addr; 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; rr = siogetreg(sio); if (rr & RR_TXRDY) { c = getc(&tp->t_outq); tp->t_state |= TS_BUSY; sio->sio_data = c; }out: splx(s);}sioparam(tp, t) register struct tty *tp; register struct termios *t;{ int unit = siounit(tp->t_dev); register struct siodevice *sio; register cflag = t->c_cflag; register u_char wr; int ospeed = ttspeedtab(t->c_ospeed, siospeedtab); sio = sio_softc[unit].sc_pc->pc_addr; switch (cflag & CSIZE) { case CS5: case CS6: case CS7: case CS8: break; } wr = ospeed; if (cflag & PARENB) { wr |= WR4_PARENAB; if ((cflag&PARODD) == 0) wr |= WR4_EPARITY; } if (cflag & CSTOPB) wr |= WR4_STOP2; /* 2 stop bit */ else wr |= WR4_STOP1; /* 1 stop bit */ (void) sioreg(sio, WR4, wr); return (0);}siomctl(){ return (0);}/* * Interrupt handling */void_siointr(){ register int port; register struct sio_portc *pc; for (port = 0; port < NPORT; port++) { pc = &sio_portc[port]; if (pc->pc_major != -1) (pc->pc_intr)(pc->pc_unit); }}siointr(unit) register int unit;{ register struct siodevice *sio = sio_softc[unit].sc_pc->pc_addr; register u_char code; register struct tty *tp; int s, rr; tp = &sio_tty[unit];start: rr = siogetreg(sio); if (rr & RR_RXRDY) { if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) { sioeint(unit, rr, sio); goto start; } code = sio->sio_data; if ((tp->t_state & TS_ISOPEN) != 0) (*linesw[tp->t_line].l_rint)(code, tp);#ifdef KGDB else { if (code == FRAME_END && kgdb_dev == makedev(siomajor, unit)) kgdb_connect(0); /* trap into kgdb */ }#endif while ((rr = siogetreg(sio)) & RR_RXRDY) { code = sio->sio_data; if ((tp->t_state & TS_ISOPEN) != 0) (*linesw[tp->t_line].l_rint)(code, tp);#ifdef KGDB else { if (code == FRAME_END && kgdb_dev == makedev(siomajor, unit)) kgdb_connect(0); /* trap into kgdb */ }#endif } } if (rr & RR_TXRDY) { sio->sio_cmd = WR0_RSTPEND; tp->t_state &= ~(TS_BUSY|TS_FLUSH); if (tp->t_line) (*linesw[tp->t_line].l_start)(tp); else siostart(tp); }}sioeint(unit, stat, sio) register int unit, stat; register struct siodevice *sio;{ register struct tty *tp; register int code; tp = &sio_tty[unit]; code = sio->sio_data; sio->sio_cmd = WR0_ERRRST; if ((tp->t_state & TS_ISOPEN) == 0) {#ifdef KGDB /* we don't care about parity errors */ if (((stat & (RR_FRAMING|RR_PARITY)) == RR_PARITY) && kgdb_dev == makedev(siomajor, unit) && code == FRAME_END) kgdb_connect(0); /* trap into kgdb */#endif return; } if (stat & RR_FRAMING) code |= TTY_FE; else if (stat & RR_PARITY) code |= TTY_PE; (*linesw[tp->t_line].l_rint)(code, tp);}/* * Following are all routines needed for SIO to act as console */#include <luna68k/luna68k/cons.h>siocnprobe(cp) register struct consdev *cp;{ register int unit = 0; /* locate the major number */ for (siomajor = 0; siomajor < nchrdev; siomajor++) if (cdevsw[siomajor].d_open == sioopen) break; /* initialize required fields */ cp->cn_dev = makedev(siomajor, unit); cp->cn_tp = &sio_tty[unit]; cp->cn_pri = CN_NORMAL;}siocninit(cp) struct consdev *cp;{ int unit = siounit(cp->cn_dev); register struct sio_softc *sc = &sio_softc[unit]; sioinit((struct siodevice *) SIO_HARDADDR, siodefaultrate); /* port assign */ sc->sc_pc = sio_port_assign(SIO_PORT, siomajor, unit, siointr); sioconsole = unit; sio_active |= 1 << unit; siosoftCAR |= 1 << unit;}siocngetc(dev) dev_t dev;{ struct sio_softc *sc = &sio_softc[siounit(dev)]; struct sio_portc *pc = sc->sc_pc; return(sio_imgetc(pc->pc_addr));}siocnputc(dev, c) dev_t dev; int c;{ struct sio_softc *sc = &sio_softc[siounit(dev)]; struct sio_portc *pc = sc->sc_pc; sio_imputc(pc->pc_addr, c);}/* * sio raw-level routines */sioinit(sio0, rate) register struct siodevice *sio0; register int rate;{ register struct siodevice *sio1; int s; rate = ttspeedtab(rate, siospeedtab); if (sio_init_done) return; sio1 = (struct siodevice *) ((u_long) sio0 + sizeof(struct siodevice)); s = splhigh(); sioreg(sio0, WR0, WR0_CHANRST); /* Channel-A Reset */ sioreg(sio0, WR2, (WR2_VEC86 | WR2_INTR_1)); /* Set CPU BUS Interface Mode */ sioreg(sio1, WR2, 0); /* Set Interrupt Vector */ sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ sioreg(sio0, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ sioreg(sio0, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ sioreg(sio0, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ sioreg(sio0, WR1, (WR1_RXALLS | WR1_TXENBL)); sioreg(sio1, WR0, WR0_CHANRST); /* Channel-B Reset */ sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ sioreg(sio1, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ sioreg(sio1, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ sioreg(sio1, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ sioreg(sio1, WR1, (WR1_RXALLS | WR1_TXENBL)); splx(s); sio_init_done = 1;}sio_imgetc(sio) register struct siodevice *sio;{ register int rr0, rr1; int c, s; s = splhigh(); while (((rr0 = sioreg(sio, RR0, 0)) & RR0_RXAVAIL) == 0) ; c = sio->sio_data; sioreg(sio, WR0, WR0_RSTPEND); splx(s); return (c);}sio_imputc(sio, c) register struct siodevice *sio; int c;{ register u_char code; register int rr; int s; s = splhigh(); sioreg(sio, WR1, WR1_RXALLS); do { DELAY(1); rr = siogetreg(sio); } while (!(rr & RR_TXRDY)); code = (c & 0xFF); sio->sio_data = code; do { DELAY(1); rr = siogetreg(sio); } while (!(rr & RR_TXRDY)); sioreg(sio, WR1, (WR1_RXALLS | WR1_TXENBL)); splx(s);}/* * uPD7201A register operation */intsiogetreg(sio) register struct siodevice *sio;{ register int rr = 0; rr = sio->sio_stat; rr <<= 8; sio->sio_cmd = 1; /* Select RR1 */ rr |= sio->sio_stat; return(rr);}intsioreg(sio, reg, val) register struct siodevice *sio; register int reg, val;{ if (isStatusReg(reg)) { if (reg != 0) sio->sio_cmd = reg; val = sio->sio_stat; } else { if (reg != 0) sio->sio_cmd = reg; sio->sio_cmd = val; } return(val);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -