BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / vaxif / if_css.c
index 6c0e332..566e35a 100644 (file)
@@ -1,9 +1,20 @@
 /*
 /*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
  *
  *
- *     @(#)if_css.c    7.1 (Berkeley) 6/5/86
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)if_css.c    7.6 (Berkeley) 6/29/88
  */
 
 #include "css.h"
  */
 
 #include "css.h"
@@ -33,8 +44,6 @@
  * If you get it wrong, it will still autoconfig, but will just
  * sit there with RECEIVE IDLE indicated on the front panel.
  */
  * If you get it wrong, it will still autoconfig, but will just
  * sit there with RECEIVE IDLE indicated on the front panel.
  */
-#include "../machine/pte.h"
-
 #include "param.h"
 #include "systm.h"
 #include "mbuf.h"
 #include "param.h"
 #include "systm.h"
 #include "mbuf.h"
@@ -43,6 +52,8 @@
 #include "socket.h"
 #include "vmmac.h"
 
 #include "socket.h"
 #include "vmmac.h"
 
+#include "../machine/pte.h"
+
 #include "../net/if.h"
 #include "../netimp/if_imp.h"
 
 #include "../net/if.h"
 #include "../netimp/if_imp.h"
 
@@ -58,9 +69,8 @@ struct  uba_device *cssinfo[NCSS];
 u_short cssstd[] = { 0 };
 struct  uba_driver cssdriver =
         { cssprobe, 0, cssattach, 0, cssstd, "css", cssinfo };
 u_short cssstd[] = { 0 };
 struct  uba_driver cssdriver =
         { cssprobe, 0, cssattach, 0, cssstd, "css", cssinfo };
