Ttys structures are now allocated dynamically via ttymalloc/ttyfree.
[unix-history] / sys / i386 / isa / com.c
index 3b85442..2771f91 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * 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
+ *     from: @(#)com.c 7.5 (Berkeley) 5/16/91
+ *     $Id: com.c,v 1.7 1993/12/19 00:50:32 wollman Exp $
  */
  */
-static char rcsid[] = "$Header: /home/cvs/386BSD/src/sys.386bsd/i386/isa/com.c,v 1.1.1.1 1993/06/12 14:58:02 rgrimes Exp $";
 
 #include "com.h"
 #if NCOM > 0
 
 #include "com.h"
 #if NCOM > 0
@@ -62,12 +52,22 @@ static char rcsid[] = "$Header: /home/cvs/386BSD/src/sys.386bsd/i386/isa/com.c,v
 #include "kernel.h"
 #include "syslog.h"
 
 #include "kernel.h"
 #include "syslog.h"
 
+#include "i386/isa/isa.h"
 #include "i386/isa/isa_device.h"
 #include "i386/isa/comreg.h"
 #include "i386/isa/ic/ns16550.h"
 #define cominor(d)
 
 #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();
+static int commctl(int /*dev_t*/, int, int);
+static int comprobe();
+static int comattach();
+void comintr(int);
+static void comstart(struct tty *);
+static int comparam(struct tty *, struct termios *);
+
+static void comeint(int, int, int);
+static void commint(int, int);
+static void cominit(int, int);
 
 struct isa_driver comdriver = {
        comprobe, comattach, "com"
 
 struct isa_driver comdriver = {
        comprobe, comattach, "com"
@@ -86,7 +86,7 @@ int   comconsinit;
 int    comdefaultrate = TTYDEF_SPEED;
 int    commajor;
 short com_addr[NCOM];
 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,
 
 struct speedtab comspeedtab[] = {
        0,      0,
@@ -120,6 +120,7 @@ extern int kgdb_debug_init;
 
 #define        UNIT(x)         (minor(x))
 
 
 #define        UNIT(x)         (minor(x))
 
+int
 comprobe(dev)
 struct isa_device *dev;
 {
 comprobe(dev)
 struct isa_device *dev;
 {
@@ -128,7 +129,7 @@ struct isa_device *dev;
        outb(dev->id_iobase+com_iir, 0);
        DELAY(100);
        if ((inb(dev->id_iobase+com_iir) & 0x38) == 0)
        outb(dev->id_iobase+com_iir, 0);
        DELAY(100);
        if ((inb(dev->id_iobase+com_iir) & 0x38) == 0)
-               return(1);
+               return(IO_COMSIZE);
        return(0);
 }
 
        return(0);
 }
 
@@ -153,7 +154,7 @@ struct isa_device *isdp;
        DELAY(100);
        if ((inb(port+com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK) {
                com_hasfifo |= 1 << unit;
        DELAY(100);
        if ((inb(port+com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK) {
                com_hasfifo |= 1 << unit;
-               printf(" fifo");
+               printf("com%d: fifo\n", unit);
        }
 
        outb(port+com_ier, 0);
        }
 
        outb(port+com_ier, 0);
@@ -188,7 +189,8 @@ struct isa_device *isdp;
 }
 
 /* ARGSUSED */
 }
 
 /* ARGSUSED */
-comopen(dev_t dev, int flag, int mode, struct proc *p)
+int
+comopen(int /*dev_t*/ dev, int flag, int mode, struct proc *p)
 {
        register struct tty *tp;
        register int unit;
 {
        register struct tty *tp;
        register int unit;
@@ -197,7 +199,7 @@ comopen(dev_t dev, int flag, int mode, struct proc *p)
        unit = UNIT(dev);
        if (unit >= NCOM || (com_active & (1 << unit)) == 0)
                return (ENXIO);
        unit = UNIT(dev);
        if (unit >= NCOM || (com_active & (1 << unit)) == 0)
                return (ENXIO);
-       tp = &com_tty[unit];
+       tp = com_tty[unit] = ttymalloc(com_tty[unit]);
        tp->t_oproc = comstart;
        tp->t_param = comparam;
        tp->t_dev = dev;
        tp->t_oproc = comstart;
        tp->t_param = comparam;
        tp->t_dev = dev;
@@ -222,17 +224,18 @@ comopen(dev_t dev, int flag, int mode, struct proc *p)
        while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
               (tp->t_state & TS_CARR_ON) == 0) {
                tp->t_state |= TS_WOPEN;
        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_raw, TTIPRI | PCATCH,
+               if (error = ttysleep(tp, (caddr_t)tp->t_raw, TTIPRI | PCATCH,
                    ttopen, 0))
                        break;
        }
        (void) spl0();
        if (error == 0)
                    ttopen, 0))
                        break;
        }
        (void) spl0();
        if (error == 0)
-               error = (*linesw[tp->t_line].l_open)(dev, tp);
+               error = (*linesw[tp->t_line].l_open)(dev, tp, 0);
        return (error);
 }
  
 /*ARGSUSED*/
        return (error);
 }
  
 /*ARGSUSED*/
+int
 comclose(dev, flag, mode, p)
        dev_t dev;
        int flag, mode;
 comclose(dev, flag, mode, p)
        dev_t dev;
        int flag, mode;
@@ -244,7 +247,7 @@ comclose(dev, flag, mode, p)
  
        unit = UNIT(dev);
        com = com_addr[unit];
  
        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
        (*linesw[tp->t_line].l_close)(tp, flag);
        outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK);
 #ifdef KGDB
@@ -256,24 +259,35 @@ comclose(dev, flag, mode, p)
            (tp->t_state&TS_ISOPEN) == 0)
                (void) commctl(dev, 0, DMSET);
        ttyclose(tp);
            (tp->t_state&TS_ISOPEN) == 0)
                (void) commctl(dev, 0, DMSET);
        ttyclose(tp);
