strategy returns void, ioctl cmd is u_long
[unix-history] / usr / src / sys / hp / dev / dca.c
index e7b6227..1ee342c 100644 (file)
@@ -1,10 +1,10 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)dca.c       7.16 (Berkeley) %G%
+ *     @(#)dca.c       8.3 (Berkeley) %G%
  */
 
 #include "dca.h"
  */
 
 #include "dca.h"
  *  The third bit of the Modem Control Register (MCR_IEN == 0x08) must be
  *  set to enable interrupts.
  */
  *  The third bit of the Modem Control Register (MCR_IEN == 0x08) must be
  *  set to enable interrupts.
  */
-#include "sys/param.h"
-#include "sys/systm.h"
-#include "sys/ioctl.h"
-#include "sys/proc.h"
-#include "sys/tty.h"
-#include "sys/conf.h"
-#include "sys/file.h"
-#include "sys/uio.h"
-#include "sys/kernel.h"
-#include "sys/syslog.h"
-
-#include "hp/dev/device.h"
-#include "dcareg.h"
-
-#include "machine/cpu.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+
+#include <hp/dev/device.h>
+#include <hp/dev/dcareg.h>
+
+#include <machine/cpu.h>
 #ifdef hp300
 #ifdef hp300
-#include "../../hp300/hp300/isr.h"
+#include <hp300/hp300/isr.h>
 #endif
 #ifdef hp700
 #endif
 #ifdef hp700
-#include "machine/asp.h"
+#include <machine/asp.h>
 #endif
 
 int    dcaprobe();
 #endif
 
 int    dcaprobe();
@@ -64,7 +64,9 @@ struct        dcadevice *dca_addr[NDCA];
 struct tty dca_tty[NDCA];
 #ifdef hp300
 struct isr dcaisr[NDCA];
 struct tty dca_tty[NDCA];
 #ifdef hp300
 struct isr dcaisr[NDCA];
+int    dcafastservice;
 #endif
 #endif
+int    dcaoflows[NDCA];
 
 struct speedtab dcaspeedtab[] = {
        0,      0,
 
 struct speedtab dcaspeedtab[] = {
        0,      0,
@@ -87,7 +89,7 @@ struct speedtab dcaspeedtab[] = {
 };
 
 #ifdef KGDB
 };
 
 #ifdef KGDB
-#include "machine/remote-sl.h"
+#include <machine/remote-sl.h>
 
 extern dev_t kgdb_dev;
 extern int kgdb_rate;
 
 extern dev_t kgdb_dev;
 extern int kgdb_rate;
@@ -224,6 +226,15 @@ dcaopen(dev, flag, mode, p)
        (void) spl0();
        if (error == 0)
                error = (*linesw[tp->t_line].l_open)(dev, tp);
        (void) spl0();
        if (error == 0)
                error = (*linesw[tp->t_line].l_open)(dev, tp);
+#ifdef hp300
+       /*
+        * XXX hack to speed up unbuffered builtin port.
+        * If dca_fastservice is set, a level 5 interrupt
+        * will be directed to dcaintr first.
+        */
+       if (error == 0 && unit == 0 && (dca_hasfifo & 1) == 0)
+               dcafastservice = 1;
+#endif
        return (error);
 }
  
        return (error);
 }
  
@@ -238,6 +249,10 @@ dcaclose(dev, flag, mode, p)
        register int unit;
  
        unit = UNIT(dev);
        register int unit;
  
        unit = UNIT(dev);
+#ifdef hp300
+       if (unit == 0)
+               dcafastservice = 0;
+#endif
        dca = dca_addr[unit];
        tp = &dca_tty[unit];
        (*linesw[tp->t_line].l_close)(tp, flag);
        dca = dca_addr[unit];
        tp = &dca_tty[unit];
        (*linesw[tp->t_line].l_close)(tp, flag);
@@ -257,15 +272,27 @@ dcaclose(dev, flag, mode, p)
 dcaread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 dcaread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
+       int flag;
 {
 {
-       register struct tty *tp = &dca_tty[UNIT(dev)];
+       int unit = UNIT(dev);
+       register struct tty *tp = &dca_tty[unit];
+       int error, of;
  
  
-       return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+       of = dcaoflows[unit];
+       error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
+       /*
+        * XXX hardly a reasonable thing to do, but reporting overflows
+        * at interrupt time just exacerbates the problem.
+        */
+       if (dcaoflows[unit] != of)
+               log(LOG_WARNING, "dca%d: silo overflow\n", unit);
+       return (error);
 }
  
 dcawrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 }
  
 dcawrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