-#define CSSUNIT(x)      minor(x)
 
 
-int     cssinit(), cssstart(), cssreset();
+int     cssinit(), cssoutput(), cssdown(), cssreset();
 
 /*
  * "Lower half" of IMP interface driver.
 
 /*
  * "Lower half" of IMP interface driver.
@@ -80,12 +90,11 @@ int     cssinit(), cssstart(), cssreset();
  * e.g. IP, interact with the IMP driver, rather than the CSS.
  */
 struct  css_softc {
  * e.g. IP, interact with the IMP driver, rather than the CSS.
  */
 struct  css_softc {
-        struct  ifnet *css_if;          /* pointer to IMP's ifnet struct */
-        struct  impcb *css_ic;          /* data structure shared with IMP */
-        struct  ifuba css_ifuba;        /* UNIBUS resources */
-        struct  mbuf *css_iq;           /* input reassembly queue */
-        short   css_olen;               /* size of last message sent */
-        char    css_flush;              /* flush remainder of message */
+       struct  imp_softc *css_imp;     /* pointer to IMP's imp_softc struct */
+       struct  ifuba css_ifuba;        /* UNIBUS resources */
+       struct  mbuf *css_iq;           /* input reassembly queue */
+       short   css_olen;               /* size of last message sent */
+       char    css_flush;              /* flush remainder of message */
 } css_softc[NCSS];
 
 /*
 } css_softc[NCSS];
 
 /*
@@ -103,7 +112,6 @@ cssprobe(reg)
         cssrint(0); cssxint(0);
 #endif
 
         cssrint(0); cssxint(0);
 #endif
 
-
         addr->css_icsr = CSS_CLR;
         addr->css_ocsr = CSS_CLR;
         DELAY(50000);
         addr->css_icsr = CSS_CLR;
         addr->css_ocsr = CSS_CLR;
         DELAY(50000);
@@ -126,25 +134,21 @@ cssprobe(reg)
  * the back pointers to common data structures.
  */
 cssattach(ui)
  * the back pointers to common data structures.
  */
 cssattach(ui)
-        struct uba_device *ui;
+        register struct uba_device *ui;
 {
         register struct css_softc *sc = &css_softc[ui->ui_unit];
         register struct impcb *ip;
 {
         register struct css_softc *sc = &css_softc[ui->ui_unit];
         register struct impcb *ip;
-        struct ifimpcb {
-                struct  ifnet ifimp_if;
-                struct  impcb ifimp_impcb;
-        } *ifimp;
 
 
-        if ((ifimp = (struct ifimpcb *)impattach(ui, cssreset)) == 0)
+        if ((sc->css_imp = impattach(ui->ui_driver->ud_dname, ui->ui_unit,
+           cssreset)) == 0)
                 return;
                 return;
-        sc->css_if = &ifimp->ifimp_if;
-        ip = &ifimp->ifimp_impcb;
-        sc->css_ic = ip;
+       ip = &sc->css_imp->imp_cb;
         ip->ic_init = cssinit;
         ip->ic_init = cssinit;
-        ip->ic_start = cssstart;
+        ip->ic_output = cssoutput;
+        ip->ic_down = cssdown;
        sc->css_ifuba.ifu_flags = UBA_CANTWAIT | UBA_NEED16;
 #ifdef notdef
        sc->css_ifuba.ifu_flags = UBA_CANTWAIT | UBA_NEED16;
 #ifdef notdef
-       sc->css_ifuba.ifu_flags =| UBA_NEEDBDP;
+       sc->css_ifuba.ifu_flags |= UBA_NEEDBDP;
 #endif
 }
 
 #endif
 }
 
@@ -156,16 +160,17 @@ cssreset(unit, uban)
         int unit, uban;
 {
         register struct uba_device *ui;
         int unit, uban;
 {
         register struct uba_device *ui;
-        struct css_softc *sc;
+        register struct css_softc *sc;
 
         if (unit >= NCSS || (ui = cssinfo[unit]) == 0 || ui->ui_alive == 0 ||
             ui->ui_ubanum != uban)
                 return;
         printf(" css%d", unit);
         sc = &css_softc[unit];
 
         if (unit >= NCSS || (ui = cssinfo[unit]) == 0 || ui->ui_alive == 0 ||
             ui->ui_ubanum != uban)
                 return;
         printf(" css%d", unit);
         sc = &css_softc[unit];
-       sc->css_if->if_flags &= ~IFF_RUNNING;
+       sc->css_imp->imp_if.if_flags &= ~IFF_RUNNING;
+       cssoflush(unit);
         /* must go through IMP to allow it to set state */
         /* must go through IMP to allow it to set state */
-        (*sc->css_if->if_init)(unit);
+        (*sc->css_imp->imp_if.if_init)(sc->css_imp->imp_if.if_unit);
 }
 
 /*
 }
 
 /*
@@ -194,13 +199,15 @@ cssinit(unit)
         * would assume we handle it on input and output.
         */
        
         * would assume we handle it on input and output.
         */
        
-        if (if_ubainit(&sc->css_ifuba, ui->ui_ubanum, 0,(int)btoc(IMPMTU)) == 0) {
+        if ((sc->css_imp->imp_if.if_flags & IFF_RUNNING) == 0 &&
+           if_ubainit(&sc->css_ifuba, ui->ui_ubanum, 0,
+           (int)btoc(IMP_RCVBUF)) == 0) {
                 printf("css%d: can't initialize\n", unit);
                ui->ui_alive = 0;
                 printf("css%d: can't initialize\n", unit);
                ui->ui_alive = 0;
-               sc->css_if->if_flags &= ~(IFF_UP | IFF_RUNNING);
+               sc->css_imp->imp_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
                return(0);
         }
                return(0);
         }
-       sc->css_if->if_flags |= IFF_RUNNING;
+       sc->css_imp->imp_if.if_flags |= IFF_RUNNING;
         addr = (struct cssdevice *)ui->ui_addr;
 
         /* reset the imp interface. */
         addr = (struct cssdevice *)ui->ui_addr;
 
         /* reset the imp interface. */
@@ -237,13 +244,13 @@ cssinit(unit)
          * Put up a read.  We can't restart any outstanding writes
          * until we're back in synch with the IMP (i.e. we've flushed
          * the NOOPs it throws at us).
          * Put up a read.  We can't restart any outstanding writes
          * until we're back in synch with the IMP (i.e. we've flushed
          * the NOOPs it throws at us).
-        * Note: IMPMTU includes the leader.
+        * Note: IMP_RCVBUF includes the leader.
          */
 
         x = spl5();
         info = sc->css_ifuba.ifu_r.ifrw_info;
         addr->css_iba = (u_short)info;
          */
 
         x = spl5();
         info = sc->css_ifuba.ifu_r.ifrw_info;
         addr->css_iba = (u_short)info;