+       ttyfree(tp);
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+       com_tty[unit] = (struct tty *)NULL;
+#endif
+       return (0);
+
+
        return(0);
 }
  
        return(0);
 }
  
+int
 comread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 comread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
+       int flag;
 {
 {
-       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));
 }
  
  
        return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
 }
  
+int
 comwrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 comwrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
+       int flag;
 {
        int unit = UNIT(dev);
 {
        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
  
        /*
         * (XXX) We disallow virtual consoles if the physical console is
@@ -286,6 +300,7 @@ comwrite(dev, uio, flag)
        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 }
  
        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 }
  
+void
 comintr(unit)
        register int unit;
 {
 comintr(unit)
        register int unit;
 {
@@ -293,16 +308,15 @@ comintr(unit)
        register u_char code;
        register struct tty *tp;
 
        register u_char code;
        register struct tty *tp;
 
-       unit;
        com = com_addr[unit];
        while (1) {
                code = inb(com+com_iir);
                switch (code & IIR_IMASK) {
                case IIR_NOPEND:
        com = com_addr[unit];
        while (1) {
                code = inb(com+com_iir);
                switch (code & IIR_IMASK) {
                case IIR_NOPEND:
-                       return (1);
+                       return;
                case IIR_RXTOUT:
                case IIR_RXRDY:
                case IIR_RXTOUT:
                case IIR_RXRDY:
-                       tp = &com_tty[unit];
+                       tp = com_tty[unit];
 /*
  * Process received bytes.  Inline for speed...
  */
 /*
  * Process received bytes.  Inline for speed...
  */
@@ -333,7 +347,7 @@ comintr(unit)
                                }
                        break;
                case IIR_TXRDY:
                                }
                        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);
                        tp->t_state &=~ (TS_BUSY|TS_FLUSH);
                        if (tp->t_line)
                                (*linesw[tp->t_line].l_start)(tp);
@@ -345,7 +359,7 @@ comintr(unit)
                        break;
                default:
                        if (code & IIR_NOPEND)
                        break;
                default:
                        if (code & IIR_NOPEND)
