Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/bi Reset the device before starting the init sequence.



details:   https://anonhg.NetBSD.org/src/rev/b597d9ca85bb
branches:  trunk
changeset: 484992:b597d9ca85bb
user:      ragge <ragge%NetBSD.org@localhost>
date:      Sun Apr 16 09:55:39 2000 +0000

description:
Reset the device before starting the init sequence.
Add shutdown hook.

diffstat:

 sys/dev/bi/if_ni.c    |  114 +++++++++++++++++++++++++++++++++++--------------
 sys/dev/bi/if_nireg.h |    5 +-
 2 files changed, 85 insertions(+), 34 deletions(-)

diffs (252 lines):

diff -r 78cf89c59d74 -r b597d9ca85bb sys/dev/bi/if_ni.c
--- a/sys/dev/bi/if_ni.c        Sun Apr 16 09:55:16 2000 +0000
+++ b/sys/dev/bi/if_ni.c        Sun Apr 16 09:55:39 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ni.c,v 1.1 2000/04/09 16:49:57 ragge Exp $ */
+/*     $NetBSD: if_ni.c,v 1.2 2000/04/16 09:55:39 ragge Exp $ */
 /*
  * Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
  *
@@ -142,9 +142,11 @@
 static int     ni_add_rxbuf(struct ni_softc *, struct ni_dg *, int);
 static void    ni_setup __P((struct ni_softc *));
 static void    nitimeout __P((struct ifnet *));
+static void    ni_shutdown(void *);
 static void ni_getpgs(struct ni_softc *sc, int size, caddr_t *v, paddr_t *p);
+static int failtest(struct ni_softc *, int, int, int, char *);
 
-volatile int endwait;  /* Used during autoconfig */
+volatile int endwait, retry;   /* Used during autoconfig */
 
 struct cfattach ni_ca = {
        sizeof(struct ni_softc), nimatch, niattach
@@ -199,8 +201,26 @@
 
        if (p)
                *p = seg.ds_addr;
+       bzero(*v, size);
 }
 
+static int
+failtest(struct ni_softc *sc, int reg, int mask, int test, char *str)
+{
+       int i = 100;
+
+       do {
+               DELAY(100000);
+       } while (((NI_RREG(reg) & mask) != test) && --i);
+
+       if (i == 0) {
+               printf("%s: %s\n", sc->sc_dev.dv_xname, str);
+               return 1;
+       }
+       return 0;
+}
+
+
 /*
  * Interface exists: make available by filling in network interface
  * record.  System will initialize the interface when it is ready
@@ -217,7 +237,7 @@
        struct ni_msg *msg;
        struct ni_ptdb *ptdb;
        caddr_t va;
-       int i, j, res;
+       int i, j, s, res;
        u_short type;
 
        type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE);
@@ -237,7 +257,6 @@
        /*
         * Zero the newly allocated memory.
         */
-       bzero(sc->sc_gvppqb, sizeof(struct ni_gvppqb));
 
        nipqb->np_veclvl = (ba->ba_ivec << 2) + 2;
        nipqb->np_node = ba->ba_intcpu;
@@ -269,17 +288,22 @@
        /*
         * Start init sequence.
         */
-       /* Check state */
-       for (i = 0; i < 100; i++) {
-               if ((NI_RREG(NI_PSR) & PSR_STATE) == PSR_UNDEF)
-                       break;
-               DELAY(100000);
-       }
-       if (i == 100) {
-               printf(": not undefined state\n");
+
+       /* Reset the node */
+       NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST);
+       DELAY(500000);
+       i = 20;
+       while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i)
+               DELAY(500000);
+       if (i == 0) {
+               printf("%s: BROKE bit set after reset\n", sc->sc_dev.dv_xname);
                return;
        }
 