+       int flag;
 {
        int unit = UNIT(dev);
        register struct tty *tp = &dca_tty[unit];
 {
        int unit = UNIT(dev);
        register struct tty *tp = &dca_tty[unit];
@@ -288,12 +315,14 @@ dcaintr(unit)
        register struct dcadevice *dca;
        register u_char code;
        register struct tty *tp;
        register struct dcadevice *dca;
        register u_char code;
        register struct tty *tp;
+       int iflowdone = 0;
 
        dca = dca_addr[unit];
 #ifdef hp300
        if ((dca->dca_ic & (IC_IR|IC_IE)) != (IC_IR|IC_IE))
                return (0);
 #endif
 
        dca = dca_addr[unit];
 #ifdef hp300
        if ((dca->dca_ic & (IC_IR|IC_IE)) != (IC_IR|IC_IE))
                return (0);
 #endif
+       tp = &dca_tty[unit];
        while (1) {
                code = dca->dca_iir;
 #ifdef DEBUG
        while (1) {
                code = dca->dca_iir;
 #ifdef DEBUG
@@ -305,7 +334,6 @@ dcaintr(unit)
                case IIR_RXTOUT:
                case IIR_RXRDY:
                        /* do time-critical read in-line */
                case IIR_RXTOUT:
                case IIR_RXRDY:
                        /* do time-critical read in-line */
-                       tp = &dca_tty[unit];
 /*
  * Process a received byte.  Inline for speed...
  */
 /*
  * Process a received byte.  Inline for speed...
  */
@@ -345,9 +373,13 @@ dcaintr(unit)
                                        fifoin[fifocnt]++;
 #endif
                        }
                                        fifoin[fifocnt]++;
 #endif
                        }
+                       if (!iflowdone && (tp->t_cflag&CRTS_IFLOW) &&
+                           tp->t_rawq.c_cc > TTYHOG/2) {
+                               dca->dca_mcr &= ~MCR_RTS;
+                               iflowdone = 1;
+                       }
                        break;
                case IIR_TXRDY:
                        break;
                case IIR_TXRDY:
-                       tp = &dca_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);
@@ -393,7 +425,7 @@ dcaeint(unit, stat, dca)
        else if (stat & LSR_PE)
                c |= TTY_PE;
        else if (stat & LSR_OE)
        else if (stat & LSR_PE)
                c |= TTY_PE;
        else if (stat & LSR_OE)
-               log(LOG_WARNING, "dca%d: silo overflow\n", unit);
+               dcaoflows[unit]++;
        (*linesw[tp->t_line].l_rint)(c, tp);
 }
 
        (*linesw[tp->t_line].l_rint)(c, tp);
 }
 
@@ -409,25 +441,31 @@ dcamint(unit, dca)
 #ifdef DEBUG
        dcamintcount[stat & 0xf]++;
 #endif
 #ifdef DEBUG
        dcamintcount[stat & 0xf]++;
 #endif
-       if ((stat & MSR_DDCD) && (dcasoftCAR & (1 << unit)) == 0) {
+       if ((stat & MSR_DDCD) &&
+           (dcasoftCAR & (1 << unit)) == 0) {
                if (stat & MSR_DCD)
                        (void)(*linesw[tp->t_line].l_modem)(tp, 1);
                else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)
                        dca->dca_mcr &= ~(MCR_DTR | MCR_RTS);
                if (stat & MSR_DCD)
                        (void)(*linesw[tp->t_line].l_modem)(tp, 1);
                else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)
                        dca->dca_mcr &= ~(MCR_DTR | MCR_RTS);
-       } else if ((stat & MSR_DCTS) && (tp->t_state & TS_ISOPEN) &&
-                  (tp->t_flags & CRTSCTS)) {
-               /* the line is up and we want to do rts/cts flow control */
+       }
+       /*
+        * CTS change.
+        * If doing HW output flow control start/stop output as appropriate.
+        */
+       if ((stat & MSR_DCTS) &&
+           (tp->t_state & TS_ISOPEN) && (tp->t_cflag & CCTS_OFLOW)) {
                if (stat & MSR_CTS) {
                        tp->t_state &=~ TS_TTSTOP;
                if (stat & MSR_CTS) {
                        tp->t_state &=~ TS_TTSTOP;
-                       ttstart(tp);
-               } else
+                       dcastart(tp);
+               } else {
                        tp->t_state |= TS_TTSTOP;
                        tp->t_state |= TS_TTSTOP;
+               }
        }
 }
 
 dcaioctl(dev, cmd, data, flag, p)
        dev_t dev;
        }
 }
 
 dcaioctl(dev, cmd, data, flag, p)
        dev_t dev;
-       int cmd;
+       u_long cmd;
        caddr_t data;
        int flag;
        struct proc *p;
        caddr_t data;
        int flag;
        struct proc *p;
@@ -584,6 +622,7 @@ out:
 /*ARGSUSED*/
 dcastop(tp, flag)
        register struct tty *tp;
 /*ARGSUSED*/
 dcastop(tp, flag)
        register struct tty *tp;
+       int flag;
 {
        register int s;
 
 {
        register int s;
 
@@ -645,7 +684,7 @@ dcamctl(dev, bits, how)
 /*
  * Following are all routines needed for DCA to act as console
  */
 /*
  * Following are all routines needed for DCA to act as console
  */
-#include "hp/dev/cons.h"
+#include <hp/dev/cons.h>
 
 dcacnprobe(cp)
        struct consdev *cp;
 
 dcacnprobe(cp)
        struct consdev *cp;
@@ -747,6 +786,7 @@ dcainit(unit, rate)
 }
 
 dcacngetc(dev)
 }
 
 dcacngetc(dev)
+       dev_t dev;
 {
        register struct dcadevice *dca = dca_addr[UNIT(dev)];
        register u_char stat;
 {
        register struct dcadevice *dca = dca_addr[UNIT(dev)];
        register u_char stat;