-                               return (1);
+                               return;
                        log(LOG_WARNING, "com%d: weird interrupt: 0x%x\n",
                            unit, code);
                        /* fall through */
                        log(LOG_WARNING, "com%d: weird interrupt: 0x%x\n",
                            unit, code);
                        /* fall through */
@@ -356,14 +370,15 @@ comintr(unit)
        }
 }
 
        }
 }
 
+static void
 comeint(unit, stat, com)
        register int unit, stat;
 comeint(unit, stat, com)
        register int unit, stat;
-       register com;
+       register int com;
 {
        register struct tty *tp;
        register int c;
 
 {
        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
        c = inb(com+com_data);
        if ((tp->t_state & TS_ISOPEN) == 0) {
 #ifdef KGDB
@@ -385,14 +400,15 @@ comeint(unit, stat, com)
        (*linesw[tp->t_line].l_rint)(c, tp);
 }
 
        (*linesw[tp->t_line].l_rint)(c, tp);
 }
 
+static void
 commint(unit, com)
        register int unit;
 commint(unit, com)
        register int unit;
-       register com;
+       register int com;
 {
        register struct tty *tp;
        register int stat;
 
 {
        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)
        stat = inb(com+com_msr);
        if ((stat & MSR_DDCD) && (comsoftCAR & (1 << unit)) == 0) {
                if (stat & MSR_DCD)
@@ -411,16 +427,19 @@ commint(unit, com)
        }
 }
 
        }
 }
 
+int
 comioctl(dev, cmd, data, flag)
        dev_t dev;
 comioctl(dev, cmd, data, flag)
        dev_t dev;
+       int cmd;
        caddr_t data;
        caddr_t data;
+       int flag;
 {
        register struct tty *tp;
        register int unit = UNIT(dev);
        register com;
        register int error;
  
 {
        register struct tty *tp;
        register int unit = UNIT(dev);
        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);
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
        if (error >= 0)
                return (error);
@@ -469,12 +488,13 @@ comioctl(dev, cmd, data, flag)
        return (0);
 }
 
        return (0);
 }
 
+static int
 comparam(tp, t)
        register struct tty *tp;
        register struct termios *t;
 {
 comparam(tp, t)
        register struct tty *tp;
        register struct termios *t;
 {
-       register com;
-       register int cfcr, cflag = t->c_cflag;
+       register int com;
+       register int cfcr = 0, cflag = t->c_cflag;
        int unit = UNIT(tp->t_dev);
        int ospeed = ttspeedtab(t->c_ospeed, comspeedtab);
  
        int unit = UNIT(tp->t_dev);
        int ospeed = ttspeedtab(t->c_ospeed, comspeedtab);
  
@@ -520,6 +540,7 @@ comparam(tp, t)
        return(0);
 }
  
        return(0);
 }
  
+void
 comstart(tp)
        register struct tty *tp;
 {
 comstart(tp)
        register struct tty *tp;
 {
@@ -531,10 +552,10 @@ comstart(tp)
        s = spltty();
        if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
                goto out;
        s = spltty();
        if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
                goto out;
-       if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
+       if (RB_LEN(tp->t_out) <= tp->t_lowat) {
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
-                       wakeup((caddr_t)&tp->t_out);
+                       wakeup((caddr_t)tp->t_out);
                }
                if (tp->t_wsel) {
                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
                }
                if (tp->t_wsel) {
                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
@@ -542,15 +563,15 @@ comstart(tp)
                        tp->t_state &= ~TS_WCOLL;
                }
        }
                        tp->t_state &= ~TS_WCOLL;
                }
        }
-       if (RB_LEN(&tp->t_out) == 0)
+       if (RB_LEN(tp->t_out) == 0)
                goto out;
        if (inb(com+com_lsr) & LSR_TXRDY) {
                goto out;
        if (inb(com+com_lsr) & LSR_TXRDY) {
-               c = getc(&tp->t_out);
+               c = getc(tp->t_out);
                tp->t_state |= TS_BUSY;
                outb(com+com_data, c);
                if (com_hasfifo & (1 << unit))
                tp->t_state |= TS_BUSY;
                outb(com+com_data, c);
                if (com_hasfifo & (1 << unit))
-                       for (c = 1; c < 16 && RB_LEN(&tp->t_out); ++c)
-                               outb(com+com_data, getc(&tp->t_out));
+                       for (c = 1; c < 16 && RB_LEN(tp->t_out); ++c)
+                               outb(com+com_data, getc(tp->t_out));
        }
 out:
        splx(s);
        }
 out:
        splx(s);
