fix to use only one soft intr for net thereby fixing bug in raw sockets
[unix-history] / usr / src / sys / vax / if / if_dmc.c
index d365575..4d00005 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_dmc.c        4.1     82/02/08        */
+/*     if_dmc.c        4.6     82/03/19        */
 
 #include "dmc.h"
 #if NDMC > 0
 
 #include "dmc.h"
 #if NDMC > 0
@@ -28,6 +28,7 @@ int dmcdebug = 1;
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/if_uba.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/if_uba.h"
+#include "../net/if_dmc.h"
 #include "../net/ip.h"
 #include "../net/ip_var.h"
 
 #include "../net/ip.h"
 #include "../net/ip_var.h"
 
@@ -40,67 +41,6 @@ u_short      dmcstd[] = { 0 };
 struct uba_driver dmcdriver =
        { dmcprobe, 0, dmcattach, 0, dmcstd, "dmc", dmcinfo };
 
 struct uba_driver dmcdriver =
        { dmcprobe, 0, dmcattach, 0, dmcstd, "dmc", dmcinfo };
 
-struct dmcdevice {
-       union {
-               char    b[8];
-               short   w[4];
-       } un;
-};
-
-#define        bsel0   un.b[0]
-#define        bsel1   un.b[1]
-#define        bsel2   un.b[2]
-#define        bsel3   un.b[3]
-#define        bsel4   un.b[4]
-#define        bsel5   un.b[5]
-#define        bsel6   un.b[6]
-#define        bsel7   un.b[7]
-#define        sel0    un.w[0]
-#define        sel2    un.w[1]
-#define        sel4    un.w[2]
-#define        sel6    un.w[3]
-
-#define        DMCMTU  (2048)
-
-#define RDYSCAN        16      /* loop delay for RDYI after RQI */
-
-/* defines for bsel0 */
-#define        DMC_BACCI       0
-#define        DMC_CNTLI       1
-#define        DMC_PERR        2
-#define        DMC_BASEI       3
-#define        DMC_WRITE       0               /* transmit block */
-#define        DMC_READ        4               /* read block */
-#define        DMC_RQI         0040            /* port request bit */
-#define        DMC_IEI         0100            /* enable input interrupts */
-#define        DMC_RDYI        0200            /* port ready */
-
-/* defines for bsel1 */
-#define        DMC_MCLR        0100            /* DMC11 Master Clear */
-#define        DMC_RUN         0200            /* clock running */
-
-/* defines for bsel2 */
-#define        DMC_BACCO       0
-#define        DMC_CNTLO       1
-#define        DMC_OUX         0               /* transmit block */
-#define        DMC_OUR         4               /* read block */
-#define        DMC_IEO         0100            /* enable output interrupts */
-#define        DMC_RDYO        0200            /* port available */
-
-/* defines for CNTLI mode */
-#define        DMC_HDPLX       02000           /* half duplex DDCMP operation */
-#define        DMC_SEC         04000           /* half duplex secondary station */
-#define        DMC_MAINT       00400           /* enter maintenance mode */
-
-/* defines for BACCI/O and BASEI mode */
-#define        DMC_XMEM        0140000         /* xmem bit position */
-#define        DMC_CCOUNT      0037777         /* character count mask */
-#define        DMC_RESUME      0002000         /* resume (BASEI only) */
-
-/* defines for CNTLO */
-#define        DMC_CNTMASK     01777
-#define DMC_FATAL      01620
-
 #define        DMC_PF  0xff            /* 8 bits of protocol type in ui_flags */
 #define        DMC_NET 0xff00          /* 8 bits of net number in ui_flags */
 
 #define        DMC_PF  0xff            /* 8 bits of protocol type in ui_flags */
 #define        DMC_NET 0xff00          /* 8 bits of net number in ui_flags */
 
@@ -181,6 +121,7 @@ dmcattach(ui)
        sc->sc_if.if_init = dmcinit;
        sc->sc_if.if_output = dmcoutput;
        sc->sc_if.if_ubareset = dmcreset;
        sc->sc_if.if_init = dmcinit;
        sc->sc_if.if_output = dmcoutput;
        sc->sc_if.if_ubareset = dmcreset;
+       sc->sc_ifuba.ifuba_flags = UBA_NEEDBDP;
        if_attach(&sc->sc_if);
 }
 
        if_attach(&sc->sc_if);
 }
 
@@ -218,7 +159,7 @@ dmcinit(unit)
                sc->sc_flag |= DMCBMAPPED;
        }
        if (if_ubainit(&sc->sc_ifuba, ui->ui_ubanum, 0,
                sc->sc_flag |= DMCBMAPPED;
        }
        if (if_ubainit(&sc->sc_ifuba, ui->ui_ubanum, 0,
-           (int)btop(DMCMTU)) == 0) {
+           (int)btoc(DMCMTU)) == 0) {
                printf("dmc%d: can't initialize\n", unit);
                return;
        }
                printf("dmc%d: can't initialize\n", unit);
                return;
        }
@@ -261,7 +202,8 @@ dmcstart(dev)
         * Have request mapped to UNIBUS for transmission.
         * Purge any stale data from this BDP and start the output.
         */
         * Have request mapped to UNIBUS for transmission.
         * Purge any stale data from this BDP and start the output.
         */
