--- Net2/arch/i386/isa/com.c 2018/04/24 18:04:01 1.1 +++ Net2/arch/i386/isa/com.c 2018/04/24 18:12:06 1.1.1.4 @@ -31,7 +31,18 @@ * SUCH DAMAGE. * * @(#)com.c 7.5 (Berkeley) 5/16/91 + * + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 4 00079 + * -------------------- ----- ---------------------- + * + * 23 Sep 92 Rodney W. Grimes Fix SILO overflow on 16550 UARTS + * 30 Aug 92 Poul-Henning Kamp Stabilize SLIP on lossy lines/UARTS + * 09 Aug 92 Christoph Robitschko Correct minor number on com ports + * 10 Feb 93 Jordan K. Hubbard Added select code */ +static char rcsid[] = "$Header: /var/lib/cvsd/net2/Net2/arch/i386/isa/com.c,v 1.1.1.4 2018/04/24 18:12:06 root Exp $"; #include "com.h" #if NCOM > 0 @@ -50,10 +61,12 @@ #include "uio.h" #include "kernel.h" #include "syslog.h" +#include "types.h" #include "i386/isa/isa_device.h" #include "i386/isa/comreg.h" #include "i386/isa/ic/ns16550.h" +#define cominor(d) int comprobe(), comattach(), comintr(), comstart(), comparam(); @@ -106,7 +119,7 @@ extern int kgdb_rate; extern int kgdb_debug_init; #endif -#define UNIT(x) minor(x) +#define UNIT(x) (minor(x)) comprobe(dev) struct isa_device *dev; @@ -114,10 +127,10 @@ struct isa_device *dev; /* force access to id reg */ outb(dev->id_iobase+com_cfcr, 0); outb(dev->id_iobase+com_iir, 0); + DELAY(100); if ((inb(dev->id_iobase+com_iir) & 0x38) == 0) - return(1); - return(1); - + return(8); + return(0); } @@ -131,16 +144,18 @@ struct isa_device *isdp; unit = isdp->id_unit; if (unit == comconsole) - DELAY(100000); + DELAY(1000); com_addr[unit] = port; com_active |= 1 << unit; comsoftCAR |= 1 << unit; /* XXX */ /* look for a NS 16550AF UART with FIFOs */ - outb(port+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14); + outb(port+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4); DELAY(100); - if ((inb(port+com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK) + if ((inb(port+com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK) { com_hasfifo |= 1 << unit; + printf("com%d: fifo\n", isdp->id_unit); + } outb(port+com_ier, 0); outb(port+com_mcr, 0 | MCR_IENABLE); @@ -174,14 +189,7 @@ struct isa_device *isdp; } /* ARGSUSED */ -#ifdef __STDC__ comopen(dev_t dev, int flag, int mode, struct proc *p) -#else -comopen(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -#endif { register struct tty *tp; register int unit; @@ -215,7 +223,7 @@ comopen(dev, flag, mode, p) while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && (tp->t_state & TS_CARR_ON) == 0) { tp->t_state |= TS_WOPEN; - if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, + if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH, ttopen, 0)) break; } @@ -286,6 +294,7 @@ comintr(unit) register u_char code; register struct tty *tp; + unit; com = com_addr[unit]; while (1) { code = inb(com+com_iir); @@ -370,8 +379,10 @@ comeint(unit, stat, com) c |= TTY_FE; else if (stat & LSR_PE) c |= TTY_PE; - else if (stat & LSR_OE) + else if (stat & LSR_OE) { /* 30 Aug 92*/ + c |= TTY_PE; /* Ought to have it's own define... */ log(LOG_WARNING, "com%d: silo overflow\n", unit); + } (*linesw[tp->t_line].l_rint)(c, tp); } @@ -505,7 +516,7 @@ comparam(tp, t) outb(com+com_cfcr, cfcr); if (com_hasfifo & (1 << unit)) - outb(com+com_fifo, FIFO_ENABLE | FIFO_TRIGGER_14); + outb(com+com_fifo, FIFO_ENABLE | FIFO_TRIGGER_4); return(0); } @@ -521,10 +532,10 @@ comstart(tp) s = spltty(); if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) goto out; - if (tp->t_outq.c_cc <= tp->t_lowat) { + if (RB_LEN(&tp->t_out) <= tp->t_lowat) { if (tp->t_state&TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t)&tp->t_outq); + wakeup((caddr_t)&tp->t_out); } if (tp->t_wsel) { selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); @@ -532,15 +543,15 @@ comstart(tp) tp->t_state &= ~TS_WCOLL; } } - if (tp->t_outq.c_cc == 0) + if (RB_LEN(&tp->t_out) == 0) goto out; if (inb(com+com_lsr) & LSR_TXRDY) { - c = getc(&tp->t_outq); + c = getc(&tp->t_out); 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)); + for (c = 1; c < 16 && RB_LEN(&tp->t_out); ++c) + outb(com+com_data, getc(&tp->t_out)); } out: splx(s); @@ -655,7 +666,7 @@ cominit(unit, rate) 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); + outb(com+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4); stat = inb(com+com_iir); splx(s); } @@ -713,4 +724,45 @@ comcnputc(dev, c) stat = inb(com+com_iir); splx(s); } + +int +comselect(dev, rw, p) + dev_t dev; + int rw; + struct proc *p; +{ + register struct tty *tp = &com_tty[UNIT(dev)]; + int nread; + int s = spltty(); + struct proc *selp; + + switch (rw) { + + case FREAD: + nread = ttnread(tp); + if (nread > 0 || + ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0)) + goto win; + if (tp->t_rsel && (selp = pfind(tp->t_rsel)) && selp->p_wchan == (caddr_t)&selwait) + tp->t_state |= TS_RCOLL; + else + tp->t_rsel = p->p_pid; + break; + + case FWRITE: + if (RB_LEN(&tp->t_out) <= tp->t_lowat) + goto win; + if (tp->t_wsel && (selp = pfind(tp->t_wsel)) && selp->p_wchan == (caddr_t)&selwait) + tp->t_state |= TS_WCOLL; + else + tp->t_wsel = p->p_pid; + break; + } + splx(s); + return (0); + win: + splx(s); + return (1); +} + #endif