@@ -560,8 +581,10 @@ out:
  * Stop output on a line.
  */
 /*ARGSUSED*/
  * Stop output on a line.
  */
 /*ARGSUSED*/
+void
 comstop(tp, flag)
        register struct tty *tp;
 comstop(tp, flag)
        register struct tty *tp;
+       int flag;
 {
        register int s;
 
 {
        register int s;
 
@@ -573,6 +596,7 @@ comstop(tp, flag)
        splx(s);
 }
  
        splx(s);
 }
  
+static int
 commctl(dev, bits, how)
        dev_t dev;
        int bits, how;
 commctl(dev, bits, how)
        dev_t dev;
        int bits, how;
@@ -611,6 +635,7 @@ commctl(dev, bits, how)
  */
 #include "i386/i386/cons.h"
 
  */
 #include "i386/i386/cons.h"
 
+void
 comcnprobe(cp)
        struct consdev *cp;
 {
 comcnprobe(cp)
        struct consdev *cp;
 {
@@ -629,7 +654,7 @@ comcnprobe(cp)
 
        /* initialize required fields */
        cp->cn_dev = makedev(commajor, unit);
 
        /* initialize required fields */
        cp->cn_dev = makedev(commajor, unit);
-       cp->cn_tp = &com_tty[unit];
+       cp->cn_tp = com_tty[unit];
 #ifdef COMCONSOLE
        cp->cn_pri = CN_REMOTE;         /* Force a serial port console */
 #else
 #ifdef COMCONSOLE
        cp->cn_pri = CN_REMOTE;         /* Force a serial port console */
 #else
@@ -637,6 +662,7 @@ comcnprobe(cp)
 #endif
 }
 
 #endif
 }
 
+void
 comcninit(cp)
        struct consdev *cp;
 {
 comcninit(cp)
        struct consdev *cp;
 {
@@ -647,6 +673,7 @@ comcninit(cp)
        comconsinit = 1;
 }
 
        comconsinit = 1;
 }
 
+static void
 cominit(unit, rate)
        int unit, rate;
 {
 cominit(unit, rate)
        int unit, rate;
 {
@@ -670,7 +697,9 @@ cominit(unit, rate)
        splx(s);
 }
 
        splx(s);
 }
 
+int
 comcngetc(dev)
 comcngetc(dev)
+       dev_t dev;
 {
        register com = com_addr[UNIT(dev)];
        short stat;
 {
        register com = com_addr[UNIT(dev)];
        short stat;
@@ -691,6 +720,7 @@ comcngetc(dev)
 /*
  * Console kernel output character routine.
  */
 /*
  * Console kernel output character routine.
  */
+void
 comcnputc(dev, c)
        dev_t dev;
        register int c;
 comcnputc(dev, c)
        dev_t dev;
        register int c;
@@ -731,7 +761,7 @@ comselect(dev, rw, p)
        int rw;
        struct proc *p;
 {
        int rw;
        struct proc *p;
 {
-       register struct tty *tp = &com_tty[UNIT(dev)];
+       register struct tty *tp = com_tty[UNIT(dev)];
        int nread;
        int s = spltty();
         struct proc *selp;
        int nread;
        int s = spltty();
         struct proc *selp;
@@ -750,7 +780,7 @@ comselect(dev, rw, p)
                break;
 
        case FWRITE:
                break;
 
        case FWRITE:
-               if (RB_LEN(&tp->t_out) <= tp->t_lowat)
+               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;
                        goto win;
                if (tp->t_wsel && (selp = pfind(tp->t_wsel)) && selp->p_wchan == (caddr_t)&selwait)
                        tp->t_state |= TS_WCOLL;