-        addr->css_iwc = -(IMPMTU >> 1);
+        addr->css_iwc = -(IMP_RCVBUF >> 1);
         addr->css_icsr = 
                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
         splx(x);
         addr->css_icsr = 
                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
         splx(x);
@@ -254,35 +261,51 @@ down:
        return(0);
 }
 
        return(0);
 }
 
+/*
+ * Drop the host ready line to mark host down.
+ * UNTESTED.
+ */
+cssdown(unit)
+       int unit;
+{
+        register struct cssdevice *addr;
+
+       addr = (struct cssdevice *)(cssinfo[unit]->ui_addr);
+        /* reset the imp interface. */
+        addr->css_icsr = CSS_CLR;
+        addr->css_ocsr = CSS_CLR;
+       DELAY(100);
+       addr->css_icsr = 0;
+       addr->css_ocsr = 0;
+       cssoflush(unit);
+       return (1);
+}
+
+cssoflush(unit)
+       int unit;
+{
+       register struct css_softc *sc = &css_softc[unit];
+
+       sc->css_imp->imp_cb.ic_oactive = 0;
+       if (sc->css_ifuba.ifu_xtofree) {
+               m_freem(sc->css_ifuba.ifu_xtofree);
+               sc->css_ifuba.ifu_xtofree = 0;
+       }
+}
+
 /*
  * Start output on an interface.
  */
 /*
  * Start output on an interface.
  */