-       UBAPURGE(sc->sc_ifuba.ifu_uba, sc->sc_ifuba.ifu_w.ifrw_bdp);
+       if (sc->sc_ifuba.ifuba_flags & UBA_NEEDBDP)
+               UBAPURGE(sc->sc_ifuba.ifu_uba, sc->sc_ifuba.ifu_w.ifrw_bdp);
        addr = sc->sc_ifuba.ifu_w.ifrw_info & 0x3ffff;
        printd("  len %d, addr 0x%x, ", len, addr);
        printd("mr 0x%x\n", sc->sc_ifuba.ifu_w.ifrw_mr[0]);
        addr = sc->sc_ifuba.ifu_w.ifrw_info & 0x3ffff;
        printd("  len %d, addr 0x%x, ", len, addr);
        printd("mr 0x%x\n", sc->sc_ifuba.ifu_w.ifrw_mr[0]);
@@ -286,9 +228,9 @@ dmcload(sc, type, w0, w1)
        if ((n = sc->sc_que.c_cc) == 0)
                addr->bsel0 = type | DMC_RQI;
        else
        if ((n = sc->sc_que.c_cc) == 0)
                addr->bsel0 = type | DMC_RQI;
        else
-               putc(type | DMC_RQI, &sc->sc_que);
-       putw(w0, &sc->sc_que);
-       putw(w1, &sc->sc_que);
+               (void) putc(type | DMC_RQI, &sc->sc_que);
+       (void) putw(w0, &sc->sc_que);
+       (void) putw(w1, &sc->sc_que);
        if (n == 0)
                dmcrint(unit);
        splx(sps);
        if (n == 0)
                dmcrint(unit);
        splx(sps);
@@ -364,13 +306,15 @@ dmcxint(unit)
                 * higher-level input routine.
                 */
                sc->sc_if.if_ipackets++;
                 * higher-level input routine.
                 */
                sc->sc_if.if_ipackets++;
-               UBAPURGE(sc->sc_ifuba.ifu_uba, sc->sc_ifuba.ifu_r.ifrw_bdp);
+               if (sc->sc_ifuba.ifuba_flags & UBA_NEEDBDP)
+                       UBAPURGE(sc->sc_ifuba.ifu_uba,
+                               sc->sc_ifuba.ifu_r.ifrw_bdp);
                len = arg & DMC_CCOUNT;
                printd("  read done, len %d\n", len);
                switch (ui->ui_flags & DMC_PF) {
 #ifdef INET
                case PF_INET:
                len = arg & DMC_CCOUNT;
                printd("  read done, len %d\n", len);
                switch (ui->ui_flags & DMC_PF) {
 #ifdef INET
                case PF_INET:
-                       setipintr();
+                       schednetisr(NETISR_IP);
                        inq = &ipintrq;
                        break;
 #endif
                        inq = &ipintrq;
                        break;
 #endif
@@ -383,7 +327,11 @@ dmcxint(unit)
                m = if_rubaget(&sc->sc_ifuba, len, 0);
                if (m == 0)
                        goto setup;
                m = if_rubaget(&sc->sc_ifuba, len, 0);
                if (m == 0)
                        goto setup;
-               IF_ENQUEUE(inq, m);
+               if (IF_QFULL(inq)) {
+                       IF_DROP(inq);
+                       (void) m_freem(m);
+               } else
+                       IF_ENQUEUE(inq, m);
 
 setup:
                arg = sc->sc_ifuba.ifu_r.ifrw_info & 0x3ffff;
 
 setup:
                arg = sc->sc_ifuba.ifu_r.ifrw_info & 0x3ffff;
@@ -401,7 +349,7 @@ setup:
                sc->sc_if.if_opackets++;
                sc->sc_oactive = 0;
                if (sc->sc_ifuba.ifu_xtofree) {
                sc->sc_if.if_opackets++;
                sc->sc_oactive = 0;
                if (sc->sc_ifuba.ifu_xtofree) {
-                       m_freem(sc->sc_ifuba.ifu_xtofree);
+                       (void) m_freem(sc->sc_ifuba.ifu_xtofree);
                        sc->sc_ifuba.ifu_xtofree = 0;
                }
                if (sc->sc_if.if_snd.ifq_head == 0)
                        sc->sc_ifuba.ifu_xtofree = 0;
                }
                if (sc->sc_if.if_snd.ifq_head == 0)
@@ -443,10 +391,16 @@ dmcoutput(ifp, m, pf)
        printd("dmcoutput\n");
        if (pf != (ui->ui_flags & DMC_PF)) {
                printf("dmc%d: protocol %d not supported\n", ifp->if_unit, pf);
        printd("dmcoutput\n");
        if (pf != (ui->ui_flags & DMC_PF)) {
                printf("dmc%d: protocol %d not supported\n", ifp->if_unit, pf);
-               m_freem(m);
+               (void) m_freem(m);
                return (0);
        }
        s = splimp();
                return (0);
        }
        s = splimp();
+       if (IF_QFULL(&ifp->if_snd)) {
+               IF_DROP(&ifp->if_snd);
+               (void) m_freem(m);
+               splx(s);
+               return (0);
+       }
        IF_ENQUEUE(&ifp->if_snd, m);
        if (dmc_softc[ifp->if_unit].sc_oactive == 0)
                dmcstart(ifp->if_unit);
        IF_ENQUEUE(&ifp->if_snd, m);
        if (dmc_softc[ifp->if_unit].sc_oactive == 0)
                dmcstart(ifp->if_unit);