+       /* Check state */
+       if (failtest(sc, NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state"))
+               return;
+
        /* Clear owner bits */
        NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
        NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN);
@@ -290,15 +314,9 @@
                DELAY(100000);
 
        /* Check state */
-       for (i = 0; i < 100; i++) {
-               if ((NI_RREG(NI_PSR) & PSR_INITED))
-                       break;
-               DELAY(100000);
-       }
-       if (i == 100) {
-               printf(": failed initialize\n");
+       if (failtest(sc, NI_PSR, PSR_INITED, PSR_INITED, "failed initialize"))
                return;
-       }
+
        NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
 
        WAITREG(NI_PCR, PCR_OWN);
@@ -307,15 +325,9 @@
        WAITREG(NI_PSR, PSR_OWN);
 
        /* Check state */
-       for (i = 0; i < 100; i++) {
-               if ((NI_RREG(NI_PSR) & PSR_STATE) == PSR_ENABLED)
-                       break;
-               DELAY(10000);
-       }
-       if (i == 100) {
-               printf(": failed enable\n");
+       if (failtest(sc, NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable"))
                return;
-       }
+
        NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
 
        /*
@@ -327,9 +339,9 @@
 #if NBPG < 4096
 #error pagesize too small
 #endif
+       s = splimp();
        /* Set up message free queue */
        ni_getpgs(sc, NMSGBUF * 512, &va, 0);
-       bzero(va, NMSGBUF * 512);
        for (i = 0; i < NMSGBUF; i++) {
                struct ni_msg *msg;
 
@@ -386,6 +398,8 @@
        NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
        WAITREG(NI_PCR, PCR_OWN);
 
+       splx(s);
+
        /* Set initial parameters */
        msg = REMQHI(&fqb->nf_mforw);
 
@@ -395,14 +409,22 @@
        msg->nm_opcode2 = NI_WPARAM;
        ((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD;
 
-       endwait = 0;
+       endwait = retry = 0;
        res = INSQTI(msg, &gvp->nc_forw0);
 
-       WAITREG(NI_PCR, PCR_OWN);
+retry: WAITREG(NI_PCR, PCR_OWN);
        NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
        WAITREG(NI_PCR, PCR_OWN);
-       while (endwait == 0)
-               ;
+       i = 1000;
+       while (endwait == 0 && --i)
+               DELAY(10000);
+
+       if (endwait == 0) {
+               if (++retry < 3)
+                       goto retry;
+               printf("%s: no response to set params\n", sc->sc_dev.dv_xname);
+               return;
+       }
 
        /* Clear counters */
        msg = REMQHI(&fqb->nf_mforw);
@@ -446,6 +468,9 @@
         */
        if_attach(ifp);
        ether_ifattach(ifp, sc->sc_enaddr);
+       if (shutdownhook_establish(ni_shutdown, sc) == 0)
+               printf("%s: WARNING: unable to establish shutdown hook\n",
+                   sc->sc_dev.dv_xname);
 
 #if NBPFILTER > 0
        bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
@@ -570,6 +595,12 @@
        struct mbuf *m;
        int idx, res;
 
+       if ((NI_RREG(NI_PSR) & PSR_STATE) != PSR_ENABLED)
+               return;
+
+       if ((NI_RREG(NI_PSR) & PSR_ERR))
+               printf("%s: PSR %x\n", sc->sc_dev.dv_xname, NI_RREG(NI_PSR));
+
        /* Got any response packets?  */
        while ((NI_RREG(NI_PSR) & PSR_RSQ) && (data = REMQHI(&gvp->nc_forwr))) {
 
@@ -860,3 +891,20 @@
        niinit(sc);
 #endif
 }
+
+/*
+ * Shutdown hook.  Make sure the interface is stopped at reboot.
+ */
+void
+ni_shutdown(arg)
+       void *arg;
+{
+       struct ni_softc *sc = arg;
+
+        WAITREG(NI_PCR, PCR_OWN);
+        NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN);
+        WAITREG(NI_PCR, PCR_OWN);
+        WAITREG(NI_PSR, PSR_OWN);
+
+}
+
diff -r 78cf89c59d74 -r b597d9ca85bb sys/dev/bi/if_nireg.h
--- a/sys/dev/bi/if_nireg.h     Sun Apr 16 09:55:16 2000 +0000
+++ b/sys/dev/bi/if_nireg.h     Sun Apr 16 09:55:39 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_nireg.h,v 1.1 2000/04/09 16:49:58 ragge Exp $       */
+/*     $NetBSD: if_nireg.h,v 1.2 2000/04/16 09:55:39 ragge Exp $       */
 /*
  * Copyright (c) 1988 Regents of the University of California.
  * All rights reserved.
@@ -85,8 +85,10 @@
 #define        PCR_CMDQ1       PCR_DFREEQ
 #define        PCR_CMDQ2       PCR_RFREEQ
 #define        PCR_CMDQ3       PCR_IFREEQ
+#define        PCR_RESTART     11
 #define PCR_FREEQNE    7
 #define PCR_CMDQNE     6
+#define        PCR_SHUTDOWN    4
 #define PCR_ENABLE     2
 #define PCR_INIT       1
 
@@ -98,6 +100,7 @@
 #define PSR_INITED     0x00020000
 #define PSR_UNDEF      0x00010000
 #define PSR_RSQ                0x00000080
+#define        PSR_ERR         0x00000040
 
 /*
  * The DEBNx uses a very wierd (set of) structure(s) to communicate



Home | Main Index | Thread Index | Old Index