--- Net2/arch/i386/isa/com.c 2018/04/24 18:04:01 1.1 +++ Net2/arch/i386/isa/com.c 2018/04/24 18:20:08 1.1.1.5 @@ -30,7 +30,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)com.c 7.5 (Berkeley) 5/16/91 + * from: @(#)com.c 7.5 (Berkeley) 5/16/91 + * com.c,v 1.11 1993/07/12 11:37:16 mycroft Exp */ #include "com.h" @@ -42,6 +43,7 @@ #include "param.h" #include "systm.h" #include "ioctl.h" +#include "select.h" #include "tty.h" #include "proc.h" #include "user.h" @@ -50,10 +52,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(); @@ -74,7 +78,7 @@ int comconsinit; int comdefaultrate = TTYDEF_SPEED; int commajor; short com_addr[NCOM]; -struct tty com_tty[NCOM]; +struct tty *com_tty[NCOM]; struct speedtab comspeedtab[] = { 0, 0, @@ -106,7 +110,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 +118,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 +135,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 +180,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; @@ -190,7 +189,10 @@ comopen(dev, flag, mode, p) unit = UNIT(dev); if (unit >= NCOM || (com_active & (1 << unit)) == 0) return (ENXIO); - tp = &com_tty[unit]; + if(!com_tty[unit]) { + tp = com_tty[unit] = ttymalloc(); + } else + tp = com_tty[unit]; tp->t_oproc = comstart; tp->t_param = comparam; tp->t_dev = dev; @@ -237,7 +239,7 @@ comclose(dev, flag, mode, p) unit = UNIT(dev); com = com_addr[unit]; - tp = &com_tty[unit]; + tp = com_tty[unit]; (*linesw[tp->t_line].l_close)(tp, flag); outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK); #ifdef KGDB @@ -249,6 +251,8 @@ comclose(dev, flag, mode, p) (tp->t_state&TS_ISOPEN) == 0) (void) commctl(dev, 0, DMSET); ttyclose(tp); + ttyfree(tp); + com_tty[unit] = (struct tty *)NULL; return(0); } @@ -256,7 +260,7 @@ comread(dev, uio, flag) dev_t dev; struct uio *uio; { - register struct tty *tp = &com_tty[UNIT(dev)]; + register struct tty *tp = com_tty[UNIT(dev)]; return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); } @@ -266,7 +270,7 @@ comwrite(dev, uio, flag) struct uio *uio; { int unit = UNIT(dev); - register struct tty *tp = &com_tty[unit]; + register struct tty *tp = com_tty[unit]; /* * (XXX) We disallow virtual consoles if the physical console is @@ -286,6 +290,7 @@ comintr(unit) register u_char code; register struct tty *tp; + unit; com = com_addr[unit]; while (1) { code = inb(com+com_iir); @@ -294,7 +299,7 @@ comintr(unit) return (1); case IIR_RXTOUT: case IIR_RXRDY: - tp = &com_tty[unit]; + tp = com_tty[unit]; /* * Process received bytes. Inline for speed... */ @@ -325,7 +330,7 @@ comintr(unit) } break; case IIR_TXRDY: - tp = &com_tty[unit]; + tp = com_tty[unit]; tp->t_state &=~ (TS_BUSY|TS_FLUSH); if (tp->t_line) (*linesw[tp->t_line].l_start)(tp); @@ -355,7 +360,7 @@ comeint(unit, stat, com) register struct tty *tp; register int c; - tp = &com_tty[unit]; + tp = com_tty[unit]; c = inb(com+com_data); if ((tp->t_state & TS_ISOPEN) == 0) { #ifdef KGDB @@ -370,8 +375,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); } @@ -382,7 +389,7 @@ commint(unit, com) register struct tty *tp; register int stat; - tp = &com_tty[unit]; + tp = com_tty[unit]; stat = inb(com+com_msr); if ((stat & MSR_DDCD) && (comsoftCAR & (1 << unit)) == 0) { if (stat & MSR_DCD) @@ -410,7 +417,7 @@ comioctl(dev, cmd, data, flag) register com; register int error; - tp = &com_tty[unit]; + tp = com_tty[unit]; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); if (error >= 0) return (error); @@ -505,7 +512,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); } @@ -526,11 +533,7 @@ comstart(tp) tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } - if (tp->t_wsel) { - selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); - tp->t_wsel = 0; - tp->t_state &= ~TS_WCOLL; - } + selwakeup(&tp->t_wsel); } if (tp->t_outq.c_cc == 0) goto out; @@ -619,7 +622,6 @@ comcnprobe(cp) /* 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 @@ -655,7 +657,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 +715,39 @@ 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; + selrecord(p, &tp->t_rsel); + break; + + case FWRITE: + if (tp->t_outq.c_cc <= tp->t_lowat) + goto win; + selrecord(p, &tp->t_wsel); + break; + } + splx(s); + return (0); + win: + splx(s); + return (1); +} + #endif