-cssstart(dev)
-        dev_t dev;
+cssoutput(unit, m)
+        int unit;
+        struct mbuf *m;
 {
 {
-        int unit = CSSUNIT(dev), info;
+        int info;
         struct uba_device *ui = cssinfo[unit];
         register struct css_softc *sc = &css_softc[unit];
         register struct cssdevice *addr;
         struct uba_device *ui = cssinfo[unit];
         register struct css_softc *sc = &css_softc[unit];
         register struct cssdevice *addr;
-        struct mbuf *m;
-        u_short cmd;
 
 
-        if (sc->css_ic->ic_oactive)
-                goto restart;
-        
-        /*
-         * Not already active, deqeue a request and
-         * map it onto the UNIBUS.  If no more
-         * requeusts, just return.
-         */
-        IF_DEQUEUE(&sc->css_if->if_snd, m);
-        if (m == 0) {
-                sc->css_ic->ic_oactive = 0;
-                return;
-        }
         sc->css_olen = if_wubaput(&sc->css_ifuba, m);
         sc->css_olen = if_wubaput(&sc->css_ifuba, m);
-
-restart:
         /*
          * Have request mapped to UNIBUS for transmission.
          * Purge any stale data from the BDP, and start the output.
         /*
          * Have request mapped to UNIBUS for transmission.
          * Purge any stale data from the BDP, and start the output.
@@ -293,9 +316,9 @@ restart:
         info = sc->css_ifuba.ifu_w.ifrw_info;
         addr->css_oba = (u_short)info;
         addr->css_owc = -((sc->css_olen + 1) >> 1);
         info = sc->css_ifuba.ifu_w.ifrw_info;
         addr->css_oba = (u_short)info;
         addr->css_owc = -((sc->css_olen + 1) >> 1);
-        cmd = CSS_IE | OUT_ENLB | ((info & 0x30000) >> 12) | CSS_GO;
-        addr->css_ocsr = cmd;
-        sc->css_ic->ic_oactive = 1;
+        addr->css_ocsr =
+           (u_short)(CSS_IE | OUT_ENLB | ((info & 0x30000) >> 12) | CSS_GO);
+        sc->css_imp->imp_cb.ic_oactive = 1;
 }
 
 /*
 }
 
 /*
@@ -308,15 +331,15 @@ cssxint(unit)
         register struct cssdevice *addr;
 
         addr = (struct cssdevice *)ui->ui_addr;
         register struct cssdevice *addr;
 
         addr = (struct cssdevice *)ui->ui_addr;
-        if (sc->css_ic->ic_oactive == 0) {
+        if (sc->css_imp->imp_cb.ic_oactive == 0) {
                 printf("css%d: stray output interrupt csr=%b\n",
                        unit, addr->css_ocsr, CSS_OUTBITS);
                 return;
         }
                 printf("css%d: stray output interrupt csr=%b\n",
                        unit, addr->css_ocsr, CSS_OUTBITS);
                 return;
         }
-        sc->css_if->if_opackets++;
-        sc->css_ic->ic_oactive = 0;
+        sc->css_imp->imp_if.if_opackets++;
+        sc->css_imp->imp_cb.ic_oactive = 0;
         if (addr->css_ocsr & CSS_ERR){
         if (addr->css_ocsr & CSS_ERR){
-                sc->css_if->if_oerrors++;
+                sc->css_imp->imp_if.if_oerrors++;
                 printf("css%d: output error, ocsr=%b icsr=%b\n", unit,
                         addr->css_ocsr, CSS_OUTBITS,
                        addr->css_icsr, CSS_INBITS);
                 printf("css%d: output error, ocsr=%b icsr=%b\n", unit,
                         addr->css_ocsr, CSS_OUTBITS,
                        addr->css_icsr, CSS_INBITS);
@@ -325,8 +348,7 @@ cssxint(unit)
                m_freem(sc->css_ifuba.ifu_xtofree);
                sc->css_ifuba.ifu_xtofree = 0;
        }
                m_freem(sc->css_ifuba.ifu_xtofree);
                sc->css_ifuba.ifu_xtofree = 0;
        }
-       if (sc->css_if->if_snd.ifq_head)
-               cssstart(unit);
+       impstart(sc->css_imp);
 }
 
 /*
 }
 
 /*
@@ -339,7 +361,7 @@ cssrint(unit)
         struct mbuf *m;
         int len, info;
 
         struct mbuf *m;
         int len, info;
 
-        sc->css_if->if_ipackets++;
+        sc->css_imp->imp_if.if_ipackets++;
 
         /*
          * Purge BDP; flush message if error indicated.
 
         /*
          * Purge BDP; flush message if error indicated.
@@ -351,7 +373,7 @@ cssrint(unit)
         if (addr->css_icsr & CSS_ERR) {
                 printf("css%d: recv error, csr=%b\n", unit,
                     addr->css_icsr, CSS_INBITS);
         if (addr->css_icsr & CSS_ERR) {
                 printf("css%d: recv error, csr=%b\n", unit,
                     addr->css_icsr, CSS_INBITS);
-                sc->css_if->if_ierrors++;
+                sc->css_imp->imp_if.if_ierrors++;
                 sc->css_flush = 1;
         }
 
                 sc->css_flush = 1;
         }
 
@@ -361,10 +383,10 @@ cssrint(unit)
                 goto setup;
         }
 
                 goto setup;
         }
 
-        len = IMPMTU + (addr->css_iwc << 1);
-       if (len < 0 || len > IMPMTU) {
+        len = IMP_RCVBUF + (addr->css_iwc << 1);
+       if (len < 0 || len > IMP_RCVBUF) {
                printf("css%d: bad length=%d\n", len);
                printf("css%d: bad length=%d\n", len);
-               sc->css_if->if_ierrors++;
+               sc->css_imp->imp_if.if_ierrors++;
                goto setup;
        }
 
                goto setup;
        }
 
@@ -372,7 +394,7 @@ cssrint(unit)
          * The offset parameter is always 0 since using
          * trailers on the ARPAnet is insane.
          */
          * The offset parameter is always 0 since using
          * trailers on the ARPAnet is insane.
          */
-        m = if_rubaget(&sc->css_ifuba, len, 0, sc->css_if);
+        m = if_rubaget(&sc->css_ifuba, len, 0, &sc->css_imp->imp_if);
         if (m == 0)
                 goto setup;
         if ((addr->css_icsr & IN_EOM) == 0) {
         if (m == 0)
                 goto setup;
         if ((addr->css_icsr & IN_EOM) == 0) {
@@ -395,7 +417,7 @@ setup:
          */
         info = sc->css_ifuba.ifu_r.ifrw_info;
         addr->css_iba = (u_short)info;
          */
         info = sc->css_ifuba.ifu_r.ifrw_info;
         addr->css_iba = (u_short)info;
-        addr->css_iwc = - (IMPMTU >> 1);
+        addr->css_iwc = - (IMP_RCVBUF >> 1);
         addr->css_icsr =
                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
 }
         addr->css_icsr =
                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
 }